lingo.dev 0.77.3 → 0.77.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/build/cli.mjs CHANGED
@@ -264,11 +264,11 @@ function _getConfigFilePath() {
264
264
 
265
265
  // src/cli/cmd/init.ts
266
266
  import { defaultConfig, resolveLocaleCode as resolveLocaleCode2, bucketTypes } from "@lingo.dev/_spec";
267
- import fs5 from "fs";
268
- import path6 from "path";
267
+ import fs6 from "fs";
268
+ import path7 from "path";
269
269
  import { spawn } from "child_process";
270
270
  import _3 from "lodash";
271
- import { checkbox, confirm, input } from "@inquirer/prompts";
271
+ import { checkbox as checkbox2, confirm as confirm2, input } from "@inquirer/prompts";
272
272
 
273
273
  // src/cli/utils/find-locale-paths.ts
274
274
  import path3 from "path";
@@ -332,10 +332,11 @@ function findLocaleFilesWithExtension(ext) {
332
332
  });
333
333
  const grouppedFilesAndPatterns = _2.groupBy(localeFilesAndPatterns, "pattern");
334
334
  const patterns = Object.keys(grouppedFilesAndPatterns);
335
+ const defaultPatterns = [`i18n/[locale]${ext}`];
335
336
  if (patterns.length > 0) {
336
- return { found: true, patterns };
337
+ return { patterns, defaultPatterns };
337
338
  }
338
- return { found: false, patterns: [`i18n/[locale]${ext}`] };
339
+ return { patterns: [], defaultPatterns };
339
340
  }
340
341
  function findLocaleFilesForFilename(fileName) {
341
342
  const pattern = fileName;
@@ -348,10 +349,11 @@ function findLocaleFilesForFilename(fileName) {
348
349
  }));
349
350
  const grouppedFilesAndPatterns = _2.groupBy(localeFilesAndPatterns, "pattern");
350
351
  const patterns = Object.keys(grouppedFilesAndPatterns);
352
+ const defaultPatterns = [fileName];
351
353
  if (patterns.length > 0) {
352
- return { found: true, patterns };
354
+ return { patterns, defaultPatterns };
353
355
  }
354
- return { found: false, patterns: [fileName] };
356
+ return { patterns: [], defaultPatterns };
355
357
  }
356
358
 
357
359
  // src/cli/utils/ensure-patterns.ts
@@ -473,10 +475,136 @@ function findCurrentProjectRoot() {
473
475
  return null;
474
476
  }
475
477
 
478
+ // src/cli/utils/init-ci-cd.ts
479
+ import { checkbox, confirm } from "@inquirer/prompts";
480
+ import fs5 from "fs";
481
+ import path6 from "path";
482
+ var platforms = ["github", "bitbucket", "gitlab"];
483
+ async function initCICD(spinner) {
484
+ const initializers = getPlatformInitializers(spinner);
485
+ const init = await confirm({
486
+ message: "Would you like to use Lingo.dev in your CI/CD?"
487
+ });
488
+ if (!init) {
489
+ spinner.warn("CI/CD not initialized. To set it up later, see docs: https://docs.lingo.dev/ci-action/overview");
490
+ return;
491
+ }
492
+ const selectedPlatforms = await checkbox({
493
+ message: "Please select CI/CD platform(s) you want to use:",
494
+ choices: platforms.map((platform) => ({
495
+ name: initializers[platform].name,
496
+ value: platform,
497
+ checked: initializers[platform].isEnabled()
498
+ }))
499
+ });
500
+ for (const platform of selectedPlatforms) {
501
+ await initializers[platform].init();
502
+ }
503
+ }
504
+ function getPlatformInitializers(spinner) {
505
+ return {
506
+ github: makeGithubInitializer(spinner),
507
+ bitbucket: makeBitbucketInitializer(spinner),
508
+ gitlab: makeGitlabInitializer(spinner)
509
+ };
510
+ }
511
+ function makePlatformInitializer(config, spinner) {
512
+ return {
513
+ name: config.name,
514
+ isEnabled: () => {
515
+ const filePath = path6.join(process.cwd(), config.checkPath);
516
+ return fs5.existsSync(filePath);
517
+ },
518
+ init: async () => {
519
+ const filePath = path6.join(process.cwd(), config.ciConfigPath);
520
+ const dirPath = path6.dirname(filePath);
521
+ if (!fs5.existsSync(dirPath)) {
522
+ fs5.mkdirSync(dirPath, { recursive: true });
523
+ }
524
+ let canWrite = true;
525
+ if (fs5.existsSync(filePath)) {
526
+ canWrite = await confirm({
527
+ message: `File ${filePath} already exists. Do you want to overwrite it?`,
528
+ default: false
529
+ });
530
+ }
531
+ if (canWrite) {
532
+ fs5.writeFileSync(filePath, config.ciConfigContent);
533
+ spinner.succeed(`CI/CD initialized for ${config.name}`);
534
+ } else {
535
+ spinner.warn(`CI/CD not initialized for ${config.name}`);
536
+ }
537
+ }
538
+ };
539
+ }
540
+ function makeGithubInitializer(spinner) {
541
+ return makePlatformInitializer(
542
+ {
543
+ name: "GitHub Action",
544
+ checkPath: ".github",
545
+ ciConfigPath: ".github/workflows/i18n.yml",
546
+ ciConfigContent: `name: Lingo.dev i18n
547
+
548
+ on:
549
+ push:
550
+ branches:
551
+ - main
552
+
553
+ permissions:
554
+ contents: write
555
+ pull-requests: write
556
+
557
+ jobs:
558
+ i18n:
559
+ name: Run i18n
560
+ runs-on: ubuntu-latest
561
+ steps:
562
+ - uses: actions/checkout@v4
563
+ - uses: lingodotdev/lingo.dev@main
564
+ with:
565
+ api-key: \${{ secrets.LINGODOTDEV_API_KEY }}
566
+ `
567
+ },
568
+ spinner
569
+ );
570
+ }
571
+ function makeBitbucketInitializer(spinner) {
572
+ return makePlatformInitializer(
573
+ {
574
+ name: "Bitbucket Pipeline",
575
+ checkPath: "bitbucket-pipelines.yml",
576
+ ciConfigPath: "bitbucket-pipelines.yml",
577
+ ciConfigContent: `pipelines:
578
+ branches:
579
+ main:
580
+ - step:
581
+ name: Run i18n
582
+ script:
583
+ - pipe: lingodotdev/lingo.dev:main`
584
+ },
585
+ spinner
586
+ );
587
+ }
588
+ function makeGitlabInitializer(spinner) {
589
+ return makePlatformInitializer(
590
+ {
591
+ name: "Gitlab CI",
592
+ checkPath: ".gitlab-ci.yml",
593
+ ciConfigPath: ".gitlab-ci.yml",
594
+ ciConfigContent: `lingodotdev:
595
+ image: lingodotdev/ci-action:latest
596
+ script:
597
+ - echo "Done"
598
+ `
599
+ },
600
+ spinner
601
+ );
602
+ }
603
+
476
604
  // src/cli/cmd/init.ts
477
- var openUrl = (path12) => {
605
+ var openUrl = (path13) => {
478
606
  const settings = getSettings(void 0);
479
- spawn("open", [`${settings.auth.webUrl}${path12}`]);
607
+ spawn("open", [`${settings.auth.webUrl}${path13}`]);
480
608
  };
481
609
  var throwHelpError = (option, value) => {
482
610
  if (value === "help") {
@@ -522,8 +650,8 @@ var init_default = new InteractiveCommand().command("init").description("Initial
522
650
  const values = value.includes(",") ? value.split(",") : value.split(" ");
523
651
  for (const p of values) {
524
652
  try {
525
- const dirPath = path6.dirname(p);
526
- const stats = fs5.statSync(dirPath);
653
+ const dirPath = path7.dirname(p);
654
+ const stats = fs6.statSync(dirPath);
527
655
  if (!stats.isDirectory()) {
528
656
  throw new Error(`${dirPath} is not a directory`);
529
657
  }
@@ -553,10 +681,10 @@ var init_default = new InteractiveCommand().command("init").description("Initial
553
681
  };
554
682
  } else {
555
683
  let selectedPatterns = [];
556
- const { found, patterns } = findLocaleFiles(options.bucket);
557
- if (found) {
684
+ const { patterns, defaultPatterns } = findLocaleFiles(options.bucket);
685
+ if (patterns.length > 0) {
558
686
  spinner.succeed("Found existing locale files:");
559
- selectedPatterns = await checkbox({
687
+ selectedPatterns = await checkbox2({
560
688
  message: "Select the paths to use",
561
689
  choices: patterns.map((value) => ({
562
690
  value
@@ -566,12 +694,12 @@ var init_default = new InteractiveCommand().command("init").description("Initial
566
694
  spinner.succeed("No existing locale files found.");
567
695
  }
568
696
  if (selectedPatterns.length === 0) {
569
- const useDefault = await confirm({
570
- message: `Use (and create) default path ${patterns.join(", ")}?`
697
+ const useDefault = await confirm2({
698
+ message: `Use (and create) default path ${defaultPatterns.join(", ")}?`
571
699
  });
572
- ensurePatterns(patterns, options.source);
573
700
  if (useDefault) {
574
- selectedPatterns = patterns;
701
+ ensurePatterns(defaultPatterns, options.source);
702
+ selectedPatterns = defaultPatterns;
575
703
  }
576
704
  }
577
705
  if (selectedPatterns.length === 0) {
@@ -589,7 +717,8 @@ var init_default = new InteractiveCommand().command("init").description("Initial
589
717
  await saveConfig(newConfig);
590
718
  spinner.succeed("Lingo.dev project initialized");
591
719
  if (isInteractive) {
592
- const openDocs = await confirm({ message: "Would you like to see our docs?" });
720
+ await initCICD(spinner);
721
+ const openDocs = await confirm2({ message: "Would you like to see our docs?" });
593
722
  if (openDocs) {
594
723
  openUrl("/go/docs");
595
724
  }
@@ -601,7 +730,7 @@ var init_default = new InteractiveCommand().command("init").description("Initial
601
730
  const auth = await authenticator.whoami();
602
731
  if (!auth) {
603
732
  if (isInteractive) {
604
- const doAuth = await confirm({
733
+ const doAuth = await confirm2({
605
734
  message: "It looks like you are not logged into the CLI. Login now?"
606
735
  });
607
736
  if (doAuth) {
@@ -637,8 +766,8 @@ import { Command as Command5 } from "interactive-commander";
637
766
  // src/cli/cmd/show/config.ts
638
767
  import { Command as Command2 } from "interactive-commander";
639
768
  import _4 from "lodash";
640
- import fs6 from "fs";
641
- import path7 from "path";
769
+ import fs7 from "fs";
770
+ import path8 from "path";
642
771
  import { defaultConfig as defaultConfig2 } from "@lingo.dev/_spec";
643
772
  var config_default = new Command2().command("config").description("Print out the current configuration").helpOption("-h, --help", "Show help").action(async (options) => {
644
773
  const fileConfig = loadReplexicaFileConfig();
@@ -646,12 +775,12 @@ var config_default = new Command2().command("config").description("Print out the
646
775
  console.log(JSON.stringify(config, null, 2));
647
776
  });
648
777
  function loadReplexicaFileConfig() {
649
- const replexicaConfigPath = path7.resolve(process.cwd(), "i18n.json");
650
- const fileExists = fs6.existsSync(replexicaConfigPath);
778
+ const replexicaConfigPath = path8.resolve(process.cwd(), "i18n.json");
779
+ const fileExists = fs7.existsSync(replexicaConfigPath);
651
780
  if (!fileExists) {
652
781
  return void 0;
653
782
  }
654
- const fileContent = fs6.readFileSync(replexicaConfigPath, "utf-8");
783
+ const fileContent = fs7.readFileSync(replexicaConfigPath, "utf-8");
655
784
  const replexicaFileConfig = JSON.parse(fileContent);
656
785
  return replexicaFileConfig;
657
786
  }
@@ -688,8 +817,8 @@ import Ora4 from "ora";
688
817
 
689
818
  // src/cli/utils/buckets.ts
690
819
  import _5 from "lodash";
691
- import path8 from "path";
692
- import * as glob2 from "glob";
820
+ import path9 from "path";
821
+ import { glob as glob2 } from "glob";
693
822
  import { resolveOverridenLocale } from "@lingo.dev/_spec";
694
823
  function getBuckets(i18nConfig) {
695
824
  const result = Object.entries(i18nConfig.buckets).map(([bucketType, bucketEntry]) => {
@@ -723,9 +852,9 @@ function extractPathPatterns(sourceLocale, include, exclude) {
723
852
  return result;
724
853
  }
725
854
  function expandPlaceholderedGlob(_pathPattern, sourceLocale) {
726
- const absolutePathPattern = path8.resolve(_pathPattern);
727
- const pathPattern = path8.relative(process.cwd(), absolutePathPattern);
728
- if (path8.relative(process.cwd(), pathPattern).startsWith("..")) {
855
+ const absolutePathPattern = path9.resolve(_pathPattern);
856
+ const pathPattern = path9.relative(process.cwd(), absolutePathPattern);
857
+ if (path9.relative(process.cwd(), pathPattern).startsWith("..")) {
729
858
  throw new CLIError({
730
859
  message: `Invalid path pattern: ${pathPattern}. Path pattern must be within the current working directory.`,
731
860
  docUrl: "invalidPathPattern"
@@ -737,7 +866,7 @@ function expandPlaceholderedGlob(_pathPattern, sourceLocale) {
737
866
  docUrl: "invalidPathPattern"
738
867
  });
739
868
  }
740
- const pathPatternChunks = pathPattern.split(path8.sep);
869
+ const pathPatternChunks = pathPattern.split(path9.sep);
741
870
  const localeSegmentIndexes = pathPatternChunks.reduce((indexes, segment, index) => {
742
871
  if (segment.includes("[locale]")) {
743
872
  indexes.push(index);
@@ -745,18 +874,23 @@ function expandPlaceholderedGlob(_pathPattern, sourceLocale) {
745
874
  return indexes;
746
875
  }, []);
747
876
  const sourcePathPattern = pathPattern.replaceAll(/\[locale\]/g, sourceLocale);
748
- const sourcePaths = glob2.sync(sourcePathPattern, { follow: true, withFileTypes: true }).filter((file) => file.isFile() || file.isSymbolicLink()).map((file) => file.fullpath()).map((fullpath) => path8.relative(process.cwd(), fullpath));
877
+ const sourcePaths = glob2.sync(sourcePathPattern, { follow: true, withFileTypes: true }).filter((file) => file.isFile() || file.isSymbolicLink()).map((file) => file.fullpath()).map((fullpath) => path9.relative(process.cwd(), fullpath));
749
878
  const placeholderedPaths = sourcePaths.map((sourcePath) => {
750
- const sourcePathChunks = sourcePath.split(path8.sep);
879
+ const sourcePathChunks = sourcePath.split(path9.sep);
751
880
  localeSegmentIndexes.forEach((localeSegmentIndex) => {
752
- const localePlaceholderIndex = pathPatternChunks[localeSegmentIndex]?.indexOf("[locale]") ?? -1;
753
- if (localeSegmentIndex >= 0 && localePlaceholderIndex >= 0) {
754
- const placeholderedPathChunk = sourcePathChunks[localeSegmentIndex];
755
- const placeholderedSegment = placeholderedPathChunk.substring(0, localePlaceholderIndex) + "[locale]" + placeholderedPathChunk.substring(localePlaceholderIndex + sourceLocale.length);
881
+ const pathPatternChunk = pathPatternChunks[localeSegmentIndex];
882
+ const sourcePathChunk = sourcePathChunks[localeSegmentIndex];
883
+ const regexp = new RegExp(
884
+ "(" + pathPatternChunk.replaceAll(".", "\\.").replaceAll("*", ".*").replace("[locale]", `)${sourceLocale}(`) + ")"
885
+ );
886
+ const match = sourcePathChunk.match(regexp);
887
+ if (match) {
888
+ const [, prefix, suffix] = match;
889
+ const placeholderedSegment = prefix + "[locale]" + suffix;
756
890
  sourcePathChunks[localeSegmentIndex] = placeholderedSegment;
757
891
  }
758
892
  });
759
- const placeholderedPath = sourcePathChunks.join(path8.sep);
893
+ const placeholderedPath = sourcePathChunks.join(path9.sep);
760
894
  return placeholderedPath;
761
895
  });
762
896
  return placeholderedPaths;
@@ -798,8 +932,8 @@ var files_default = new Command4().command("files").description("Print out the l
798
932
  } else if (type.target) {
799
933
  result.push(...targetPaths);
800
934
  }
801
- result.forEach((path12) => {
802
- console.log(path12);
935
+ result.forEach((path13) => {
936
+ console.log(path13);
803
937
  });
804
938
  }
805
939
  }
@@ -1021,8 +1155,8 @@ function normalizeObjectKeys(obj) {
1021
1155
  }
1022
1156
 
1023
1157
  // src/cli/loaders/text-file.ts
1024
- import fs7 from "fs/promises";
1025
- import path9 from "path";
1158
+ import fs8 from "fs/promises";
1159
+ import path10 from "path";
1026
1160
  function createTextFileLoader(pathPattern) {
1027
1161
  return createLoader({
1028
1162
  async pull(locale) {
@@ -1032,13 +1166,13 @@ function createTextFileLoader(pathPattern) {
1032
1166
  },
1033
1167
  async push(locale, data, _21, originalLocale) {
1034
1168
  const draftPath = pathPattern.replaceAll("[locale]", locale);
1035
- const finalPath = path9.resolve(draftPath);
1036
- const dirPath = path9.dirname(finalPath);
1037
- await fs7.mkdir(dirPath, { recursive: true });
1169
+ const finalPath = path10.resolve(draftPath);
1170
+ const dirPath = path10.dirname(finalPath);
1171
+ await fs8.mkdir(dirPath, { recursive: true });
1038
1172
  const trimmedPayload = data.trim();
1039
1173
  const trailingNewLine = await getTrailingNewLine(pathPattern, locale, originalLocale);
1040
1174
  let finalPayload = trimmedPayload + trailingNewLine;
1041
- await fs7.writeFile(finalPath, finalPayload, {
1175
+ await fs8.writeFile(finalPath, finalPayload, {
1042
1176
  encoding: "utf-8",
1043
1177
  flag: "w"
1044
1178
  });
@@ -1047,12 +1181,12 @@ function createTextFileLoader(pathPattern) {
1047
1181
  }
1048
1182
  async function readFileForLocale(pathPattern, locale) {
1049
1183
  const draftPath = pathPattern.replaceAll("[locale]", locale);
1050
- const finalPath = path9.resolve(draftPath);
1051
- const exists = await fs7.access(finalPath).then(() => true).catch(() => false);
1184
+ const finalPath = path10.resolve(draftPath);
1185
+ const exists = await fs8.access(finalPath).then(() => true).catch(() => false);
1052
1186
  if (!exists) {
1053
1187
  return "";
1054
1188
  }
1055
- return fs7.readFile(finalPath, "utf-8");
1189
+ return fs8.readFile(finalPath, "utf-8");
1056
1190
  }
1057
1191
  async function getTrailingNewLine(pathPattern, locale, originalLocale) {
1058
1192
  let templateData = await readFileForLocale(pathPattern, locale);
@@ -1339,9 +1473,9 @@ function createHtmlLoader() {
1339
1473
  const bDepth = b.split("/").length;
1340
1474
  return aDepth - bDepth;
1341
1475
  });
1342
- paths.forEach((path12) => {
1343
- const value = data[path12];
1344
- const [nodePath, attribute] = path12.split("#");
1476
+ paths.forEach((path13) => {
1477
+ const value = data[path13];
1478
+ const [nodePath, attribute] = path13.split("#");
1345
1479
  const [rootTag, ...indices] = nodePath.split("/");
1346
1480
  let parent = rootTag === "head" ? document.head : document.body;
1347
1481
  let current = parent;
@@ -1845,7 +1979,7 @@ function createSrtLoader() {
1845
1979
  }
1846
1980
 
1847
1981
  // src/cli/loaders/dato/index.ts
1848
- import fs8 from "fs";
1982
+ import fs9 from "fs";
1849
1983
  import JSON5 from "json5";
1850
1984
 
1851
1985
  // src/cli/loaders/dato/_base.ts
@@ -2348,18 +2482,18 @@ function createRawDatoValue(parsedDatoValue, originalRawDatoValue, isClean = fal
2348
2482
  }
2349
2483
  function serializeStructuredText(rawStructuredText) {
2350
2484
  return serializeStructuredTextNode(rawStructuredText);
2351
- function serializeStructuredTextNode(node, path12 = [], acc = {}) {
2485
+ function serializeStructuredTextNode(node, path13 = [], acc = {}) {
2352
2486
  if ("document" in node) {
2353
- return serializeStructuredTextNode(node.document, [...path12, "document"], acc);
2487
+ return serializeStructuredTextNode(node.document, [...path13, "document"], acc);
2354
2488
  }
2355
2489
  if (!_15.isNil(node.value)) {
2356
- acc[[...path12, "value"].join(".")] = node.value;
2490
+ acc[[...path13, "value"].join(".")] = node.value;
2357
2491
  } else if (_15.get(node, "type") === "block") {
2358
- acc[[...path12, "item"].join(".")] = serializeBlock(node.item);
2492
+ acc[[...path13, "item"].join(".")] = serializeBlock(node.item);
2359
2493
  }
2360
2494
  if (node.children) {
2361
2495
  for (let i = 0; i < node.children.length; i++) {
2362
- serializeStructuredTextNode(node.children[i], [...path12, i.toString()], acc);
2496
+ serializeStructuredTextNode(node.children[i], [...path13, i.toString()], acc);
2363
2497
  }
2364
2498
  }
2365
2499
  return acc;
@@ -2418,8 +2552,8 @@ function deserializeBlockList(parsedBlockList, originalRawBlockList, isClean = f
2418
2552
  }
2419
2553
  function deserializeStructuredText(parsedStructuredText, originalRawStructuredText) {
2420
2554
  const result = _15.cloneDeep(originalRawStructuredText);
2421
- for (const [path12, value] of _15.entries(parsedStructuredText)) {
2422
- const realPath = _15.chain(path12.split(".")).flatMap((s) => !_15.isNaN(_15.toNumber(s)) ? ["children", s] : s).value();
2555
+ for (const [path13, value] of _15.entries(parsedStructuredText)) {
2556
+ const realPath = _15.chain(path13.split(".")).flatMap((s) => !_15.isNaN(_15.toNumber(s)) ? ["children", s] : s).value();
2423
2557
  const deserializedValue = createRawDatoValue(value, _15.get(originalRawStructuredText, realPath), true);
2424
2558
  _15.set(result, realPath, deserializedValue);
2425
2559
  }
@@ -2444,12 +2578,12 @@ function _isVideo(rawDatoValue) {
2444
2578
  // src/cli/loaders/dato/index.ts
2445
2579
  function createDatoLoader(configFilePath) {
2446
2580
  try {
2447
- const configContent = fs8.readFileSync(configFilePath, "utf-8");
2581
+ const configContent = fs9.readFileSync(configFilePath, "utf-8");
2448
2582
  const datoConfig = datoConfigSchema.parse(JSON5.parse(configContent));
2449
2583
  return composeLoaders(
2450
2584
  createDatoApiLoader(
2451
2585
  datoConfig,
2452
- (updatedConfig) => fs8.writeFileSync(configFilePath, JSON5.stringify(updatedConfig, null, 2))
2586
+ (updatedConfig) => fs9.writeFileSync(configFilePath, JSON5.stringify(updatedConfig, null, 2))
2453
2587
  ),
2454
2588
  createDatoFilterLoader(),
2455
2589
  createDatoExtractLoader()
@@ -2871,8 +3005,8 @@ function createBucketLoader(bucketType, bucketPathPattern, { isCacheRestore = fa
2871
3005
  }
2872
3006
 
2873
3007
  // src/cli/utils/lockfile.ts
2874
- import fs9 from "fs";
2875
- import path10 from "path";
3008
+ import fs10 from "fs";
3009
+ import path11 from "path";
2876
3010
  import Z3 from "zod";
2877
3011
  import YAML3 from "yaml";
2878
3012
  import { MD5 } from "object-hash";
@@ -2881,7 +3015,7 @@ function createLockfileHelper() {
2881
3015
  return {
2882
3016
  isLockfileExists: () => {
2883
3017
  const lockfilePath = _getLockfilePath();
2884
- return fs9.existsSync(lockfilePath);
3018
+ return fs10.existsSync(lockfilePath);
2885
3019
  },
2886
3020
  registerSourceData: (pathPattern, sourceData) => {
2887
3021
  const lockfile = _loadLockfile();
@@ -2908,20 +3042,20 @@ function createLockfileHelper() {
2908
3042
  };
2909
3043
  function _loadLockfile() {
2910
3044
  const lockfilePath = _getLockfilePath();
2911
- if (!fs9.existsSync(lockfilePath)) {
3045
+ if (!fs10.existsSync(lockfilePath)) {
2912
3046
  return LockfileSchema.parse({});
2913
3047
  }
2914
- const content = fs9.readFileSync(lockfilePath, "utf-8");
3048
+ const content = fs10.readFileSync(lockfilePath, "utf-8");
2915
3049
  const result = LockfileSchema.parse(YAML3.parse(content));
2916
3050
  return result;
2917
3051
  }
2918
3052
  function _saveLockfile(lockfile) {
2919
3053
  const lockfilePath = _getLockfilePath();
2920
3054
  const content = YAML3.stringify(lockfile);
2921
- fs9.writeFileSync(lockfilePath, content);
3055
+ fs10.writeFileSync(lockfilePath, content);
2922
3056
  }
2923
3057
  function _getLockfilePath() {
2924
- return path10.join(process.cwd(), "i18n.lock");
3058
+ return path11.join(process.cwd(), "i18n.lock");
2925
3059
  }
2926
3060
  }
2927
3061
  var LockfileSchema = Z3.object({
@@ -2946,8 +3080,8 @@ import inquirer2 from "inquirer";
2946
3080
  import externalEditor from "external-editor";
2947
3081
 
2948
3082
  // src/cli/utils/cache.ts
2949
- import path11 from "path";
2950
- import fs10 from "fs";
3083
+ import path12 from "path";
3084
+ import fs11 from "fs";
2951
3085
  var cacheChunk = (targetLocale, sourceChunk, processedChunk) => {
2952
3086
  const rows = Object.entries(sourceChunk).map(([key, source]) => ({
2953
3087
  targetLocale,
@@ -2977,26 +3111,26 @@ function getNormalizedCache() {
2977
3111
  function deleteCache() {
2978
3112
  const cacheFilePath = _getCacheFilePath();
2979
3113
  try {
2980
- fs10.unlinkSync(cacheFilePath);
3114
+ fs11.unlinkSync(cacheFilePath);
2981
3115
  } catch (e) {
2982
3116
  }
2983
3117
  }
2984
3118
  function _loadCache() {
2985
3119
  const cacheFilePath = _getCacheFilePath();
2986
- if (!fs10.existsSync(cacheFilePath)) {
3120
+ if (!fs11.existsSync(cacheFilePath)) {
2987
3121
  return [];
2988
3122
  }
2989
- const content = fs10.readFileSync(cacheFilePath, "utf-8");
3123
+ const content = fs11.readFileSync(cacheFilePath, "utf-8");
2990
3124
  const result = _parseJSONLines(content);
2991
3125
  return result;
2992
3126
  }
2993
3127
  function _appendToCache(rows) {
2994
3128
  const cacheFilePath = _getCacheFilePath();
2995
3129
  const lines = _buildJSONLines(rows);
2996
- fs10.appendFileSync(cacheFilePath, lines);
3130
+ fs11.appendFileSync(cacheFilePath, lines);
2997
3131
  }
2998
3132
  function _getCacheFilePath() {
2999
- return path11.join(process.cwd(), "i18n.cache");
3133
+ return path12.join(process.cwd(), "i18n.cache");
3000
3134
  }
3001
3135
  function _buildJSONLines(rows) {
3002
3136
  return rows.map((row) => JSON.stringify(row)).join("\n") + "\n";
@@ -3618,7 +3752,7 @@ var mcp_default = new Command9().command("mcp").description("Use Lingo.dev model
3618
3752
  // package.json
3619
3753
  var package_default = {
3620
3754
  name: "lingo.dev",
3621
- version: "0.77.3",
3755
+ version: "0.77.5",
3622
3756
  description: "Lingo.dev CLI",
3623
3757
  private: false,
3624
3758
  publishConfig: {