ai-localize-cli 1.0.0 → 1.0.1
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/cli.js +77 -77
- package/package.json +10 -10
- package/src/cli.ts +1 -1
- package/src/commands/cleanup.ts +3 -3
- package/src/commands/extract.ts +3 -3
- package/src/commands/full-migrate.ts +6 -6
- package/src/commands/init.ts +2 -2
- package/src/commands/migrate-cdn.ts +3 -3
- package/src/commands/replace-cdn.ts +5 -5
- package/src/commands/report.ts +4 -4
- package/src/commands/scan.ts +3 -3
- package/src/commands/upload-assets.ts +3 -3
- package/src/commands/validate.ts +2 -2
package/dist/cli.js
CHANGED
|
@@ -25,7 +25,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
25
25
|
// src/cli.ts
|
|
26
26
|
var import_commander11 = require("commander");
|
|
27
27
|
var import_chalk12 = __toESM(require("chalk"));
|
|
28
|
-
var
|
|
28
|
+
var import_ai_localize_shared5 = require("ai-localize-shared");
|
|
29
29
|
|
|
30
30
|
// src/commands/init.ts
|
|
31
31
|
var import_commander = require("commander");
|
|
@@ -50,8 +50,8 @@ function createSpinner(text) {
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
// src/commands/init.ts
|
|
53
|
-
var
|
|
54
|
-
var
|
|
53
|
+
var import_ai_localize_config = require("ai-localize-config");
|
|
54
|
+
var import_ai_localize_framework_detectors = require("ai-localize-framework-detectors");
|
|
55
55
|
function initCommand() {
|
|
56
56
|
return new import_commander.Command("init").description("Initialize ai-localize configuration in the current project").option("-f, --framework <type>", "Override framework detection").option("--cwd <path>", "Working directory", process.cwd()).action(async (opts) => {
|
|
57
57
|
logger.header("ai-localize init");
|
|
@@ -60,12 +60,12 @@ function initCommand() {
|
|
|
60
60
|
const cwd = opts.cwd;
|
|
61
61
|
let framework = opts.framework;
|
|
62
62
|
if (!framework) {
|
|
63
|
-
framework = (0,
|
|
63
|
+
framework = (0, import_ai_localize_framework_detectors.detectFramework)(cwd);
|
|
64
64
|
spinner.succeed("Detected framework: " + import_chalk2.default.cyan(framework));
|
|
65
65
|
} else {
|
|
66
66
|
spinner.succeed("Using framework: " + import_chalk2.default.cyan(framework));
|
|
67
67
|
}
|
|
68
|
-
const configPath = (0,
|
|
68
|
+
const configPath = (0, import_ai_localize_config.writeDefaultConfig)(cwd, framework);
|
|
69
69
|
logger.success("Config created: " + import_chalk2.default.cyan(configPath));
|
|
70
70
|
} catch (err) {
|
|
71
71
|
spinner.fail("Initialization failed");
|
|
@@ -79,25 +79,25 @@ function initCommand() {
|
|
|
79
79
|
var import_commander2 = require("commander");
|
|
80
80
|
var import_chalk3 = __toESM(require("chalk"));
|
|
81
81
|
var path = __toESM(require("path"));
|
|
82
|
-
var
|
|
83
|
-
var
|
|
84
|
-
var
|
|
82
|
+
var import_ai_localize_config2 = require("ai-localize-config");
|
|
83
|
+
var import_ai_localize_scanner = require("ai-localize-scanner");
|
|
84
|
+
var import_ai_localize_shared = require("ai-localize-shared");
|
|
85
85
|
function scanCommand() {
|
|
86
86
|
return new import_commander2.Command("scan").description("Scan project for hardcoded texts and asset references").option("--incremental", "Scan only changed files based on git diff").option("--staged", "Scan only git staged files").option("--cwd <path>", "Working directory", process.cwd()).option("--output <path>", "Output JSON file path").action(async (opts) => {
|
|
87
87
|
logger.header("ai-localize scan");
|
|
88
88
|
const spinner = createSpinner("Loading configuration...").start();
|
|
89
89
|
try {
|
|
90
90
|
const cwd = opts.cwd;
|
|
91
|
-
const { config } = await (0,
|
|
91
|
+
const { config } = await (0, import_ai_localize_config2.loadConfig)(cwd);
|
|
92
92
|
spinner.succeed("Configuration loaded");
|
|
93
93
|
let files;
|
|
94
94
|
if (opts.staged || opts.incremental) {
|
|
95
|
-
const git = new
|
|
95
|
+
const git = new import_ai_localize_scanner.GitScanner(cwd);
|
|
96
96
|
files = opts.staged ? git.getStagedFiles() : git.getChangedFiles();
|
|
97
97
|
logger.info("Changed files: " + import_chalk3.default.cyan(String(files.length)));
|
|
98
98
|
}
|
|
99
99
|
const scanSpinner = createSpinner("Scanning files...").start();
|
|
100
|
-
const scanner = new
|
|
100
|
+
const scanner = new import_ai_localize_scanner.ProjectScanner(config);
|
|
101
101
|
const result = await scanner.scan({ files });
|
|
102
102
|
scanSpinner.succeed("Scanned " + import_chalk3.default.cyan(String(result.scannedFiles)) + " files in " + import_chalk3.default.cyan(result.duration + "ms"));
|
|
103
103
|
logger.info("Hardcoded texts: " + import_chalk3.default.yellow(String(result.detectedTexts.length)));
|
|
@@ -105,7 +105,7 @@ function scanCommand() {
|
|
|
105
105
|
logger.info("Legacy CDN URLs: " + import_chalk3.default.red(String(result.legacyCdnUrls.length)));
|
|
106
106
|
if (opts.output) {
|
|
107
107
|
const outPath = path.resolve(cwd, opts.output);
|
|
108
|
-
(0,
|
|
108
|
+
(0, import_ai_localize_shared.writeJson)(outPath, result);
|
|
109
109
|
logger.success("Results saved to " + import_chalk3.default.cyan(outPath));
|
|
110
110
|
}
|
|
111
111
|
} catch (err) {
|
|
@@ -120,24 +120,24 @@ function scanCommand() {
|
|
|
120
120
|
var import_commander3 = require("commander");
|
|
121
121
|
var import_chalk4 = __toESM(require("chalk"));
|
|
122
122
|
var path2 = __toESM(require("path"));
|
|
123
|
-
var
|
|
124
|
-
var
|
|
125
|
-
var
|
|
123
|
+
var import_ai_localize_config3 = require("ai-localize-config");
|
|
124
|
+
var import_ai_localize_scanner2 = require("ai-localize-scanner");
|
|
125
|
+
var import_ai_localize_locale_engine = require("ai-localize-locale-engine");
|
|
126
126
|
function extractCommand() {
|
|
127
127
|
return new import_commander3.Command("extract").description("Extract hardcoded text to locale JSON files").option("--cwd <path>", "Working directory", process.cwd()).option("--dry-run", "Preview changes without modifying files").option("--no-merge", "Overwrite existing keys").action(async (opts) => {
|
|
128
128
|
logger.header("ai-localize extract");
|
|
129
129
|
const cwd = opts.cwd;
|
|
130
130
|
const spinner = createSpinner("Loading configuration...").start();
|
|
131
131
|
try {
|
|
132
|
-
const { config } = await (0,
|
|
132
|
+
const { config } = await (0, import_ai_localize_config3.loadConfig)(cwd);
|
|
133
133
|
spinner.succeed("Configuration loaded");
|
|
134
134
|
const ss = createSpinner("Scanning for hardcoded text...").start();
|
|
135
|
-
const scanner = new
|
|
135
|
+
const scanner = new import_ai_localize_scanner2.ProjectScanner(config);
|
|
136
136
|
const scanResult = await scanner.scan();
|
|
137
137
|
ss.succeed("Found " + import_chalk4.default.cyan(String(scanResult.detectedTexts.length)) + " texts in " + scanResult.scannedFiles + " files");
|
|
138
|
-
const uniqueTexts = (0,
|
|
138
|
+
const uniqueTexts = (0, import_ai_localize_locale_engine.deduplicateTexts)(scanResult.detectedTexts);
|
|
139
139
|
logger.info("Unique texts: " + import_chalk4.default.cyan(String(uniqueTexts.length)));
|
|
140
|
-
const extractor = new
|
|
140
|
+
const extractor = new import_ai_localize_locale_engine.LocaleExtractor({
|
|
141
141
|
defaultLanguage: config.defaultLanguage,
|
|
142
142
|
targetLanguages: config.targetLanguages,
|
|
143
143
|
namespaceSplitting: true
|
|
@@ -147,7 +147,7 @@ function extractCommand() {
|
|
|
147
147
|
logger.info("Namespaces: " + import_chalk4.default.cyan(namespaces.join(", ")));
|
|
148
148
|
if (!opts.dryRun) {
|
|
149
149
|
const localesDir = path2.resolve(cwd, config.localesDir);
|
|
150
|
-
const writer = new
|
|
150
|
+
const writer = new import_ai_localize_locale_engine.LocaleWriter({ localesDir, merge: opts.merge !== false });
|
|
151
151
|
const { written, created, merged } = writer.write(localeFiles);
|
|
152
152
|
logger.success("Wrote " + written.length + " locale files (" + created.length + " new, " + merged.length + " merged)");
|
|
153
153
|
} else {
|
|
@@ -165,18 +165,18 @@ function extractCommand() {
|
|
|
165
165
|
var import_commander4 = require("commander");
|
|
166
166
|
var import_chalk5 = __toESM(require("chalk"));
|
|
167
167
|
var path3 = __toESM(require("path"));
|
|
168
|
-
var
|
|
169
|
-
var
|
|
168
|
+
var import_ai_localize_config4 = require("ai-localize-config");
|
|
169
|
+
var import_ai_localize_validators = require("ai-localize-validators");
|
|
170
170
|
function validateCommand() {
|
|
171
171
|
return new import_commander4.Command("validate").description("Validate locale files for missing/duplicate/unused keys").option("--cwd <path>", "Working directory", process.cwd()).option("--no-unused", "Skip unused key check").option("--no-duplicates", "Skip duplicate key check").option("--no-placeholders", "Skip placeholder check").option("--fail-on-warning", "Exit with error if warnings exist").action(async (opts) => {
|
|
172
172
|
logger.header("ai-localize validate");
|
|
173
173
|
const spinner = createSpinner("Loading configuration...").start();
|
|
174
174
|
try {
|
|
175
175
|
const cwd = opts.cwd;
|
|
176
|
-
const { config } = await (0,
|
|
176
|
+
const { config } = await (0, import_ai_localize_config4.loadConfig)(cwd);
|
|
177
177
|
spinner.succeed("Configuration loaded");
|
|
178
178
|
const vs = createSpinner("Validating locale files...").start();
|
|
179
|
-
const validator = new
|
|
179
|
+
const validator = new import_ai_localize_validators.LocaleValidator({
|
|
180
180
|
localesDir: path3.resolve(cwd, config.localesDir),
|
|
181
181
|
sourceDir: path3.resolve(cwd, config.sourceDir),
|
|
182
182
|
defaultLanguage: config.defaultLanguage,
|
|
@@ -209,19 +209,19 @@ var import_commander5 = require("commander");
|
|
|
209
209
|
var import_chalk6 = __toESM(require("chalk"));
|
|
210
210
|
var path4 = __toESM(require("path"));
|
|
211
211
|
var fs = __toESM(require("fs"));
|
|
212
|
-
var
|
|
213
|
-
var
|
|
214
|
-
var
|
|
212
|
+
var import_ai_localize_config5 = require("ai-localize-config");
|
|
213
|
+
var import_ai_localize_validators2 = require("ai-localize-validators");
|
|
214
|
+
var import_ai_localize_shared2 = require("ai-localize-shared");
|
|
215
215
|
function cleanupCommand() {
|
|
216
216
|
return new import_commander5.Command("cleanup").description("Remove unused locale keys from translation files").option("--cwd <path>", "Working directory", process.cwd()).option("--dry-run", "Preview changes without modifying files").action(async (opts) => {
|
|
217
217
|
logger.header("ai-localize cleanup");
|
|
218
218
|
const spinner = createSpinner("Validating keys...").start();
|
|
219
219
|
try {
|
|
220
220
|
const cwd = opts.cwd;
|
|
221
|
-
const { config } = await (0,
|
|
221
|
+
const { config } = await (0, import_ai_localize_config5.loadConfig)(cwd);
|
|
222
222
|
const localesDir = path4.resolve(cwd, config.localesDir);
|
|
223
223
|
const sourceDir = path4.resolve(cwd, config.sourceDir);
|
|
224
|
-
const validator = new
|
|
224
|
+
const validator = new import_ai_localize_validators2.UnusedKeyValidator(localesDir, sourceDir, config.defaultLanguage);
|
|
225
225
|
const { unusedKeys } = validator.validate();
|
|
226
226
|
spinner.succeed("Found " + import_chalk6.default.yellow(String(unusedKeys.length)) + " unused keys");
|
|
227
227
|
if (unusedKeys.length === 0) {
|
|
@@ -236,7 +236,7 @@ function cleanupCommand() {
|
|
|
236
236
|
for (const nsFile of nsFiles) {
|
|
237
237
|
const ns = nsFile.replace(".json", "");
|
|
238
238
|
const fp = path4.join(defaultDir, nsFile);
|
|
239
|
-
const entries = (0,
|
|
239
|
+
const entries = (0, import_ai_localize_shared2.readJsonSafe)(fp) || {};
|
|
240
240
|
for (const key of unusedKeys) {
|
|
241
241
|
const lk = key.startsWith(ns + ".") ? key.slice(ns.length + 1) : null;
|
|
242
242
|
if (lk && lk in entries) {
|
|
@@ -244,7 +244,7 @@ function cleanupCommand() {
|
|
|
244
244
|
removed++;
|
|
245
245
|
}
|
|
246
246
|
}
|
|
247
|
-
(0,
|
|
247
|
+
(0, import_ai_localize_shared2.writeJson)(fp, entries);
|
|
248
248
|
}
|
|
249
249
|
logger.success("Removed " + removed + " unused keys");
|
|
250
250
|
} else {
|
|
@@ -262,16 +262,16 @@ function cleanupCommand() {
|
|
|
262
262
|
var import_commander6 = require("commander");
|
|
263
263
|
var import_chalk7 = __toESM(require("chalk"));
|
|
264
264
|
var path5 = __toESM(require("path"));
|
|
265
|
-
var
|
|
266
|
-
var
|
|
267
|
-
var
|
|
265
|
+
var import_ai_localize_config6 = require("ai-localize-config");
|
|
266
|
+
var import_ai_localize_scanner3 = require("ai-localize-scanner");
|
|
267
|
+
var import_ai_localize_aws_cloudfront = require("ai-localize-aws-cloudfront");
|
|
268
268
|
function migrateCdnCommand() {
|
|
269
269
|
return new import_commander6.Command("migrate-cdn").description("Migrate legacy CDN URLs to CloudFront").option("--cwd <path>", "Working directory", process.cwd()).option("--assets-dir <path>", "Local assets directory to upload").option("--dry-run", "Preview changes without executing").option("--invalidate", "Invalidate CloudFront cache after upload").action(async (opts) => {
|
|
270
270
|
logger.header("ai-localize migrate-cdn");
|
|
271
271
|
const spinner = createSpinner("Loading configuration...").start();
|
|
272
272
|
try {
|
|
273
273
|
const cwd = opts.cwd;
|
|
274
|
-
const { config } = await (0,
|
|
274
|
+
const { config } = await (0, import_ai_localize_config6.loadConfig)(cwd);
|
|
275
275
|
if (!config.aws?.bucket) {
|
|
276
276
|
spinner.fail("AWS configuration missing");
|
|
277
277
|
logger.error("Set aws.bucket and aws.distributionId in ai-localize.config.json");
|
|
@@ -279,14 +279,14 @@ function migrateCdnCommand() {
|
|
|
279
279
|
}
|
|
280
280
|
spinner.succeed("Configuration loaded");
|
|
281
281
|
const ss = createSpinner("Scanning for legacy CDN URLs...").start();
|
|
282
|
-
const scanner = new
|
|
282
|
+
const scanner = new import_ai_localize_scanner3.ProjectScanner(config);
|
|
283
283
|
const scanResult = await scanner.scan();
|
|
284
284
|
ss.succeed("Found " + import_chalk7.default.yellow(String(scanResult.legacyCdnUrls.length)) + " legacy CDN URLs");
|
|
285
285
|
if (scanResult.legacyCdnUrls.length === 0) {
|
|
286
286
|
logger.success("No legacy CDN URLs found!");
|
|
287
287
|
return;
|
|
288
288
|
}
|
|
289
|
-
const migrator = new
|
|
289
|
+
const migrator = new import_ai_localize_aws_cloudfront.CdnMigrator(config.aws);
|
|
290
290
|
const result = await migrator.migrate({
|
|
291
291
|
sourceDir: path5.resolve(cwd, config.sourceDir),
|
|
292
292
|
assetsDir: path5.resolve(cwd, opts.assetsDir),
|
|
@@ -311,22 +311,22 @@ function migrateCdnCommand() {
|
|
|
311
311
|
var import_commander7 = require("commander");
|
|
312
312
|
var import_chalk8 = __toESM(require("chalk"));
|
|
313
313
|
var path6 = __toESM(require("path"));
|
|
314
|
-
var
|
|
315
|
-
var
|
|
316
|
-
var
|
|
314
|
+
var import_ai_localize_config7 = require("ai-localize-config");
|
|
315
|
+
var import_ai_localize_aws_cloudfront2 = require("ai-localize-aws-cloudfront");
|
|
316
|
+
var import_ai_localize_shared3 = require("ai-localize-shared");
|
|
317
317
|
function uploadAssetsCommand() {
|
|
318
318
|
return new import_commander7.Command("upload-assets").description("Upload local assets to AWS S3").option("--cwd <path>", "Working directory", process.cwd()).option("--assets-dir <path>", "Directory containing assets to upload").option("--force", "Force upload even if file already exists with same hash").option("--output <path>", "Output manifest JSON path").action(async (opts) => {
|
|
319
319
|
logger.header("ai-localize upload-assets");
|
|
320
320
|
const spinner = createSpinner("Loading configuration...").start();
|
|
321
321
|
try {
|
|
322
322
|
const cwd = opts.cwd;
|
|
323
|
-
const { config } = await (0,
|
|
323
|
+
const { config } = await (0, import_ai_localize_config7.loadConfig)(cwd);
|
|
324
324
|
if (!config.aws?.bucket) {
|
|
325
325
|
spinner.fail("AWS configuration missing");
|
|
326
326
|
process.exit(1);
|
|
327
327
|
}
|
|
328
328
|
spinner.succeed("Configuration loaded");
|
|
329
|
-
const uploader = new
|
|
329
|
+
const uploader = new import_ai_localize_aws_cloudfront2.S3Uploader(config.aws);
|
|
330
330
|
const assetsDir = path6.resolve(cwd, opts.assetsDir);
|
|
331
331
|
const uploadSpinner = createSpinner("Uploading assets...").start();
|
|
332
332
|
const result = await uploader.uploadDirectory({
|
|
@@ -339,7 +339,7 @@ function uploadAssetsCommand() {
|
|
|
339
339
|
uploadSpinner.succeed("Uploaded " + import_chalk8.default.green(String(result.uploaded.length)) + " (" + result.skipped.length + " skipped)");
|
|
340
340
|
if (opts.output) {
|
|
341
341
|
const outPath = path6.resolve(cwd, opts.output);
|
|
342
|
-
(0,
|
|
342
|
+
(0, import_ai_localize_shared3.writeJson)(outPath, [...result.uploaded, ...result.skipped]);
|
|
343
343
|
logger.success("Manifest saved to " + import_chalk8.default.cyan(outPath));
|
|
344
344
|
}
|
|
345
345
|
} catch (err) {
|
|
@@ -354,24 +354,24 @@ function uploadAssetsCommand() {
|
|
|
354
354
|
var import_commander8 = require("commander");
|
|
355
355
|
var import_chalk9 = __toESM(require("chalk"));
|
|
356
356
|
var path7 = __toESM(require("path"));
|
|
357
|
-
var
|
|
358
|
-
var
|
|
359
|
-
var
|
|
360
|
-
var
|
|
357
|
+
var import_ai_localize_config8 = require("ai-localize-config");
|
|
358
|
+
var import_ai_localize_scanner4 = require("ai-localize-scanner");
|
|
359
|
+
var import_ai_localize_shared4 = require("ai-localize-shared");
|
|
360
|
+
var import_ai_localize_codemods = require("ai-localize-codemods");
|
|
361
361
|
function replaceCdnCommand() {
|
|
362
362
|
return new import_commander8.Command("replace-cdn").description("Replace legacy CDN URLs with CloudFront URLs in source files").option("--cwd <path>", "Working directory", process.cwd()).option("--manifest <path>", "Path to upload manifest JSON").option("--dry-run", "Preview changes without executing").action(async (opts) => {
|
|
363
363
|
logger.header("ai-localize replace-cdn");
|
|
364
364
|
const spinner = createSpinner("Loading configuration...").start();
|
|
365
365
|
try {
|
|
366
366
|
const cwd = opts.cwd;
|
|
367
|
-
const { config } = await (0,
|
|
367
|
+
const { config } = await (0, import_ai_localize_config8.loadConfig)(cwd);
|
|
368
368
|
spinner.succeed("Configuration loaded");
|
|
369
369
|
let assets = [];
|
|
370
370
|
if (opts.manifest) {
|
|
371
|
-
assets = (0,
|
|
371
|
+
assets = (0, import_ai_localize_shared4.readJsonSafe)(path7.resolve(cwd, opts.manifest)) || [];
|
|
372
372
|
}
|
|
373
373
|
const ss = createSpinner("Scanning for legacy CDN URLs...").start();
|
|
374
|
-
const scanner = new
|
|
374
|
+
const scanner = new import_ai_localize_scanner4.ProjectScanner(config);
|
|
375
375
|
const scanResult = await scanner.scan();
|
|
376
376
|
ss.succeed("Found " + import_chalk9.default.yellow(String(scanResult.legacyCdnUrls.length)) + " legacy CDN URLs");
|
|
377
377
|
if (scanResult.legacyCdnUrls.length === 0) {
|
|
@@ -380,7 +380,7 @@ function replaceCdnCommand() {
|
|
|
380
380
|
}
|
|
381
381
|
if (!opts.dryRun) {
|
|
382
382
|
const rs = createSpinner("Replacing URLs...").start();
|
|
383
|
-
const replacedCount = await (0,
|
|
383
|
+
const replacedCount = await (0, import_ai_localize_codemods.batchReplaceCdnUrls)(
|
|
384
384
|
path7.resolve(cwd, config.sourceDir),
|
|
385
385
|
scanResult.legacyCdnUrls,
|
|
386
386
|
assets
|
|
@@ -401,24 +401,24 @@ function replaceCdnCommand() {
|
|
|
401
401
|
var import_commander9 = require("commander");
|
|
402
402
|
var import_chalk10 = __toESM(require("chalk"));
|
|
403
403
|
var path8 = __toESM(require("path"));
|
|
404
|
-
var
|
|
405
|
-
var
|
|
406
|
-
var
|
|
407
|
-
var
|
|
404
|
+
var import_ai_localize_config9 = require("ai-localize-config");
|
|
405
|
+
var import_ai_localize_scanner5 = require("ai-localize-scanner");
|
|
406
|
+
var import_ai_localize_validators3 = require("ai-localize-validators");
|
|
407
|
+
var import_ai_localize_reporting = require("ai-localize-reporting");
|
|
408
408
|
function reportCommand() {
|
|
409
409
|
return new import_commander9.Command("report").description("Generate JSON and HTML localization reports").option("--cwd <path>", "Working directory", process.cwd()).option("--output-dir <path>", "Output directory for reports", ".ai-localize-reports").option("--no-html", "Skip HTML report generation").action(async (opts) => {
|
|
410
410
|
logger.header("ai-localize report");
|
|
411
411
|
const spinner = createSpinner("Loading configuration...").start();
|
|
412
412
|
try {
|
|
413
413
|
const cwd = opts.cwd;
|
|
414
|
-
const { config } = await (0,
|
|
414
|
+
const { config } = await (0, import_ai_localize_config9.loadConfig)(cwd);
|
|
415
415
|
spinner.succeed("Configuration loaded");
|
|
416
416
|
const ss = createSpinner("Scanning project...").start();
|
|
417
|
-
const scanner = new
|
|
417
|
+
const scanner = new import_ai_localize_scanner5.ProjectScanner(config);
|
|
418
418
|
const scanResult = await scanner.scan();
|
|
419
419
|
ss.succeed("Scanned " + scanResult.scannedFiles + " files");
|
|
420
420
|
const vs = createSpinner("Validating locale files...").start();
|
|
421
|
-
const validator = new
|
|
421
|
+
const validator = new import_ai_localize_validators3.LocaleValidator({
|
|
422
422
|
localesDir: path8.resolve(cwd, config.localesDir),
|
|
423
423
|
sourceDir: path8.resolve(cwd, config.sourceDir),
|
|
424
424
|
defaultLanguage: config.defaultLanguage,
|
|
@@ -428,12 +428,12 @@ function reportCommand() {
|
|
|
428
428
|
vs.succeed("Validation complete");
|
|
429
429
|
const outDir = path8.resolve(cwd, opts.outputDir);
|
|
430
430
|
const rs = createSpinner("Building report...").start();
|
|
431
|
-
const report = (0,
|
|
431
|
+
const report = (0, import_ai_localize_reporting.buildReport)({ scanResult, validationResult });
|
|
432
432
|
if (opts.html !== false) {
|
|
433
|
-
(0,
|
|
433
|
+
(0, import_ai_localize_reporting.generateHtmlReport)(report, outDir);
|
|
434
434
|
}
|
|
435
435
|
rs.succeed("Report generated at " + import_chalk10.default.cyan(outDir));
|
|
436
|
-
(0,
|
|
436
|
+
(0, import_ai_localize_reporting.printCliSummary)(report);
|
|
437
437
|
} catch (err) {
|
|
438
438
|
spinner.fail("Report generation failed");
|
|
439
439
|
logger.error(String(err));
|
|
@@ -446,12 +446,12 @@ function reportCommand() {
|
|
|
446
446
|
var import_commander10 = require("commander");
|
|
447
447
|
var import_chalk11 = __toESM(require("chalk"));
|
|
448
448
|
var path9 = __toESM(require("path"));
|
|
449
|
-
var
|
|
450
|
-
var
|
|
451
|
-
var
|
|
452
|
-
var
|
|
453
|
-
var
|
|
454
|
-
var
|
|
449
|
+
var import_ai_localize_config10 = require("ai-localize-config");
|
|
450
|
+
var import_ai_localize_scanner6 = require("ai-localize-scanner");
|
|
451
|
+
var import_ai_localize_locale_engine2 = require("ai-localize-locale-engine");
|
|
452
|
+
var import_ai_localize_codemods2 = require("ai-localize-codemods");
|
|
453
|
+
var import_ai_localize_validators4 = require("ai-localize-validators");
|
|
454
|
+
var import_ai_localize_reporting2 = require("ai-localize-reporting");
|
|
455
455
|
function fullMigrateCommand() {
|
|
456
456
|
return new import_commander10.Command("full-migrate").description("Run full localization pipeline: scan -> extract -> codemod -> validate -> report").option("--cwd <path>", "Working directory", process.cwd()).option("--dry-run", "Preview changes without modifying files").option("--no-codemods", "Skip codemod phase").option("--no-report", "Skip report generation").action(async (opts) => {
|
|
457
457
|
logger.header("ai-localize full-migrate");
|
|
@@ -459,15 +459,15 @@ function fullMigrateCommand() {
|
|
|
459
459
|
const dryRun = opts.dryRun;
|
|
460
460
|
try {
|
|
461
461
|
const cs = createSpinner("Loading configuration...").start();
|
|
462
|
-
const { config } = await (0,
|
|
462
|
+
const { config } = await (0, import_ai_localize_config10.loadConfig)(cwd);
|
|
463
463
|
cs.succeed("Configuration loaded");
|
|
464
464
|
const ss = createSpinner("Scanning for hardcoded text...").start();
|
|
465
|
-
const scanner = new
|
|
465
|
+
const scanner = new import_ai_localize_scanner6.ProjectScanner(config);
|
|
466
466
|
const scanResult = await scanner.scan();
|
|
467
467
|
ss.succeed("Found " + import_chalk11.default.cyan(String(scanResult.detectedTexts.length)) + " texts in " + scanResult.scannedFiles + " files");
|
|
468
468
|
const es = createSpinner("Extracting locale keys...").start();
|
|
469
|
-
const uniqueTexts = (0,
|
|
470
|
-
const extractor = new
|
|
469
|
+
const uniqueTexts = (0, import_ai_localize_locale_engine2.deduplicateTexts)(scanResult.detectedTexts);
|
|
470
|
+
const extractor = new import_ai_localize_locale_engine2.LocaleExtractor({
|
|
471
471
|
defaultLanguage: config.defaultLanguage,
|
|
472
472
|
targetLanguages: config.targetLanguages,
|
|
473
473
|
namespaceSplitting: true
|
|
@@ -475,17 +475,17 @@ function fullMigrateCommand() {
|
|
|
475
475
|
const { localeFiles, keyCount } = extractor.extract(uniqueTexts);
|
|
476
476
|
es.succeed("Generated " + import_chalk11.default.green(String(keyCount)) + " locale keys");
|
|
477
477
|
if (!dryRun) {
|
|
478
|
-
const writer = new
|
|
478
|
+
const writer = new import_ai_localize_locale_engine2.LocaleWriter({ localesDir: path9.resolve(cwd, config.localesDir), merge: true });
|
|
479
479
|
writer.write(localeFiles);
|
|
480
480
|
}
|
|
481
481
|
if (opts.codemods !== false) {
|
|
482
482
|
const ms = createSpinner("Applying i18n codemods...").start();
|
|
483
|
-
const runner = new
|
|
483
|
+
const runner = new import_ai_localize_codemods2.CodemodRunner(config);
|
|
484
484
|
const codemodResult = await runner.run(uniqueTexts, { dryRun });
|
|
485
485
|
ms.succeed("Codemods: " + import_chalk11.default.green(String(codemodResult.totalReplacements)) + " replacements in " + codemodResult.changedFiles + " files");
|
|
486
486
|
}
|
|
487
487
|
const vs = createSpinner("Validating locale files...").start();
|
|
488
|
-
const validator = new
|
|
488
|
+
const validator = new import_ai_localize_validators4.LocaleValidator({
|
|
489
489
|
localesDir: path9.resolve(cwd, config.localesDir),
|
|
490
490
|
sourceDir: path9.resolve(cwd, config.sourceDir),
|
|
491
491
|
defaultLanguage: config.defaultLanguage,
|
|
@@ -494,8 +494,8 @@ function fullMigrateCommand() {
|
|
|
494
494
|
const validationResult = validator.validate();
|
|
495
495
|
vs.succeed(validationResult.valid ? import_chalk11.default.green("Locale files valid!") : import_chalk11.default.yellow(validationResult.errors.length + " errors, " + validationResult.warnings.length + " warnings"));
|
|
496
496
|
if (opts.report !== false) {
|
|
497
|
-
const report = (0,
|
|
498
|
-
(0,
|
|
497
|
+
const report = (0, import_ai_localize_reporting2.buildReport)({ scanResult, validationResult });
|
|
498
|
+
(0, import_ai_localize_reporting2.printCliSummary)(report);
|
|
499
499
|
}
|
|
500
500
|
logger.success("Full migration complete!");
|
|
501
501
|
} catch (err) {
|
|
@@ -507,7 +507,7 @@ function fullMigrateCommand() {
|
|
|
507
507
|
|
|
508
508
|
// src/cli.ts
|
|
509
509
|
var program = new import_commander11.Command();
|
|
510
|
-
program.name("ai-localize").description(import_chalk12.default.cyan("ai-localize-core") + " \u2014 Deterministic localization + CloudFront migration platform").version(
|
|
510
|
+
program.name("ai-localize").description(import_chalk12.default.cyan("ai-localize-core") + " \u2014 Deterministic localization + CloudFront migration platform").version(import_ai_localize_shared5.PLATFORM_VERSION, "-v, --version");
|
|
511
511
|
program.addCommand(initCommand());
|
|
512
512
|
program.addCommand(scanCommand());
|
|
513
513
|
program.addCommand(extractCommand());
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ai-localize-cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "CLI for ai-localize-core: scan, extract, validate, migrate CDN",
|
|
5
5
|
"bin": {
|
|
6
6
|
"ai-localize": "./dist/cli.js"
|
|
@@ -11,15 +11,15 @@
|
|
|
11
11
|
"chalk": "^5.3.0",
|
|
12
12
|
"ora": "^8.0.1",
|
|
13
13
|
"inquirer": "^9.2.12",
|
|
14
|
-
"ai-localize-
|
|
15
|
-
"ai-localize-
|
|
16
|
-
"ai-localize-config": "1.0.
|
|
17
|
-
"ai-localize-
|
|
18
|
-
"ai-localize-scanner": "1.0.
|
|
19
|
-
"ai-localize-
|
|
20
|
-
"ai-localize-
|
|
21
|
-
"ai-localize-
|
|
22
|
-
"ai-localize-
|
|
14
|
+
"ai-localize-shared": "1.0.1",
|
|
15
|
+
"ai-localize-framework-detectors": "1.0.1",
|
|
16
|
+
"ai-localize-config": "1.0.1",
|
|
17
|
+
"ai-localize-codemods": "1.0.1",
|
|
18
|
+
"ai-localize-scanner": "1.0.1",
|
|
19
|
+
"ai-localize-validators": "1.0.1",
|
|
20
|
+
"ai-localize-locale-engine": "1.0.1",
|
|
21
|
+
"ai-localize-aws-cloudfront": "1.0.1",
|
|
22
|
+
"ai-localize-reporting": "1.0.1"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
25
|
"@types/inquirer": "^9.0.7",
|
package/src/cli.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import chalk from 'chalk';
|
|
3
|
-
import { PLATFORM_VERSION } from '
|
|
3
|
+
import { PLATFORM_VERSION } from 'ai-localize-shared';
|
|
4
4
|
import { initCommand } from './commands/init.js';
|
|
5
5
|
import { scanCommand } from './commands/scan.js';
|
|
6
6
|
import { extractCommand } from './commands/extract.js';
|
package/src/commands/cleanup.ts
CHANGED
|
@@ -4,9 +4,9 @@ import * as path from 'path';
|
|
|
4
4
|
import * as fs from 'fs';
|
|
5
5
|
import { logger } from '../utils/logger.js';
|
|
6
6
|
import { createSpinner } from '../utils/spinner.js';
|
|
7
|
-
import { loadConfig } from '
|
|
8
|
-
import { UnusedKeyValidator } from '
|
|
9
|
-
import { readJsonSafe, writeJson } from '
|
|
7
|
+
import { loadConfig } from 'ai-localize-config';
|
|
8
|
+
import { UnusedKeyValidator } from 'ai-localize-validators';
|
|
9
|
+
import { readJsonSafe, writeJson } from 'ai-localize-shared';
|
|
10
10
|
|
|
11
11
|
export function cleanupCommand(): Command {
|
|
12
12
|
return new Command('cleanup')
|
package/src/commands/extract.ts
CHANGED
|
@@ -3,9 +3,9 @@ import chalk from 'chalk';
|
|
|
3
3
|
import * as path from 'path';
|
|
4
4
|
import { logger } from '../utils/logger.js';
|
|
5
5
|
import { createSpinner } from '../utils/spinner.js';
|
|
6
|
-
import { loadConfig } from '
|
|
7
|
-
import { ProjectScanner } from '
|
|
8
|
-
import { deduplicateTexts, LocaleExtractor, LocaleWriter } from '
|
|
6
|
+
import { loadConfig } from 'ai-localize-config';
|
|
7
|
+
import { ProjectScanner } from 'ai-localize-scanner';
|
|
8
|
+
import { deduplicateTexts, LocaleExtractor, LocaleWriter } from 'ai-localize-locale-engine';
|
|
9
9
|
|
|
10
10
|
export function extractCommand(): Command {
|
|
11
11
|
return new Command('extract')
|
|
@@ -3,12 +3,12 @@ import chalk from 'chalk';
|
|
|
3
3
|
import * as path from 'path';
|
|
4
4
|
import { logger } from '../utils/logger.js';
|
|
5
5
|
import { createSpinner } from '../utils/spinner.js';
|
|
6
|
-
import { loadConfig } from '
|
|
7
|
-
import { ProjectScanner } from '
|
|
8
|
-
import { deduplicateTexts, LocaleExtractor, LocaleWriter } from '
|
|
9
|
-
import { CodemodRunner } from '
|
|
10
|
-
import { LocaleValidator } from '
|
|
11
|
-
import { buildReport, generateHtmlReport, printCliSummary } from '
|
|
6
|
+
import { loadConfig } from 'ai-localize-config';
|
|
7
|
+
import { ProjectScanner } from 'ai-localize-scanner';
|
|
8
|
+
import { deduplicateTexts, LocaleExtractor, LocaleWriter } from 'ai-localize-locale-engine';
|
|
9
|
+
import { CodemodRunner } from 'ai-localize-codemods';
|
|
10
|
+
import { LocaleValidator } from 'ai-localize-validators';
|
|
11
|
+
import { buildReport, generateHtmlReport, printCliSummary } from 'ai-localize-reporting';
|
|
12
12
|
|
|
13
13
|
export function fullMigrateCommand(): Command {
|
|
14
14
|
return new Command('full-migrate')
|
package/src/commands/init.ts
CHANGED
|
@@ -2,8 +2,8 @@ import { Command } from 'commander';
|
|
|
2
2
|
import chalk from 'chalk';
|
|
3
3
|
import { logger } from '../utils/logger.js';
|
|
4
4
|
import { createSpinner } from '../utils/spinner.js';
|
|
5
|
-
import { writeDefaultConfig } from '
|
|
6
|
-
import { detectFramework } from '
|
|
5
|
+
import { writeDefaultConfig } from 'ai-localize-config';
|
|
6
|
+
import { detectFramework } from 'ai-localize-framework-detectors';
|
|
7
7
|
|
|
8
8
|
export function initCommand(): Command {
|
|
9
9
|
return new Command('init')
|
|
@@ -3,9 +3,9 @@ import chalk from 'chalk';
|
|
|
3
3
|
import * as path from 'path';
|
|
4
4
|
import { logger } from '../utils/logger.js';
|
|
5
5
|
import { createSpinner } from '../utils/spinner.js';
|
|
6
|
-
import { loadConfig } from '
|
|
7
|
-
import { ProjectScanner } from '
|
|
8
|
-
import { CdnMigrator } from '
|
|
6
|
+
import { loadConfig } from 'ai-localize-config';
|
|
7
|
+
import { ProjectScanner } from 'ai-localize-scanner';
|
|
8
|
+
import { CdnMigrator } from 'ai-localize-aws-cloudfront';
|
|
9
9
|
|
|
10
10
|
export function migrateCdnCommand(): Command {
|
|
11
11
|
return new Command('migrate-cdn')
|
|
@@ -3,11 +3,11 @@ import chalk from 'chalk';
|
|
|
3
3
|
import * as path from 'path';
|
|
4
4
|
import { logger } from '../utils/logger.js';
|
|
5
5
|
import { createSpinner } from '../utils/spinner.js';
|
|
6
|
-
import { loadConfig } from '
|
|
7
|
-
import { ProjectScanner } from '
|
|
8
|
-
import { readJsonSafe } from '
|
|
9
|
-
import type { CloudFrontAsset } from '
|
|
10
|
-
import { batchReplaceCdnUrls } from '
|
|
6
|
+
import { loadConfig } from 'ai-localize-config';
|
|
7
|
+
import { ProjectScanner } from 'ai-localize-scanner';
|
|
8
|
+
import { readJsonSafe } from 'ai-localize-shared';
|
|
9
|
+
import type { CloudFrontAsset } from 'ai-localize-shared';
|
|
10
|
+
import { batchReplaceCdnUrls } from 'ai-localize-codemods';
|
|
11
11
|
|
|
12
12
|
export function replaceCdnCommand(): Command {
|
|
13
13
|
return new Command('replace-cdn')
|
package/src/commands/report.ts
CHANGED
|
@@ -3,10 +3,10 @@ import chalk from 'chalk';
|
|
|
3
3
|
import * as path from 'path';
|
|
4
4
|
import { logger } from '../utils/logger.js';
|
|
5
5
|
import { createSpinner } from '../utils/spinner.js';
|
|
6
|
-
import { loadConfig } from '
|
|
7
|
-
import { ProjectScanner } from '
|
|
8
|
-
import { LocaleValidator } from '
|
|
9
|
-
import { buildReport, generateHtmlReport, printCliSummary } from '
|
|
6
|
+
import { loadConfig } from 'ai-localize-config';
|
|
7
|
+
import { ProjectScanner } from 'ai-localize-scanner';
|
|
8
|
+
import { LocaleValidator } from 'ai-localize-validators';
|
|
9
|
+
import { buildReport, generateHtmlReport, printCliSummary } from 'ai-localize-reporting';
|
|
10
10
|
|
|
11
11
|
export function reportCommand(): Command {
|
|
12
12
|
return new Command('report')
|
package/src/commands/scan.ts
CHANGED
|
@@ -3,9 +3,9 @@ import chalk from 'chalk';
|
|
|
3
3
|
import * as path from 'path';
|
|
4
4
|
import { logger } from '../utils/logger.js';
|
|
5
5
|
import { createSpinner } from '../utils/spinner.js';
|
|
6
|
-
import { loadConfig } from '
|
|
7
|
-
import { ProjectScanner, GitScanner } from '
|
|
8
|
-
import { writeJson } from '
|
|
6
|
+
import { loadConfig } from 'ai-localize-config';
|
|
7
|
+
import { ProjectScanner, GitScanner } from 'ai-localize-scanner';
|
|
8
|
+
import { writeJson } from 'ai-localize-shared';
|
|
9
9
|
|
|
10
10
|
export function scanCommand(): Command {
|
|
11
11
|
return new Command('scan')
|
|
@@ -3,9 +3,9 @@ import chalk from 'chalk';
|
|
|
3
3
|
import * as path from 'path';
|
|
4
4
|
import { logger } from '../utils/logger.js';
|
|
5
5
|
import { createSpinner } from '../utils/spinner.js';
|
|
6
|
-
import { loadConfig } from '
|
|
7
|
-
import { S3Uploader } from '
|
|
8
|
-
import { writeJson } from '
|
|
6
|
+
import { loadConfig } from 'ai-localize-config';
|
|
7
|
+
import { S3Uploader } from 'ai-localize-aws-cloudfront';
|
|
8
|
+
import { writeJson } from 'ai-localize-shared';
|
|
9
9
|
|
|
10
10
|
export function uploadAssetsCommand(): Command {
|
|
11
11
|
return new Command('upload-assets')
|
package/src/commands/validate.ts
CHANGED
|
@@ -3,8 +3,8 @@ import chalk from 'chalk';
|
|
|
3
3
|
import * as path from 'path';
|
|
4
4
|
import { logger } from '../utils/logger.js';
|
|
5
5
|
import { createSpinner } from '../utils/spinner.js';
|
|
6
|
-
import { loadConfig } from '
|
|
7
|
-
import { LocaleValidator } from '
|
|
6
|
+
import { loadConfig } from 'ai-localize-config';
|
|
7
|
+
import { LocaleValidator } from 'ai-localize-validators';
|
|
8
8
|
|
|
9
9
|
export function validateCommand(): Command {
|
|
10
10
|
return new Command('validate')
|