lingo.dev 0.74.14 → 0.74.16

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
@@ -263,15 +263,173 @@ function _getConfigFilePath() {
263
263
  }
264
264
 
265
265
  // src/cli/cmd/init.ts
266
- import { defaultConfig, resolveLocaleCode, bucketTypes } from "@lingo.dev/_spec";
267
- import fs3 from "fs";
268
- import path3 from "path";
266
+ import { defaultConfig, resolveLocaleCode as resolveLocaleCode2, bucketTypes } from "@lingo.dev/_spec";
267
+ import fs4 from "fs";
268
+ import path5 from "path";
269
269
  import { spawn } from "child_process";
270
+ import _3 from "lodash";
271
+ import { checkbox, confirm, input } from "@inquirer/prompts";
272
+
273
+ // src/cli/utils/find-locale-paths.ts
274
+ import path3 from "path";
275
+ import { glob } from "glob";
270
276
  import _2 from "lodash";
271
- import { confirm } from "@inquirer/prompts";
272
- var openUrl = (path9) => {
277
+ import { resolveLocaleCode } from "@lingo.dev/_spec";
278
+ function findLocaleFiles(bucket) {
279
+ switch (bucket) {
280
+ case "json":
281
+ return findLocaleFilesWithExtension(".json");
282
+ case "yaml":
283
+ return findLocaleFilesWithExtension(".yml");
284
+ case "flutter":
285
+ return findLocaleFilesWithExtension(".arb");
286
+ case "android":
287
+ return findLocaleFilesWithExtension(".xml");
288
+ case "markdown":
289
+ return findLocaleFilesWithExtension(".md");
290
+ case "xcode-xcstrings":
291
+ return findLocaleFilesForFilename("Localizable.xcstrings");
292
+ case "xcode-strings":
293
+ return findLocaleFilesForFilename("Localizable.strings");
294
+ case "xcode-stringsdict":
295
+ return findLocaleFilesForFilename("Localizable.stringsdict");
296
+ default:
297
+ throw new Error(`Unsupported bucket type: ${bucket}`);
298
+ }
299
+ }
300
+ function findLocaleFilesWithExtension(ext) {
301
+ const files = glob.sync(`**/*${ext}`, {
302
+ ignore: ["node_modules/**", "package*.json", "i18n.json", "lingo.json"]
303
+ });
304
+ const localeFilePattern = new RegExp(`[/\\\\]([a-z]{2}(-[A-Z]{2})?)${ext}$`);
305
+ const localeDirectoryPattern = new RegExp(`[/\\\\]([a-z]{2}(-[A-Z]{2})?)[/\\\\][^/\\\\]+${ext}$`);
306
+ const potentialLocaleFiles = files.filter(
307
+ (file) => localeFilePattern.test(file) || localeDirectoryPattern.test(file)
308
+ );
309
+ const localeFilesAndPatterns = potentialLocaleFiles.map((file) => {
310
+ const match = file.match(new RegExp(`[/|\\\\]([a-z]{2}(-[A-Z]{2})?)(/|\\\\|${ext})`));
311
+ const locale = match?.[1];
312
+ const localeInDir = match?.[3] !== ext;
313
+ const filePattern = localeInDir ? file.replace(`/${locale}/`, `/[locale]/`) : path3.join(path3.dirname(file), `[locale]${ext}`);
314
+ return { file, locale, pattern: filePattern };
315
+ }).filter(({ locale }) => {
316
+ try {
317
+ resolveLocaleCode(locale);
318
+ return true;
319
+ } catch (e) {
320
+ }
321
+ return false;
322
+ });
323
+ const grouppedFilesAndPatterns = _2.groupBy(localeFilesAndPatterns, "pattern");
324
+ const patterns = Object.keys(grouppedFilesAndPatterns);
325
+ if (patterns.length > 0) {
326
+ return { found: true, patterns };
327
+ }
328
+ return { found: false, patterns: [`i18n/[locale]${ext}`] };
329
+ }
330
+ function findLocaleFilesForFilename(fileName) {
331
+ const pattern = fileName;
332
+ const localeFiles = glob.sync(`**/${fileName}`, {
333
+ ignore: ["node_modules/**", "package*.json", "i18n.json", "lingo.json"]
334
+ });
335
+ const localeFilesAndPatterns = localeFiles.map((file) => ({
336
+ file,
337
+ pattern: path3.join(path3.dirname(file), pattern)
338
+ }));
339
+ const grouppedFilesAndPatterns = _2.groupBy(localeFilesAndPatterns, "pattern");
340
+ const patterns = Object.keys(grouppedFilesAndPatterns);
341
+ if (patterns.length > 0) {
342
+ return { found: true, patterns };
343
+ }
344
+ return { found: false, patterns: [fileName] };
345
+ }
346
+
347
+ // src/cli/utils/ensure-patterns.ts
348
+ import fs3 from "fs";
349
+ import path4 from "path";
350
+ function ensurePatterns(patterns, source) {
351
+ if (patterns.length === 0) {
352
+ throw new Error("No patterns found");
353
+ }
354
+ patterns.forEach((pattern) => {
355
+ const filePath = pattern.replace("[locale]", source);
356
+ if (!fs3.existsSync(filePath)) {
357
+ const defaultContent = getDefaultContent(path4.extname(filePath), source);
358
+ fs3.mkdirSync(path4.dirname(filePath), { recursive: true });
359
+ fs3.writeFileSync(filePath, defaultContent);
360
+ }
361
+ });
362
+ }
363
+ function getDefaultContent(ext, source) {
364
+ const defaultGreeting = "Hello from Lingo.dev";
365
+ switch (ext) {
366
+ case ".json":
367
+ case ".arb":
368
+ return `{
369
+ "greeting": "${defaultGreeting}"
370
+ }`;
371
+ case ".yml":
372
+ return `${source}:
373
+ greeting: "${defaultGreeting}"`;
374
+ case ".xml":
375
+ return `<resources>
376
+ <string name="greeting">${defaultGreeting}</string>
377
+ </resources>`;
378
+ case ".md":
379
+ return `# ${defaultGreeting}`;
380
+ case ".xcstrings":
381
+ return `{
382
+ "sourceLanguage" : "${source}",
383
+ "strings" : {
384
+ "${defaultGreeting}" : {
385
+ "extractionState" : "manual",
386
+ "localizations" : {
387
+ "${source}" : {
388
+ "stringUnit" : {
389
+ "state" : "translated",
390
+ "value" : "${defaultGreeting}"
391
+ }
392
+ }
393
+ }
394
+ }
395
+ }
396
+ }`;
397
+ case ".strings":
398
+ return `"greeting" = "${defaultGreeting}";`;
399
+ case ".stringsdict":
400
+ return `<?xml version="1.0" encoding="UTF-8"?>
401
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
402
+ <plist version="1.0">
403
+ <dict>
404
+ <key>key</key>
405
+ <dict>
406
+ <key>NSStringLocalizedFormatKey</key>
407
+ <string>%#@count@</string>
408
+ <key>count</key>
409
+ <dict>
410
+ <key>NSStringFormatSpecTypeKey</key>
411
+ <string>NSStringPluralRuleType</string>
412
+ <key>NSStringFormatValueTypeKey</key>
413
+ <string>d</string>
414
+ <key>zero</key>
415
+ <string>No items</string>
416
+ <key>one</key>
417
+ <string>One item</string>
418
+ <key>other</key>
419
+ <string>%d items</string>
420
+ </dict>
421
+ </dict>
422
+ </dict>
423
+ </plist>`;
424
+ default:
425
+ throw new Error(`Unsupported file extension: ${ext}`);
426
+ }
427
+ }
428
+
429
+ // src/cli/cmd/init.ts
430
+ var openUrl = (path11) => {
273
431
  const settings = getSettings(void 0);
274
- spawn("open", [`${settings.auth.webUrl}${path9}`]);
432
+ spawn("open", [`${settings.auth.webUrl}${path11}`]);
275
433
  };
276
434
  var throwHelpError = (option, value) => {
277
435
  if (value === "help") {
@@ -286,7 +444,7 @@ Do you need support for ${value} ${option}? Type "help" and we will.`
286
444
  var init_default = new InteractiveCommand().command("init").description("Initialize Lingo.dev project").helpOption("-h, --help", "Show help").addOption(new InteractiveOption("-f --force", "Overwrite existing config").prompt(void 0).default(false)).addOption(
287
445
  new InteractiveOption("-s --source <locale>", "Source locale").argParser((value) => {
288
446
  try {
289
- resolveLocaleCode(value);
447
+ resolveLocaleCode2(value);
290
448
  } catch (e) {
291
449
  throwHelpError("locale", value);
292
450
  }
@@ -297,7 +455,7 @@ var init_default = new InteractiveCommand().command("init").description("Initial
297
455
  const values = value.includes(",") ? value.split(",") : value.split(" ");
298
456
  values.forEach((value2) => {
299
457
  try {
300
- resolveLocaleCode(value2);
458
+ resolveLocaleCode2(value2);
301
459
  } catch (e) {
302
460
  throwHelpError("locale", value2);
303
461
  }
@@ -317,8 +475,8 @@ var init_default = new InteractiveCommand().command("init").description("Initial
317
475
  const values = value.includes(",") ? value.split(",") : value.split(" ");
318
476
  for (const p of values) {
319
477
  try {
320
- const dirPath = path3.dirname(p);
321
- const stats = fs3.statSync(dirPath);
478
+ const dirPath = path5.dirname(p);
479
+ const stats = fs4.statSync(dirPath);
322
480
  if (!stats.isDirectory()) {
323
481
  throw new Error(`${dirPath} is not a directory`);
324
482
  }
@@ -327,26 +485,60 @@ var init_default = new InteractiveCommand().command("init").description("Initial
327
485
  }
328
486
  }
329
487
  return values;
330
- }).default([])
488
+ }).prompt(void 0).default([])
331
489
  ).action(async (options) => {
332
490
  const settings = getSettings(void 0);
491
+ const isInteractive = options.interactive;
333
492
  const spinner = Ora2().start("Initializing Lingo.dev project");
334
493
  let existingConfig = await getConfig(false);
335
494
  if (existingConfig && !options.force) {
336
495
  spinner.fail("Lingo.dev project already initialized");
337
496
  return process.exit(1);
338
497
  }
339
- const newConfig = _2.cloneDeep(defaultConfig);
498
+ const newConfig = _3.cloneDeep(defaultConfig);
340
499
  newConfig.locale.source = options.source;
341
500
  newConfig.locale.targets = options.targets;
342
- newConfig.buckets = {
343
- [options.bucket]: {
344
- include: options.paths || []
501
+ if (!isInteractive) {
502
+ newConfig.buckets = {
503
+ [options.bucket]: {
504
+ include: options.paths || []
505
+ }
506
+ };
507
+ } else {
508
+ let selectedPatterns = [];
509
+ const { found, patterns } = findLocaleFiles(options.bucket);
510
+ if (found) {
511
+ spinner.succeed("Found existing locale files:");
512
+ selectedPatterns = await checkbox({
513
+ message: "Select the paths to use",
514
+ choices: patterns.map((value) => ({
515
+ value
516
+ }))
517
+ });
518
+ } else {
519
+ spinner.succeed("No existing locale files found.");
520
+ const useDefault = await confirm({
521
+ message: `Use default path ${patterns.join(", ")}?`
522
+ });
523
+ ensurePatterns(patterns, options.source);
524
+ if (useDefault) {
525
+ selectedPatterns = patterns;
526
+ }
345
527
  }
346
- };
528
+ if (selectedPatterns.length === 0) {
529
+ const customPaths = await input({
530
+ message: "Enter paths to use"
531
+ });
532
+ selectedPatterns = customPaths.includes(",") ? customPaths.split(",") : customPaths.split(" ");
533
+ }
534
+ newConfig.buckets = {
535
+ [options.bucket]: {
536
+ include: selectedPatterns || []
537
+ }
538
+ };
539
+ }
347
540
  await saveConfig(newConfig);
348
541
  spinner.succeed("Lingo.dev project initialized");
349
- const isInteractive = !process.argv.includes("-y") && !process.argv.includes("--no-interactive");
350
542
  if (isInteractive) {
351
543
  const openDocs = await confirm({ message: "Would you like to see our docs?" });
352
544
  if (openDocs) {
@@ -394,22 +586,22 @@ import { Command as Command5 } from "interactive-commander";
394
586
 
395
587
  // src/cli/cmd/show/config.ts
396
588
  import { Command as Command2 } from "interactive-commander";
397
- import _3 from "lodash";
398
- import fs4 from "fs";
399
- import path4 from "path";
589
+ import _4 from "lodash";
590
+ import fs5 from "fs";
591
+ import path6 from "path";
400
592
  import { defaultConfig as defaultConfig2 } from "@lingo.dev/_spec";
401
593
  var config_default = new Command2().command("config").description("Print out the current configuration").helpOption("-h, --help", "Show help").action(async (options) => {
402
594
  const fileConfig = loadReplexicaFileConfig();
403
- const config = _3.merge({}, defaultConfig2, fileConfig);
595
+ const config = _4.merge({}, defaultConfig2, fileConfig);
404
596
  console.log(JSON.stringify(config, null, 2));
405
597
  });
406
598
  function loadReplexicaFileConfig() {
407
- const replexicaConfigPath = path4.resolve(process.cwd(), "i18n.json");
408
- const fileExists = fs4.existsSync(replexicaConfigPath);
599
+ const replexicaConfigPath = path6.resolve(process.cwd(), "i18n.json");
600
+ const fileExists = fs5.existsSync(replexicaConfigPath);
409
601
  if (!fileExists) {
410
602
  return void 0;
411
603
  }
412
- const fileContent = fs4.readFileSync(replexicaConfigPath, "utf-8");
604
+ const fileContent = fs5.readFileSync(replexicaConfigPath, "utf-8");
413
605
  const replexicaFileConfig = JSON.parse(fileContent);
414
606
  return replexicaFileConfig;
415
607
  }
@@ -445,9 +637,9 @@ import { Command as Command4 } from "interactive-commander";
445
637
  import Ora4 from "ora";
446
638
 
447
639
  // src/cli/utils/buckets.ts
448
- import _4 from "lodash";
449
- import path5 from "path";
450
- import * as glob from "glob";
640
+ import _5 from "lodash";
641
+ import path7 from "path";
642
+ import * as glob2 from "glob";
451
643
  import { resolveOverridenLocale } from "@lingo.dev/_spec";
452
644
  function getBuckets(i18nConfig) {
453
645
  const result = Object.entries(i18nConfig.buckets).map(([bucketType, bucketEntry]) => {
@@ -477,13 +669,13 @@ function extractPathPatterns(sourceLocale, include, exclude) {
477
669
  })
478
670
  )
479
671
  );
480
- const result = _4.differenceBy(includedPatterns, excludedPatterns ?? [], (item) => item.pathPattern);
672
+ const result = _5.differenceBy(includedPatterns, excludedPatterns ?? [], (item) => item.pathPattern);
481
673
  return result;
482
674
  }
483
675
  function expandPlaceholderedGlob(_pathPattern, sourceLocale) {
484
- const absolutePathPattern = path5.resolve(_pathPattern);
485
- const pathPattern = path5.relative(process.cwd(), absolutePathPattern);
486
- if (path5.relative(process.cwd(), pathPattern).startsWith("..")) {
676
+ const absolutePathPattern = path7.resolve(_pathPattern);
677
+ const pathPattern = path7.relative(process.cwd(), absolutePathPattern);
678
+ if (path7.relative(process.cwd(), pathPattern).startsWith("..")) {
487
679
  throw new CLIError({
488
680
  message: `Invalid path pattern: ${pathPattern}. Path pattern must be within the current working directory.`,
489
681
  docUrl: "invalidPathPattern"
@@ -501,19 +693,19 @@ function expandPlaceholderedGlob(_pathPattern, sourceLocale) {
501
693
  docUrl: "invalidPathPattern"
502
694
  });
503
695
  }
504
- const pathPatternChunks = pathPattern.split(path5.sep);
696
+ const pathPatternChunks = pathPattern.split(path7.sep);
505
697
  const localeSegmentIndex = pathPatternChunks.findIndex((segment) => segment.includes("[locale]"));
506
698
  const localePlaceholderIndex = pathPatternChunks[localeSegmentIndex]?.indexOf("[locale]") ?? -1;
507
699
  const sourcePathPattern = pathPattern.replace(/\[locale\]/g, sourceLocale);
508
- const sourcePaths = glob.sync(sourcePathPattern, { follow: true, withFileTypes: true }).filter((file) => file.isFile() || file.isSymbolicLink()).map((file) => file.fullpath()).map((fullpath) => path5.relative(process.cwd(), fullpath));
700
+ const sourcePaths = glob2.sync(sourcePathPattern, { follow: true, withFileTypes: true }).filter((file) => file.isFile() || file.isSymbolicLink()).map((file) => file.fullpath()).map((fullpath) => path7.relative(process.cwd(), fullpath));
509
701
  const placeholderedPaths = sourcePaths.map((sourcePath) => {
510
- const sourcePathChunks = sourcePath.split(path5.sep);
702
+ const sourcePathChunks = sourcePath.split(path7.sep);
511
703
  if (localeSegmentIndex >= 0 && localePlaceholderIndex >= 0) {
512
704
  const placeholderedPathChunk = sourcePathChunks[localeSegmentIndex];
513
705
  const placeholderedSegment = placeholderedPathChunk.substring(0, localePlaceholderIndex) + "[locale]" + placeholderedPathChunk.substring(localePlaceholderIndex + sourceLocale.length);
514
706
  sourcePathChunks[localeSegmentIndex] = placeholderedSegment;
515
707
  }
516
- const placeholderedPath = sourcePathChunks.join(path5.sep);
708
+ const placeholderedPath = sourcePathChunks.join(path7.sep);
517
709
  return placeholderedPath;
518
710
  });
519
711
  return placeholderedPaths;
@@ -555,8 +747,8 @@ var files_default = new Command4().command("files").description("Print out the l
555
747
  } else if (type.target) {
556
748
  result.push(...targetPaths);
557
749
  }
558
- result.forEach((path9) => {
559
- console.log(path9);
750
+ result.forEach((path11) => {
751
+ console.log(path11);
560
752
  });
561
753
  }
562
754
  }
@@ -580,7 +772,7 @@ import { bucketTypeSchema, localeCodeSchema, resolveOverridenLocale as resolveOv
580
772
  import { ReplexicaEngine } from "@lingo.dev/_sdk";
581
773
  import { Command as Command6 } from "interactive-commander";
582
774
  import Z4 from "zod";
583
- import _18 from "lodash";
775
+ import _19 from "lodash";
584
776
  import Ora5 from "ora";
585
777
 
586
778
  // src/cli/loaders/_utils.ts
@@ -597,8 +789,8 @@ function composeLoaders(...loaders) {
597
789
  }
598
790
  return this;
599
791
  },
600
- pull: async (locale, input) => {
601
- let result = input;
792
+ pull: async (locale, input2) => {
793
+ let result = input2;
602
794
  for (let i = 0; i < loaders.length; i++) {
603
795
  result = await loaders[i].pull(locale, result);
604
796
  }
@@ -634,7 +826,7 @@ function createLoader(lDefinition) {
634
826
  state.defaultLocale = locale;
635
827
  return this;
636
828
  },
637
- async pull(locale, input) {
829
+ async pull(locale, input2) {
638
830
  if (!state.defaultLocale) {
639
831
  throw new Error("Default locale not set");
640
832
  }
@@ -642,9 +834,9 @@ function createLoader(lDefinition) {
642
834
  throw new Error("The first pull must be for the default locale");
643
835
  }
644
836
  if (locale === state.defaultLocale) {
645
- state.originalInput = input || null;
837
+ state.originalInput = input2 || null;
646
838
  }
647
- return lDefinition.pull(locale, input, state.initCtx);
839
+ return lDefinition.pull(locale, input2, state.initCtx);
648
840
  },
649
841
  async push(locale, data) {
650
842
  if (!state.defaultLocale) {
@@ -663,8 +855,8 @@ function createLoader(lDefinition) {
663
855
  import { jsonrepair } from "jsonrepair";
664
856
  function createJsonLoader() {
665
857
  return createLoader({
666
- pull: async (locale, input) => {
667
- const jsonString = input || "{}";
858
+ pull: async (locale, input2) => {
859
+ const jsonString = input2 || "{}";
668
860
  let result;
669
861
  try {
670
862
  result = JSON.parse(jsonString);
@@ -682,33 +874,46 @@ function createJsonLoader() {
682
874
 
683
875
  // src/cli/loaders/flat.ts
684
876
  import { flatten, unflatten } from "flat";
685
- import _5 from "lodash";
877
+ import _6 from "lodash";
686
878
  var OBJECT_NUMERIC_KEY_PREFIX = "__lingodotdev__obj__";
687
879
  function createFlatLoader() {
688
- let denormalizedKeysMap = {};
880
+ return composeLoaders(createDenormalizeLoader(), createNormalizeLoader());
881
+ }
882
+ function createDenormalizeLoader() {
689
883
  return createLoader({
690
- pull: async (locale, input) => {
691
- const denormalized = denormalizeObjectKeys(input || {});
692
- const flattened = flatten(denormalized, {
884
+ pull: async (locale, input2) => {
885
+ const inputDenormalized = denormalizeObjectKeys(input2 || {});
886
+ const denormalized = flatten(inputDenormalized, {
693
887
  delimiter: "/",
694
888
  transformKey(key) {
695
889
  return encodeURIComponent(String(key));
696
890
  }
697
891
  });
698
- denormalizedKeysMap = { ...denormalizedKeysMap, ...buildDenormalizedKeysMap(flattened) };
699
- const normalized = normalizeObjectKeys(flattened);
892
+ const keysMap = buildDenormalizedKeysMap(denormalized);
893
+ return { denormalized, keysMap };
894
+ },
895
+ push: async (locale, { denormalized }) => {
896
+ const normalized = normalizeObjectKeys(denormalized);
897
+ return normalized;
898
+ }
899
+ });
900
+ }
901
+ function createNormalizeLoader() {
902
+ return createLoader({
903
+ pull: async (locale, input2) => {
904
+ const normalized = normalizeObjectKeys(input2.denormalized);
700
905
  return normalized;
701
906
  },
702
- push: async (locale, data) => {
703
- const denormalized = mapDenormalizedKeys(data, denormalizedKeysMap);
704
- const unflattened = unflatten(denormalized || {}, {
907
+ push: async (locale, data, originalInput) => {
908
+ const keysMap = originalInput?.keysMap ?? {};
909
+ const input2 = mapDenormalizedKeys(data, keysMap);
910
+ const denormalized = unflatten(input2, {
705
911
  delimiter: "/",
706
912
  transformKey(key) {
707
913
  return decodeURIComponent(String(key));
708
914
  }
709
915
  });
710
- const normalized = normalizeObjectKeys(unflattened);
711
- return normalized;
916
+ return { denormalized, keysMap: keysMap || {} };
712
917
  }
713
918
  });
714
919
  }
@@ -728,7 +933,7 @@ function buildDenormalizedKeysMap(obj) {
728
933
  function mapDenormalizedKeys(obj, denormalizedKeysMap) {
729
934
  return Object.keys(obj).reduce(
730
935
  (acc, key) => {
731
- const denormalizedKey = denormalizedKeysMap[key];
936
+ const denormalizedKey = denormalizedKeysMap[key] ?? key;
732
937
  acc[denormalizedKey] = obj[key];
733
938
  return acc;
734
939
  },
@@ -736,12 +941,12 @@ function mapDenormalizedKeys(obj, denormalizedKeysMap) {
736
941
  );
737
942
  }
738
943
  function denormalizeObjectKeys(obj) {
739
- if (_5.isObject(obj) && !_5.isArray(obj)) {
740
- return _5.transform(
944
+ if (_6.isObject(obj) && !_6.isArray(obj)) {
945
+ return _6.transform(
741
946
  obj,
742
947
  (result, value, key) => {
743
948
  const newKey = !isNaN(Number(key)) ? `${OBJECT_NUMERIC_KEY_PREFIX}${key}` : key;
744
- result[newKey] = _5.isObject(value) ? denormalizeObjectKeys(value) : value;
949
+ result[newKey] = _6.isObject(value) ? denormalizeObjectKeys(value) : value;
745
950
  },
746
951
  {}
747
952
  );
@@ -750,12 +955,12 @@ function denormalizeObjectKeys(obj) {
750
955
  }
751
956
  }
752
957
  function normalizeObjectKeys(obj) {
753
- if (_5.isObject(obj) && !_5.isArray(obj)) {
754
- return _5.transform(
958
+ if (_6.isObject(obj) && !_6.isArray(obj)) {
959
+ return _6.transform(
755
960
  obj,
756
961
  (result, value, key) => {
757
962
  const newKey = `${key}`.replace(OBJECT_NUMERIC_KEY_PREFIX, "");
758
- result[newKey] = _5.isObject(value) ? normalizeObjectKeys(value) : value;
963
+ result[newKey] = _6.isObject(value) ? normalizeObjectKeys(value) : value;
759
964
  },
760
965
  {}
761
966
  );
@@ -765,8 +970,8 @@ function normalizeObjectKeys(obj) {
765
970
  }
766
971
 
767
972
  // src/cli/loaders/text-file.ts
768
- import fs5 from "fs/promises";
769
- import path6 from "path";
973
+ import fs6 from "fs/promises";
974
+ import path8 from "path";
770
975
  function createTextFileLoader(pathPattern) {
771
976
  return createLoader({
772
977
  async pull(locale) {
@@ -774,15 +979,15 @@ function createTextFileLoader(pathPattern) {
774
979
  const trimmedResult = result.trim();
775
980
  return trimmedResult;
776
981
  },
777
- async push(locale, data, _20, originalLocale) {
982
+ async push(locale, data, _21, originalLocale) {
778
983
  const draftPath = pathPattern.replace("[locale]", locale);
779
- const finalPath = path6.resolve(draftPath);
780
- const dirPath = path6.dirname(finalPath);
781
- await fs5.mkdir(dirPath, { recursive: true });
984
+ const finalPath = path8.resolve(draftPath);
985
+ const dirPath = path8.dirname(finalPath);
986
+ await fs6.mkdir(dirPath, { recursive: true });
782
987
  const trimmedPayload = data.trim();
783
988
  const trailingNewLine = await getTrailingNewLine(pathPattern, locale, originalLocale);
784
989
  let finalPayload = trimmedPayload + trailingNewLine;
785
- await fs5.writeFile(finalPath, finalPayload, {
990
+ await fs6.writeFile(finalPath, finalPayload, {
786
991
  encoding: "utf-8",
787
992
  flag: "w"
788
993
  });
@@ -791,12 +996,12 @@ function createTextFileLoader(pathPattern) {
791
996
  }
792
997
  async function readFileForLocale(pathPattern, locale) {
793
998
  const draftPath = pathPattern.replace("[locale]", locale);
794
- const finalPath = path6.resolve(draftPath);
795
- const exists = await fs5.access(finalPath).then(() => true).catch(() => false);
999
+ const finalPath = path8.resolve(draftPath);
1000
+ const exists = await fs6.access(finalPath).then(() => true).catch(() => false);
796
1001
  if (!exists) {
797
1002
  return "";
798
1003
  }
799
- return fs5.readFile(finalPath, "utf-8");
1004
+ return fs6.readFile(finalPath, "utf-8");
800
1005
  }
801
1006
  async function getTrailingNewLine(pathPattern, locale, originalLocale) {
802
1007
  let templateData = await readFileForLocale(pathPattern, locale);
@@ -814,8 +1019,8 @@ async function getTrailingNewLine(pathPattern, locale, originalLocale) {
814
1019
  import YAML from "yaml";
815
1020
  function createYamlLoader() {
816
1021
  return createLoader({
817
- async pull(locale, input) {
818
- return YAML.parse(input) || {};
1022
+ async pull(locale, input2) {
1023
+ return YAML.parse(input2) || {};
819
1024
  },
820
1025
  async push(locale, payload) {
821
1026
  return YAML.stringify(payload, {
@@ -828,8 +1033,8 @@ function createYamlLoader() {
828
1033
  // src/cli/loaders/root-key.ts
829
1034
  function createRootKeyLoader(replaceAll = false) {
830
1035
  return createLoader({
831
- async pull(locale, input) {
832
- const result = input[locale];
1036
+ async pull(locale, input2) {
1037
+ const result = input2[locale];
833
1038
  return result;
834
1039
  },
835
1040
  async push(locale, data, originalInput) {
@@ -843,15 +1048,15 @@ function createRootKeyLoader(replaceAll = false) {
843
1048
  }
844
1049
 
845
1050
  // src/cli/loaders/flutter.ts
846
- import _6 from "lodash";
1051
+ import _7 from "lodash";
847
1052
  function createFlutterLoader() {
848
1053
  return createLoader({
849
- async pull(locale, input) {
850
- const result = _6.pickBy(input, (value, key) => !key.startsWith("@"));
1054
+ async pull(locale, input2) {
1055
+ const result = _7.pickBy(input2, (value, key) => !key.startsWith("@"));
851
1056
  return result;
852
1057
  },
853
1058
  async push(locale, data, originalInput) {
854
- const result = _6.merge({}, originalInput, { "@@locale": locale }, data);
1059
+ const result = _7.merge({}, originalInput, { "@@locale": locale }, data);
855
1060
  return result;
856
1061
  }
857
1062
  });
@@ -861,10 +1066,10 @@ function createFlutterLoader() {
861
1066
  import { parseStringPromise, Builder } from "xml2js";
862
1067
  function createAndroidLoader() {
863
1068
  return createLoader({
864
- async pull(locale, input) {
1069
+ async pull(locale, input2) {
865
1070
  try {
866
1071
  const result = {};
867
- const parsed = !input ? { resources: {} } : await parseStringPromise(input, { explicitArray: true });
1072
+ const parsed = !input2 ? { resources: {} } : await parseStringPromise(input2, { explicitArray: true });
868
1073
  if (!parsed || !parsed.resources) {
869
1074
  console.warn("No resources found in the Android resource file");
870
1075
  return result;
@@ -953,16 +1158,16 @@ function createAndroidLoader() {
953
1158
  // src/cli/loaders/csv.ts
954
1159
  import { parse } from "csv-parse/sync";
955
1160
  import { stringify } from "csv-stringify/sync";
956
- import _7 from "lodash";
1161
+ import _8 from "lodash";
957
1162
  function createCsvLoader() {
958
1163
  return createLoader({
959
1164
  async pull(locale, _input) {
960
- const input = parse(_input, {
1165
+ const input2 = parse(_input, {
961
1166
  columns: true,
962
1167
  skip_empty_lines: true
963
1168
  });
964
1169
  const result = {};
965
- _7.forEach(input, (row) => {
1170
+ _8.forEach(input2, (row) => {
966
1171
  const key = row.id;
967
1172
  if (key && row[locale] && row[locale].trim() !== "") {
968
1173
  result[key] = row[locale];
@@ -971,16 +1176,16 @@ function createCsvLoader() {
971
1176
  return result;
972
1177
  },
973
1178
  async push(locale, data, originalInput) {
974
- const input = parse(originalInput || "", {
1179
+ const input2 = parse(originalInput || "", {
975
1180
  columns: true,
976
1181
  skip_empty_lines: true
977
1182
  });
978
- const columns = input.length > 0 ? Object.keys(input[0]) : ["id", locale];
979
- const updatedRows = input.map((row) => ({
1183
+ const columns = input2.length > 0 ? Object.keys(input2[0]) : ["id", locale];
1184
+ const updatedRows = input2.map((row) => ({
980
1185
  ...row,
981
1186
  [locale]: data[row.id] || row[locale] || ""
982
1187
  }));
983
- const existingKeys = new Set(input.map((row) => row.id));
1188
+ const existingKeys = new Set(input2.map((row) => row.id));
984
1189
  Object.entries(data).forEach(([key, value]) => {
985
1190
  if (!existingKeys.has(key)) {
986
1191
  const newRow = {
@@ -1015,9 +1220,9 @@ function createHtmlLoader() {
1015
1220
  };
1016
1221
  const UNLOCALIZABLE_TAGS = ["script", "style"];
1017
1222
  return createLoader({
1018
- async pull(locale, input) {
1223
+ async pull(locale, input2) {
1019
1224
  const result = {};
1020
- const dom = new JSDOM(input);
1225
+ const dom = new JSDOM(input2);
1021
1226
  const document = dom.window.document;
1022
1227
  const getPath = (node, attribute) => {
1023
1228
  const indices = [];
@@ -1083,9 +1288,9 @@ function createHtmlLoader() {
1083
1288
  const bDepth = b.split("/").length;
1084
1289
  return aDepth - bDepth;
1085
1290
  });
1086
- paths.forEach((path9) => {
1087
- const value = data[path9];
1088
- const [nodePath, attribute] = path9.split("#");
1291
+ paths.forEach((path11) => {
1292
+ const value = data[path11];
1293
+ const [nodePath, attribute] = path11.split("#");
1089
1294
  const [rootTag, ...indices] = nodePath.split("/");
1090
1295
  let parent = rootTag === "head" ? document.head : document.body;
1091
1296
  let current = parent;
@@ -1137,8 +1342,8 @@ var yamlEngine = {
1137
1342
  };
1138
1343
  function createMarkdownLoader() {
1139
1344
  return createLoader({
1140
- async pull(locale, input) {
1141
- const { data: frontmatter, content } = matter(input, {
1345
+ async pull(locale, input2) {
1346
+ const { data: frontmatter, content } = matter(input2, {
1142
1347
  engines: {
1143
1348
  yaml: yamlEngine
1144
1349
  }
@@ -1188,7 +1393,7 @@ function createPropertiesLoader() {
1188
1393
  return result;
1189
1394
  },
1190
1395
  async push(locale, payload) {
1191
- const result = Object.entries(payload).filter(([_20, value]) => value != null).map(([key, value]) => `${key}=${value}`).join("\n");
1396
+ const result = Object.entries(payload).filter(([_21, value]) => value != null).map(([key, value]) => `${key}=${value}`).join("\n");
1192
1397
  return result;
1193
1398
  }
1194
1399
  });
@@ -1207,8 +1412,8 @@ function parsePropertyLine(line) {
1207
1412
  // src/cli/loaders/xcode-strings.ts
1208
1413
  function createXcodeStringsLoader() {
1209
1414
  return createLoader({
1210
- async pull(locale, input) {
1211
- const lines = input.split("\n");
1415
+ async pull(locale, input2) {
1416
+ const lines = input2.split("\n");
1212
1417
  const result = {};
1213
1418
  for (const line of lines) {
1214
1419
  const trimmedLine = line.trim();
@@ -1249,9 +1454,9 @@ var emptyData = [
1249
1454
  ].join("\n");
1250
1455
  function createXcodeStringsdictLoader() {
1251
1456
  return createLoader({
1252
- async pull(locale, input) {
1457
+ async pull(locale, input2) {
1253
1458
  try {
1254
- const parsed = plist.parse(input || emptyData);
1459
+ const parsed = plist.parse(input2 || emptyData);
1255
1460
  if (typeof parsed !== "object" || parsed === null) {
1256
1461
  throw new CLIError({
1257
1462
  message: "Invalid .stringsdict format",
@@ -1274,12 +1479,12 @@ function createXcodeStringsdictLoader() {
1274
1479
  }
1275
1480
 
1276
1481
  // src/cli/loaders/xcode-xcstrings.ts
1277
- import _8 from "lodash";
1482
+ import _9 from "lodash";
1278
1483
  function createXcodeXcstringsLoader() {
1279
1484
  return createLoader({
1280
- async pull(locale, input) {
1485
+ async pull(locale, input2) {
1281
1486
  const resultData = {};
1282
- for (const [translationKey, _translationEntity] of Object.entries(input.strings)) {
1487
+ for (const [translationKey, _translationEntity] of Object.entries(input2.strings)) {
1283
1488
  const rootTranslationEntity = _translationEntity;
1284
1489
  const langTranslationEntity = rootTranslationEntity?.localizations?.[locale];
1285
1490
  if (langTranslationEntity) {
@@ -1338,7 +1543,7 @@ function createXcodeXcstringsLoader() {
1338
1543
  };
1339
1544
  }
1340
1545
  }
1341
- const result = _8.merge({}, originalInput, langDataToMerge);
1546
+ const result = _9.merge({}, originalInput, langDataToMerge);
1342
1547
  return result;
1343
1548
  }
1344
1549
  });
@@ -1380,33 +1585,33 @@ async function loadPrettierConfig() {
1380
1585
  }
1381
1586
 
1382
1587
  // src/cli/loaders/unlocalizable.ts
1383
- import _9 from "lodash";
1588
+ import _10 from "lodash";
1384
1589
  import _isUrl from "is-url";
1385
1590
  import { isValid, parseISO } from "date-fns";
1386
1591
  function createUnlocalizableLoader() {
1387
1592
  const rules = {
1388
- isEmpty: (v) => _9.isEmpty(v),
1389
- isNumber: (v) => !_9.isNaN(_9.toNumber(v)),
1390
- isBoolean: (v) => _9.isBoolean(v),
1391
- isIsoDate: (v) => _9.isString(v) && _isIsoDate(v),
1392
- isSystemId: (v) => _9.isString(v) && _isSystemId(v),
1393
- isUrl: (v) => _9.isString(v) && _isUrl(v)
1593
+ isEmpty: (v) => _10.isEmpty(v),
1594
+ isNumber: (v) => !_10.isNaN(_10.toNumber(v)),
1595
+ isBoolean: (v) => _10.isBoolean(v),
1596
+ isIsoDate: (v) => _10.isString(v) && _isIsoDate(v),
1597
+ isSystemId: (v) => _10.isString(v) && _isSystemId(v),
1598
+ isUrl: (v) => _10.isString(v) && _isUrl(v)
1394
1599
  };
1395
1600
  return createLoader({
1396
- async pull(locale, input) {
1397
- const passthroughKeys = Object.entries(input).filter(([key, value]) => {
1601
+ async pull(locale, input2) {
1602
+ const passthroughKeys = Object.entries(input2).filter(([key, value]) => {
1398
1603
  for (const [ruleName, rule] of Object.entries(rules)) {
1399
1604
  if (rule(value)) {
1400
1605
  return true;
1401
1606
  }
1402
1607
  }
1403
1608
  return false;
1404
- }).map(([key, _20]) => key);
1405
- const result = _9.omitBy(input, (_20, key) => passthroughKeys.includes(key));
1609
+ }).map(([key, _21]) => key);
1610
+ const result = _10.omitBy(input2, (_21, key) => passthroughKeys.includes(key));
1406
1611
  return result;
1407
1612
  },
1408
1613
  async push(locale, data, originalInput) {
1409
- const result = _9.merge({}, originalInput, data);
1614
+ const result = _10.merge({}, originalInput, data);
1410
1615
  return result;
1411
1616
  }
1412
1617
  });
@@ -1419,20 +1624,20 @@ function _isIsoDate(v) {
1419
1624
  }
1420
1625
 
1421
1626
  // src/cli/loaders/po/index.ts
1422
- import _10 from "lodash";
1627
+ import _11 from "lodash";
1423
1628
  import gettextParser from "gettext-parser";
1424
1629
  function createPoLoader(params = { multiline: false }) {
1425
1630
  return composeLoaders(createPoDataLoader(params), createPoContentLoader());
1426
1631
  }
1427
1632
  function createPoDataLoader(params) {
1428
1633
  return createLoader({
1429
- async pull(locale, input) {
1430
- const parsedPo = gettextParser.po.parse(input);
1634
+ async pull(locale, input2) {
1635
+ const parsedPo = gettextParser.po.parse(input2);
1431
1636
  const result = {};
1432
- const sections = input.split("\n\n").filter(Boolean);
1637
+ const sections = input2.split("\n\n").filter(Boolean);
1433
1638
  for (const section of sections) {
1434
1639
  const sectionPo = gettextParser.po.parse(section);
1435
- const contextKey = _10.keys(sectionPo.translations)[0];
1640
+ const contextKey = _11.keys(sectionPo.translations)[0];
1436
1641
  const entries = sectionPo.translations[contextKey];
1437
1642
  Object.entries(entries).forEach(([msgid, entry]) => {
1438
1643
  if (msgid && entry.msgid) {
@@ -1450,12 +1655,12 @@ function createPoDataLoader(params) {
1450
1655
  const sections = originalInput?.split("\n\n").filter(Boolean) || [];
1451
1656
  const result = sections.map((section) => {
1452
1657
  const sectionPo = gettextParser.po.parse(section);
1453
- const contextKey = _10.keys(sectionPo.translations)[0];
1658
+ const contextKey = _11.keys(sectionPo.translations)[0];
1454
1659
  const entries = sectionPo.translations[contextKey];
1455
1660
  const msgid = Object.keys(entries).find((key) => entries[key].msgid);
1456
1661
  if (!msgid) return section;
1457
1662
  if (data[msgid]) {
1458
- const updatedPo = _10.merge({}, sectionPo, {
1663
+ const updatedPo = _11.merge({}, sectionPo, {
1459
1664
  translations: {
1460
1665
  [contextKey]: {
1461
1666
  [msgid]: {
@@ -1474,8 +1679,8 @@ function createPoDataLoader(params) {
1474
1679
  }
1475
1680
  function createPoContentLoader() {
1476
1681
  return createLoader({
1477
- async pull(locale, input) {
1478
- const result = _10.chain(input).entries().filter(([, entry]) => !!entry.msgid).map(([, entry]) => [
1682
+ async pull(locale, input2) {
1683
+ const result = _11.chain(input2).entries().filter(([, entry]) => !!entry.msgid).map(([, entry]) => [
1479
1684
  entry.msgid,
1480
1685
  {
1481
1686
  singular: entry.msgstr[0] || entry.msgid,
@@ -1485,7 +1690,7 @@ function createPoContentLoader() {
1485
1690
  return result;
1486
1691
  },
1487
1692
  async push(locale, data, originalInput) {
1488
- const result = _10.chain(originalInput).entries().map(([, entry]) => [
1693
+ const result = _11.chain(originalInput).entries().map(([, entry]) => [
1489
1694
  entry.msgid,
1490
1695
  {
1491
1696
  ...entry,
@@ -1501,8 +1706,8 @@ function createPoContentLoader() {
1501
1706
  import xliff from "xliff";
1502
1707
  function createXliffLoader() {
1503
1708
  return createLoader({
1504
- async pull(locale, input) {
1505
- const js = await xliff.xliff2js(input);
1709
+ async pull(locale, input2) {
1710
+ const js = await xliff.xliff2js(input2);
1506
1711
  return js || {};
1507
1712
  },
1508
1713
  async push(locale, payload) {
@@ -1519,10 +1724,10 @@ function normalizeXMLString(xmlString) {
1519
1724
  }
1520
1725
  function createXmlLoader() {
1521
1726
  return createLoader({
1522
- async pull(locale, input) {
1727
+ async pull(locale, input2) {
1523
1728
  let result = {};
1524
1729
  try {
1525
- const parsed = await parseStringPromise2(input, {
1730
+ const parsed = await parseStringPromise2(input2, {
1526
1731
  explicitArray: false,
1527
1732
  mergeAttrs: false,
1528
1733
  normalize: true,
@@ -1557,8 +1762,8 @@ import srtParser from "srt-parser-2";
1557
1762
  function createSrtLoader() {
1558
1763
  const parser = new srtParser();
1559
1764
  return createLoader({
1560
- async pull(locale, input) {
1561
- const parsed = parser.fromSrt(input) || [];
1765
+ async pull(locale, input2) {
1766
+ const parsed = parser.fromSrt(input2) || [];
1562
1767
  const result = {};
1563
1768
  parsed.forEach((entry) => {
1564
1769
  const key = `${entry.id}#${entry.startTime}-${entry.endTime}`;
@@ -1586,7 +1791,7 @@ function createSrtLoader() {
1586
1791
  }
1587
1792
 
1588
1793
  // src/cli/loaders/dato/index.ts
1589
- import fs6 from "fs";
1794
+ import fs7 from "fs";
1590
1795
  import JSON5 from "json5";
1591
1796
 
1592
1797
  // src/cli/loaders/dato/_base.ts
@@ -1608,34 +1813,34 @@ var datoSettingsSchema = Z2.object({
1608
1813
  });
1609
1814
 
1610
1815
  // src/cli/loaders/dato/filter.ts
1611
- import _11 from "lodash";
1816
+ import _12 from "lodash";
1612
1817
  function createDatoFilterLoader() {
1613
1818
  return createLoader({
1614
- async pull(locale, input) {
1819
+ async pull(locale, input2) {
1615
1820
  const result = {};
1616
- for (const [modelId, modelInfo] of _11.entries(input)) {
1821
+ for (const [modelId, modelInfo] of _12.entries(input2)) {
1617
1822
  result[modelId] = {};
1618
1823
  for (const record of modelInfo.records) {
1619
- result[modelId][record.id] = _11.chain(modelInfo.fields).mapKeys((field) => field.api_key).mapValues((field) => _11.get(record, [field.api_key, locale])).value();
1824
+ result[modelId][record.id] = _12.chain(modelInfo.fields).mapKeys((field) => field.api_key).mapValues((field) => _12.get(record, [field.api_key, locale])).value();
1620
1825
  }
1621
1826
  }
1622
1827
  return result;
1623
1828
  },
1624
1829
  async push(locale, data, originalInput, originalLocale) {
1625
- const result = _11.cloneDeep(originalInput || {});
1626
- for (const [modelId, modelInfo] of _11.entries(result)) {
1830
+ const result = _12.cloneDeep(originalInput || {});
1831
+ for (const [modelId, modelInfo] of _12.entries(result)) {
1627
1832
  for (const record of modelInfo.records) {
1628
- for (const [fieldId, fieldValue] of _11.entries(record)) {
1833
+ for (const [fieldId, fieldValue] of _12.entries(record)) {
1629
1834
  const fieldInfo = modelInfo.fields.find((field) => field.api_key === fieldId);
1630
1835
  if (fieldInfo) {
1631
- const sourceFieldValue = _11.get(fieldValue, [originalLocale]);
1632
- const targetFieldValue = _11.get(data, [modelId, record.id, fieldId]);
1836
+ const sourceFieldValue = _12.get(fieldValue, [originalLocale]);
1837
+ const targetFieldValue = _12.get(data, [modelId, record.id, fieldId]);
1633
1838
  if (targetFieldValue) {
1634
- _11.set(record, [fieldId, locale], targetFieldValue);
1839
+ _12.set(record, [fieldId, locale], targetFieldValue);
1635
1840
  } else {
1636
- _11.set(record, [fieldId, locale], sourceFieldValue);
1841
+ _12.set(record, [fieldId, locale], sourceFieldValue);
1637
1842
  }
1638
- _11.chain(fieldValue).keys().reject((loc) => loc === locale || loc === originalLocale).filter((loc) => _11.isEmpty(_11.get(fieldValue, [loc]))).forEach((loc) => _11.set(record, [fieldId, loc], sourceFieldValue)).value();
1843
+ _12.chain(fieldValue).keys().reject((loc) => loc === locale || loc === originalLocale).filter((loc) => _12.isEmpty(_12.get(fieldValue, [loc]))).forEach((loc) => _12.set(record, [fieldId, loc], sourceFieldValue)).value();
1639
1844
  }
1640
1845
  }
1641
1846
  }
@@ -1646,10 +1851,10 @@ function createDatoFilterLoader() {
1646
1851
  }
1647
1852
 
1648
1853
  // src/cli/loaders/dato/api.ts
1649
- import _13 from "lodash";
1854
+ import _14 from "lodash";
1650
1855
 
1651
1856
  // src/cli/loaders/dato/_utils.ts
1652
- import _12 from "lodash";
1857
+ import _13 from "lodash";
1653
1858
  import { buildClient } from "@datocms/cma-client-node";
1654
1859
  function createDatoClient(params) {
1655
1860
  if (!params.apiKey) {
@@ -1824,7 +2029,7 @@ function createDatoApiLoader(config, onConfigUpdate) {
1824
2029
  const result = {
1825
2030
  models: {}
1826
2031
  };
1827
- const updatedConfig = _13.cloneDeep(config);
2032
+ const updatedConfig = _14.cloneDeep(config);
1828
2033
  console.log(`Initializing DatoCMS loader...`);
1829
2034
  const project = await dato.findProject();
1830
2035
  const modelChoices = await getModelChoices(dato, config);
@@ -1842,7 +2047,7 @@ function createDatoApiLoader(config, onConfigUpdate) {
1842
2047
  delete updatedConfig.models[modelId];
1843
2048
  }
1844
2049
  }
1845
- for (const modelId of _13.keys(updatedConfig.models)) {
2050
+ for (const modelId of _14.keys(updatedConfig.models)) {
1846
2051
  const { modelName, fields } = await getModelFields(dato, modelId);
1847
2052
  if (fields.length > 0) {
1848
2053
  result.models[modelId] = { fields: [], records: [] };
@@ -1853,7 +2058,7 @@ function createDatoApiLoader(config, onConfigUpdate) {
1853
2058
  const isLocalized = await updateFieldLocalization(dato, fieldInfo, selectedFields.includes(fieldInfo.id));
1854
2059
  if (isLocalized) {
1855
2060
  result.models[modelId].fields.push(fieldInfo);
1856
- updatedConfig.models[modelId].fields = _13.uniq([
2061
+ updatedConfig.models[modelId].fields = _14.uniq([
1857
2062
  ...updatedConfig.models[modelId].fields || [],
1858
2063
  fieldInfo.api_key
1859
2064
  ]);
@@ -1870,9 +2075,9 @@ function createDatoApiLoader(config, onConfigUpdate) {
1870
2075
  onConfigUpdate(updatedConfig);
1871
2076
  return result;
1872
2077
  },
1873
- async pull(locale, input, initCtx) {
2078
+ async pull(locale, input2, initCtx) {
1874
2079
  const result = {};
1875
- for (const modelId of _13.keys(initCtx?.models || {})) {
2080
+ for (const modelId of _14.keys(initCtx?.models || {})) {
1876
2081
  let records = initCtx?.models[modelId].records || [];
1877
2082
  const recordIds = records.map((record) => record.id);
1878
2083
  records = await dato.findRecords(recordIds);
@@ -1887,7 +2092,7 @@ function createDatoApiLoader(config, onConfigUpdate) {
1887
2092
  return result;
1888
2093
  },
1889
2094
  async push(locale, data, originalInput) {
1890
- for (const modelId of _13.keys(data)) {
2095
+ for (const modelId of _14.keys(data)) {
1891
2096
  for (let i = 0; i < data[modelId].records.length; i++) {
1892
2097
  const record = data[modelId].records[i];
1893
2098
  console.log(`Updating record ${i + 1}/${data[modelId].records.length} for model ${modelId}...`);
@@ -1901,7 +2106,7 @@ async function getModelFields(dato, modelId) {
1901
2106
  const modelInfo = await dato.findModel(modelId);
1902
2107
  return {
1903
2108
  modelName: modelInfo.name,
1904
- fields: _13.filter(modelInfo.fields, (field) => field.type === "field")
2109
+ fields: _14.filter(modelInfo.fields, (field) => field.type === "field")
1905
2110
  };
1906
2111
  }
1907
2112
  async function getFieldDetails(dato, fields) {
@@ -1979,17 +2184,17 @@ async function promptModelSelection(choices) {
1979
2184
  }
1980
2185
 
1981
2186
  // src/cli/loaders/dato/extract.ts
1982
- import _14 from "lodash";
2187
+ import _15 from "lodash";
1983
2188
  function createDatoExtractLoader() {
1984
2189
  return createLoader({
1985
- async pull(locale, input) {
2190
+ async pull(locale, input2) {
1986
2191
  const result = {};
1987
- for (const [modelId, modelInfo] of _14.entries(input)) {
1988
- for (const [recordId, record] of _14.entries(modelInfo)) {
1989
- for (const [fieldName, fieldValue] of _14.entries(record)) {
2192
+ for (const [modelId, modelInfo] of _15.entries(input2)) {
2193
+ for (const [recordId, record] of _15.entries(modelInfo)) {
2194
+ for (const [fieldName, fieldValue] of _15.entries(record)) {
1990
2195
  const parsedValue = createParsedDatoValue(fieldValue);
1991
2196
  if (parsedValue) {
1992
- _14.set(result, [modelId, `_${recordId}`, fieldName], parsedValue);
2197
+ _15.set(result, [modelId, `_${recordId}`, fieldName], parsedValue);
1993
2198
  }
1994
2199
  }
1995
2200
  }
@@ -1997,14 +2202,14 @@ function createDatoExtractLoader() {
1997
2202
  return result;
1998
2203
  },
1999
2204
  async push(locale, data, originalInput) {
2000
- const result = _14.cloneDeep(originalInput || {});
2001
- for (const [modelId, modelInfo] of _14.entries(data)) {
2002
- for (const [virtualRecordId, record] of _14.entries(modelInfo)) {
2003
- for (const [fieldName, fieldValue] of _14.entries(record)) {
2205
+ const result = _15.cloneDeep(originalInput || {});
2206
+ for (const [modelId, modelInfo] of _15.entries(data)) {
2207
+ for (const [virtualRecordId, record] of _15.entries(modelInfo)) {
2208
+ for (const [fieldName, fieldValue] of _15.entries(record)) {
2004
2209
  const [, recordId] = virtualRecordId.split("_");
2005
- const originalFieldValue = _14.get(originalInput, [modelId, recordId, fieldName]);
2210
+ const originalFieldValue = _15.get(originalInput, [modelId, recordId, fieldName]);
2006
2211
  const rawValue = createRawDatoValue(fieldValue, originalFieldValue, true);
2007
- _14.set(result, [modelId, recordId, fieldName], rawValue || originalFieldValue);
2212
+ _15.set(result, [modelId, recordId, fieldName], rawValue || originalFieldValue);
2008
2213
  }
2009
2214
  }
2010
2215
  }
@@ -2013,25 +2218,25 @@ function createDatoExtractLoader() {
2013
2218
  });
2014
2219
  }
2015
2220
  function detectDatoFieldType(rawDatoValue) {
2016
- if (_14.has(rawDatoValue, "document") && _14.get(rawDatoValue, "schema") === "dast") {
2221
+ if (_15.has(rawDatoValue, "document") && _15.get(rawDatoValue, "schema") === "dast") {
2017
2222
  return "structured_text";
2018
- } else if (_14.has(rawDatoValue, "no_index") || _14.has(rawDatoValue, "twitter_card")) {
2223
+ } else if (_15.has(rawDatoValue, "no_index") || _15.has(rawDatoValue, "twitter_card")) {
2019
2224
  return "seo";
2020
- } else if (_14.get(rawDatoValue, "type") === "item") {
2225
+ } else if (_15.get(rawDatoValue, "type") === "item") {
2021
2226
  return "single_block";
2022
- } else if (_14.isArray(rawDatoValue) && _14.every(rawDatoValue, (item) => _14.get(item, "type") === "item")) {
2227
+ } else if (_15.isArray(rawDatoValue) && _15.every(rawDatoValue, (item) => _15.get(item, "type") === "item")) {
2023
2228
  return "rich_text";
2024
2229
  } else if (_isFile(rawDatoValue)) {
2025
2230
  return "file";
2026
- } else if (_14.isArray(rawDatoValue) && _14.every(rawDatoValue, (item) => _isFile(item))) {
2231
+ } else if (_15.isArray(rawDatoValue) && _15.every(rawDatoValue, (item) => _isFile(item))) {
2027
2232
  return "gallery";
2028
2233
  } else if (_isJson(rawDatoValue)) {
2029
2234
  return "json";
2030
- } else if (_14.isString(rawDatoValue)) {
2235
+ } else if (_15.isString(rawDatoValue)) {
2031
2236
  return "string";
2032
2237
  } else if (_isVideo(rawDatoValue)) {
2033
2238
  return "video";
2034
- } else if (_14.isArray(rawDatoValue) && _14.every(rawDatoValue, (item) => _14.isString(item))) {
2239
+ } else if (_15.isArray(rawDatoValue) && _15.every(rawDatoValue, (item) => _15.isString(item))) {
2035
2240
  return "ref_list";
2036
2241
  } else {
2037
2242
  return null;
@@ -2089,62 +2294,62 @@ function createRawDatoValue(parsedDatoValue, originalRawDatoValue, isClean = fal
2089
2294
  }
2090
2295
  function serializeStructuredText(rawStructuredText) {
2091
2296
  return serializeStructuredTextNode(rawStructuredText);
2092
- function serializeStructuredTextNode(node, path9 = [], acc = {}) {
2297
+ function serializeStructuredTextNode(node, path11 = [], acc = {}) {
2093
2298
  if ("document" in node) {
2094
- return serializeStructuredTextNode(node.document, [...path9, "document"], acc);
2299
+ return serializeStructuredTextNode(node.document, [...path11, "document"], acc);
2095
2300
  }
2096
- if (!_14.isNil(node.value)) {
2097
- acc[[...path9, "value"].join(".")] = node.value;
2098
- } else if (_14.get(node, "type") === "block") {
2099
- acc[[...path9, "item"].join(".")] = serializeBlock(node.item);
2301
+ if (!_15.isNil(node.value)) {
2302
+ acc[[...path11, "value"].join(".")] = node.value;
2303
+ } else if (_15.get(node, "type") === "block") {
2304
+ acc[[...path11, "item"].join(".")] = serializeBlock(node.item);
2100
2305
  }
2101
2306
  if (node.children) {
2102
2307
  for (let i = 0; i < node.children.length; i++) {
2103
- serializeStructuredTextNode(node.children[i], [...path9, i.toString()], acc);
2308
+ serializeStructuredTextNode(node.children[i], [...path11, i.toString()], acc);
2104
2309
  }
2105
2310
  }
2106
2311
  return acc;
2107
2312
  }
2108
2313
  }
2109
2314
  function serializeSeo(rawSeo) {
2110
- return _14.chain(rawSeo).pick(["title", "description"]).value();
2315
+ return _15.chain(rawSeo).pick(["title", "description"]).value();
2111
2316
  }
2112
2317
  function serializeBlock(rawBlock) {
2113
- if (_14.get(rawBlock, "type") === "item" && _14.has(rawBlock, "id")) {
2318
+ if (_15.get(rawBlock, "type") === "item" && _15.has(rawBlock, "id")) {
2114
2319
  return serializeBlock(rawBlock.attributes);
2115
2320
  }
2116
2321
  const result = {};
2117
- for (const [attributeName, attributeValue] of _14.entries(rawBlock)) {
2322
+ for (const [attributeName, attributeValue] of _15.entries(rawBlock)) {
2118
2323
  result[attributeName] = createParsedDatoValue(attributeValue);
2119
2324
  }
2120
2325
  return result;
2121
2326
  }
2122
2327
  function serializeBlockList(rawBlockList) {
2123
- return _14.chain(rawBlockList).map((block) => serializeBlock(block)).value();
2328
+ return _15.chain(rawBlockList).map((block) => serializeBlock(block)).value();
2124
2329
  }
2125
2330
  function serializeVideo(rawVideo) {
2126
- return _14.chain(rawVideo).pick(["title"]).value();
2331
+ return _15.chain(rawVideo).pick(["title"]).value();
2127
2332
  }
2128
2333
  function serializeFile(rawFile) {
2129
- return _14.chain(rawFile).pick(["alt", "title"]).value();
2334
+ return _15.chain(rawFile).pick(["alt", "title"]).value();
2130
2335
  }
2131
2336
  function serializeGallery(rawGallery) {
2132
- return _14.chain(rawGallery).map((item) => serializeFile(item)).value();
2337
+ return _15.chain(rawGallery).map((item) => serializeFile(item)).value();
2133
2338
  }
2134
2339
  function deserializeFile(parsedFile, originalRawFile) {
2135
- return _14.chain(parsedFile).defaults(originalRawFile).value();
2340
+ return _15.chain(parsedFile).defaults(originalRawFile).value();
2136
2341
  }
2137
2342
  function deserializeGallery(parsedGallery, originalRawGallery) {
2138
- return _14.chain(parsedGallery).map((item, i) => deserializeFile(item, originalRawGallery[i])).value();
2343
+ return _15.chain(parsedGallery).map((item, i) => deserializeFile(item, originalRawGallery[i])).value();
2139
2344
  }
2140
2345
  function deserializeVideo(parsedVideo, originalRawVideo) {
2141
- return _14.chain(parsedVideo).defaults(originalRawVideo).value();
2346
+ return _15.chain(parsedVideo).defaults(originalRawVideo).value();
2142
2347
  }
2143
2348
  function deserializeBlock(payload, rawNode, isClean = false) {
2144
- const result = _14.cloneDeep(rawNode);
2145
- for (const [attributeName, attributeValue] of _14.entries(rawNode.attributes)) {
2349
+ const result = _15.cloneDeep(rawNode);
2350
+ for (const [attributeName, attributeValue] of _15.entries(rawNode.attributes)) {
2146
2351
  const rawValue = createRawDatoValue(payload[attributeName], attributeValue, isClean);
2147
- _14.set(result, ["attributes", attributeName], rawValue);
2352
+ _15.set(result, ["attributes", attributeName], rawValue);
2148
2353
  }
2149
2354
  if (isClean) {
2150
2355
  delete result["id"];
@@ -2152,45 +2357,45 @@ function deserializeBlock(payload, rawNode, isClean = false) {
2152
2357
  return result;
2153
2358
  }
2154
2359
  function deserializeSeo(parsedSeo, originalRawSeo) {
2155
- return _14.chain(parsedSeo).pick(["title", "description"]).defaults(originalRawSeo).value();
2360
+ return _15.chain(parsedSeo).pick(["title", "description"]).defaults(originalRawSeo).value();
2156
2361
  }
2157
2362
  function deserializeBlockList(parsedBlockList, originalRawBlockList, isClean = false) {
2158
- return _14.chain(parsedBlockList).map((block, i) => deserializeBlock(block, originalRawBlockList[i], isClean)).value();
2363
+ return _15.chain(parsedBlockList).map((block, i) => deserializeBlock(block, originalRawBlockList[i], isClean)).value();
2159
2364
  }
2160
2365
  function deserializeStructuredText(parsedStructuredText, originalRawStructuredText) {
2161
- const result = _14.cloneDeep(originalRawStructuredText);
2162
- for (const [path9, value] of _14.entries(parsedStructuredText)) {
2163
- const realPath = _14.chain(path9.split(".")).flatMap((s) => !_14.isNaN(_14.toNumber(s)) ? ["children", s] : s).value();
2164
- const deserializedValue = createRawDatoValue(value, _14.get(originalRawStructuredText, realPath), true);
2165
- _14.set(result, realPath, deserializedValue);
2366
+ const result = _15.cloneDeep(originalRawStructuredText);
2367
+ for (const [path11, value] of _15.entries(parsedStructuredText)) {
2368
+ const realPath = _15.chain(path11.split(".")).flatMap((s) => !_15.isNaN(_15.toNumber(s)) ? ["children", s] : s).value();
2369
+ const deserializedValue = createRawDatoValue(value, _15.get(originalRawStructuredText, realPath), true);
2370
+ _15.set(result, realPath, deserializedValue);
2166
2371
  }
2167
2372
  return result;
2168
2373
  }
2169
2374
  function _isJson(rawDatoValue) {
2170
2375
  try {
2171
- return _14.isString(rawDatoValue) && rawDatoValue.startsWith("{") && rawDatoValue.endsWith("}") && !!JSON.parse(rawDatoValue);
2376
+ return _15.isString(rawDatoValue) && rawDatoValue.startsWith("{") && rawDatoValue.endsWith("}") && !!JSON.parse(rawDatoValue);
2172
2377
  } catch (e) {
2173
2378
  return false;
2174
2379
  }
2175
2380
  }
2176
2381
  function _isFile(rawDatoValue) {
2177
- return _14.isObject(rawDatoValue) && ["alt", "title", "custom_data", "focal_point", "upload_id"].every((key) => _14.has(rawDatoValue, key));
2382
+ return _15.isObject(rawDatoValue) && ["alt", "title", "custom_data", "focal_point", "upload_id"].every((key) => _15.has(rawDatoValue, key));
2178
2383
  }
2179
2384
  function _isVideo(rawDatoValue) {
2180
- return _14.isObject(rawDatoValue) && ["url", "title", "width", "height", "provider", "provider_uid", "thumbnail_url"].every(
2181
- (key) => _14.has(rawDatoValue, key)
2385
+ return _15.isObject(rawDatoValue) && ["url", "title", "width", "height", "provider", "provider_uid", "thumbnail_url"].every(
2386
+ (key) => _15.has(rawDatoValue, key)
2182
2387
  );
2183
2388
  }
2184
2389
 
2185
2390
  // src/cli/loaders/dato/index.ts
2186
2391
  function createDatoLoader(configFilePath) {
2187
2392
  try {
2188
- const configContent = fs6.readFileSync(configFilePath, "utf-8");
2393
+ const configContent = fs7.readFileSync(configFilePath, "utf-8");
2189
2394
  const datoConfig = datoConfigSchema.parse(JSON5.parse(configContent));
2190
2395
  return composeLoaders(
2191
2396
  createDatoApiLoader(
2192
2397
  datoConfig,
2193
- (updatedConfig) => fs6.writeFileSync(configFilePath, JSON5.stringify(updatedConfig, null, 2))
2398
+ (updatedConfig) => fs7.writeFileSync(configFilePath, JSON5.stringify(updatedConfig, null, 2))
2194
2399
  ),
2195
2400
  createDatoFilterLoader(),
2196
2401
  createDatoExtractLoader()
@@ -2204,8 +2409,8 @@ function createDatoLoader(configFilePath) {
2204
2409
  import webvtt from "node-webvtt";
2205
2410
  function createVttLoader() {
2206
2411
  return createLoader({
2207
- async pull(locale, input) {
2208
- const vtt = webvtt.parse(input)?.cues;
2412
+ async pull(locale, input2) {
2413
+ const vtt = webvtt.parse(input2)?.cues;
2209
2414
  if (Object.keys(vtt).length === 0) {
2210
2415
  return {};
2211
2416
  } else {
@@ -2228,27 +2433,27 @@ function createVttLoader() {
2228
2433
  text
2229
2434
  };
2230
2435
  });
2231
- const input = {
2436
+ const input2 = {
2232
2437
  valid: true,
2233
2438
  strict: true,
2234
2439
  cues: output
2235
2440
  };
2236
- return webvtt.compile(input);
2441
+ return webvtt.compile(input2);
2237
2442
  }
2238
2443
  });
2239
2444
  }
2240
2445
 
2241
2446
  // src/cli/loaders/variable/index.ts
2242
- import _15 from "lodash";
2447
+ import _16 from "lodash";
2243
2448
  function createVariableLoader(params) {
2244
2449
  return composeLoaders(variableExtractLoader(params), variableContentLoader());
2245
2450
  }
2246
2451
  function variableExtractLoader(params) {
2247
2452
  const specifierPattern = getFormatSpecifierPattern(params.type);
2248
2453
  return createLoader({
2249
- pull: async (locale, input) => {
2454
+ pull: async (locale, input2) => {
2250
2455
  const result = {};
2251
- for (const [key, value] of Object.entries(input)) {
2456
+ for (const [key, value] of Object.entries(input2)) {
2252
2457
  const matches = value.match(specifierPattern) || [];
2253
2458
  result[key] = result[key] || {
2254
2459
  value,
@@ -2281,12 +2486,12 @@ function variableExtractLoader(params) {
2281
2486
  }
2282
2487
  function variableContentLoader() {
2283
2488
  return createLoader({
2284
- pull: async (locale, input) => {
2285
- const result = _15.mapValues(input, (payload) => payload.value);
2489
+ pull: async (locale, input2) => {
2490
+ const result = _16.mapValues(input2, (payload) => payload.value);
2286
2491
  return result;
2287
2492
  },
2288
2493
  push: async (locale, data, originalInput) => {
2289
- const result = _15.cloneDeep(originalInput || {});
2494
+ const result = _16.cloneDeep(originalInput || {});
2290
2495
  for (const [key, originalValueObj] of Object.entries(result)) {
2291
2496
  result[key] = {
2292
2497
  ...originalValueObj,
@@ -2309,20 +2514,20 @@ function getFormatSpecifierPattern(type) {
2309
2514
  }
2310
2515
 
2311
2516
  // src/cli/loaders/sync.ts
2312
- import _16 from "lodash";
2517
+ import _17 from "lodash";
2313
2518
  function createSyncLoader() {
2314
2519
  return createLoader({
2315
- async pull(locale, input, originalInput) {
2520
+ async pull(locale, input2, originalInput) {
2316
2521
  if (!originalInput) {
2317
- return input;
2522
+ return input2;
2318
2523
  }
2319
- return _16.chain(originalInput).mapValues((value, key) => input[key]).value();
2524
+ return _17.chain(originalInput).mapValues((value, key) => input2[key]).value();
2320
2525
  },
2321
2526
  async push(locale, data, originalInput) {
2322
2527
  if (!originalInput) {
2323
2528
  return data;
2324
2529
  }
2325
- return _16.chain(originalInput || {}).mapValues((value, key) => data[key]).value();
2530
+ return _17.chain(originalInput || {}).mapValues((value, key) => data[key]).value();
2326
2531
  }
2327
2532
  });
2328
2533
  }
@@ -2544,57 +2749,57 @@ function createBucketLoader(bucketType, bucketPathPattern) {
2544
2749
  }
2545
2750
 
2546
2751
  // src/cli/utils/lockfile.ts
2547
- import fs7 from "fs";
2548
- import path7 from "path";
2752
+ import fs8 from "fs";
2753
+ import path9 from "path";
2549
2754
  import Z3 from "zod";
2550
2755
  import YAML3 from "yaml";
2551
2756
  import { MD5 } from "object-hash";
2552
- import _17 from "lodash";
2757
+ import _18 from "lodash";
2553
2758
  function createLockfileHelper() {
2554
2759
  return {
2555
2760
  isLockfileExists: () => {
2556
2761
  const lockfilePath = _getLockfilePath();
2557
- return fs7.existsSync(lockfilePath);
2762
+ return fs8.existsSync(lockfilePath);
2558
2763
  },
2559
2764
  registerSourceData: (pathPattern, sourceData) => {
2560
2765
  const lockfile = _loadLockfile();
2561
2766
  const sectionKey = MD5(pathPattern);
2562
- const sectionChecksums = _17.mapValues(sourceData, (value) => MD5(value));
2767
+ const sectionChecksums = _18.mapValues(sourceData, (value) => MD5(value));
2563
2768
  lockfile.checksums[sectionKey] = sectionChecksums;
2564
2769
  _saveLockfile(lockfile);
2565
2770
  },
2566
2771
  registerPartialSourceData: (pathPattern, partialSourceData) => {
2567
2772
  const lockfile = _loadLockfile();
2568
2773
  const sectionKey = MD5(pathPattern);
2569
- const sectionChecksums = _17.mapValues(partialSourceData, (value) => MD5(value));
2570
- lockfile.checksums[sectionKey] = _17.merge({}, lockfile.checksums[sectionKey] ?? {}, sectionChecksums);
2774
+ const sectionChecksums = _18.mapValues(partialSourceData, (value) => MD5(value));
2775
+ lockfile.checksums[sectionKey] = _18.merge({}, lockfile.checksums[sectionKey] ?? {}, sectionChecksums);
2571
2776
  _saveLockfile(lockfile);
2572
2777
  },
2573
2778
  extractUpdatedData: (pathPattern, sourceData) => {
2574
2779
  const lockfile = _loadLockfile();
2575
2780
  const sectionKey = MD5(pathPattern);
2576
- const currentChecksums = _17.mapValues(sourceData, (value) => MD5(value));
2781
+ const currentChecksums = _18.mapValues(sourceData, (value) => MD5(value));
2577
2782
  const savedChecksums = lockfile.checksums[sectionKey] || {};
2578
- const updatedData = _17.pickBy(sourceData, (value, key) => savedChecksums[key] !== currentChecksums[key]);
2783
+ const updatedData = _18.pickBy(sourceData, (value, key) => savedChecksums[key] !== currentChecksums[key]);
2579
2784
  return updatedData;
2580
2785
  }
2581
2786
  };
2582
2787
  function _loadLockfile() {
2583
2788
  const lockfilePath = _getLockfilePath();
2584
- if (!fs7.existsSync(lockfilePath)) {
2789
+ if (!fs8.existsSync(lockfilePath)) {
2585
2790
  return LockfileSchema.parse({});
2586
2791
  }
2587
- const content = fs7.readFileSync(lockfilePath, "utf-8");
2792
+ const content = fs8.readFileSync(lockfilePath, "utf-8");
2588
2793
  const result = LockfileSchema.parse(YAML3.parse(content));
2589
2794
  return result;
2590
2795
  }
2591
2796
  function _saveLockfile(lockfile) {
2592
2797
  const lockfilePath = _getLockfilePath();
2593
2798
  const content = YAML3.stringify(lockfile);
2594
- fs7.writeFileSync(lockfilePath, content);
2799
+ fs8.writeFileSync(lockfilePath, content);
2595
2800
  }
2596
2801
  function _getLockfilePath() {
2597
- return path7.join(process.cwd(), "i18n.lock");
2802
+ return path9.join(process.cwd(), "i18n.lock");
2598
2803
  }
2599
2804
  }
2600
2805
  var LockfileSchema = Z3.object({
@@ -2619,8 +2824,8 @@ import inquirer2 from "inquirer";
2619
2824
  import externalEditor from "external-editor";
2620
2825
 
2621
2826
  // src/cli/utils/cache.ts
2622
- import path8 from "path";
2623
- import fs8 from "fs";
2827
+ import path10 from "path";
2828
+ import fs9 from "fs";
2624
2829
  var cacheChunk = (targetLocale, sourceChunk, processedChunk) => {
2625
2830
  const rows = Object.entries(sourceChunk).map(([key, source]) => ({
2626
2831
  targetLocale,
@@ -2650,26 +2855,26 @@ function getNormalizedCache() {
2650
2855
  function deleteCache() {
2651
2856
  const cacheFilePath = _getCacheFilePath();
2652
2857
  try {
2653
- fs8.unlinkSync(cacheFilePath);
2858
+ fs9.unlinkSync(cacheFilePath);
2654
2859
  } catch (e) {
2655
2860
  }
2656
2861
  }
2657
2862
  function _loadCache() {
2658
2863
  const cacheFilePath = _getCacheFilePath();
2659
- if (!fs8.existsSync(cacheFilePath)) {
2864
+ if (!fs9.existsSync(cacheFilePath)) {
2660
2865
  return [];
2661
2866
  }
2662
- const content = fs8.readFileSync(cacheFilePath, "utf-8");
2867
+ const content = fs9.readFileSync(cacheFilePath, "utf-8");
2663
2868
  const result = _parseJSONLines(content);
2664
2869
  return result;
2665
2870
  }
2666
2871
  function _appendToCache(rows) {
2667
2872
  const cacheFilePath = _getCacheFilePath();
2668
2873
  const lines = _buildJSONLines(rows);
2669
- fs8.appendFileSync(cacheFilePath, lines);
2874
+ fs9.appendFileSync(cacheFilePath, lines);
2670
2875
  }
2671
2876
  function _getCacheFilePath() {
2672
- return path8.join(process.cwd(), "i18n.cache");
2877
+ return path10.join(process.cwd(), "i18n.cache");
2673
2878
  }
2674
2879
  function _buildJSONLines(rows) {
2675
2880
  return rows.map((row) => JSON.stringify(row)).join("\n") + "\n";
@@ -2823,7 +3028,7 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
2823
3028
  targetData
2824
3029
  });
2825
3030
  if (flags.key) {
2826
- processableData = _18.pickBy(processableData, (_20, key) => key === flags.key);
3031
+ processableData = _19.pickBy(processableData, (_21, key) => key === flags.key);
2827
3032
  }
2828
3033
  if (flags.verbose) {
2829
3034
  bucketOra.info(JSON.stringify(processableData, null, 2));
@@ -2859,7 +3064,7 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
2859
3064
  if (flags.verbose) {
2860
3065
  bucketOra.info(JSON.stringify(processedTargetData, null, 2));
2861
3066
  }
2862
- let finalTargetData = _18.merge({}, sourceData, targetData, processedTargetData);
3067
+ let finalTargetData = _19.merge({}, sourceData, targetData, processedTargetData);
2863
3068
  if (flags.interactive) {
2864
3069
  bucketOra.stop();
2865
3070
  const reviewedData = await reviewChanges({
@@ -2873,7 +3078,7 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
2873
3078
  finalTargetData = reviewedData;
2874
3079
  bucketOra.start(`Applying changes to ${bucketConfig} (${targetLocale})`);
2875
3080
  }
2876
- const finalDiffSize = _18.chain(finalTargetData).omitBy((value, key) => value === targetData[key]).size().value();
3081
+ const finalDiffSize = _19.chain(finalTargetData).omitBy((value, key) => value === targetData[key]).size().value();
2877
3082
  if (finalDiffSize > 0 || flags.force) {
2878
3083
  await bucketLoader.push(targetLocale, finalTargetData);
2879
3084
  bucketOra.succeed(`[${sourceLocale} -> ${targetLocale}] Localization completed`);
@@ -2918,9 +3123,9 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
2918
3123
  }
2919
3124
  });
2920
3125
  function calculateDataDelta(args) {
2921
- const newKeys = _18.difference(Object.keys(args.sourceData), Object.keys(args.targetData));
3126
+ const newKeys = _19.difference(Object.keys(args.sourceData), Object.keys(args.targetData));
2922
3127
  const updatedKeys = Object.keys(args.updatedSourceData);
2923
- const result = _18.chain(args.sourceData).pickBy((value, key) => newKeys.includes(key) || updatedKeys.includes(key)).value();
3128
+ const result = _19.chain(args.sourceData).pickBy((value, key) => newKeys.includes(key) || updatedKeys.includes(key)).value();
2924
3129
  return result;
2925
3130
  }
2926
3131
  async function retryWithExponentialBackoff(operation, maxAttempts, baseDelay = 1e3) {
@@ -3061,7 +3266,7 @@ Reviewing changes for ${chalk.blue(args.pathPattern)} (${chalk.yellow(args.targe
3061
3266
  return args.currentData;
3062
3267
  }
3063
3268
  const customData = { ...args.currentData };
3064
- const changes = _18.reduce(
3269
+ const changes = _19.reduce(
3065
3270
  args.proposedData,
3066
3271
  (result, value, key) => {
3067
3272
  if (args.currentData[key] !== value) {
@@ -3142,7 +3347,7 @@ var flagsSchema = Z5.object({
3142
3347
  // src/cli/cmd/cleanup.ts
3143
3348
  import { resolveOverridenLocale as resolveOverridenLocale5 } from "@lingo.dev/_spec";
3144
3349
  import { Command as Command8 } from "interactive-commander";
3145
- import _19 from "lodash";
3350
+ import _20 from "lodash";
3146
3351
  import Ora7 from "ora";
3147
3352
  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("--verbose", "Show verbose output").action(async function(options) {
3148
3353
  const ora = Ora7();
@@ -3172,7 +3377,7 @@ var cleanup_default = new Command8().command("cleanup").description("Remove keys
3172
3377
  try {
3173
3378
  const targetData = await bucketLoader.pull(targetLocale);
3174
3379
  const targetKeys = Object.keys(targetData);
3175
- const keysToRemove = _19.difference(targetKeys, sourceKeys);
3380
+ const keysToRemove = _20.difference(targetKeys, sourceKeys);
3176
3381
  if (keysToRemove.length === 0) {
3177
3382
  bucketOra.succeed(`[${targetLocale}] No keys to remove`);
3178
3383
  continue;
@@ -3181,7 +3386,7 @@ var cleanup_default = new Command8().command("cleanup").description("Remove keys
3181
3386
  bucketOra.info(`[${targetLocale}] Keys to remove: ${JSON.stringify(keysToRemove, null, 2)}`);
3182
3387
  }
3183
3388
  if (!options.dryRun) {
3184
- const cleanedData = _19.pick(targetData, sourceKeys);
3389
+ const cleanedData = _20.pick(targetData, sourceKeys);
3185
3390
  await bucketLoader.push(targetLocale, cleanedData);
3186
3391
  bucketOra.succeed(`[${targetLocale}] Removed ${keysToRemove.length} keys`);
3187
3392
  } else {
@@ -3233,7 +3438,7 @@ function displaySummary(results) {
3233
3438
  // package.json
3234
3439
  var package_default = {
3235
3440
  name: "lingo.dev",
3236
- version: "0.74.14",
3441
+ version: "0.74.16",
3237
3442
  description: "Lingo.dev CLI",
3238
3443
  private: false,
3239
3444
  publishConfig: {