Skip to content

feat(i18n): consume central translations from @escalated-dev/locale#68

Merged
mpge merged 6 commits intomainfrom
feat/central-locale
May 2, 2026
Merged

feat(i18n): consume central translations from @escalated-dev/locale#68
mpge merged 6 commits intomainfrom
feat/central-locale

Conversation

@mpge
Copy link
Copy Markdown
Member

@mpge mpge commented May 2, 2026

Summary

Wires escalated-adonis to consume translations from the new central npm package @escalated-dev/locale. The package's translation loader now layers three sources, with later layers winning on key conflict:

  1. Central package@escalated-dev/locale/locales/{locale}/ (canonical, shared across every host plugin)
  2. Bundled localresources/lang/{locale}/messages.json (this package's existing files, kept as overrides)
  3. Host overridesresources/lang/overrides/{locale}/messages.json (new per-host override slot)

No translation content was modified. Existing call sites (t('tickets.created') etc.) keep working because the loader hoists messages.json keys to the top level for backwards compatibility.

Wiring

  • package.json — added "@escalated-dev/locale": "^0.1.0" to dependencies.
  • src/support/i18n.ts — replaced the single-source loader with a layered loader that resolves the central package via createRequire, deep-merges the bundled local files on top, and finally deep-merges any host-supplied overrides under resources/lang/overrides/.
  • stubs/config/i18n.stub — new stub that ships a canonical config/i18n.ts for host apps using @adonisjs/i18n v3+ directly. Chains two loaders.fs(...) entries (central path resolved via require.resolve('@escalated-dev/locale/package.json'), then app.languageFilesPath()) in order so local resources override the central package.
  • resources/lang/overrides/.gitkeep + README.md — new directory with documentation of the layering pattern and a sample @adonisjs/i18n config snippet.
  • README.md / CHANGELOG.md — documented the new i18n source-of-truth.

Blocked on escalated-dev/escalated-locale v0.1.0 publish

CI will fail on npm install until @escalated-dev/locale@0.1.0 is published to npm. Mark merge-ready once the upstream package ships. Expected error:

npm error code E404
npm error 404 Not Found - GET https://registry.npmjs.org/@escalated-dev%2flocale - Not found
npm error 404 '@escalated-dev/locale@^0.1.0' is not in this registry.

The runtime loader already handles the missing-package case gracefully (resolveCentralLangDir() returns null and the bundled local files are used alone), so local development without the published package keeps working.

Test plan

  • npm install succeeds once @escalated-dev/locale@0.1.0 is published
  • npm run build (or tsc) passes
  • node --test tests/*.test.js continues to pass — no translation regressions
  • Manual: add a key only to the central package, verify t('newKey') resolves
  • Manual: add the same key to resources/lang/en/messages.json, verify the local value wins
  • Manual: add the same key to resources/lang/overrides/en/messages.json, verify the override wins

mpge added 6 commits May 1, 2026 22:09
…verrides

Loads translations from @escalated-dev/locale/locales/{locale}/ as the base
layer, then deep-merges this package's resources/lang/{locale}/messages.json
on top, then any host-supplied resources/lang/overrides/{locale}/ files.

Existing call sites (t('tickets.created')) keep working because messages.json
keys are hoisted to the top level.
Switch from npm range "^0.1.0" (no published npm package) to a GitHub
tarball reference at v0.1.2, which ships the root package.json shim so
the install resolves cleanly under Adonis 7 / Node 24.
@mpge mpge marked this pull request as ready for review May 2, 2026 19:28
@mpge mpge merged commit 9e8722e into main May 2, 2026
3 checks passed
@mpge mpge deleted the feat/central-locale branch May 2, 2026 19:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant