67700c0e75
CI / update (push) Successful in 21s
Server runs from build output dir where CWD-relative `static/*.tsv` misses — adapter-node ships static assets at build/client/. New resolveStaticAsset() helper uses import.meta.url to find the bundled location, falls back to <cwd>/static/ in dev. Fixes ENOENT on drb.tsv/allioli.tsv after deploy.
92 lines
2.3 KiB
TypeScript
92 lines
2.3 KiB
TypeScript
import { readFileSync } from 'fs';
|
|
import { resolveStaticAsset } from './staticAsset';
|
|
|
|
export interface BibleVerse {
|
|
bookName: string;
|
|
abbreviation: string;
|
|
bookNumber: number;
|
|
chapter: number;
|
|
verseNumber: number;
|
|
text: string;
|
|
}
|
|
|
|
const versesCache = new Map<string, BibleVerse[]>();
|
|
|
|
export function loadVersesFromFile(tsvPath?: string): BibleVerse[] {
|
|
const filePath = tsvPath ?? resolveStaticAsset('allioli.tsv');
|
|
const cached = versesCache.get(filePath);
|
|
if (cached) return cached;
|
|
|
|
const content = readFileSync(filePath, 'utf-8');
|
|
const lines = content.trim().split('\n');
|
|
|
|
const verses = lines.map((line) => {
|
|
const [bookName, abbreviation, bookNumber, chapter, verseNumber, text] = line.split('\t');
|
|
return {
|
|
bookName,
|
|
abbreviation,
|
|
bookNumber: parseInt(bookNumber),
|
|
chapter: parseInt(chapter),
|
|
verseNumber: parseInt(verseNumber),
|
|
text
|
|
};
|
|
});
|
|
|
|
versesCache.set(filePath, verses);
|
|
return verses;
|
|
}
|
|
|
|
function parseReference(reference: string) {
|
|
const match = reference.match(
|
|
/^(\d?\s?[A-Za-zäöüÄÖÜss]+)\s*(\d+)[\s,:]+(\d+)(?:[-:](\d+))?$/
|
|
);
|
|
if (!match) return null;
|
|
|
|
const [, rawBookRef, chapterStr, startVerseStr, endVerseStr] = match;
|
|
const bookRef = rawBookRef.replace(/\s/g, '');
|
|
|
|
return {
|
|
bookRef,
|
|
isFullName: bookRef.length > 5,
|
|
chapter: parseInt(chapterStr),
|
|
startVerse: parseInt(startVerseStr),
|
|
endVerse: endVerseStr ? parseInt(endVerseStr) : parseInt(startVerseStr)
|
|
};
|
|
}
|
|
|
|
export function getVersesByReference(
|
|
verses: BibleVerse[],
|
|
reference: string
|
|
): BibleVerse[] {
|
|
const parsed = parseReference(reference);
|
|
if (!parsed) return [];
|
|
|
|
return verses.filter((v) => {
|
|
const bookMatches = parsed.isFullName
|
|
? v.bookName === parsed.bookRef
|
|
: v.abbreviation === parsed.bookRef;
|
|
|
|
return (
|
|
bookMatches &&
|
|
v.chapter === parsed.chapter &&
|
|
v.verseNumber >= parsed.startVerse &&
|
|
v.verseNumber <= parsed.endVerse
|
|
);
|
|
});
|
|
}
|
|
|
|
export function lookupReference(reference: string, tsvPath?: string) {
|
|
const verses = loadVersesFromFile(tsvPath);
|
|
const matched = getVersesByReference(verses, reference);
|
|
|
|
if (matched.length === 0) return null;
|
|
|
|
const first = matched[0];
|
|
return {
|
|
reference,
|
|
book: first.bookName,
|
|
chapter: first.chapter,
|
|
verses: matched.map((v) => ({ verse: v.verseNumber, text: v.text }))
|
|
};
|
|
}
|