lingo.dev 0.92.12 → 0.92.14

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.mjs CHANGED
@@ -621,9 +621,9 @@ function makeGitlabInitializer(spinner) {
621
621
 
622
622
  // src/cli/cmd/init.ts
623
623
  import open2 from "open";
624
- var openUrl = (path17) => {
624
+ var openUrl = (path16) => {
625
625
  const settings = getSettings(void 0);
626
- open2(`${settings.auth.webUrl}${path17}`, { wait: false });
626
+ open2(`${settings.auth.webUrl}${path16}`, { wait: false });
627
627
  };
628
628
  var throwHelpError = (option, value) => {
629
629
  if (value === "help") {
@@ -997,8 +997,8 @@ var files_default = new Command4().command("files").description("Print out the l
997
997
  } else if (type.target) {
998
998
  result.push(...targetPaths);
999
999
  }
1000
- result.forEach((path17) => {
1001
- console.log(path17);
1000
+ result.forEach((path16) => {
1001
+ console.log(path16);
1002
1002
  });
1003
1003
  }
1004
1004
  }
@@ -1025,8 +1025,7 @@ import {
1025
1025
  } from "@lingo.dev/_spec";
1026
1026
  import { Command as Command6 } from "interactive-commander";
1027
1027
  import Z3 from "zod";
1028
- import _25 from "lodash";
1029
- import * as path14 from "path";
1028
+ import _26 from "lodash";
1030
1029
  import Ora5 from "ora";
1031
1030
 
1032
1031
  // src/cli/loaders/_utils.ts
@@ -1250,7 +1249,7 @@ function createTextFileLoader(pathPattern) {
1250
1249
  const trimmedResult = result.trim();
1251
1250
  return trimmedResult;
1252
1251
  },
1253
- async push(locale, data, _29, originalLocale) {
1252
+ async push(locale, data, _30, originalLocale) {
1254
1253
  const draftPath = pathPattern.replaceAll("[locale]", locale);
1255
1254
  const finalPath = path10.resolve(draftPath);
1256
1255
  const dirPath = path10.dirname(finalPath);
@@ -1674,9 +1673,9 @@ function createHtmlLoader() {
1674
1673
  const bDepth = b.split("/").length;
1675
1674
  return aDepth - bDepth;
1676
1675
  });
1677
- paths.forEach((path17) => {
1678
- const value = data[path17];
1679
- const [nodePath, attribute] = path17.split("#");
1676
+ paths.forEach((path16) => {
1677
+ const value = data[path16];
1678
+ const [nodePath, attribute] = path16.split("#");
1680
1679
  const [rootTag, ...indices] = nodePath.split("/");
1681
1680
  let parent = rootTag === "head" ? document.head : document.body;
1682
1681
  let current = parent;
@@ -1779,7 +1778,7 @@ function createPropertiesLoader() {
1779
1778
  return result;
1780
1779
  },
1781
1780
  async push(locale, payload) {
1782
- const result = Object.entries(payload).filter(([_29, value]) => value != null).map(([key, value]) => `${key}=${value}`).join("\n");
1781
+ const result = Object.entries(payload).filter(([_30, value]) => value != null).map(([key, value]) => `${key}=${value}`).join("\n");
1783
1782
  return result;
1784
1783
  }
1785
1784
  });
@@ -2046,10 +2045,10 @@ function createUnlocalizableLoader(isCacheRestore = false, returnUnlocalizedKeys
2046
2045
  }
2047
2046
  }
2048
2047
  return false;
2049
- }).map(([key, _29]) => key);
2050
- const result = _10.omitBy(input2, (_29, key) => passthroughKeys.includes(key));
2048
+ }).map(([key, _30]) => key);
2049
+ const result = _10.omitBy(input2, (_30, key) => passthroughKeys.includes(key));
2051
2050
  if (returnUnlocalizedKeys) {
2052
- result.unlocalizable = _10.omitBy(input2, (_29, key) => !passthroughKeys.includes(key));
2051
+ result.unlocalizable = _10.omitBy(input2, (_30, key) => !passthroughKeys.includes(key));
2053
2052
  }
2054
2053
  return result;
2055
2054
  },
@@ -2766,18 +2765,18 @@ function createRawDatoValue(parsedDatoValue, originalRawDatoValue, isClean = fal
2766
2765
  }
2767
2766
  function serializeStructuredText(rawStructuredText) {
2768
2767
  return serializeStructuredTextNode(rawStructuredText);
2769
- function serializeStructuredTextNode(node, path17 = [], acc = {}) {
2768
+ function serializeStructuredTextNode(node, path16 = [], acc = {}) {
2770
2769
  if ("document" in node) {
2771
- return serializeStructuredTextNode(node.document, [...path17, "document"], acc);
2770
+ return serializeStructuredTextNode(node.document, [...path16, "document"], acc);
2772
2771
  }
2773
2772
  if (!_15.isNil(node.value)) {
2774
- acc[[...path17, "value"].join(".")] = node.value;
2773
+ acc[[...path16, "value"].join(".")] = node.value;
2775
2774
  } else if (_15.get(node, "type") === "block") {
2776
- acc[[...path17, "item"].join(".")] = serializeBlock(node.item);
2775
+ acc[[...path16, "item"].join(".")] = serializeBlock(node.item);
2777
2776
  }
2778
2777
  if (node.children) {
2779
2778
  for (let i = 0; i < node.children.length; i++) {
2780
- serializeStructuredTextNode(node.children[i], [...path17, i.toString()], acc);
2779
+ serializeStructuredTextNode(node.children[i], [...path16, i.toString()], acc);
2781
2780
  }
2782
2781
  }
2783
2782
  return acc;
@@ -2836,8 +2835,8 @@ function deserializeBlockList(parsedBlockList, originalRawBlockList, isClean = f
2836
2835
  }
2837
2836
  function deserializeStructuredText(parsedStructuredText, originalRawStructuredText) {
2838
2837
  const result = _15.cloneDeep(originalRawStructuredText);
2839
- for (const [path17, value] of _15.entries(parsedStructuredText)) {
2840
- const realPath = _15.chain(path17.split(".")).flatMap((s) => !_15.isNaN(_15.toNumber(s)) ? ["children", s] : s).value();
2838
+ for (const [path16, value] of _15.entries(parsedStructuredText)) {
2839
+ const realPath = _15.chain(path16.split(".")).flatMap((s) => !_15.isNaN(_15.toNumber(s)) ? ["children", s] : s).value();
2841
2840
  const deserializedValue = createRawDatoValue(value, _15.get(originalRawStructuredText, realPath), true);
2842
2841
  _15.set(result, realPath, deserializedValue);
2843
2842
  }
@@ -3219,15 +3218,15 @@ function parseTypeScript(input2) {
3219
3218
  function extractStringsFromDefaultExport(ast) {
3220
3219
  let extracted = {};
3221
3220
  traverse(ast, {
3222
- ExportDefaultDeclaration(path17) {
3223
- const { declaration } = path17.node;
3221
+ ExportDefaultDeclaration(path16) {
3222
+ const { declaration } = path16.node;
3224
3223
  const decl = unwrapTSAsExpression(declaration);
3225
3224
  if (t.isObjectExpression(decl)) {
3226
3225
  extracted = objectExpressionToObject(decl);
3227
3226
  } else if (t.isArrayExpression(decl)) {
3228
3227
  extracted = arrayExpressionToArray(decl);
3229
3228
  } else if (t.isIdentifier(decl)) {
3230
- const binding = path17.scope.bindings[decl.name];
3229
+ const binding = path16.scope.bindings[decl.name];
3231
3230
  if (binding && t.isVariableDeclarator(binding.path.node) && binding.path.node.init) {
3232
3231
  const initRaw = binding.path.node.init;
3233
3232
  const init = initRaw ? unwrapTSAsExpression(initRaw) : initRaw;
@@ -3292,8 +3291,8 @@ function arrayExpressionToArray(arrayExpression) {
3292
3291
  function updateStringsInDefaultExport(ast, data) {
3293
3292
  let modified = false;
3294
3293
  traverse(ast, {
3295
- ExportDefaultDeclaration(path17) {
3296
- const { declaration } = path17.node;
3294
+ ExportDefaultDeclaration(path16) {
3295
+ const { declaration } = path16.node;
3297
3296
  const decl = unwrapTSAsExpression(declaration);
3298
3297
  if (t.isObjectExpression(decl)) {
3299
3298
  modified = updateStringsInObjectExpression(decl, data) || modified;
@@ -3302,7 +3301,7 @@ function updateStringsInDefaultExport(ast, data) {
3302
3301
  modified = updateStringsInArrayExpression(decl, data) || modified;
3303
3302
  }
3304
3303
  } else if (t.isIdentifier(decl)) {
3305
- modified = updateStringsInExportedIdentifier(path17, data) || modified;
3304
+ modified = updateStringsInExportedIdentifier(path16, data) || modified;
3306
3305
  }
3307
3306
  }
3308
3307
  });
@@ -3373,9 +3372,9 @@ function updateStringsInArrayExpression(arrayExpression, incoming) {
3373
3372
  });
3374
3373
  return modified;
3375
3374
  }
3376
- function updateStringsInExportedIdentifier(path17, data) {
3377
- const exportName = path17.node.declaration.name;
3378
- const binding = path17.scope.bindings[exportName];
3375
+ function updateStringsInExportedIdentifier(path16, data) {
3376
+ const exportName = path16.node.declaration.name;
3377
+ const binding = path16.scope.bindings[exportName];
3379
3378
  if (!binding || !binding.path.node) return false;
3380
3379
  if (t.isVariableDeclarator(binding.path.node) && binding.path.node.init) {
3381
3380
  const initRaw = binding.path.node.init;
@@ -4006,8 +4005,24 @@ function createLingoLocalizer(params) {
4006
4005
 
4007
4006
  // src/cli/processor/basic.ts
4008
4007
  import { generateText } from "ai";
4008
+ import _24 from "lodash";
4009
4009
  function createBasicTranslator(model, systemPrompt) {
4010
4010
  return async (input2, onProgress) => {
4011
+ const chunks = extractPayloadChunks(input2.processableData);
4012
+ const subResults = [];
4013
+ for (let i = 0; i < chunks.length; i++) {
4014
+ const chunk = chunks[i];
4015
+ const result2 = await doJob({
4016
+ ...input2,
4017
+ processableData: chunk
4018
+ });
4019
+ subResults.push(result2);
4020
+ onProgress(i / chunks.length * 100, chunk, result2);
4021
+ }
4022
+ const result = _24.merge({}, ...subResults);
4023
+ return result;
4024
+ };
4025
+ async function doJob(input2) {
4011
4026
  if (!Object.keys(input2.processableData).length) {
4012
4027
  return input2.processableData;
4013
4028
  }
@@ -4053,7 +4068,41 @@ function createBasicTranslator(model, systemPrompt) {
4053
4068
  });
4054
4069
  const result = JSON.parse(response.text);
4055
4070
  return result?.data || {};
4056
- };
4071
+ }
4072
+ }
4073
+ function extractPayloadChunks(payload) {
4074
+ const idealBatchItemSize = 250;
4075
+ const batchSize = 25;
4076
+ const result = [];
4077
+ let currentChunk = {};
4078
+ let currentChunkItemCount = 0;
4079
+ const payloadEntries = Object.entries(payload);
4080
+ for (let i = 0; i < payloadEntries.length; i++) {
4081
+ const [key, value] = payloadEntries[i];
4082
+ currentChunk[key] = value;
4083
+ currentChunkItemCount++;
4084
+ const currentChunkSize = countWordsInRecord(currentChunk);
4085
+ if (currentChunkSize > idealBatchItemSize || currentChunkItemCount >= batchSize || i === payloadEntries.length - 1) {
4086
+ result.push(currentChunk);
4087
+ currentChunk = {};
4088
+ currentChunkItemCount = 0;
4089
+ }
4090
+ }
4091
+ return result;
4092
+ }
4093
+ function countWordsInRecord(payload) {
4094
+ if (Array.isArray(payload)) {
4095
+ return payload.reduce((acc, item) => acc + countWordsInRecord(item), 0);
4096
+ } else if (typeof payload === "object" && payload !== null) {
4097
+ return Object.values(payload).reduce(
4098
+ (acc, item) => acc + countWordsInRecord(item),
4099
+ 0
4100
+ );
4101
+ } else if (typeof payload === "string") {
4102
+ return payload.trim().split(/\s+/).filter(Boolean).length;
4103
+ } else {
4104
+ return 0;
4105
+ }
4057
4106
  }
4058
4107
 
4059
4108
  // src/cli/processor/index.ts
@@ -4179,7 +4228,7 @@ async function trackEvent(distinctId, event, properties) {
4179
4228
  }
4180
4229
 
4181
4230
  // src/cli/utils/delta.ts
4182
- import _24 from "lodash";
4231
+ import _25 from "lodash";
4183
4232
  import z from "zod";
4184
4233
 
4185
4234
  // src/cli/utils/fs.ts
@@ -4228,9 +4277,9 @@ function createDeltaProcessor(fileKey) {
4228
4277
  return checkIfFileExists(lockfilePath);
4229
4278
  },
4230
4279
  async calculateDelta(params) {
4231
- let added = _24.difference(Object.keys(params.sourceData), Object.keys(params.targetData));
4232
- let removed = _24.difference(Object.keys(params.targetData), Object.keys(params.sourceData));
4233
- const updated = _24.filter(Object.keys(params.sourceData), (key) => {
4280
+ let added = _25.difference(Object.keys(params.sourceData), Object.keys(params.targetData));
4281
+ let removed = _25.difference(Object.keys(params.targetData), Object.keys(params.sourceData));
4282
+ const updated = _25.filter(Object.keys(params.sourceData), (key) => {
4234
4283
  return md5(params.sourceData[key]) !== params.checksums[key] && params.checksums[key];
4235
4284
  });
4236
4285
  const renamed = [];
@@ -4279,14 +4328,13 @@ function createDeltaProcessor(fileKey) {
4279
4328
  await this.saveLock(lockfileData);
4280
4329
  },
4281
4330
  async createChecksums(sourceData) {
4282
- const checksums = _24.mapValues(sourceData, (value) => md5(value));
4331
+ const checksums = _25.mapValues(sourceData, (value) => md5(value));
4283
4332
  return checksums;
4284
4333
  }
4285
4334
  };
4286
4335
  }
4287
4336
 
4288
4337
  // src/cli/cmd/i18n.ts
4289
- import { flatten as flatten2, unflatten as unflatten2 } from "flat";
4290
4338
  var i18n_default = new Command6().command("i18n").description("Run Localization engine").helpOption("-h, --help", "Show help").option(
4291
4339
  "--locale <locale>",
4292
4340
  "Locale to process",
@@ -4369,7 +4417,7 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
4369
4417
  if (flags.file?.length) {
4370
4418
  buckets = buckets.map((bucket) => {
4371
4419
  const paths = bucket.paths.filter(
4372
- (path17) => flags.file.find((file) => path17.pathPattern?.includes(file))
4420
+ (path16) => flags.file.find((file) => path16.pathPattern?.includes(file))
4373
4421
  );
4374
4422
  return { ...bucket, paths };
4375
4423
  }).filter((bucket) => bucket.paths.length > 0);
@@ -4382,8 +4430,8 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
4382
4430
  ora.info(`\x1B[36mProcessing only filtered buckets:\x1B[0m`);
4383
4431
  buckets.map((bucket) => {
4384
4432
  ora.info(` ${bucket.type}:`);
4385
- bucket.paths.forEach((path17) => {
4386
- ora.info(` - ${path17.pathPattern}`);
4433
+ bucket.paths.forEach((path16) => {
4434
+ ora.info(` - ${path16.pathPattern}`);
4387
4435
  });
4388
4436
  });
4389
4437
  }
@@ -4426,73 +4474,6 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
4426
4474
  } else {
4427
4475
  ora.succeed("Localization cache loaded");
4428
4476
  }
4429
- for (const bucket of buckets) {
4430
- if (bucket.type !== "json") {
4431
- continue;
4432
- }
4433
- ora.start("Validating localization state...");
4434
- for (const bucketPath of bucket.paths) {
4435
- const sourceLocale = resolveOverriddenLocale3(
4436
- i18nConfig.locale.source,
4437
- bucketPath.delimiter
4438
- );
4439
- const deltaProcessor = createDeltaProcessor(bucketPath.pathPattern);
4440
- const sourcePath = path14.join(
4441
- process.cwd(),
4442
- bucketPath.pathPattern.replace("[locale]", sourceLocale)
4443
- );
4444
- const sourceContent = tryReadFile(sourcePath, null);
4445
- const sourceData = JSON.parse(sourceContent || "{}");
4446
- const sourceFlattenedData = flatten2(sourceData, {
4447
- delimiter: "/",
4448
- transformKey(key) {
4449
- return encodeURIComponent(key);
4450
- }
4451
- });
4452
- for (const _targetLocale of targetLocales) {
4453
- const targetLocale = resolveOverriddenLocale3(
4454
- _targetLocale,
4455
- bucketPath.delimiter
4456
- );
4457
- const targetPath = path14.join(
4458
- process.cwd(),
4459
- bucketPath.pathPattern.replace("[locale]", targetLocale)
4460
- );
4461
- const targetContent = tryReadFile(targetPath, null);
4462
- const targetData = JSON.parse(targetContent || "{}");
4463
- const targetFlattenedData = flatten2(targetData, {
4464
- delimiter: "/",
4465
- transformKey(key) {
4466
- return encodeURIComponent(key);
4467
- }
4468
- });
4469
- const checksums = await deltaProcessor.loadChecksums();
4470
- const delta = await deltaProcessor.calculateDelta({
4471
- sourceData: sourceFlattenedData,
4472
- targetData: targetFlattenedData,
4473
- checksums
4474
- });
4475
- if (!delta.hasChanges) {
4476
- continue;
4477
- }
4478
- for (const [oldKey, newKey] of delta.renamed) {
4479
- targetFlattenedData[newKey] = targetFlattenedData[oldKey];
4480
- delete targetFlattenedData[oldKey];
4481
- }
4482
- const updatedTargetData = unflatten2(targetFlattenedData, {
4483
- delimiter: "/",
4484
- transformKey(key) {
4485
- return decodeURIComponent(key);
4486
- }
4487
- });
4488
- await writeFile(
4489
- targetPath,
4490
- JSON.stringify(updatedTargetData, null, 2)
4491
- );
4492
- }
4493
- }
4494
- ora.succeed("Localization state check completed");
4495
- }
4496
4477
  if (flags.frozen) {
4497
4478
  ora.start("Checking for lockfile updates...");
4498
4479
  let requiresUpdate = null;
@@ -4519,7 +4500,7 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
4519
4500
  const deltaProcessor = createDeltaProcessor(bucketPath.pathPattern);
4520
4501
  const sourceChecksums = await deltaProcessor.createChecksums(sourceData);
4521
4502
  const savedChecksums = await deltaProcessor.loadChecksums();
4522
- const updatedSourceData = _25.pickBy(
4503
+ const updatedSourceData = _26.pickBy(
4523
4504
  sourceData,
4524
4505
  (value, key) => sourceChecksums[key] !== savedChecksums[key]
4525
4506
  );
@@ -4533,15 +4514,15 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
4533
4514
  bucketPath.delimiter
4534
4515
  );
4535
4516
  const { unlocalizable: targetUnlocalizable, ...targetData } = await bucketLoader.pull(targetLocale);
4536
- const missingKeys = _25.difference(
4517
+ const missingKeys = _26.difference(
4537
4518
  Object.keys(sourceData),
4538
4519
  Object.keys(targetData)
4539
4520
  );
4540
- const extraKeys = _25.difference(
4521
+ const extraKeys = _26.difference(
4541
4522
  Object.keys(targetData),
4542
4523
  Object.keys(sourceData)
4543
4524
  );
4544
- const unlocalizableDataDiff = !_25.isEqual(
4525
+ const unlocalizableDataDiff = !_26.isEqual(
4545
4526
  sourceUnlocalizable,
4546
4527
  targetUnlocalizable
4547
4528
  );
@@ -4623,13 +4604,13 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
4623
4604
  targetData,
4624
4605
  checksums: checksums2
4625
4606
  });
4626
- let processableData = _25.chain(sourceData).entries().filter(
4607
+ let processableData = _26.chain(sourceData).entries().filter(
4627
4608
  ([key, value]) => delta.added.includes(key) || delta.updated.includes(key) || !!flags.force
4628
4609
  ).fromPairs().value();
4629
4610
  if (flags.key) {
4630
- processableData = _25.pickBy(
4611
+ processableData = _26.pickBy(
4631
4612
  processableData,
4632
- (_29, key) => key === flags.key
4613
+ (_30, key) => key === flags.key
4633
4614
  );
4634
4615
  }
4635
4616
  if (flags.verbose) {
@@ -4662,12 +4643,21 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
4662
4643
  if (flags.verbose) {
4663
4644
  bucketOra.info(JSON.stringify(processedTargetData, null, 2));
4664
4645
  }
4665
- let finalTargetData = _25.merge(
4646
+ let finalTargetData = _26.merge(
4666
4647
  {},
4667
4648
  sourceData,
4668
4649
  targetData,
4669
4650
  processedTargetData
4670
4651
  );
4652
+ finalTargetData = _26.chain(finalTargetData).entries().map(([key, value]) => {
4653
+ const renaming = delta.renamed.find(
4654
+ ([oldKey, newKey]) => oldKey === key
4655
+ );
4656
+ if (!renaming) {
4657
+ return [key, value];
4658
+ }
4659
+ return [renaming[1], value];
4660
+ }).fromPairs().value();
4671
4661
  if (flags.interactive) {
4672
4662
  bucketOra.stop();
4673
4663
  const reviewedData = await reviewChanges({
@@ -4683,7 +4673,7 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
4683
4673
  `Applying changes to ${bucketPath} (${targetLocale})`
4684
4674
  );
4685
4675
  }
4686
- const finalDiffSize = _25.chain(finalTargetData).omitBy((value, key) => value === targetData[key]).size().value();
4676
+ const finalDiffSize = _26.chain(finalTargetData).omitBy((value, key) => value === targetData[key]).size().value();
4687
4677
  await bucketLoader.push(targetLocale, finalTargetData);
4688
4678
  if (finalDiffSize > 0 || flags.force) {
4689
4679
  bucketOra.succeed(
@@ -4854,7 +4844,7 @@ Reviewing changes for ${chalk2.blue(args.pathPattern)} (${chalk2.yellow(args.tar
4854
4844
  return args.currentData;
4855
4845
  }
4856
4846
  const customData = { ...args.currentData };
4857
- const changes = _25.reduce(
4847
+ const changes = _26.reduce(
4858
4848
  args.proposedData,
4859
4849
  (result, value, key) => {
4860
4850
  if (args.currentData[key] !== value) {
@@ -4923,11 +4913,11 @@ import Ora6 from "ora";
4923
4913
 
4924
4914
  // src/cli/utils/lockfile.ts
4925
4915
  import fs11 from "fs";
4926
- import path15 from "path";
4916
+ import path14 from "path";
4927
4917
  import Z4 from "zod";
4928
4918
  import YAML5 from "yaml";
4929
4919
  import { MD5 as MD52 } from "object-hash";
4930
- import _26 from "lodash";
4920
+ import _27 from "lodash";
4931
4921
  function createLockfileHelper() {
4932
4922
  return {
4933
4923
  isLockfileExists: () => {
@@ -4937,23 +4927,23 @@ function createLockfileHelper() {
4937
4927
  registerSourceData: (pathPattern, sourceData) => {
4938
4928
  const lockfile = _loadLockfile();
4939
4929
  const sectionKey = MD52(pathPattern);
4940
- const sectionChecksums = _26.mapValues(sourceData, (value) => MD52(value));
4930
+ const sectionChecksums = _27.mapValues(sourceData, (value) => MD52(value));
4941
4931
  lockfile.checksums[sectionKey] = sectionChecksums;
4942
4932
  _saveLockfile(lockfile);
4943
4933
  },
4944
4934
  registerPartialSourceData: (pathPattern, partialSourceData) => {
4945
4935
  const lockfile = _loadLockfile();
4946
4936
  const sectionKey = MD52(pathPattern);
4947
- const sectionChecksums = _26.mapValues(partialSourceData, (value) => MD52(value));
4948
- lockfile.checksums[sectionKey] = _26.merge({}, lockfile.checksums[sectionKey] ?? {}, sectionChecksums);
4937
+ const sectionChecksums = _27.mapValues(partialSourceData, (value) => MD52(value));
4938
+ lockfile.checksums[sectionKey] = _27.merge({}, lockfile.checksums[sectionKey] ?? {}, sectionChecksums);
4949
4939
  _saveLockfile(lockfile);
4950
4940
  },
4951
4941
  extractUpdatedData: (pathPattern, sourceData) => {
4952
4942
  const lockfile = _loadLockfile();
4953
4943
  const sectionKey = MD52(pathPattern);
4954
- const currentChecksums = _26.mapValues(sourceData, (value) => MD52(value));
4944
+ const currentChecksums = _27.mapValues(sourceData, (value) => MD52(value));
4955
4945
  const savedChecksums = lockfile.checksums[sectionKey] || {};
4956
- const updatedData = _26.pickBy(sourceData, (value, key) => savedChecksums[key] !== currentChecksums[key]);
4946
+ const updatedData = _27.pickBy(sourceData, (value, key) => savedChecksums[key] !== currentChecksums[key]);
4957
4947
  return updatedData;
4958
4948
  }
4959
4949
  };
@@ -4972,7 +4962,7 @@ function createLockfileHelper() {
4972
4962
  fs11.writeFileSync(lockfilePath, content);
4973
4963
  }
4974
4964
  function _getLockfilePath() {
4975
- return path15.join(process.cwd(), "i18n.lock");
4965
+ return path14.join(process.cwd(), "i18n.lock");
4976
4966
  }
4977
4967
  }
4978
4968
  var LockfileSchema = Z4.object({
@@ -5023,7 +5013,7 @@ var flagsSchema = Z5.object({
5023
5013
  // src/cli/cmd/cleanup.ts
5024
5014
  import { resolveOverriddenLocale as resolveOverriddenLocale5 } from "@lingo.dev/_spec";
5025
5015
  import { Command as Command8 } from "interactive-commander";
5026
- import _27 from "lodash";
5016
+ import _28 from "lodash";
5027
5017
  import Ora7 from "ora";
5028
5018
  var cleanup_default = new Command8().command("cleanup").description("Remove keys from target files that do not exist in the source file").helpOption("-h, --help", "Show help").option("--locale <locale>", "Specific locale to cleanup").option("--bucket <bucket>", "Specific bucket to cleanup").option("--dry-run", "Show what would be removed without making changes").option(
5029
5019
  "--verbose",
@@ -5059,7 +5049,7 @@ var cleanup_default = new Command8().command("cleanup").description("Remove keys
5059
5049
  try {
5060
5050
  const targetData = await bucketLoader.pull(targetLocale);
5061
5051
  const targetKeys = Object.keys(targetData);
5062
- const keysToRemove = _27.difference(targetKeys, sourceKeys);
5052
+ const keysToRemove = _28.difference(targetKeys, sourceKeys);
5063
5053
  if (keysToRemove.length === 0) {
5064
5054
  bucketOra.succeed(`[${targetLocale}] No keys to remove`);
5065
5055
  continue;
@@ -5068,7 +5058,7 @@ var cleanup_default = new Command8().command("cleanup").description("Remove keys
5068
5058
  bucketOra.info(`[${targetLocale}] Keys to remove: ${JSON.stringify(keysToRemove, null, 2)}`);
5069
5059
  }
5070
5060
  if (!options.dryRun) {
5071
- const cleanedData = _27.pick(targetData, sourceKeys);
5061
+ const cleanedData = _28.pick(targetData, sourceKeys);
5072
5062
  await bucketLoader.push(targetLocale, cleanedData);
5073
5063
  bucketOra.succeed(`[${targetLocale}] Removed ${keysToRemove.length} keys`);
5074
5064
  } else {
@@ -5123,7 +5113,7 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
5123
5113
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
5124
5114
  import Z6 from "zod";
5125
5115
  import { ReplexicaEngine } from "@lingo.dev/_sdk";
5126
- var mcp_default = new Command9().command("mcp").description("Use Lingo.dev model context provider with your AI agent").helpOption("-h, --help", "Show help").action(async (_29, program) => {
5116
+ var mcp_default = new Command9().command("mcp").description("Use Lingo.dev model context provider with your AI agent").helpOption("-h, --help", "Show help").action(async (_30, program) => {
5127
5117
  const apiKey = program.args[0];
5128
5118
  const settings = getSettings(apiKey);
5129
5119
  if (!settings.auth.apiKey) {
@@ -5179,7 +5169,7 @@ import { execSync as execSync2 } from "child_process";
5179
5169
 
5180
5170
  // src/cli/cmd/ci/flows/in-branch.ts
5181
5171
  import { execSync } from "child_process";
5182
- import path16 from "path";
5172
+ import path15 from "path";
5183
5173
 
5184
5174
  // src/cli/cmd/ci/flows/_base.ts
5185
5175
  var IntegrationFlow = class {
@@ -5275,7 +5265,7 @@ var InBranchFlow = class extends IntegrationFlow {
5275
5265
  return false;
5276
5266
  }
5277
5267
  }
5278
- const workingDir = path16.resolve(
5268
+ const workingDir = path15.resolve(
5279
5269
  process.cwd(),
5280
5270
  this.platformKit.config.workingDir
5281
5271
  );
@@ -5932,7 +5922,7 @@ var status_default = new Command11().command("status").description("Show the sta
5932
5922
  ora.succeed("Buckets retrieved");
5933
5923
  if (flags.file?.length) {
5934
5924
  buckets = buckets.map((bucket) => {
5935
- const paths = bucket.paths.filter((path17) => flags.file.find((file) => path17.pathPattern?.match(file)));
5925
+ const paths = bucket.paths.filter((path16) => flags.file.find((file) => path16.pathPattern?.match(file)));
5936
5926
  return { ...bucket, paths };
5937
5927
  }).filter((bucket) => bucket.paths.length > 0);
5938
5928
  if (buckets.length === 0) {
@@ -5942,8 +5932,8 @@ var status_default = new Command11().command("status").description("Show the sta
5942
5932
  ora.info(`\x1B[36mProcessing only filtered buckets:\x1B[0m`);
5943
5933
  buckets.map((bucket) => {
5944
5934
  ora.info(` ${bucket.type}:`);
5945
- bucket.paths.forEach((path17) => {
5946
- ora.info(` - ${path17.pathPattern}`);
5935
+ bucket.paths.forEach((path16) => {
5936
+ ora.info(` - ${path16.pathPattern}`);
5947
5937
  });
5948
5938
  });
5949
5939
  }
@@ -6172,10 +6162,10 @@ var status_default = new Command11().command("status").description("Show the sta
6172
6162
  if (flags.confirm && Object.keys(fileStats).length > 0) {
6173
6163
  console.log(chalk3.bold(`
6174
6164
  \u{1F4D1} BREAKDOWN BY FILE:`));
6175
- Object.entries(fileStats).sort((a, b) => b[1].wordCount - a[1].wordCount).forEach(([path17, stats]) => {
6165
+ Object.entries(fileStats).sort((a, b) => b[1].wordCount - a[1].wordCount).forEach(([path16, stats]) => {
6176
6166
  if (stats.sourceKeys === 0) return;
6177
6167
  console.log(chalk3.bold(`
6178
- \u2022 ${path17}:`));
6168
+ \u2022 ${path16}:`));
6179
6169
  console.log(` ${stats.sourceKeys} source keys, ~${stats.wordCount.toLocaleString()} source words`);
6180
6170
  const fileTable = new Table({
6181
6171
  head: ["Language", "Status", "Details"],
@@ -6377,7 +6367,7 @@ async function renderHero() {
6377
6367
  // package.json
6378
6368
  var package_default = {
6379
6369
  name: "lingo.dev",
6380
- version: "0.92.12",
6370
+ version: "0.92.14",
6381
6371
  description: "Lingo.dev CLI",
6382
6372
  private: false,
6383
6373
  publishConfig: {
@@ -6945,7 +6935,7 @@ async function plan(input2) {
6945
6935
  import chalk10 from "chalk";
6946
6936
  import { Listr as Listr3 } from "listr2";
6947
6937
  import pLimit from "p-limit";
6948
- import _28 from "lodash";
6938
+ import _29 from "lodash";
6949
6939
  var MAX_WORKER_COUNT = 10;
6950
6940
  async function execute(input2) {
6951
6941
  const effectiveConcurrency = Math.min(
@@ -6976,7 +6966,7 @@ async function execute(input2) {
6976
6966
  const workerTasks = [];
6977
6967
  for (let i = 0; i < workersCount; i++) {
6978
6968
  const assignedTasks = ctx.tasks.filter(
6979
- (_29, idx) => idx % workersCount === i
6969
+ (_30, idx) => idx % workersCount === i
6980
6970
  );
6981
6971
  workerTasks.push(
6982
6972
  createWorkerTask({
@@ -7075,7 +7065,7 @@ function createWorkerTask(args) {
7075
7065
  targetData,
7076
7066
  checksums
7077
7067
  });
7078
- const processableData = _28.chain(sourceData).entries().filter(
7068
+ const processableData = _29.chain(sourceData).entries().filter(
7079
7069
  ([key, value]) => delta.added.includes(key) || delta.updated.includes(key) || !!args.ctx.flags.force
7080
7070
  ).fromPairs().value();
7081
7071
  if (!Object.keys(processableData).length) {
@@ -7096,12 +7086,21 @@ function createWorkerTask(args) {
7096
7086
  });
7097
7087
  }
7098
7088
  );
7099
- const finalTargetData = _28.merge(
7089
+ let finalTargetData = _29.merge(
7100
7090
  {},
7101
7091
  sourceData,
7102
7092
  targetData,
7103
7093
  processedTargetData
7104
7094
  );
7095
+ finalTargetData = _29.chain(finalTargetData).entries().map(([key, value]) => {
7096
+ const renaming = delta.renamed.find(
7097
+ ([oldKey]) => oldKey === key
7098
+ );
7099
+ if (!renaming) {
7100
+ return [key, value];
7101
+ }
7102
+ return [renaming[1], value];
7103
+ }).fromPairs().value();
7105
7104
  await args.ioLimiter(async () => {
7106
7105
  await bucketLoader.pull(assignedTask.sourceLocale);
7107
7106
  await bucketLoader.push(