Skip to content

Upgrade the version of i18next to address some CVEs and add translations tests - #101

Merged
Nkemjiks merged 1 commit into
mainfrom
dvlp-7216-upgrade-i18next
May 8, 2026
Merged

Nkemjiks merged 1 commit into
mainfrom
dvlp-7216-upgrade-i18next

Conversation

@stuartmg

@stuartmg stuartmg commented May 5, 2026

Copy link
Copy Markdown
Contributor

Summary

Replace the @prebsch-exo/i18next@19.9.2-patch.1 fork with the upstream i18next@^26.0.6 in @execonline-inc/translations, and add real tests for the package (it previously had only a broken placeholder).

  • Dependency swap: @prebsch-exo/i18next → i18next (skipping ~7 major versions of upstream changes; the v19 fork was a long-stale patch release)
  • Package bump: @execonline-inc/translations 11.5.0 → 12.0.0 (breaking dep change for consumers)
  • Tests: added 13 passing tests covering the i18next adapter init, the translation state machine, the alreadyTranslatedText decoder, and languageTag; removed the prior placeholder that wasn't even a valid test.

Why now

The @prebsch-exo/i18next fork hasn't moved in years and pinned us to v19-era APIs. Upstream i18next is at v26 with active maintenance, CLDR-based plural rules via Intl, and current TypeScript definitions. The init
API surface this adapter relies on (init(options, callback) returning a Promise) is unchanged across the gap, so the swap is mechanical.

Changes

packages/translations/package.json

-    "@prebsch-exo/i18next": "19.9.2-patch.1",
     "htmlparser2": "^4.1.0",
+    "i18next": "^26.0.6",

Version bumped to 12.0.0.

packages/translations/src/adapters/i18next/index.ts

-import i18next, * as i18n from '@prebsch-exo/i18next';
+import i18next, * as i18n from 'i18next';

packages/translations/__tests__/translations.test.ts (new)

Replaces the broken translations.test.js placeholder. Covers:

  • defaultSettings shape — guards ns/defaultNS/fallbackLng/keySeparator/nsSeparator/interpolation.escapeValue
  • initTask — end-to-end check that v26 init resolves a Loaded state with the right language and a working translator (including {{name}} interpolation)
  • translation — uninitialized → empty string; loaded → translator lookup; not-translatable keys → returned unchanged without invoking the translator; loaded-from-fallback → still uses the translator
  • alreadyTranslatedText — decodes strings; rejects non-strings
  • languageTag — strips region/script (en-US → en, zh-Hant-TW → zh); passes through when no hyphen

Tests run via bun test and import from ../src directly so they don't depend on a prior build.

Compatibility notes for downstream consumers

The initTask/defaultSettings API is unchanged, but consumers' translation content may be affected by upstream i18next changes between v19 and v26:

  • Plural rules: i18next moved from compatibilityJSON: 'v3' to Intl/CLDR-based plurals. JSON keys like key_plural no longer match — use key_one / key_other etc., or pass compatibilityJSON: 'v3' in your
    settings override.
  • Init still callback-compatible: init(options, (err, t) => …) works as before; no changes required in consumer init code.

Known pre-existing quirk (out of scope here)

While writing the init test I noticed adapters/i18next/index.ts lines 25 & 27 read i18next.language (the global default instance) instead of initializer.language (the argument). Consumers who pass a custom instance
via i18next.createInstance() will see Loaded.language as undefined. Not introduced by this PR; happy to file a follow-up.

@Nkemjiks
Nkemjiks merged commit 622e87c into main May 8, 2026
2 checks passed
@Nkemjiks
Nkemjiks deleted the dvlp-7216-upgrade-i18next branch May 8, 2026 14:12
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.

2 participants