@owlmeans/client-i18n 0.1.16-rc.0 → 0.1.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -63,10 +63,9 @@ Returns a `t()` function for shared/common translations.
63
63
  <!-- owlmeans:agent-guidance:start -->
64
64
  ## Agent guidance
65
65
 
66
- This package ships embedded Claude Code skills and GitHub Copilot instructions under
67
- `agent-meta/`. After installing your `@owlmeans/*` packages, run the OwlMeans
68
- agent-skills installer to place them into your project's native locations
69
- (`.claude/skills/` and `.github/instructions/`):
66
+ This package ships embedded agent skills under `agent-meta/`. After installing your
67
+ `@owlmeans/*` packages, run the OwlMeans agent-skills installer to place them into
68
+ your project's skill store (`.agents/skills/`):
70
69
 
71
70
  ```sh
72
71
  npx @owlmeans/agent-skills
@@ -1,8 +1,8 @@
1
1
  {
2
- "schemaVersion": 1,
2
+ "schemaVersion": 2,
3
3
  "package": "@owlmeans/client-i18n",
4
- "version": "0.1.16-rc.0",
5
- "generatedAt": "2026-08-11T14:02:34.986Z",
4
+ "version": "0.1.17",
5
+ "generatedAt": "2026-08-15T13:01:19.935Z",
6
6
  "canonicalRepo": "https://github.com/owlmeans/common",
7
7
  "entries": [
8
8
  {
@@ -10,14 +10,7 @@
10
10
  "name": "client-i18n",
11
11
  "category": "package-specific",
12
12
  "file": "skills/client-i18n/SKILL.md",
13
- "canonicalPath": ".claude/skills/client-i18n/SKILL.md"
14
- },
15
- {
16
- "kind": "instruction",
17
- "name": "client-i18n",
18
- "category": "package-specific",
19
- "file": "instructions/client-i18n.instructions.md",
20
- "canonicalPath": ".github/instructions/client-i18n.instructions.md"
13
+ "canonicalPath": ".agents/skills/client-i18n/SKILL.md"
21
14
  }
22
15
  ]
23
16
  }
@@ -8,7 +8,7 @@ user-invocable: false
8
8
  # @owlmeans/client-i18n
9
9
 
10
10
  **Layer:** Client (React)
11
- **Install:** `"@owlmeans/client-i18n": "^0.1.16-rc.0"` in `dependencies`
11
+ **Install:** `"@owlmeans/client-i18n": "^0.1.17"` in `dependencies`
12
12
 
13
13
  ## Purpose
14
14
 
@@ -106,6 +106,19 @@ import myErrors from './i18n/en.json' // with { type: 'json' }
106
106
  addI18nApp('en', 'errors', myErrors)
107
107
  ```
108
108
 
109
+ ## Resource JSON format
110
+
111
+ The shared instance runs i18next's **v4** JSON format — `compatibilityJSON` is not set and must
112
+ not be, because i18next >= 26 accepts only `'v4'` and rejects `'v3'` at compile time. Plurals
113
+ therefore use Intl.PluralRules suffixes (`key_one` / `key_other`), never the v3 `key_plural` /
114
+ `key_0` / `key_1` forms. No resource in the ecosystem carries a plural-suffixed key today;
115
+ `{{count}}` in a message is plain interpolation and is unaffected.
116
+
117
+ Keep `i18next` and `react-i18next` in step — `react-i18next@17` requires `i18next >= 26.2.0`, and
118
+ a dependabot bump of one without the other leaves an unmet peer that installs fine and only
119
+ misbehaves at runtime.
120
+
109
121
  ## Depends On
110
122
 
111
- `@owlmeans/i18n`, `@owlmeans/client-context`, `i18next`, `react-i18next`, `react` (peer)
123
+ `@owlmeans/i18n`, `@owlmeans/client-context`, `i18next` (>= 26.2), `react-i18next` (>= 17),
124
+ `react` (peer)
@@ -1 +1 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAA;AAC/B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAElD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAKxC,eAAO,MAAM,WAAW,EAAE,EAAE,CAAC,gBAAgB,CAI3C,CAAA;AAEF,kGAAkG;AAClG,eAAO,MAAM,aAAa,GAAI,SAAS,MAAM,EAAE,QAAQ,MAAM,KAAG,MAK/D,CAAA;AAyCD;4FAC4F;AAC5F,eAAO,MAAM,OAAO,GAAI,UAAU,MAAM,EAAE,KAAK,MAAM,EAAE,SAAS,MAAM,KAAG,SAExE,CAAA;AAED,eAAO,MAAM,UAAU,GAAI,SAAS,MAAM,EAAE,SAAS,MAAM,KAAG,SAE7D,CAAA;AAED,eAAO,MAAM,UAAU,GAAI,UAAU,MAAM,EAAE,SAAS,MAAM,KAAG,SAK9D,CAAA;AAED,eAAO,MAAM,WAAW,QAAO,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAU5D,CAAA"}
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAA;AAC/B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAElD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAKxC,eAAO,MAAM,WAAW,EAAE,EAAE,CAAC,gBAAgB,CAI3C,CAAA;AAEF,kGAAkG;AAClG,eAAO,MAAM,aAAa,YAAa,MAAM,UAAU,MAAM,KAAG,MAK/D,CAAA;AAyCD;4FAC4F;AAC5F,eAAO,MAAM,OAAO,aAAc,MAAM,OAAO,MAAM,WAAW,MAAM,KAAG,SAExE,CAAA;AAED,eAAO,MAAM,UAAU,YAAa,MAAM,WAAW,MAAM,KAAG,SAE7D,CAAA;AAED,eAAO,MAAM,UAAU,aAAc,MAAM,WAAW,MAAM,KAAG,SAK9D,CAAA;AAED,eAAO,MAAM,WAAW,QAAO,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAU5D,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"instance.d.ts","sourceRoot":"","sources":["../../src/utils/instance.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,SAAS,CAAA;AAEnC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAO5D,eAAO,MAAM,eAAe,GAAI,QAAQ,YAAY,KAAG,IAItD,CAAA;AAED,eAAO,MAAM,eAAe,GAAI,QAAQ,YAAY,KAAG,IAC3B,CAAA;AAE5B,eAAO,MAAM,WAAW,GAAI,KAAK,MAAM,KAAG,IAMzC,CAAA"}
1
+ {"version":3,"file":"instance.d.ts","sourceRoot":"","sources":["../../src/utils/instance.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,SAAS,CAAA;AAEnC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAO5D,eAAO,MAAM,eAAe,WAAY,YAAY,KAAG,IAItD,CAAA;AAED,eAAO,MAAM,eAAe,WAAY,YAAY,KAAG,IAC3B,CAAA;AAE5B,eAAO,MAAM,WAAW,QAAS,MAAM,KAAG,IAMzC,CAAA"}
@@ -37,7 +37,10 @@ const createI18nInstance = (config) => {
37
37
  ? persistedLng
38
38
  : fallbackLng;
39
39
  const instance = createInstance({
40
- compatibilityJSON: 'v3',
40
+ // No `compatibilityJSON` — i18next >= 26 accepts only the v4 JSON format
41
+ // (Intl.PluralRules suffixes `_one`/`_other`, not the v3 `_plural`/`_0`/`_1`).
42
+ // No resource in the ecosystem uses plural-suffixed keys; `{{count}}` is plain
43
+ // interpolation, so the v4 default is a no-op here.
41
44
  defaultNS: config.i18n?.defaultNs ?? DEFAULT_NAMESPACE,
42
45
  fallbackLng,
43
46
  lng,
@@ -1 +1 @@
1
- {"version":3,"file":"instance.js","sourceRoot":"","sources":["../../src/utils/instance.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAEhD,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AAE/B,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAE/E,MAAM,eAAe,GAAG,cAAc,CAAA;AAEtC,IAAI,YAAY,GAAgB,IAAI,CAAA;AAEpC,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,MAAoB,EAAQ,EAAE;IAC5D,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,CAAA;IAE9D,OAAO,QAAQ,CAAA;AACjB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,MAAoB,EAAQ,EAAE,CAC5D,kBAAkB,CAAC,MAAM,CAAC,CAAA;AAE5B,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,GAAW,EAAQ,EAAE;IAC/C,IAAI,YAAY,IAAI,IAAI;QAAE,OAAM;IAChC,IAAI,CAAC;QACH,YAAY,CAAC,OAAO,CAAC,eAAe,EAAE,GAAG,CAAC,CAAA;IAC5C,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC,CAAC,sCAAsC,CAAC,CAAC;IACtD,YAAY,CAAC,cAAc,CAAC,GAAG,CAAC,CAAA;AAClC,CAAC,CAAA;AAED,MAAM,oBAAoB,GAAG,GAAkB,EAAE;IAC/C,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,OAAO,CAAC,eAAe,CAAC,CAAA;IAC9C,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC,CAAA;AAED,MAAM,kBAAkB,GAAG,CAAC,MAAoB,EAAQ,EAAE;IACxD,IAAI,YAAY,IAAI,IAAI,EAAE,CAAC;QACzB,OAAO,YAAY,CAAA;IACrB,CAAC;IAED,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,EAAE,WAAW,IAAI,MAAM,CAAC,IAAI,EAAE,UAAU,IAAI,WAAW,CAAA;IACtF,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,EAAE,aAAa,IAAI,CAAC,GAAG,cAAc,CAAC,CAAA;IACvE,MAAM,YAAY,GAAG,oBAAoB,EAAE,CAAA;IAC3C,MAAM,GAAG,GAAG,YAAY,IAAI,IAAI,IAAI,aAAa,CAAC,QAAQ,CAAC,YAAY,CAAC;QACtE,CAAC,CAAC,YAAY;QACd,CAAC,CAAC,WAAW,CAAA;IAEf,MAAM,QAAQ,GAAG,cAAc,CAAC;QAC9B,iBAAiB,EAAE,IAAI;QACvB,SAAS,EAAE,MAAM,CAAC,IAAI,EAAE,SAAS,IAAI,iBAAiB;QACtD,WAAW;QACX,GAAG;QACH,aAAa;QACb,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,GAAG,IAAI,MAAM,CAAC,KAAK,EAAE,IAAI,IAAI,KAAK;KACxD,CAAC,CAAA;IAEF,QAAQ,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,IAAI,EAAE,CAAA;IAErC,OAAO,YAAY,GAAG,QAAQ,CAAA;AAChC,CAAC,CAAA"}
1
+ {"version":3,"file":"instance.js","sourceRoot":"","sources":["../../src/utils/instance.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAEhD,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AAE/B,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAE/E,MAAM,eAAe,GAAG,cAAc,CAAA;AAEtC,IAAI,YAAY,GAAgB,IAAI,CAAA;AAEpC,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,MAAoB,EAAQ,EAAE;IAC5D,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,CAAA;IAE9D,OAAO,QAAQ,CAAA;AACjB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,MAAoB,EAAQ,EAAE,CAC5D,kBAAkB,CAAC,MAAM,CAAC,CAAA;AAE5B,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,GAAW,EAAQ,EAAE;IAC/C,IAAI,YAAY,IAAI,IAAI;QAAE,OAAM;IAChC,IAAI,CAAC;QACH,YAAY,CAAC,OAAO,CAAC,eAAe,EAAE,GAAG,CAAC,CAAA;IAC5C,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC,CAAC,sCAAsC,CAAC,CAAC;IACtD,YAAY,CAAC,cAAc,CAAC,GAAG,CAAC,CAAA;AAClC,CAAC,CAAA;AAED,MAAM,oBAAoB,GAAG,GAAkB,EAAE;IAC/C,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,OAAO,CAAC,eAAe,CAAC,CAAA;IAC9C,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC,CAAA;AAED,MAAM,kBAAkB,GAAG,CAAC,MAAoB,EAAQ,EAAE;IACxD,IAAI,YAAY,IAAI,IAAI,EAAE,CAAC;QACzB,OAAO,YAAY,CAAA;IACrB,CAAC;IAED,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,EAAE,WAAW,IAAI,MAAM,CAAC,IAAI,EAAE,UAAU,IAAI,WAAW,CAAA;IACtF,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,EAAE,aAAa,IAAI,CAAC,GAAG,cAAc,CAAC,CAAA;IACvE,MAAM,YAAY,GAAG,oBAAoB,EAAE,CAAA;IAC3C,MAAM,GAAG,GAAG,YAAY,IAAI,IAAI,IAAI,aAAa,CAAC,QAAQ,CAAC,YAAY,CAAC;QACtE,CAAC,CAAC,YAAY;QACd,CAAC,CAAC,WAAW,CAAA;IAEf,MAAM,QAAQ,GAAG,cAAc,CAAC;QAC9B,yEAAyE;QACzE,+EAA+E;QAC/E,+EAA+E;QAC/E,oDAAoD;QACpD,SAAS,EAAE,MAAM,CAAC,IAAI,EAAE,SAAS,IAAI,iBAAiB;QACtD,WAAW;QACX,GAAG;QACH,aAAa;QACb,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,GAAG,IAAI,MAAM,CAAC,KAAK,EAAE,IAAI,IAAI,KAAK;KACxD,CAAC,CAAA;IAEF,QAAQ,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,IAAI,EAAE,CAAA;IAErC,OAAO,YAAY,GAAG,QAAQ,CAAA;AAChC,CAAC,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@owlmeans/client-i18n",
3
- "version": "0.1.16-rc.0",
3
+ "version": "0.1.17",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -34,14 +34,14 @@
34
34
  "@owlmeans/dep-config": "workspace:*",
35
35
  "@types/react": "^19.2.17",
36
36
  "nodemon": "^3.1.14",
37
- "typescript": "^6.0.3"
37
+ "typescript": "^7.0.2"
38
38
  },
39
39
  "dependencies": {
40
- "@owlmeans/client": "^0.1.16-rc.0",
41
- "@owlmeans/client-context": "^0.1.16-rc.0",
42
- "@owlmeans/i18n": "^0.1.16-rc.0",
43
- "i18next": "^23.15.1",
44
- "react-i18next": "^15.0.2"
40
+ "@owlmeans/client": "^0.1.17",
41
+ "@owlmeans/client-context": "^0.1.17",
42
+ "@owlmeans/i18n": "^0.1.17",
43
+ "i18next": "^26.2.0",
44
+ "react-i18next": "^17.0.11"
45
45
  },
46
46
  "publishConfig": {
47
47
  "access": "public"
@@ -48,7 +48,10 @@ const createI18nInstance = (config: ClientConfig): i18n => {
48
48
  : fallbackLng
49
49
 
50
50
  const instance = createInstance({
51
- compatibilityJSON: 'v3',
51
+ // No `compatibilityJSON` — i18next >= 26 accepts only the v4 JSON format
52
+ // (Intl.PluralRules suffixes `_one`/`_other`, not the v3 `_plural`/`_0`/`_1`).
53
+ // No resource in the ecosystem uses plural-suffixed keys; `{{count}}` is plain
54
+ // interpolation, so the v4 default is a no-op here.
52
55
  defaultNS: config.i18n?.defaultNs ?? DEFAULT_NAMESPACE,
53
56
  fallbackLng,
54
57
  lng,
@@ -1,54 +0,0 @@
1
- ---
2
- description: "How to use @owlmeans/client-i18n — React i18next wrapper with lazy bundle loading and language persistence. Use when setting up i18n in a React app or adding translation hooks."
3
- applyTo: "**/*.ts, **/*.tsx"
4
- ---
5
- <!-- AUTO-GENERATED — do not edit. Regenerate via sync-agent-meta. -->
6
-
7
- # @owlmeans/client-i18n
8
-
9
- **Layer:** Client (React)
10
- **Version:** `"@owlmeans/client-i18n": "^0.1.16-rc.0"`
11
-
12
- ## Key exports
13
-
14
- | Export | Description |
15
- |--------|-------------|
16
- | `I18nContext` | Provider — wraps the app tree |
17
- | `useI18nLib(resource, prefix?)` | Hook for library strings (ns=`'lib'`) |
18
- | `useI18nApp(resource?, prefix?)` | Hook for app strings (ns=resource name) |
19
- | `useI18n(resource, ns?, prefix?)` | Low-level explicit hook |
20
- | `useLanguage()` | `[lng, setLng]` — read/switch active language |
21
- | `composePrefix(parent?, child?)` | Dot-join for prefix segments |
22
- | `I18nProps`, `I18nBaseProps` | Prop types for i18n overrides |
23
-
24
- ## Setup
25
-
26
- ```tsx
27
- import { I18nContext } from '@owlmeans/client-i18n'
28
- <I18nContext config={clientConfig}><App /></I18nContext>
29
- ```
30
-
31
- ## Translation hooks
32
-
33
- ```typescript
34
- // Library component
35
- const t = useI18nLib('errors', 'form') // lib:errors.form.*
36
- t('minLength')
37
-
38
- // App component
39
- const t = useI18nApp(undefined, 'home') // appName:appName.home.*
40
- t('title')
41
-
42
- // Language switcher
43
- const [lng, setLng] = useLanguage()
44
- ```
45
-
46
- ## Key invariants
47
-
48
- - Use `useI18nLib` in `@owlmeans/*` packages, `useI18nApp` in app/project packages.
49
- - Never hardcode UI strings — always use a translation hook.
50
- - Language is persisted in `localStorage` under `owlmeans-lng`.
51
-
52
- ## Depends On
53
-
54
- `@owlmeans/i18n`, `@owlmeans/client-context`, `i18next`, `react-i18next`, `react` (peer)