@gabrielbourget/i18n-foundation 0.1.0
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 +159 -0
- package/dist/assets/index.d.ts +35 -0
- package/dist/assets/index.d.ts.map +1 -0
- package/dist/assets/index.js +102 -0
- package/dist/common/index.d.ts +18 -0
- package/dist/common/index.d.ts.map +1 -0
- package/dist/common/index.js +27 -0
- package/dist/core/client.d.ts +22 -0
- package/dist/core/client.d.ts.map +1 -0
- package/dist/core/client.js +89 -0
- package/dist/core/configuration.d.ts +18 -0
- package/dist/core/configuration.d.ts.map +1 -0
- package/dist/core/configuration.js +36 -0
- package/dist/core/createIsolatedI18nInstance.d.ts +13 -0
- package/dist/core/createIsolatedI18nInstance.d.ts.map +1 -0
- package/dist/core/createIsolatedI18nInstance.js +16 -0
- package/dist/core/i18nStrictMode.d.ts +11 -0
- package/dist/core/i18nStrictMode.d.ts.map +1 -0
- package/dist/core/i18nStrictMode.js +19 -0
- package/dist/core/index.d.ts +7 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +6 -0
- package/dist/core/initCommon.d.ts +15 -0
- package/dist/core/initCommon.d.ts.map +1 -0
- package/dist/core/initCommon.js +51 -0
- package/dist/core/resourceLoader.d.ts +9 -0
- package/dist/core/resourceLoader.d.ts.map +1 -0
- package/dist/core/resourceLoader.js +56 -0
- package/dist/core/server.d.ts +21 -0
- package/dist/core/server.d.ts.map +1 -0
- package/dist/core/server.js +20 -0
- package/dist/core/types.d.ts +20 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +1 -0
- package/dist/env/client.d.ts +29 -0
- package/dist/env/client.d.ts.map +1 -0
- package/dist/env/client.js +42 -0
- package/dist/env/index.d.ts +4 -0
- package/dist/env/index.d.ts.map +1 -0
- package/dist/env/index.js +3 -0
- package/dist/env/server.d.ts +30 -0
- package/dist/env/server.d.ts.map +1 -0
- package/dist/env/server.js +45 -0
- package/dist/env/utils.d.ts +23 -0
- package/dist/env/utils.d.ts.map +1 -0
- package/dist/env/utils.js +65 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/manifest/index.d.ts +37 -0
- package/dist/manifest/index.d.ts.map +1 -0
- package/dist/manifest/index.js +46 -0
- package/dist/pseudolocalization/index.d.ts +89 -0
- package/dist/pseudolocalization/index.d.ts.map +1 -0
- package/dist/pseudolocalization/index.js +182 -0
- package/dist/verifier/domainContracts.d.ts +43 -0
- package/dist/verifier/domainContracts.d.ts.map +1 -0
- package/dist/verifier/domainContracts.js +324 -0
- package/dist/verifier/fileSystem.d.ts +9 -0
- package/dist/verifier/fileSystem.d.ts.map +1 -0
- package/dist/verifier/fileSystem.js +42 -0
- package/dist/verifier/icuContracts.d.ts +13 -0
- package/dist/verifier/icuContracts.d.ts.map +1 -0
- package/dist/verifier/icuContracts.js +109 -0
- package/dist/verifier/index.d.ts +7 -0
- package/dist/verifier/index.d.ts.map +1 -0
- package/dist/verifier/index.js +6 -0
- package/dist/verifier/keyShape.d.ts +12 -0
- package/dist/verifier/keyShape.d.ts.map +1 -0
- package/dist/verifier/keyShape.js +73 -0
- package/dist/verifier/sheetOrdering.d.ts +2 -0
- package/dist/verifier/sheetOrdering.d.ts.map +1 -0
- package/dist/verifier/sheetOrdering.js +161 -0
- package/dist/verifier/verifyI18nSource.d.ts +25 -0
- package/dist/verifier/verifyI18nSource.d.ts.map +1 -0
- package/dist/verifier/verifyI18nSource.js +162 -0
- package/locales/en/common--carousel.json +30 -0
- package/locales/en/common--delete-entity-modal.json +15 -0
- package/locales/en/common--file-upload.json +88 -0
- package/locales/en/common--form-rules.json +12 -0
- package/locales/en/common--form-validation.json +19 -0
- package/locales/en/common--pagination.json +36 -0
- package/locales/en/common--saved-views.json +37 -0
- package/locales/en/common--searching.json +14 -0
- package/locales/en/common--sort-and-filter-panel.json +135 -0
- package/locales/en/common--theme.json +9 -0
- package/locales/en/common--ui.json +52 -0
- package/locales/fr/common--carousel.json +30 -0
- package/locales/fr/common--delete-entity-modal.json +15 -0
- package/locales/fr/common--file-upload.json +88 -0
- package/locales/fr/common--form-rules.json +12 -0
- package/locales/fr/common--form-validation.json +19 -0
- package/locales/fr/common--pagination.json +36 -0
- package/locales/fr/common--saved-views.json +37 -0
- package/locales/fr/common--searching.json +14 -0
- package/locales/fr/common--sort-and-filter-panel.json +135 -0
- package/locales/fr/common--theme.json +9 -0
- package/locales/fr/common--ui.json +52 -0
- package/package.json +103 -0
package/README.md
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# i18n Foundation
|
|
2
|
+
|
|
3
|
+
Shared i18n runtime foundation for the Wavemap and Waveguide app-owned i18n
|
|
4
|
+
facade packages.
|
|
5
|
+
|
|
6
|
+
This package is intentionally not an application-facing API. Application code
|
|
7
|
+
should import from `@wavemap/i18n` or `@waveguide/i18n`; those facades own app
|
|
8
|
+
locale registries, namespace lists, generated assets, and product vocabulary.
|
|
9
|
+
|
|
10
|
+
## First Extraction Boundary
|
|
11
|
+
|
|
12
|
+
Included first:
|
|
13
|
+
|
|
14
|
+
- Shared `common--*` namespace content that has been promoted into the
|
|
15
|
+
foundation package.
|
|
16
|
+
- Core i18next runtime factories.
|
|
17
|
+
- Pseudolocalization helpers.
|
|
18
|
+
- Environment parsing primitives.
|
|
19
|
+
- Manifest helpers.
|
|
20
|
+
- Generated asset helpers.
|
|
21
|
+
- Source verification helpers.
|
|
22
|
+
|
|
23
|
+
Excluded first:
|
|
24
|
+
|
|
25
|
+
- App-owned `common--*` namespace content.
|
|
26
|
+
- `page--*` namespace content.
|
|
27
|
+
- `wavemap--*` and `waveguide--*` namespace content.
|
|
28
|
+
- Email i18n utilities.
|
|
29
|
+
- CDN publish and prune scripts.
|
|
30
|
+
|
|
31
|
+
## Published Name
|
|
32
|
+
|
|
33
|
+
The intended private npm package name is:
|
|
34
|
+
|
|
35
|
+
```text
|
|
36
|
+
@gabrielbourget/i18n-foundation
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
The package omits `"private": true` so it can be published, and sets
|
|
40
|
+
`publishConfig.access` to `restricted` so npm publishes it as a private scoped
|
|
41
|
+
package.
|
|
42
|
+
|
|
43
|
+
## Export Surface
|
|
44
|
+
|
|
45
|
+
```text
|
|
46
|
+
@gabrielbourget/i18n-foundation
|
|
47
|
+
@gabrielbourget/i18n-foundation/common
|
|
48
|
+
@gabrielbourget/i18n-foundation/core
|
|
49
|
+
@gabrielbourget/i18n-foundation/core/client
|
|
50
|
+
@gabrielbourget/i18n-foundation/core/server
|
|
51
|
+
@gabrielbourget/i18n-foundation/env
|
|
52
|
+
@gabrielbourget/i18n-foundation/env/client
|
|
53
|
+
@gabrielbourget/i18n-foundation/env/server
|
|
54
|
+
@gabrielbourget/i18n-foundation/manifest
|
|
55
|
+
@gabrielbourget/i18n-foundation/pseudolocalization
|
|
56
|
+
@gabrielbourget/i18n-foundation/assets
|
|
57
|
+
@gabrielbourget/i18n-foundation/verifier
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Foundation-Owned Common Namespaces
|
|
61
|
+
|
|
62
|
+
These namespaces and their locale JSON files are owned by this package:
|
|
63
|
+
|
|
64
|
+
```text
|
|
65
|
+
common--carousel
|
|
66
|
+
common--delete-entity-modal
|
|
67
|
+
common--file-upload
|
|
68
|
+
common--form-rules
|
|
69
|
+
common--form-validation
|
|
70
|
+
common--pagination
|
|
71
|
+
common--saved-views
|
|
72
|
+
common--searching
|
|
73
|
+
common--sort-and-filter-panel
|
|
74
|
+
common--theme
|
|
75
|
+
common--ui
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
These common namespaces remain app-facade owned:
|
|
79
|
+
|
|
80
|
+
```text
|
|
81
|
+
common--entities
|
|
82
|
+
common--external-institutions
|
|
83
|
+
common--nav-panel
|
|
84
|
+
common--navbar
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Facade asset generation should treat each namespace as having exactly one
|
|
88
|
+
source root. Do not overlay foundation and app-owned JSON for the same
|
|
89
|
+
namespace.
|
|
90
|
+
|
|
91
|
+
## Facade Usage Shape
|
|
92
|
+
|
|
93
|
+
The app facade owns all app-specific registry values:
|
|
94
|
+
|
|
95
|
+
```ts
|
|
96
|
+
import {
|
|
97
|
+
buildClientRuntimeConfig,
|
|
98
|
+
createI18nClientEnvReader,
|
|
99
|
+
createI18nProvider,
|
|
100
|
+
validateDevManifest,
|
|
101
|
+
} from "@gabrielbourget/i18n-foundation"
|
|
102
|
+
|
|
103
|
+
const registry = {
|
|
104
|
+
defaultLocale: DEFAULT_LOCALE,
|
|
105
|
+
availableLocales: DECLARED_LOCALES,
|
|
106
|
+
availableNamespaces: AVAILABLE_NAMESPACES,
|
|
107
|
+
initialLoadNamespaces: INITIAL_LOAD_NAMESPACES,
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const clientEnvReader = createI18nClientEnvReader({
|
|
111
|
+
config: {
|
|
112
|
+
declaredLocales: DECLARED_LOCALES,
|
|
113
|
+
defaultLocale: DEFAULT_LOCALE,
|
|
114
|
+
i18nVersion: I18N_VERSION,
|
|
115
|
+
},
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
export const I18nProvider = createI18nProvider({
|
|
119
|
+
registry,
|
|
120
|
+
getRuntimeConfig: () => buildClientRuntimeConfig(clientEnvReader.get()),
|
|
121
|
+
validateManifest: validateDevManifest,
|
|
122
|
+
})
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
The facade should continue to export app-owned constants, resource maps, and
|
|
126
|
+
script entrypoints. Application code should keep importing the facade package.
|
|
127
|
+
|
|
128
|
+
## Asset And Verifier Usage Shape
|
|
129
|
+
|
|
130
|
+
Facade scripts should pass explicit app paths and registries into foundation
|
|
131
|
+
helpers:
|
|
132
|
+
|
|
133
|
+
```ts
|
|
134
|
+
import { buildI18nManifest, generateI18nAssets, verifyI18nSource } from "@gabrielbourget/i18n-foundation"
|
|
135
|
+
|
|
136
|
+
const manifest = buildI18nManifest({
|
|
137
|
+
defaultLocale: DEFAULT_LOCALE,
|
|
138
|
+
locales: DECLARED_LOCALES,
|
|
139
|
+
namespaces: AVAILABLE_NAMESPACES,
|
|
140
|
+
version: I18N_VERSION,
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
generateI18nAssets({
|
|
144
|
+
localesRoot,
|
|
145
|
+
outputRoot,
|
|
146
|
+
manifest,
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
await verifyI18nSource({
|
|
150
|
+
localesRoot,
|
|
151
|
+
availableNamespaces: AVAILABLE_NAMESPACES,
|
|
152
|
+
declaredLocales: DECLARED_LOCALES,
|
|
153
|
+
defaultLocale: DEFAULT_LOCALE,
|
|
154
|
+
initialLoadNamespaces: INITIAL_LOAD_NAMESPACES,
|
|
155
|
+
repoRoot,
|
|
156
|
+
domainTranslationContracts,
|
|
157
|
+
domainSeedSourceContracts,
|
|
158
|
+
})
|
|
159
|
+
```
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { TI18nManifest } from "../manifest/index.js";
|
|
2
|
+
export type TGeneratedI18nAsset<Locale extends string = string, Namespace extends string = string> = {
|
|
3
|
+
locale: Locale;
|
|
4
|
+
namespace: Namespace;
|
|
5
|
+
sourcePath: string;
|
|
6
|
+
outputPath: string;
|
|
7
|
+
};
|
|
8
|
+
export type TGenerateI18nAssetsArgs<Locale extends string, Namespace extends string> = {
|
|
9
|
+
localesRoot: string;
|
|
10
|
+
outputRoot: string;
|
|
11
|
+
manifest: TI18nManifest<Locale, Namespace>;
|
|
12
|
+
cleanOutputRoot?: boolean | undefined;
|
|
13
|
+
};
|
|
14
|
+
export type TGenerateI18nAssetsResult<Locale extends string, Namespace extends string> = {
|
|
15
|
+
outputRoot: string;
|
|
16
|
+
manifestPath: string;
|
|
17
|
+
assets: readonly TGeneratedI18nAsset<Locale, Namespace>[];
|
|
18
|
+
};
|
|
19
|
+
export type TValidateGeneratedI18nAssetsArgs<Locale extends string, Namespace extends string> = {
|
|
20
|
+
localesRoot: string;
|
|
21
|
+
generatedRoot: string;
|
|
22
|
+
manifest: TI18nManifest<Locale, Namespace>;
|
|
23
|
+
};
|
|
24
|
+
export declare const readUTF8: (filePath: string) => string;
|
|
25
|
+
export declare const writeUTF8: (filePath: string, value: string) => void;
|
|
26
|
+
export declare const readJSONFile: (filePath: string) => unknown;
|
|
27
|
+
export declare const writeJSONFile: (filePath: string, value: unknown) => void;
|
|
28
|
+
export declare const listDirectoryNames: (directoryPath: string) => string[];
|
|
29
|
+
export declare const listJSONFileNames: (directoryPath: string) => string[];
|
|
30
|
+
export declare const assertEqualArrays: (label: string, expected: readonly string[], actual: readonly string[]) => void;
|
|
31
|
+
export declare const ensureDirectory: (directoryPath: string) => void;
|
|
32
|
+
export declare const removeDirectoryIfExists: (directoryPath: string) => void;
|
|
33
|
+
export declare const generateI18nAssets: <Locale extends string, Namespace extends string>({ localesRoot, outputRoot, manifest, cleanOutputRoot, }: TGenerateI18nAssetsArgs<Locale, Namespace>) => TGenerateI18nAssetsResult<Locale, Namespace>;
|
|
34
|
+
export declare const validateGeneratedI18nAssets: <Locale extends string, Namespace extends string>({ localesRoot, generatedRoot, manifest, }: TValidateGeneratedI18nAssetsArgs<Locale, Namespace>) => void;
|
|
35
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/assets/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAEzD,MAAM,MAAM,mBAAmB,CAAC,MAAM,SAAS,MAAM,GAAG,MAAM,EAAE,SAAS,SAAS,MAAM,GAAG,MAAM,IAAI;IACnG,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,SAAS,CAAA;IACpB,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;CACnB,CAAA;AAED,MAAM,MAAM,uBAAuB,CAAC,MAAM,SAAS,MAAM,EAAE,SAAS,SAAS,MAAM,IAAI;IACrF,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,aAAa,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IAC1C,eAAe,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;CACtC,CAAA;AAED,MAAM,MAAM,yBAAyB,CAAC,MAAM,SAAS,MAAM,EAAE,SAAS,SAAS,MAAM,IAAI;IACvF,UAAU,EAAE,MAAM,CAAA;IAClB,YAAY,EAAE,MAAM,CAAA;IACpB,MAAM,EAAE,SAAS,mBAAmB,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE,CAAA;CAC1D,CAAA;AAED,MAAM,MAAM,gCAAgC,CAAC,MAAM,SAAS,MAAM,EAAE,SAAS,SAAS,MAAM,IAAI;IAC9F,WAAW,EAAE,MAAM,CAAA;IACnB,aAAa,EAAE,MAAM,CAAA;IACrB,QAAQ,EAAE,aAAa,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;CAC3C,CAAA;AAED,eAAO,MAAM,QAAQ,GAAI,UAAU,MAAM,KAAG,MAA2C,CAAA;AAEvF,eAAO,MAAM,SAAS,GAAI,UAAU,MAAM,EAAE,OAAO,MAAM,KAAG,IAE3D,CAAA;AAED,eAAO,MAAM,YAAY,GAAI,UAAU,MAAM,KAAG,OAQ/C,CAAA;AAED,eAAO,MAAM,aAAa,GAAI,UAAU,MAAM,EAAE,OAAO,OAAO,KAAG,IAEhE,CAAA;AAED,eAAO,MAAM,kBAAkB,GAAI,eAAe,MAAM,KAAG,MAAM,EAMhE,CAAA;AAED,eAAO,MAAM,iBAAiB,GAAI,eAAe,MAAM,KAAG,MAAM,EAM/D,CAAA;AAED,eAAO,MAAM,iBAAiB,GAAI,OAAO,MAAM,EAAE,UAAU,SAAS,MAAM,EAAE,EAAE,QAAQ,SAAS,MAAM,EAAE,KAAG,IAOzG,CAAA;AAED,eAAO,MAAM,eAAe,GAAI,eAAe,MAAM,KAAG,IAEvD,CAAA;AAED,eAAO,MAAM,uBAAuB,GAAI,eAAe,MAAM,KAAG,IAE/D,CAAA;AAWD,eAAO,MAAM,kBAAkB,GAAI,MAAM,SAAS,MAAM,EAAE,SAAS,SAAS,MAAM,EAAE,yDAKjF,uBAAuB,CAAC,MAAM,EAAE,SAAS,CAAC,KAAG,yBAAyB,CAAC,MAAM,EAAE,SAAS,CAgC1F,CAAA;AAED,eAAO,MAAM,2BAA2B,GAAI,MAAM,SAAS,MAAM,EAAE,SAAS,SAAS,MAAM,EAAE,2CAI1F,gCAAgC,CAAC,MAAM,EAAE,SAAS,CAAC,KAAG,IA0CxD,CAAA"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
export const readUTF8 = (filePath) => fs.readFileSync(filePath, "utf8");
|
|
4
|
+
export const writeUTF8 = (filePath, value) => {
|
|
5
|
+
fs.writeFileSync(filePath, value, "utf8");
|
|
6
|
+
};
|
|
7
|
+
export const readJSONFile = (filePath) => {
|
|
8
|
+
try {
|
|
9
|
+
return JSON.parse(readUTF8(filePath));
|
|
10
|
+
}
|
|
11
|
+
catch (error) {
|
|
12
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
13
|
+
throw new Error(`${filePath} is not valid JSON: ${message}`);
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
export const writeJSONFile = (filePath, value) => {
|
|
17
|
+
writeUTF8(filePath, `${JSON.stringify(value, null, 2)}\n`);
|
|
18
|
+
};
|
|
19
|
+
export const listDirectoryNames = (directoryPath) => {
|
|
20
|
+
return fs
|
|
21
|
+
.readdirSync(directoryPath, { withFileTypes: true })
|
|
22
|
+
.filter((entry) => entry.isDirectory())
|
|
23
|
+
.map((entry) => entry.name)
|
|
24
|
+
.sort((left, right) => left.localeCompare(right));
|
|
25
|
+
};
|
|
26
|
+
export const listJSONFileNames = (directoryPath) => {
|
|
27
|
+
return fs
|
|
28
|
+
.readdirSync(directoryPath, { withFileTypes: true })
|
|
29
|
+
.filter((entry) => entry.isFile() && entry.name.endsWith(".json"))
|
|
30
|
+
.map((entry) => entry.name)
|
|
31
|
+
.sort((left, right) => left.localeCompare(right));
|
|
32
|
+
};
|
|
33
|
+
export const assertEqualArrays = (label, expected, actual) => {
|
|
34
|
+
const expectedKey = JSON.stringify(expected);
|
|
35
|
+
const actualKey = JSON.stringify(actual);
|
|
36
|
+
if (expectedKey !== actualKey) {
|
|
37
|
+
throw new Error(`${label} mismatch\nexpected: ${expectedKey}\nactual: ${actualKey}`);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
export const ensureDirectory = (directoryPath) => {
|
|
41
|
+
fs.mkdirSync(directoryPath, { recursive: true });
|
|
42
|
+
};
|
|
43
|
+
export const removeDirectoryIfExists = (directoryPath) => {
|
|
44
|
+
fs.rmSync(directoryPath, { recursive: true, force: true });
|
|
45
|
+
};
|
|
46
|
+
const assertFileContentMatches = (label, expectedPath, actualPath) => {
|
|
47
|
+
const expected = readUTF8(expectedPath);
|
|
48
|
+
const actual = readUTF8(actualPath);
|
|
49
|
+
if (actual !== expected) {
|
|
50
|
+
throw new Error(`${label} does not match source file.\nsource: ${expectedPath}\nasset: ${actualPath}`);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
export const generateI18nAssets = ({ localesRoot, outputRoot, manifest, cleanOutputRoot = true, }) => {
|
|
54
|
+
if (cleanOutputRoot) {
|
|
55
|
+
removeDirectoryIfExists(outputRoot);
|
|
56
|
+
}
|
|
57
|
+
ensureDirectory(outputRoot);
|
|
58
|
+
const assets = [];
|
|
59
|
+
for (const locale of manifest.locales) {
|
|
60
|
+
const localeOutputPath = path.join(outputRoot, locale);
|
|
61
|
+
ensureDirectory(localeOutputPath);
|
|
62
|
+
for (const namespace of manifest.namespaces) {
|
|
63
|
+
const sourcePath = path.join(localesRoot, locale, `${namespace}.json`);
|
|
64
|
+
const outputPath = path.join(localeOutputPath, `${namespace}.json`);
|
|
65
|
+
readJSONFile(sourcePath);
|
|
66
|
+
writeUTF8(outputPath, readUTF8(sourcePath));
|
|
67
|
+
assets.push({ locale, namespace, outputPath, sourcePath });
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
const manifestPath = path.join(outputRoot, "manifest.json");
|
|
71
|
+
writeJSONFile(manifestPath, manifest);
|
|
72
|
+
return {
|
|
73
|
+
assets,
|
|
74
|
+
manifestPath,
|
|
75
|
+
outputRoot,
|
|
76
|
+
};
|
|
77
|
+
};
|
|
78
|
+
export const validateGeneratedI18nAssets = ({ localesRoot, generatedRoot, manifest, }) => {
|
|
79
|
+
const manifestPath = path.join(generatedRoot, "manifest.json");
|
|
80
|
+
if (!fs.existsSync(generatedRoot))
|
|
81
|
+
throw new Error(`[i18n assets] Generated root not found: ${generatedRoot}`);
|
|
82
|
+
if (!fs.existsSync(manifestPath))
|
|
83
|
+
throw new Error(`[i18n assets] Manifest not found: ${manifestPath}`);
|
|
84
|
+
const generatedManifest = readJSONFile(manifestPath);
|
|
85
|
+
if (generatedManifest.version !== manifest.version) {
|
|
86
|
+
throw new Error(`[i18n assets] Manifest version mismatch. expected=${manifest.version}, actual=${generatedManifest.version}`);
|
|
87
|
+
}
|
|
88
|
+
if (generatedManifest.defaultLocale !== manifest.defaultLocale) {
|
|
89
|
+
throw new Error(`[i18n assets] Manifest defaultLocale mismatch. expected=${manifest.defaultLocale}, actual=${generatedManifest.defaultLocale}`);
|
|
90
|
+
}
|
|
91
|
+
assertEqualArrays("[i18n assets] manifest.locales", manifest.locales, generatedManifest.locales);
|
|
92
|
+
assertEqualArrays("[i18n assets] manifest.namespaces", manifest.namespaces, generatedManifest.namespaces);
|
|
93
|
+
assertEqualArrays("[i18n assets] generated locale folders", manifest.locales, listDirectoryNames(generatedRoot));
|
|
94
|
+
for (const locale of manifest.locales) {
|
|
95
|
+
const generatedLocalePath = path.join(generatedRoot, locale);
|
|
96
|
+
const expectedFileNames = manifest.namespaces.map((namespace) => `${namespace}.json`);
|
|
97
|
+
assertEqualArrays(`[i18n assets] generated namespace files for ${locale}`, expectedFileNames, listJSONFileNames(generatedLocalePath));
|
|
98
|
+
for (const namespace of manifest.namespaces) {
|
|
99
|
+
assertFileContentMatches(`[i18n assets] ${locale}/${namespace}.json`, path.join(localesRoot, locale, `${namespace}.json`), path.join(generatedLocalePath, `${namespace}.json`));
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export declare const FOUNDATION_COMMON_LOCALE__EN: "en";
|
|
2
|
+
export declare const FOUNDATION_COMMON_LOCALE__FR: "fr";
|
|
3
|
+
export declare const FOUNDATION_COMMON_LOCALES: readonly ["en", "fr"];
|
|
4
|
+
export declare const NAMESPACE__COMMON__CAROUSEL: "common--carousel";
|
|
5
|
+
export declare const NAMESPACE__COMMON__DELETE_ENTITY_MODAL: "common--delete-entity-modal";
|
|
6
|
+
export declare const NAMESPACE__COMMON__FILE_UPLOAD: "common--file-upload";
|
|
7
|
+
export declare const NAMESPACE__COMMON__FORM_RULES: "common--form-rules";
|
|
8
|
+
export declare const NAMESPACE__COMMON__FORM_VALIDATION: "common--form-validation";
|
|
9
|
+
export declare const NAMESPACE__COMMON__PAGINATION: "common--pagination";
|
|
10
|
+
export declare const NAMESPACE__COMMON__SAVED_VIEWS: "common--saved-views";
|
|
11
|
+
export declare const NAMESPACE__COMMON__SEARCHING: "common--searching";
|
|
12
|
+
export declare const NAMESPACE__COMMON__SORT_AND_FILTER_PANEL: "common--sort-and-filter-panel";
|
|
13
|
+
export declare const NAMESPACE__COMMON__THEME: "common--theme";
|
|
14
|
+
export declare const NAMESPACE__COMMON__UI: "common--ui";
|
|
15
|
+
export declare const FOUNDATION_COMMON_NAMESPACES: readonly ["common--carousel", "common--delete-entity-modal", "common--file-upload", "common--form-rules", "common--form-validation", "common--pagination", "common--saved-views", "common--searching", "common--sort-and-filter-panel", "common--theme", "common--ui"];
|
|
16
|
+
export type TFoundationCommonLocale = (typeof FOUNDATION_COMMON_LOCALES)[number];
|
|
17
|
+
export type TFoundationCommonNamespace = (typeof FOUNDATION_COMMON_NAMESPACES)[number];
|
|
18
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/common/index.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,4BAA4B,EAAG,IAAa,CAAA;AACzD,eAAO,MAAM,4BAA4B,EAAG,IAAa,CAAA;AAEzD,eAAO,MAAM,yBAAyB,uBAAwE,CAAA;AAE9G,eAAO,MAAM,2BAA2B,EAAG,kBAA2B,CAAA;AACtE,eAAO,MAAM,sCAAsC,EAAG,6BAAsC,CAAA;AAC5F,eAAO,MAAM,8BAA8B,EAAG,qBAA8B,CAAA;AAC5E,eAAO,MAAM,6BAA6B,EAAG,oBAA6B,CAAA;AAC1E,eAAO,MAAM,kCAAkC,EAAG,yBAAkC,CAAA;AACpF,eAAO,MAAM,6BAA6B,EAAG,oBAA6B,CAAA;AAC1E,eAAO,MAAM,8BAA8B,EAAG,qBAA8B,CAAA;AAC5E,eAAO,MAAM,4BAA4B,EAAG,mBAA4B,CAAA;AACxE,eAAO,MAAM,wCAAwC,EAAG,+BAAwC,CAAA;AAChG,eAAO,MAAM,wBAAwB,EAAG,eAAwB,CAAA;AAChE,eAAO,MAAM,qBAAqB,EAAG,YAAqB,CAAA;AAE1D,eAAO,MAAM,4BAA4B,wQAY/B,CAAA;AAEV,MAAM,MAAM,uBAAuB,GAAG,CAAC,OAAO,yBAAyB,CAAC,CAAC,MAAM,CAAC,CAAA;AAChF,MAAM,MAAM,0BAA0B,GAAG,CAAC,OAAO,4BAA4B,CAAC,CAAC,MAAM,CAAC,CAAA"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export const FOUNDATION_COMMON_LOCALE__EN = "en";
|
|
2
|
+
export const FOUNDATION_COMMON_LOCALE__FR = "fr";
|
|
3
|
+
export const FOUNDATION_COMMON_LOCALES = [FOUNDATION_COMMON_LOCALE__EN, FOUNDATION_COMMON_LOCALE__FR];
|
|
4
|
+
export const NAMESPACE__COMMON__CAROUSEL = "common--carousel";
|
|
5
|
+
export const NAMESPACE__COMMON__DELETE_ENTITY_MODAL = "common--delete-entity-modal";
|
|
6
|
+
export const NAMESPACE__COMMON__FILE_UPLOAD = "common--file-upload";
|
|
7
|
+
export const NAMESPACE__COMMON__FORM_RULES = "common--form-rules";
|
|
8
|
+
export const NAMESPACE__COMMON__FORM_VALIDATION = "common--form-validation";
|
|
9
|
+
export const NAMESPACE__COMMON__PAGINATION = "common--pagination";
|
|
10
|
+
export const NAMESPACE__COMMON__SAVED_VIEWS = "common--saved-views";
|
|
11
|
+
export const NAMESPACE__COMMON__SEARCHING = "common--searching";
|
|
12
|
+
export const NAMESPACE__COMMON__SORT_AND_FILTER_PANEL = "common--sort-and-filter-panel";
|
|
13
|
+
export const NAMESPACE__COMMON__THEME = "common--theme";
|
|
14
|
+
export const NAMESPACE__COMMON__UI = "common--ui";
|
|
15
|
+
export const FOUNDATION_COMMON_NAMESPACES = [
|
|
16
|
+
NAMESPACE__COMMON__CAROUSEL,
|
|
17
|
+
NAMESPACE__COMMON__DELETE_ENTITY_MODAL,
|
|
18
|
+
NAMESPACE__COMMON__FILE_UPLOAD,
|
|
19
|
+
NAMESPACE__COMMON__FORM_RULES,
|
|
20
|
+
NAMESPACE__COMMON__FORM_VALIDATION,
|
|
21
|
+
NAMESPACE__COMMON__PAGINATION,
|
|
22
|
+
NAMESPACE__COMMON__SAVED_VIEWS,
|
|
23
|
+
NAMESPACE__COMMON__SEARCHING,
|
|
24
|
+
NAMESPACE__COMMON__SORT_AND_FILTER_PANEL,
|
|
25
|
+
NAMESPACE__COMMON__THEME,
|
|
26
|
+
NAMESPACE__COMMON__UI,
|
|
27
|
+
];
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { TI18nProviderFallback, TI18nRegistry, TI18nRuntimeConfig } from "./types.js";
|
|
3
|
+
export type TI18nProviderProps<Locale extends string, Namespace extends string> = {
|
|
4
|
+
locale: Locale;
|
|
5
|
+
preloadNamespaces?: readonly Namespace[] | undefined;
|
|
6
|
+
children: React.ReactNode;
|
|
7
|
+
};
|
|
8
|
+
export type TValidateI18nManifestArgs<Locale extends string, Namespace extends string> = {
|
|
9
|
+
version: string;
|
|
10
|
+
expectedLocales: readonly Locale[];
|
|
11
|
+
expectedNamespaces: readonly Namespace[];
|
|
12
|
+
};
|
|
13
|
+
export type TCreateI18nProviderArgs<Locale extends string, Namespace extends string> = {
|
|
14
|
+
registry: TI18nRegistry<Locale, Namespace>;
|
|
15
|
+
getRuntimeConfig: () => TI18nRuntimeConfig;
|
|
16
|
+
validateManifest?: ((args: TValidateI18nManifestArgs<Locale, Namespace>) => Promise<void> | void) | undefined;
|
|
17
|
+
environment?: string | undefined;
|
|
18
|
+
loadingFallback?: TI18nProviderFallback | undefined;
|
|
19
|
+
};
|
|
20
|
+
export declare const createI18nProvider: <Locale extends string, Namespace extends string>({ registry, getRuntimeConfig, validateManifest, environment, loadingFallback, }: TCreateI18nProviderArgs<Locale, Namespace>) => React.FC<TI18nProviderProps<Locale, Namespace>>;
|
|
21
|
+
export declare const useTypedTranslation: <Namespace extends string>(namespace?: Namespace | readonly Namespace[]) => import("react-i18next").UseTranslationResponse<string | readonly string[], undefined>;
|
|
22
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/core/client.tsx"],"names":[],"mappings":"AAGA,OAAO,KAA+C,MAAM,OAAO,CAAA;AAKnE,OAAO,KAAK,EAAE,qBAAqB,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAE1F,MAAM,MAAM,kBAAkB,CAAC,MAAM,SAAS,MAAM,EAAE,SAAS,SAAS,MAAM,IAAI;IAChF,MAAM,EAAE,MAAM,CAAA;IACd,iBAAiB,CAAC,EAAE,SAAS,SAAS,EAAE,GAAG,SAAS,CAAA;IACpD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAC1B,CAAA;AAED,MAAM,MAAM,yBAAyB,CAAC,MAAM,SAAS,MAAM,EAAE,SAAS,SAAS,MAAM,IAAI;IACvF,OAAO,EAAE,MAAM,CAAA;IACf,eAAe,EAAE,SAAS,MAAM,EAAE,CAAA;IAClC,kBAAkB,EAAE,SAAS,SAAS,EAAE,CAAA;CACzC,CAAA;AAED,MAAM,MAAM,uBAAuB,CAAC,MAAM,SAAS,MAAM,EAAE,SAAS,SAAS,MAAM,IAAI;IACrF,QAAQ,EAAE,aAAa,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IAC1C,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;IAC1C,gBAAgB,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,yBAAyB,CAAC,MAAM,EAAE,SAAS,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,SAAS,CAAA;IAC7G,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAChC,eAAe,CAAC,EAAE,qBAAqB,GAAG,SAAS,CAAA;CACpD,CAAA;AAaD,eAAO,MAAM,kBAAkB,GAAI,MAAM,SAAS,MAAM,EAAE,SAAS,SAAS,MAAM,EAAE,iFAMjF,uBAAuB,CAAC,MAAM,EAAE,SAAS,CAAC,oDAiF5C,CAAA;AAED,eAAO,MAAM,mBAAmB,GAAI,SAAS,SAAS,MAAM,EAAE,YAAY,SAAS,GAAG,SAAS,SAAS,EAAE,0FACrC,CAAA"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import i18next from "i18next";
|
|
4
|
+
import { useEffect, useMemo, useRef, useState } from "react";
|
|
5
|
+
import { I18nextProvider, useTranslation } from "react-i18next";
|
|
6
|
+
import { initReactI18next } from "react-i18next/initReactI18next";
|
|
7
|
+
import { initI18nCommon } from "./initCommon.js";
|
|
8
|
+
const defaultLoadingFallback = (_jsx("div", { style: {
|
|
9
|
+
backgroundColor: "#2c2c2c",
|
|
10
|
+
height: "100vh",
|
|
11
|
+
padding: 15,
|
|
12
|
+
width: "100vw",
|
|
13
|
+
} }));
|
|
14
|
+
export const createI18nProvider = ({ registry, getRuntimeConfig, validateManifest, environment = process.env.NODE_ENV, loadingFallback = defaultLoadingFallback, }) => {
|
|
15
|
+
const I18nProvider = ({ locale, preloadNamespaces, children }) => {
|
|
16
|
+
const i18nRef = useRef(null);
|
|
17
|
+
const devCheckedRef = useRef(false);
|
|
18
|
+
const isDev = environment === "development";
|
|
19
|
+
if (!i18nRef.current) {
|
|
20
|
+
const instance = i18next.createInstance();
|
|
21
|
+
instance.use(initReactI18next);
|
|
22
|
+
i18nRef.current = instance;
|
|
23
|
+
}
|
|
24
|
+
const i18n = i18nRef.current;
|
|
25
|
+
const [ready, setReady] = useState(i18n.isInitialized);
|
|
26
|
+
const preloadKey = useMemo(() => (preloadNamespaces ? preloadNamespaces.join("|") : ""), [preloadNamespaces]);
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
if (!isDev)
|
|
29
|
+
return;
|
|
30
|
+
if (devCheckedRef.current)
|
|
31
|
+
return;
|
|
32
|
+
if (!validateManifest)
|
|
33
|
+
return;
|
|
34
|
+
devCheckedRef.current = true;
|
|
35
|
+
const runtimeConfig = getRuntimeConfig();
|
|
36
|
+
if (!runtimeConfig.version) {
|
|
37
|
+
console.warn("[i18n] I18N_VERSION missing; skipping dev manifest validation.");
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
void validateManifest({
|
|
41
|
+
expectedLocales: registry.availableLocales,
|
|
42
|
+
expectedNamespaces: registry.availableNamespaces,
|
|
43
|
+
version: runtimeConfig.version,
|
|
44
|
+
});
|
|
45
|
+
}, [isDev]);
|
|
46
|
+
useEffect(() => {
|
|
47
|
+
let cancelled = false;
|
|
48
|
+
const runtimeConfig = getRuntimeConfig();
|
|
49
|
+
if (!runtimeConfig.version) {
|
|
50
|
+
console.error("[i18n] I18N_VERSION is missing; cannot init i18n.");
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
void (async () => {
|
|
54
|
+
try {
|
|
55
|
+
if (!i18n.isInitialized) {
|
|
56
|
+
await initI18nCommon({
|
|
57
|
+
environment,
|
|
58
|
+
installReactPlugin: false,
|
|
59
|
+
instance: i18n,
|
|
60
|
+
locale,
|
|
61
|
+
namespaces: preloadNamespaces,
|
|
62
|
+
registry,
|
|
63
|
+
runtimeConfig,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
await i18n.changeLanguage(locale);
|
|
68
|
+
}
|
|
69
|
+
if (!cancelled)
|
|
70
|
+
setReady(true);
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
console.error("[I18nProvider] init failed", error);
|
|
74
|
+
if (!cancelled)
|
|
75
|
+
setReady(true);
|
|
76
|
+
}
|
|
77
|
+
})();
|
|
78
|
+
return () => {
|
|
79
|
+
cancelled = true;
|
|
80
|
+
};
|
|
81
|
+
}, [i18n, locale, preloadKey]);
|
|
82
|
+
if (!ready) {
|
|
83
|
+
return loadingFallback;
|
|
84
|
+
}
|
|
85
|
+
return _jsx(I18nextProvider, { i18n: i18n, children: children });
|
|
86
|
+
};
|
|
87
|
+
return I18nProvider;
|
|
88
|
+
};
|
|
89
|
+
export const useTypedTranslation = (namespace) => useTranslation(namespace);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { InitOptions } from "i18next";
|
|
2
|
+
import { type TPseudolocalizationCharacterSet } from "../pseudolocalization/index.js";
|
|
3
|
+
import type { TI18nRegistry } from "./types.js";
|
|
4
|
+
export type TBuildCoreConfigArgs<Locale extends string = string, Namespace extends string = string> = {
|
|
5
|
+
locale: Locale;
|
|
6
|
+
namespaces?: readonly Namespace[] | undefined;
|
|
7
|
+
registry: TI18nRegistry<Locale, Namespace>;
|
|
8
|
+
productionLike?: boolean | undefined;
|
|
9
|
+
environment?: string | undefined;
|
|
10
|
+
developmentEnvironmentName?: string | undefined;
|
|
11
|
+
initializePseudolocalizationInDevelopment?: boolean | undefined;
|
|
12
|
+
missingKeyWarnings?: boolean | undefined;
|
|
13
|
+
pseudolocalizationActive?: boolean | undefined;
|
|
14
|
+
pseudolocalizationCharacterSet?: TPseudolocalizationCharacterSet | undefined;
|
|
15
|
+
pseudolocalizationPostProcessorName?: string | undefined;
|
|
16
|
+
};
|
|
17
|
+
export declare const buildCoreConfig: <Locale extends string, Namespace extends string>({ locale, namespaces, registry, productionLike, environment, developmentEnvironmentName, initializePseudolocalizationInDevelopment, missingKeyWarnings, pseudolocalizationActive, pseudolocalizationCharacterSet, pseudolocalizationPostProcessorName, }: TBuildCoreConfigArgs<Locale, Namespace>) => InitOptions;
|
|
18
|
+
//# sourceMappingURL=configuration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configuration.d.ts","sourceRoot":"","sources":["../../src/core/configuration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAE1C,OAAO,EAGL,KAAK,+BAA+B,EACrC,MAAM,gCAAgC,CAAA;AAGvC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAE/C,MAAM,MAAM,oBAAoB,CAAC,MAAM,SAAS,MAAM,GAAG,MAAM,EAAE,SAAS,SAAS,MAAM,GAAG,MAAM,IAAI;IACpG,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,CAAC,EAAE,SAAS,SAAS,EAAE,GAAG,SAAS,CAAA;IAC7C,QAAQ,EAAE,aAAa,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IAC1C,cAAc,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IACpC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAChC,0BAA0B,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC/C,yCAAyC,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IAC/D,kBAAkB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IACxC,wBAAwB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IAC9C,8BAA8B,CAAC,EAAE,+BAA+B,GAAG,SAAS,CAAA;IAC5E,mCAAmC,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACzD,CAAA;AAED,eAAO,MAAM,eAAe,GAAI,MAAM,SAAS,MAAM,EAAE,SAAS,SAAS,MAAM,EAAE,0PAY9E,oBAAoB,CAAC,MAAM,EAAE,SAAS,CAAC,KAAG,WAwC5C,CAAA"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { getPseudolocalizationPostProcessConfig, initializePseudolocalization, } from "../pseudolocalization/index.js";
|
|
2
|
+
import { makeMissingKeyHandler, parseMissingKey } from "./i18nStrictMode.js";
|
|
3
|
+
export const buildCoreConfig = ({ locale, namespaces, registry, productionLike = false, environment = process.env.NODE_ENV, developmentEnvironmentName = "development", initializePseudolocalizationInDevelopment = true, missingKeyWarnings, pseudolocalizationActive, pseudolocalizationCharacterSet, pseudolocalizationPostProcessorName, }) => {
|
|
4
|
+
const ns = [...(namespaces ?? registry.initialLoadNamespaces)];
|
|
5
|
+
const defaultNS = registry.defaultNamespace ?? ns[0];
|
|
6
|
+
const shouldWarnForMissingKeys = missingKeyWarnings ?? !productionLike;
|
|
7
|
+
const config = {
|
|
8
|
+
fallbackLng: registry.defaultLocale,
|
|
9
|
+
interpolation: { escapeValue: false },
|
|
10
|
+
keySeparator: false,
|
|
11
|
+
lng: locale,
|
|
12
|
+
ns,
|
|
13
|
+
nsSeparator: false,
|
|
14
|
+
partialBundledLanguages: true,
|
|
15
|
+
react: { useSuspense: false },
|
|
16
|
+
returnEmptyString: false,
|
|
17
|
+
returnNull: false,
|
|
18
|
+
supportedLngs: [...registry.availableLocales],
|
|
19
|
+
};
|
|
20
|
+
if (defaultNS) {
|
|
21
|
+
config.defaultNS = defaultNS;
|
|
22
|
+
}
|
|
23
|
+
if (shouldWarnForMissingKeys) {
|
|
24
|
+
config.saveMissing = true;
|
|
25
|
+
config.parseMissingKeyHandler = parseMissingKey;
|
|
26
|
+
config.missingKeyHandler = makeMissingKeyHandler();
|
|
27
|
+
}
|
|
28
|
+
if (pseudolocalizationActive) {
|
|
29
|
+
config.postProcess = getPseudolocalizationPostProcessConfig(pseudolocalizationPostProcessorName);
|
|
30
|
+
}
|
|
31
|
+
const isDevelopment = environment === developmentEnvironmentName;
|
|
32
|
+
if (!productionLike && isDevelopment && pseudolocalizationActive && initializePseudolocalizationInDevelopment) {
|
|
33
|
+
initializePseudolocalization({ characterSet: pseudolocalizationCharacterSet });
|
|
34
|
+
}
|
|
35
|
+
return config;
|
|
36
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type i18n } from "i18next";
|
|
2
|
+
import type { TI18nRegistry, TI18nRuntimeConfig } from "./types.js";
|
|
3
|
+
export type TCreateIsolatedI18nInstanceArgs<Locale extends string, Namespace extends string> = {
|
|
4
|
+
locale: Locale;
|
|
5
|
+
namespaces?: readonly Namespace[] | undefined;
|
|
6
|
+
registry: TI18nRegistry<Locale, Namespace>;
|
|
7
|
+
runtimeConfig: TI18nRuntimeConfig;
|
|
8
|
+
productionLike?: boolean | undefined;
|
|
9
|
+
environment?: string | undefined;
|
|
10
|
+
missingKeyWarnings?: boolean | undefined;
|
|
11
|
+
};
|
|
12
|
+
export declare const createIsolatedI18nInstance: <Locale extends string, Namespace extends string>({ locale, namespaces, registry, runtimeConfig, productionLike, environment, missingKeyWarnings, }: TCreateIsolatedI18nInstanceArgs<Locale, Namespace>) => Promise<i18n>;
|
|
13
|
+
//# sourceMappingURL=createIsolatedI18nInstance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createIsolatedI18nInstance.d.ts","sourceRoot":"","sources":["../../src/core/createIsolatedI18nInstance.ts"],"names":[],"mappings":"AAAA,OAAgB,EAAE,KAAK,IAAI,EAAE,MAAM,SAAS,CAAA;AAG5C,OAAO,KAAK,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAEnE,MAAM,MAAM,+BAA+B,CAAC,MAAM,SAAS,MAAM,EAAE,SAAS,SAAS,MAAM,IAAI;IAC7F,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,CAAC,EAAE,SAAS,SAAS,EAAE,GAAG,SAAS,CAAA;IAC7C,QAAQ,EAAE,aAAa,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IAC1C,aAAa,EAAE,kBAAkB,CAAA;IACjC,cAAc,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IACpC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAChC,kBAAkB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;CACzC,CAAA;AAED,eAAO,MAAM,0BAA0B,GAAU,MAAM,SAAS,MAAM,EAAE,SAAS,SAAS,MAAM,EAAE,mGAQ/F,+BAA+B,CAAC,MAAM,EAAE,SAAS,CAAC,KAAG,OAAO,CAAC,IAAI,CAcnE,CAAA"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import i18next from "i18next";
|
|
2
|
+
import { initI18nCommon } from "./initCommon.js";
|
|
3
|
+
export const createIsolatedI18nInstance = async ({ locale, namespaces, registry, runtimeConfig, productionLike = true, environment, missingKeyWarnings, }) => {
|
|
4
|
+
const instance = i18next.createInstance();
|
|
5
|
+
return await initI18nCommon({
|
|
6
|
+
environment,
|
|
7
|
+
installReactPlugin: false,
|
|
8
|
+
instance,
|
|
9
|
+
locale,
|
|
10
|
+
missingKeyWarnings,
|
|
11
|
+
namespaces,
|
|
12
|
+
productionLike,
|
|
13
|
+
registry,
|
|
14
|
+
runtimeConfig,
|
|
15
|
+
});
|
|
16
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare const parseMissingKey: (key: string) => string;
|
|
2
|
+
export type TMissingKeyHandlerArgs = {
|
|
3
|
+
lngs: readonly string[] | string;
|
|
4
|
+
ns: string;
|
|
5
|
+
key: string;
|
|
6
|
+
fallbackValue: string;
|
|
7
|
+
updateMissing: boolean;
|
|
8
|
+
options: Record<string, unknown>;
|
|
9
|
+
};
|
|
10
|
+
export declare const makeMissingKeyHandler: () => ((...unsafeArgs: unknown[]) => void);
|
|
11
|
+
//# sourceMappingURL=i18nStrictMode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"i18nStrictMode.d.ts","sourceRoot":"","sources":["../../src/core/i18nStrictMode.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,eAAe,GAAI,KAAK,MAAM,KAAG,MAAoB,CAAA;AAElE,MAAM,MAAM,sBAAsB,GAAG;IACnC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAAA;IAChC,EAAE,EAAE,MAAM,CAAA;IACV,GAAG,EAAE,MAAM,CAAA;IACX,aAAa,EAAE,MAAM,CAAA;IACrB,aAAa,EAAE,OAAO,CAAA;IACtB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACjC,CAAA;AASD,eAAO,MAAM,qBAAqB,QAAO,CAAC,CAAC,GAAG,UAAU,EAAE,OAAO,EAAE,KAAK,IAAI,CAoB3E,CAAA"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export const parseMissingKey = (key) => `⟦${key}⟧`;
|
|
2
|
+
const handleMissingKey = ({ lngs, ns, key }) => {
|
|
3
|
+
const normalizedLngs = Array.isArray(lngs) ? lngs : [String(lngs)];
|
|
4
|
+
const lng = normalizedLngs[0];
|
|
5
|
+
console.warn(`[i18n] Missing key: ns="${ns}" key="${key}" (lng=${lng})`);
|
|
6
|
+
};
|
|
7
|
+
export const makeMissingKeyHandler = () => {
|
|
8
|
+
return (...unsafeArgs) => {
|
|
9
|
+
const [lngs, ns, key, fallbackValue, updateMissing, options] = unsafeArgs;
|
|
10
|
+
handleMissingKey({
|
|
11
|
+
fallbackValue,
|
|
12
|
+
key,
|
|
13
|
+
lngs,
|
|
14
|
+
ns,
|
|
15
|
+
options,
|
|
16
|
+
updateMissing,
|
|
17
|
+
});
|
|
18
|
+
};
|
|
19
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAA;AAClC,cAAc,iCAAiC,CAAA;AAC/C,cAAc,qBAAqB,CAAA;AACnC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,qBAAqB,CAAA;AACnC,cAAc,YAAY,CAAA"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { i18n } from "i18next";
|
|
2
|
+
import type { TI18nRegistry, TI18nRuntimeConfig } from "./types.js";
|
|
3
|
+
export type TInitI18nCommonArgs<Locale extends string, Namespace extends string> = {
|
|
4
|
+
instance: i18n;
|
|
5
|
+
locale: Locale;
|
|
6
|
+
namespaces?: readonly Namespace[] | undefined;
|
|
7
|
+
registry: TI18nRegistry<Locale, Namespace>;
|
|
8
|
+
runtimeConfig: TI18nRuntimeConfig;
|
|
9
|
+
productionLike?: boolean | undefined;
|
|
10
|
+
installReactPlugin?: boolean | undefined;
|
|
11
|
+
environment?: string | undefined;
|
|
12
|
+
missingKeyWarnings?: boolean | undefined;
|
|
13
|
+
};
|
|
14
|
+
export declare const initI18nCommon: <Locale extends string, Namespace extends string>({ instance, locale, namespaces, registry, runtimeConfig, productionLike, installReactPlugin, environment, missingKeyWarnings, }: TInitI18nCommonArgs<Locale, Namespace>) => Promise<i18n>;
|
|
15
|
+
//# sourceMappingURL=initCommon.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"initCommon.d.ts","sourceRoot":"","sources":["../../src/core/initCommon.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,SAAS,CAAA;AAYnC,OAAO,KAAK,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAEnE,MAAM,MAAM,mBAAmB,CAAC,MAAM,SAAS,MAAM,EAAE,SAAS,SAAS,MAAM,IAAI;IACjF,QAAQ,EAAE,IAAI,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,CAAC,EAAE,SAAS,SAAS,EAAE,GAAG,SAAS,CAAA;IAC7C,QAAQ,EAAE,aAAa,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IAC1C,aAAa,EAAE,kBAAkB,CAAA;IACjC,cAAc,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IACpC,kBAAkB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IACxC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAChC,kBAAkB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;CACzC,CAAA;AAwCD,eAAO,MAAM,cAAc,GAAU,MAAM,SAAS,MAAM,EAAE,SAAS,SAAS,MAAM,EAAE,iIAUnF,mBAAmB,CAAC,MAAM,EAAE,SAAS,CAAC,KAAG,OAAO,CAAC,IAAI,CA4BvD,CAAA"}
|