[haxcms-nodejs] Localization settings parity (PHP): service, routes, createSite default language - #33
Conversation
…ill, createSite default language Mirrors the haxtheweb/haxcms-php localization settings implementation for backend parity. Stores the system-wide default language as a localization block on _config/config.json (single source of truth), matching the PHP HAXCMSLocalizationSettingsService shape exactly. - src/lib/localizationSettings.js: normalize/read/write the localization block on config.json (preserving sibling keys), BCP-47 validation, en-US default, in-memory config sync on write. - getLocalizationSettings / saveLocalizationSettings route handlers (user-token auth + payload validation), wired into settings.js (getLocalizationSettings / configurationLocalization / saveLocalizationSettings). - SystemRoutesMap: registered v1/configuration/localization GET/POST/PATCH + added to SystemV1AdminRoutes. - HAXCMS.js: localization config backfill (defaultLanguage en-US). - createSite.js: seeds new sites from HAXCMS.config.localization.defaultLanguage (fallback en-US) instead of hardcoding 'en-US'. - OpenAPI spec: /system/api/v1/configuration/localization path + schemas. - Tests: 16 unit tests (settings.test.cjs), e2e admin-system tests, api- conformance operation path. 91/91 unit tests pass. Refs haxtheweb/issues#2974 Co-Authored-By: Warp <agent@warp.dev>
Review or Edit in CodeSandboxOpen the branch in Web Editor • VS Code • Insiders |
There was a problem hiding this comment.
🟡 Changes recommended
The localization endpoint’s request/response contract and normalization behavior are not fully aligned with the OpenAPI schema and with GET-vs-PATCH consistency, risking client/conformance mismatches.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Adds Node.js backend support for system-level localization settings (default language) to match the PHP backend and the admin Configuration panel, including persistence in _config/config.json, new system API routes, and test coverage.
Changes:
- Introduces
src/lib/localizationSettings.jsfor reading/writing/normalizingconfig.json’slocalization.defaultLanguage. - Adds
/system/api/v1/configuration/localizationGET/POST (read) + PATCH (write) routes and wires them into the system route map. - Updates site creation to seed new sites’ language from
HAXCMS.config.localization.defaultLanguageand extends unit/e2e/api-conformance tests plus OpenAPI spec.
File summaries
| File | Description |
|---|---|
| test/unit/settings.test.cjs | Adds unit tests for localization settings normalization + read/write behavior. |
| test/e2e/admin-system.e2e.test.cjs | Adds e2e coverage for GET/PATCH localization configuration. |
| test/api-conformance/site-spec.conformance.test.cjs | Registers the new system route path in route-group conformance assertions. |
| src/systemRoutes/v1/settings.js | Wires route handlers for localization settings into the v1 settings controller. |
| src/systemRoutes/v1/routes/saveLocalizationSettings.js | Implements authenticated PATCH handler for persisting localization settings. |
| src/systemRoutes/v1/routes/getLocalizationSettings.js | Implements read handler returning effective localization settings. |
| src/systemRoutes/v1/routes/createSite.js | Seeds new site language from system localization config instead of hardcoding en-US. |
| src/openapi/system-spec.yaml | Adds the new endpoint + schemas to the system OpenAPI spec. |
| src/lib/SystemRoutesMap.js | Registers GET/POST/PATCH handlers and marks the route as an admin system route. |
| src/lib/localizationSettings.js | Adds config.json localization read/write + normalization helpers. |
| src/lib/HAXCMS.js | Backfills in-memory config.localization.defaultLanguage to en-US at boot. |
Review details
Suppressed comments (1)
src/systemRoutes/v1/routes/saveLocalizationSettings.js:78
- This PATCH route returns the raw persisted value from writeLocalizationSettings (which can be null when the client clears defaultLanguage), while GET always returns the effective (non-null) default via getEffectiveLocalizationSettings. Returning the effective settings here as well avoids a surprising mismatch between PATCH and a subsequent GET, and better matches the OpenAPI response contract.
const localizationSettings = await writeLocalizationSettings(HAXCMS, payload);
return res.json({
status: 200,
data: localizationSettings,
});
- Files reviewed: 11/11 changed files
- Comments generated: 4
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| const DEFAULT_LANGUAGE = 'en-US'; | ||
| const BCP47_LANGUAGE_REGEX = /^[a-zA-Z]{2,3}(-[a-zA-Z]{2,4})?$/; | ||
| const DEFAULT_LOCALIZATION_SETTINGS = { |
| LocalizationSettings: | ||
| type: object | ||
| description: Localization settings payload (defaultLanguage BCP-47 tag) | ||
| properties: | ||
| defaultLanguage: | ||
| type: string | ||
| description: BCP-47 language tag (e.g. en-US, es-ES, fr-FR) | ||
| additionalProperties: true | ||
| LocalizationSettingsData: | ||
| type: object | ||
| description: > | ||
| Localization settings returned by getLocalizationSettings and | ||
| saveLocalizationSettingsPatch. The front-end reads defaultLanguage. | ||
| properties: | ||
| defaultLanguage: | ||
| type: string | ||
| additionalProperties: true |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Summary
NodeJS backend parity for the localization settings feature introduced in
haxtheweb/haxcms-php(companion PR haxtheweb/haxcms-php#624). Stores the system-wide default language as alocalizationblock on_config/config.json— the single source of truth shared across both backends and the admin Configuration panel.What's added
src/lib/localizationSettings.js— mirrorsmediaSettings.js:normalizeDefaultLanguage(BCP-47 validation,en-USdefault),normalizeLocalizationSettings,getEffectiveLocalizationSettings,hasSupportedLocalizationSettingsPayload,isValidDefaultLanguagePayloadValue,readLocalizationSettings/writeLocalizationSettings(reads fullconfig.json, updates thelocalizationblock, writes back preserving sibling keys, syncshaxcms.config.localizationin memory).getLocalizationSettings/saveLocalizationSettingsroute handlers (user-token auth + payload validation), wired intosettings.js(getLocalizationSettings/configurationLocalization/saveLocalizationSettings).SystemRoutesMap.js— registeredv1/configuration/localizationGET/POST/PATCH + added toSystemV1AdminRoutes.HAXCMS.js—localizationconfig backfill (defaultLanguage: 'en-US').createSite.js— seeds new sites fromHAXCMS.config.localization.defaultLanguage(fallbacken-US) instead of hardcoding'en-US'./system/api/v1/configuration/localizationpath +LocalizationSettings/LocalizationSettingsDataschemas.settings.test.cjs, e2e admin-system tests, api-conformance operation path.Parity / consistency
defaultLanguage, storage_config/config.jsonlocalizationblock, routev1/configuration/localization, operation namesgetLocalizationSettings/saveLocalizationSettings— all match the PHP backend and the webcomponents Configuration panel exactly.?.); usesglobalThis. No build/ubiquity scripts run.Validation
node -con all 11 modified/new JS + test files: PASS.js-yamlparse of the OpenAPI spec: PASS.node --test test/unit/settings.test.cjs: 91/91 passed (includes the 16 new localizationSettings tests).Refs haxtheweb/issues#2974
Co-Authored-By: Warp agent@warp.dev