lingo.dev 0.101.0 → 0.102.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/build/cli.cjs CHANGED
@@ -4542,9 +4542,7 @@ function reorderKeys(data, originalInput) {
4542
4542
  const dataKeys = new Set(Object.keys(data));
4543
4543
  for (const key of originalKeys) {
4544
4544
  if (dataKeys.has(key)) {
4545
- if (data[key]) {
4546
- orderedData[key] = reorderKeys(data[key], originalInput[key]);
4547
- }
4545
+ orderedData[key] = reorderKeys(data[key], originalInput[key]);
4548
4546
  dataKeys.delete(key);
4549
4547
  }
4550
4548
  }
@@ -8344,6 +8342,135 @@ function processRenamedKeys(delta, targetData) {
8344
8342
  }).fromPairs().value();
8345
8343
  }
8346
8344
 
8345
+ // src/cli/cmd/run/watch.ts
8346
+ var _chokidar = require('chokidar'); var chokidar = _interopRequireWildcard(_chokidar);
8347
+
8348
+ async function watch2(ctx) {
8349
+ const debounceDelay = ctx.flags.debounce || 5e3;
8350
+ console.log(_chalk2.default.hex(colors.orange)("[Watch Mode]"));
8351
+ console.log(
8352
+ `\u{1F440} Watching for changes... (Press ${_chalk2.default.yellow("Ctrl+C")} to stop)`
8353
+ );
8354
+ console.log(_chalk2.default.dim(` Debounce delay: ${debounceDelay}ms`));
8355
+ console.log("");
8356
+ const state = {
8357
+ isRunning: false,
8358
+ pendingChanges: /* @__PURE__ */ new Set()
8359
+ };
8360
+ const watchPatterns = await getWatchPatterns(ctx);
8361
+ if (watchPatterns.length === 0) {
8362
+ console.log(_chalk2.default.yellow("\u26A0\uFE0F No source files found to watch"));
8363
+ return;
8364
+ }
8365
+ console.log(_chalk2.default.dim(`Watching ${watchPatterns.length} file pattern(s):`));
8366
+ watchPatterns.forEach((pattern) => {
8367
+ console.log(_chalk2.default.dim(` \u2022 ${pattern}`));
8368
+ });
8369
+ console.log("");
8370
+ const watcher = chokidar.watch(watchPatterns, {
8371
+ ignoreInitial: true,
8372
+ persistent: true,
8373
+ awaitWriteFinish: {
8374
+ stabilityThreshold: 500,
8375
+ pollInterval: 100
8376
+ }
8377
+ });
8378
+ watcher.on("change", (path17) => {
8379
+ handleFileChange(path17, state, ctx);
8380
+ });
8381
+ watcher.on("add", (path17) => {
8382
+ handleFileChange(path17, state, ctx);
8383
+ });
8384
+ watcher.on("unlink", (path17) => {
8385
+ handleFileChange(path17, state, ctx);
8386
+ });
8387
+ watcher.on("error", (error) => {
8388
+ console.error(
8389
+ _chalk2.default.red(
8390
+ `Watch error: ${error instanceof Error ? error.message : String(error)}`
8391
+ )
8392
+ );
8393
+ });
8394
+ process.on("SIGINT", () => {
8395
+ console.log(_chalk2.default.yellow("\n\n\u{1F6D1} Stopping watch mode..."));
8396
+ watcher.close();
8397
+ process.exit(0);
8398
+ });
8399
+ await new Promise(() => {
8400
+ });
8401
+ }
8402
+ async function getWatchPatterns(ctx) {
8403
+ if (!ctx.config) return [];
8404
+ const buckets = getBuckets(ctx.config);
8405
+ const patterns = [];
8406
+ for (const bucket of buckets) {
8407
+ if (ctx.flags.bucket && !ctx.flags.bucket.includes(bucket.type)) {
8408
+ continue;
8409
+ }
8410
+ for (const bucketPath of bucket.paths) {
8411
+ if (ctx.flags.file) {
8412
+ if (!ctx.flags.file.some((f) => bucketPath.pathPattern.includes(f))) {
8413
+ continue;
8414
+ }
8415
+ }
8416
+ const sourceLocale = ctx.flags.sourceLocale || ctx.config.locale.source;
8417
+ const sourcePattern = bucketPath.pathPattern.replace(
8418
+ "[locale]",
8419
+ sourceLocale
8420
+ );
8421
+ patterns.push(sourcePattern);
8422
+ }
8423
+ }
8424
+ return patterns;
8425
+ }
8426
+ function handleFileChange(filePath, state, ctx) {
8427
+ const debounceDelay = ctx.flags.debounce || 5e3;
8428
+ state.pendingChanges.add(filePath);
8429
+ console.log(_chalk2.default.dim(`\u{1F4DD} File changed: ${filePath}`));
8430
+ if (state.debounceTimer) {
8431
+ clearTimeout(state.debounceTimer);
8432
+ }
8433
+ state.debounceTimer = setTimeout(async () => {
8434
+ if (state.isRunning) {
8435
+ console.log(
8436
+ _chalk2.default.yellow("\u23F3 Translation already in progress, skipping...")
8437
+ );
8438
+ return;
8439
+ }
8440
+ await triggerRetranslation(state, ctx);
8441
+ }, debounceDelay);
8442
+ }
8443
+ async function triggerRetranslation(state, ctx) {
8444
+ if (state.isRunning) return;
8445
+ state.isRunning = true;
8446
+ try {
8447
+ const changedFiles = Array.from(state.pendingChanges);
8448
+ state.pendingChanges.clear();
8449
+ console.log(_chalk2.default.hex(colors.green)("\n\u{1F504} Triggering retranslation..."));
8450
+ console.log(_chalk2.default.dim(`Changed files: ${changedFiles.join(", ")}`));
8451
+ console.log("");
8452
+ const runCtx = {
8453
+ ...ctx,
8454
+ tasks: [],
8455
+ results: /* @__PURE__ */ new Map()
8456
+ };
8457
+ await plan(runCtx);
8458
+ if (runCtx.tasks.length === 0) {
8459
+ console.log(_chalk2.default.dim("\u2728 No translation tasks needed"));
8460
+ } else {
8461
+ await execute(runCtx);
8462
+ await renderSummary(runCtx.results);
8463
+ }
8464
+ console.log(_chalk2.default.hex(colors.green)("\u2705 Retranslation completed"));
8465
+ console.log(_chalk2.default.dim("\u{1F440} Continuing to watch for changes...\n"));
8466
+ } catch (error) {
8467
+ console.error(_chalk2.default.red(`\u274C Retranslation failed: ${error.message}`));
8468
+ console.log(_chalk2.default.dim("\u{1F440} Continuing to watch for changes...\n"));
8469
+ } finally {
8470
+ state.isRunning = false;
8471
+ }
8472
+ }
8473
+
8347
8474
  // src/cli/cmd/run/_types.ts
8348
8475
 
8349
8476
 
@@ -8362,7 +8489,10 @@ var flagsSchema2 = _zod.z.object({
8362
8489
  concurrency: _zod.z.number().positive().default(10),
8363
8490
  debug: _zod.z.boolean().default(false),
8364
8491
  sourceLocale: _zod.z.string().optional(),
8365
- targetLocale: _zod.z.array(_zod.z.string()).optional()
8492
+ targetLocale: _zod.z.array(_zod.z.string()).optional(),
8493
+ watch: _zod.z.boolean().default(false),
8494
+ debounce: _zod.z.number().positive().default(5e3)
8495
+ // 5 seconds default
8366
8496
  });
8367
8497
 
8368
8498
  // src/cli/cmd/run/_utils.ts
@@ -8413,6 +8543,13 @@ var run_default = new (0, _interactivecommander.Command)().command("run").descri
8413
8543
  "--concurrency <concurrency>",
8414
8544
  "Number of concurrent tasks to run",
8415
8545
  (val) => parseInt(val)
8546
+ ).option(
8547
+ "--watch",
8548
+ "Watch source files for changes and automatically retranslate"
8549
+ ).option(
8550
+ "--debounce <milliseconds>",
8551
+ "Debounce delay in milliseconds for watch mode (default: 5000ms)",
8552
+ (val) => parseInt(val)
8416
8553
  ).action(async (args) => {
8417
8554
  let authId = null;
8418
8555
  try {
@@ -8442,6 +8579,9 @@ var run_default = new (0, _interactivecommander.Command)().command("run").descri
8442
8579
  await renderSpacer();
8443
8580
  await renderSummary(ctx.results);
8444
8581
  await renderSpacer();
8582
+ if (ctx.flags.watch) {
8583
+ await watch2(ctx);
8584
+ }
8445
8585
  trackEvent(authId, "cmd.run.success", {
8446
8586
  config: ctx.config,
8447
8587
  flags: ctx.flags
@@ -9759,7 +9899,7 @@ async function renderHero2() {
9759
9899
  // package.json
9760
9900
  var package_default = {
9761
9901
  name: "lingo.dev",
9762
- version: "0.101.0",
9902
+ version: "0.102.0",
9763
9903
  description: "Lingo.dev CLI",
9764
9904
  private: false,
9765
9905
  publishConfig: {
@@ -9894,6 +10034,7 @@ var package_default = {
9894
10034
  ai: "^4.3.15",
9895
10035
  bitbucket: "^2.12.0",
9896
10036
  chalk: "^5.4.1",
10037
+ chokidar: "^4.0.3",
9897
10038
  "cli-progress": "^3.12.0",
9898
10039
  "cli-table3": "^0.6.5",
9899
10040
  cors: "^2.8.5",
@@ -9962,6 +10103,7 @@ var package_default = {
9962
10103
  },
9963
10104
  devDependencies: {
9964
10105
  "@types/babel__generator": "^7.27.0",
10106
+ "@types/chokidar": "^2.1.7",
9965
10107
  "@types/cli-progress": "^3.11.6",
9966
10108
  "@types/cors": "^2.8.17",
9967
10109
  "@types/diff": "^7.0.0",