feat: content fetch, sitemap fixes, remove oidcAuthFlow

- Add contentFetchFlow() to proxy (FR-001 through FR-012)
- Add extractArticleBody() helper with vkm:articleBody / articleBody fallback
- Dynamic proxyBaseUrl derivation from x-forwarded-proto/host headers
- Forward query/size/category params on /sitemap.xml requests
- Add Accept: application/ld+json header to content API calls
- Remove oidcAuthFlow() - unmatched requests now return 404 Not Found
- Fix xmlbuilder2 import: default import, call as xmlbuilder2.create(...)
- Version bump 0.2.0 → 0.3.0
- 45/45 tests passing

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
2026-04-23 16:40:06 -05:00
parent d50f041488
commit f840587e5e
29 changed files with 1998 additions and 352 deletions

View File

@@ -72,11 +72,11 @@ adaption to the real shape is a one-line change.
## R-003: xmlbuilder2 `create()` API for Sitemap XML
**Decision**: Use the `xmlBuilder` context variable (which is `xmlbuilder2`'s `create` function)
**Decision**: Use the `xmlbuilder2` context variable (which is `xmlbuilder2`'s `create` function)
with the following call chain:
```javascript
const doc = xmlBuilder({ version: '1.0', encoding: 'UTF-8' });
const doc = xmlbuilder2({ version: '1.0', encoding: 'UTF-8' });
const urlset = doc.ele('urlset', { xmlns: 'http://www.sitemaps.org/schemas/sitemap/0.9' });
for (const item of items) {
urlset.ele('url').ele('loc').txt(locValue).up().up();
@@ -98,7 +98,7 @@ Unit tests will assert this.
**Alternatives considered**:
- Manual string concatenation: rejected (error-prone escaping, violates FR-008 which requires
xmlBuilder).
xmlbuilder2).
- `xmlbuilder` (v1/v2): not the installed package; rejected.
---
@@ -184,7 +184,7 @@ if (!vkmUrl) continue; // omit silently
|---|---|---|
| R-001 | Token reuse | Inline shared token-fetch logic; branch on URL first |
| R-002 | Search API response shape | Assume `{ items: [...] }`; verify against live API |
| R-003 | xmlbuilder2 API | `xmlBuilder({...}).ele('urlset', {...})…doc.end({})` |
| R-003 | xmlbuilder2 API | `xmlbuilder2({...}).ele('urlset', {...})…doc.end({})` |
| R-004 | Error mapping | Reuse existing `err.response` / `err.code` pattern |
| R-005 | Settings validation | Explicit `requiredSitemapFields` guard → HTTP 500 |
| R-006 | `loc` construction | `proxyBaseUrl?kmeURL=encodeURIComponent(vkm:url)` |