Files
biblical-guide.com/scripts/parse-bsb-md-full.js
andupetcu 196ca00194 Fix authentication state persistence and admin role display
- Implement complete authentication system with JWT token validation
- Add auth provider with persistent login state across page refreshes
- Create multilingual login/register forms with Material-UI components
- Fix token validation using raw SQL queries to bypass Prisma sync issues
- Add comprehensive error handling for expired/invalid tokens
- Create profile and settings pages with full i18n support
- Add proper user role management (admin/user) with database sync
- Implement secure middleware with CSRF protection and auth checks
- Add debug endpoints for troubleshooting authentication issues
- Fix Zustand store persistence for authentication state

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-21 01:06:30 +03:00

104 lines
5.4 KiB
JavaScript

#!/usr/bin/env node
const fs = require('fs')
const path = require('path')
const SRC = process.env.BSB_MD_PATH || path.join('bibles', 'bible-bsb.md')
const OUT_ABBR = (process.env.EN_ABBR || 'BSB_MD').toUpperCase()
const OUT_DIR = process.env.OUTPUT_DIR || path.join('data','en_bible', OUT_ABBR)
function ensureDir(p){ fs.mkdirSync(p,{recursive:true}) }
function writeJson(file,obj){ ensureDir(path.dirname(file)); fs.writeFileSync(file, JSON.stringify(obj,null,2),'utf-8') }
const BOOKS = [
['Genesis', ['Genesis'],'OT'], ['Exodus',['Exodus'],'OT'], ['Leviticus',['Leviticus'],'OT'], ['Numbers',['Numbers'],'OT'], ['Deuteronomy',['Deuteronomy'],'OT'],
['Joshua',['Joshua'],'OT'], ['Judges',['Judges'],'OT'], ['Ruth',['Ruth'],'OT'], ['1 Samuel',['1\s+Samuel','1\s+Samuel'],'OT'], ['2 Samuel',['2\s+Samuel','2\s+Samuel'],'OT'],
['1 Kings',['1\s+Kings'],'OT'], ['2 Kings',['2\s+Kings'],'OT'], ['1 Chronicles',['1\s+Chronicles'],'OT'], ['2 Chronicles',['2\s+Chronicles'],'OT'],
['Ezra',['Ezra'],'OT'], ['Nehemiah',['Nehemiah'],'OT'], ['Esther',['Esther'],'OT'], ['Job',['Job'],'OT'], ['Psalms',['Psalms|Psalm'],'OT'],
['Proverbs',['Proverbs'],'OT'], ['Ecclesiastes',['Ecclesiastes'],'OT'], ['Song of Songs',['Song\s+of\s+Songs|Song\s+of\s+Solomon'],'OT'], ['Isaiah',['Isaiah'],'OT'],
['Jeremiah',['Jeremiah'],'OT'], ['Lamentations',['Lamentations'],'OT'], ['Ezekiel',['Ezekiel'],'OT'], ['Daniel',['Daniel'],'OT'],
['Hosea',['Hosea'],'OT'], ['Joel',['Joel'],'OT'], ['Amos',['Amos'],'OT'], ['Obadiah',['Obadiah'],'OT'], ['Jonah',['Jonah'],'OT'], ['Micah',['Micah'],'OT'],
['Nahum',['Nahum'],'OT'], ['Habakkuk',['Habakkuk'],'OT'], ['Zephaniah',['Zephaniah'],'OT'], ['Haggai',['Haggai'],'OT'], ['Zechariah',['Zechariah'],'OT'], ['Malachi',['Malachi'],'OT'],
['Matthew',['Matthew'],'NT'], ['Mark',['Mark'],'NT'], ['Luke',['Luke'],'NT'], ['John',['John'],'NT'], ['Acts',['Acts'],'NT'],
['Romans',['Romans'],'NT'], ['1 Corinthians',['1\s+Corinthians'],'NT'], ['2 Corinthians',['2\s+Corinthians'],'NT'], ['Galatians',['Galatians'],'NT'], ['Ephesians',['Ephesians'],'NT'],
['Philippians',['Philippians'],'NT'], ['Colossians',['Colossians'],'NT'], ['1 Thessalonians',['1\s+Thessalonians'],'NT'], ['2 Thessalonians',['2\s+Thessalonians'],'NT'],
['1 Timothy',['1\s+Timothy'],'NT'], ['2 Timothy',['2\s+Timothy'],'NT'], ['Titus',['Titus'],'NT'], ['Philemon',['Philemon'],'NT'],
['Hebrews',['Hebrews'],'NT'], ['James',['James'],'NT'], ['1 Peter',['1\\s+Peter'],'NT'], ['2 Peter',['2\\s+Peter'],'NT'],
['1 John',['1\s+John'],'NT'], ['2 John',['2\s+John'],'NT'], ['3 John',['3\s+John'],'NT'], ['Jude',['Jude'],'NT'], ['Revelation',['Revelation'],'NT']
]
function main(){
if(!fs.existsSync(SRC)) { console.error('Missing source:', SRC); process.exit(1) }
const md = fs.readFileSync(SRC,'utf-8')
// Collect all verse markers across the entire doc
const markers = []
for(const [name, variants] of BOOKS){
const names = variants.join('|')
const re = new RegExp('(?:^|[\\n\\r\\f\\s\\|\\(])(?:'+names+')\\s+(\\d+):(\\d+)', 'gi')
let m
while((m=re.exec(md))!==null){
markers.push({ book:name, chapter:parseInt(m[1],10), verse:parseInt(m[2],10), index:m.index, matchLen:m[0].length })
}
}
if(markers.length===0){ console.error('No verse markers found'); process.exit(1) }
markers.sort((a,b)=>a.index-b.index)
// Build text segments per marker (chapter/verse)
const entries = []
for(let i=0;i<markers.length;i++){
const cur = markers[i]
const start = cur.index + cur.matchLen
const end = (i+1<markers.length) ? markers[i+1].index : md.length
let text = md.slice(start, end)
text = text.replace(/[\u000c\r]+/g,'\n') // formfeed
text = text.replace(/\s+/g,' ').trim()
// Stop overly long spill
if(text.length>1500) text = text.slice(0,1500).trim()
entries.push({ ...cur, text })
}
// Aggregate into OT/NT JSON
const bookIndex = new Map(BOOKS.map(([n,_,t],i)=>[n,{testament:t, order:i+1}]))
const byBook = new Map()
for(const e of entries){
if(!byBook.has(e.book)) byBook.set(e.book, new Map())
const chMap = byBook.get(e.book)
if(!chMap.has(e.chapter)) chMap.set(e.chapter, new Map())
const vMap = chMap.get(e.chapter)
if(!vMap.has(e.verse)) vMap.set(e.verse, e.text)
}
const otBooks=[]; const ntBooks=[]
for(const [name, chMap] of byBook){
const meta = bookIndex.get(name)
const chapters=[]
for(const [ch, vMap] of Array.from(chMap.entries()).sort((a,b)=>a[0]-b[0])){
const verses=[]
for(const [vn, txt] of Array.from(vMap.entries()).sort((a,b)=>a[0]-b[0])){
verses.push({ verseNum: vn, text: txt })
}
if(verses.length>0) chapters.push({ chapterNum: ch, verses })
}
const bookObj={ name, chapters }
if(meta?.testament==='OT') otBooks.push({name,chapters})
else ntBooks.push({name,chapters})
}
// Sort books in canonical order
otBooks.sort((a,b)=>bookIndex.get(a.name).order-bookIndex.get(b.name).order)
ntBooks.sort((a,b)=>bookIndex.get(a.name).order-bookIndex.get(b.name).order)
const ot={ testament:'Old Testament', books: otBooks }
const nt={ testament:'New Testament', books: ntBooks }
const otFile = path.join(OUT_DIR,'old_testament.json')
const ntFile = path.join(OUT_DIR,'new_testament.json')
writeJson(otFile, ot)
writeJson(ntFile, nt)
console.log('Wrote:', otFile)
console.log('Wrote:', ntFile)
console.log('Books parsed:', otBooks.length + ntBooks.length)
}
main()