diff --git a/.changeset/honest-panthers-glow.md b/.changeset/honest-panthers-glow.md new file mode 100644 index 00000000..b03510a2 --- /dev/null +++ b/.changeset/honest-panthers-glow.md @@ -0,0 +1,5 @@ +--- +'@withease/i18next': major +--- + +Support i18next@25 diff --git a/package.json b/package.json index 8c129b7b..4bc00e82 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "effector-vue": "23.0.0", "estree-walker": "^3.0.3", "glob": "^8.0.3", - "i18next": "24.0.0", + "i18next": "25.0.0", "markdown": "^0.5.0", "playwright": "^1.32.2", "prettier": "^2.6.2", diff --git a/packages/i18next/package.json b/packages/i18next/package.json index 61378fc9..855a4e53 100644 --- a/packages/i18next/package.json +++ b/packages/i18next/package.json @@ -4,7 +4,7 @@ "license": "MIT", "peerDependencies": { "effector": "^22.5.0 || ^23.0.0", - "i18next": "^23.0.0 || ^24.0.0" + "i18next": "^23.0.0 || ^24.0.0 || ^25.0.0" }, "scripts": { "test:run": "vitest run --typecheck", @@ -35,7 +35,7 @@ "size-limit": [ { "path": "./dist/i18next.js", - "limit": "1.26 kB" + "limit": "1.33 kB" } ] } diff --git a/packages/i18next/src/integration.ts b/packages/i18next/src/integration.ts index 476c6829..ffc7cce9 100644 --- a/packages/i18next/src/integration.ts +++ b/packages/i18next/src/integration.ts @@ -176,7 +176,13 @@ export function createI18nextIntegration({ ): Store { return combine( { t: $t, variables: combine(variables ?? {}) }, - ({ t, variables }) => t(key, variables) ?? key + ({ t, variables }) => + t( + key, + // since i18next@25 t-function mutates variables object, + // so we spread it to avoid mutating original object + { ...variables } + ) ?? key ); } diff --git a/packages/i18next/src/translated.test.ts b/packages/i18next/src/translated.test.ts index 50f80873..f252aca1 100644 --- a/packages/i18next/src/translated.test.ts +++ b/packages/i18next/src/translated.test.ts @@ -27,6 +27,35 @@ describe('integration.translated', () => { expect(scope.getState($result)).toBe('valueOne'); }); + + test('supports simple key and language change', async () => { + const instance = createInstance({ + resources: { + th: { common: { key: 'valueOne' } }, + en: { common: { key: 'valueTwo' } }, + }, + lng: 'th', + }); + + const setup = createEvent(); + + const { translated, changeLanguageFx } = createI18nextIntegration({ + instance, + setup, + }); + + const $result = translated('common:key'); + + const scope = fork(); + + await allSettled(setup, { scope }); + + expect(scope.getState($result)).toBe('valueOne'); + + await allSettled(changeLanguageFx, { scope, params: 'en' }); + + expect(scope.getState($result)).toBe('valueTwo'); + }); }); describe('overload: template literal', () => { @@ -87,5 +116,40 @@ describe('integration.translated', () => { expect(scope.getState($result)).toBe('valueOne kek'); }); + + test('changes after language changed', async () => { + const instance = createInstance({ + resources: { + th: { common: { key: 'valueOne {{name}}' } }, + en: { common: { key: 'valueTwo {{name}}' } }, + }, + lng: 'th', + }); + + const setup = createEvent(); + + const { translated, changeLanguageFx } = createI18nextIntegration({ + instance, + setup, + }); + + const $name = createStore('wow'); + + const $result = translated('common:key', { name: $name }); + + const scope = fork(); + + await allSettled(setup, { scope }); + + expect(scope.getState($result)).toBe('valueOne wow'); + + await allSettled(changeLanguageFx, { scope, params: 'en' }); + + expect(scope.getState($result)).toBe('valueTwo wow'); + + await allSettled($name, { scope, params: 'kek' }); + + expect(scope.getState($result)).toBe('valueTwo kek'); + }); }); }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f4f56ff1..14dc7703 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -22,7 +22,7 @@ importers: effector-vue: 23.0.0 estree-walker: ^3.0.3 glob: ^8.0.3 - i18next: 24.0.0 + i18next: 25.0.0 lodash-es: ^4.17.21 markdown: ^0.5.0 playwright: ^1.32.2 @@ -69,7 +69,7 @@ importers: effector-vue: 23.0.0_effector@23.0.0+vue@3.4.35 estree-walker: 3.0.3 glob: 8.1.0 - i18next: 24.0.0_typescript@5.1.6 + i18next: 25.0.0_typescript@5.1.6 markdown: 0.5.0 playwright: 1.32.2 prettier: 2.7.1 @@ -354,22 +354,8 @@ packages: regenerator-runtime: 0.13.11 dev: true - /@babel/runtime/7.21.0: - resolution: {integrity: sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==} - engines: {node: '>=6.9.0'} - dependencies: - regenerator-runtime: 0.13.11 - dev: true - - /@babel/runtime/7.22.15: - resolution: {integrity: sha512-T0O+aa+4w0u06iNmapipJXMV4HoUir03hpx3/YqXXhu9xim3w+dVphjFWl1OH8NbZHw5Lbm9k45drDkgq2VNNA==} - engines: {node: '>=6.9.0'} - dependencies: - regenerator-runtime: 0.14.0 - dev: true - - /@babel/runtime/7.26.7: - resolution: {integrity: sha512-AOPI3D+a8dXnja+iwsUqGRjr1BbZIe771sXdapOtYI531gSqpi92vXivKcq2asu/DFpdl1ceFAKZyRzK2PCVcQ==} + /@babel/runtime/7.27.0: + resolution: {integrity: sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==} engines: {node: '>=6.9.0'} dependencies: regenerator-runtime: 0.14.0 @@ -386,7 +372,7 @@ packages: /@changesets/apply-release-plan/6.0.3: resolution: {integrity: sha512-/3JKqtDefs2YSEQI6JQo43/MKTLfhPdrW/BFmqnRpW8UmPB+YXjjQgfjR/2KOaObLOkoixcL3WCK4wNkn/Krmw==} dependencies: - '@babel/runtime': 7.21.0 + '@babel/runtime': 7.27.0 '@changesets/config': 2.1.0 '@changesets/get-version-range-type': 0.3.2 '@changesets/git': 1.4.1 @@ -404,7 +390,7 @@ packages: /@changesets/assemble-release-plan/5.2.0: resolution: {integrity: sha512-ewY24PEbSec2eKX0+KM7eyENA2hUUp6s4LF9p/iBxTtc+TX2Xbx5rZnlLKZkc8tpuQ3PZbyjLFXWhd1PP6SjCg==} dependencies: - '@babel/runtime': 7.21.0 + '@babel/runtime': 7.27.0 '@changesets/errors': 0.1.4 '@changesets/get-dependents-graph': 1.3.3 '@changesets/types': 5.1.0 @@ -488,7 +474,7 @@ packages: /@changesets/get-release-plan/3.0.12: resolution: {integrity: sha512-TlpEdpxV5ZQmNeHoD6KNKAc01wjRrcu9/CQqzmO4qAlX7ARA4pIuAxd8QZ1AQXv/l4qhHox7SUYH3VLHfarv5w==} dependencies: - '@babel/runtime': 7.21.0 + '@babel/runtime': 7.27.0 '@changesets/assemble-release-plan': 5.2.0 '@changesets/config': 2.1.0 '@changesets/pre': 1.0.12 @@ -504,7 +490,7 @@ packages: /@changesets/git/1.4.1: resolution: {integrity: sha512-GWwRXEqBsQ3nEYcyvY/u2xUK86EKAevSoKV/IhELoZ13caZ1A1TSak/71vyKILtzuLnFPk5mepP5HjBxr7lZ9Q==} dependencies: - '@babel/runtime': 7.21.0 + '@babel/runtime': 7.27.0 '@changesets/errors': 0.1.4 '@changesets/types': 5.1.0 '@manypkg/get-packages': 1.1.3 @@ -528,7 +514,7 @@ packages: /@changesets/pre/1.0.12: resolution: {integrity: sha512-RFzWYBZx56MtgMesXjxx7ymyI829/rcIw/41hvz3VJPnY8mDscN7RJyYu7Xm7vts2Fcd+SRcO0T/Ws3I1/6J7g==} dependencies: - '@babel/runtime': 7.21.0 + '@babel/runtime': 7.27.0 '@changesets/errors': 0.1.4 '@changesets/types': 5.1.0 '@manypkg/get-packages': 1.1.3 @@ -538,7 +524,7 @@ packages: /@changesets/read/0.5.7: resolution: {integrity: sha512-Iteg0ccTPpkJ+qFzY97k7qqdVE5Kz30TqPo9GibpBk2g8tcLFUqf+Qd0iXPLcyhUZpPL1U6Hia1gINHNKIKx4g==} dependencies: - '@babel/runtime': 7.21.0 + '@babel/runtime': 7.27.0 '@changesets/git': 1.4.1 '@changesets/logger': 0.0.5 '@changesets/parse': 0.3.14 @@ -559,7 +545,7 @@ packages: /@changesets/write/0.1.9: resolution: {integrity: sha512-E90ZrsrfJVOOQaP3Mm5Xd7uDwBAqq3z5paVEavTHKA8wxi7NAL8CmjgbGxSFuiP7ubnJA2BuHlrdE4z86voGOg==} dependencies: - '@babel/runtime': 7.21.0 + '@babel/runtime': 7.27.0 '@changesets/types': 5.1.0 fs-extra: 7.0.1 human-id: 1.0.2 @@ -1026,7 +1012,7 @@ packages: /@manypkg/find-root/1.1.0: resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==} dependencies: - '@babel/runtime': 7.21.0 + '@babel/runtime': 7.27.0 '@types/node': 12.20.55 find-up: 4.1.0 fs-extra: 8.1.0 @@ -1035,7 +1021,7 @@ packages: /@manypkg/get-packages/1.1.3: resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==} dependencies: - '@babel/runtime': 7.21.0 + '@babel/runtime': 7.27.0 '@changesets/types': 4.1.0 '@manypkg/find-root': 1.1.0 fs-extra: 8.1.0 @@ -1126,7 +1112,7 @@ packages: /@redux-saga/core/1.2.3: resolution: {integrity: sha512-U1JO6ncFBAklFTwoQ3mjAeQZ6QGutsJzwNBjgVLSWDpZTRhobUzuVDS1qH3SKGJD8fvqoaYOjp6XJ3gCmeZWgA==} dependencies: - '@babel/runtime': 7.22.15 + '@babel/runtime': 7.27.0 '@redux-saga/deferred': 1.2.1 '@redux-saga/delay-p': 1.2.1 '@redux-saga/is': 1.1.3 @@ -2730,15 +2716,15 @@ packages: engines: {node: '>=16.17.0'} dev: true - /i18next/24.0.0_typescript@5.1.6: - resolution: {integrity: sha512-ORGCwMrXxpmB/AljFbGEe0UK/9Pz6umb9aZgLZ9qJGE+kjKhlnLj423WX2mt+N0MlEJ78pQXFMBmeMzrkLxriQ==} + /i18next/25.0.0_typescript@5.1.6: + resolution: {integrity: sha512-POPvwjOPR1GQvRnbikTMPEhQD+ekd186MHE6NtVxl3Lby+gPp0iq60eCqGrY6wfRnp1lejjFNu0EKs1afA322w==} peerDependencies: typescript: ^5 peerDependenciesMeta: typescript: optional: true dependencies: - '@babel/runtime': 7.26.7 + '@babel/runtime': 7.27.0 typescript: 5.1.6 dev: true @@ -3625,7 +3611,7 @@ packages: /redux/4.2.1: resolution: {integrity: sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==} dependencies: - '@babel/runtime': 7.22.15 + '@babel/runtime': 7.27.0 dev: true /redux/5.0.0: