lingo.dev 0.100.0 → 0.101.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/build/cli.cjs CHANGED
@@ -22,16 +22,17 @@ function getSettings(explicitApiKey) {
22
22
  _envVarsInfo();
23
23
  return {
24
24
  auth: {
25
- apiKey: explicitApiKey || env.LINGODOTDEV_API_KEY || _optionalChain([systemFile, 'access', _34 => _34.auth, 'optionalAccess', _35 => _35.apiKey]) || defaults2.auth.apiKey,
26
- apiUrl: env.LINGODOTDEV_API_URL || _optionalChain([systemFile, 'access', _36 => _36.auth, 'optionalAccess', _37 => _37.apiUrl]) || defaults2.auth.apiUrl,
27
- webUrl: env.LINGODOTDEV_WEB_URL || _optionalChain([systemFile, 'access', _38 => _38.auth, 'optionalAccess', _39 => _39.webUrl]) || defaults2.auth.webUrl
25
+ apiKey: explicitApiKey || env.LINGODOTDEV_API_KEY || _optionalChain([systemFile, 'access', _35 => _35.auth, 'optionalAccess', _36 => _36.apiKey]) || defaults2.auth.apiKey,
26
+ apiUrl: env.LINGODOTDEV_API_URL || _optionalChain([systemFile, 'access', _37 => _37.auth, 'optionalAccess', _38 => _38.apiUrl]) || defaults2.auth.apiUrl,
27
+ webUrl: env.LINGODOTDEV_WEB_URL || _optionalChain([systemFile, 'access', _39 => _39.auth, 'optionalAccess', _40 => _40.webUrl]) || defaults2.auth.webUrl
28
28
  },
29
29
  llm: {
30
- openaiApiKey: env.OPENAI_API_KEY || _optionalChain([systemFile, 'access', _40 => _40.llm, 'optionalAccess', _41 => _41.openaiApiKey]),
31
- anthropicApiKey: env.ANTHROPIC_API_KEY || _optionalChain([systemFile, 'access', _42 => _42.llm, 'optionalAccess', _43 => _43.anthropicApiKey]),
32
- groqApiKey: env.GROQ_API_KEY || _optionalChain([systemFile, 'access', _44 => _44.llm, 'optionalAccess', _45 => _45.groqApiKey]),
33
- googleApiKey: env.GOOGLE_API_KEY || _optionalChain([systemFile, 'access', _46 => _46.llm, 'optionalAccess', _47 => _47.googleApiKey]),
34
- openrouterApiKey: env.OPENROUTER_API_KEY || _optionalChain([systemFile, 'access', _48 => _48.llm, 'optionalAccess', _49 => _49.openrouterApiKey])
30
+ openaiApiKey: env.OPENAI_API_KEY || _optionalChain([systemFile, 'access', _41 => _41.llm, 'optionalAccess', _42 => _42.openaiApiKey]),
31
+ anthropicApiKey: env.ANTHROPIC_API_KEY || _optionalChain([systemFile, 'access', _43 => _43.llm, 'optionalAccess', _44 => _44.anthropicApiKey]),
32
+ groqApiKey: env.GROQ_API_KEY || _optionalChain([systemFile, 'access', _45 => _45.llm, 'optionalAccess', _46 => _46.groqApiKey]),
33
+ googleApiKey: env.GOOGLE_API_KEY || _optionalChain([systemFile, 'access', _47 => _47.llm, 'optionalAccess', _48 => _48.googleApiKey]),
34
+ openrouterApiKey: env.OPENROUTER_API_KEY || _optionalChain([systemFile, 'access', _49 => _49.llm, 'optionalAccess', _50 => _50.openrouterApiKey]),
35
+ mistralApiKey: env.MISTRAL_API_KEY || _optionalChain([systemFile, 'access', _51 => _51.llm, 'optionalAccess', _52 => _52.mistralApiKey])
35
36
  }
36
37
  };
37
38
  }
@@ -61,7 +62,8 @@ var SettingsSchema = _zod2.default.object({
61
62
  anthropicApiKey: _zod2.default.string().optional(),
62
63
  groqApiKey: _zod2.default.string().optional(),
63
64
  googleApiKey: _zod2.default.string().optional(),
64
- openrouterApiKey: _zod2.default.string().optional()
65
+ openrouterApiKey: _zod2.default.string().optional(),
66
+ mistralApiKey: _zod2.default.string().optional()
65
67
  })
66
68
  });
67
69
  var SETTINGS_KEYS = flattenZodObject(
@@ -86,7 +88,8 @@ function _loadEnv() {
86
88
  ANTHROPIC_API_KEY: _zod2.default.string().optional(),
87
89
  GROQ_API_KEY: _zod2.default.string().optional(),
88
90
  GOOGLE_API_KEY: _zod2.default.string().optional(),
89
- OPENROUTER_API_KEY: _zod2.default.string().optional()
91
+ OPENROUTER_API_KEY: _zod2.default.string().optional(),
92
+ MISTRAL_API_KEY: _zod2.default.string().optional()
90
93
  }).passthrough().parse(process.env);
91
94
  }
92
95
  function _loadSystemFile() {
@@ -104,7 +107,8 @@ function _loadSystemFile() {
104
107
  anthropicApiKey: _zod2.default.string().optional(),
105
108
  groqApiKey: _zod2.default.string().optional(),
106
109
  googleApiKey: _zod2.default.string().optional(),
107
- openrouterApiKey: _zod2.default.string().optional()
110
+ openrouterApiKey: _zod2.default.string().optional(),
111
+ mistralApiKey: _zod2.default.string().optional()
108
112
  }).optional()
109
113
  }).passthrough().parse(data);
110
114
  }
@@ -137,42 +141,48 @@ Please use LINGODOTDEV_API_KEY instead.
137
141
  function _envVarsInfo() {
138
142
  const env = _loadEnv();
139
143
  const systemFile = _loadSystemFile();
140
- if (env.LINGODOTDEV_API_KEY && _optionalChain([systemFile, 'access', _50 => _50.auth, 'optionalAccess', _51 => _51.apiKey])) {
144
+ if (env.LINGODOTDEV_API_KEY && _optionalChain([systemFile, 'access', _53 => _53.auth, 'optionalAccess', _54 => _54.apiKey])) {
141
145
  console.info(
142
146
  "\x1B[36m%s\x1B[0m",
143
147
  `\u2139\uFE0F Using LINGODOTDEV_API_KEY env var instead of credentials from user config`
144
148
  );
145
149
  }
146
- if (env.OPENAI_API_KEY && _optionalChain([systemFile, 'access', _52 => _52.llm, 'optionalAccess', _53 => _53.openaiApiKey])) {
150
+ if (env.OPENAI_API_KEY && _optionalChain([systemFile, 'access', _55 => _55.llm, 'optionalAccess', _56 => _56.openaiApiKey])) {
147
151
  console.info(
148
152
  "\x1B[36m%s\x1B[0m",
149
153
  `\u2139\uFE0F Using OPENAI_API_KEY env var instead of key from user config.`
150
154
  );
151
155
  }
152
- if (env.ANTHROPIC_API_KEY && _optionalChain([systemFile, 'access', _54 => _54.llm, 'optionalAccess', _55 => _55.anthropicApiKey])) {
156
+ if (env.ANTHROPIC_API_KEY && _optionalChain([systemFile, 'access', _57 => _57.llm, 'optionalAccess', _58 => _58.anthropicApiKey])) {
153
157
  console.info(
154
158
  "\x1B[36m%s\x1B[0m",
155
159
  `\u2139\uFE0F Using ANTHROPIC_API_KEY env var instead of key from user config`
156
160
  );
157
161
  }
158
- if (env.GROQ_API_KEY && _optionalChain([systemFile, 'access', _56 => _56.llm, 'optionalAccess', _57 => _57.groqApiKey])) {
162
+ if (env.GROQ_API_KEY && _optionalChain([systemFile, 'access', _59 => _59.llm, 'optionalAccess', _60 => _60.groqApiKey])) {
159
163
  console.info(
160
164
  "\x1B[36m%s\x1B[0m",
161
165
  `\u2139\uFE0F Using GROQ_API_KEY env var instead of key from user config`
162
166
  );
163
167
  }
164
- if (env.GOOGLE_API_KEY && _optionalChain([systemFile, 'access', _58 => _58.llm, 'optionalAccess', _59 => _59.googleApiKey])) {
168
+ if (env.GOOGLE_API_KEY && _optionalChain([systemFile, 'access', _61 => _61.llm, 'optionalAccess', _62 => _62.googleApiKey])) {
165
169
  console.info(
166
170
  "\x1B[36m%s\x1B[0m",
167
171
  `\u2139\uFE0F Using GOOGLE_API_KEY env var instead of key from user config`
168
172
  );
169
173
  }
170
- if (env.OPENROUTER_API_KEY && _optionalChain([systemFile, 'access', _60 => _60.llm, 'optionalAccess', _61 => _61.openrouterApiKey])) {
174
+ if (env.OPENROUTER_API_KEY && _optionalChain([systemFile, 'access', _63 => _63.llm, 'optionalAccess', _64 => _64.openrouterApiKey])) {
171
175
  console.info(
172
176
  "\x1B[36m%s\x1B[0m",
173
177
  `\u2139\uFE0F Using OPENROUTER_API_KEY env var instead of key from user config`
174
178
  );
175
179
  }
180
+ if (env.MISTRAL_API_KEY && _optionalChain([systemFile, 'access', _65 => _65.llm, 'optionalAccess', _66 => _66.mistralApiKey])) {
181
+ console.info(
182
+ "\x1B[36m%s\x1B[0m",
183
+ `\u2139\uFE0F Using MISTRAL_API_KEY env var instead of key from user config`
184
+ );
185
+ }
176
186
  if (env.LINGODOTDEV_API_URL) {
177
187
  console.info(
178
188
  "\x1B[36m%s\x1B[0m",
@@ -217,9 +227,12 @@ var CLIError = class extends Error {
217
227
  // src/cli/utils/cloudflare-status.ts
218
228
  async function checkCloudflareStatus() {
219
229
  try {
220
- const response = await fetch("https://www.cloudflarestatus.com/api/v2/status.json", {
221
- signal: AbortSignal.timeout(5e3)
222
- });
230
+ const response = await fetch(
231
+ "https://www.cloudflarestatus.com/api/v2/status.json",
232
+ {
233
+ signal: AbortSignal.timeout(5e3)
234
+ }
235
+ );
223
236
  if (response.ok) {
224
237
  return await response.json();
225
238
  }
@@ -248,7 +261,7 @@ function createAuthenticator(params) {
248
261
  });
249
262
  if (res.ok) {
250
263
  const payload = await res.json();
251
- if (!_optionalChain([payload, 'optionalAccess', _62 => _62.email])) {
264
+ if (!_optionalChain([payload, 'optionalAccess', _67 => _67.email])) {
252
265
  return null;
253
266
  }
254
267
  return {
@@ -378,7 +391,9 @@ async function renderBanner() {
378
391
  }
379
392
  async function renderHero() {
380
393
  console.log(
381
- `\u26A1\uFE0F ${_chalk2.default.hex(colors.green)("Lingo.dev")} - open-source, AI-powered i18n CLI for web & mobile localization.`
394
+ `\u26A1\uFE0F ${_chalk2.default.hex(colors.green)(
395
+ "Lingo.dev"
396
+ )} - open-source, AI-powered i18n CLI for web & mobile localization.`
382
397
  );
383
398
  console.log("");
384
399
  const label1 = "\u2B50 GitHub Repo:";
@@ -386,13 +401,19 @@ async function renderHero() {
386
401
  const label3 = "\u{1F4AC} 24/7 Support:";
387
402
  const maxLabelWidth = 17;
388
403
  console.log(
389
- `${_chalk2.default.hex(colors.blue)(label1.padEnd(maxLabelWidth))} ${_chalk2.default.hex(colors.blue)("https://lingo.dev/go/gh")}`
404
+ `${_chalk2.default.hex(colors.blue)(label1.padEnd(maxLabelWidth))} ${_chalk2.default.hex(
405
+ colors.blue
406
+ )("https://lingo.dev/go/gh")}`
390
407
  );
391
408
  console.log(
392
- `${_chalk2.default.hex(colors.blue)(label2.padEnd(maxLabelWidth + 1))} ${_chalk2.default.hex(colors.blue)("https://lingo.dev/go/docs")}`
409
+ `${_chalk2.default.hex(colors.blue)(label2.padEnd(maxLabelWidth + 1))} ${_chalk2.default.hex(
410
+ colors.blue
411
+ )("https://lingo.dev/go/docs")}`
393
412
  );
394
413
  console.log(
395
- `${_chalk2.default.hex(colors.blue)(label3.padEnd(maxLabelWidth + 1))} ${_chalk2.default.hex(colors.blue)("hi@lingo.dev")}`
414
+ `${_chalk2.default.hex(colors.blue)(label3.padEnd(maxLabelWidth + 1))} ${_chalk2.default.hex(
415
+ colors.blue
416
+ )("hi@lingo.dev")}`
396
417
  );
397
418
  }
398
419
  async function waitForUserPrompt(message) {
@@ -545,6 +566,10 @@ function _getConfigFilePath() {
545
566
 
546
567
 
547
568
 
569
+
570
+
571
+
572
+
548
573
  var _prompts = require('@inquirer/prompts');
549
574
 
550
575
  // src/cli/utils/find-locale-paths.ts
@@ -583,13 +608,17 @@ function findLocaleFilesWithExtension(ext2) {
583
608
  ignore: ["node_modules/**", "package*.json", "i18n.json", "lingo.json"]
584
609
  });
585
610
  const localeFilePattern = new RegExp(`/([a-z]{2}(-[A-Z]{2})?)${ext2}$`);
586
- const localeDirectoryPattern = new RegExp(`/([a-z]{2}(-[A-Z]{2})?)/[^/]+${ext2}$`);
611
+ const localeDirectoryPattern = new RegExp(
612
+ `/([a-z]{2}(-[A-Z]{2})?)/[^/]+${ext2}$`
613
+ );
587
614
  const potentialLocaleFiles = files.filter(
588
615
  (file) => localeFilePattern.test(file) || localeDirectoryPattern.test(file)
589
616
  );
590
617
  const potantialLocaleFilesAndPatterns = potentialLocaleFiles.map((file) => {
591
618
  const matchPotentialLocales = Array.from(
592
- file.matchAll(new RegExp(`/([a-z]{2}(-[A-Z]{2})?|[^/]+)(?=/|${ext2})`, "g"))
619
+ file.matchAll(
620
+ new RegExp(`/([a-z]{2}(-[A-Z]{2})?|[^/]+)(?=/|${ext2})`, "g")
621
+ )
593
622
  );
594
623
  const potantialLocales = matchPotentialLocales.map((match2) => match2[1]);
595
624
  return { file, potantialLocales };
@@ -603,10 +632,12 @@ function findLocaleFilesWithExtension(ext2) {
603
632
  }
604
633
  return { file, locale: null };
605
634
  }).filter(({ locale }) => locale !== null);
606
- const localeFilesAndPatterns = potantialLocaleFilesAndPatterns.map(({ file, locale }) => {
607
- const pattern = file.replaceAll(new RegExp(`/${locale}${ext2}`, "g"), `/[locale]${ext2}`).replaceAll(new RegExp(`/${locale}/`, "g"), `/[locale]/`).replaceAll(new RegExp(`/${locale}/`, "g"), `/[locale]/`);
608
- return { pattern, file };
609
- });
635
+ const localeFilesAndPatterns = potantialLocaleFilesAndPatterns.map(
636
+ ({ file, locale }) => {
637
+ const pattern = file.replaceAll(new RegExp(`/${locale}${ext2}`, "g"), `/[locale]${ext2}`).replaceAll(new RegExp(`/${locale}/`, "g"), `/[locale]/`).replaceAll(new RegExp(`/${locale}/`, "g"), `/[locale]/`);
638
+ return { pattern, file };
639
+ }
640
+ );
610
641
  const grouppedFilesAndPatterns = _lodash2.default.groupBy(localeFilesAndPatterns, "pattern");
611
642
  const patterns = Object.keys(grouppedFilesAndPatterns);
612
643
  const defaultPatterns = [`i18n/[locale]${ext2}`];
@@ -764,7 +795,9 @@ async function initCICD(spinner) {
764
795
  message: "Would you like to use Lingo.dev in your CI/CD?"
765
796
  });
766
797
  if (!init) {
767
- spinner.warn("CI/CD not initialized. To set it up later, see docs: https://lingo.dev/ci");
798
+ spinner.warn(
799
+ "CI/CD not initialized. To set it up later, see docs: https://lingo.dev/ci"
800
+ );
768
801
  return;
769
802
  }
770
803
  const selectedPlatforms = await _prompts.checkbox.call(void 0, {
@@ -895,7 +928,9 @@ var throwHelpError = (option, value) => {
895
928
  Do you need support for ${value} ${option}? Type "help" and we will.`
896
929
  );
897
930
  };
898
- var init_default = new (0, _interactivecommander.InteractiveCommand)().command("init").description("Initialize Lingo.dev project").helpOption("-h, --help", "Show help").addOption(new (0, _interactivecommander.InteractiveOption)("-f --force", "Overwrite existing config").prompt(void 0).default(false)).addOption(
931
+ var init_default = new (0, _interactivecommander.InteractiveCommand)().command("init").description("Initialize Lingo.dev project").helpOption("-h, --help", "Show help").addOption(
932
+ new (0, _interactivecommander.InteractiveOption)("-f --force", "Overwrite existing config").prompt(void 0).default(false)
933
+ ).addOption(
899
934
  new (0, _interactivecommander.InteractiveOption)("-s --source <locale>", "Source locale").argParser((value) => {
900
935
  try {
901
936
  __spec.resolveLocaleCode.call(void 0, value);
@@ -924,7 +959,10 @@ var init_default = new (0, _interactivecommander.InteractiveCommand)().command("
924
959
  return value;
925
960
  }).default("json")
926
961
  ).addOption(
927
- new (0, _interactivecommander.InteractiveOption)("-p, --paths [path...]", "List of paths for the bucket").argParser((value) => {
962
+ new (0, _interactivecommander.InteractiveOption)(
963
+ "-p, --paths [path...]",
964
+ "List of paths for the bucket"
965
+ ).argParser((value) => {
928
966
  if (!value || value.length === 0) return [];
929
967
  const values = value.includes(",") ? value.split(",") : value.split(" ");
930
968
  for (const p of values) {
@@ -985,7 +1023,9 @@ var init_default = new (0, _interactivecommander.InteractiveCommand)().command("
985
1023
  }
986
1024
  if (selectedPatterns.length === 0) {
987
1025
  const useDefault = await _prompts.confirm.call(void 0, {
988
- message: `Use (and create) default path ${defaultPatterns.join(", ")}?`
1026
+ message: `Use (and create) default path ${defaultPatterns.join(
1027
+ ", "
1028
+ )}?`
989
1029
  });
990
1030
  if (useDefault) {
991
1031
  ensurePatterns(defaultPatterns, options.source);
@@ -1009,7 +1049,9 @@ var init_default = new (0, _interactivecommander.InteractiveCommand)().command("
1009
1049
  spinner.succeed("Lingo.dev project initialized");
1010
1050
  if (isInteractive) {
1011
1051
  await initCICD(spinner);
1012
- const openDocs = await _prompts.confirm.call(void 0, { message: "Would you like to see our docs?" });
1052
+ const openDocs = await _prompts.confirm.call(void 0, {
1053
+ message: "Would you like to see our docs?"
1054
+ });
1013
1055
  if (openDocs) {
1014
1056
  openUrl("/go/docs");
1015
1057
  }
@@ -1034,13 +1076,15 @@ var init_default = new (0, _interactivecommander.InteractiveCommand)().command("
1034
1076
  });
1035
1077
  const auth2 = await newAuthenticator.whoami();
1036
1078
  if (auth2) {
1037
- _ora2.default.call(void 0, ).succeed(`Authenticated as ${_optionalChain([auth2, 'optionalAccess', _63 => _63.email])}`);
1079
+ _ora2.default.call(void 0, ).succeed(`Authenticated as ${_optionalChain([auth2, 'optionalAccess', _68 => _68.email])}`);
1038
1080
  } else {
1039
1081
  _ora2.default.call(void 0, ).fail("Authentication failed.");
1040
1082
  }
1041
1083
  }
1042
1084
  } else {
1043
- _ora2.default.call(void 0, ).warn("You are not logged in. Run `npx lingo.dev@latest auth --login` to login.");
1085
+ _ora2.default.call(void 0, ).warn(
1086
+ "You are not logged in. Run `npx lingo.dev@latest auth --login` to login."
1087
+ );
1044
1088
  }
1045
1089
  } else {
1046
1090
  _ora2.default.call(void 0, ).succeed(`Authenticated as ${auth.email}`);
@@ -1119,7 +1163,7 @@ function getBuckets(i18nConfig) {
1119
1163
  const includeItems = bucketEntry.include.map(
1120
1164
  (item) => resolveBucketItem(item)
1121
1165
  );
1122
- const excludeItems = _optionalChain([bucketEntry, 'access', _64 => _64.exclude, 'optionalAccess', _65 => _65.map, 'call', _66 => _66(
1166
+ const excludeItems = _optionalChain([bucketEntry, 'access', _69 => _69.exclude, 'optionalAccess', _70 => _70.map, 'call', _71 => _71(
1123
1167
  (item) => resolveBucketItem(item)
1124
1168
  )]);
1125
1169
  const config = {
@@ -1157,7 +1201,7 @@ function extractPathPatterns(sourceLocale, include, exclude) {
1157
1201
  delimiter: pattern.delimiter
1158
1202
  }))
1159
1203
  );
1160
- const excludedPatterns = _optionalChain([exclude, 'optionalAccess', _67 => _67.flatMap, 'call', _68 => _68(
1204
+ const excludedPatterns = _optionalChain([exclude, 'optionalAccess', _72 => _72.flatMap, 'call', _73 => _73(
1161
1205
  (pattern) => expandPlaceholderedGlob(
1162
1206
  pattern.path,
1163
1207
  __spec.resolveOverriddenLocale.call(void 0, sourceLocale, pattern.delimiter)
@@ -1229,7 +1273,13 @@ function resolveBucketItem(bucketItem) {
1229
1273
 
1230
1274
  // src/cli/cmd/show/files.ts
1231
1275
 
1232
- var files_default = new (0, _interactivecommander.Command)().command("files").description("Print out the list of files managed by Lingo.dev").option("--source", "Only show source files, files containing the original translations").option("--target", "Only show target files, files containing translated content").helpOption("-h, --help", "Show help").action(async (type) => {
1276
+ var files_default = new (0, _interactivecommander.Command)().command("files").description("Print out the list of files managed by Lingo.dev").option(
1277
+ "--source",
1278
+ "Only show source files, files containing the original translations"
1279
+ ).option(
1280
+ "--target",
1281
+ "Only show target files, files containing translated content"
1282
+ ).helpOption("-h, --help", "Show help").action(async (type) => {
1233
1283
  const ora = _ora2.default.call(void 0, );
1234
1284
  try {
1235
1285
  try {
@@ -1243,12 +1293,26 @@ var files_default = new (0, _interactivecommander.Command)().command("files").de
1243
1293
  const buckets = getBuckets(i18nConfig);
1244
1294
  for (const bucket of buckets) {
1245
1295
  for (const bucketConfig of bucket.paths) {
1246
- const sourceLocale = __spec.resolveOverriddenLocale.call(void 0, i18nConfig.locale.source, bucketConfig.delimiter);
1247
- const sourcePath = bucketConfig.pathPattern.replace(/\[locale\]/g, sourceLocale);
1248
- const targetPaths = i18nConfig.locale.targets.map((_targetLocale) => {
1249
- const targetLocale = __spec.resolveOverriddenLocale.call(void 0, _targetLocale, bucketConfig.delimiter);
1250
- return bucketConfig.pathPattern.replace(/\[locale\]/g, targetLocale);
1251
- });
1296
+ const sourceLocale = __spec.resolveOverriddenLocale.call(void 0,
1297
+ i18nConfig.locale.source,
1298
+ bucketConfig.delimiter
1299
+ );
1300
+ const sourcePath = bucketConfig.pathPattern.replace(
1301
+ /\[locale\]/g,
1302
+ sourceLocale
1303
+ );
1304
+ const targetPaths = i18nConfig.locale.targets.map(
1305
+ (_targetLocale) => {
1306
+ const targetLocale = __spec.resolveOverriddenLocale.call(void 0,
1307
+ _targetLocale,
1308
+ bucketConfig.delimiter
1309
+ );
1310
+ return bucketConfig.pathPattern.replace(
1311
+ /\[locale\]/g,
1312
+ targetLocale
1313
+ );
1314
+ }
1315
+ );
1252
1316
  const result = [];
1253
1317
  if (!type.source && !type.target) {
1254
1318
  result.push(sourcePath, ...targetPaths);
@@ -1328,7 +1392,9 @@ Available keys:
1328
1392
  console.error(
1329
1393
  _dedent2.default`
1330
1394
  ${_chalk2.default.red("\u2716")} Unknown configuration key: ${_chalk2.default.bold(key)}
1331
- Run ${_chalk2.default.dim("lingo.dev config unset --help")} to see available keys.
1395
+ Run ${_chalk2.default.dim(
1396
+ "lingo.dev config unset --help"
1397
+ )} to see available keys.
1332
1398
  `
1333
1399
  );
1334
1400
  process.exitCode = 1;
@@ -1410,12 +1476,12 @@ function composeLoaders(...loaders) {
1410
1476
  return {
1411
1477
  init: async () => {
1412
1478
  for (const loader of loaders) {
1413
- await _optionalChain([loader, 'access', _69 => _69.init, 'optionalCall', _70 => _70()]);
1479
+ await _optionalChain([loader, 'access', _74 => _74.init, 'optionalCall', _75 => _75()]);
1414
1480
  }
1415
1481
  },
1416
1482
  setDefaultLocale(locale) {
1417
1483
  for (const loader of loaders) {
1418
- _optionalChain([loader, 'access', _71 => _71.setDefaultLocale, 'optionalCall', _72 => _72(locale)]);
1484
+ _optionalChain([loader, 'access', _76 => _76.setDefaultLocale, 'optionalCall', _77 => _77(locale)]);
1419
1485
  }
1420
1486
  return this;
1421
1487
  },
@@ -1448,7 +1514,7 @@ function createLoader(lDefinition) {
1448
1514
  if (state.initCtx) {
1449
1515
  return state.initCtx;
1450
1516
  }
1451
- state.initCtx = await _optionalChain([lDefinition, 'access', _73 => _73.init, 'optionalCall', _74 => _74()]);
1517
+ state.initCtx = await _optionalChain([lDefinition, 'access', _78 => _78.init, 'optionalCall', _79 => _79()]);
1452
1518
  return state.initCtx;
1453
1519
  },
1454
1520
  setDefaultLocale(locale) {
@@ -1553,7 +1619,7 @@ function createNormalizeLoader() {
1553
1619
  return normalized;
1554
1620
  },
1555
1621
  push: async (locale, data, originalInput) => {
1556
- const keysMap = _nullishCoalesce(_optionalChain([originalInput, 'optionalAccess', _75 => _75.keysMap]), () => ( {}));
1622
+ const keysMap = _nullishCoalesce(_optionalChain([originalInput, 'optionalAccess', _80 => _80.keysMap]), () => ( {}));
1557
1623
  const input2 = mapDenormalizedKeys(data, keysMap);
1558
1624
  const denormalized = _flat.unflatten.call(void 0, input2, {
1559
1625
  delimiter: "/",
@@ -1627,13 +1693,17 @@ function createTextFileLoader(pathPattern) {
1627
1693
  const trimmedResult = result.trim();
1628
1694
  return trimmedResult;
1629
1695
  },
1630
- async push(locale, data, _33, originalLocale) {
1696
+ async push(locale, data, _34, originalLocale) {
1631
1697
  const draftPath = pathPattern.replaceAll("[locale]", locale);
1632
1698
  const finalPath = path12.default.resolve(draftPath);
1633
1699
  const dirPath = path12.default.dirname(finalPath);
1634
1700
  await _promises4.default.mkdir(dirPath, { recursive: true });
1635
1701
  const trimmedPayload = data.trim();
1636
- const trailingNewLine = await getTrailingNewLine(pathPattern, locale, originalLocale);
1702
+ const trailingNewLine = await getTrailingNewLine(
1703
+ pathPattern,
1704
+ locale,
1705
+ originalLocale
1706
+ );
1637
1707
  let finalPayload = trimmedPayload + trailingNewLine;
1638
1708
  await _promises4.default.writeFile(finalPath, finalPayload, {
1639
1709
  encoding: "utf-8",
@@ -1656,8 +1726,8 @@ async function getTrailingNewLine(pathPattern, locale, originalLocale) {
1656
1726
  if (!templateData) {
1657
1727
  templateData = await readFileForLocale(pathPattern, originalLocale);
1658
1728
  }
1659
- if (_optionalChain([templateData, 'optionalAccess', _76 => _76.match, 'call', _77 => _77(/[\r\n]$/)])) {
1660
- const ending = _optionalChain([templateData, 'optionalAccess', _78 => _78.includes, 'call', _79 => _79("\r\n")]) ? "\r\n" : _optionalChain([templateData, 'optionalAccess', _80 => _80.includes, 'call', _81 => _81("\r")]) ? "\r" : "\n";
1729
+ if (_optionalChain([templateData, 'optionalAccess', _81 => _81.match, 'call', _82 => _82(/[\r\n]$/)])) {
1730
+ const ending = _optionalChain([templateData, 'optionalAccess', _83 => _83.includes, 'call', _84 => _84("\r\n")]) ? "\r\n" : _optionalChain([templateData, 'optionalAccess', _85 => _85.includes, 'call', _86 => _86("\r")]) ? "\r" : "\n";
1661
1731
  return ending;
1662
1732
  }
1663
1733
  return "";
@@ -1727,15 +1797,22 @@ function createRootKeyLoader(replaceAll = false) {
1727
1797
  function createFlutterLoader() {
1728
1798
  return createLoader({
1729
1799
  async pull(locale, input2) {
1730
- const result = _lodash2.default.pickBy(input2, (value, key) => !key.startsWith("@"));
1800
+ const result = _lodash2.default.pickBy(input2, (value, key) => !_isMetadataKey(key));
1731
1801
  return result;
1732
1802
  },
1733
1803
  async push(locale, data, originalInput) {
1734
- const result = _lodash2.default.merge({}, originalInput, { "@@locale": locale }, data);
1804
+ const metadata = _lodash2.default.pickBy(
1805
+ originalInput,
1806
+ (value, key) => _isMetadataKey(key)
1807
+ );
1808
+ const result = _lodash2.default.merge({}, metadata, { "@@locale": locale }, data);
1735
1809
  return result;
1736
1810
  }
1737
1811
  });
1738
1812
  }
1813
+ function _isMetadataKey(key) {
1814
+ return key.startsWith("@");
1815
+ }
1739
1816
 
1740
1817
  // src/cli/loaders/android.ts
1741
1818
  var _xml2js = require('xml2js');
@@ -1921,7 +1998,7 @@ var _sync3 = require('csv-stringify/sync');
1921
1998
 
1922
1999
  function detectKeyColumnName(csvString) {
1923
2000
  const row = _sync.parse.call(void 0, csvString)[0];
1924
- const firstColumn = _optionalChain([row, 'optionalAccess', _82 => _82[0], 'optionalAccess', _83 => _83.trim, 'call', _84 => _84()]);
2001
+ const firstColumn = _optionalChain([row, 'optionalAccess', _87 => _87[0], 'optionalAccess', _88 => _88.trim, 'call', _89 => _89()]);
1925
2002
  return firstColumn || "KEY";
1926
2003
  }
1927
2004
  function createCsvLoader() {
@@ -1930,7 +2007,9 @@ function createCsvLoader() {
1930
2007
  function _createCsvLoader() {
1931
2008
  return createLoader({
1932
2009
  async pull(locale, input2) {
1933
- const keyColumnName = detectKeyColumnName(input2.split("\n").find((l) => l.length));
2010
+ const keyColumnName = detectKeyColumnName(
2011
+ input2.split("\n").find((l) => l.length)
2012
+ );
1934
2013
  const inputParsed = _sync.parse.call(void 0, input2, {
1935
2014
  columns: true,
1936
2015
  skip_empty_lines: true,
@@ -1958,7 +2037,9 @@ function _createCsvLoader() {
1958
2037
  ...row,
1959
2038
  [locale]: items[row[keyColumnName]] || row[locale] || ""
1960
2039
  }));
1961
- const existingKeys = new Set(inputParsed.map((row) => row[keyColumnName]));
2040
+ const existingKeys = new Set(
2041
+ inputParsed.map((row) => row[keyColumnName])
2042
+ );
1962
2043
  Object.entries(items).forEach(([key, value]) => {
1963
2044
  if (!existingKeys.has(key)) {
1964
2045
  const newRow = {
@@ -2019,7 +2100,7 @@ function createHtmlLoader() {
2019
2100
  break;
2020
2101
  }
2021
2102
  const siblings = Array.from(parent.childNodes).filter(
2022
- (n) => n.nodeType === 1 || n.nodeType === 3 && _optionalChain([n, 'access', _85 => _85.textContent, 'optionalAccess', _86 => _86.trim, 'call', _87 => _87()])
2103
+ (n) => n.nodeType === 1 || n.nodeType === 3 && _optionalChain([n, 'access', _90 => _90.textContent, 'optionalAccess', _91 => _91.trim, 'call', _92 => _92()])
2023
2104
  );
2024
2105
  const index = siblings.indexOf(current);
2025
2106
  if (index !== -1) {
@@ -2054,15 +2135,23 @@ function createHtmlLoader() {
2054
2135
  result[getPath(element, attr)] = value;
2055
2136
  }
2056
2137
  });
2057
- Array.from(element.childNodes).filter((n) => n.nodeType === 1 || n.nodeType === 3 && _optionalChain([n, 'access', _88 => _88.textContent, 'optionalAccess', _89 => _89.trim, 'call', _90 => _90()])).forEach(processNode);
2138
+ Array.from(element.childNodes).filter(
2139
+ (n) => n.nodeType === 1 || n.nodeType === 3 && _optionalChain([n, 'access', _93 => _93.textContent, 'optionalAccess', _94 => _94.trim, 'call', _95 => _95()])
2140
+ ).forEach(processNode);
2058
2141
  }
2059
2142
  };
2060
- Array.from(document.head.childNodes).filter((n) => n.nodeType === 1 || n.nodeType === 3 && _optionalChain([n, 'access', _91 => _91.textContent, 'optionalAccess', _92 => _92.trim, 'call', _93 => _93()])).forEach(processNode);
2061
- Array.from(document.body.childNodes).filter((n) => n.nodeType === 1 || n.nodeType === 3 && _optionalChain([n, 'access', _94 => _94.textContent, 'optionalAccess', _95 => _95.trim, 'call', _96 => _96()])).forEach(processNode);
2143
+ Array.from(document.head.childNodes).filter(
2144
+ (n) => n.nodeType === 1 || n.nodeType === 3 && _optionalChain([n, 'access', _96 => _96.textContent, 'optionalAccess', _97 => _97.trim, 'call', _98 => _98()])
2145
+ ).forEach(processNode);
2146
+ Array.from(document.body.childNodes).filter(
2147
+ (n) => n.nodeType === 1 || n.nodeType === 3 && _optionalChain([n, 'access', _99 => _99.textContent, 'optionalAccess', _100 => _100.trim, 'call', _101 => _101()])
2148
+ ).forEach(processNode);
2062
2149
  return result;
2063
2150
  },
2064
2151
  async push(locale, data, originalInput) {
2065
- const dom = new (0, _jsdom.JSDOM)(_nullishCoalesce(originalInput, () => ( "<!DOCTYPE html><html><head></head><body></body></html>")));
2152
+ const dom = new (0, _jsdom.JSDOM)(
2153
+ _nullishCoalesce(originalInput, () => ( "<!DOCTYPE html><html><head></head><body></body></html>"))
2154
+ );
2066
2155
  const document = dom.window.document;
2067
2156
  const htmlElement = document.documentElement;
2068
2157
  htmlElement.setAttribute("lang", locale);
@@ -2080,7 +2169,7 @@ function createHtmlLoader() {
2080
2169
  for (let i = 0; i < indices.length; i++) {
2081
2170
  const index = parseInt(indices[i]);
2082
2171
  const siblings = Array.from(parent.childNodes).filter(
2083
- (n) => n.nodeType === 1 || n.nodeType === 3 && _optionalChain([n, 'access', _97 => _97.textContent, 'optionalAccess', _98 => _98.trim, 'call', _99 => _99()])
2172
+ (n) => n.nodeType === 1 || n.nodeType === 3 && _optionalChain([n, 'access', _102 => _102.textContent, 'optionalAccess', _103 => _103.trim, 'call', _104 => _104()])
2084
2173
  );
2085
2174
  if (index >= siblings.length) {
2086
2175
  if (i === indices.length - 1) {
@@ -2131,19 +2220,26 @@ function createMarkdownLoader() {
2131
2220
  yaml: yamlEngine
2132
2221
  }
2133
2222
  });
2134
- const sections = content.split(SECTION_REGEX).map((section) => _nullishCoalesce(_optionalChain([section, 'optionalAccess', _100 => _100.trim, 'call', _101 => _101()]), () => ( ""))).filter(Boolean);
2223
+ const sections = content.split(SECTION_REGEX).map((section) => _nullishCoalesce(_optionalChain([section, 'optionalAccess', _105 => _105.trim, 'call', _106 => _106()]), () => ( ""))).filter(Boolean);
2135
2224
  return {
2136
2225
  ...Object.fromEntries(
2137
2226
  sections.map((section, index) => [`${MD_SECTION_PREFIX}${index}`, section]).filter(([, section]) => Boolean(section))
2138
2227
  ),
2139
- ...Object.fromEntries(Object.entries(frontmatter).map(([key, value]) => [`${FM_ATTR_PREFIX}${key}`, value]))
2228
+ ...Object.fromEntries(
2229
+ Object.entries(frontmatter).map(([key, value]) => [
2230
+ `${FM_ATTR_PREFIX}${key}`,
2231
+ value
2232
+ ])
2233
+ )
2140
2234
  };
2141
2235
  },
2142
2236
  async push(locale, data) {
2143
2237
  const frontmatter = Object.fromEntries(
2144
2238
  Object.entries(data).filter(([key]) => key.startsWith(FM_ATTR_PREFIX)).map(([key, value]) => [key.replace(FM_ATTR_PREFIX, ""), value])
2145
2239
  );
2146
- let content = Object.entries(data).filter(([key]) => key.startsWith(MD_SECTION_PREFIX)).sort(([a], [b]) => Number(a.split("-").pop()) - Number(b.split("-").pop())).map(([, value]) => _nullishCoalesce(_optionalChain([value, 'optionalAccess', _102 => _102.trim, 'call', _103 => _103()]), () => ( ""))).filter(Boolean).join("\n\n");
2240
+ let content = Object.entries(data).filter(([key]) => key.startsWith(MD_SECTION_PREFIX)).sort(
2241
+ ([a], [b]) => Number(a.split("-").pop()) - Number(b.split("-").pop())
2242
+ ).map(([, value]) => _nullishCoalesce(_optionalChain([value, 'optionalAccess', _107 => _107.trim, 'call', _108 => _108()]), () => ( ""))).filter(Boolean).join("\n\n");
2147
2243
  if (Object.keys(frontmatter).length > 0) {
2148
2244
  content = `
2149
2245
  ${content}`;
@@ -2176,7 +2272,7 @@ function createPropertiesLoader() {
2176
2272
  return result;
2177
2273
  },
2178
2274
  async push(locale, payload) {
2179
- const result = Object.entries(payload).filter(([_33, value]) => value != null).map(([key, value]) => `${key}=${value}`).join("\n");
2275
+ const result = Object.entries(payload).filter(([_34, value]) => value != null).map(([key, value]) => `${key}=${value}`).join("\n");
2180
2276
  return result;
2181
2277
  }
2182
2278
  });
@@ -2187,7 +2283,7 @@ function isSkippableLine(line) {
2187
2283
  function parsePropertyLine(line) {
2188
2284
  const [key, ...valueParts] = line.split("=");
2189
2285
  return {
2190
- key: _optionalChain([key, 'optionalAccess', _104 => _104.trim, 'call', _105 => _105()]) || "",
2286
+ key: _optionalChain([key, 'optionalAccess', _109 => _109.trim, 'call', _110 => _110()]) || "",
2191
2287
  value: valueParts.join("=").trim()
2192
2288
  };
2193
2289
  }
@@ -2268,12 +2364,14 @@ function createXcodeXcstringsLoader(defaultLocale) {
2268
2364
  async pull(locale, input2, initCtx) {
2269
2365
  const resultData = {};
2270
2366
  const isSourceLanguage = locale === defaultLocale;
2271
- for (const [translationKey, _translationEntity] of Object.entries(input2.strings)) {
2367
+ for (const [translationKey, _translationEntity] of Object.entries(
2368
+ input2.strings
2369
+ )) {
2272
2370
  const rootTranslationEntity = _translationEntity;
2273
2371
  if (rootTranslationEntity.shouldTranslate === false) {
2274
2372
  continue;
2275
2373
  }
2276
- const langTranslationEntity = _optionalChain([rootTranslationEntity, 'optionalAccess', _106 => _106.localizations, 'optionalAccess', _107 => _107[locale]]);
2374
+ const langTranslationEntity = _optionalChain([rootTranslationEntity, 'optionalAccess', _111 => _111.localizations, 'optionalAccess', _112 => _112[locale]]);
2277
2375
  if (langTranslationEntity) {
2278
2376
  if ("stringUnit" in langTranslationEntity) {
2279
2377
  resultData[translationKey] = langTranslationEntity.stringUnit.value;
@@ -2282,7 +2380,7 @@ function createXcodeXcstringsLoader(defaultLocale) {
2282
2380
  resultData[translationKey] = {};
2283
2381
  const pluralForms = langTranslationEntity.variations.plural;
2284
2382
  for (const form in pluralForms) {
2285
- if (_optionalChain([pluralForms, 'access', _108 => _108[form], 'optionalAccess', _109 => _109.stringUnit, 'optionalAccess', _110 => _110.value])) {
2383
+ if (_optionalChain([pluralForms, 'access', _113 => _113[form], 'optionalAccess', _114 => _114.stringUnit, 'optionalAccess', _115 => _115.value])) {
2286
2384
  resultData[translationKey][form] = pluralForms[form].stringUnit.value;
2287
2385
  }
2288
2386
  }
@@ -2297,7 +2395,10 @@ function createXcodeXcstringsLoader(defaultLocale) {
2297
2395
  async push(locale, payload, originalInput) {
2298
2396
  const langDataToMerge = {};
2299
2397
  langDataToMerge.strings = {};
2300
- const input2 = _lodash2.default.cloneDeep(originalInput) || { sourceLanguage: locale, strings: {} };
2398
+ const input2 = _lodash2.default.cloneDeep(originalInput) || {
2399
+ sourceLanguage: locale,
2400
+ strings: {}
2401
+ };
2301
2402
  for (const [key, value] of Object.entries(payload)) {
2302
2403
  if (value === null || value === void 0) {
2303
2404
  continue;
@@ -2305,7 +2406,7 @@ function createXcodeXcstringsLoader(defaultLocale) {
2305
2406
  const hasDoNotTranslateFlag = originalInput && originalInput.strings && originalInput.strings[key] && originalInput.strings[key].shouldTranslate === false;
2306
2407
  if (typeof value === "string") {
2307
2408
  langDataToMerge.strings[key] = {
2308
- extractionState: _optionalChain([originalInput, 'optionalAccess', _111 => _111.strings, 'optionalAccess', _112 => _112[key], 'optionalAccess', _113 => _113.extractionState]),
2409
+ extractionState: _optionalChain([originalInput, 'optionalAccess', _116 => _116.strings, 'optionalAccess', _117 => _117[key], 'optionalAccess', _118 => _118.extractionState]),
2309
2410
  localizations: {
2310
2411
  [locale]: {
2311
2412
  stringUnit: {
@@ -2343,11 +2444,22 @@ function createXcodeXcstringsLoader(defaultLocale) {
2343
2444
  }
2344
2445
  }
2345
2446
  }
2346
- const result = _lodash2.default.merge({}, originalInput, langDataToMerge);
2447
+ const originalInputWithoutLocale = originalInput ? _removeLocale(originalInput, locale) : {};
2448
+ const result = _lodash2.default.merge({}, originalInputWithoutLocale, langDataToMerge);
2347
2449
  return result;
2348
2450
  }
2349
2451
  });
2350
2452
  }
2453
+ function _removeLocale(input2, locale) {
2454
+ const { sourceLanguage, strings } = input2;
2455
+ const newStrings = _lodash2.default.cloneDeep(strings);
2456
+ for (const [key, value] of Object.entries(newStrings)) {
2457
+ if (_optionalChain([value, 'access', _119 => _119.localizations, 'optionalAccess', _120 => _120[locale]])) {
2458
+ delete value.localizations[locale];
2459
+ }
2460
+ }
2461
+ return { sourceLanguage, strings: newStrings };
2462
+ }
2351
2463
 
2352
2464
  // src/cli/loaders/prettier.ts
2353
2465
 
@@ -2425,36 +2537,29 @@ async function formatDataWithPrettier(data, filePath, options) {
2425
2537
 
2426
2538
  var _isurl = require('is-url'); var _isurl2 = _interopRequireDefault(_isurl);
2427
2539
  var _datefns = require('date-fns');
2428
- function createUnlocalizableLoader(isCacheRestore = false, returnUnlocalizedKeys = false) {
2429
- const rules = {
2430
- isEmpty: (v) => _lodash2.default.isEmpty(v),
2431
- isNumber: (v) => typeof v === "number" || /^[0-9]+$/.test(v),
2432
- isBoolean: (v) => _lodash2.default.isBoolean(v),
2433
- isIsoDate: (v) => _lodash2.default.isString(v) && _isIsoDate(v),
2434
- isSystemId: (v) => _lodash2.default.isString(v) && _isSystemId(v),
2435
- isUrl: (v) => _lodash2.default.isString(v) && _isurl2.default.call(void 0, v)
2436
- };
2540
+ function createUnlocalizableLoader(returnUnlocalizedKeys = false) {
2437
2541
  return createLoader({
2438
2542
  async pull(locale, input2) {
2439
- const passthroughKeys = Object.entries(input2).filter(([key, value]) => {
2440
- for (const [ruleName, rule] of Object.entries(rules)) {
2441
- if (rule(value)) {
2442
- return true;
2443
- }
2444
- }
2445
- return false;
2446
- }).map(([key, _33]) => key);
2447
- const result = _lodash2.default.omitBy(input2, (_33, key) => passthroughKeys.includes(key));
2543
+ const unlocalizableKeys = _getUnlocalizableKeys(input2);
2544
+ const result = _lodash2.default.omitBy(
2545
+ input2,
2546
+ (_34, key) => unlocalizableKeys.includes(key)
2547
+ );
2448
2548
  if (returnUnlocalizedKeys) {
2449
- result.unlocalizable = _lodash2.default.omitBy(input2, (_33, key) => !passthroughKeys.includes(key));
2549
+ result.unlocalizable = _lodash2.default.omitBy(
2550
+ input2,
2551
+ (_34, key) => !unlocalizableKeys.includes(key)
2552
+ );
2450
2553
  }
2451
2554
  return result;
2452
2555
  },
2453
2556
  async push(locale, data, originalInput) {
2454
- if (isCacheRestore) {
2455
- return _lodash2.default.merge({}, data);
2456
- }
2457
- const result = _lodash2.default.merge({}, originalInput, data);
2557
+ const unlocalizableKeys = _getUnlocalizableKeys(originalInput);
2558
+ const result = _lodash2.default.merge(
2559
+ {},
2560
+ data,
2561
+ _lodash2.default.omitBy(originalInput, (_34, key) => !unlocalizableKeys.includes(key))
2562
+ );
2458
2563
  return result;
2459
2564
  }
2460
2565
  });
@@ -2465,6 +2570,27 @@ function _isSystemId(v) {
2465
2570
  function _isIsoDate(v) {
2466
2571
  return _datefns.isValid.call(void 0, _datefns.parseISO.call(void 0, v));
2467
2572
  }
2573
+ function _getUnlocalizableKeys(input2) {
2574
+ const rules = {
2575
+ isEmpty: (v) => _lodash2.default.isEmpty(v),
2576
+ isNumber: (v) => typeof v === "number" || /^[0-9]+$/.test(v),
2577
+ isBoolean: (v) => _lodash2.default.isBoolean(v),
2578
+ isIsoDate: (v) => _lodash2.default.isString(v) && _isIsoDate(v),
2579
+ isSystemId: (v) => _lodash2.default.isString(v) && _isSystemId(v),
2580
+ isUrl: (v) => _lodash2.default.isString(v) && _isurl2.default.call(void 0, v)
2581
+ };
2582
+ if (!input2) {
2583
+ return [];
2584
+ }
2585
+ return Object.entries(input2).filter(([key, value]) => {
2586
+ for (const [ruleName, rule] of Object.entries(rules)) {
2587
+ if (rule(value)) {
2588
+ return true;
2589
+ }
2590
+ }
2591
+ return false;
2592
+ }).map(([key, _34]) => key);
2593
+ }
2468
2594
 
2469
2595
  // src/cli/loaders/po/index.ts
2470
2596
 
@@ -2488,7 +2614,7 @@ function createPoDataLoader(params) {
2488
2614
  Object.entries(entries).forEach(([msgid, entry]) => {
2489
2615
  if (msgid && entry.msgid) {
2490
2616
  const context = entry.msgctxt || "";
2491
- const fullEntry = _optionalChain([parsedPo, 'access', _114 => _114.translations, 'access', _115 => _115[context], 'optionalAccess', _116 => _116[msgid]]);
2617
+ const fullEntry = _optionalChain([parsedPo, 'access', _121 => _121.translations, 'access', _122 => _122[context], 'optionalAccess', _123 => _123[msgid]]);
2492
2618
  if (fullEntry) {
2493
2619
  result[msgid] = fullEntry;
2494
2620
  }
@@ -2498,8 +2624,8 @@ function createPoDataLoader(params) {
2498
2624
  return result;
2499
2625
  },
2500
2626
  async push(locale, data, originalInput, originalLocale, pullInput) {
2501
- const currentSections = _optionalChain([pullInput, 'optionalAccess', _117 => _117.split, 'call', _118 => _118("\n\n"), 'access', _119 => _119.filter, 'call', _120 => _120(Boolean)]) || [];
2502
- const originalSections = _optionalChain([originalInput, 'optionalAccess', _121 => _121.split, 'call', _122 => _122("\n\n"), 'access', _123 => _123.filter, 'call', _124 => _124(Boolean)]) || [];
2627
+ const currentSections = _optionalChain([pullInput, 'optionalAccess', _124 => _124.split, 'call', _125 => _125("\n\n"), 'access', _126 => _126.filter, 'call', _127 => _127(Boolean)]) || [];
2628
+ const originalSections = _optionalChain([originalInput, 'optionalAccess', _128 => _128.split, 'call', _129 => _129("\n\n"), 'access', _130 => _130.filter, 'call', _131 => _131(Boolean)]) || [];
2503
2629
  const result = originalSections.map((section) => {
2504
2630
  const sectionPo = _gettextparser2.default.po.parse(section);
2505
2631
  if (Object.keys(sectionPo.translations).length === 0) {
@@ -2568,8 +2694,8 @@ function createPoContentLoader() {
2568
2694
  {
2569
2695
  ...entry,
2570
2696
  msgstr: [
2571
- _optionalChain([data, 'access', _125 => _125[entry.msgid], 'optionalAccess', _126 => _126.singular]),
2572
- _optionalChain([data, 'access', _127 => _127[entry.msgid], 'optionalAccess', _128 => _128.plural]) || null
2697
+ _optionalChain([data, 'access', _132 => _132[entry.msgid], 'optionalAccess', _133 => _133.singular]),
2698
+ _optionalChain([data, 'access', _134 => _134[entry.msgid], 'optionalAccess', _135 => _135.plural]) || null
2573
2699
  ].filter(Boolean)
2574
2700
  }
2575
2701
  ]).fromPairs().value();
@@ -2736,16 +2862,24 @@ function createDatoFilterLoader() {
2736
2862
  for (const [modelId, modelInfo] of _lodash2.default.entries(result)) {
2737
2863
  for (const record of modelInfo.records) {
2738
2864
  for (const [fieldId, fieldValue] of _lodash2.default.entries(record)) {
2739
- const fieldInfo = modelInfo.fields.find((field) => field.api_key === fieldId);
2865
+ const fieldInfo = modelInfo.fields.find(
2866
+ (field) => field.api_key === fieldId
2867
+ );
2740
2868
  if (fieldInfo) {
2741
2869
  const sourceFieldValue = _lodash2.default.get(fieldValue, [originalLocale]);
2742
- const targetFieldValue = _lodash2.default.get(data, [modelId, record.id, fieldId]);
2870
+ const targetFieldValue = _lodash2.default.get(data, [
2871
+ modelId,
2872
+ record.id,
2873
+ fieldId
2874
+ ]);
2743
2875
  if (targetFieldValue) {
2744
2876
  _lodash2.default.set(record, [fieldId, locale], targetFieldValue);
2745
2877
  } else {
2746
2878
  _lodash2.default.set(record, [fieldId, locale], sourceFieldValue);
2747
2879
  }
2748
- _lodash2.default.chain(fieldValue).keys().reject((loc) => loc === locale || loc === originalLocale).filter((loc) => _lodash2.default.isEmpty(_lodash2.default.get(fieldValue, [loc]))).forEach((loc) => _lodash2.default.set(record, [fieldId, loc], sourceFieldValue)).value();
2880
+ _lodash2.default.chain(fieldValue).keys().reject((loc) => loc === locale || loc === originalLocale).filter((loc) => _lodash2.default.isEmpty(_lodash2.default.get(fieldValue, [loc]))).forEach(
2881
+ (loc) => _lodash2.default.set(record, [fieldId, loc], sourceFieldValue)
2882
+ ).value();
2749
2883
  }
2750
2884
  }
2751
2885
  }
@@ -2763,7 +2897,9 @@ function createDatoFilterLoader() {
2763
2897
  var _cmaclientnode = require('@datocms/cma-client-node');
2764
2898
  function createDatoClient(params) {
2765
2899
  if (!params.apiKey) {
2766
- throw new Error("Missing required environment variable: DATO_API_TOKEN. Please set this variable and try again.");
2900
+ throw new Error(
2901
+ "Missing required environment variable: DATO_API_TOKEN. Please set this variable and try again."
2902
+ );
2767
2903
  }
2768
2904
  const dato = _cmaclientnode.buildClient.call(void 0, {
2769
2905
  apiToken: params.apiKey,
@@ -2810,11 +2946,16 @@ function createDatoClient(params) {
2810
2946
  findModels: async () => {
2811
2947
  try {
2812
2948
  const models = await dato.itemTypes.list();
2813
- const modelsWithoutBlocks = models.filter((model) => !model.modular_block);
2949
+ const modelsWithoutBlocks = models.filter(
2950
+ (model) => !model.modular_block
2951
+ );
2814
2952
  return modelsWithoutBlocks;
2815
2953
  } catch (_error) {
2816
2954
  throw new Error(
2817
- [`Failed to find models in DatoCMS.`, `Error: ${JSON.stringify(_error, null, 2)}`].join("\n\n")
2955
+ [
2956
+ `Failed to find models in DatoCMS.`,
2957
+ `Error: ${JSON.stringify(_error, null, 2)}`
2958
+ ].join("\n\n")
2818
2959
  );
2819
2960
  }
2820
2961
  },
@@ -2845,7 +2986,9 @@ function createDatoClient(params) {
2845
2986
  only_valid: "true",
2846
2987
  ids: !records.length ? void 0 : records.join(",")
2847
2988
  }
2848
- }).catch((error) => Promise.reject(_optionalChain([error, 'optionalAccess', _129 => _129.response, 'optionalAccess', _130 => _130.body, 'optionalAccess', _131 => _131.data, 'optionalAccess', _132 => _132[0]]) || error));
2989
+ }).catch(
2990
+ (error) => Promise.reject(_optionalChain([error, 'optionalAccess', _136 => _136.response, 'optionalAccess', _137 => _137.body, 'optionalAccess', _138 => _138.data, 'optionalAccess', _139 => _139[0]]) || error)
2991
+ );
2849
2992
  },
2850
2993
  findRecordsForModel: async (modelId, records) => {
2851
2994
  try {
@@ -2855,9 +2998,11 @@ function createDatoClient(params) {
2855
2998
  filter: {
2856
2999
  type: modelId,
2857
3000
  only_valid: "true",
2858
- ids: !_optionalChain([records, 'optionalAccess', _133 => _133.length]) ? void 0 : records.join(",")
3001
+ ids: !_optionalChain([records, 'optionalAccess', _140 => _140.length]) ? void 0 : records.join(",")
2859
3002
  }
2860
- }).catch((error) => Promise.reject(_optionalChain([error, 'optionalAccess', _134 => _134.response, 'optionalAccess', _135 => _135.body, 'optionalAccess', _136 => _136.data, 'optionalAccess', _137 => _137[0]]) || error));
3003
+ }).catch(
3004
+ (error) => Promise.reject(_optionalChain([error, 'optionalAccess', _141 => _141.response, 'optionalAccess', _142 => _142.body, 'optionalAccess', _143 => _143.data, 'optionalAccess', _144 => _144[0]]) || error)
3005
+ );
2861
3006
  return result;
2862
3007
  } catch (_error) {
2863
3008
  throw new Error(
@@ -2871,9 +3016,11 @@ function createDatoClient(params) {
2871
3016
  },
2872
3017
  updateRecord: async (id, payload) => {
2873
3018
  try {
2874
- await dato.items.update(id, payload).catch((error) => Promise.reject(_optionalChain([error, 'optionalAccess', _138 => _138.response, 'optionalAccess', _139 => _139.body, 'optionalAccess', _140 => _140.data, 'optionalAccess', _141 => _141[0]]) || error));
3019
+ await dato.items.update(id, payload).catch(
3020
+ (error) => Promise.reject(_optionalChain([error, 'optionalAccess', _145 => _145.response, 'optionalAccess', _146 => _146.body, 'optionalAccess', _147 => _147.data, 'optionalAccess', _148 => _148[0]]) || error)
3021
+ );
2875
3022
  } catch (_error) {
2876
- if (_optionalChain([_error, 'optionalAccess', _142 => _142.attributes, 'optionalAccess', _143 => _143.details, 'optionalAccess', _144 => _144.message])) {
3023
+ if (_optionalChain([_error, 'optionalAccess', _149 => _149.attributes, 'optionalAccess', _150 => _150.details, 'optionalAccess', _151 => _151.message])) {
2877
3024
  throw new Error(
2878
3025
  [
2879
3026
  `${_error.attributes.details.message}`,
@@ -2894,9 +3041,11 @@ function createDatoClient(params) {
2894
3041
  },
2895
3042
  enableFieldLocalization: async (args) => {
2896
3043
  try {
2897
- await dato.fields.update(`${args.modelId}::${args.fieldId}`, { localized: true }).catch((error) => Promise.reject(_optionalChain([error, 'optionalAccess', _145 => _145.response, 'optionalAccess', _146 => _146.body, 'optionalAccess', _147 => _147.data, 'optionalAccess', _148 => _148[0]]) || error));
3044
+ await dato.fields.update(`${args.modelId}::${args.fieldId}`, { localized: true }).catch(
3045
+ (error) => Promise.reject(_optionalChain([error, 'optionalAccess', _152 => _152.response, 'optionalAccess', _153 => _153.body, 'optionalAccess', _154 => _154.data, 'optionalAccess', _155 => _155[0]]) || error)
3046
+ );
2898
3047
  } catch (_error) {
2899
- if (_optionalChain([_error, 'optionalAccess', _149 => _149.attributes, 'optionalAccess', _150 => _150.code]) === "NOT_FOUND") {
3048
+ if (_optionalChain([_error, 'optionalAccess', _156 => _156.attributes, 'optionalAccess', _157 => _157.code]) === "NOT_FOUND") {
2900
3049
  throw new Error(
2901
3050
  [
2902
3051
  `Field "${args.fieldId}" not found in model "${args.modelId}".`,
@@ -2904,9 +3053,12 @@ function createDatoClient(params) {
2904
3053
  ].join("\n\n")
2905
3054
  );
2906
3055
  }
2907
- if (_optionalChain([_error, 'optionalAccess', _151 => _151.attributes, 'optionalAccess', _152 => _152.details, 'optionalAccess', _153 => _153.message])) {
3056
+ if (_optionalChain([_error, 'optionalAccess', _158 => _158.attributes, 'optionalAccess', _159 => _159.details, 'optionalAccess', _160 => _160.message])) {
2908
3057
  throw new Error(
2909
- [`${_error.attributes.details.message}`, `Error: ${JSON.stringify(_error, null, 2)}`].join("\n\n")
3058
+ [
3059
+ `${_error.attributes.details.message}`,
3060
+ `Error: ${JSON.stringify(_error, null, 2)}`
3061
+ ].join("\n\n")
2910
3062
  );
2911
3063
  }
2912
3064
  throw new Error(
@@ -2958,9 +3110,16 @@ function createDatoApiLoader(config, onConfigUpdate) {
2958
3110
  result.models[modelId] = { fields: [], records: [] };
2959
3111
  const fieldInfos = await getFieldDetails(dato, fields);
2960
3112
  const fieldChoices = createFieldChoices(fieldInfos);
2961
- const selectedFields = await promptFieldSelection(modelName, fieldChoices);
3113
+ const selectedFields = await promptFieldSelection(
3114
+ modelName,
3115
+ fieldChoices
3116
+ );
2962
3117
  for (const fieldInfo of fieldInfos) {
2963
- const isLocalized = await updateFieldLocalization(dato, fieldInfo, selectedFields.includes(fieldInfo.id));
3118
+ const isLocalized = await updateFieldLocalization(
3119
+ dato,
3120
+ fieldInfo,
3121
+ selectedFields.includes(fieldInfo.id)
3122
+ );
2964
3123
  if (isLocalized) {
2965
3124
  result.models[modelId].fields.push(fieldInfo);
2966
3125
  updatedConfig.models[modelId].fields = _lodash2.default.uniq([
@@ -2970,9 +3129,18 @@ function createDatoApiLoader(config, onConfigUpdate) {
2970
3129
  }
2971
3130
  }
2972
3131
  const records = await dato.findRecordsForModel(modelId);
2973
- const recordChoices = createRecordChoices(records, _optionalChain([config, 'access', _154 => _154.models, 'access', _155 => _155[modelId], 'optionalAccess', _156 => _156.records]) || [], project);
2974
- const selectedRecords = await promptRecordSelection(modelName, recordChoices);
2975
- result.models[modelId].records = records.filter((record) => selectedRecords.includes(record.id));
3132
+ const recordChoices = createRecordChoices(
3133
+ records,
3134
+ _optionalChain([config, 'access', _161 => _161.models, 'access', _162 => _162[modelId], 'optionalAccess', _163 => _163.records]) || [],
3135
+ project
3136
+ );
3137
+ const selectedRecords = await promptRecordSelection(
3138
+ modelName,
3139
+ recordChoices
3140
+ );
3141
+ result.models[modelId].records = records.filter(
3142
+ (record) => selectedRecords.includes(record.id)
3143
+ );
2976
3144
  updatedConfig.models[modelId].records = selectedRecords;
2977
3145
  }
2978
3146
  }
@@ -2982,14 +3150,14 @@ function createDatoApiLoader(config, onConfigUpdate) {
2982
3150
  },
2983
3151
  async pull(locale, input2, initCtx) {
2984
3152
  const result = {};
2985
- for (const modelId of _lodash2.default.keys(_optionalChain([initCtx, 'optionalAccess', _157 => _157.models]) || {})) {
2986
- let records = _optionalChain([initCtx, 'optionalAccess', _158 => _158.models, 'access', _159 => _159[modelId], 'access', _160 => _160.records]) || [];
3153
+ for (const modelId of _lodash2.default.keys(_optionalChain([initCtx, 'optionalAccess', _164 => _164.models]) || {})) {
3154
+ let records = _optionalChain([initCtx, 'optionalAccess', _165 => _165.models, 'access', _166 => _166[modelId], 'access', _167 => _167.records]) || [];
2987
3155
  const recordIds = records.map((record) => record.id);
2988
3156
  records = await dato.findRecords(recordIds);
2989
3157
  console.log(`Fetched ${records.length} records for model ${modelId}`);
2990
3158
  if (records.length > 0) {
2991
3159
  result[modelId] = {
2992
- fields: _optionalChain([initCtx, 'optionalAccess', _161 => _161.models, 'optionalAccess', _162 => _162[modelId], 'optionalAccess', _163 => _163.fields]) || [],
3160
+ fields: _optionalChain([initCtx, 'optionalAccess', _168 => _168.models, 'optionalAccess', _169 => _169[modelId], 'optionalAccess', _170 => _170.fields]) || [],
2993
3161
  records
2994
3162
  };
2995
3163
  }
@@ -3000,7 +3168,9 @@ function createDatoApiLoader(config, onConfigUpdate) {
3000
3168
  for (const modelId of _lodash2.default.keys(data)) {
3001
3169
  for (let i = 0; i < data[modelId].records.length; i++) {
3002
3170
  const record = data[modelId].records[i];
3003
- console.log(`Updating record ${i + 1}/${data[modelId].records.length} for model ${modelId}...`);
3171
+ console.log(
3172
+ `Updating record ${i + 1}/${data[modelId].records.length} for model ${modelId}...`
3173
+ );
3004
3174
  await dato.updateRecord(record.id, record);
3005
3175
  }
3006
3176
  }
@@ -3039,7 +3209,9 @@ async function promptFieldSelection(modelName, choices) {
3039
3209
  }
3040
3210
  async function updateFieldLocalization(dato, fieldInfo, shouldBeLocalized) {
3041
3211
  if (shouldBeLocalized !== fieldInfo.localized) {
3042
- console.log(`${shouldBeLocalized ? "Enabling" : "Disabling"} localization for ${fieldInfo.label}...`);
3212
+ console.log(
3213
+ `${shouldBeLocalized ? "Enabling" : "Disabling"} localization for ${fieldInfo.label}...`
3214
+ );
3043
3215
  await dato.updateField(fieldInfo.id, { localized: shouldBeLocalized });
3044
3216
  }
3045
3217
  return shouldBeLocalized;
@@ -3048,7 +3220,7 @@ function createRecordChoices(records, selectedIds = [], project) {
3048
3220
  return records.map((record) => ({
3049
3221
  name: `${record.id} - https://${project.internal_domain}/editor/item_types/${record.item_type.id}/items/${record.id}`,
3050
3222
  value: record.id,
3051
- checked: _optionalChain([selectedIds, 'optionalAccess', _164 => _164.includes, 'call', _165 => _165(record.id)])
3223
+ checked: _optionalChain([selectedIds, 'optionalAccess', _171 => _171.includes, 'call', _172 => _172(record.id)])
3052
3224
  }));
3053
3225
  }
3054
3226
  async function promptRecordSelection(modelName, choices) {
@@ -3112,9 +3284,21 @@ function createDatoExtractLoader() {
3112
3284
  for (const [virtualRecordId, record] of _lodash2.default.entries(modelInfo)) {
3113
3285
  for (const [fieldName, fieldValue] of _lodash2.default.entries(record)) {
3114
3286
  const [, recordId] = virtualRecordId.split("_");
3115
- const originalFieldValue = _lodash2.default.get(originalInput, [modelId, recordId, fieldName]);
3116
- const rawValue = createRawDatoValue(fieldValue, originalFieldValue, true);
3117
- _lodash2.default.set(result, [modelId, recordId, fieldName], rawValue || originalFieldValue);
3287
+ const originalFieldValue = _lodash2.default.get(originalInput, [
3288
+ modelId,
3289
+ recordId,
3290
+ fieldName
3291
+ ]);
3292
+ const rawValue = createRawDatoValue(
3293
+ fieldValue,
3294
+ originalFieldValue,
3295
+ true
3296
+ );
3297
+ _lodash2.default.set(
3298
+ result,
3299
+ [modelId, recordId, fieldName],
3300
+ rawValue || originalFieldValue
3301
+ );
3118
3302
  }
3119
3303
  }
3120
3304
  }
@@ -3184,7 +3368,11 @@ function createRawDatoValue(parsedDatoValue, originalRawDatoValue, isClean = fal
3184
3368
  case "single_block":
3185
3369
  return deserializeBlock(parsedDatoValue, originalRawDatoValue, isClean);
3186
3370
  case "rich_text":
3187
- return deserializeBlockList(parsedDatoValue, originalRawDatoValue, isClean);
3371
+ return deserializeBlockList(
3372
+ parsedDatoValue,
3373
+ originalRawDatoValue,
3374
+ isClean
3375
+ );
3188
3376
  case "json":
3189
3377
  return JSON.stringify(parsedDatoValue, null, 2);
3190
3378
  case "video":
@@ -3201,7 +3389,11 @@ function serializeStructuredText(rawStructuredText) {
3201
3389
  return serializeStructuredTextNode(rawStructuredText);
3202
3390
  function serializeStructuredTextNode(node, path17 = [], acc = {}) {
3203
3391
  if ("document" in node) {
3204
- return serializeStructuredTextNode(node.document, [...path17, "document"], acc);
3392
+ return serializeStructuredTextNode(
3393
+ node.document,
3394
+ [...path17, "document"],
3395
+ acc
3396
+ );
3205
3397
  }
3206
3398
  if (!_lodash2.default.isNil(node.value)) {
3207
3399
  acc[[...path17, "value"].join(".")] = node.value;
@@ -3210,7 +3402,11 @@ function serializeStructuredText(rawStructuredText) {
3210
3402
  }
3211
3403
  if (node.children) {
3212
3404
  for (let i = 0; i < node.children.length; i++) {
3213
- serializeStructuredTextNode(node.children[i], [...path17, i.toString()], acc);
3405
+ serializeStructuredTextNode(
3406
+ node.children[i],
3407
+ [...path17, i.toString()],
3408
+ acc
3409
+ );
3214
3410
  }
3215
3411
  }
3216
3412
  return acc;
@@ -3253,7 +3449,11 @@ function deserializeVideo(parsedVideo, originalRawVideo) {
3253
3449
  function deserializeBlock(payload, rawNode, isClean = false) {
3254
3450
  const result = _lodash2.default.cloneDeep(rawNode);
3255
3451
  for (const [attributeName, attributeValue] of _lodash2.default.entries(rawNode.attributes)) {
3256
- const rawValue = createRawDatoValue(payload[attributeName], attributeValue, isClean);
3452
+ const rawValue = createRawDatoValue(
3453
+ payload[attributeName],
3454
+ attributeValue,
3455
+ isClean
3456
+ );
3257
3457
  _lodash2.default.set(result, ["attributes", attributeName], rawValue);
3258
3458
  }
3259
3459
  if (isClean) {
@@ -3265,13 +3465,19 @@ function deserializeSeo(parsedSeo, originalRawSeo) {
3265
3465
  return _lodash2.default.chain(parsedSeo).pick(["title", "description"]).defaults(originalRawSeo).value();
3266
3466
  }
3267
3467
  function deserializeBlockList(parsedBlockList, originalRawBlockList, isClean = false) {
3268
- return _lodash2.default.chain(parsedBlockList).map((block, i) => deserializeBlock(block, originalRawBlockList[i], isClean)).value();
3468
+ return _lodash2.default.chain(parsedBlockList).map(
3469
+ (block, i) => deserializeBlock(block, originalRawBlockList[i], isClean)
3470
+ ).value();
3269
3471
  }
3270
3472
  function deserializeStructuredText(parsedStructuredText, originalRawStructuredText) {
3271
3473
  const result = _lodash2.default.cloneDeep(originalRawStructuredText);
3272
3474
  for (const [path17, value] of _lodash2.default.entries(parsedStructuredText)) {
3273
3475
  const realPath = _lodash2.default.chain(path17.split(".")).flatMap((s) => !_lodash2.default.isNaN(_lodash2.default.toNumber(s)) ? ["children", s] : s).value();
3274
- const deserializedValue = createRawDatoValue(value, _lodash2.default.get(originalRawStructuredText, realPath), true);
3476
+ const deserializedValue = createRawDatoValue(
3477
+ value,
3478
+ _lodash2.default.get(originalRawStructuredText, realPath),
3479
+ true
3480
+ );
3275
3481
  _lodash2.default.set(result, realPath, deserializedValue);
3276
3482
  }
3277
3483
  return result;
@@ -3284,13 +3490,21 @@ function _isJson(rawDatoValue) {
3284
3490
  }
3285
3491
  }
3286
3492
  function _isFile(rawDatoValue) {
3287
- return _lodash2.default.isObject(rawDatoValue) && ["alt", "title", "custom_data", "focal_point", "upload_id"].every((key) => _lodash2.default.has(rawDatoValue, key));
3288
- }
3289
- function _isVideo(rawDatoValue) {
3290
- return _lodash2.default.isObject(rawDatoValue) && ["url", "title", "width", "height", "provider", "provider_uid", "thumbnail_url"].every(
3493
+ return _lodash2.default.isObject(rawDatoValue) && ["alt", "title", "custom_data", "focal_point", "upload_id"].every(
3291
3494
  (key) => _lodash2.default.has(rawDatoValue, key)
3292
3495
  );
3293
3496
  }
3497
+ function _isVideo(rawDatoValue) {
3498
+ return _lodash2.default.isObject(rawDatoValue) && [
3499
+ "url",
3500
+ "title",
3501
+ "width",
3502
+ "height",
3503
+ "provider",
3504
+ "provider_uid",
3505
+ "thumbnail_url"
3506
+ ].every((key) => _lodash2.default.has(rawDatoValue, key));
3507
+ }
3294
3508
 
3295
3509
  // src/cli/loaders/dato/index.ts
3296
3510
  function createDatoLoader(configFilePath) {
@@ -3300,13 +3514,20 @@ function createDatoLoader(configFilePath) {
3300
3514
  return composeLoaders(
3301
3515
  createDatoApiLoader(
3302
3516
  datoConfig,
3303
- (updatedConfig) => fs10.default.writeFileSync(configFilePath, _json52.default.stringify(updatedConfig, null, 2))
3517
+ (updatedConfig) => fs10.default.writeFileSync(
3518
+ configFilePath,
3519
+ _json52.default.stringify(updatedConfig, null, 2)
3520
+ )
3304
3521
  ),
3305
3522
  createDatoFilterLoader(),
3306
3523
  createDatoExtractLoader()
3307
3524
  );
3308
3525
  } catch (error) {
3309
- throw new Error([`Failed to parse DatoCMS config file.`, `Error: ${error.message}`].join("\n\n"));
3526
+ throw new Error(
3527
+ [`Failed to parse DatoCMS config file.`, `Error: ${error.message}`].join(
3528
+ "\n\n"
3529
+ )
3530
+ );
3310
3531
  }
3311
3532
  }
3312
3533
 
@@ -3318,7 +3539,7 @@ function createVttLoader() {
3318
3539
  if (!input2) {
3319
3540
  return "";
3320
3541
  }
3321
- const vtt = _optionalChain([_nodewebvtt2.default, 'access', _166 => _166.parse, 'call', _167 => _167(input2), 'optionalAccess', _168 => _168.cues]);
3542
+ const vtt = _optionalChain([_nodewebvtt2.default, 'access', _173 => _173.parse, 'call', _174 => _174(input2), 'optionalAccess', _175 => _175.cues]);
3322
3543
  if (Object.keys(vtt).length === 0) {
3323
3544
  return {};
3324
3545
  } else {
@@ -3372,7 +3593,7 @@ function variableExtractLoader(params) {
3372
3593
  for (let i = 0; i < matches.length; i++) {
3373
3594
  const match2 = matches[i];
3374
3595
  const currentValue = result[key].value;
3375
- const newValue = _optionalChain([currentValue, 'optionalAccess', _169 => _169.replace, 'call', _170 => _170(match2, `{variable:${i}}`)]);
3596
+ const newValue = _optionalChain([currentValue, 'optionalAccess', _176 => _176.replace, 'call', _177 => _177(match2, `{variable:${i}}`)]);
3376
3597
  result[key].value = newValue;
3377
3598
  result[key].variables[i] = match2;
3378
3599
  }
@@ -3386,7 +3607,7 @@ function variableExtractLoader(params) {
3386
3607
  for (let i = 0; i < valueObj.variables.length; i++) {
3387
3608
  const variable = valueObj.variables[i];
3388
3609
  const currentValue = result[key];
3389
- const newValue = _optionalChain([currentValue, 'optionalAccess', _171 => _171.replace, 'call', _172 => _172(`{variable:${i}}`, variable)]);
3610
+ const newValue = _optionalChain([currentValue, 'optionalAccess', _178 => _178.replace, 'call', _179 => _179(`{variable:${i}}`, variable)]);
3390
3611
  result[key] = newValue;
3391
3612
  }
3392
3613
  }
@@ -3455,7 +3676,9 @@ function formatPlutilStyle(jsonData, existingJson) {
3455
3676
  }
3456
3677
  if (Array.isArray(data)) {
3457
3678
  if (data.length === 0) return "[]";
3458
- const items2 = data.map((item) => `${nextIndent}${format(item, level + 1)}`);
3679
+ const items2 = data.map(
3680
+ (item) => `${nextIndent}${format(item, level + 1)}`
3681
+ );
3459
3682
  return `[
3460
3683
  ${items2.join(",\n")}
3461
3684
  ${currentIndent}]`;
@@ -3475,7 +3698,10 @@ ${currentIndent}}`;
3475
3698
  });
3476
3699
  const items = sortedKeys.map((key) => {
3477
3700
  const value = data[key];
3478
- return `${nextIndent}${JSON.stringify(key)} : ${format(value, level + 1)}`;
3701
+ return `${nextIndent}${JSON.stringify(key)} : ${format(
3702
+ value,
3703
+ level + 1
3704
+ )}`;
3479
3705
  });
3480
3706
  return `{
3481
3707
  ${items.join(",\n")}
@@ -3548,11 +3774,23 @@ function toPhpArray(data, shortSyntax = true, indentLevel = 1) {
3548
3774
  const arrayEnd = shortSyntax ? "]" : ")";
3549
3775
  if (Array.isArray(data)) {
3550
3776
  return `${arrayStart}
3551
- ${data.map((value) => `${indent(indentLevel)}${toPhpArray(value, shortSyntax, indentLevel + 1)}`).join(",\n")}
3777
+ ${data.map(
3778
+ (value) => `${indent(indentLevel)}${toPhpArray(
3779
+ value,
3780
+ shortSyntax,
3781
+ indentLevel + 1
3782
+ )}`
3783
+ ).join(",\n")}
3552
3784
  ${indent(indentLevel - 1)}${arrayEnd}`;
3553
3785
  }
3554
3786
  const output = `${arrayStart}
3555
- ${Object.entries(data).map(([key, value]) => `${indent(indentLevel)}'${key}' => ${toPhpArray(value, shortSyntax, indentLevel + 1)}`).join(",\n")}
3787
+ ${Object.entries(data).map(
3788
+ ([key, value]) => `${indent(indentLevel)}'${key}' => ${toPhpArray(
3789
+ value,
3790
+ shortSyntax,
3791
+ indentLevel + 1
3792
+ )}`
3793
+ ).join(",\n")}
3556
3794
  ${indent(indentLevel - 1)}${arrayEnd}`;
3557
3795
  return output;
3558
3796
  }
@@ -3569,7 +3807,7 @@ function createVueJsonLoader() {
3569
3807
  return createLoader({
3570
3808
  pull: async (locale, input2, ctx) => {
3571
3809
  const parsed = parseVueFile(input2);
3572
- return _nullishCoalesce(_optionalChain([parsed, 'optionalAccess', _173 => _173.i18n, 'optionalAccess', _174 => _174[locale]]), () => ( {}));
3810
+ return _nullishCoalesce(_optionalChain([parsed, 'optionalAccess', _180 => _180.i18n, 'optionalAccess', _181 => _181[locale]]), () => ( {}));
3573
3811
  },
3574
3812
  push: async (locale, data, originalInput) => {
3575
3813
  const parsed = parseVueFile(_nullishCoalesce(originalInput, () => ( "")));
@@ -3578,7 +3816,11 @@ function createVueJsonLoader() {
3578
3816
  }
3579
3817
  parsed.i18n[locale] = data;
3580
3818
  return `${parsed.before}<i18n>
3581
- ${JSON.stringify(parsed.i18n, null, 2)}
3819
+ ${JSON.stringify(
3820
+ parsed.i18n,
3821
+ null,
3822
+ 2
3823
+ )}
3582
3824
  </i18n>${parsed.after}`;
3583
3825
  }
3584
3826
  });
@@ -3750,7 +3992,7 @@ function updateStringsInObjectExpression(objectExpression, data) {
3750
3992
  objectExpression.properties.forEach((prop) => {
3751
3993
  if (!t.isObjectProperty(prop)) return;
3752
3994
  const key = getPropertyKey(prop);
3753
- const incomingVal = _optionalChain([data, 'optionalAccess', _175 => _175[key]]);
3995
+ const incomingVal = _optionalChain([data, 'optionalAccess', _182 => _182[key]]);
3754
3996
  if (incomingVal === void 0) {
3755
3997
  return;
3756
3998
  }
@@ -3786,7 +4028,7 @@ function updateStringsInArrayExpression(arrayExpression, incoming) {
3786
4028
  let modified = false;
3787
4029
  arrayExpression.elements.forEach((element, index) => {
3788
4030
  if (!element) return;
3789
- const incomingVal = _optionalChain([incoming, 'optionalAccess', _176 => _176[index]]);
4031
+ const incomingVal = _optionalChain([incoming, 'optionalAccess', _183 => _183[index]]);
3790
4032
  if (incomingVal === void 0) return;
3791
4033
  if (t.isStringLiteral(element) && typeof incomingVal === "string") {
3792
4034
  if (element.value !== incomingVal) {
@@ -3844,42 +4086,48 @@ function createInjectLocaleLoader(injectLocaleKeys) {
3844
4086
  if (!injectLocaleKeys) {
3845
4087
  return data;
3846
4088
  }
3847
- const omitKeys = injectLocaleKeys.filter((key) => {
3848
- return _lodash2.default.get(data, key) === locale;
3849
- });
4089
+ const omitKeys = _getKeysWithLocales(data, injectLocaleKeys, locale);
3850
4090
  const result = _lodash2.default.omit(data, omitKeys);
3851
4091
  return result;
3852
4092
  },
3853
4093
  async push(locale, data, originalInput, originalLocale) {
3854
- if (!injectLocaleKeys) {
4094
+ if (!injectLocaleKeys || !originalInput) {
3855
4095
  return data;
3856
4096
  }
3857
- const mergedData = _lodash2.default.merge({}, originalInput, data);
3858
- injectLocaleKeys.forEach((key) => {
3859
- if (_lodash2.default.get(mergedData, key) === originalLocale) {
3860
- _lodash2.default.set(mergedData, key, locale);
3861
- }
4097
+ const localeKeys = _getKeysWithLocales(
4098
+ originalInput,
4099
+ injectLocaleKeys,
4100
+ originalLocale
4101
+ );
4102
+ localeKeys.forEach((key) => {
4103
+ _lodash2.default.set(data, key, locale);
3862
4104
  });
3863
- return mergedData;
4105
+ return data;
3864
4106
  }
3865
4107
  });
3866
4108
  }
4109
+ function _getKeysWithLocales(data, injectLocaleKeys, locale) {
4110
+ return injectLocaleKeys.filter((key) => {
4111
+ return _lodash2.default.get(data, key) === locale;
4112
+ });
4113
+ }
3867
4114
 
3868
4115
  // src/cli/loaders/locked-keys.ts
3869
4116
 
3870
- function createLockedKeysLoader(lockedKeys, isCacheRestore = false) {
4117
+ function createLockedKeysLoader(lockedKeys) {
3871
4118
  return createLoader({
3872
- pull: async (locale, data) => _lodash2.default.chain(data).pickBy((value, key) => !lockedKeys.some((lockedKey) => key.startsWith(lockedKey))).value(),
4119
+ pull: async (locale, data) => {
4120
+ return _lodash2.default.pickBy(data, (value, key) => !_isLockedKey(key, lockedKeys));
4121
+ },
3873
4122
  push: async (locale, data, originalInput) => {
3874
- const lockedSubObject = _lodash2.default.chain(originalInput).pickBy((value, key) => lockedKeys.some((lockedKey) => key.startsWith(lockedKey))).value();
3875
- if (isCacheRestore) {
3876
- return _lodash2.default.merge({}, data, lockedSubObject);
3877
- } else {
3878
- return _lodash2.default.merge({}, originalInput, data, lockedSubObject);
3879
- }
4123
+ const lockedSubObject = _lodash2.default.chain(originalInput).pickBy((value, key) => _isLockedKey(key, lockedKeys)).value();
4124
+ return _lodash2.default.merge({}, data, lockedSubObject);
3880
4125
  }
3881
4126
  });
3882
4127
  }
4128
+ function _isLockedKey(key, lockedKeys) {
4129
+ return lockedKeys.some((lockedKey) => key.startsWith(lockedKey));
4130
+ }
3883
4131
 
3884
4132
  // src/cli/loaders/mdx2/frontmatter-split.ts
3885
4133
 
@@ -4062,7 +4310,7 @@ function createMdxSectionsSplit2Loader() {
4062
4310
  const content = _lodash2.default.chain(data.sections).values().join("\n\n").value();
4063
4311
  const result = {
4064
4312
  frontmatter: data.frontmatter,
4065
- codePlaceholders: _optionalChain([pullInput, 'optionalAccess', _177 => _177.codePlaceholders]) || {},
4313
+ codePlaceholders: _optionalChain([pullInput, 'optionalAccess', _184 => _184.codePlaceholders]) || {},
4066
4314
  content
4067
4315
  };
4068
4316
  return result;
@@ -4109,9 +4357,14 @@ function createMdxLockedPatternsLoader(defaultPatterns) {
4109
4357
  if (!pullInput) {
4110
4358
  return data;
4111
4359
  }
4112
- const { lockedPlaceholders } = extractLockedPatterns(pullInput, patterns);
4360
+ const { lockedPlaceholders } = extractLockedPatterns(
4361
+ pullInput,
4362
+ patterns
4363
+ );
4113
4364
  let result = data;
4114
- for (const [placeholder, original] of Object.entries(lockedPlaceholders)) {
4365
+ for (const [placeholder, original] of Object.entries(
4366
+ lockedPlaceholders
4367
+ )) {
4115
4368
  result = result.replaceAll(placeholder, original);
4116
4369
  }
4117
4370
  return result;
@@ -4205,7 +4458,10 @@ function parseEjsForTranslation(input2) {
4205
4458
  if (trimmedContent) {
4206
4459
  const key = `text_${counter++}`;
4207
4460
  translatable[key] = trimmedContent;
4208
- template += textPart.content.replace(trimmedContent, `__LINGO_PLACEHOLDER_${key}__`);
4461
+ template += textPart.content.replace(
4462
+ trimmedContent,
4463
+ `__LINGO_PLACEHOLDER_${key}__`
4464
+ );
4209
4465
  } else {
4210
4466
  template += textPart.content;
4211
4467
  }
@@ -4235,7 +4491,9 @@ function createEjsLoader() {
4235
4491
  const parseResult = parseEjsForTranslation(input2);
4236
4492
  return parseResult.translatable;
4237
4493
  } catch (error) {
4238
- console.warn("Warning: Could not parse EJS template, treating as plain text");
4494
+ console.warn(
4495
+ "Warning: Could not parse EJS template, treating as plain text"
4496
+ );
4239
4497
  return { content: input2.trim() };
4240
4498
  }
4241
4499
  },
@@ -4246,15 +4504,53 @@ function createEjsLoader() {
4246
4504
  try {
4247
4505
  const parseResult = parseEjsForTranslation(originalInput);
4248
4506
  const mergedTranslatable = { ...parseResult.translatable, ...data };
4249
- return reconstructEjsWithTranslation(parseResult.content, mergedTranslatable);
4507
+ return reconstructEjsWithTranslation(
4508
+ parseResult.content,
4509
+ mergedTranslatable
4510
+ );
4250
4511
  } catch (error) {
4251
- console.warn("Warning: Could not reconstruct EJS template, returning translated data");
4512
+ console.warn(
4513
+ "Warning: Could not reconstruct EJS template, returning translated data"
4514
+ );
4252
4515
  return Object.values(data).join("\n");
4253
4516
  }
4254
4517
  }
4255
4518
  });
4256
4519
  }
4257
4520
 
4521
+ // src/cli/loaders/ensure-key-order.ts
4522
+
4523
+ function createEnsureKeyOrderLoader() {
4524
+ return createLoader({
4525
+ pull: async (_locale, input2) => {
4526
+ return input2;
4527
+ },
4528
+ push: async (_locale, data, originalInput) => {
4529
+ if (!originalInput || !data) {
4530
+ return data;
4531
+ }
4532
+ return reorderKeys(data, originalInput);
4533
+ }
4534
+ });
4535
+ }
4536
+ function reorderKeys(data, originalInput) {
4537
+ if (!_lodash2.default.isObject(data) || _lodash2.default.isArray(data) || _lodash2.default.isDate(data)) {
4538
+ return data;
4539
+ }
4540
+ const orderedData = {};
4541
+ const originalKeys = Object.keys(originalInput);
4542
+ const dataKeys = new Set(Object.keys(data));
4543
+ for (const key of originalKeys) {
4544
+ if (dataKeys.has(key)) {
4545
+ if (data[key]) {
4546
+ orderedData[key] = reorderKeys(data[key], originalInput[key]);
4547
+ }
4548
+ dataKeys.delete(key);
4549
+ }
4550
+ }
4551
+ return orderedData;
4552
+ }
4553
+
4258
4554
  // src/cli/loaders/index.ts
4259
4555
  function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys, lockedPatterns, ignoredKeys) {
4260
4556
  switch (bucketType) {
@@ -4264,23 +4560,19 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys,
4264
4560
  return composeLoaders(
4265
4561
  createTextFileLoader(bucketPathPattern),
4266
4562
  createAndroidLoader(),
4563
+ createEnsureKeyOrderLoader(),
4267
4564
  createFlatLoader(),
4268
4565
  createSyncLoader(),
4269
- createUnlocalizableLoader(
4270
- options.isCacheRestore,
4271
- options.returnUnlocalizedKeys
4272
- )
4566
+ createUnlocalizableLoader(options.returnUnlocalizedKeys)
4273
4567
  );
4274
4568
  case "csv":
4275
4569
  return composeLoaders(
4276
4570
  createTextFileLoader(bucketPathPattern),
4277
4571
  createCsvLoader(),
4572
+ createEnsureKeyOrderLoader(),
4278
4573
  createFlatLoader(),
4279
4574
  createSyncLoader(),
4280
- createUnlocalizableLoader(
4281
- options.isCacheRestore,
4282
- options.returnUnlocalizedKeys
4283
- )
4575
+ createUnlocalizableLoader(options.returnUnlocalizedKeys)
4284
4576
  );
4285
4577
  case "html":
4286
4578
  return composeLoaders(
@@ -4288,34 +4580,26 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys,
4288
4580
  createPrettierLoader({ parser: "html", bucketPathPattern }),
4289
4581
  createHtmlLoader(),
4290
4582
  createSyncLoader(),
4291
- createUnlocalizableLoader(
4292
- options.isCacheRestore,
4293
- options.returnUnlocalizedKeys
4294
- )
4583
+ createUnlocalizableLoader(options.returnUnlocalizedKeys)
4295
4584
  );
4296
4585
  case "ejs":
4297
4586
  return composeLoaders(
4298
4587
  createTextFileLoader(bucketPathPattern),
4299
4588
  createEjsLoader(),
4300
4589
  createSyncLoader(),
4301
- createUnlocalizableLoader(
4302
- options.isCacheRestore,
4303
- options.returnUnlocalizedKeys
4304
- )
4590
+ createUnlocalizableLoader(options.returnUnlocalizedKeys)
4305
4591
  );
4306
4592
  case "json":
4307
4593
  return composeLoaders(
4308
4594
  createTextFileLoader(bucketPathPattern),
4309
4595
  createPrettierLoader({ parser: "json", bucketPathPattern }),
4310
4596
  createJsonLoader(),
4597
+ createEnsureKeyOrderLoader(),
4311
4598
  createInjectLocaleLoader(options.injectLocale),
4312
4599
  createFlatLoader(),
4313
- createLockedKeysLoader(lockedKeys || [], options.isCacheRestore),
4600
+ createLockedKeysLoader(lockedKeys || []),
4314
4601
  createSyncLoader(),
4315
- createUnlocalizableLoader(
4316
- options.isCacheRestore,
4317
- options.returnUnlocalizedKeys
4318
- )
4602
+ createUnlocalizableLoader(options.returnUnlocalizedKeys)
4319
4603
  );
4320
4604
  case "markdown":
4321
4605
  return composeLoaders(
@@ -4323,10 +4607,7 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys,
4323
4607
  createPrettierLoader({ parser: "markdown", bucketPathPattern }),
4324
4608
  createMarkdownLoader(),
4325
4609
  createSyncLoader(),
4326
- createUnlocalizableLoader(
4327
- options.isCacheRestore,
4328
- options.returnUnlocalizedKeys
4329
- )
4610
+ createUnlocalizableLoader(options.returnUnlocalizedKeys)
4330
4611
  );
4331
4612
  case "mdx":
4332
4613
  return composeLoaders(
@@ -4341,55 +4622,43 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys,
4341
4622
  createMdxSectionsSplit2Loader(),
4342
4623
  createLocalizableMdxDocumentLoader(),
4343
4624
  createFlatLoader(),
4344
- createLockedKeysLoader(lockedKeys || [], options.isCacheRestore),
4625
+ createEnsureKeyOrderLoader(),
4626
+ createLockedKeysLoader(lockedKeys || []),
4345
4627
  createSyncLoader(),
4346
- createUnlocalizableLoader(
4347
- options.isCacheRestore,
4348
- options.returnUnlocalizedKeys
4349
- )
4628
+ createUnlocalizableLoader(options.returnUnlocalizedKeys)
4350
4629
  );
4351
4630
  case "po":
4352
4631
  return composeLoaders(
4353
4632
  createTextFileLoader(bucketPathPattern),
4354
4633
  createPoLoader(),
4355
4634
  createFlatLoader(),
4635
+ createEnsureKeyOrderLoader(),
4356
4636
  createSyncLoader(),
4357
4637
  createVariableLoader({ type: "python" }),
4358
- createUnlocalizableLoader(
4359
- options.isCacheRestore,
4360
- options.returnUnlocalizedKeys
4361
- )
4638
+ createUnlocalizableLoader(options.returnUnlocalizedKeys)
4362
4639
  );
4363
4640
  case "properties":
4364
4641
  return composeLoaders(
4365
4642
  createTextFileLoader(bucketPathPattern),
4366
4643
  createPropertiesLoader(),
4367
4644
  createSyncLoader(),
4368
- createUnlocalizableLoader(
4369
- options.isCacheRestore,
4370
- options.returnUnlocalizedKeys
4371
- )
4645
+ createUnlocalizableLoader(options.returnUnlocalizedKeys)
4372
4646
  );
4373
4647
  case "xcode-strings":
4374
4648
  return composeLoaders(
4375
4649
  createTextFileLoader(bucketPathPattern),
4376
4650
  createXcodeStringsLoader(),
4377
4651
  createSyncLoader(),
4378
- createUnlocalizableLoader(
4379
- options.isCacheRestore,
4380
- options.returnUnlocalizedKeys
4381
- )
4652
+ createUnlocalizableLoader(options.returnUnlocalizedKeys)
4382
4653
  );
4383
4654
  case "xcode-stringsdict":
4384
4655
  return composeLoaders(
4385
4656
  createTextFileLoader(bucketPathPattern),
4386
4657
  createXcodeStringsdictLoader(),
4387
4658
  createFlatLoader(),
4659
+ createEnsureKeyOrderLoader(),
4388
4660
  createSyncLoader(),
4389
- createUnlocalizableLoader(
4390
- options.isCacheRestore,
4391
- options.returnUnlocalizedKeys
4392
- )
4661
+ createUnlocalizableLoader(options.returnUnlocalizedKeys)
4393
4662
  );
4394
4663
  case "xcode-xcstrings":
4395
4664
  return composeLoaders(
@@ -4398,12 +4667,10 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys,
4398
4667
  createJsonLoader(),
4399
4668
  createXcodeXcstringsLoader(options.defaultLocale),
4400
4669
  createFlatLoader(),
4670
+ createEnsureKeyOrderLoader(),
4401
4671
  createSyncLoader(),
4402
4672
  createVariableLoader({ type: "ieee" }),
4403
- createUnlocalizableLoader(
4404
- options.isCacheRestore,
4405
- options.returnUnlocalizedKeys
4406
- )
4673
+ createUnlocalizableLoader(options.returnUnlocalizedKeys)
4407
4674
  );
4408
4675
  case "yaml":
4409
4676
  return composeLoaders(
@@ -4411,12 +4678,10 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys,
4411
4678
  createPrettierLoader({ parser: "yaml", bucketPathPattern }),
4412
4679
  createYamlLoader(),
4413
4680
  createFlatLoader(),
4414
- createLockedKeysLoader(lockedKeys || [], options.isCacheRestore),
4681
+ createEnsureKeyOrderLoader(),
4682
+ createLockedKeysLoader(lockedKeys || []),
4415
4683
  createSyncLoader(),
4416
- createUnlocalizableLoader(
4417
- options.isCacheRestore,
4418
- options.returnUnlocalizedKeys
4419
- )
4684
+ createUnlocalizableLoader(options.returnUnlocalizedKeys)
4420
4685
  );
4421
4686
  case "yaml-root-key":
4422
4687
  return composeLoaders(
@@ -4425,76 +4690,60 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys,
4425
4690
  createYamlLoader(),
4426
4691
  createRootKeyLoader(true),
4427
4692
  createFlatLoader(),
4693
+ createEnsureKeyOrderLoader(),
4428
4694
  createSyncLoader(),
4429
- createUnlocalizableLoader(
4430
- options.isCacheRestore,
4431
- options.returnUnlocalizedKeys
4432
- )
4695
+ createUnlocalizableLoader(options.returnUnlocalizedKeys)
4433
4696
  );
4434
4697
  case "flutter":
4435
4698
  return composeLoaders(
4436
4699
  createTextFileLoader(bucketPathPattern),
4437
4700
  createPrettierLoader({ parser: "json", bucketPathPattern }),
4438
4701
  createJsonLoader(),
4702
+ createEnsureKeyOrderLoader(),
4439
4703
  createFlutterLoader(),
4440
4704
  createFlatLoader(),
4441
4705
  createSyncLoader(),
4442
- createUnlocalizableLoader(
4443
- options.isCacheRestore,
4444
- options.returnUnlocalizedKeys
4445
- )
4706
+ createUnlocalizableLoader(options.returnUnlocalizedKeys)
4446
4707
  );
4447
4708
  case "xliff":
4448
4709
  return composeLoaders(
4449
4710
  createTextFileLoader(bucketPathPattern),
4450
4711
  createXliffLoader(),
4451
4712
  createFlatLoader(),
4713
+ createEnsureKeyOrderLoader(),
4452
4714
  createSyncLoader(),
4453
- createUnlocalizableLoader(
4454
- options.isCacheRestore,
4455
- options.returnUnlocalizedKeys
4456
- )
4715
+ createUnlocalizableLoader(options.returnUnlocalizedKeys)
4457
4716
  );
4458
4717
  case "xml":
4459
4718
  return composeLoaders(
4460
4719
  createTextFileLoader(bucketPathPattern),
4461
4720
  createXmlLoader(),
4462
4721
  createFlatLoader(),
4722
+ createEnsureKeyOrderLoader(),
4463
4723
  createSyncLoader(),
4464
- createUnlocalizableLoader(
4465
- options.isCacheRestore,
4466
- options.returnUnlocalizedKeys
4467
- )
4724
+ createUnlocalizableLoader(options.returnUnlocalizedKeys)
4468
4725
  );
4469
4726
  case "srt":
4470
4727
  return composeLoaders(
4471
4728
  createTextFileLoader(bucketPathPattern),
4472
4729
  createSrtLoader(),
4473
4730
  createSyncLoader(),
4474
- createUnlocalizableLoader(
4475
- options.isCacheRestore,
4476
- options.returnUnlocalizedKeys
4477
- )
4731
+ createUnlocalizableLoader(options.returnUnlocalizedKeys)
4478
4732
  );
4479
4733
  case "dato":
4480
4734
  return composeLoaders(
4481
4735
  createDatoLoader(bucketPathPattern),
4482
4736
  createSyncLoader(),
4483
4737
  createFlatLoader(),
4484
- createUnlocalizableLoader(
4485
- options.isCacheRestore,
4486
- options.returnUnlocalizedKeys
4487
- )
4738
+ createEnsureKeyOrderLoader(),
4739
+ createUnlocalizableLoader(options.returnUnlocalizedKeys)
4488
4740
  );
4489
4741
  case "vtt":
4490
4742
  return composeLoaders(
4491
4743
  createTextFileLoader(bucketPathPattern),
4492
4744
  createVttLoader(),
4493
4745
  createSyncLoader(),
4494
- createUnlocalizableLoader(
4495
- options.isCacheRestore,
4496
- options.returnUnlocalizedKeys
4497
- )
4746
+ createUnlocalizableLoader(options.returnUnlocalizedKeys)
4498
4747
  );
4499
4748
  case "php":
4500
4749
  return composeLoaders(
@@ -4502,10 +4751,8 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys,
4502
4751
  createPhpLoader(),
4503
4752
  createSyncLoader(),
4504
4753
  createFlatLoader(),
4505
- createUnlocalizableLoader(
4506
- options.isCacheRestore,
4507
- options.returnUnlocalizedKeys
4508
- )
4754
+ createEnsureKeyOrderLoader(),
4755
+ createUnlocalizableLoader(options.returnUnlocalizedKeys)
4509
4756
  );
4510
4757
  case "vue-json":
4511
4758
  return composeLoaders(
@@ -4513,10 +4760,8 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys,
4513
4760
  createVueJsonLoader(),
4514
4761
  createSyncLoader(),
4515
4762
  createFlatLoader(),
4516
- createUnlocalizableLoader(
4517
- options.isCacheRestore,
4518
- options.returnUnlocalizedKeys
4519
- )
4763
+ createEnsureKeyOrderLoader(),
4764
+ createUnlocalizableLoader(options.returnUnlocalizedKeys)
4520
4765
  );
4521
4766
  case "typescript":
4522
4767
  return composeLoaders(
@@ -4524,13 +4769,11 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys,
4524
4769
  createPrettierLoader({ parser: "typescript", bucketPathPattern }),
4525
4770
  createTypescriptLoader(),
4526
4771
  createFlatLoader(),
4772
+ createEnsureKeyOrderLoader(),
4527
4773
  createSyncLoader(),
4528
- createLockedKeysLoader(lockedKeys || [], options.isCacheRestore),
4774
+ createLockedKeysLoader(lockedKeys || []),
4529
4775
  createIgnoredKeysLoader(ignoredKeys || []),
4530
- createUnlocalizableLoader(
4531
- options.isCacheRestore,
4532
- options.returnUnlocalizedKeys
4533
- )
4776
+ createUnlocalizableLoader(options.returnUnlocalizedKeys)
4534
4777
  );
4535
4778
  }
4536
4779
  }
@@ -4636,7 +4879,7 @@ function createBasicTranslator(model, systemPrompt) {
4636
4879
  ]
4637
4880
  });
4638
4881
  const result = JSON.parse(response.text);
4639
- return _optionalChain([result, 'optionalAccess', _178 => _178.data]) || {};
4882
+ return _optionalChain([result, 'optionalAccess', _185 => _185.data]) || {};
4640
4883
  }
4641
4884
  }
4642
4885
  function extractPayloadChunks(payload) {
@@ -4679,6 +4922,7 @@ var _openai = require('@ai-sdk/openai');
4679
4922
  var _anthropic = require('@ai-sdk/anthropic');
4680
4923
  var _google = require('@ai-sdk/google');
4681
4924
  var _aisdkprovider = require('@openrouter/ai-sdk-provider');
4925
+ var _mistral = require('@ai-sdk/mistral');
4682
4926
  var _ollamaaiprovider = require('ollama-ai-provider');
4683
4927
  function createProcessor(provider, params) {
4684
4928
  if (!provider) {
@@ -4696,7 +4940,11 @@ function getPureModelProvider(provider) {
4696
4940
 
4697
4941
  To fix this issue:
4698
4942
  1. ${envVar ? `Set ${_chalk2.default.dim(envVar)} in your environment variables` : "Set the environment variable for your provider (if required)"}, or
4699
- 2. Remove the ${_chalk2.default.italic("provider")} node from your i18n.json configuration to switch to ${_chalk2.default.hex(colors.green)("Lingo.dev")}
4943
+ 2. Remove the ${_chalk2.default.italic(
4944
+ "provider"
4945
+ )} node from your i18n.json configuration to switch to ${_chalk2.default.hex(
4946
+ colors.green
4947
+ )("Lingo.dev")}
4700
4948
 
4701
4949
  ${_chalk2.default.hex(colors.blue)("Docs: https://lingo.dev/go/docs")}
4702
4950
  `;
@@ -4705,11 +4953,15 @@ function getPureModelProvider(provider) {
4705
4953
 
4706
4954
  To fix this issue:
4707
4955
  1. Switch to one of the supported providers, or
4708
- 2. Remove the ${_chalk2.default.italic("provider")} node from your i18n.json configuration to switch to ${_chalk2.default.hex(colors.green)("Lingo.dev")}
4956
+ 2. Remove the ${_chalk2.default.italic(
4957
+ "provider"
4958
+ )} node from your i18n.json configuration to switch to ${_chalk2.default.hex(
4959
+ colors.green
4960
+ )("Lingo.dev")}
4709
4961
 
4710
4962
  ${_chalk2.default.hex(colors.blue)("Docs: https://lingo.dev/go/docs")}
4711
4963
  `;
4712
- switch (_optionalChain([provider, 'optionalAccess', _179 => _179.id])) {
4964
+ switch (_optionalChain([provider, 'optionalAccess', _186 => _186.id])) {
4713
4965
  case "openai": {
4714
4966
  if (!process.env.OPENAI_API_KEY) {
4715
4967
  throw new Error(
@@ -4755,8 +5007,19 @@ function getPureModelProvider(provider) {
4755
5007
  case "ollama": {
4756
5008
  return _ollamaaiprovider.createOllama.call(void 0, )(provider.model);
4757
5009
  }
5010
+ case "mistral": {
5011
+ if (!process.env.MISTRAL_API_KEY) {
5012
+ throw new Error(
5013
+ createMissingKeyErrorMessage("Mistral", "MISTRAL_API_KEY")
5014
+ );
5015
+ }
5016
+ return _mistral.createMistral.call(void 0, {
5017
+ apiKey: process.env.MISTRAL_API_KEY,
5018
+ baseURL: provider.baseUrl
5019
+ })(provider.model);
5020
+ }
4758
5021
  default: {
4759
- throw new Error(createUnsupportedProviderErrorMessage(_optionalChain([provider, 'optionalAccess', _180 => _180.id])));
5022
+ throw new Error(createUnsupportedProviderErrorMessage(_optionalChain([provider, 'optionalAccess', _187 => _187.id])));
4760
5023
  }
4761
5024
  }
4762
5025
  }
@@ -4864,11 +5127,17 @@ function createDeltaProcessor(fileKey) {
4864
5127
  return checkIfFileExists(lockfilePath);
4865
5128
  },
4866
5129
  async calculateDelta(params) {
4867
- let added = _lodash2.default.difference(Object.keys(params.sourceData), Object.keys(params.targetData));
4868
- let removed = _lodash2.default.difference(Object.keys(params.targetData), Object.keys(params.sourceData));
4869
- const updated = _lodash2.default.filter(Object.keys(params.sourceData), (key) => {
4870
- return md5(params.sourceData[key]) !== params.checksums[key] && params.checksums[key];
4871
- });
5130
+ let added = _lodash2.default.difference(
5131
+ Object.keys(params.sourceData),
5132
+ Object.keys(params.targetData)
5133
+ );
5134
+ let removed = _lodash2.default.difference(
5135
+ Object.keys(params.targetData),
5136
+ Object.keys(params.sourceData)
5137
+ );
5138
+ const updated = Object.keys(params.sourceData).filter(
5139
+ (key) => md5(params.sourceData[key]) !== params.checksums[key] && params.checksums[key]
5140
+ );
4872
5141
  const renamed = [];
4873
5142
  for (const addedKey of added) {
4874
5143
  const addedHash = md5(params.sourceData[addedKey]);
@@ -4879,9 +5148,18 @@ function createDeltaProcessor(fileKey) {
4879
5148
  }
4880
5149
  }
4881
5150
  }
4882
- added = added.filter((key) => !renamed.some(([oldKey, newKey]) => newKey === key));
4883
- removed = removed.filter((key) => !renamed.some(([oldKey, newKey]) => oldKey === key));
4884
- const hasChanges = [added.length > 0, removed.length > 0, updated.length > 0, renamed.length > 0].some((v) => v);
5151
+ added = added.filter(
5152
+ (key) => !renamed.some(([oldKey, newKey]) => newKey === key)
5153
+ );
5154
+ removed = removed.filter(
5155
+ (key) => !renamed.some(([oldKey, newKey]) => oldKey === key)
5156
+ );
5157
+ const hasChanges = [
5158
+ added.length > 0,
5159
+ removed.length > 0,
5160
+ updated.length > 0,
5161
+ renamed.length > 0
5162
+ ].some((v) => v);
4885
5163
  return {
4886
5164
  added,
4887
5165
  removed,
@@ -4981,7 +5259,7 @@ var i18n_default = new (0, _interactivecommander.Command)().command("i18n").desc
4981
5259
  validateParams(i18nConfig, flags);
4982
5260
  ora.succeed("Localization configuration is valid");
4983
5261
  ora.start("Connecting to Lingo.dev Localization Engine...");
4984
- const isByokMode = !!_optionalChain([i18nConfig, 'optionalAccess', _181 => _181.provider]);
5262
+ const isByokMode = !!_optionalChain([i18nConfig, 'optionalAccess', _188 => _188.provider]);
4985
5263
  if (isByokMode) {
4986
5264
  authId = null;
4987
5265
  ora.succeed("Using external provider (BYOK mode)");
@@ -4995,16 +5273,16 @@ var i18n_default = new (0, _interactivecommander.Command)().command("i18n").desc
4995
5273
  flags
4996
5274
  });
4997
5275
  let buckets = getBuckets(i18nConfig);
4998
- if (_optionalChain([flags, 'access', _182 => _182.bucket, 'optionalAccess', _183 => _183.length])) {
5276
+ if (_optionalChain([flags, 'access', _189 => _189.bucket, 'optionalAccess', _190 => _190.length])) {
4999
5277
  buckets = buckets.filter(
5000
5278
  (bucket) => flags.bucket.includes(bucket.type)
5001
5279
  );
5002
5280
  }
5003
5281
  ora.succeed("Buckets retrieved");
5004
- if (_optionalChain([flags, 'access', _184 => _184.file, 'optionalAccess', _185 => _185.length])) {
5282
+ if (_optionalChain([flags, 'access', _191 => _191.file, 'optionalAccess', _192 => _192.length])) {
5005
5283
  buckets = buckets.map((bucket) => {
5006
5284
  const paths = bucket.paths.filter(
5007
- (path17) => flags.file.find((file) => _optionalChain([path17, 'access', _186 => _186.pathPattern, 'optionalAccess', _187 => _187.includes, 'call', _188 => _188(file)]))
5285
+ (path17) => flags.file.find((file) => _optionalChain([path17, 'access', _193 => _193.pathPattern, 'optionalAccess', _194 => _194.includes, 'call', _195 => _195(file)]))
5008
5286
  );
5009
5287
  return { ...bucket, paths };
5010
5288
  }).filter((bucket) => bucket.paths.length > 0);
@@ -5023,7 +5301,7 @@ var i18n_default = new (0, _interactivecommander.Command)().command("i18n").desc
5023
5301
  });
5024
5302
  }
5025
5303
  }
5026
- const targetLocales = _optionalChain([flags, 'access', _189 => _189.locale, 'optionalAccess', _190 => _190.length]) ? flags.locale : i18nConfig.locale.targets;
5304
+ const targetLocales = _optionalChain([flags, 'access', _196 => _196.locale, 'optionalAccess', _197 => _197.length]) ? flags.locale : i18nConfig.locale.targets;
5027
5305
  ora.start("Setting up localization cache...");
5028
5306
  const checkLockfileProcessor = createDeltaProcessor("");
5029
5307
  const lockfileExists = await checkLockfileProcessor.checkIfLockExists();
@@ -5039,7 +5317,6 @@ var i18n_default = new (0, _interactivecommander.Command)().command("i18n").desc
5039
5317
  bucket.type,
5040
5318
  bucketPath.pathPattern,
5041
5319
  {
5042
- isCacheRestore: false,
5043
5320
  defaultLocale: sourceLocale,
5044
5321
  injectLocale: bucket.injectLocale
5045
5322
  },
@@ -5074,7 +5351,6 @@ var i18n_default = new (0, _interactivecommander.Command)().command("i18n").desc
5074
5351
  bucket.type,
5075
5352
  bucketPath.pathPattern,
5076
5353
  {
5077
- isCacheRestore: false,
5078
5354
  defaultLocale: sourceLocale,
5079
5355
  returnUnlocalizedKeys: true,
5080
5356
  injectLocale: bucket.injectLocale
@@ -5160,7 +5436,6 @@ var i18n_default = new (0, _interactivecommander.Command)().command("i18n").desc
5160
5436
  bucket.type,
5161
5437
  bucketPath.pathPattern,
5162
5438
  {
5163
- isCacheRestore: false,
5164
5439
  defaultLocale: sourceLocale,
5165
5440
  injectLocale: bucket.injectLocale
5166
5441
  },
@@ -5197,7 +5472,7 @@ var i18n_default = new (0, _interactivecommander.Command)().command("i18n").desc
5197
5472
  if (flags.key) {
5198
5473
  processableData = _lodash2.default.pickBy(
5199
5474
  processableData,
5200
- (_33, key) => key === flags.key
5475
+ (_34, key) => key === flags.key
5201
5476
  );
5202
5477
  }
5203
5478
  if (flags.verbose) {
@@ -5367,12 +5642,12 @@ function validateParams(i18nConfig, flags) {
5367
5642
  message: "No buckets found in i18n.json. Please add at least one bucket containing i18n content.",
5368
5643
  docUrl: "bucketNotFound"
5369
5644
  });
5370
- } else if (_optionalChain([flags, 'access', _191 => _191.locale, 'optionalAccess', _192 => _192.some, 'call', _193 => _193((locale) => !i18nConfig.locale.targets.includes(locale))])) {
5645
+ } else if (_optionalChain([flags, 'access', _198 => _198.locale, 'optionalAccess', _199 => _199.some, 'call', _200 => _200((locale) => !i18nConfig.locale.targets.includes(locale))])) {
5371
5646
  throw new CLIError({
5372
5647
  message: `One or more specified locales do not exist in i18n.json locale.targets. Please add them to the list and try again.`,
5373
5648
  docUrl: "localeTargetNotFound"
5374
5649
  });
5375
- } else if (_optionalChain([flags, 'access', _194 => _194.bucket, 'optionalAccess', _195 => _195.some, 'call', _196 => _196(
5650
+ } else if (_optionalChain([flags, 'access', _201 => _201.bucket, 'optionalAccess', _202 => _202.some, 'call', _203 => _203(
5376
5651
  (bucket) => !i18nConfig.buckets[bucket]
5377
5652
  )])) {
5378
5653
  throw new CLIError({
@@ -5387,7 +5662,9 @@ async function reviewChanges(args) {
5387
5662
  if (currentStr === proposedStr && !args.force) {
5388
5663
  console.log(
5389
5664
  `
5390
- ${_chalk2.default.blue(args.pathPattern)} (${_chalk2.default.yellow(args.targetLocale)}): ${_chalk2.default.gray("No changes to review")}`
5665
+ ${_chalk2.default.blue(args.pathPattern)} (${_chalk2.default.yellow(
5666
+ args.targetLocale
5667
+ )}): ${_chalk2.default.gray("No changes to review")}`
5391
5668
  );
5392
5669
  return args.proposedData;
5393
5670
  }
@@ -5408,7 +5685,9 @@ ${_chalk2.default.blue(args.pathPattern)} (${_chalk2.default.yellow(args.targetL
5408
5685
  }).join("\n");
5409
5686
  console.log(
5410
5687
  `
5411
- Reviewing changes for ${_chalk2.default.blue(args.pathPattern)} (${_chalk2.default.yellow(args.targetLocale)}):`
5688
+ Reviewing changes for ${_chalk2.default.blue(args.pathPattern)} (${_chalk2.default.yellow(
5689
+ args.targetLocale
5690
+ )}):`
5412
5691
  );
5413
5692
  console.log(coloredDiff);
5414
5693
  const { action } = await _inquirer2.default.prompt([
@@ -5521,8 +5800,15 @@ function createLockfileHelper() {
5521
5800
  registerPartialSourceData: (pathPattern, partialSourceData) => {
5522
5801
  const lockfile = _loadLockfile();
5523
5802
  const sectionKey = _objecthash.MD5.call(void 0, pathPattern);
5524
- const sectionChecksums = _lodash2.default.mapValues(partialSourceData, (value) => _objecthash.MD5.call(void 0, value));
5525
- lockfile.checksums[sectionKey] = _lodash2.default.merge({}, _nullishCoalesce(lockfile.checksums[sectionKey], () => ( {})), sectionChecksums);
5803
+ const sectionChecksums = _lodash2.default.mapValues(
5804
+ partialSourceData,
5805
+ (value) => _objecthash.MD5.call(void 0, value)
5806
+ );
5807
+ lockfile.checksums[sectionKey] = _lodash2.default.merge(
5808
+ {},
5809
+ _nullishCoalesce(lockfile.checksums[sectionKey], () => ( {})),
5810
+ sectionChecksums
5811
+ );
5526
5812
  _saveLockfile(lockfile);
5527
5813
  },
5528
5814
  extractUpdatedData: (pathPattern, sourceData) => {
@@ -5530,7 +5816,10 @@ function createLockfileHelper() {
5530
5816
  const sectionKey = _objecthash.MD5.call(void 0, pathPattern);
5531
5817
  const currentChecksums = _lodash2.default.mapValues(sourceData, (value) => _objecthash.MD5.call(void 0, value));
5532
5818
  const savedChecksums = lockfile.checksums[sectionKey] || {};
5533
- const updatedData = _lodash2.default.pickBy(sourceData, (value, key) => savedChecksums[key] !== currentChecksums[key]);
5819
+ const updatedData = _lodash2.default.pickBy(
5820
+ sourceData,
5821
+ (value, key) => savedChecksums[key] !== currentChecksums[key]
5822
+ );
5534
5823
  return updatedData;
5535
5824
  }
5536
5825
  };
@@ -5574,20 +5863,31 @@ var lockfile_default = new (0, _interactivecommander.Command)().command("lockfil
5574
5863
  const ora = _ora2.default.call(void 0, );
5575
5864
  const lockfileHelper = createLockfileHelper();
5576
5865
  if (lockfileHelper.isLockfileExists() && !flags.force) {
5577
- ora.warn(`Lockfile won't be created because it already exists. Use --force to overwrite.`);
5866
+ ora.warn(
5867
+ `Lockfile won't be created because it already exists. Use --force to overwrite.`
5868
+ );
5578
5869
  } else {
5579
5870
  const i18nConfig = getConfig();
5580
5871
  const buckets = getBuckets(i18nConfig);
5581
5872
  for (const bucket of buckets) {
5582
5873
  for (const bucketConfig of bucket.paths) {
5583
- const sourceLocale = __spec.resolveOverriddenLocale.call(void 0, i18nConfig.locale.source, bucketConfig.delimiter);
5584
- const bucketLoader = createBucketLoader(bucket.type, bucketConfig.pathPattern, {
5585
- isCacheRestore: false,
5586
- defaultLocale: sourceLocale
5587
- });
5874
+ const sourceLocale = __spec.resolveOverriddenLocale.call(void 0,
5875
+ i18nConfig.locale.source,
5876
+ bucketConfig.delimiter
5877
+ );
5878
+ const bucketLoader = createBucketLoader(
5879
+ bucket.type,
5880
+ bucketConfig.pathPattern,
5881
+ {
5882
+ defaultLocale: sourceLocale
5883
+ }
5884
+ );
5588
5885
  bucketLoader.setDefaultLocale(sourceLocale);
5589
5886
  const sourceData = await bucketLoader.pull(sourceLocale);
5590
- lockfileHelper.registerSourceData(bucketConfig.pathPattern, sourceData);
5887
+ lockfileHelper.registerSourceData(
5888
+ bucketConfig.pathPattern,
5889
+ sourceData
5890
+ );
5591
5891
  }
5592
5892
  }
5593
5893
  ora.succeed("Lockfile created");
@@ -5602,7 +5902,9 @@ var flagsSchema = _zod2.default.object({
5602
5902
 
5603
5903
 
5604
5904
 
5605
- var cleanup_default = new (0, _interactivecommander.Command)().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(
5905
+ var cleanup_default = new (0, _interactivecommander.Command)().command("cleanup").description(
5906
+ "Remove keys from target files that do not exist in the source file"
5907
+ ).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(
5606
5908
  "--verbose",
5607
5909
  "Show detailed output including:\n - List of keys that would be removed.\n - Processing steps."
5608
5910
  ).action(async function(options) {
@@ -5615,24 +5917,37 @@ var cleanup_default = new (0, _interactivecommander.Command)().command("cleanup"
5615
5917
  ora.succeed("Configuration loaded");
5616
5918
  let buckets = getBuckets(i18nConfig);
5617
5919
  if (options.bucket) {
5618
- buckets = buckets.filter((bucket) => bucket.type === options.bucket);
5920
+ buckets = buckets.filter(
5921
+ (bucket) => bucket.type === options.bucket
5922
+ );
5619
5923
  }
5620
5924
  const targetLocales = options.locale ? [options.locale] : i18nConfig.locale.targets;
5621
5925
  for (const bucket of buckets) {
5622
5926
  console.log();
5623
5927
  ora.info(`Processing bucket: ${bucket.type}`);
5624
5928
  for (const bucketConfig of bucket.paths) {
5625
- const sourceLocale = __spec.resolveOverriddenLocale.call(void 0, i18nConfig.locale.source, bucketConfig.delimiter);
5626
- const bucketOra = _ora2.default.call(void 0, { indent: 2 }).info(`Processing path: ${bucketConfig.pathPattern}`);
5627
- const bucketLoader = createBucketLoader(bucket.type, bucketConfig.pathPattern, {
5628
- isCacheRestore: false,
5629
- defaultLocale: sourceLocale
5630
- });
5929
+ const sourceLocale = __spec.resolveOverriddenLocale.call(void 0,
5930
+ i18nConfig.locale.source,
5931
+ bucketConfig.delimiter
5932
+ );
5933
+ const bucketOra = _ora2.default.call(void 0, { indent: 2 }).info(
5934
+ `Processing path: ${bucketConfig.pathPattern}`
5935
+ );
5936
+ const bucketLoader = createBucketLoader(
5937
+ bucket.type,
5938
+ bucketConfig.pathPattern,
5939
+ {
5940
+ defaultLocale: sourceLocale
5941
+ }
5942
+ );
5631
5943
  bucketLoader.setDefaultLocale(sourceLocale);
5632
5944
  const sourceData = await bucketLoader.pull(sourceLocale);
5633
5945
  const sourceKeys = Object.keys(sourceData);
5634
5946
  for (const _targetLocale of targetLocales) {
5635
- const targetLocale = __spec.resolveOverriddenLocale.call(void 0, _targetLocale, bucketConfig.delimiter);
5947
+ const targetLocale = __spec.resolveOverriddenLocale.call(void 0,
5948
+ _targetLocale,
5949
+ bucketConfig.delimiter
5950
+ );
5636
5951
  try {
5637
5952
  const targetData = await bucketLoader.pull(targetLocale);
5638
5953
  const targetKeys = Object.keys(targetData);
@@ -5642,17 +5957,29 @@ var cleanup_default = new (0, _interactivecommander.Command)().command("cleanup"
5642
5957
  continue;
5643
5958
  }
5644
5959
  if (options.verbose) {
5645
- bucketOra.info(`[${targetLocale}] Keys to remove: ${JSON.stringify(keysToRemove, null, 2)}`);
5960
+ bucketOra.info(
5961
+ `[${targetLocale}] Keys to remove: ${JSON.stringify(
5962
+ keysToRemove,
5963
+ null,
5964
+ 2
5965
+ )}`
5966
+ );
5646
5967
  }
5647
5968
  if (!options.dryRun) {
5648
5969
  const cleanedData = _lodash2.default.pick(targetData, sourceKeys);
5649
5970
  await bucketLoader.push(targetLocale, cleanedData);
5650
- bucketOra.succeed(`[${targetLocale}] Removed ${keysToRemove.length} keys`);
5971
+ bucketOra.succeed(
5972
+ `[${targetLocale}] Removed ${keysToRemove.length} keys`
5973
+ );
5651
5974
  } else {
5652
- bucketOra.succeed(`[${targetLocale}] Would remove ${keysToRemove.length} keys (dry run)`);
5975
+ bucketOra.succeed(
5976
+ `[${targetLocale}] Would remove ${keysToRemove.length} keys (dry run)`
5977
+ );
5653
5978
  }
5654
5979
  } catch (error) {
5655
- bucketOra.fail(`[${targetLocale}] Failed to cleanup: ${error.message}`);
5980
+ bucketOra.fail(
5981
+ `[${targetLocale}] Failed to cleanup: ${error.message}`
5982
+ );
5656
5983
  results.push({
5657
5984
  step: `Cleanup ${bucket.type}/${bucketConfig} for ${targetLocale}`,
5658
5985
  status: "Failed",
@@ -5700,7 +6027,7 @@ var _stdiojs = require('@modelcontextprotocol/sdk/server/stdio.js');
5700
6027
  var _mcpjs = require('@modelcontextprotocol/sdk/server/mcp.js');
5701
6028
 
5702
6029
 
5703
- var mcp_default = new (0, _interactivecommander.Command)().command("mcp").description("Use Lingo.dev model context provider with your AI agent").helpOption("-h, --help", "Show help").action(async (_33, program) => {
6030
+ var mcp_default = new (0, _interactivecommander.Command)().command("mcp").description("Use Lingo.dev model context provider with your AI agent").helpOption("-h, --help", "Show help").action(async (_34, program) => {
5704
6031
  const apiKey = program.args[0];
5705
6032
  const settings = getSettings(apiKey);
5706
6033
  if (!settings.auth.apiKey) {
@@ -5802,7 +6129,9 @@ function createLingoDotDevLocalizer(explicitApiKey) {
5802
6129
  if (!auth) {
5803
6130
  throw new Error(
5804
6131
  _dedent2.default`
5805
- You're trying to use ${_chalk2.default.hex(colors.green)("Lingo.dev")} provider, however, you are not authenticated.
6132
+ You're trying to use ${_chalk2.default.hex(colors.green)(
6133
+ "Lingo.dev"
6134
+ )} provider, however, you are not authenticated.
5806
6135
 
5807
6136
  To fix this issue:
5808
6137
  1. Run ${_chalk2.default.dim("lingo.dev login")} to authenticate, or
@@ -5822,7 +6151,7 @@ function createLingoDotDevLocalizer(explicitApiKey) {
5822
6151
  const response = await engine.whoami();
5823
6152
  return {
5824
6153
  authenticated: !!response,
5825
- username: _optionalChain([response, 'optionalAccess', _197 => _197.email])
6154
+ username: _optionalChain([response, 'optionalAccess', _204 => _204.email])
5826
6155
  };
5827
6156
  } catch (e2) {
5828
6157
  return { authenticated: false };
@@ -5859,6 +6188,7 @@ function createLingoDotDevLocalizer(explicitApiKey) {
5859
6188
 
5860
6189
 
5861
6190
 
6191
+
5862
6192
  function createExplicitLocalizer(provider) {
5863
6193
  switch (provider.id) {
5864
6194
  default:
@@ -5868,7 +6198,11 @@ function createExplicitLocalizer(provider) {
5868
6198
 
5869
6199
  To fix this issue:
5870
6200
  1. Switch to one of the supported providers, or
5871
- 2. Remove the ${_chalk2.default.italic("provider")} node from your i18n.json configuration to switch to ${_chalk2.default.hex(colors.green)("Lingo.dev")}
6201
+ 2. Remove the ${_chalk2.default.italic(
6202
+ "provider"
6203
+ )} node from your i18n.json configuration to switch to ${_chalk2.default.hex(
6204
+ colors.green
6205
+ )("Lingo.dev")}
5872
6206
 
5873
6207
  ${_chalk2.default.hex(colors.blue)("Docs: https://lingo.dev/go/docs")}
5874
6208
  `
@@ -5912,19 +6246,35 @@ function createExplicitLocalizer(provider) {
5912
6246
  prompt: provider.prompt,
5913
6247
  skipAuth: true
5914
6248
  });
6249
+ case "mistral":
6250
+ return createAiSdkLocalizer({
6251
+ factory: (params) => _mistral.createMistral.call(void 0, params).languageModel(provider.model),
6252
+ id: provider.id,
6253
+ prompt: provider.prompt,
6254
+ apiKeyName: "MISTRAL_API_KEY",
6255
+ baseUrl: provider.baseUrl
6256
+ });
5915
6257
  }
5916
6258
  }
5917
6259
  function createAiSdkLocalizer(params) {
5918
6260
  const skipAuth = params.skipAuth === true;
5919
- const apiKey = process.env[_nullishCoalesce(_optionalChain([params, 'optionalAccess', _198 => _198.apiKeyName]), () => ( ""))];
6261
+ const apiKey = process.env[_nullishCoalesce(_optionalChain([params, 'optionalAccess', _205 => _205.apiKeyName]), () => ( ""))];
5920
6262
  if (!skipAuth && !apiKey || !params.apiKeyName) {
5921
6263
  throw new Error(
5922
6264
  _dedent2.default`
5923
- You're trying to use raw ${_chalk2.default.dim(params.id)} API for translation. ${params.apiKeyName ? `However, ${_chalk2.default.dim(params.apiKeyName)} environment variable is not set.` : "However, that provider is unavailable."}
6265
+ You're trying to use raw ${_chalk2.default.dim(params.id)} API for translation. ${params.apiKeyName ? `However, ${_chalk2.default.dim(
6266
+ params.apiKeyName
6267
+ )} environment variable is not set.` : "However, that provider is unavailable."}
5924
6268
 
5925
6269
  To fix this issue:
5926
- 1. ${params.apiKeyName ? `Set ${_chalk2.default.dim(params.apiKeyName)} in your environment variables` : "Set the environment variable for your provider (if required)"}, or
5927
- 2. Remove the ${_chalk2.default.italic("provider")} node from your i18n.json configuration to switch to ${_chalk2.default.hex(colors.green)("Lingo.dev")}
6270
+ 1. ${params.apiKeyName ? `Set ${_chalk2.default.dim(
6271
+ params.apiKeyName
6272
+ )} in your environment variables` : "Set the environment variable for your provider (if required)"}, or
6273
+ 2. Remove the ${_chalk2.default.italic(
6274
+ "provider"
6275
+ )} node from your i18n.json configuration to switch to ${_chalk2.default.hex(
6276
+ colors.green
6277
+ )("Lingo.dev")}
5928
6278
 
5929
6279
  ${_chalk2.default.hex(colors.blue)("Docs: https://lingo.dev/go/docs")}
5930
6280
  `
@@ -6033,8 +6383,8 @@ async function setup(input2) {
6033
6383
  throw new Error(
6034
6384
  "No buckets found in i18n.json. Please add at least one bucket containing i18n content."
6035
6385
  );
6036
- } else if (_optionalChain([ctx, 'access', _199 => _199.flags, 'access', _200 => _200.bucket, 'optionalAccess', _201 => _201.some, 'call', _202 => _202(
6037
- (bucket) => !_optionalChain([ctx, 'access', _203 => _203.config, 'optionalAccess', _204 => _204.buckets, 'access', _205 => _205[bucket]])
6386
+ } else if (_optionalChain([ctx, 'access', _206 => _206.flags, 'access', _207 => _207.bucket, 'optionalAccess', _208 => _208.some, 'call', _209 => _209(
6387
+ (bucket) => !_optionalChain([ctx, 'access', _210 => _210.config, 'optionalAccess', _211 => _211.buckets, 'access', _212 => _212[bucket]])
6038
6388
  )])) {
6039
6389
  throw new Error(
6040
6390
  `One or more specified buckets do not exist in i18n.json. Please add them to the list first and try again.`
@@ -6047,7 +6397,7 @@ async function setup(input2) {
6047
6397
  title: "Selecting localization provider",
6048
6398
  task: async (ctx, task) => {
6049
6399
  ctx.localizer = createLocalizer(
6050
- _optionalChain([ctx, 'access', _206 => _206.config, 'optionalAccess', _207 => _207.provider]),
6400
+ _optionalChain([ctx, 'access', _213 => _213.config, 'optionalAccess', _214 => _214.provider]),
6051
6401
  ctx.flags.apiKey
6052
6402
  );
6053
6403
  if (!ctx.localizer) {
@@ -6064,10 +6414,14 @@ async function setup(input2) {
6064
6414
  const authStatus = await ctx.localizer.checkAuth();
6065
6415
  if (!authStatus.authenticated) {
6066
6416
  throw new Error(
6067
- `Failed to authenticate with ${_chalk2.default.hex(colors.yellow)(ctx.localizer.id)} provider. Please check your API key and try again.`
6417
+ `Failed to authenticate with ${_chalk2.default.hex(colors.yellow)(
6418
+ ctx.localizer.id
6419
+ )} provider. Please check your API key and try again.`
6068
6420
  );
6069
6421
  }
6070
- task.title = `Authenticated as ${_chalk2.default.hex(colors.yellow)(authStatus.username)}`;
6422
+ task.title = `Authenticated as ${_chalk2.default.hex(colors.yellow)(
6423
+ authStatus.username
6424
+ )}`;
6071
6425
  }
6072
6426
  },
6073
6427
  {
@@ -6128,14 +6482,22 @@ async function plan(input2) {
6128
6482
  title: "Locating content buckets",
6129
6483
  task: async (ctx, task) => {
6130
6484
  const bucketCount = buckets.length;
6131
- const bucketFilter = input2.flags.bucket ? ` ${_chalk2.default.dim(`(filtered by: ${_chalk2.default.hex(colors.yellow)(input2.flags.bucket.join(", "))})`)}` : "";
6132
- task.title = `Found ${_chalk2.default.hex(colors.yellow)(bucketCount.toString())} bucket(s)${bucketFilter}`;
6485
+ const bucketFilter = input2.flags.bucket ? ` ${_chalk2.default.dim(
6486
+ `(filtered by: ${_chalk2.default.hex(colors.yellow)(
6487
+ input2.flags.bucket.join(", ")
6488
+ )})`
6489
+ )}` : "";
6490
+ task.title = `Found ${_chalk2.default.hex(colors.yellow)(
6491
+ bucketCount.toString()
6492
+ )} bucket(s)${bucketFilter}`;
6133
6493
  }
6134
6494
  },
6135
6495
  {
6136
6496
  title: "Detecting locales",
6137
6497
  task: async (ctx, task) => {
6138
- task.title = `Found ${_chalk2.default.hex(colors.yellow)(_targetLocales.length.toString())} target locale(s)`;
6498
+ task.title = `Found ${_chalk2.default.hex(colors.yellow)(
6499
+ _targetLocales.length.toString()
6500
+ )} target locale(s)`;
6139
6501
  }
6140
6502
  },
6141
6503
  {
@@ -6154,8 +6516,14 @@ async function plan(input2) {
6154
6516
  patterns.push(bucketPath.pathPattern);
6155
6517
  }
6156
6518
  }
6157
- const fileFilter = input2.flags.file ? ` ${_chalk2.default.dim(`(filtered by: ${_chalk2.default.hex(colors.yellow)(input2.flags.file.join(", "))})`)}` : "";
6158
- task.title = `Found ${_chalk2.default.hex(colors.yellow)(patterns.length.toString())} path pattern(s)${fileFilter}`;
6519
+ const fileFilter = input2.flags.file ? ` ${_chalk2.default.dim(
6520
+ `(filtered by: ${_chalk2.default.hex(colors.yellow)(
6521
+ input2.flags.file.join(", ")
6522
+ )})`
6523
+ )}` : "";
6524
+ task.title = `Found ${_chalk2.default.hex(colors.yellow)(
6525
+ patterns.length.toString()
6526
+ )} path pattern(s)${fileFilter}`;
6159
6527
  }
6160
6528
  },
6161
6529
  {
@@ -6193,7 +6561,9 @@ async function plan(input2) {
6193
6561
  }
6194
6562
  }
6195
6563
  }
6196
- task.title = `Prepared ${_chalk2.default.hex(colors.green)(ctx.tasks.length.toString())} translation task(s)`;
6564
+ task.title = `Prepared ${_chalk2.default.hex(colors.green)(
6565
+ ctx.tasks.length.toString()
6566
+ )} translation task(s)`;
6197
6567
  }
6198
6568
  }
6199
6569
  ],
@@ -6647,7 +7017,7 @@ var AST = class _AST {
6647
7017
  const ret = this.type === null ? this.#parts.slice().map((p) => typeof p === "string" ? p : p.toJSON()) : [this.type, ...this.#parts.map((p) => p.toJSON())];
6648
7018
  if (this.isStart() && !this.type)
6649
7019
  ret.unshift([]);
6650
- if (this.isEnd() && (this === this.#root || this.#root.#filledNegs && _optionalChain([this, 'access', _208 => _208.#parent, 'optionalAccess', _209 => _209.type]) === "!")) {
7020
+ if (this.isEnd() && (this === this.#root || this.#root.#filledNegs && _optionalChain([this, 'access', _215 => _215.#parent, 'optionalAccess', _216 => _216.type]) === "!")) {
6651
7021
  ret.push({});
6652
7022
  }
6653
7023
  return ret;
@@ -6655,7 +7025,7 @@ var AST = class _AST {
6655
7025
  isStart() {
6656
7026
  if (this.#root === this)
6657
7027
  return true;
6658
- if (!_optionalChain([this, 'access', _210 => _210.#parent, 'optionalAccess', _211 => _211.isStart, 'call', _212 => _212()]))
7028
+ if (!_optionalChain([this, 'access', _217 => _217.#parent, 'optionalAccess', _218 => _218.isStart, 'call', _219 => _219()]))
6659
7029
  return false;
6660
7030
  if (this.#parentIndex === 0)
6661
7031
  return true;
@@ -6671,12 +7041,12 @@ var AST = class _AST {
6671
7041
  isEnd() {
6672
7042
  if (this.#root === this)
6673
7043
  return true;
6674
- if (_optionalChain([this, 'access', _213 => _213.#parent, 'optionalAccess', _214 => _214.type]) === "!")
7044
+ if (_optionalChain([this, 'access', _220 => _220.#parent, 'optionalAccess', _221 => _221.type]) === "!")
6675
7045
  return true;
6676
- if (!_optionalChain([this, 'access', _215 => _215.#parent, 'optionalAccess', _216 => _216.isEnd, 'call', _217 => _217()]))
7046
+ if (!_optionalChain([this, 'access', _222 => _222.#parent, 'optionalAccess', _223 => _223.isEnd, 'call', _224 => _224()]))
6677
7047
  return false;
6678
7048
  if (!this.type)
6679
- return _optionalChain([this, 'access', _218 => _218.#parent, 'optionalAccess', _219 => _219.isEnd, 'call', _220 => _220()]);
7049
+ return _optionalChain([this, 'access', _225 => _225.#parent, 'optionalAccess', _226 => _226.isEnd, 'call', _227 => _227()]);
6680
7050
  const pl = this.#parent ? this.#parent.#parts.length : 0;
6681
7051
  return this.#parentIndex === pl - 1;
6682
7052
  }
@@ -6898,7 +7268,7 @@ var AST = class _AST {
6898
7268
  if (!this.type) {
6899
7269
  const noEmpty = this.isStart() && this.isEnd();
6900
7270
  const src = this.#parts.map((p) => {
6901
- const [re, _33, hasMagic, uflag] = typeof p === "string" ? _AST.#parseGlob(p, this.#hasMagic, noEmpty) : p.toRegExpSource(allowDot);
7271
+ const [re, _34, hasMagic, uflag] = typeof p === "string" ? _AST.#parseGlob(p, this.#hasMagic, noEmpty) : p.toRegExpSource(allowDot);
6902
7272
  this.#hasMagic = this.#hasMagic || hasMagic;
6903
7273
  this.#uflag = this.#uflag || uflag;
6904
7274
  return re;
@@ -6921,7 +7291,7 @@ var AST = class _AST {
6921
7291
  }
6922
7292
  }
6923
7293
  let end = "";
6924
- if (this.isEnd() && this.#root.#filledNegs && _optionalChain([this, 'access', _221 => _221.#parent, 'optionalAccess', _222 => _222.type]) === "!") {
7294
+ if (this.isEnd() && this.#root.#filledNegs && _optionalChain([this, 'access', _228 => _228.#parent, 'optionalAccess', _229 => _229.type]) === "!") {
6925
7295
  end = "(?:$|\\/)";
6926
7296
  }
6927
7297
  const final2 = start2 + src + end;
@@ -6971,7 +7341,7 @@ var AST = class _AST {
6971
7341
  if (typeof p === "string") {
6972
7342
  throw new Error("string type in extglob ast??");
6973
7343
  }
6974
- const [re, _33, _hasMagic, uflag] = p.toRegExpSource(dot);
7344
+ const [re, _34, _hasMagic, uflag] = p.toRegExpSource(dot);
6975
7345
  this.#uflag = this.#uflag || uflag;
6976
7346
  return re;
6977
7347
  }).filter((p) => !(this.isStart() && this.isEnd()) || !!p).join("|");
@@ -7216,7 +7586,7 @@ var Minimatch = class {
7216
7586
  }
7217
7587
  return false;
7218
7588
  }
7219
- debug(..._33) {
7589
+ debug(..._34) {
7220
7590
  }
7221
7591
  make() {
7222
7592
  const pattern = this.pattern;
@@ -7238,7 +7608,7 @@ var Minimatch = class {
7238
7608
  const rawGlobParts = this.globSet.map((s) => this.slashSplit(s));
7239
7609
  this.globParts = this.preprocess(rawGlobParts);
7240
7610
  this.debug(this.pattern, this.globParts);
7241
- let set = this.globParts.map((s, _33, __) => {
7611
+ let set = this.globParts.map((s, _34, __) => {
7242
7612
  if (this.isWindows && this.windowsNoMagicRoot) {
7243
7613
  const isUNC = s[0] === "" && s[1] === "" && (s[2] === "?" || !globMagic.test(s[2])) && !globMagic.test(s[3]);
7244
7614
  const isDrive = /^[a-z]:/i.test(s[0]);
@@ -7761,11 +8131,15 @@ async function execute(input2) {
7761
8131
  {
7762
8132
  title: "Initializing localization engine",
7763
8133
  task: async (ctx, task) => {
7764
- task.title = `Localization engine ${_chalk2.default.hex(colors.green)("ready")} (${ctx.localizer.id})`;
8134
+ task.title = `Localization engine ${_chalk2.default.hex(colors.green)(
8135
+ "ready"
8136
+ )} (${ctx.localizer.id})`;
7765
8137
  }
7766
8138
  },
7767
8139
  {
7768
- title: `Processing localization tasks ${_chalk2.default.dim(`(tasks: ${input2.tasks.length}, concurrency: ${effectiveConcurrency})`)}`,
8140
+ title: `Processing localization tasks ${_chalk2.default.dim(
8141
+ `(tasks: ${input2.tasks.length}, concurrency: ${effectiveConcurrency})`
8142
+ )}`,
7769
8143
  task: (ctx, task) => {
7770
8144
  if (input2.tasks.length < 1) {
7771
8145
  task.title = `Skipping, nothing to localize.`;
@@ -7778,7 +8152,7 @@ async function execute(input2) {
7778
8152
  const workerTasks = [];
7779
8153
  for (let i = 0; i < workersCount; i++) {
7780
8154
  const assignedTasks = ctx.tasks.filter(
7781
- (_33, idx) => idx % workersCount === i
8155
+ (_34, idx) => idx % workersCount === i
7782
8156
  );
7783
8157
  workerTasks.push(
7784
8158
  createWorkerTask({
@@ -7814,11 +8188,11 @@ function createWorkerStatusMessage(args) {
7814
8188
  "[locale]",
7815
8189
  args.assignedTask.targetLocale
7816
8190
  );
7817
- return `[${_chalk2.default.hex(colors.yellow)(`${args.percentage}%`)}] Processing: ${_chalk2.default.dim(
7818
- displayPath
7819
- )} (${_chalk2.default.hex(colors.yellow)(args.assignedTask.sourceLocale)} -> ${_chalk2.default.hex(
7820
- colors.yellow
7821
- )(args.assignedTask.targetLocale)})`;
8191
+ return `[${_chalk2.default.hex(colors.yellow)(
8192
+ `${args.percentage}%`
8193
+ )}] Processing: ${_chalk2.default.dim(displayPath)} (${_chalk2.default.hex(colors.yellow)(
8194
+ args.assignedTask.sourceLocale
8195
+ )} -> ${_chalk2.default.hex(colors.yellow)(args.assignedTask.targetLocale)})`;
7822
8196
  }
7823
8197
  function createExecutionProgressMessage(ctx) {
7824
8198
  const succeededTasksCount = countTasks(
@@ -7833,7 +8207,9 @@ function createExecutionProgressMessage(ctx) {
7833
8207
  ctx,
7834
8208
  (_t, result) => result.status === "skipped"
7835
8209
  );
7836
- return `Processed ${_chalk2.default.green(succeededTasksCount)}/${ctx.tasks.length}, Failed ${_chalk2.default.red(failedTasksCount)}, Skipped ${_chalk2.default.dim(skippedTasksCount)}`;
8210
+ return `Processed ${_chalk2.default.green(succeededTasksCount)}/${ctx.tasks.length}, Failed ${_chalk2.default.red(failedTasksCount)}, Skipped ${_chalk2.default.dim(
8211
+ skippedTasksCount
8212
+ )}`;
7837
8213
  }
7838
8214
  function createLoaderForTask(assignedTask) {
7839
8215
  const bucketLoader = createBucketLoader(
@@ -7841,7 +8217,6 @@ function createLoaderForTask(assignedTask) {
7841
8217
  assignedTask.bucketPathPattern,
7842
8218
  {
7843
8219
  defaultLocale: assignedTask.sourceLocale,
7844
- isCacheRestore: false,
7845
8220
  injectLocale: assignedTask.injectLocale
7846
8221
  },
7847
8222
  assignedTask.lockedKeys,
@@ -7880,7 +8255,7 @@ function createWorkerTask(args) {
7880
8255
  const processableData = _lodash2.default.chain(sourceData).entries().filter(
7881
8256
  ([key, value]) => delta.added.includes(key) || delta.updated.includes(key) || !!args.ctx.flags.force
7882
8257
  ).filter(
7883
- ([key]) => !assignedTask.onlyKeys.length || _optionalChain([assignedTask, 'access', _223 => _223.onlyKeys, 'optionalAccess', _224 => _224.some, 'call', _225 => _225(
8258
+ ([key]) => !assignedTask.onlyKeys.length || _optionalChain([assignedTask, 'access', _230 => _230.onlyKeys, 'optionalAccess', _231 => _231.some, 'call', _232 => _232(
7884
8259
  (pattern) => minimatch(key, pattern)
7885
8260
  )])
7886
8261
  ).fromPairs().value();
@@ -7895,33 +8270,47 @@ function createWorkerTask(args) {
7895
8270
  targetData,
7896
8271
  processableData
7897
8272
  },
7898
- (progress) => {
8273
+ async (progress, _sourceChunk, processedChunk) => {
8274
+ await args.ioLimiter(async () => {
8275
+ await bucketLoader.pull(assignedTask.sourceLocale);
8276
+ const latestTargetData = await bucketLoader.pull(
8277
+ assignedTask.targetLocale
8278
+ );
8279
+ const _partialData = _lodash2.default.merge(
8280
+ {},
8281
+ latestTargetData,
8282
+ processedChunk
8283
+ );
8284
+ const finalChunkTargetData = processRenamedKeys(
8285
+ delta,
8286
+ _partialData
8287
+ );
8288
+ await bucketLoader.push(
8289
+ assignedTask.targetLocale,
8290
+ finalChunkTargetData
8291
+ );
8292
+ });
7899
8293
  subTask.title = createWorkerStatusMessage({
7900
8294
  assignedTask,
7901
8295
  percentage: progress
7902
8296
  });
7903
8297
  }
7904
8298
  );
7905
- let finalTargetData = _lodash2.default.merge(
8299
+ const finalTargetData = _lodash2.default.merge(
7906
8300
  {},
7907
8301
  sourceData,
7908
8302
  targetData,
7909
8303
  processedTargetData
7910
8304
  );
7911
- finalTargetData = _lodash2.default.chain(finalTargetData).entries().map(([key, value]) => {
7912
- const renaming = delta.renamed.find(
7913
- ([oldKey]) => oldKey === key
7914
- );
7915
- if (!renaming) {
7916
- return [key, value];
7917
- }
7918
- return [renaming[1], value];
7919
- }).fromPairs().value();
8305
+ const finalRenamedTargetData = processRenamedKeys(
8306
+ delta,
8307
+ finalTargetData
8308
+ );
7920
8309
  await args.ioLimiter(async () => {
7921
8310
  await bucketLoader.pull(assignedTask.sourceLocale);
7922
8311
  await bucketLoader.push(
7923
8312
  assignedTask.targetLocale,
7924
- finalTargetData
8313
+ finalRenamedTargetData
7925
8314
  );
7926
8315
  const checksums2 = await deltaProcessor.createChecksums(sourceData);
7927
8316
  await deltaProcessor.saveChecksums(checksums2);
@@ -7945,6 +8334,15 @@ function countTasks(ctx, predicate) {
7945
8334
  ([task, result]) => predicate(task, result)
7946
8335
  ).length;
7947
8336
  }
8337
+ function processRenamedKeys(delta, targetData) {
8338
+ return _lodash2.default.chain(targetData).entries().map(([key, value]) => {
8339
+ const renaming = delta.renamed.find(([oldKey]) => oldKey === key);
8340
+ if (!renaming) {
8341
+ return [key, value];
8342
+ }
8343
+ return [renaming[1], value];
8344
+ }).fromPairs().value();
8345
+ }
7948
8346
 
7949
8347
  // src/cli/cmd/run/_types.ts
7950
8348
 
@@ -7969,13 +8367,13 @@ var flagsSchema2 = _zod.z.object({
7969
8367
 
7970
8368
  // src/cli/cmd/run/_utils.ts
7971
8369
  async function determineAuthId(ctx) {
7972
- const isByokMode = !!_optionalChain([ctx, 'access', _226 => _226.config, 'optionalAccess', _227 => _227.provider]);
8370
+ const isByokMode = !!_optionalChain([ctx, 'access', _233 => _233.config, 'optionalAccess', _234 => _234.provider]);
7973
8371
  if (isByokMode) {
7974
8372
  return null;
7975
8373
  } else {
7976
8374
  try {
7977
- const authStatus = await _optionalChain([ctx, 'access', _228 => _228.localizer, 'optionalAccess', _229 => _229.checkAuth, 'call', _230 => _230()]);
7978
- return _optionalChain([authStatus, 'optionalAccess', _231 => _231.username]) || null;
8375
+ const authStatus = await _optionalChain([ctx, 'access', _235 => _235.localizer, 'optionalAccess', _236 => _236.checkAuth, 'call', _237 => _237()]);
8376
+ return _optionalChain([authStatus, 'optionalAccess', _238 => _238.username]) || null;
7979
8377
  } catch (e3) {
7980
8378
  return null;
7981
8379
  }
@@ -8075,7 +8473,9 @@ var InBranchFlow = class extends IntegrationFlow {
8075
8473
  _child_process.execSync.call(void 0, `git add .`, { stdio: "inherit" });
8076
8474
  _child_process.execSync.call(void 0, `git status --porcelain`, { stdio: "inherit" });
8077
8475
  _child_process.execSync.call(void 0,
8078
- `git commit -m ${escapeShellArg(this.platformKit.config.commitMessage)} --no-verify`,
8476
+ `git commit -m ${escapeShellArg(
8477
+ this.platformKit.config.commitMessage
8478
+ )} --no-verify`,
8079
8479
  {
8080
8480
  stdio: "inherit"
8081
8481
  }
@@ -8123,7 +8523,7 @@ var InBranchFlow = class extends IntegrationFlow {
8123
8523
  _child_process.execSync.call(void 0, `git config --global safe.directory ${process.cwd()}`);
8124
8524
  _child_process.execSync.call(void 0, `git config user.name "${gitConfig.userName}"`);
8125
8525
  _child_process.execSync.call(void 0, `git config user.email "${gitConfig.userEmail}"`);
8126
- _optionalChain([this, 'access', _232 => _232.platformKit, 'optionalAccess', _233 => _233.gitConfig, 'call', _234 => _234()]);
8526
+ _optionalChain([this, 'access', _239 => _239.platformKit, 'optionalAccess', _240 => _240.gitConfig, 'call', _241 => _241()]);
8127
8527
  _child_process.execSync.call(void 0, `git fetch origin ${baseBranchName}`, { stdio: "inherit" });
8128
8528
  _child_process.execSync.call(void 0, `git checkout ${baseBranchName} --`, { stdio: "inherit" });
8129
8529
  if (!processOwnCommits) {
@@ -8155,7 +8555,7 @@ var InBranchFlow = class extends IntegrationFlow {
8155
8555
  // src/cli/cmd/ci/flows/pull-request.ts
8156
8556
  var PullRequestFlow = class extends InBranchFlow {
8157
8557
  async preRun() {
8158
- const canContinue = await _optionalChain([super.preRun.bind(this), 'optionalCall', _235 => _235()]);
8558
+ const canContinue = await _optionalChain([super.preRun.bind(this), 'optionalCall', _242 => _242()]);
8159
8559
  if (!canContinue) {
8160
8560
  return false;
8161
8561
  }
@@ -8198,7 +8598,9 @@ var PullRequestFlow = class extends InBranchFlow {
8198
8598
  this.ora.start("Checking if PR already exists");
8199
8599
  const pullRequestNumber = await this.ensureFreshPr(this.i18nBranchName);
8200
8600
  this.ora.succeed(
8201
- `Pull request ready: ${this.platformKit.buildPullRequestUrl(pullRequestNumber)}`
8601
+ `Pull request ready: ${this.platformKit.buildPullRequestUrl(
8602
+ pullRequestNumber
8603
+ )}`
8202
8604
  );
8203
8605
  }
8204
8606
  calculatePrBranchName() {
@@ -8368,11 +8770,17 @@ var PlatformKit = class {
8368
8770
  get config() {
8369
8771
  const env = _zod2.default.object({
8370
8772
  LINGODOTDEV_API_KEY: _zod2.default.string(),
8371
- LINGODOTDEV_PULL_REQUEST: _zod2.default.preprocess((val) => val === "true" || val === true, _zod2.default.boolean()),
8773
+ LINGODOTDEV_PULL_REQUEST: _zod2.default.preprocess(
8774
+ (val) => val === "true" || val === true,
8775
+ _zod2.default.boolean()
8776
+ ),
8372
8777
  LINGODOTDEV_COMMIT_MESSAGE: _zod2.default.string().optional(),
8373
8778
  LINGODOTDEV_PULL_REQUEST_TITLE: _zod2.default.string().optional(),
8374
8779
  LINGODOTDEV_WORKING_DIRECTORY: _zod2.default.string().optional(),
8375
- LINGODOTDEV_PROCESS_OWN_COMMITS: _zod2.default.preprocess((val) => val === "true" || val === true, _zod2.default.boolean()).optional()
8780
+ LINGODOTDEV_PROCESS_OWN_COMMITS: _zod2.default.preprocess(
8781
+ (val) => val === "true" || val === true,
8782
+ _zod2.default.boolean()
8783
+ ).optional()
8376
8784
  }).parse(process.env);
8377
8785
  return {
8378
8786
  replexicaApiKey: env.LINGODOTDEV_API_KEY,
@@ -8410,10 +8818,10 @@ var BitbucketPlatformKit = class extends PlatformKit {
8410
8818
  repo_slug: this.platformConfig.repositoryName,
8411
8819
  state: "OPEN"
8412
8820
  }).then(({ data: { values } }) => {
8413
- return _optionalChain([values, 'optionalAccess', _236 => _236.find, 'call', _237 => _237(
8414
- ({ source, destination }) => _optionalChain([source, 'optionalAccess', _238 => _238.branch, 'optionalAccess', _239 => _239.name]) === branch && _optionalChain([destination, 'optionalAccess', _240 => _240.branch, 'optionalAccess', _241 => _241.name]) === this.platformConfig.baseBranchName
8821
+ return _optionalChain([values, 'optionalAccess', _243 => _243.find, 'call', _244 => _244(
8822
+ ({ source, destination }) => _optionalChain([source, 'optionalAccess', _245 => _245.branch, 'optionalAccess', _246 => _246.name]) === branch && _optionalChain([destination, 'optionalAccess', _247 => _247.branch, 'optionalAccess', _248 => _248.name]) === this.platformConfig.baseBranchName
8415
8823
  )]);
8416
- }).then((pr) => _optionalChain([pr, 'optionalAccess', _242 => _242.id]));
8824
+ }).then((pr) => _optionalChain([pr, 'optionalAccess', _249 => _249.id]));
8417
8825
  }
8418
8826
  async closePullRequest({ pullRequestNumber }) {
8419
8827
  await this.bb.repositories.declinePullRequest({
@@ -8509,7 +8917,7 @@ var GitHubPlatformKit = class extends PlatformKit {
8509
8917
  repo: this.platformConfig.repositoryName,
8510
8918
  base: this.platformConfig.baseBranchName,
8511
8919
  state: "open"
8512
- }).then(({ data }) => data[0]).then((pr) => _optionalChain([pr, 'optionalAccess', _243 => _243.number]));
8920
+ }).then(({ data }) => data[0]).then((pr) => _optionalChain([pr, 'optionalAccess', _250 => _250.number]));
8513
8921
  }
8514
8922
  async closePullRequest({ pullRequestNumber }) {
8515
8923
  await this.octokit.rest.pulls.update({
@@ -8636,7 +9044,7 @@ var GitlabPlatformKit = class extends PlatformKit {
8636
9044
  sourceBranch: branch,
8637
9045
  state: "opened"
8638
9046
  });
8639
- return _optionalChain([mergeRequests, 'access', _244 => _244[0], 'optionalAccess', _245 => _245.iid]);
9047
+ return _optionalChain([mergeRequests, 'access', _251 => _251[0], 'optionalAccess', _252 => _252.iid]);
8640
9048
  }
8641
9049
  async closePullRequest({
8642
9050
  pullRequestNumber
@@ -8726,7 +9134,7 @@ var ci_default = new (0, _interactivecommander.Command)().command("ci").descript
8726
9134
  }
8727
9135
  const env = {
8728
9136
  LINGODOTDEV_API_KEY: settings.auth.apiKey,
8729
- LINGODOTDEV_PULL_REQUEST: _optionalChain([options, 'access', _246 => _246.pullRequest, 'optionalAccess', _247 => _247.toString, 'call', _248 => _248()]) || "false",
9137
+ LINGODOTDEV_PULL_REQUEST: _optionalChain([options, 'access', _253 => _253.pullRequest, 'optionalAccess', _254 => _254.toString, 'call', _255 => _255()]) || "false",
8730
9138
  ...options.commitMessage && {
8731
9139
  LINGODOTDEV_COMMIT_MESSAGE: options.commitMessage
8732
9140
  },
@@ -8746,7 +9154,7 @@ var ci_default = new (0, _interactivecommander.Command)().command("ci").descript
8746
9154
  const { isPullRequestMode } = platformKit.config;
8747
9155
  ora.info(`Pull request mode: ${isPullRequestMode ? "on" : "off"}`);
8748
9156
  const flow = isPullRequestMode ? new PullRequestFlow(ora, platformKit) : new InBranchFlow(ora, platformKit);
8749
- const canRun = await _optionalChain([flow, 'access', _249 => _249.preRun, 'optionalCall', _250 => _250()]);
9157
+ const canRun = await _optionalChain([flow, 'access', _256 => _256.preRun, 'optionalCall', _257 => _257()]);
8750
9158
  if (canRun === false) {
8751
9159
  return;
8752
9160
  }
@@ -8756,7 +9164,7 @@ var ci_default = new (0, _interactivecommander.Command)().command("ci").descript
8756
9164
  if (!hasChanges) {
8757
9165
  return;
8758
9166
  }
8759
- await _optionalChain([flow, 'access', _251 => _251.postRun, 'optionalCall', _252 => _252()]);
9167
+ await _optionalChain([flow, 'access', _258 => _258.postRun, 'optionalCall', _259 => _259()]);
8760
9168
  });
8761
9169
  function parseBooleanArg(val) {
8762
9170
  if (val === true) return true;
@@ -8772,11 +9180,29 @@ function parseBooleanArg(val) {
8772
9180
 
8773
9181
 
8774
9182
 
9183
+
9184
+
9185
+
9186
+
8775
9187
  var _clitable3 = require('cli-table3'); var _clitable32 = _interopRequireDefault(_clitable3);
8776
- var status_default = new (0, _interactivecommander.Command)().command("status").description("Show the status of the localization process").helpOption("-h, --help", "Show help").option("--locale <locale>", "Locale to process", (val, prev) => prev ? [...prev, val] : [val]).option("--bucket <bucket>", "Bucket to process", (val, prev) => prev ? [...prev, val] : [val]).option(
9188
+ var status_default = new (0, _interactivecommander.Command)().command("status").description("Show the status of the localization process").helpOption("-h, --help", "Show help").option(
9189
+ "--locale <locale>",
9190
+ "Locale to process",
9191
+ (val, prev) => prev ? [...prev, val] : [val]
9192
+ ).option(
9193
+ "--bucket <bucket>",
9194
+ "Bucket to process",
9195
+ (val, prev) => prev ? [...prev, val] : [val]
9196
+ ).option(
8777
9197
  "--file [files...]",
8778
9198
  "File to process. Process only a specific path, may contain asterisk * to match multiple files."
8779
- ).option("--force", "Ignore lockfile and process all keys, useful for estimating full re-translation").option("--verbose", "Show detailed output including key-level word counts").option("--api-key <api-key>", "Explicitly set the API key to use, override the default API key from settings").action(async function(options) {
9199
+ ).option(
9200
+ "--force",
9201
+ "Ignore lockfile and process all keys, useful for estimating full re-translation"
9202
+ ).option("--verbose", "Show detailed output including key-level word counts").option(
9203
+ "--api-key <api-key>",
9204
+ "Explicitly set the API key to use, override the default API key from settings"
9205
+ ).action(async function(options) {
8780
9206
  const ora = _ora2.default.call(void 0, );
8781
9207
  const flags = parseFlags2(options);
8782
9208
  let authId = null;
@@ -8807,17 +9233,23 @@ var status_default = new (0, _interactivecommander.Command)().command("status").
8807
9233
  flags
8808
9234
  });
8809
9235
  let buckets = getBuckets(i18nConfig);
8810
- if (_optionalChain([flags, 'access', _253 => _253.bucket, 'optionalAccess', _254 => _254.length])) {
8811
- buckets = buckets.filter((bucket) => flags.bucket.includes(bucket.type));
9236
+ if (_optionalChain([flags, 'access', _260 => _260.bucket, 'optionalAccess', _261 => _261.length])) {
9237
+ buckets = buckets.filter(
9238
+ (bucket) => flags.bucket.includes(bucket.type)
9239
+ );
8812
9240
  }
8813
9241
  ora.succeed("Buckets retrieved");
8814
- if (_optionalChain([flags, 'access', _255 => _255.file, 'optionalAccess', _256 => _256.length])) {
9242
+ if (_optionalChain([flags, 'access', _262 => _262.file, 'optionalAccess', _263 => _263.length])) {
8815
9243
  buckets = buckets.map((bucket) => {
8816
- const paths = bucket.paths.filter((path17) => flags.file.find((file) => _optionalChain([path17, 'access', _257 => _257.pathPattern, 'optionalAccess', _258 => _258.match, 'call', _259 => _259(file)])));
9244
+ const paths = bucket.paths.filter(
9245
+ (path17) => flags.file.find((file) => _optionalChain([path17, 'access', _264 => _264.pathPattern, 'optionalAccess', _265 => _265.match, 'call', _266 => _266(file)]))
9246
+ );
8817
9247
  return { ...bucket, paths };
8818
9248
  }).filter((bucket) => bucket.paths.length > 0);
8819
9249
  if (buckets.length === 0) {
8820
- ora.fail("No buckets found. All buckets were filtered out by --file option.");
9250
+ ora.fail(
9251
+ "No buckets found. All buckets were filtered out by --file option."
9252
+ );
8821
9253
  process.exit(1);
8822
9254
  } else {
8823
9255
  ora.info(`\x1B[36mProcessing only filtered buckets:\x1B[0m`);
@@ -8829,7 +9261,7 @@ var status_default = new (0, _interactivecommander.Command)().command("status").
8829
9261
  });
8830
9262
  }
8831
9263
  }
8832
- const targetLocales = _optionalChain([flags, 'access', _260 => _260.locale, 'optionalAccess', _261 => _261.length]) ? flags.locale : i18nConfig.locale.targets;
9264
+ const targetLocales = _optionalChain([flags, 'access', _267 => _267.locale, 'optionalAccess', _268 => _268.length]) ? flags.locale : i18nConfig.locale.targets;
8833
9265
  let totalSourceKeyCount = 0;
8834
9266
  let uniqueKeysToTranslate = 0;
8835
9267
  let totalExistingTranslations = 0;
@@ -8850,13 +9282,17 @@ var status_default = new (0, _interactivecommander.Command)().command("status").
8850
9282
  console.log();
8851
9283
  ora.info(`Analyzing bucket: ${bucket.type}`);
8852
9284
  for (const bucketPath of bucket.paths) {
8853
- const bucketOra = _ora2.default.call(void 0, { indent: 2 }).info(`Analyzing path: ${bucketPath.pathPattern}`);
8854
- const sourceLocale = __spec.resolveOverriddenLocale.call(void 0, i18nConfig.locale.source, bucketPath.delimiter);
9285
+ const bucketOra = _ora2.default.call(void 0, { indent: 2 }).info(
9286
+ `Analyzing path: ${bucketPath.pathPattern}`
9287
+ );
9288
+ const sourceLocale = __spec.resolveOverriddenLocale.call(void 0,
9289
+ i18nConfig.locale.source,
9290
+ bucketPath.delimiter
9291
+ );
8855
9292
  const bucketLoader = createBucketLoader(
8856
9293
  bucket.type,
8857
9294
  bucketPath.pathPattern,
8858
9295
  {
8859
- isCacheRestore: false,
8860
9296
  defaultLocale: sourceLocale,
8861
9297
  injectLocale: bucket.injectLocale
8862
9298
  },
@@ -8895,8 +9331,13 @@ var status_default = new (0, _interactivecommander.Command)().command("status").
8895
9331
  }
8896
9332
  fileStats[filePath].wordCount = sourceWordCount;
8897
9333
  for (const _targetLocale of targetLocales) {
8898
- const targetLocale = __spec.resolveOverriddenLocale.call(void 0, _targetLocale, bucketPath.delimiter);
8899
- bucketOra.start(`[${sourceLocale} -> ${targetLocale}] Analyzing translation status...`);
9334
+ const targetLocale = __spec.resolveOverriddenLocale.call(void 0,
9335
+ _targetLocale,
9336
+ bucketPath.delimiter
9337
+ );
9338
+ bucketOra.start(
9339
+ `[${sourceLocale} -> ${targetLocale}] Analyzing translation status...`
9340
+ );
8900
9341
  let targetData = {};
8901
9342
  let fileExists = true;
8902
9343
  try {
@@ -8912,13 +9353,20 @@ var status_default = new (0, _interactivecommander.Command)().command("status").
8912
9353
  fileStats[filePath].languageStats[_targetLocale].words = sourceWordCount;
8913
9354
  languageStats[_targetLocale].missing += sourceKeys.length;
8914
9355
  languageStats[_targetLocale].words += sourceWordCount;
8915
- totalWordCount.set(_targetLocale, (totalWordCount.get(_targetLocale) || 0) + sourceWordCount);
9356
+ totalWordCount.set(
9357
+ _targetLocale,
9358
+ (totalWordCount.get(_targetLocale) || 0) + sourceWordCount
9359
+ );
8916
9360
  bucketOra.succeed(
8917
- `[${sourceLocale} -> ${targetLocale}] ${_chalk2.default.red(`0% complete`)} (0/${sourceKeys.length} keys) - file not found`
9361
+ `[${sourceLocale} -> ${targetLocale}] ${_chalk2.default.red(
9362
+ `0% complete`
9363
+ )} (0/${sourceKeys.length} keys) - file not found`
8918
9364
  );
8919
9365
  continue;
8920
9366
  }
8921
- const deltaProcessor = createDeltaProcessor(bucketPath.pathPattern);
9367
+ const deltaProcessor = createDeltaProcessor(
9368
+ bucketPath.pathPattern
9369
+ );
8922
9370
  const checksums = await deltaProcessor.loadChecksums();
8923
9371
  const delta = await deltaProcessor.calculateDelta({
8924
9372
  sourceData,
@@ -8927,7 +9375,9 @@ var status_default = new (0, _interactivecommander.Command)().command("status").
8927
9375
  });
8928
9376
  const missingKeys = delta.added;
8929
9377
  const updatedKeys = delta.updated;
8930
- const completeKeys = sourceKeys.filter((key) => !missingKeys.includes(key) && !updatedKeys.includes(key));
9378
+ const completeKeys = sourceKeys.filter(
9379
+ (key) => !missingKeys.includes(key) && !updatedKeys.includes(key)
9380
+ );
8931
9381
  let wordsToTranslate = 0;
8932
9382
  const keysToProcess = flags.force ? sourceKeys : [...missingKeys, ...updatedKeys];
8933
9383
  for (const key of keysToProcess) {
@@ -8945,25 +9395,39 @@ var status_default = new (0, _interactivecommander.Command)().command("status").
8945
9395
  languageStats[_targetLocale].updated += updatedKeys.length;
8946
9396
  languageStats[_targetLocale].complete += completeKeys.length;
8947
9397
  languageStats[_targetLocale].words += wordsToTranslate;
8948
- totalWordCount.set(_targetLocale, (totalWordCount.get(_targetLocale) || 0) + wordsToTranslate);
9398
+ totalWordCount.set(
9399
+ _targetLocale,
9400
+ (totalWordCount.get(_targetLocale) || 0) + wordsToTranslate
9401
+ );
8949
9402
  const totalKeysInFile = sourceKeys.length;
8950
9403
  const completionPercent = (completeKeys.length / totalKeysInFile * 100).toFixed(1);
8951
9404
  if (missingKeys.length === 0 && updatedKeys.length === 0) {
8952
9405
  bucketOra.succeed(
8953
- `[${sourceLocale} -> ${targetLocale}] ${_chalk2.default.green(`100% complete`)} (${completeKeys.length}/${totalKeysInFile} keys)`
9406
+ `[${sourceLocale} -> ${targetLocale}] ${_chalk2.default.green(
9407
+ `100% complete`
9408
+ )} (${completeKeys.length}/${totalKeysInFile} keys)`
8954
9409
  );
8955
9410
  } else {
8956
9411
  const message = `[${sourceLocale} -> ${targetLocale}] ${parseFloat(completionPercent) > 50 ? _chalk2.default.yellow(`${completionPercent}% complete`) : _chalk2.default.red(`${completionPercent}% complete`)} (${completeKeys.length}/${totalKeysInFile} keys)`;
8957
9412
  bucketOra.succeed(message);
8958
9413
  if (flags.verbose) {
8959
9414
  if (missingKeys.length > 0) {
8960
- console.log(` ${_chalk2.default.red(`Missing:`)} ${missingKeys.length} keys, ~${wordsToTranslate} words`);
8961
9415
  console.log(
8962
- ` ${_chalk2.default.dim(`Example missing: ${missingKeys.slice(0, 2).join(", ")}${missingKeys.length > 2 ? "..." : ""}`)}`
9416
+ ` ${_chalk2.default.red(`Missing:`)} ${missingKeys.length} keys, ~${wordsToTranslate} words`
9417
+ );
9418
+ console.log(
9419
+ ` ${_chalk2.default.red(`Missing:`)} ${missingKeys.length} keys, ~${wordsToTranslate} words`
9420
+ );
9421
+ console.log(
9422
+ ` ${_chalk2.default.dim(
9423
+ `Example missing: ${missingKeys.slice(0, 2).join(", ")}${missingKeys.length > 2 ? "..." : ""}`
9424
+ )}`
8963
9425
  );
8964
9426
  }
8965
9427
  if (updatedKeys.length > 0) {
8966
- console.log(` ${_chalk2.default.yellow(`Updated:`)} ${updatedKeys.length} keys that changed in source`);
9428
+ console.log(
9429
+ ` ${_chalk2.default.yellow(`Updated:`)} ${updatedKeys.length} keys that changed in source`
9430
+ );
8967
9431
  }
8968
9432
  }
8969
9433
  }
@@ -8973,9 +9437,12 @@ var status_default = new (0, _interactivecommander.Command)().command("status").
8973
9437
  ora.fail(`Failed to analyze bucket ${bucket.type}: ${error.message}`);
8974
9438
  }
8975
9439
  }
8976
- const totalKeysNeedingTranslation = Object.values(languageStats).reduce((sum, stats) => {
8977
- return sum + stats.missing + stats.updated;
8978
- }, 0);
9440
+ const totalKeysNeedingTranslation = Object.values(languageStats).reduce(
9441
+ (sum, stats) => {
9442
+ return sum + stats.missing + stats.updated;
9443
+ },
9444
+ 0
9445
+ );
8979
9446
  const totalCompletedKeys = totalSourceKeyCount - totalKeysNeedingTranslation / targetLocales.length;
8980
9447
  console.log();
8981
9448
  ora.succeed(_chalk2.default.green(`Localization status completed.`));
@@ -8985,12 +9452,26 @@ var status_default = new (0, _interactivecommander.Command)().command("status").
8985
9452
  console.log(_chalk2.default.bold.cyan(`\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D`));
8986
9453
  console.log(_chalk2.default.bold(`
8987
9454
  \u{1F4DD} SOURCE CONTENT:`));
8988
- console.log(`\u2022 Source language: ${_chalk2.default.green(i18nConfig.locale.source)}`);
8989
- console.log(`\u2022 Source keys: ${_chalk2.default.yellow(totalSourceKeyCount.toString())} keys across all files`);
9455
+ console.log(
9456
+ `\u2022 Source language: ${_chalk2.default.green(i18nConfig.locale.source)}`
9457
+ );
9458
+ console.log(
9459
+ `\u2022 Source keys: ${_chalk2.default.yellow(
9460
+ totalSourceKeyCount.toString()
9461
+ )} keys across all files`
9462
+ );
8990
9463
  console.log(_chalk2.default.bold(`
8991
9464
  \u{1F310} LANGUAGE BY LANGUAGE BREAKDOWN:`));
8992
9465
  const table = new (0, _clitable32.default)({
8993
- head: ["Language", "Status", "Complete", "Missing", "Updated", "Total Keys", "Words to Translate"],
9466
+ head: [
9467
+ "Language",
9468
+ "Status",
9469
+ "Complete",
9470
+ "Missing",
9471
+ "Updated",
9472
+ "Total Keys",
9473
+ "Words to Translate"
9474
+ ],
8994
9475
  style: {
8995
9476
  head: ["white"],
8996
9477
  // White color for headers
@@ -9039,15 +9520,21 @@ var status_default = new (0, _interactivecommander.Command)().command("status").
9039
9520
  console.log(_chalk2.default.bold(`
9040
9521
  \u{1F4CA} USAGE ESTIMATE:`));
9041
9522
  console.log(
9042
- `\u2022 WORDS TO BE CONSUMED: ~${_chalk2.default.yellow.bold(totalWordsToTranslate.toLocaleString())} words across all languages`
9523
+ `\u2022 WORDS TO BE CONSUMED: ~${_chalk2.default.yellow.bold(
9524
+ totalWordsToTranslate.toLocaleString()
9525
+ )} words across all languages`
9526
+ );
9527
+ console.log(
9528
+ ` (Words are counted from source language for keys that need translation in target languages)`
9043
9529
  );
9044
- console.log(` (Words are counted from source language for keys that need translation in target languages)`);
9045
9530
  if (targetLocales.length > 1) {
9046
9531
  console.log(`\u2022 Per-language breakdown:`);
9047
9532
  for (const locale of targetLocales) {
9048
9533
  const words = totalWordCount.get(locale) || 0;
9049
9534
  const percent = (words / totalWordsToTranslate * 100).toFixed(1);
9050
- console.log(` - ${locale}: ~${words.toLocaleString()} words (${percent}% of total)`);
9535
+ console.log(
9536
+ ` - ${locale}: ~${words.toLocaleString()} words (${percent}% of total)`
9537
+ );
9051
9538
  }
9052
9539
  }
9053
9540
  if (flags.confirm && Object.keys(fileStats).length > 0) {
@@ -9057,7 +9544,9 @@ var status_default = new (0, _interactivecommander.Command)().command("status").
9057
9544
  if (stats.sourceKeys === 0) return;
9058
9545
  console.log(_chalk2.default.bold(`
9059
9546
  \u2022 ${path17}:`));
9060
- console.log(` ${stats.sourceKeys} source keys, ~${stats.wordCount.toLocaleString()} source words`);
9547
+ console.log(
9548
+ ` ${stats.sourceKeys} source keys, ~${stats.wordCount.toLocaleString()} source words`
9549
+ );
9061
9550
  const fileTable = new (0, _clitable32.default)({
9062
9551
  head: ["Language", "Status", "Details"],
9063
9552
  style: {
@@ -9084,8 +9573,10 @@ var status_default = new (0, _interactivecommander.Command)().command("status").
9084
9573
  let details = "";
9085
9574
  if (langStats.missing > 0 || langStats.updated > 0) {
9086
9575
  const parts = [];
9087
- if (langStats.missing > 0) parts.push(`${langStats.missing} missing`);
9088
- if (langStats.updated > 0) parts.push(`${langStats.updated} changed`);
9576
+ if (langStats.missing > 0)
9577
+ parts.push(`${langStats.missing} missing`);
9578
+ if (langStats.updated > 0)
9579
+ parts.push(`${langStats.updated} changed`);
9089
9580
  details = `${parts.join(", ")}, ~${langStats.words} words`;
9090
9581
  } else {
9091
9582
  details = "All keys translated";
@@ -9098,7 +9589,9 @@ var status_default = new (0, _interactivecommander.Command)().command("status").
9098
9589
  const completeLanguages = targetLocales.filter(
9099
9590
  (locale) => languageStats[locale].missing === 0 && languageStats[locale].updated === 0
9100
9591
  );
9101
- const missingLanguages = targetLocales.filter((locale) => languageStats[locale].complete === 0);
9592
+ const missingLanguages = targetLocales.filter(
9593
+ (locale) => languageStats[locale].complete === 0
9594
+ );
9102
9595
  console.log(_chalk2.default.bold.green(`
9103
9596
  \u{1F4A1} OPTIMIZATION TIPS:`));
9104
9597
  if (missingLanguages.length > 0) {
@@ -9113,7 +9606,9 @@ var status_default = new (0, _interactivecommander.Command)().command("status").
9113
9606
  }
9114
9607
  if (targetLocales.length > 1) {
9115
9608
  console.log(`\u2022 Translating one language at a time reduces complexity`);
9116
- console.log(`\u2022 Try 'lingo.dev@latest i18n --locale ${targetLocales[0]}' to process just one language`);
9609
+ console.log(
9610
+ `\u2022 Try 'lingo.dev@latest i18n --locale ${targetLocales[0]}' to process just one language`
9611
+ );
9117
9612
  }
9118
9613
  trackEvent(authId || "status", "cmd.status.success", {
9119
9614
  i18nConfig,
@@ -9170,12 +9665,14 @@ function validateParams2(i18nConfig, flags) {
9170
9665
  message: "No buckets found in i18n.json. Please add at least one bucket containing i18n content.",
9171
9666
  docUrl: "bucketNotFound"
9172
9667
  });
9173
- } else if (_optionalChain([flags, 'access', _262 => _262.locale, 'optionalAccess', _263 => _263.some, 'call', _264 => _264((locale) => !i18nConfig.locale.targets.includes(locale))])) {
9668
+ } else if (_optionalChain([flags, 'access', _269 => _269.locale, 'optionalAccess', _270 => _270.some, 'call', _271 => _271((locale) => !i18nConfig.locale.targets.includes(locale))])) {
9174
9669
  throw new CLIError({
9175
9670
  message: `One or more specified locales do not exist in i18n.json locale.targets. Please add them to the list and try again.`,
9176
9671
  docUrl: "localeTargetNotFound"
9177
9672
  });
9178
- } else if (_optionalChain([flags, 'access', _265 => _265.bucket, 'optionalAccess', _266 => _266.some, 'call', _267 => _267((bucket) => !i18nConfig.buckets[bucket])])) {
9673
+ } else if (_optionalChain([flags, 'access', _272 => _272.bucket, 'optionalAccess', _273 => _273.some, 'call', _274 => _274(
9674
+ (bucket) => !i18nConfig.buckets[bucket]
9675
+ )])) {
9179
9676
  throw new CLIError({
9180
9677
  message: `One or more specified buckets do not exist in i18n.json. Please add them to the list and try again.`,
9181
9678
  docUrl: "bucketNotFound"
@@ -9220,7 +9717,9 @@ var may_the_fourth_default = new (0, _interactivecommander.Command)().command("m
9220
9717
  });
9221
9718
  await renderSpacer2();
9222
9719
  console.log(
9223
- `${_chalk2.default.hex(colors2.green)("We hope you enjoyed it! :)")} ${_chalk2.default.hex(colors2.blue)("May the Fourth be with you! \u{1F680}")}`
9720
+ `${_chalk2.default.hex(colors2.green)("We hope you enjoyed it! :)")} ${_chalk2.default.hex(
9721
+ colors2.blue
9722
+ )("May the Fourth be with you! \u{1F680}")}`
9224
9723
  );
9225
9724
  await renderSpacer2();
9226
9725
  console.log(_chalk2.default.dim(`---`));
@@ -9246,7 +9745,9 @@ async function renderBanner2() {
9246
9745
  }
9247
9746
  async function renderHero2() {
9248
9747
  console.log(
9249
- `\u26A1\uFE0F ${_chalk2.default.hex(colors2.green)("Lingo.dev")} - open-source, AI-powered i18n CLI for web & mobile localization.`
9748
+ `\u26A1\uFE0F ${_chalk2.default.hex(colors2.green)(
9749
+ "Lingo.dev"
9750
+ )} - open-source, AI-powered i18n CLI for web & mobile localization.`
9250
9751
  );
9251
9752
  console.log(" ");
9252
9753
  console.log(
@@ -9258,7 +9759,7 @@ async function renderHero2() {
9258
9759
  // package.json
9259
9760
  var package_default = {
9260
9761
  name: "lingo.dev",
9261
- version: "0.100.0",
9762
+ version: "0.101.0",
9262
9763
  description: "Lingo.dev CLI",
9263
9764
  private: false,
9264
9765
  publishConfig: {
@@ -9372,6 +9873,7 @@ var package_default = {
9372
9873
  dependencies: {
9373
9874
  "@ai-sdk/anthropic": "^1.2.11",
9374
9875
  "@ai-sdk/google": "^1.2.19",
9876
+ "@ai-sdk/mistral": "^1.2.8",
9375
9877
  "@ai-sdk/openai": "^1.3.22",
9376
9878
  "@babel/generator": "^7.27.1",
9377
9879
  "@babel/parser": "^7.27.1",
@@ -9488,6 +9990,167 @@ var package_default = {
9488
9990
  packageManager: "pnpm@9.12.3"
9489
9991
  };
9490
9992
 
9993
+ // src/cli/cmd/purge.ts
9994
+
9995
+
9996
+
9997
+
9998
+ var purge_default = new (0, _interactivecommander.Command)().command("purge").description(
9999
+ "Remove translations for given --bucket, --file, --key, --locale"
10000
+ ).helpOption("-h, --help", "Show help").option(
10001
+ "--bucket <bucket>",
10002
+ "Bucket to process",
10003
+ (val, prev) => prev ? [...prev, val] : [val]
10004
+ ).option(
10005
+ "--file [files...]",
10006
+ "File(s) to process. Only process files that match the given glob pattern(s)."
10007
+ ).option(
10008
+ "--key <key>",
10009
+ "Key to remove. Remove all translation keys matching the given glob pattern."
10010
+ ).option(
10011
+ "--locale <locale>",
10012
+ "Locale to process",
10013
+ (val, prev) => prev ? [...prev, val] : [val]
10014
+ ).option(
10015
+ "--yes-really",
10016
+ "Skip interactive confirmation and delete without asking."
10017
+ ).action(async function(options) {
10018
+ const ora = _ora2.default.call(void 0, );
10019
+ try {
10020
+ ora.start("Loading configuration...");
10021
+ const i18nConfig = getConfig();
10022
+ if (!i18nConfig) {
10023
+ throw new Error("i18n.json not found. Please run `lingo.dev init`.");
10024
+ }
10025
+ ora.succeed("Configuration loaded");
10026
+ let buckets = getBuckets(i18nConfig);
10027
+ if (options.bucket && options.bucket.length) {
10028
+ buckets = buckets.filter(
10029
+ (bucket) => options.bucket.includes(bucket.type)
10030
+ );
10031
+ }
10032
+ if (options.file && options.file.length) {
10033
+ buckets = buckets.map((bucket) => {
10034
+ const paths = bucket.paths.filter(
10035
+ (bucketPath) => _optionalChain([options, 'access', _275 => _275.file, 'optionalAccess', _276 => _276.some, 'call', _277 => _277((f) => bucketPath.pathPattern.includes(f))])
10036
+ );
10037
+ return { ...bucket, paths };
10038
+ }).filter((bucket) => bucket.paths.length > 0);
10039
+ if (buckets.length === 0) {
10040
+ ora.fail("All files were filtered out by --file option.");
10041
+ process.exit(1);
10042
+ }
10043
+ }
10044
+ const sourceLocale = i18nConfig.locale.source;
10045
+ const targetLocales = options.locale && options.locale.length ? options.locale : i18nConfig.locale.targets;
10046
+ let removedAny = false;
10047
+ for (const bucket of buckets) {
10048
+ console.log();
10049
+ ora.info(`Processing bucket: ${bucket.type}`);
10050
+ for (const bucketPath of bucket.paths) {
10051
+ for (const _targetLocale of targetLocales) {
10052
+ const targetLocale = __spec.resolveOverriddenLocale.call(void 0,
10053
+ _targetLocale,
10054
+ bucketPath.delimiter
10055
+ );
10056
+ const bucketOra = _ora2.default.call(void 0, { indent: 2 }).start(
10057
+ `Processing path: ${bucketPath.pathPattern} [${targetLocale}]`
10058
+ );
10059
+ try {
10060
+ const bucketLoader = createBucketLoader(
10061
+ bucket.type,
10062
+ bucketPath.pathPattern,
10063
+ {
10064
+ defaultLocale: sourceLocale,
10065
+ injectLocale: bucket.injectLocale
10066
+ },
10067
+ bucket.lockedKeys,
10068
+ bucket.lockedPatterns,
10069
+ bucket.ignoredKeys
10070
+ );
10071
+ await bucketLoader.init();
10072
+ bucketLoader.setDefaultLocale(sourceLocale);
10073
+ await bucketLoader.pull(sourceLocale);
10074
+ let targetData = await bucketLoader.pull(targetLocale);
10075
+ if (!targetData || Object.keys(targetData).length === 0) {
10076
+ bucketOra.info(
10077
+ `No translations found for ${bucketPath.pathPattern} [${targetLocale}]`
10078
+ );
10079
+ continue;
10080
+ }
10081
+ let newData = { ...targetData };
10082
+ let keysToRemove = [];
10083
+ if (options.key) {
10084
+ keysToRemove = Object.keys(newData).filter(
10085
+ (k) => minimatch(k, options.key)
10086
+ );
10087
+ } else {
10088
+ keysToRemove = Object.keys(newData);
10089
+ }
10090
+ if (keysToRemove.length > 0) {
10091
+ if (options.key) {
10092
+ bucketOra.info(
10093
+ `About to delete ${keysToRemove.length} key(s) matching '${options.key}' from ${bucketPath.pathPattern} [${targetLocale}]:
10094
+ ${keysToRemove.slice(0, 10).join(", ")}${keysToRemove.length > 10 ? ", ..." : ""}`
10095
+ );
10096
+ } else {
10097
+ bucketOra.info(
10098
+ `About to delete all (${keysToRemove.length}) keys from ${bucketPath.pathPattern} [${targetLocale}]`
10099
+ );
10100
+ }
10101
+ if (!options.yesReally) {
10102
+ bucketOra.warn(
10103
+ "This is a destructive operation. If you are sure, type 'y' to continue. (Use --yes-really to skip this check.)"
10104
+ );
10105
+ const confirmed = await _prompts.confirm.call(void 0, {
10106
+ message: `Delete these keys from ${bucketPath.pathPattern} [${targetLocale}]?`,
10107
+ default: false
10108
+ });
10109
+ if (!confirmed) {
10110
+ bucketOra.info("Skipped by user.");
10111
+ continue;
10112
+ }
10113
+ }
10114
+ for (const key of keysToRemove) {
10115
+ delete newData[key];
10116
+ }
10117
+ removedAny = true;
10118
+ await bucketLoader.push(targetLocale, newData);
10119
+ if (options.key) {
10120
+ bucketOra.succeed(
10121
+ `Removed ${keysToRemove.length} key(s) matching '${options.key}' from ${bucketPath.pathPattern} [${targetLocale}]`
10122
+ );
10123
+ } else {
10124
+ bucketOra.succeed(
10125
+ `Removed all keys (${keysToRemove.length}) from ${bucketPath.pathPattern} [${targetLocale}]`
10126
+ );
10127
+ }
10128
+ } else if (options.key) {
10129
+ bucketOra.info(
10130
+ `No keys matching '${options.key}' found in ${bucketPath.pathPattern} [${targetLocale}]`
10131
+ );
10132
+ } else {
10133
+ bucketOra.info("No keys to remove.");
10134
+ }
10135
+ } catch (error) {
10136
+ const err = error;
10137
+ bucketOra.fail(`Failed: ${err.message}`);
10138
+ }
10139
+ }
10140
+ }
10141
+ }
10142
+ if (!removedAny) {
10143
+ ora.info("No keys were removed.");
10144
+ } else {
10145
+ ora.succeed("Purge completed.");
10146
+ }
10147
+ } catch (error) {
10148
+ const err = error;
10149
+ ora.fail(err.message);
10150
+ process.exit(1);
10151
+ }
10152
+ });
10153
+
9491
10154
  // src/cli/index.ts
9492
10155
  _dotenv2.default.config();
9493
10156
  var cli_default = new (0, _interactivecommander.InteractiveCommand)().name("lingo.dev").description("Lingo.dev CLI").helpOption("-h, --help", "Show help").addHelpText(
@@ -9505,7 +10168,7 @@ ${_gradientstring.vice.call(void 0,
9505
10168
 
9506
10169
  Star the the repo :) https://github.com/LingoDotDev/lingo.dev
9507
10170
  `
9508
- ).version(`v${package_default.version}`, "-v, --version", "Show version").addCommand(init_default).interactive("-y, --no-interactive", "Disable interactive mode").addCommand(i18n_default).addCommand(auth_default).addCommand(login_default).addCommand(logout_default).addCommand(show_default).addCommand(config_default2).addCommand(lockfile_default).addCommand(cleanup_default).addCommand(mcp_default).addCommand(ci_default).addCommand(status_default).addCommand(may_the_fourth_default, { hidden: true }).addCommand(run_default, { hidden: true }).exitOverride((err) => {
10171
+ ).version(`v${package_default.version}`, "-v, --version", "Show version").addCommand(init_default).interactive("-y, --no-interactive", "Disable interactive mode").addCommand(i18n_default).addCommand(auth_default).addCommand(login_default).addCommand(logout_default).addCommand(show_default).addCommand(config_default2).addCommand(lockfile_default).addCommand(cleanup_default).addCommand(mcp_default).addCommand(ci_default).addCommand(status_default).addCommand(may_the_fourth_default, { hidden: true }).addCommand(run_default).addCommand(purge_default).exitOverride((err) => {
9509
10172
  if (err.code === "commander.helpDisplayed" || err.code === "commander.version" || err.code === "commander.help") {
9510
10173
  process.exit(0);
9511
10174
  }