ai-localize-cli 2.0.4 → 2.0.5

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.
Files changed (3) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/dist/cli.js +57 -28
  3. package/package.json +10 -10
package/CHANGELOG.md CHANGED
@@ -1,5 +1,49 @@
1
1
  # ai-localize-cli
2
2
 
3
+ ## 2.0.5
4
+
5
+ ### Patch Changes
6
+
7
+ - **Bug fix — `validate` always reported "valid"**: Downstream fix in `ai-localize-validators`.
8
+ The `MissingKeyValidator` now catches keys where the target language value equals the English
9
+ source placeholder (seeded by the extractor). Validation correctly reports
10
+ `Missing translation for "key" in "fr" (value equals source)` instead of silently passing.
11
+
12
+ - **Bug fix — `full-migrate` pipeline appeared to do nothing**: Three issues fixed:
13
+ 1. `staticKeys` from `ai-localize.config.json` are now correctly passed to `LocaleExtractor`
14
+ in the `full-migrate` command (the standalone `extract` command already did this).
15
+ 2. `--dry-run` mode now prints a clear yellow banner, lists every locale file that *would*
16
+ be written, and skips validation/report with an explanatory message — previously it
17
+ produced no output for the write step, making the pipeline look inactive.
18
+ 3. Validation and report phases now run only in non-dry-run mode; error/warning details
19
+ are printed inline after validation (matching the standalone `validate` command).
20
+ 4. `LocaleWriter` write counts (`X new, Y merged`) are now logged after every live write.
21
+
22
+ - **Bug fix — `report` CLI summary crashed with `RangeError`**: Downstream fix in
23
+ `ai-localize-reporting`; coverage percentage is now clamped to `[0, 100]` and all bar
24
+ renderers guard against negative `String.repeat()` calls.
25
+
26
+ ### Dependency Updates
27
+
28
+ - ai-localize-validators@2.0.5
29
+ - ai-localize-reporting@2.0.5
30
+ - ai-localize-locale-engine@2.0.5
31
+
32
+ ## 2.0.4
33
+
34
+ ### Patch Changes
35
+
36
+ - Updated dependencies
37
+ - ai-localize-scanner@2.0.4
38
+ - ai-localize-config@2.0.4
39
+ - ai-localize-shared@2.0.4
40
+ - ai-localize-aws-cloudfront@2.0.4
41
+ - ai-localize-codemods@2.0.4
42
+ - ai-localize-framework-detectors@2.0.4
43
+ - ai-localize-locale-engine@2.0.4
44
+ - ai-localize-reporting@2.0.4
45
+ - ai-localize-validators@2.0.4
46
+
3
47
  ## 2.0.3
4
48
 
5
49
  ### Minor Changes
package/dist/cli.js CHANGED
@@ -528,6 +528,17 @@ function fullMigrateCommand() {
528
528
  const { config } = await (0, import_ai_localize_config10.loadConfig)(cwd);
529
529
  cs.succeed("Configuration loaded");
530
530
  const structure = config.localeStructure ?? "nested";
531
+ const staticKeys = config.staticKeys ?? {};
532
+ const staticKeyCount = Object.keys(staticKeys).length;
533
+ if (dryRun) {
534
+ logger.info(import_chalk11.default.yellow("Dry run mode \u2014 no files will be written or modified"));
535
+ }
536
+ logger.info("Locale structure: " + import_chalk11.default.cyan(structure));
537
+ if (staticKeyCount > 0) {
538
+ logger.info(
539
+ "Static keys: " + import_chalk11.default.cyan(String(staticKeyCount)) + " (" + Object.keys(staticKeys).join(", ") + ")"
540
+ );
541
+ }
531
542
  const ss = createSpinner("Scanning for hardcoded text...").start();
532
543
  const scanner = new import_ai_localize_scanner6.ProjectScanner(config);
533
544
  const scanResult = await scanner.scan();
@@ -540,17 +551,29 @@ function fullMigrateCommand() {
540
551
  defaultLanguage: config.defaultLanguage,
541
552
  targetLanguages: config.targetLanguages,
542
553
  // Flat layout merges all keys into one file per language — no namespace splitting
543
- namespaceSplitting: structure === "nested"
554
+ namespaceSplitting: structure === "nested",
555
+ staticKeys
544
556
  });
545
557
  const { localeFiles, keyCount } = extractor.extract(uniqueTexts);
546
- es.succeed("Generated " + import_chalk11.default.green(String(keyCount)) + " locale keys");
558
+ es.succeed(
559
+ "Generated " + import_chalk11.default.green(String(keyCount)) + " locale keys" + (staticKeyCount > 0 ? import_chalk11.default.dim(" (+ " + staticKeyCount + " static)") : "")
560
+ );
547
561
  if (!dryRun) {
548
562
  const writer = new import_ai_localize_locale_engine2.LocaleWriter({
549
563
  localesDir: path9.resolve(cwd, config.localesDir),
550
564
  merge: true,
551
565
  localeStructure: structure
552
566
  });
553
- writer.write(localeFiles);
567
+ const { written, created, merged } = writer.write(localeFiles);
568
+ logger.success(
569
+ "Wrote " + written.length + " locale files (" + created.length + " new, " + merged.length + " merged)"
570
+ );
571
+ } else {
572
+ logger.info("Dry run \u2014 locale files that would be written:");
573
+ localeFiles.forEach((lf) => {
574
+ const label = structure === "flat" ? `${lf.language}.json` : `${lf.language}/${lf.namespace}.json`;
575
+ logger.info(" " + import_chalk11.default.gray(label) + " \u2014 " + Object.keys(lf.entries).length + " keys");
576
+ });
554
577
  }
555
578
  if (opts.codemods !== false) {
556
579
  const ms = createSpinner("Applying i18n codemods...").start();
@@ -560,33 +583,39 @@ function fullMigrateCommand() {
560
583
  "Codemods: " + import_chalk11.default.green(String(codemodResult.totalReplacements)) + " replacements in " + codemodResult.changedFiles + " files"
561
584
  );
562
585
  }
563
- const vs = createSpinner("Validating locale files...").start();
564
- const validator = new import_ai_localize_validators4.LocaleValidator({
565
- localesDir: path9.resolve(cwd, config.localesDir),
566
- sourceDir: path9.resolve(cwd, config.sourceDir),
567
- defaultLanguage: config.defaultLanguage,
568
- targetLanguages: config.targetLanguages
569
- });
570
- const validationResult = validator.validate();
571
- vs.succeed(
572
- validationResult.valid ? import_chalk11.default.green("Locale files valid!") : import_chalk11.default.yellow(
573
- validationResult.errors.length + " errors, " + validationResult.warnings.length + " warnings"
574
- )
575
- );
576
- if (opts.report !== false) {
577
- const rs = createSpinner("Generating report...").start();
578
- const report = (0, import_ai_localize_reporting2.buildReport)({ scanResult, validationResult });
579
- const reportDir = path9.resolve(cwd, opts.reportDir);
580
- const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19);
581
- const htmlPath = path9.join(reportDir, "report-" + timestamp + ".html");
582
- (0, import_ai_localize_reporting2.generateHtmlReport)(report, htmlPath);
583
- rs.succeed("Report saved to " + import_chalk11.default.cyan(htmlPath));
584
- (0, import_ai_localize_reporting2.printCliSummary)(report);
585
- logger.info(
586
- "\n View report:\n " + import_chalk11.default.underline("file://" + htmlPath)
586
+ if (dryRun) {
587
+ logger.info(import_chalk11.default.dim("Skipping validation in dry-run mode (no files were written)"));
588
+ } else {
589
+ const vs = createSpinner("Validating locale files...").start();
590
+ const validator = new import_ai_localize_validators4.LocaleValidator({
591
+ localesDir: path9.resolve(cwd, config.localesDir),
592
+ sourceDir: path9.resolve(cwd, config.sourceDir),
593
+ defaultLanguage: config.defaultLanguage,
594
+ targetLanguages: config.targetLanguages
595
+ });
596
+ const validationResult = validator.validate();
597
+ vs.succeed(
598
+ validationResult.valid ? import_chalk11.default.green("Locale files valid!") : import_chalk11.default.yellow(
599
+ validationResult.errors.length + " errors, " + validationResult.warnings.length + " warnings"
600
+ )
587
601
  );
602
+ validationResult.errors.forEach((e) => logger.error(` [${e.type}] ${e.message}`));
603
+ validationResult.warnings.forEach((w) => logger.warn(` [${w.type}] ${w.message}`));
604
+ if (opts.report !== false) {
605
+ const rs = createSpinner("Generating report...").start();
606
+ const report = (0, import_ai_localize_reporting2.buildReport)({ scanResult, validationResult });
607
+ const reportDir = path9.resolve(cwd, opts.reportDir);
608
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19);
609
+ const htmlPath = path9.join(reportDir, "report-" + timestamp + ".html");
610
+ (0, import_ai_localize_reporting2.generateHtmlReport)(report, htmlPath);
611
+ rs.succeed("Report saved to " + import_chalk11.default.cyan(htmlPath));
612
+ (0, import_ai_localize_reporting2.printCliSummary)(report);
613
+ logger.info("\n View report:\n " + import_chalk11.default.underline("file://" + htmlPath));
614
+ }
588
615
  }
589
- logger.success("Full migration complete!");
616
+ logger.success(
617
+ dryRun ? "Dry run complete \u2014 no files were modified." : "Full migration complete!"
618
+ );
590
619
  } catch (err) {
591
620
  logger.error("Migration failed: " + String(err));
592
621
  process.exit(1);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-localize-cli",
3
- "version": "2.0.4",
3
+ "version": "2.0.5",
4
4
  "description": "CLI for ai-localize-core: scan, extract, validate, codemod and migrate CDN",
5
5
  "bin": {
6
6
  "ai-localize": "./dist/cli.js"
@@ -35,15 +35,15 @@
35
35
  "chalk": "^5.3.0",
36
36
  "ora": "^8.0.1",
37
37
  "inquirer": "^9.2.12",
38
- "ai-localize-config": "2.0.4",
39
- "ai-localize-scanner": "2.0.4",
40
- "ai-localize-codemods": "2.0.4",
41
- "ai-localize-framework-detectors": "2.0.4",
42
- "ai-localize-shared": "2.0.4",
43
- "ai-localize-validators": "2.0.4",
44
- "ai-localize-aws-cloudfront": "2.0.4",
45
- "ai-localize-locale-engine": "2.0.4",
46
- "ai-localize-reporting": "2.0.4"
38
+ "ai-localize-shared": "2.0.5",
39
+ "ai-localize-config": "2.0.5",
40
+ "ai-localize-codemods": "2.0.5",
41
+ "ai-localize-framework-detectors": "2.0.5",
42
+ "ai-localize-scanner": "2.0.5",
43
+ "ai-localize-locale-engine": "2.0.5",
44
+ "ai-localize-validators": "2.0.5",
45
+ "ai-localize-aws-cloudfront": "2.0.5",
46
+ "ai-localize-reporting": "2.0.5"
47
47
  },
48
48
  "devDependencies": {
49
49
  "@types/inquirer": "^9.0.7",