Files
homepage/src/lib/server/bible.ts
T
Alexander 67700c0e75
CI / update (push) Successful in 21s
fix(faith): resolve bible TSVs relative to module, not CWD
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.
2026-04-21 14:25:40 +02:00

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 }))
};
}