Add Nuggets to global search and RSS-sourced scripture refs to index; v2.0.26
Publish Container / docker (push) Successful in 15m20s

- Raise RSS description truncation from 220 → 800 chars so scripture
  references in episode descriptions are preserved
- Global search now indexes Nuggets podcast episodes from
  /api/nuggets/episodes/all (title, subtitle, description via Fuse)
- Scripture Index (/api/public/scripture-index) now extracts verse
  references from both main podcast and Nuggets RSS descriptions
  using a regex built from the shared BIBLE_BOOKS list; duplicate refs
  across sources are merged by the existing client-side dedup logic
- Export fetchNuggetsEpisodes from nuggets.js for reuse

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
nmemmertandClaude Sonnet 4.6 committed 2026-09-17 10:27:12 -04:00
1 parent 590885f6b1
commit 1ddb8ee7be
5 files changed
+77 -5

No files matched your search

+1 -1
View File
@@ -9,7 +9,7 @@ function feedUrl() {
return state.cachedSiteContent?.nuggets?.rssFeedUrl?.trim() ?? ''
}
async function fetchNuggetsEpisodes() {
export async function fetchNuggetsEpisodes() {
const url = feedUrl()
if (!url) { cache = null; return [] }
+54 -1
View File
@@ -16,6 +16,33 @@ import { state } from '../state.js'
import { loadSiteContentFile } from '../data.js'
import { DATA_FILE } from '../config.js'
import { sanitizeRedirectRules } from '../study-helpers.js'
import { fetchAllEpisodes } from './episodes.js'
import { fetchNuggetsEpisodes } from './nuggets.js'
import { BIBLE_BOOKS } from '../../shared/bible-books.js'
// Build a regex that matches scripture references like "Titus 1:5-9" or "1 Cor 13:4-7"
// out of plain text. Sorted longest-first so "1 Corinthians" beats "1 Cor".
const _refPatterns = []
for (const b of BIBLE_BOOKS) {
_refPatterns.push(b.name, ...(b.aliases ?? []))
}
_refPatterns.sort((a, z) => z.length - a.length)
const _bookPart = _refPatterns.map(p => p.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')).join('|')
const SCRIPTURE_REF_RE = new RegExp(
`(${_bookPart})\\s+(\\d+):(\\d+)(?:-((?:\\d+):)?(\\d+))?`,
'gi',
)
function extractScriptureRefs(text) {
const refs = []
const seen = new Set()
for (const m of String(text || '').matchAll(SCRIPTURE_REF_RE)) {
const ref = m[0].trim()
const key = ref.toLowerCase()
if (!seen.has(key)) { seen.add(key); refs.push(ref) }
}
return refs
}
export function register(app) {
const SALVATION_INDEX_FILE = path.join(DIST_DIR, 'salvation', 'index.html')
@@ -160,7 +187,7 @@ export function register(app) {
})
// Scripture index — every passage covered across released study lessons and podcast episodes
app.get('/api/public/scripture-index', (_req, res) => {
app.get('/api/public/scripture-index', async (_req, res) => {
const content = state.cachedSiteContent
const allStudies = Array.isArray(content?.studies) ? content.studies : []
const allEpisodes = Array.isArray(content?.podcastFeaturedLinks) ? content.podcastFeaturedLinks : []
@@ -196,6 +223,32 @@ export function register(app) {
}
}
// Extract scripture refs from main podcast episode descriptions
try {
const mainEps = await fetchAllEpisodes()
for (const ep of mainEps) {
if (!ep.description) continue
const refs = extractScriptureRefs(ep.description)
for (const ref of refs) {
const title = ep.episode ? `Episode ${ep.episode}: ${ep.title}` : ep.title
entries.push({ reference: ref, sourceType: 'episode', sourceTitle: title, url: ep.link || '/episodes' })
}
}
} catch { /* keep going if RSS is down */ }
// Extract scripture refs from Nuggets episode descriptions
try {
const nuggetsEps = await fetchNuggetsEpisodes()
for (const ep of nuggetsEps) {
if (!ep.description) continue
const refs = extractScriptureRefs(ep.description)
for (const ref of refs) {
const title = ep.episode ? `Nuggets Ep. ${ep.episode}: ${ep.title}` : ep.title
entries.push({ reference: ref, sourceType: 'episode', sourceTitle: title, url: '/nuggets' })
}
}
} catch { /* keep going if RSS is down */ }
res.json({ entries })
})
+1 -1
View File
@@ -42,7 +42,7 @@ export function parseRssItems(xml, limit = Infinity) {
items.push({
title, pubDate, link,
audioUrl: enclosureUrl,
description: descText.slice(0, 220) + (descText.length > 220 ? '…' : ''),
description: descText.slice(0, 800) + (descText.length > 800 ? '…' : ''),
duration, episode, season,
})
}