Peter.Morton d1563e8190 feat: sitemap pagination, HTML wrapper, and title from vkm:name
- Paginate sitemap using hydra:view['hydra:last'] (0-based item index model)
- Select latest vkm:datePublished fragment per SearchResultItem
- Cap sitemap at 50,000 URLs per sitemaps.org protocol
- Wrap content fetch response in full HTML document (DOCTYPE, head, body)
- Add <head><title> populated from vkm:name field
- Remove oidcAuthFlow route (404 for unmatched paths)
- All 51 tests passing

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-23 19:07:06 -05:00
2026-04-22 18:05:20 -05:00
2026-04-22 19:41:14 -05:00
2026-04-22 18:05:20 -05:00

kme-content-adapter

An HTTP proxy adapter that authenticates against KME and proxies content requests through an isolated VM sandbox, mirroring the IVA Studio proxy script execution environment.

Requirements

  • Node.js ≥ 18
  • Redis (used for token caching)
  • jq (optional — used by npm start for log pretty-printing)

Setup

npm install
cp src/globalVariables/kme_CSA_settings.json.example src/globalVariables/kme_CSA_settings.json
# Edit kme_CSA_settings.json with real credentials

Configuration

src/globalVariables/kme_CSA_settings.json

Credentials and OIDC settings — never commit this file.

{
  "tokenUrl": "https://<host>/oidc-token-service/<env>/token",
  "username": "<username>",
  "password": "<password>",
  "clientId": "default",
  "scope": "openid tags content_entitlements"
}

config/default.json

Infrastructure settings (port, host, log level). Override with environment variables:

Variable Default Description
PORT 3000 HTTP server port
HOST 0.0.0.0 Bind address
LOG_LEVEL debug Log level: DEBUG, INFO, WARN, ERROR

Running

npm run dev      # Development — auto-restart on file changes
npm start        # Production — logs piped through jq

Testing

npm test                    # All tests
npm run test:unit           # Unit tests only
npm run test:integration    # Integration tests only
npm run test:contract       # Contract tests only

# Single test file
node --test tests/unit/proxy.test.js

Tests use the Node.js built-in node:test runner. No external test framework.

Architecture

The server loads src/proxyScripts/kmeContentSourceAdapter.js once at startup via vm.Script, then executes it in a fresh isolated VM context per request via vm.createContext.

src/
├── proxyScripts/
│   └── kmeContentSourceAdapter.js   # All business logic (zero imports/exports)
├── globalVariables/
│   ├── kme_CSA_settings.json        # OIDC credentials (gitignored)
│   └── adapterHelper.js             # Pure utilities (optional)
├── logger.js                        # Structured JSON logger
└── server.js                        # HTTP server bootstrap only
config/
└── default.json                     # Infrastructure settings

VM Context Globals

All dependencies are injected into each request's sandbox:

Variable Source
console Structured logger
crypto Node.js Web Crypto API
axios HTTP client
jwt jsonwebtoken
uuidv4 UUID v4 generator
xmlbuilder2 xmlbuilder2 create
redis Connected Redis client
URLSearchParams, URL Node.js globals
kme_CSA_settings Loaded from src/globalVariables/kme_CSA_settings.json
req, res Node.js HTTP request/response

Key Constraints for kmeContentSourceAdapter.js

  • Zero import/export — runs in a VM with no module system
  • No config, global.config, or process.env — use injected globals only
  • Routing metadata is available via req.params (set by server.js)

Token Caching

OIDC tokens are cached in Redis under the hash key authorization (fields token and expiry). The cache survives adapter restarts. Token expiry is stored as an absolute Unix epoch timestamp.

Changelog

See CHANGELOG.md.

Description
KME Content Source Adapter
Readme 455 KiB
Languages
Shell 47.9%
JavaScript 39%
PowerShell 13.1%