ai-localize-cli 2.0.7 → 3.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/CHANGELOG.md +36 -1
- package/dist/cli.js +41 -19
- package/package.json +10 -10
package/CHANGELOG.md
CHANGED
|
@@ -1,7 +1,42 @@
|
|
|
1
1
|
# ai-localize-cli
|
|
2
2
|
|
|
3
|
+
## 3.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- **`copyDefaultValues` config option** — `extract` command now passes `copyDefaultValues` from `ai-localize.config.json` to `LocaleExtractor`. When `true`, target language locale files are pre-populated with the default language's source text values instead of empty strings, ensuring the app always has a visible fallback while translators fill in proper translations.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies
|
|
12
|
+
- ai-localize-config@3.1.0
|
|
13
|
+
- ai-localize-locale-engine@3.1.0
|
|
14
|
+
|
|
15
|
+
## 3.0.0
|
|
16
|
+
|
|
17
|
+
### Major Changes
|
|
18
|
+
|
|
19
|
+
- bug fixes
|
|
20
|
+
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
- Updated dependencies
|
|
24
|
+
- ai-localize-aws-cloudfront@3.0.0
|
|
25
|
+
- ai-localize-codemods@3.0.0
|
|
26
|
+
- ai-localize-config@3.0.0
|
|
27
|
+
- ai-localize-framework-detectors@3.0.0
|
|
28
|
+
- ai-localize-locale-engine@3.0.0
|
|
29
|
+
- ai-localize-reporting@3.0.0
|
|
30
|
+
- ai-localize-scanner@3.0.0
|
|
31
|
+
- ai-localize-shared@3.0.0
|
|
32
|
+
- ai-localize-validators@3.0.0
|
|
33
|
+
|
|
3
34
|
## 2.0.7
|
|
4
35
|
|
|
36
|
+
### Fixed
|
|
37
|
+
|
|
38
|
+
- **`ai-localize scan` no longer crashes with `(0 , import_traverse.default) is not a function`** — Fixed `@babel/traverse` and `@babel/generator` CJS/ESM interop in the bundled CLI. The scanner and React codemod now work correctly when installed from npm.
|
|
39
|
+
|
|
5
40
|
### Minor Changes
|
|
6
41
|
|
|
7
42
|
- **Scanner now correctly skips CSS class names, font-family values, camelCase identifiers,
|
|
@@ -39,7 +74,7 @@
|
|
|
39
74
|
- **Bug fix — `full-migrate` pipeline appeared to do nothing**: Three issues fixed:
|
|
40
75
|
1. `staticKeys` from `ai-localize.config.json` are now correctly passed to `LocaleExtractor`
|
|
41
76
|
in the `full-migrate` command (the standalone `extract` command already did this).
|
|
42
|
-
2. `--dry-run` mode now prints a clear yellow banner, lists every locale file that
|
|
77
|
+
2. `--dry-run` mode now prints a clear yellow banner, lists every locale file that _would_
|
|
43
78
|
be written, and skips validation/report with an explanatory message — previously it
|
|
44
79
|
produced no output for the write step, making the pipeline look inactive.
|
|
45
80
|
3. Validation and report phases now run only in non-dry-run mode; error/warning details
|
package/dist/cli.js
CHANGED
|
@@ -247274,7 +247274,7 @@ var require_lib5 = __commonJS({
|
|
|
247274
247274
|
Object.defineProperty(exports2, "traverse", {
|
|
247275
247275
|
enumerable: true,
|
|
247276
247276
|
get: function() {
|
|
247277
|
-
return
|
|
247277
|
+
return _traverse3.default;
|
|
247278
247278
|
}
|
|
247279
247279
|
});
|
|
247280
247280
|
Object.defineProperty(exports2, "traverseFast", {
|
|
@@ -247405,15 +247405,15 @@ var require_lib5 = __commonJS({
|
|
|
247405
247405
|
var _getBindingIdentifiers = require_getBindingIdentifiers();
|
|
247406
247406
|
var _getOuterBindingIdentifiers = require_getOuterBindingIdentifiers();
|
|
247407
247407
|
var _getFunctionName = require_getFunctionName();
|
|
247408
|
-
var
|
|
247409
|
-
Object.keys(
|
|
247408
|
+
var _traverse3 = require_traverse();
|
|
247409
|
+
Object.keys(_traverse3).forEach(function(key) {
|
|
247410
247410
|
if (key === "default" || key === "__esModule") return;
|
|
247411
247411
|
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
247412
|
-
if (key in exports2 && exports2[key] ===
|
|
247412
|
+
if (key in exports2 && exports2[key] === _traverse3[key]) return;
|
|
247413
247413
|
Object.defineProperty(exports2, key, {
|
|
247414
247414
|
enumerable: true,
|
|
247415
247415
|
get: function() {
|
|
247416
|
-
return
|
|
247416
|
+
return _traverse3[key];
|
|
247417
247417
|
}
|
|
247418
247418
|
});
|
|
247419
247419
|
});
|
|
@@ -248038,8 +248038,8 @@ var require_traverseForScope = __commonJS({
|
|
|
248038
248038
|
if (exploded.enter || exploded.exit) {
|
|
248039
248039
|
throw new Error("Should not be used with enter/exit visitors.");
|
|
248040
248040
|
}
|
|
248041
|
-
|
|
248042
|
-
function
|
|
248041
|
+
_traverse3(path19.parentPath, path19.parent, path19.node, path19.container, path19.key, path19.listKey, path19.hub, path19);
|
|
248042
|
+
function _traverse3(parentPath, parent, node, container, key, listKey, hub, inPath) {
|
|
248043
248043
|
if (!node) {
|
|
248044
248044
|
return;
|
|
248045
248045
|
}
|
|
@@ -248071,10 +248071,10 @@ var require_traverseForScope = __commonJS({
|
|
|
248071
248071
|
if (Array.isArray(prop)) {
|
|
248072
248072
|
for (let i7 = 0; i7 < prop.length; i7++) {
|
|
248073
248073
|
const value = prop[i7];
|
|
248074
|
-
|
|
248074
|
+
_traverse3(path20, node, value, prop, i7, key2);
|
|
248075
248075
|
}
|
|
248076
248076
|
} else {
|
|
248077
|
-
|
|
248077
|
+
_traverse3(path20, node, prop, node, key2, null);
|
|
248078
248078
|
}
|
|
248079
248079
|
}
|
|
248080
248080
|
if (visitor != null && visitor.exit) {
|
|
@@ -294057,7 +294057,7 @@ async function batchReplaceCdnUrls(fileUrlMap, assets, dryRun = false) {
|
|
|
294057
294057
|
}
|
|
294058
294058
|
return results;
|
|
294059
294059
|
}
|
|
294060
|
-
var fs10, nodePath2, parser3, import_traverse2, import_generator, t9, fs24, fs33, fs43, path11, path24, DEFAULT_IMPORT_PACKAGE, DEFAULT_HOOK_NAME, DEFAULT_TRANSLATION_FN, DEFAULT_ACCESSOR_STYLE, ReactCodemod, DEFAULT_TRANSLATION_FN2, VueCodemod, DEFAULT_TS_SERVICE, DEFAULT_TEMPLATE_PIPE, AngularCodemod, CdnReplacer, CodemodRunner;
|
|
294060
|
+
var fs10, nodePath2, parser3, import_traverse2, import_generator, t9, fs24, fs33, fs43, path11, path24, traverse2, generate, DEFAULT_IMPORT_PACKAGE, DEFAULT_HOOK_NAME, DEFAULT_TRANSLATION_FN, DEFAULT_ACCESSOR_STYLE, ReactCodemod, DEFAULT_TRANSLATION_FN2, VueCodemod, DEFAULT_TS_SERVICE, DEFAULT_TEMPLATE_PIPE, AngularCodemod, CdnReplacer, CodemodRunner;
|
|
294061
294061
|
var init_dist = __esm({
|
|
294062
294062
|
"../../packages/codemods/dist/index.mjs"() {
|
|
294063
294063
|
"use strict";
|
|
@@ -294072,6 +294072,8 @@ var init_dist = __esm({
|
|
|
294072
294072
|
fs43 = __toESM(require("fs"), 1);
|
|
294073
294073
|
path11 = __toESM(require("path"), 1);
|
|
294074
294074
|
path24 = __toESM(require("path"), 1);
|
|
294075
|
+
traverse2 = import_traverse2.default.default ?? import_traverse2.default;
|
|
294076
|
+
generate = import_generator.default.default ?? import_generator.default;
|
|
294075
294077
|
DEFAULT_IMPORT_PACKAGE = "react-i18next";
|
|
294076
294078
|
DEFAULT_HOOK_NAME = "useTranslation";
|
|
294077
294079
|
DEFAULT_TRANSLATION_FN = "t";
|
|
@@ -294158,7 +294160,7 @@ var init_dist = __esm({
|
|
|
294158
294160
|
}
|
|
294159
294161
|
return t9.callExpression(t9.identifier(translationFn), [t9.stringLiteral(key)]);
|
|
294160
294162
|
};
|
|
294161
|
-
(
|
|
294163
|
+
traverse2(ast, {
|
|
294162
294164
|
ImportDeclaration(nodePath22) {
|
|
294163
294165
|
if (nodePath22.node.source.value === importSpecifier2) {
|
|
294164
294166
|
hasImport = true;
|
|
@@ -294173,7 +294175,7 @@ var init_dist = __esm({
|
|
|
294173
294175
|
}
|
|
294174
294176
|
}
|
|
294175
294177
|
});
|
|
294176
|
-
(
|
|
294178
|
+
traverse2(ast, {
|
|
294177
294179
|
JSXText(nodePath22) {
|
|
294178
294180
|
const text = nodePath22.node.value.trim();
|
|
294179
294181
|
if (!text) return;
|
|
@@ -294225,7 +294227,7 @@ var init_dist = __esm({
|
|
|
294225
294227
|
this.injectHook(ast);
|
|
294226
294228
|
injectedHook = true;
|
|
294227
294229
|
}
|
|
294228
|
-
const output = (
|
|
294230
|
+
const output = generate(
|
|
294229
294231
|
ast,
|
|
294230
294232
|
{ retainLines: false, comments: true, compact: false },
|
|
294231
294233
|
this.content
|
|
@@ -294244,7 +294246,7 @@ var init_dist = __esm({
|
|
|
294244
294246
|
const hookName = this.hookName;
|
|
294245
294247
|
const translationFn = this.translationFn;
|
|
294246
294248
|
const namespace = this.namespace;
|
|
294247
|
-
(
|
|
294249
|
+
traverse2(ast, {
|
|
294248
294250
|
FunctionDeclaration(nodePath22) {
|
|
294249
294251
|
if (!isReactComponent(nodePath22.node.id?.name)) return;
|
|
294250
294252
|
injectHookIntoBody(nodePath22.node.body, hookName, translationFn, namespace);
|
|
@@ -298929,7 +298931,24 @@ var LocalizationConfigSchema = external_exports.object({
|
|
|
298929
298931
|
* Example:
|
|
298930
298932
|
* "ignoreTextPatterns": ["^MyBrand", "^theme-", "^data-"]
|
|
298931
298933
|
*/
|
|
298932
|
-
ignoreTextPatterns: external_exports.array(external_exports.string()).default([])
|
|
298934
|
+
ignoreTextPatterns: external_exports.array(external_exports.string()).default([]),
|
|
298935
|
+
/**
|
|
298936
|
+
* When `true`, target language locale files are pre-populated with the same
|
|
298937
|
+
* source text values as the default language instead of empty strings.
|
|
298938
|
+
*
|
|
298939
|
+
* This ensures the app always has a visible fallback value while translators
|
|
298940
|
+
* work on proper translations. Empty-string values cause the UI to show
|
|
298941
|
+
* nothing at all for untranslated keys.
|
|
298942
|
+
*
|
|
298943
|
+
* Applies to both `extract` (new files) and `sync` (adding missing keys to
|
|
298944
|
+
* existing files).
|
|
298945
|
+
*
|
|
298946
|
+
* Defaults to `false`.
|
|
298947
|
+
*
|
|
298948
|
+
* Example:
|
|
298949
|
+
* "copyDefaultValues": true
|
|
298950
|
+
*/
|
|
298951
|
+
copyDefaultValues: external_exports.boolean().default(false)
|
|
298933
298952
|
});
|
|
298934
298953
|
async function loadConfig(cwd = process.cwd(), overrides = {}) {
|
|
298935
298954
|
dotenv.config({ path: path2.join(cwd, ".env") });
|
|
@@ -299339,6 +299358,7 @@ var os = __toESM(require("os"), 1);
|
|
|
299339
299358
|
var crypto22 = __toESM(require("crypto"), 1);
|
|
299340
299359
|
var import_child_process = require("child_process");
|
|
299341
299360
|
var path42 = __toESM(require("path"), 1);
|
|
299361
|
+
var traverse = import_traverse.default.default ?? import_traverse.default;
|
|
299342
299362
|
var BUILTIN_TRANSLATION_IMPORT_SOURCES = /* @__PURE__ */ new Set([
|
|
299343
299363
|
"react-i18next",
|
|
299344
299364
|
"i18next",
|
|
@@ -299634,7 +299654,7 @@ var AstScanner = class {
|
|
|
299634
299654
|
return this.regexFallbackScan();
|
|
299635
299655
|
}
|
|
299636
299656
|
this.collectTranslationImports(ast);
|
|
299637
|
-
(
|
|
299657
|
+
traverse(ast, {
|
|
299638
299658
|
// ── JSX text nodes: <h1>Welcome</h1> ───────────────────────────────────
|
|
299639
299659
|
JSXText: (nodePath3) => {
|
|
299640
299660
|
const text = normalizeText(nodePath3.node.value);
|
|
@@ -300271,7 +300291,8 @@ var LocaleExtractor = class {
|
|
|
300271
300291
|
defaultLanguage: options.defaultLanguage || "en",
|
|
300272
300292
|
targetLanguages: options.targetLanguages || [],
|
|
300273
300293
|
namespaceSplitting: options.namespaceSplitting ?? true,
|
|
300274
|
-
staticKeys: options.staticKeys ?? {}
|
|
300294
|
+
staticKeys: options.staticKeys ?? {},
|
|
300295
|
+
copyDefaultValues: options.copyDefaultValues ?? false
|
|
300275
300296
|
};
|
|
300276
300297
|
}
|
|
300277
300298
|
extract(detectedTexts) {
|
|
@@ -300314,7 +300335,7 @@ var LocaleExtractor = class {
|
|
|
300314
300335
|
for (const lang of allLanguages) {
|
|
300315
300336
|
for (const [namespace, entries] of namespaceMap) {
|
|
300316
300337
|
const isDefault = lang === this.options.defaultLanguage;
|
|
300317
|
-
const langEntries = isDefault ? { ...entries } : Object.fromEntries(Object.keys(entries).map((k7) => [k7, ""]));
|
|
300338
|
+
const langEntries = isDefault || this.options.copyDefaultValues ? { ...entries } : Object.fromEntries(Object.keys(entries).map((k7) => [k7, ""]));
|
|
300318
300339
|
localeFiles.push({ language: lang, namespace, entries: langEntries, filePath: "" });
|
|
300319
300340
|
}
|
|
300320
300341
|
}
|
|
@@ -300469,7 +300490,8 @@ function extractCommand() {
|
|
|
300469
300490
|
targetLanguages: config2.targetLanguages,
|
|
300470
300491
|
namespaceSplitting: structure === "nested",
|
|
300471
300492
|
// flat mode does not need namespace splitting
|
|
300472
|
-
staticKeys
|
|
300493
|
+
staticKeys,
|
|
300494
|
+
copyDefaultValues: config2.copyDefaultValues
|
|
300473
300495
|
});
|
|
300474
300496
|
const { localeFiles, keyCount, namespaces } = extractor.extract(uniqueTexts);
|
|
300475
300497
|
logger.info(
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ai-localize-cli",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"description": "CLI for ai-localize-core: scan, extract, validate, codemod and migrate CDN",
|
|
5
5
|
"author": "ai-localize-core contributors",
|
|
6
6
|
"license": "MIT",
|
|
@@ -46,15 +46,15 @@
|
|
|
46
46
|
"chalk": "^5.3.0",
|
|
47
47
|
"ora": "^8.0.1",
|
|
48
48
|
"inquirer": "^9.2.12",
|
|
49
|
-
"ai-localize-
|
|
50
|
-
"ai-localize-
|
|
51
|
-
"ai-localize-
|
|
52
|
-
"ai-localize-
|
|
53
|
-
"ai-localize-
|
|
54
|
-
"ai-localize-
|
|
55
|
-
"ai-localize-
|
|
56
|
-
"ai-localize-aws-cloudfront": "
|
|
57
|
-
"ai-localize-reporting": "
|
|
49
|
+
"ai-localize-shared": "3.0.0",
|
|
50
|
+
"ai-localize-config": "3.1.0",
|
|
51
|
+
"ai-localize-codemods": "3.0.0",
|
|
52
|
+
"ai-localize-scanner": "3.0.0",
|
|
53
|
+
"ai-localize-framework-detectors": "3.0.0",
|
|
54
|
+
"ai-localize-validators": "3.0.0",
|
|
55
|
+
"ai-localize-locale-engine": "3.1.0",
|
|
56
|
+
"ai-localize-aws-cloudfront": "3.0.0",
|
|
57
|
+
"ai-localize-reporting": "3.0.0"
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
60
|
"@types/inquirer": "^9.0.7",
|