i18next-cli 1.42.5 → 1.42.7
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/dist/cjs/cli.js +14 -14
- package/dist/cjs/config.js +4 -4
- package/dist/cjs/extractor/core/extractor.js +11 -11
- package/dist/cjs/extractor/core/translation-manager.js +12 -3
- package/dist/cjs/linter.js +7 -7
- package/dist/cjs/locize.js +18 -18
- package/dist/cjs/rename-key.js +3 -3
- package/dist/cjs/status.js +25 -20
- package/dist/cjs/syncer.js +11 -11
- package/dist/cjs/types-generator.js +6 -6
- package/dist/cjs/utils/file-utils.js +38 -0
- package/dist/esm/cli.js +14 -14
- package/dist/esm/config.js +4 -4
- package/dist/esm/extractor/core/extractor.js +11 -11
- package/dist/esm/extractor/core/translation-manager.js +14 -5
- package/dist/esm/linter.js +7 -7
- package/dist/esm/locize.js +18 -18
- package/dist/esm/rename-key.js +3 -3
- package/dist/esm/status.js +25 -20
- package/dist/esm/syncer.js +11 -11
- package/dist/esm/types-generator.js +6 -6
- package/dist/esm/utils/file-utils.js +38 -1
- package/package.json +2 -5
- package/types/extractor/core/translation-manager.d.ts.map +1 -1
- package/types/utils/file-utils.d.ts +16 -0
- package/types/utils/file-utils.d.ts.map +1 -1
|
@@ -2,7 +2,7 @@ import { ConsoleLogger } from './utils/logger.js';
|
|
|
2
2
|
import { mergeResourcesAsInterface } from 'i18next-resources-for-ts';
|
|
3
3
|
import { glob } from 'glob';
|
|
4
4
|
import { createSpinnerLike } from './utils/wrap-ora.js';
|
|
5
|
-
import
|
|
5
|
+
import { styleText } from 'node:util';
|
|
6
6
|
import { mkdir, writeFile, access, readFile } from 'node:fs/promises';
|
|
7
7
|
import { join, dirname, basename, extname, resolve, relative } from 'node:path';
|
|
8
8
|
import { transform } from '@swc/core';
|
|
@@ -109,7 +109,7 @@ async function runTypesGenerator(config, options = {}) {
|
|
|
109
109
|
}
|
|
110
110
|
const nonObjectKeys = keys.filter(k => !parsedContent[k] || typeof parsedContent[k] !== 'object');
|
|
111
111
|
if (nonObjectKeys.length > 0) {
|
|
112
|
-
console.warn(
|
|
112
|
+
console.warn(styleText('yellow', `Warning: The file ${file} contains top-level keys that are not objects (${nonObjectKeys.join(', ')}). When 'mergeNamespaces' is enabled, top-level keys are treated as namespaces. These keys will be ignored.`));
|
|
113
113
|
}
|
|
114
114
|
continue;
|
|
115
115
|
}
|
|
@@ -125,7 +125,7 @@ ${mergeResourcesAsInterface(resources, { optimize: !!enableSelector, indentation
|
|
|
125
125
|
const resourcesOutputPath = resolve(process.cwd(), config.types.resourcesFile);
|
|
126
126
|
await mkdir(dirname(resourcesOutputPath), { recursive: true });
|
|
127
127
|
await writeFile(resourcesOutputPath, interfaceDefinition);
|
|
128
|
-
logMessages.push(` ${
|
|
128
|
+
logMessages.push(` ${styleText('green', '✓')} Resources interface written to ${config.types.resourcesFile}`);
|
|
129
129
|
let outputPathExists;
|
|
130
130
|
try {
|
|
131
131
|
await access(outputPath);
|
|
@@ -152,13 +152,13 @@ declare module 'i18next' {
|
|
|
152
152
|
}`;
|
|
153
153
|
await mkdir(dirname(outputPath), { recursive: true });
|
|
154
154
|
await writeFile(outputPath, fileContent);
|
|
155
|
-
logMessages.push(` ${
|
|
155
|
+
logMessages.push(` ${styleText('green', '✓')} TypeScript definitions written to ${config.types.output || ''}`);
|
|
156
156
|
}
|
|
157
|
-
spinner.succeed(
|
|
157
|
+
spinner.succeed(styleText('bold', 'TypeScript definitions generated successfully.'));
|
|
158
158
|
logMessages.forEach(msg => typeof internalLogger.info === 'function' ? internalLogger.info(msg) : console.log(msg));
|
|
159
159
|
}
|
|
160
160
|
catch (error) {
|
|
161
|
-
spinner.fail(
|
|
161
|
+
spinner.fail(styleText('red', 'Failed to generate TypeScript definitions.'));
|
|
162
162
|
if (typeof internalLogger.error === 'function')
|
|
163
163
|
internalLogger.error(error);
|
|
164
164
|
else
|
|
@@ -43,6 +43,43 @@ function getOutputPath(outputTemplate, language, namespace) {
|
|
|
43
43
|
out = out.replace(/\/\/+/g, '/');
|
|
44
44
|
return normalize(out);
|
|
45
45
|
}
|
|
46
|
+
/**
|
|
47
|
+
* Extracts the namespace value from a concrete file path by matching it against
|
|
48
|
+
* the output template.
|
|
49
|
+
*
|
|
50
|
+
* Given a template like `src/{{namespace}}/locales/{{language}}.json` and a file
|
|
51
|
+
* path like `src/widgets/component/locales/en.json`, this returns `widgets/component`.
|
|
52
|
+
*
|
|
53
|
+
* This handles multi-segment namespaces (namespaces containing `/`) which
|
|
54
|
+
* `basename()` cannot recover.
|
|
55
|
+
*
|
|
56
|
+
* @param outputTemplate - The output path template string (must contain `{{namespace}}`)
|
|
57
|
+
* @param language - The language value used when the file was generated
|
|
58
|
+
* @param filePath - The concrete file path to extract the namespace from
|
|
59
|
+
* @returns The namespace string, or `undefined` if the path doesn't match the template
|
|
60
|
+
*/
|
|
61
|
+
function extractNamespaceFromPath(outputTemplate, language, filePath) {
|
|
62
|
+
// Build a regex from the template by escaping everything except the placeholders.
|
|
63
|
+
// Replace {{language}}/{{lng}} with the literal language value and
|
|
64
|
+
// {{namespace}} with a named capture group that matches one or more path segments.
|
|
65
|
+
const pattern = outputTemplate
|
|
66
|
+
// Normalise to forward slashes for matching
|
|
67
|
+
.replace(/\\/g, '/');
|
|
68
|
+
// Escape regex-special characters (but keep our placeholders intact first)
|
|
69
|
+
const nsPlaceholder = '{{namespace}}';
|
|
70
|
+
const parts = pattern.split(nsPlaceholder);
|
|
71
|
+
// Escape each part individually then rejoin with the capture group
|
|
72
|
+
const escaped = parts.map(p => p
|
|
73
|
+
.replace(/\{\{language\}\}|\{\{lng\}\}/g, () => escapeForRegex(language))
|
|
74
|
+
.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'));
|
|
75
|
+
// Don't anchor the start — the glob may return absolute or prefixed paths.
|
|
76
|
+
// Anchor only the end so that the namespace capture is unambiguous.
|
|
77
|
+
const regexStr = escaped.join('(.+)') + '$';
|
|
78
|
+
const normalized = filePath.replace(/\\/g, '/');
|
|
79
|
+
const m = new RegExp(regexStr).exec(normalized);
|
|
80
|
+
return m?.[1];
|
|
81
|
+
}
|
|
82
|
+
const escapeForRegex = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
46
83
|
/**
|
|
47
84
|
* Dynamically loads a translation file, supporting .json, .js, and .ts formats.
|
|
48
85
|
* @param filePath - The path to the translation file.
|
|
@@ -154,4 +191,4 @@ function inferFormatFromPath(filePath, defaultFormat = 'json') {
|
|
|
154
191
|
return defaultFormat || 'json';
|
|
155
192
|
}
|
|
156
193
|
|
|
157
|
-
export { getOutputPath, inferFormatFromPath, loadRawJson5Content, loadTranslationFile, serializeTranslationFile };
|
|
194
|
+
export { extractNamespaceFromPath, getOutputPath, inferFormatFromPath, loadRawJson5Content, loadTranslationFile, serializeTranslationFile };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "i18next-cli",
|
|
3
|
-
"version": "1.42.
|
|
3
|
+
"version": "1.42.7",
|
|
4
4
|
"description": "A unified, high-performance i18next CLI.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -63,7 +63,6 @@
|
|
|
63
63
|
"memfs": "4.56.10",
|
|
64
64
|
"neostandard": "0.12.2",
|
|
65
65
|
"rollup-plugin-typescript2": "0.36.0",
|
|
66
|
-
"ts-node": "10.9.2",
|
|
67
66
|
"typescript": "5.9.3",
|
|
68
67
|
"unplugin-swc": "1.5.9",
|
|
69
68
|
"vitest": "4.0.18"
|
|
@@ -72,7 +71,6 @@
|
|
|
72
71
|
"@croct/json5-parser": "0.2.2",
|
|
73
72
|
"@swc/core": "1.15.11",
|
|
74
73
|
"yaml": "2.8.2",
|
|
75
|
-
"chalk": "5.6.2",
|
|
76
74
|
"chokidar": "5.0.0",
|
|
77
75
|
"commander": "14.0.3",
|
|
78
76
|
"execa": "9.6.1",
|
|
@@ -84,7 +82,6 @@
|
|
|
84
82
|
"minimatch": "10.1.2",
|
|
85
83
|
"ora": "9.3.0",
|
|
86
84
|
"react": "^19.2.4",
|
|
87
|
-
"react-i18next": "^16.5.4"
|
|
88
|
-
"swc-walk": "1.0.1"
|
|
85
|
+
"react-i18next": "^16.5.4"
|
|
89
86
|
}
|
|
90
87
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"translation-manager.d.ts","sourceRoot":"","sources":["../../../src/extractor/core/translation-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAgyBnF;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,EAC/B,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,EACvB,MAAM,EAAE,oBAAoB,EAC5B,EACE,uBAA+B,EAC/B,OAAe,EAChB,GAAE;IACD,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,OAAO,CAAC,EAAE,OAAO,CAAA;CACb,GACL,OAAO,CAAC,iBAAiB,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"translation-manager.d.ts","sourceRoot":"","sources":["../../../src/extractor/core/translation-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAgyBnF;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,EAC/B,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,EACvB,MAAM,EAAE,oBAAoB,EAC5B,EACE,uBAA+B,EAC/B,OAAe,EAChB,GAAE;IACD,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,OAAO,CAAC,EAAE,OAAO,CAAA;CACb,GACL,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAmJ9B"}
|
|
@@ -48,6 +48,22 @@ export declare function writeFileAsync(filePath: string, data: string): Promise<
|
|
|
48
48
|
* - Normalizes duplicate slashes and returns a platform-correct path.
|
|
49
49
|
*/
|
|
50
50
|
export declare function getOutputPath(outputTemplate: string | ((language: string, namespace?: string) => string) | undefined, language: string, namespace?: string): string;
|
|
51
|
+
/**
|
|
52
|
+
* Extracts the namespace value from a concrete file path by matching it against
|
|
53
|
+
* the output template.
|
|
54
|
+
*
|
|
55
|
+
* Given a template like `src/{{namespace}}/locales/{{language}}.json` and a file
|
|
56
|
+
* path like `src/widgets/component/locales/en.json`, this returns `widgets/component`.
|
|
57
|
+
*
|
|
58
|
+
* This handles multi-segment namespaces (namespaces containing `/`) which
|
|
59
|
+
* `basename()` cannot recover.
|
|
60
|
+
*
|
|
61
|
+
* @param outputTemplate - The output path template string (must contain `{{namespace}}`)
|
|
62
|
+
* @param language - The language value used when the file was generated
|
|
63
|
+
* @param filePath - The concrete file path to extract the namespace from
|
|
64
|
+
* @returns The namespace string, or `undefined` if the path doesn't match the template
|
|
65
|
+
*/
|
|
66
|
+
export declare function extractNamespaceFromPath(outputTemplate: string, language: string, filePath: string): string | undefined;
|
|
51
67
|
/**
|
|
52
68
|
* Dynamically loads a translation file, supporting .json, .js, and .ts formats.
|
|
53
69
|
* @param filePath - The path to the translation file.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-utils.d.ts","sourceRoot":"","sources":["../../src/utils/file-utils.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA;AAKpD;;;;;;;;;;;GAWG;AACH,wBAAsB,qBAAqB,CAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG5E;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,aAAa,CAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAEtE;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,cAAc,CAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEnF;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAC3B,cAAc,EAAE,MAAM,GAAG,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC,GAAG,SAAS,EACvF,QAAQ,EAAE,MAAM,EAChB,SAAS,CAAC,EAAE,MAAM,GACjB,MAAM,CA8BR;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,CAwChG;AAGD,wBAAsB,mBAAmB,CAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAQnF;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,MAAM,GAAE,oBAAoB,CAAC,SAAS,CAAC,CAAC,cAAc,CAAU,EAChE,WAAW,GAAE,MAAM,GAAG,MAAU,EAChC,UAAU,CAAC,EAAE,MAAM,GAClB,MAAM,CA6BR;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,aAAa,GAAE,oBAAoB,CAAC,SAAS,CAAC,CAAC,cAAc,CAAU,GACtE,WAAW,CAAC,oBAAoB,CAAC,SAAS,CAAC,CAAC,cAAc,CAAC,CAAC,CAO9D"}
|
|
1
|
+
{"version":3,"file":"file-utils.d.ts","sourceRoot":"","sources":["../../src/utils/file-utils.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA;AAKpD;;;;;;;;;;;GAWG;AACH,wBAAsB,qBAAqB,CAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG5E;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,aAAa,CAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAEtE;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,cAAc,CAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEnF;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAC3B,cAAc,EAAE,MAAM,GAAG,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC,GAAG,SAAS,EACvF,QAAQ,EAAE,MAAM,EAChB,SAAS,CAAC,EAAE,MAAM,GACjB,MAAM,CA8BR;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,wBAAwB,CACtC,cAAc,EAAE,MAAM,EACtB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACf,MAAM,GAAG,SAAS,CAwBpB;AAID;;;;GAIG;AACH,wBAAsB,mBAAmB,CAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,CAwChG;AAGD,wBAAsB,mBAAmB,CAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAQnF;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,MAAM,GAAE,oBAAoB,CAAC,SAAS,CAAC,CAAC,cAAc,CAAU,EAChE,WAAW,GAAE,MAAM,GAAG,MAAU,EAChC,UAAU,CAAC,EAAE,MAAM,GAClB,MAAM,CA6BR;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,aAAa,GAAE,oBAAoB,CAAC,SAAS,CAAC,CAAC,cAAc,CAAU,GACtE,WAAW,CAAC,oBAAoB,CAAC,SAAS,CAAC,CAAC,cAAc,CAAC,CAAC,CAO9D"}
|