@aidc-toolkit/core 0.9.1 → 0.9.3
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/eslint.config.js +1 -16
- package/package.json +7 -11
- package/src/locale/i18n.ts +61 -10
package/eslint.config.js
CHANGED
|
@@ -1,18 +1,3 @@
|
|
|
1
|
-
import tseslint from "typescript-eslint";
|
|
2
|
-
import js from "@eslint/js";
|
|
3
|
-
import stylistic from "@stylistic/eslint-plugin";
|
|
4
|
-
import jsdoc from "eslint-plugin-jsdoc";
|
|
5
|
-
import esLintConfigLove from "eslint-config-love";
|
|
6
1
|
import { esLintConfigAIDCToolkit } from "@aidc-toolkit/dev";
|
|
7
2
|
|
|
8
|
-
export default
|
|
9
|
-
{
|
|
10
|
-
ignores: ["eslint.config.js", "dist"]
|
|
11
|
-
},
|
|
12
|
-
js.configs.recommended,
|
|
13
|
-
...tseslint.configs.strictTypeChecked,
|
|
14
|
-
stylistic.configs["recommended-flat"],
|
|
15
|
-
jsdoc.configs["flat/recommended-typescript"],
|
|
16
|
-
esLintConfigLove,
|
|
17
|
-
esLintConfigAIDCToolkit
|
|
18
|
-
);
|
|
3
|
+
export default esLintConfigAIDCToolkit;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aidc-toolkit/core",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.3",
|
|
4
4
|
"description": "Core functionality for AIDC Toolkit",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -21,21 +21,17 @@
|
|
|
21
21
|
"scripts": {
|
|
22
22
|
"eslint": "eslint .",
|
|
23
23
|
"build": "tsup src/index.ts --clean --format cjs,esm --dts",
|
|
24
|
-
"build-
|
|
24
|
+
"build-doc": "npm run build && tsc src/index.ts --outDir dist --target esnext --moduleResolution nodenext --module nodenext --emitDeclarationOnly --declaration --declarationMap"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
|
-
"@aidc-toolkit/dev": "^0.9.
|
|
28
|
-
"
|
|
29
|
-
"@stylistic/eslint-plugin": "^2.8.0",
|
|
30
|
-
"eslint-config-love": "^71.0.0",
|
|
31
|
-
"eslint-plugin-jsdoc": "^50.3.0",
|
|
27
|
+
"@aidc-toolkit/dev": "^0.9.3",
|
|
28
|
+
"eslint": "^9.14.0",
|
|
32
29
|
"ts-node": "^10.9.2",
|
|
33
|
-
"tsup": "^8.3.
|
|
34
|
-
"typescript": "^5.6.
|
|
35
|
-
"typescript-eslint": "^8.7.0"
|
|
30
|
+
"tsup": "^8.3.5",
|
|
31
|
+
"typescript": "^5.6.3"
|
|
36
32
|
},
|
|
37
33
|
"dependencies": {
|
|
38
|
-
"i18next": "^23.
|
|
34
|
+
"i18next": "^23.16.5",
|
|
39
35
|
"i18next-browser-languagedetector": "^8.0.0",
|
|
40
36
|
"i18next-cli-language-detector": "^1.1.8"
|
|
41
37
|
}
|
package/src/locale/i18n.ts
CHANGED
|
@@ -38,8 +38,6 @@ export enum I18NEnvironment {
|
|
|
38
38
|
Browser
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
let i18nInitPending = true;
|
|
42
|
-
|
|
43
41
|
/**
|
|
44
42
|
* Initialize internationalization.
|
|
45
43
|
*
|
|
@@ -53,11 +51,11 @@ let i18nInitPending = true;
|
|
|
53
51
|
* True if initialization was completed, false if skipped (already initialized).
|
|
54
52
|
*/
|
|
55
53
|
export async function i18nInit(environment: I18NEnvironment, debug = false): Promise<boolean> {
|
|
56
|
-
|
|
54
|
+
let initialized: boolean;
|
|
57
55
|
|
|
58
56
|
// Skip if initialization is not pending.
|
|
59
|
-
if (
|
|
60
|
-
|
|
57
|
+
if (pendingResourceBundles !== undefined) {
|
|
58
|
+
initialized = true;
|
|
61
59
|
|
|
62
60
|
let module: object;
|
|
63
61
|
|
|
@@ -74,22 +72,26 @@ export async function i18nInit(environment: I18NEnvironment, debug = false): Pro
|
|
|
74
72
|
throw new Error("Not supported");
|
|
75
73
|
}
|
|
76
74
|
|
|
75
|
+
const initResourceBundles = pendingResourceBundles;
|
|
76
|
+
|
|
77
|
+
// No need to manage pending resource bundles past this point.
|
|
78
|
+
pendingResourceBundles = undefined;
|
|
79
|
+
|
|
77
80
|
await i18next.use(module as never).init({
|
|
78
81
|
fallbackLng: "en",
|
|
79
82
|
debug,
|
|
80
83
|
resources: {}
|
|
81
84
|
}).then(() => {
|
|
82
|
-
//
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
// No need to manage pending resource bundles past this point.
|
|
86
|
-
pendingResourceBundles = undefined;
|
|
85
|
+
// Add toLowerCase function.
|
|
86
|
+
i18next.services.formatter?.add("toLowerCase", value => (value as string).toLowerCase());
|
|
87
87
|
|
|
88
88
|
// Add pending resource bundles.
|
|
89
89
|
for (const initResourceBundle of initResourceBundles) {
|
|
90
90
|
i18nAddResourceBundle(initResourceBundle.lng, initResourceBundle.ns, initResourceBundle.resources);
|
|
91
91
|
}
|
|
92
92
|
});
|
|
93
|
+
} else {
|
|
94
|
+
initialized = false;
|
|
93
95
|
}
|
|
94
96
|
|
|
95
97
|
return initialized;
|
|
@@ -115,6 +117,55 @@ export function i18nAddResourceBundle(lng: string, ns: string, resources: object
|
|
|
115
117
|
resources
|
|
116
118
|
});
|
|
117
119
|
} else {
|
|
120
|
+
// Already initialized; add resource bundle directly.
|
|
118
121
|
i18next.addResourceBundle(lng, ns, resources);
|
|
119
122
|
}
|
|
120
123
|
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Assert that language resources are a type match for English (default) resources.
|
|
127
|
+
*
|
|
128
|
+
* @param enResources
|
|
129
|
+
* English resources.
|
|
130
|
+
*
|
|
131
|
+
* @param lng
|
|
132
|
+
* Language.
|
|
133
|
+
*
|
|
134
|
+
* @param lngResources
|
|
135
|
+
* Language resources.
|
|
136
|
+
*
|
|
137
|
+
* @param parent
|
|
138
|
+
* Parent key name (set recursively).
|
|
139
|
+
*/
|
|
140
|
+
export function i18nAssertValidResources(enResources: object, lng: string, lngResources: object, parent?: string): void {
|
|
141
|
+
const enResourcesMap = new Map<string, object>(Object.entries(enResources));
|
|
142
|
+
const lngResourcesMap = new Map<string, object>(Object.entries(lngResources));
|
|
143
|
+
|
|
144
|
+
const isLocale = lng.includes("-");
|
|
145
|
+
|
|
146
|
+
for (const [enKey, enValue] of enResourcesMap) {
|
|
147
|
+
const lngValue = lngResourcesMap.get(enKey);
|
|
148
|
+
|
|
149
|
+
if (lngValue !== undefined) {
|
|
150
|
+
const enValueType = typeof enValue;
|
|
151
|
+
const lngValueType = typeof lngValue;
|
|
152
|
+
|
|
153
|
+
if (lngValueType !== enValueType) {
|
|
154
|
+
throw new Error(`Invalid value type ${lngValueType} for key ${parent === undefined ? "" : `${parent}.`}${enKey} in ${lng} resources`);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
if (enValueType === "object") {
|
|
158
|
+
i18nAssertValidResources(enValue, lng, lngValue, `${parent === undefined ? "" : `${parent}.`}${enKey}`);
|
|
159
|
+
}
|
|
160
|
+
// Locale falls back to raw language so ignore if missing.
|
|
161
|
+
} else if (!isLocale) {
|
|
162
|
+
throw new Error(`Missing key ${parent === undefined ? "" : `${parent}.`}${enKey} from ${lng} resources`);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
for (const [lngKey] of lngResourcesMap) {
|
|
167
|
+
if (!enResourcesMap.has(lngKey)) {
|
|
168
|
+
throw new Error(`Extraneous key ${parent === undefined ? "" : `${parent}.`}${lngKey} in ${lng} resources`);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|