lingo.dev 0.112.0 → 0.113.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.mjs CHANGED
@@ -1277,7 +1277,7 @@ var init_default = new InteractiveCommand().command("init").description("Create
1277
1277
  });
1278
1278
 
1279
1279
  // src/cli/cmd/show/index.ts
1280
- import { Command as Command7 } from "interactive-commander";
1280
+ import { Command as Command9 } from "interactive-commander";
1281
1281
 
1282
1282
  // src/cli/cmd/show/config.ts
1283
1283
  import { Command as Command4 } from "interactive-commander";
@@ -1539,150 +1539,13 @@ var files_default = new Command6().command("files").description(
1539
1539
  }
1540
1540
  });
1541
1541
 
1542
- // src/cli/cmd/show/index.ts
1543
- var show_default = new Command7().command("show").description("Display configuration, locales, and file paths").helpOption("-h, --help", "Show help").addCommand(config_default).addCommand(locale_default).addCommand(files_default);
1544
-
1545
- // src/cli/cmd/config/index.ts
1546
- import { Command as Command11 } from "interactive-commander";
1547
-
1548
- // src/cli/cmd/config/set.ts
1549
- import { Command as Command8 } from "interactive-commander";
1550
- import chalk2 from "chalk";
1551
- import dedent from "dedent";
1552
- import _6 from "lodash";
1553
- var set_default = new Command8().name("set").description("Set or update a CLI setting in ~/.lingodotdevrc").addHelpText("afterAll", `
1554
- Available keys:
1555
- ${SETTINGS_KEYS.join("\n ")}`).argument(
1556
- "<key>",
1557
- "Configuration key to set (dot notation, e.g., auth.apiKey)"
1558
- ).argument("<value>", "The configuration value to set").helpOption("-h, --help", "Show help").action(async (key, value) => {
1559
- if (!SETTINGS_KEYS.includes(key)) {
1560
- console.error(
1561
- dedent`
1562
- ${chalk2.red("\u2716")} Unknown configuration key: ${chalk2.bold(key)}
1563
- Run ${chalk2.dim("lingo.dev config set --help")} to see available keys.
1564
- `
1565
- );
1566
- process.exitCode = 1;
1567
- return;
1568
- }
1569
- const current = loadSystemSettings();
1570
- const updated = _6.cloneDeep(current);
1571
- _6.set(updated, key, value);
1572
- try {
1573
- saveSettings(updated);
1574
- console.log(`${chalk2.green("\u2714")} Set ${chalk2.bold(key)}`);
1575
- } catch (err) {
1576
- console.error(
1577
- chalk2.red(
1578
- `\u2716 Failed to save configuration: ${chalk2.dim(
1579
- err instanceof Error ? err.message : String(err)
1580
- )}`
1581
- )
1582
- );
1583
- process.exitCode = 1;
1584
- }
1585
- });
1586
-
1587
- // src/cli/cmd/config/unset.ts
1588
- import { Command as Command9 } from "interactive-commander";
1589
- import chalk3 from "chalk";
1590
- import dedent2 from "dedent";
1591
- import _7 from "lodash";
1592
- var unset_default = new Command9().name("unset").description("Remove a CLI setting from ~/.lingodotdevrc").addHelpText("afterAll", `
1593
- Available keys:
1594
- ${SETTINGS_KEYS.join("\n ")}`).argument(
1595
- "<key>",
1596
- "Configuration key to remove (must match one of the available keys listed below)"
1597
- ).helpOption("-h, --help", "Show help").action(async (key) => {
1598
- if (!SETTINGS_KEYS.includes(key)) {
1599
- console.error(
1600
- dedent2`
1601
- ${chalk3.red("\u2716")} Unknown configuration key: ${chalk3.bold(key)}
1602
- Run ${chalk3.dim(
1603
- "lingo.dev config unset --help"
1604
- )} to see available keys.
1605
- `
1606
- );
1607
- process.exitCode = 1;
1608
- return;
1609
- }
1610
- const settings = loadSystemSettings();
1611
- const currentValue = _7.get(settings, key);
1612
- if (!_7.trim(String(currentValue || ""))) {
1613
- console.log(`${chalk3.cyan("\u2139")} ${chalk3.bold(key)} is not set.`);
1614
- return;
1615
- } else {
1616
- const updated = _7.cloneDeep(settings);
1617
- _7.unset(updated, key);
1618
- try {
1619
- saveSettings(updated);
1620
- console.log(
1621
- `${chalk3.green("\u2714")} Removed configuration key ${chalk3.bold(key)}`
1622
- );
1623
- } catch (err) {
1624
- console.error(
1625
- chalk3.red(
1626
- `\u2716 Failed to save configuration: ${chalk3.dim(
1627
- err instanceof Error ? err.message : String(err)
1628
- )}`
1629
- )
1630
- );
1631
- process.exitCode = 1;
1632
- }
1633
- }
1634
- });
1635
-
1636
- // src/cli/cmd/config/get.ts
1637
- import { Command as Command10 } from "interactive-commander";
1638
- import chalk4 from "chalk";
1639
- import _8 from "lodash";
1640
- import dedent3 from "dedent";
1641
- var get_default = new Command10().name("get").description("Display the value of a CLI setting from ~/.lingodotdevrc").addHelpText("afterAll", `
1642
- Available keys:
1643
- ${SETTINGS_KEYS.join("\n ")}`).argument(
1644
- "<key>",
1645
- "Configuration key to read (choose from the available keys listed below)"
1646
- ).helpOption("-h, --help", "Show help").action(async (key) => {
1647
- if (!SETTINGS_KEYS.includes(key)) {
1648
- console.error(
1649
- dedent3`
1650
- ${chalk4.red("\u2716")} Unknown configuration key: ${chalk4.bold(key)}
1651
- Run ${chalk4.dim("lingo.dev config get --help")} to see available keys.
1652
- `
1653
- );
1654
- process.exitCode = 1;
1655
- return;
1656
- }
1657
- const settings = loadSystemSettings();
1658
- const value = _8.get(settings, key);
1659
- if (!value) {
1660
- console.log(`${chalk4.cyan("\u2139")} ${chalk4.bold(key)} is not set.`);
1661
- return;
1662
- }
1663
- if (typeof value === "object") {
1664
- console.log(JSON.stringify(value, null, 2));
1665
- } else {
1666
- console.log(value);
1667
- }
1668
- });
1669
-
1670
- // src/cli/cmd/config/index.ts
1671
- var config_default2 = new Command11().command("config").description(
1672
- "Manage CLI settings (authentication, API keys) stored in ~/.lingodotdevrc"
1673
- ).helpOption("-h, --help", "Show help").addCommand(set_default).addCommand(unset_default).addCommand(get_default);
1674
-
1675
- // src/cli/cmd/i18n.ts
1676
- import {
1677
- bucketTypeSchema,
1678
- localeCodeSchema,
1679
- resolveOverriddenLocale as resolveOverriddenLocale3
1680
- } from "@lingo.dev/_spec";
1681
- import { Command as Command12 } from "interactive-commander";
1682
- import Z3 from "zod";
1683
- import _31 from "lodash";
1542
+ // src/cli/cmd/show/locked-keys.ts
1543
+ import { Command as Command7 } from "interactive-commander";
1684
1544
  import Ora7 from "ora";
1685
1545
 
1546
+ // src/cli/cmd/show/_shared-key-command.ts
1547
+ import { resolveOverriddenLocale as resolveOverriddenLocale3 } from "@lingo.dev/_spec";
1548
+
1686
1549
  // src/cli/loaders/_utils.ts
1687
1550
  function composeLoaders(...loaders) {
1688
1551
  return {
@@ -2009,7 +1872,7 @@ function createJsoncLoader() {
2009
1872
 
2010
1873
  // src/cli/loaders/flat.ts
2011
1874
  import { flatten, unflatten } from "flat";
2012
- import _9 from "lodash";
1875
+ import _6 from "lodash";
2013
1876
  var OBJECT_NUMERIC_KEY_PREFIX = "__lingodotdev__obj__";
2014
1877
  function createFlatLoader() {
2015
1878
  const composedLoader = composeLoaders(
@@ -2088,12 +1951,12 @@ function mapDenormalizedKeys(obj, denormalizedKeysMap) {
2088
1951
  );
2089
1952
  }
2090
1953
  function denormalizeObjectKeys(obj) {
2091
- if (_9.isObject(obj) && !_9.isArray(obj)) {
2092
- return _9.transform(
1954
+ if (_6.isObject(obj) && !_6.isArray(obj)) {
1955
+ return _6.transform(
2093
1956
  obj,
2094
1957
  (result, value, key) => {
2095
1958
  const newKey = !isNaN(Number(key)) ? `${OBJECT_NUMERIC_KEY_PREFIX}${key}` : key;
2096
- result[newKey] = _9.isObject(value) && !_9.isDate(value) ? denormalizeObjectKeys(value) : value;
1959
+ result[newKey] = _6.isObject(value) && !_6.isDate(value) ? denormalizeObjectKeys(value) : value;
2097
1960
  },
2098
1961
  {}
2099
1962
  );
@@ -2102,12 +1965,12 @@ function denormalizeObjectKeys(obj) {
2102
1965
  }
2103
1966
  }
2104
1967
  function normalizeObjectKeys(obj) {
2105
- if (_9.isObject(obj) && !_9.isArray(obj)) {
2106
- return _9.transform(
1968
+ if (_6.isObject(obj) && !_6.isArray(obj)) {
1969
+ return _6.transform(
2107
1970
  obj,
2108
1971
  (result, value, key) => {
2109
1972
  const newKey = `${key}`.replace(OBJECT_NUMERIC_KEY_PREFIX, "");
2110
- result[newKey] = _9.isObject(value) && !_9.isDate(value) ? normalizeObjectKeys(value) : value;
1973
+ result[newKey] = _6.isObject(value) && !_6.isDate(value) ? normalizeObjectKeys(value) : value;
2111
1974
  },
2112
1975
  {}
2113
1976
  );
@@ -2118,14 +1981,14 @@ function normalizeObjectKeys(obj) {
2118
1981
  function flattenHints(obj, parentHints = [], parentPath = "") {
2119
1982
  const result = {};
2120
1983
  for (const [key, _value] of Object.entries(obj)) {
2121
- if (_9.isObject(_value) && !_9.isArray(_value)) {
1984
+ if (_6.isObject(_value) && !_6.isArray(_value)) {
2122
1985
  const value = _value;
2123
1986
  const currentHints = [...parentHints];
2124
1987
  const currentPath = parentPath ? `${parentPath}/${key}` : key;
2125
1988
  if (value.hint && typeof value.hint === "string") {
2126
1989
  currentHints.push(value.hint);
2127
1990
  }
2128
- const nestedObj = _9.omit(value, "hint");
1991
+ const nestedObj = _6.omit(value, "hint");
2129
1992
  if (Object.keys(nestedObj).length === 0) {
2130
1993
  if (currentHints.length > 0) {
2131
1994
  result[currentPath] = currentHints;
@@ -2153,7 +2016,7 @@ function createTextFileLoader(pathPattern) {
2153
2016
  const trimmedResult = result.trim();
2154
2017
  return trimmedResult;
2155
2018
  },
2156
- async push(locale, data, _35, originalLocale) {
2019
+ async push(locale, data, _36, originalLocale) {
2157
2020
  const draftPath = pathPattern.replaceAll("[locale]", locale);
2158
2021
  const finalPath = path10.resolve(draftPath);
2159
2022
  const dirPath = path10.dirname(finalPath);
@@ -2253,19 +2116,19 @@ function createRootKeyLoader(replaceAll = false) {
2253
2116
  }
2254
2117
 
2255
2118
  // src/cli/loaders/flutter.ts
2256
- import _10 from "lodash";
2119
+ import _7 from "lodash";
2257
2120
  function createFlutterLoader() {
2258
2121
  return createLoader({
2259
2122
  async pull(locale, input2) {
2260
- const result = _10.pickBy(input2, (value, key) => !_isMetadataKey(key));
2123
+ const result = _7.pickBy(input2, (value, key) => !_isMetadataKey(key));
2261
2124
  return result;
2262
2125
  },
2263
2126
  async push(locale, data, originalInput) {
2264
- const metadata = _10.pickBy(
2127
+ const metadata = _7.pickBy(
2265
2128
  originalInput,
2266
2129
  (value, key) => _isMetadataKey(key)
2267
2130
  );
2268
- const result = _10.merge({}, metadata, { "@@locale": locale }, data);
2131
+ const result = _7.merge({}, metadata, { "@@locale": locale }, data);
2269
2132
  return result;
2270
2133
  }
2271
2134
  });
@@ -2455,7 +2318,7 @@ function createAndroidLoader() {
2455
2318
  // src/cli/loaders/csv.ts
2456
2319
  import { parse as parse2 } from "csv-parse/sync";
2457
2320
  import { stringify } from "csv-stringify/sync";
2458
- import _11 from "lodash";
2321
+ import _8 from "lodash";
2459
2322
  function detectKeyColumnName(csvString) {
2460
2323
  const row = parse2(csvString)[0];
2461
2324
  const firstColumn = row?.[0]?.trim();
@@ -2476,7 +2339,7 @@ function _createCsvLoader() {
2476
2339
  relax_column_count_less: true
2477
2340
  });
2478
2341
  const items = {};
2479
- _11.forEach(inputParsed, (row) => {
2342
+ _8.forEach(inputParsed, (row) => {
2480
2343
  const key = row[keyColumnName];
2481
2344
  if (key && row[locale] && row[locale].trim() !== "") {
2482
2345
  items[key] = row[locale];
@@ -2859,7 +2722,7 @@ function createPropertiesLoader() {
2859
2722
  return result;
2860
2723
  },
2861
2724
  async push(locale, payload) {
2862
- const result = Object.entries(payload).filter(([_35, value]) => value != null).map(([key, value]) => `${key}=${value}`).join("\n");
2725
+ const result = Object.entries(payload).filter(([_36, value]) => value != null).map(([key, value]) => `${key}=${value}`).join("\n");
2863
2726
  return result;
2864
2727
  }
2865
2728
  });
@@ -2945,7 +2808,7 @@ function createXcodeStringsdictLoader() {
2945
2808
  }
2946
2809
 
2947
2810
  // src/cli/loaders/xcode-xcstrings.ts
2948
- import _12 from "lodash";
2811
+ import _9 from "lodash";
2949
2812
  function createXcodeXcstringsLoader(defaultLocale) {
2950
2813
  return createLoader({
2951
2814
  async pull(locale, input2, initCtx) {
@@ -2982,7 +2845,7 @@ function createXcodeXcstringsLoader(defaultLocale) {
2982
2845
  async push(locale, payload, originalInput) {
2983
2846
  const langDataToMerge = {};
2984
2847
  langDataToMerge.strings = {};
2985
- const input2 = _12.cloneDeep(originalInput) || {
2848
+ const input2 = _9.cloneDeep(originalInput) || {
2986
2849
  sourceLanguage: locale,
2987
2850
  strings: {}
2988
2851
  };
@@ -3032,7 +2895,7 @@ function createXcodeXcstringsLoader(defaultLocale) {
3032
2895
  }
3033
2896
  }
3034
2897
  const originalInputWithoutLocale = originalInput ? _removeLocale(originalInput, locale) : {};
3035
- const result = _12.merge({}, originalInputWithoutLocale, langDataToMerge);
2898
+ const result = _9.merge({}, originalInputWithoutLocale, langDataToMerge);
3036
2899
  return result;
3037
2900
  },
3038
2901
  async pullHints(originalInput) {
@@ -3069,7 +2932,7 @@ function createXcodeXcstringsLoader(defaultLocale) {
3069
2932
  }
3070
2933
  function _removeLocale(input2, locale) {
3071
2934
  const { strings } = input2;
3072
- const newStrings = _12.cloneDeep(strings);
2935
+ const newStrings = _9.cloneDeep(strings);
3073
2936
  for (const [key, value] of Object.entries(newStrings)) {
3074
2937
  if (value.localizations?.[locale]) {
3075
2938
  delete value.localizations[locale];
@@ -3079,31 +2942,31 @@ function _removeLocale(input2, locale) {
3079
2942
  }
3080
2943
 
3081
2944
  // src/cli/loaders/unlocalizable.ts
3082
- import _13 from "lodash";
2945
+ import _10 from "lodash";
3083
2946
  import _isUrl from "is-url";
3084
2947
  import { isValid, parseISO } from "date-fns";
3085
2948
  function createUnlocalizableLoader(returnUnlocalizedKeys = false) {
3086
2949
  return createLoader({
3087
2950
  async pull(locale, input2) {
3088
2951
  const unlocalizableKeys = _getUnlocalizableKeys(input2);
3089
- const result = _13.omitBy(
2952
+ const result = _10.omitBy(
3090
2953
  input2,
3091
- (_35, key) => unlocalizableKeys.includes(key)
2954
+ (_36, key) => unlocalizableKeys.includes(key)
3092
2955
  );
3093
2956
  if (returnUnlocalizedKeys) {
3094
- result.unlocalizable = _13.omitBy(
2957
+ result.unlocalizable = _10.omitBy(
3095
2958
  input2,
3096
- (_35, key) => !unlocalizableKeys.includes(key)
2959
+ (_36, key) => !unlocalizableKeys.includes(key)
3097
2960
  );
3098
2961
  }
3099
2962
  return result;
3100
2963
  },
3101
2964
  async push(locale, data, originalInput) {
3102
2965
  const unlocalizableKeys = _getUnlocalizableKeys(originalInput);
3103
- const result = _13.merge(
2966
+ const result = _10.merge(
3104
2967
  {},
3105
2968
  data,
3106
- _13.omitBy(originalInput, (_35, key) => !unlocalizableKeys.includes(key))
2969
+ _10.omitBy(originalInput, (_36, key) => !unlocalizableKeys.includes(key))
3107
2970
  );
3108
2971
  return result;
3109
2972
  }
@@ -3117,12 +2980,12 @@ function _isIsoDate(v) {
3117
2980
  }
3118
2981
  function _getUnlocalizableKeys(input2) {
3119
2982
  const rules = {
3120
- isEmpty: (v) => _13.isEmpty(v),
2983
+ isEmpty: (v) => _10.isEmpty(v),
3121
2984
  isNumber: (v) => typeof v === "number" || /^[0-9]+$/.test(v),
3122
- isBoolean: (v) => _13.isBoolean(v),
3123
- isIsoDate: (v) => _13.isString(v) && _isIsoDate(v),
3124
- isSystemId: (v) => _13.isString(v) && _isSystemId(v),
3125
- isUrl: (v) => _13.isString(v) && _isUrl(v)
2985
+ isBoolean: (v) => _10.isBoolean(v),
2986
+ isIsoDate: (v) => _10.isString(v) && _isIsoDate(v),
2987
+ isSystemId: (v) => _10.isString(v) && _isSystemId(v),
2988
+ isUrl: (v) => _10.isString(v) && _isUrl(v)
3126
2989
  };
3127
2990
  if (!input2) {
3128
2991
  return [];
@@ -3134,7 +2997,7 @@ function _getUnlocalizableKeys(input2) {
3134
2997
  }
3135
2998
  }
3136
2999
  return false;
3137
- }).map(([key, _35]) => key);
3000
+ }).map(([key, _36]) => key);
3138
3001
  }
3139
3002
 
3140
3003
  // src/cli/loaders/formatters/prettier.ts
@@ -3301,7 +3164,7 @@ function createFormatterLoader(formatterType, parser, bucketPathPattern) {
3301
3164
  }
3302
3165
 
3303
3166
  // src/cli/loaders/po/index.ts
3304
- import _14 from "lodash";
3167
+ import _11 from "lodash";
3305
3168
  import gettextParser from "gettext-parser";
3306
3169
  function createPoLoader(params = { multiline: false }) {
3307
3170
  return composeLoaders(createPoDataLoader(params), createPoContentLoader());
@@ -3317,7 +3180,7 @@ function createPoDataLoader(params) {
3317
3180
  if (Object.keys(sectionPo.translations).length === 0) {
3318
3181
  continue;
3319
3182
  }
3320
- const contextKey = _14.keys(sectionPo.translations)[0];
3183
+ const contextKey = _11.keys(sectionPo.translations)[0];
3321
3184
  const entries = sectionPo.translations[contextKey];
3322
3185
  Object.entries(entries).forEach(([msgid, entry]) => {
3323
3186
  if (msgid && entry.msgid) {
@@ -3339,13 +3202,13 @@ function createPoDataLoader(params) {
3339
3202
  if (Object.keys(sectionPo.translations).length === 0) {
3340
3203
  return null;
3341
3204
  }
3342
- const contextKey = _14.keys(sectionPo.translations)[0];
3205
+ const contextKey = _11.keys(sectionPo.translations)[0];
3343
3206
  const entries = sectionPo.translations[contextKey];
3344
3207
  const msgid = Object.keys(entries).find((key) => entries[key].msgid);
3345
3208
  if (!msgid) {
3346
3209
  const currentSection = currentSections.find((cs) => {
3347
3210
  const csPo = gettextParser.po.parse(cs);
3348
- const csContextKey = _14.keys(csPo.translations)[0];
3211
+ const csContextKey = _11.keys(csPo.translations)[0];
3349
3212
  const csEntries = csPo.translations[csContextKey];
3350
3213
  const csMsgid = Object.keys(csEntries).find(
3351
3214
  (key) => csEntries[key].msgid
@@ -3358,7 +3221,7 @@ function createPoDataLoader(params) {
3358
3221
  return section;
3359
3222
  }
3360
3223
  if (data[msgid]) {
3361
- const updatedPo = _14.merge({}, sectionPo, {
3224
+ const updatedPo = _11.merge({}, sectionPo, {
3362
3225
  translations: {
3363
3226
  [contextKey]: {
3364
3227
  [msgid]: {
@@ -3382,7 +3245,7 @@ function createPoDataLoader(params) {
3382
3245
  function createPoContentLoader() {
3383
3246
  return createLoader({
3384
3247
  async pull(locale, input2, initCtx, originalLocale) {
3385
- const result = _14.chain(input2).entries().filter(([, entry]) => !!entry.msgid).map(([, entry]) => {
3248
+ const result = _11.chain(input2).entries().filter(([, entry]) => !!entry.msgid).map(([, entry]) => {
3386
3249
  const singularFallback = locale === originalLocale ? entry.msgid : null;
3387
3250
  const pluralFallback = locale === originalLocale ? entry.msgid_plural || entry.msgid : null;
3388
3251
  const hasPlural = entry.msgstr.length > 1;
@@ -3397,7 +3260,7 @@ function createPoContentLoader() {
3397
3260
  return result;
3398
3261
  },
3399
3262
  async push(locale, data, originalInput) {
3400
- const result = _14.chain(originalInput).entries().map(([, entry]) => [
3263
+ const result = _11.chain(originalInput).entries().map(([, entry]) => [
3401
3264
  entry.msgid,
3402
3265
  {
3403
3266
  ...entry,
@@ -3940,41 +3803,41 @@ var datoSettingsSchema = Z2.object({
3940
3803
  });
3941
3804
 
3942
3805
  // src/cli/loaders/dato/filter.ts
3943
- import _15 from "lodash";
3806
+ import _12 from "lodash";
3944
3807
  function createDatoFilterLoader() {
3945
3808
  return createLoader({
3946
3809
  async pull(locale, input2) {
3947
3810
  const result = {};
3948
- for (const [modelId, modelInfo] of _15.entries(input2)) {
3811
+ for (const [modelId, modelInfo] of _12.entries(input2)) {
3949
3812
  result[modelId] = {};
3950
3813
  for (const record of modelInfo.records) {
3951
- result[modelId][record.id] = _15.chain(modelInfo.fields).mapKeys((field) => field.api_key).mapValues((field) => _15.get(record, [field.api_key, locale])).value();
3814
+ result[modelId][record.id] = _12.chain(modelInfo.fields).mapKeys((field) => field.api_key).mapValues((field) => _12.get(record, [field.api_key, locale])).value();
3952
3815
  }
3953
3816
  }
3954
3817
  return result;
3955
3818
  },
3956
3819
  async push(locale, data, originalInput, originalLocale) {
3957
- const result = _15.cloneDeep(originalInput || {});
3958
- for (const [modelId, modelInfo] of _15.entries(result)) {
3820
+ const result = _12.cloneDeep(originalInput || {});
3821
+ for (const [modelId, modelInfo] of _12.entries(result)) {
3959
3822
  for (const record of modelInfo.records) {
3960
- for (const [fieldId, fieldValue] of _15.entries(record)) {
3823
+ for (const [fieldId, fieldValue] of _12.entries(record)) {
3961
3824
  const fieldInfo = modelInfo.fields.find(
3962
3825
  (field) => field.api_key === fieldId
3963
3826
  );
3964
3827
  if (fieldInfo) {
3965
- const sourceFieldValue = _15.get(fieldValue, [originalLocale]);
3966
- const targetFieldValue = _15.get(data, [
3828
+ const sourceFieldValue = _12.get(fieldValue, [originalLocale]);
3829
+ const targetFieldValue = _12.get(data, [
3967
3830
  modelId,
3968
3831
  record.id,
3969
3832
  fieldId
3970
3833
  ]);
3971
3834
  if (targetFieldValue) {
3972
- _15.set(record, [fieldId, locale], targetFieldValue);
3835
+ _12.set(record, [fieldId, locale], targetFieldValue);
3973
3836
  } else {
3974
- _15.set(record, [fieldId, locale], sourceFieldValue);
3837
+ _12.set(record, [fieldId, locale], sourceFieldValue);
3975
3838
  }
3976
- _15.chain(fieldValue).keys().reject((loc) => loc === locale || loc === originalLocale).filter((loc) => _15.isEmpty(_15.get(fieldValue, [loc]))).forEach(
3977
- (loc) => _15.set(record, [fieldId, loc], sourceFieldValue)
3839
+ _12.chain(fieldValue).keys().reject((loc) => loc === locale || loc === originalLocale).filter((loc) => _12.isEmpty(_12.get(fieldValue, [loc]))).forEach(
3840
+ (loc) => _12.set(record, [fieldId, loc], sourceFieldValue)
3978
3841
  ).value();
3979
3842
  }
3980
3843
  }
@@ -3986,10 +3849,10 @@ function createDatoFilterLoader() {
3986
3849
  }
3987
3850
 
3988
3851
  // src/cli/loaders/dato/api.ts
3989
- import _17 from "lodash";
3852
+ import _14 from "lodash";
3990
3853
 
3991
3854
  // src/cli/loaders/dato/_utils.ts
3992
- import _16 from "lodash";
3855
+ import _13 from "lodash";
3993
3856
  import { buildClient } from "@datocms/cma-client-node";
3994
3857
  function createDatoClient(params) {
3995
3858
  if (!params.apiKey) {
@@ -4182,7 +4045,7 @@ function createDatoApiLoader(config, onConfigUpdate) {
4182
4045
  const result = {
4183
4046
  models: {}
4184
4047
  };
4185
- const updatedConfig = _17.cloneDeep(config);
4048
+ const updatedConfig = _14.cloneDeep(config);
4186
4049
  console.log(`Initializing DatoCMS loader...`);
4187
4050
  const project = await dato.findProject();
4188
4051
  const modelChoices = await getModelChoices(dato, config);
@@ -4200,7 +4063,7 @@ function createDatoApiLoader(config, onConfigUpdate) {
4200
4063
  delete updatedConfig.models[modelId];
4201
4064
  }
4202
4065
  }
4203
- for (const modelId of _17.keys(updatedConfig.models)) {
4066
+ for (const modelId of _14.keys(updatedConfig.models)) {
4204
4067
  const { modelName, fields } = await getModelFields(dato, modelId);
4205
4068
  if (fields.length > 0) {
4206
4069
  result.models[modelId] = { fields: [], records: [] };
@@ -4218,7 +4081,7 @@ function createDatoApiLoader(config, onConfigUpdate) {
4218
4081
  );
4219
4082
  if (isLocalized) {
4220
4083
  result.models[modelId].fields.push(fieldInfo);
4221
- updatedConfig.models[modelId].fields = _17.uniq([
4084
+ updatedConfig.models[modelId].fields = _14.uniq([
4222
4085
  ...updatedConfig.models[modelId].fields || [],
4223
4086
  fieldInfo.api_key
4224
4087
  ]);
@@ -4246,7 +4109,7 @@ function createDatoApiLoader(config, onConfigUpdate) {
4246
4109
  },
4247
4110
  async pull(locale, input2, initCtx) {
4248
4111
  const result = {};
4249
- for (const modelId of _17.keys(initCtx?.models || {})) {
4112
+ for (const modelId of _14.keys(initCtx?.models || {})) {
4250
4113
  let records = initCtx?.models[modelId].records || [];
4251
4114
  const recordIds = records.map((record) => record.id);
4252
4115
  records = await dato.findRecords(recordIds);
@@ -4261,7 +4124,7 @@ function createDatoApiLoader(config, onConfigUpdate) {
4261
4124
  return result;
4262
4125
  },
4263
4126
  async push(locale, data, originalInput) {
4264
- for (const modelId of _17.keys(data)) {
4127
+ for (const modelId of _14.keys(data)) {
4265
4128
  for (let i = 0; i < data[modelId].records.length; i++) {
4266
4129
  const record = data[modelId].records[i];
4267
4130
  console.log(
@@ -4277,7 +4140,7 @@ async function getModelFields(dato, modelId) {
4277
4140
  const modelInfo = await dato.findModel(modelId);
4278
4141
  return {
4279
4142
  modelName: modelInfo.name,
4280
- fields: _17.filter(modelInfo.fields, (field) => field.type === "field")
4143
+ fields: _14.filter(modelInfo.fields, (field) => field.type === "field")
4281
4144
  };
4282
4145
  }
4283
4146
  async function getFieldDetails(dato, fields) {
@@ -4357,17 +4220,17 @@ async function promptModelSelection(choices) {
4357
4220
  }
4358
4221
 
4359
4222
  // src/cli/loaders/dato/extract.ts
4360
- import _18 from "lodash";
4223
+ import _15 from "lodash";
4361
4224
  function createDatoExtractLoader() {
4362
4225
  return createLoader({
4363
4226
  async pull(locale, input2) {
4364
4227
  const result = {};
4365
- for (const [modelId, modelInfo] of _18.entries(input2)) {
4366
- for (const [recordId, record] of _18.entries(modelInfo)) {
4367
- for (const [fieldName, fieldValue] of _18.entries(record)) {
4228
+ for (const [modelId, modelInfo] of _15.entries(input2)) {
4229
+ for (const [recordId, record] of _15.entries(modelInfo)) {
4230
+ for (const [fieldName, fieldValue] of _15.entries(record)) {
4368
4231
  const parsedValue = createParsedDatoValue(fieldValue);
4369
4232
  if (parsedValue) {
4370
- _18.set(result, [modelId, `_${recordId}`, fieldName], parsedValue);
4233
+ _15.set(result, [modelId, `_${recordId}`, fieldName], parsedValue);
4371
4234
  }
4372
4235
  }
4373
4236
  }
@@ -4375,12 +4238,12 @@ function createDatoExtractLoader() {
4375
4238
  return result;
4376
4239
  },
4377
4240
  async push(locale, data, originalInput) {
4378
- const result = _18.cloneDeep(originalInput || {});
4379
- for (const [modelId, modelInfo] of _18.entries(data)) {
4380
- for (const [virtualRecordId, record] of _18.entries(modelInfo)) {
4381
- for (const [fieldName, fieldValue] of _18.entries(record)) {
4241
+ const result = _15.cloneDeep(originalInput || {});
4242
+ for (const [modelId, modelInfo] of _15.entries(data)) {
4243
+ for (const [virtualRecordId, record] of _15.entries(modelInfo)) {
4244
+ for (const [fieldName, fieldValue] of _15.entries(record)) {
4382
4245
  const [, recordId] = virtualRecordId.split("_");
4383
- const originalFieldValue = _18.get(originalInput, [
4246
+ const originalFieldValue = _15.get(originalInput, [
4384
4247
  modelId,
4385
4248
  recordId,
4386
4249
  fieldName
@@ -4390,7 +4253,7 @@ function createDatoExtractLoader() {
4390
4253
  originalFieldValue,
4391
4254
  true
4392
4255
  );
4393
- _18.set(
4256
+ _15.set(
4394
4257
  result,
4395
4258
  [modelId, recordId, fieldName],
4396
4259
  rawValue || originalFieldValue
@@ -4403,25 +4266,25 @@ function createDatoExtractLoader() {
4403
4266
  });
4404
4267
  }
4405
4268
  function detectDatoFieldType(rawDatoValue) {
4406
- if (_18.has(rawDatoValue, "document") && _18.get(rawDatoValue, "schema") === "dast") {
4269
+ if (_15.has(rawDatoValue, "document") && _15.get(rawDatoValue, "schema") === "dast") {
4407
4270
  return "structured_text";
4408
- } else if (_18.has(rawDatoValue, "no_index") || _18.has(rawDatoValue, "twitter_card")) {
4271
+ } else if (_15.has(rawDatoValue, "no_index") || _15.has(rawDatoValue, "twitter_card")) {
4409
4272
  return "seo";
4410
- } else if (_18.get(rawDatoValue, "type") === "item") {
4273
+ } else if (_15.get(rawDatoValue, "type") === "item") {
4411
4274
  return "single_block";
4412
- } else if (_18.isArray(rawDatoValue) && _18.every(rawDatoValue, (item) => _18.get(item, "type") === "item")) {
4275
+ } else if (_15.isArray(rawDatoValue) && _15.every(rawDatoValue, (item) => _15.get(item, "type") === "item")) {
4413
4276
  return "rich_text";
4414
4277
  } else if (_isFile(rawDatoValue)) {
4415
4278
  return "file";
4416
- } else if (_18.isArray(rawDatoValue) && _18.every(rawDatoValue, (item) => _isFile(item))) {
4279
+ } else if (_15.isArray(rawDatoValue) && _15.every(rawDatoValue, (item) => _isFile(item))) {
4417
4280
  return "gallery";
4418
4281
  } else if (_isJson(rawDatoValue)) {
4419
4282
  return "json";
4420
- } else if (_18.isString(rawDatoValue)) {
4283
+ } else if (_15.isString(rawDatoValue)) {
4421
4284
  return "string";
4422
4285
  } else if (_isVideo(rawDatoValue)) {
4423
4286
  return "video";
4424
- } else if (_18.isArray(rawDatoValue) && _18.every(rawDatoValue, (item) => _18.isString(item))) {
4287
+ } else if (_15.isArray(rawDatoValue) && _15.every(rawDatoValue, (item) => _15.isString(item))) {
4425
4288
  return "ref_list";
4426
4289
  } else {
4427
4290
  return null;
@@ -4491,9 +4354,9 @@ function serializeStructuredText(rawStructuredText) {
4491
4354
  acc
4492
4355
  );
4493
4356
  }
4494
- if (!_18.isNil(node.value)) {
4357
+ if (!_15.isNil(node.value)) {
4495
4358
  acc[[...path19, "value"].join(".")] = node.value;
4496
- } else if (_18.get(node, "type") === "block") {
4359
+ } else if (_15.get(node, "type") === "block") {
4497
4360
  acc[[...path19, "item"].join(".")] = serializeBlock(node.item);
4498
4361
  }
4499
4362
  if (node.children) {
@@ -4509,48 +4372,48 @@ function serializeStructuredText(rawStructuredText) {
4509
4372
  }
4510
4373
  }
4511
4374
  function serializeSeo(rawSeo) {
4512
- return _18.chain(rawSeo).pick(["title", "description"]).value();
4375
+ return _15.chain(rawSeo).pick(["title", "description"]).value();
4513
4376
  }
4514
4377
  function serializeBlock(rawBlock) {
4515
- if (_18.get(rawBlock, "type") === "item" && _18.has(rawBlock, "id")) {
4378
+ if (_15.get(rawBlock, "type") === "item" && _15.has(rawBlock, "id")) {
4516
4379
  return serializeBlock(rawBlock.attributes);
4517
4380
  }
4518
4381
  const result = {};
4519
- for (const [attributeName, attributeValue] of _18.entries(rawBlock)) {
4382
+ for (const [attributeName, attributeValue] of _15.entries(rawBlock)) {
4520
4383
  result[attributeName] = createParsedDatoValue(attributeValue);
4521
4384
  }
4522
4385
  return result;
4523
4386
  }
4524
4387
  function serializeBlockList(rawBlockList) {
4525
- return _18.chain(rawBlockList).map((block) => serializeBlock(block)).value();
4388
+ return _15.chain(rawBlockList).map((block) => serializeBlock(block)).value();
4526
4389
  }
4527
4390
  function serializeVideo(rawVideo) {
4528
- return _18.chain(rawVideo).pick(["title"]).value();
4391
+ return _15.chain(rawVideo).pick(["title"]).value();
4529
4392
  }
4530
4393
  function serializeFile(rawFile) {
4531
- return _18.chain(rawFile).pick(["alt", "title"]).value();
4394
+ return _15.chain(rawFile).pick(["alt", "title"]).value();
4532
4395
  }
4533
4396
  function serializeGallery(rawGallery) {
4534
- return _18.chain(rawGallery).map((item) => serializeFile(item)).value();
4397
+ return _15.chain(rawGallery).map((item) => serializeFile(item)).value();
4535
4398
  }
4536
4399
  function deserializeFile(parsedFile, originalRawFile) {
4537
- return _18.chain(parsedFile).defaults(originalRawFile).value();
4400
+ return _15.chain(parsedFile).defaults(originalRawFile).value();
4538
4401
  }
4539
4402
  function deserializeGallery(parsedGallery, originalRawGallery) {
4540
- return _18.chain(parsedGallery).map((item, i) => deserializeFile(item, originalRawGallery[i])).value();
4403
+ return _15.chain(parsedGallery).map((item, i) => deserializeFile(item, originalRawGallery[i])).value();
4541
4404
  }
4542
4405
  function deserializeVideo(parsedVideo, originalRawVideo) {
4543
- return _18.chain(parsedVideo).defaults(originalRawVideo).value();
4406
+ return _15.chain(parsedVideo).defaults(originalRawVideo).value();
4544
4407
  }
4545
4408
  function deserializeBlock(payload, rawNode, isClean = false) {
4546
- const result = _18.cloneDeep(rawNode);
4547
- for (const [attributeName, attributeValue] of _18.entries(rawNode.attributes)) {
4409
+ const result = _15.cloneDeep(rawNode);
4410
+ for (const [attributeName, attributeValue] of _15.entries(rawNode.attributes)) {
4548
4411
  const rawValue = createRawDatoValue(
4549
4412
  payload[attributeName],
4550
4413
  attributeValue,
4551
4414
  isClean
4552
4415
  );
4553
- _18.set(result, ["attributes", attributeName], rawValue);
4416
+ _15.set(result, ["attributes", attributeName], rawValue);
4554
4417
  }
4555
4418
  if (isClean) {
4556
4419
  delete result["id"];
@@ -4558,40 +4421,40 @@ function deserializeBlock(payload, rawNode, isClean = false) {
4558
4421
  return result;
4559
4422
  }
4560
4423
  function deserializeSeo(parsedSeo, originalRawSeo) {
4561
- return _18.chain(parsedSeo).pick(["title", "description"]).defaults(originalRawSeo).value();
4424
+ return _15.chain(parsedSeo).pick(["title", "description"]).defaults(originalRawSeo).value();
4562
4425
  }
4563
4426
  function deserializeBlockList(parsedBlockList, originalRawBlockList, isClean = false) {
4564
- return _18.chain(parsedBlockList).map(
4427
+ return _15.chain(parsedBlockList).map(
4565
4428
  (block, i) => deserializeBlock(block, originalRawBlockList[i], isClean)
4566
4429
  ).value();
4567
4430
  }
4568
4431
  function deserializeStructuredText(parsedStructuredText, originalRawStructuredText) {
4569
- const result = _18.cloneDeep(originalRawStructuredText);
4570
- for (const [path19, value] of _18.entries(parsedStructuredText)) {
4571
- const realPath = _18.chain(path19.split(".")).flatMap((s) => !_18.isNaN(_18.toNumber(s)) ? ["children", s] : s).value();
4432
+ const result = _15.cloneDeep(originalRawStructuredText);
4433
+ for (const [path19, value] of _15.entries(parsedStructuredText)) {
4434
+ const realPath = _15.chain(path19.split(".")).flatMap((s) => !_15.isNaN(_15.toNumber(s)) ? ["children", s] : s).value();
4572
4435
  const deserializedValue = createRawDatoValue(
4573
4436
  value,
4574
- _18.get(originalRawStructuredText, realPath),
4437
+ _15.get(originalRawStructuredText, realPath),
4575
4438
  true
4576
4439
  );
4577
- _18.set(result, realPath, deserializedValue);
4440
+ _15.set(result, realPath, deserializedValue);
4578
4441
  }
4579
4442
  return result;
4580
4443
  }
4581
4444
  function _isJson(rawDatoValue) {
4582
4445
  try {
4583
- return _18.isString(rawDatoValue) && rawDatoValue.startsWith("{") && rawDatoValue.endsWith("}") && !!JSON.parse(rawDatoValue);
4446
+ return _15.isString(rawDatoValue) && rawDatoValue.startsWith("{") && rawDatoValue.endsWith("}") && !!JSON.parse(rawDatoValue);
4584
4447
  } catch (e) {
4585
4448
  return false;
4586
4449
  }
4587
4450
  }
4588
4451
  function _isFile(rawDatoValue) {
4589
- return _18.isObject(rawDatoValue) && ["alt", "title", "custom_data", "focal_point", "upload_id"].every(
4590
- (key) => _18.has(rawDatoValue, key)
4452
+ return _15.isObject(rawDatoValue) && ["alt", "title", "custom_data", "focal_point", "upload_id"].every(
4453
+ (key) => _15.has(rawDatoValue, key)
4591
4454
  );
4592
4455
  }
4593
4456
  function _isVideo(rawDatoValue) {
4594
- return _18.isObject(rawDatoValue) && [
4457
+ return _15.isObject(rawDatoValue) && [
4595
4458
  "url",
4596
4459
  "title",
4597
4460
  "width",
@@ -4599,7 +4462,7 @@ function _isVideo(rawDatoValue) {
4599
4462
  "provider",
4600
4463
  "provider_uid",
4601
4464
  "thumbnail_url"
4602
- ].every((key) => _18.has(rawDatoValue, key));
4465
+ ].every((key) => _15.has(rawDatoValue, key));
4603
4466
  }
4604
4467
 
4605
4468
  // src/cli/loaders/dato/index.ts
@@ -4669,7 +4532,7 @@ function createVttLoader() {
4669
4532
  }
4670
4533
 
4671
4534
  // src/cli/loaders/variable/index.ts
4672
- import _19 from "lodash";
4535
+ import _16 from "lodash";
4673
4536
  function createVariableLoader(params) {
4674
4537
  return composeLoaders(variableExtractLoader(params), variableContentLoader());
4675
4538
  }
@@ -4678,7 +4541,7 @@ function variableExtractLoader(params) {
4678
4541
  return createLoader({
4679
4542
  pull: async (locale, input2, initXtx, originalLocale, originalInput) => {
4680
4543
  const result = {};
4681
- const inputValues = _19.omitBy(input2, _19.isEmpty);
4544
+ const inputValues = _16.omitBy(input2, _16.isEmpty);
4682
4545
  for (const [key, value] of Object.entries(inputValues)) {
4683
4546
  const originalValue = originalInput[key];
4684
4547
  const matches = originalValue.match(specifierPattern) || [];
@@ -4714,11 +4577,11 @@ function variableExtractLoader(params) {
4714
4577
  function variableContentLoader() {
4715
4578
  return createLoader({
4716
4579
  pull: async (locale, input2) => {
4717
- const result = _19.mapValues(input2, (payload) => payload.value);
4580
+ const result = _16.mapValues(input2, (payload) => payload.value);
4718
4581
  return result;
4719
4582
  },
4720
4583
  push: async (locale, data, originalInput, defaultLocale, pullInput) => {
4721
- const result = _19.cloneDeep(
4584
+ const result = _16.cloneDeep(
4722
4585
  originalInput || {}
4723
4586
  );
4724
4587
  for (const [key, originalValueObj] of Object.entries(result)) {
@@ -4743,20 +4606,20 @@ function getFormatSpecifierPattern(type) {
4743
4606
  }
4744
4607
 
4745
4608
  // src/cli/loaders/sync.ts
4746
- import _20 from "lodash";
4609
+ import _17 from "lodash";
4747
4610
  function createSyncLoader() {
4748
4611
  return createLoader({
4749
4612
  async pull(locale, input2, initCtx, originalLocale, originalInput) {
4750
4613
  if (!originalInput) {
4751
4614
  return input2;
4752
4615
  }
4753
- return _20.chain(originalInput).mapValues((value, key) => input2[key]).value();
4616
+ return _17.chain(originalInput).mapValues((value, key) => input2[key]).value();
4754
4617
  },
4755
4618
  async push(locale, data, originalInput) {
4756
4619
  if (!originalInput) {
4757
4620
  return data;
4758
4621
  }
4759
- return _20.chain(originalInput || {}).mapValues((value, key) => data[key]).value();
4622
+ return _17.chain(originalInput || {}).mapValues((value, key) => data[key]).value();
4760
4623
  }
4761
4624
  });
4762
4625
  }
@@ -4938,7 +4801,7 @@ function parseVueFile(input2) {
4938
4801
 
4939
4802
  // src/cli/loaders/typescript/index.ts
4940
4803
  import { parse as parse3 } from "@babel/parser";
4941
- import _21 from "lodash";
4804
+ import _18 from "lodash";
4942
4805
  import babelTraverseModule from "@babel/traverse";
4943
4806
  import * as t from "@babel/types";
4944
4807
  import babelGenerateModule from "@babel/generator";
@@ -4974,7 +4837,7 @@ function createTypescriptLoader() {
4974
4837
  },
4975
4838
  push: async (locale, data, originalInput, defaultLocale, pullInput, pullOutput) => {
4976
4839
  const ast = parseTypeScript(originalInput || "");
4977
- const finalData = _21.merge({}, pullOutput, data);
4840
+ const finalData = _18.merge({}, pullOutput, data);
4978
4841
  updateStringsInDefaultExport(ast, finalData);
4979
4842
  const { code } = generate(ast, {
4980
4843
  jsescOption: {
@@ -5175,7 +5038,7 @@ function getPropertyKey(prop) {
5175
5038
  }
5176
5039
 
5177
5040
  // src/cli/loaders/inject-locale.ts
5178
- import _22 from "lodash";
5041
+ import _19 from "lodash";
5179
5042
 
5180
5043
  // ../../node_modules/.pnpm/@isaacs+balanced-match@4.0.1/node_modules/@isaacs/balanced-match/dist/esm/index.js
5181
5044
  var balanced = (a, b, str) => {
@@ -5866,7 +5729,7 @@ var AST = class _AST {
5866
5729
  if (!this.type) {
5867
5730
  const noEmpty = this.isStart() && this.isEnd();
5868
5731
  const src = this.#parts.map((p) => {
5869
- const [re, _35, hasMagic, uflag] = typeof p === "string" ? _AST.#parseGlob(p, this.#hasMagic, noEmpty) : p.toRegExpSource(allowDot);
5732
+ const [re, _36, hasMagic, uflag] = typeof p === "string" ? _AST.#parseGlob(p, this.#hasMagic, noEmpty) : p.toRegExpSource(allowDot);
5870
5733
  this.#hasMagic = this.#hasMagic || hasMagic;
5871
5734
  this.#uflag = this.#uflag || uflag;
5872
5735
  return re;
@@ -5939,7 +5802,7 @@ var AST = class _AST {
5939
5802
  if (typeof p === "string") {
5940
5803
  throw new Error("string type in extglob ast??");
5941
5804
  }
5942
- const [re, _35, _hasMagic, uflag] = p.toRegExpSource(dot);
5805
+ const [re, _36, _hasMagic, uflag] = p.toRegExpSource(dot);
5943
5806
  this.#uflag = this.#uflag || uflag;
5944
5807
  return re;
5945
5808
  }).filter((p) => !(this.isStart() && this.isEnd()) || !!p).join("|");
@@ -6184,7 +6047,7 @@ var Minimatch = class {
6184
6047
  }
6185
6048
  return false;
6186
6049
  }
6187
- debug(..._35) {
6050
+ debug(..._36) {
6188
6051
  }
6189
6052
  make() {
6190
6053
  const pattern = this.pattern;
@@ -6206,7 +6069,7 @@ var Minimatch = class {
6206
6069
  const rawGlobParts = this.globSet.map((s) => this.slashSplit(s));
6207
6070
  this.globParts = this.preprocess(rawGlobParts);
6208
6071
  this.debug(this.pattern, this.globParts);
6209
- let set = this.globParts.map((s, _35, __) => {
6072
+ let set = this.globParts.map((s, _36, __) => {
6210
6073
  if (this.isWindows && this.windowsNoMagicRoot) {
6211
6074
  const isUNC = s[0] === "" && s[1] === "" && (s[2] === "?" || !globMagic.test(s[2])) && !globMagic.test(s[3]);
6212
6075
  const isDrive = /^[a-z]:/i.test(s[0]);
@@ -6723,7 +6586,7 @@ function createInjectLocaleLoader(injectLocaleKeys) {
6723
6586
  return data;
6724
6587
  }
6725
6588
  const omitKeys = _getKeysWithLocales(data, injectLocaleKeys, locale);
6726
- const result = _22.omit(data, omitKeys);
6589
+ const result = _19.omit(data, omitKeys);
6727
6590
  return result;
6728
6591
  },
6729
6592
  async push(locale, data, originalInput, originalLocale) {
@@ -6736,7 +6599,7 @@ function createInjectLocaleLoader(injectLocaleKeys) {
6736
6599
  originalLocale
6737
6600
  );
6738
6601
  localeKeys.forEach((key) => {
6739
- _22.set(data, key, locale);
6602
+ _19.set(data, key, locale);
6740
6603
  });
6741
6604
  return data;
6742
6605
  }
@@ -6745,7 +6608,7 @@ function createInjectLocaleLoader(injectLocaleKeys) {
6745
6608
  function _getKeysWithLocales(data, injectLocaleKeys, locale) {
6746
6609
  const allKeys = _getAllKeys(data);
6747
6610
  return allKeys.filter((key) => {
6748
- return injectLocaleKeys.some((pattern) => minimatch(key, pattern)) && _22.get(data, key) === locale;
6611
+ return injectLocaleKeys.some((pattern) => minimatch(key, pattern)) && _19.get(data, key) === locale;
6749
6612
  });
6750
6613
  }
6751
6614
  function _getAllKeys(obj, prefix = "") {
@@ -6763,23 +6626,36 @@ function _getAllKeys(obj, prefix = "") {
6763
6626
  }
6764
6627
 
6765
6628
  // src/cli/loaders/locked-keys.ts
6766
- import _23 from "lodash";
6629
+ import _20 from "lodash";
6630
+
6631
+ // src/cli/utils/key-matching.ts
6632
+ function matchesKeyPattern(key, patterns) {
6633
+ return patterns.some(
6634
+ (pattern) => key.startsWith(pattern) || minimatch(key, pattern)
6635
+ );
6636
+ }
6637
+ function formatDisplayValue(value, maxLength = 50) {
6638
+ if (typeof value === "string") {
6639
+ return value.length > maxLength ? `${value.substring(0, maxLength)}...` : value;
6640
+ }
6641
+ return JSON.stringify(value);
6642
+ }
6643
+
6644
+ // src/cli/loaders/locked-keys.ts
6767
6645
  function createLockedKeysLoader(lockedKeys) {
6768
6646
  return createLoader({
6769
6647
  pull: async (locale, data) => {
6770
- return _23.pickBy(data, (value, key) => !_isLockedKey(key, lockedKeys));
6648
+ return _20.pickBy(
6649
+ data,
6650
+ (value, key) => !matchesKeyPattern(key, lockedKeys)
6651
+ );
6771
6652
  },
6772
6653
  push: async (locale, data, originalInput) => {
6773
- const lockedSubObject = _23.chain(originalInput).pickBy((value, key) => _isLockedKey(key, lockedKeys)).value();
6774
- return _23.merge({}, data, lockedSubObject);
6654
+ const lockedSubObject = _20.chain(originalInput).pickBy((value, key) => matchesKeyPattern(key, lockedKeys)).value();
6655
+ return _20.merge({}, data, lockedSubObject);
6775
6656
  }
6776
6657
  });
6777
6658
  }
6778
- function _isLockedKey(key, lockedKeys) {
6779
- return lockedKeys.some(
6780
- (lockedKey) => key.startsWith(lockedKey) || minimatch(key, lockedKey)
6781
- );
6782
- }
6783
6659
 
6784
6660
  // src/cli/loaders/mdx2/frontmatter-split.ts
6785
6661
  import matter2 from "gray-matter";
@@ -6828,7 +6704,7 @@ function md5(input2) {
6828
6704
  }
6829
6705
 
6830
6706
  // src/cli/loaders/mdx2/code-placeholder.ts
6831
- import _24 from "lodash";
6707
+ import _21 from "lodash";
6832
6708
  var fenceRegex = /([ \t]*)(^>\s*)?```([\s\S]*?)```/gm;
6833
6709
  var inlineCodeRegex = /(?<!`)`([^`\r\n]+?)`(?!`)/g;
6834
6710
  var imageRegex = /([ \t]*)(^>\s*)?!\[[^\]]*?\]\(([^()]*(\([^()]*\)[^()]*)*)\)/gm;
@@ -6851,7 +6727,7 @@ ${match2}
6851
6727
  found = true;
6852
6728
  }
6853
6729
  } while (found);
6854
- content = _24.chain(content).split("\n\n").map((section) => _24.trim(section, "\n")).filter(Boolean).join("\n\n").value();
6730
+ content = _21.chain(content).split("\n\n").map((section) => _21.trim(section, "\n")).filter(Boolean).join("\n\n").value();
6855
6731
  return content;
6856
6732
  }
6857
6733
  function ensureTrailingFenceNewline(_content) {
@@ -6873,7 +6749,7 @@ ${match2}
6873
6749
  found = true;
6874
6750
  }
6875
6751
  } while (found);
6876
- content = _24.chain(content).split("\n\n").map((section) => _24.trim(section, "\n")).filter(Boolean).join("\n\n").value();
6752
+ content = _21.chain(content).split("\n\n").map((section) => _21.trim(section, "\n")).filter(Boolean).join("\n\n").value();
6877
6753
  return content;
6878
6754
  }
6879
6755
  function extractCodePlaceholders(content) {
@@ -6915,7 +6791,7 @@ function createMdxCodePlaceholderLoader() {
6915
6791
  async push(locale, data, originalInput, originalLocale, pullInput) {
6916
6792
  const sourceInfo = extractCodePlaceholders(originalInput ?? "");
6917
6793
  const currentInfo = extractCodePlaceholders(pullInput ?? "");
6918
- const codePlaceholders = _24.merge(
6794
+ const codePlaceholders = _21.merge(
6919
6795
  sourceInfo.codePlaceholders,
6920
6796
  currentInfo.codePlaceholders,
6921
6797
  globalPlaceholderRegistry
@@ -6923,7 +6799,7 @@ function createMdxCodePlaceholderLoader() {
6923
6799
  );
6924
6800
  let result = data;
6925
6801
  for (const [placeholder, original] of Object.entries(codePlaceholders)) {
6926
- const replacement = original.startsWith(">") ? _24.trimStart(original, "> ") : original;
6802
+ const replacement = original.startsWith(">") ? _21.trimStart(original, "> ") : original;
6927
6803
  result = result.replaceAll(placeholder, replacement);
6928
6804
  }
6929
6805
  return result;
@@ -6951,11 +6827,11 @@ function createLocalizableMdxDocumentLoader() {
6951
6827
  }
6952
6828
 
6953
6829
  // src/cli/loaders/mdx2/sections-split-2.ts
6954
- import _25 from "lodash";
6830
+ import _22 from "lodash";
6955
6831
  function createMdxSectionsSplit2Loader() {
6956
6832
  return createLoader({
6957
6833
  async pull(locale, input2) {
6958
- const sections = _25.chain(input2.content).split("\n\n").filter(Boolean).map((section, index) => [index, section]).fromPairs().value();
6834
+ const sections = _22.chain(input2.content).split("\n\n").filter(Boolean).map((section, index) => [index, section]).fromPairs().value();
6959
6835
  const result = {
6960
6836
  frontmatter: input2.frontmatter,
6961
6837
  sections
@@ -6963,7 +6839,7 @@ function createMdxSectionsSplit2Loader() {
6963
6839
  return result;
6964
6840
  },
6965
6841
  async push(locale, data, originalInput, _originalLocale, pullInput) {
6966
- const content = _25.chain(data.sections).values().join("\n\n").value();
6842
+ const content = _22.chain(data.sections).values().join("\n\n").value();
6967
6843
  const result = {
6968
6844
  frontmatter: data.frontmatter,
6969
6845
  codePlaceholders: pullInput?.codePlaceholders || {},
@@ -7029,31 +6905,26 @@ function createMdxLockedPatternsLoader(defaultPatterns) {
7029
6905
  }
7030
6906
 
7031
6907
  // src/cli/loaders/ignored-keys.ts
7032
- import _26 from "lodash";
6908
+ import _23 from "lodash";
7033
6909
  function createIgnoredKeysLoader(ignoredKeys) {
7034
6910
  return createLoader({
7035
6911
  pull: async (locale, data) => {
7036
- const result = _26.omitBy(
6912
+ const result = _23.omitBy(
7037
6913
  data,
7038
- (value, key) => _isIgnoredKey(key, ignoredKeys)
6914
+ (value, key) => matchesKeyPattern(key, ignoredKeys)
7039
6915
  );
7040
6916
  return result;
7041
6917
  },
7042
6918
  push: async (locale, data, originalInput, originalLocale, pullInput) => {
7043
- const ignoredSubObject = _26.pickBy(
6919
+ const ignoredSubObject = _23.pickBy(
7044
6920
  pullInput,
7045
- (value, key) => _isIgnoredKey(key, ignoredKeys)
6921
+ (value, key) => matchesKeyPattern(key, ignoredKeys)
7046
6922
  );
7047
- const result = _26.merge({}, data, ignoredSubObject);
6923
+ const result = _23.merge({}, data, ignoredSubObject);
7048
6924
  return result;
7049
6925
  }
7050
6926
  });
7051
6927
  }
7052
- function _isIgnoredKey(key, ignoredKeys) {
7053
- return ignoredKeys.some(
7054
- (ignoredKey) => key.startsWith(ignoredKey) || minimatch(key, ignoredKey)
7055
- );
7056
- }
7057
6928
 
7058
6929
  // src/cli/loaders/ejs.ts
7059
6930
  function parseEjsForTranslation(input2) {
@@ -7187,7 +7058,7 @@ function createEjsLoader() {
7187
7058
  }
7188
7059
 
7189
7060
  // src/cli/loaders/ensure-key-order.ts
7190
- import _27 from "lodash";
7061
+ import _24 from "lodash";
7191
7062
  function createEnsureKeyOrderLoader() {
7192
7063
  return createLoader({
7193
7064
  pull: async (_locale, input2) => {
@@ -7202,10 +7073,10 @@ function createEnsureKeyOrderLoader() {
7202
7073
  });
7203
7074
  }
7204
7075
  function reorderKeys(data, originalInput) {
7205
- if (_27.isArray(originalInput) && _27.isArray(data)) {
7076
+ if (_24.isArray(originalInput) && _24.isArray(data)) {
7206
7077
  return data.map((item, idx) => reorderKeys(item, originalInput[idx] ?? {}));
7207
7078
  }
7208
- if (!_27.isObject(data) || _27.isArray(data) || _27.isDate(data)) {
7079
+ if (!_24.isObject(data) || _24.isArray(data) || _24.isDate(data)) {
7209
7080
  return data;
7210
7081
  }
7211
7082
  const orderedData = {};
@@ -7237,13 +7108,13 @@ function createTxtLoader() {
7237
7108
  const sortedEntries = Object.entries(payload).sort(
7238
7109
  ([a], [b]) => parseInt(a) - parseInt(b)
7239
7110
  );
7240
- return sortedEntries.map(([_35, value]) => value).join("\n");
7111
+ return sortedEntries.map(([_36, value]) => value).join("\n");
7241
7112
  }
7242
7113
  });
7243
7114
  }
7244
7115
 
7245
7116
  // src/cli/loaders/json-dictionary.ts
7246
- import _28 from "lodash";
7117
+ import _25 from "lodash";
7247
7118
  var TOP_LEVEL_KEY = "--content--";
7248
7119
  function createJsonDictionaryLoader() {
7249
7120
  return createLoader({
@@ -7258,7 +7129,7 @@ function createJsonDictionaryLoader() {
7258
7129
  if (!originalInput) {
7259
7130
  throw new Error("Error while parsing json-dictionary bucket");
7260
7131
  }
7261
- const input2 = _28.cloneDeep(originalInput);
7132
+ const input2 = _25.cloneDeep(originalInput);
7262
7133
  if (Object.keys(data).length === 1 && Object.keys(data)[0] === TOP_LEVEL_KEY) {
7263
7134
  setNestedLocale(
7264
7135
  { [TOP_LEVEL_KEY]: input2 },
@@ -7613,7 +7484,276 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys,
7613
7484
  }
7614
7485
  }
7615
7486
 
7487
+ // src/cli/cmd/show/_shared-key-command.ts
7488
+ async function executeKeyCommand(i18nConfig, buckets, options, config) {
7489
+ let hasAnyKeys = false;
7490
+ for (const bucket of buckets) {
7491
+ if (options.bucket && bucket.type !== options.bucket) {
7492
+ continue;
7493
+ }
7494
+ const keyPatterns = bucket[config.filterType];
7495
+ if (!keyPatterns || keyPatterns.length === 0) {
7496
+ continue;
7497
+ }
7498
+ hasAnyKeys = true;
7499
+ console.log(`
7500
+ Bucket: ${bucket.type}`);
7501
+ console.log(
7502
+ `${capitalize(config.displayName)} key patterns: ${keyPatterns.join(", ")}`
7503
+ );
7504
+ for (const bucketConfig of bucket.paths) {
7505
+ const sourceLocale = resolveOverriddenLocale3(
7506
+ i18nConfig.locale.source,
7507
+ bucketConfig.delimiter
7508
+ );
7509
+ const sourcePath = bucketConfig.pathPattern.replace(
7510
+ /\[locale\]/g,
7511
+ sourceLocale
7512
+ );
7513
+ try {
7514
+ const loader = createBucketLoader(
7515
+ bucket.type,
7516
+ bucketConfig.pathPattern,
7517
+ {
7518
+ defaultLocale: sourceLocale,
7519
+ injectLocale: bucket.injectLocale
7520
+ },
7521
+ [],
7522
+ // Don't apply any filtering when reading
7523
+ [],
7524
+ []
7525
+ );
7526
+ loader.setDefaultLocale(sourceLocale);
7527
+ const data = await loader.pull(sourceLocale);
7528
+ if (!data || Object.keys(data).length === 0) {
7529
+ continue;
7530
+ }
7531
+ const matchedEntries = Object.entries(data).filter(
7532
+ ([key]) => matchesKeyPattern(key, keyPatterns)
7533
+ );
7534
+ if (matchedEntries.length > 0) {
7535
+ console.log(`
7536
+ Matches in ${sourcePath}:`);
7537
+ for (const [key, value] of matchedEntries) {
7538
+ const displayValue = formatDisplayValue(value);
7539
+ console.log(` - ${key}: ${displayValue}`);
7540
+ }
7541
+ console.log(
7542
+ `Total: ${matchedEntries.length} ${config.displayName} key(s)`
7543
+ );
7544
+ }
7545
+ } catch (error) {
7546
+ console.error(` Error reading ${sourcePath}: ${error.message}`);
7547
+ }
7548
+ }
7549
+ }
7550
+ if (!hasAnyKeys) {
7551
+ if (options.bucket) {
7552
+ console.log(
7553
+ `No ${config.displayName} keys configured for bucket: ${options.bucket}`
7554
+ );
7555
+ } else {
7556
+ console.log(`No ${config.displayName} keys configured in any bucket.`);
7557
+ }
7558
+ }
7559
+ }
7560
+ function capitalize(str) {
7561
+ return str.charAt(0).toUpperCase() + str.slice(1);
7562
+ }
7563
+
7564
+ // src/cli/cmd/show/locked-keys.ts
7565
+ var locked_keys_default = new Command7().command("locked-keys").description(
7566
+ "Show which key-value pairs in source files match lockedKeys patterns"
7567
+ ).option("--bucket <name>", "Only show locked keys for a specific bucket").helpOption("-h, --help", "Show help").action(async (options) => {
7568
+ const ora = Ora7();
7569
+ try {
7570
+ const i18nConfig = await getConfig();
7571
+ if (!i18nConfig) {
7572
+ throw new CLIError({
7573
+ message: "i18n.json not found. Please run `lingo.dev init` to initialize the project.",
7574
+ docUrl: "i18nNotFound"
7575
+ });
7576
+ }
7577
+ const buckets = getBuckets(i18nConfig);
7578
+ await executeKeyCommand(i18nConfig, buckets, options, {
7579
+ filterType: "lockedKeys",
7580
+ displayName: "locked"
7581
+ });
7582
+ } catch (error) {
7583
+ ora.fail(error.message);
7584
+ process.exit(1);
7585
+ }
7586
+ });
7587
+
7588
+ // src/cli/cmd/show/ignored-keys.ts
7589
+ import { Command as Command8 } from "interactive-commander";
7590
+ import Ora8 from "ora";
7591
+ var ignored_keys_default = new Command8().command("ignored-keys").description(
7592
+ "Show which key-value pairs in source files match ignoredKeys patterns"
7593
+ ).option("--bucket <name>", "Only show ignored keys for a specific bucket").helpOption("-h, --help", "Show help").action(async (options) => {
7594
+ const ora = Ora8();
7595
+ try {
7596
+ const i18nConfig = await getConfig();
7597
+ if (!i18nConfig) {
7598
+ throw new CLIError({
7599
+ message: "i18n.json not found. Please run `lingo.dev init` to initialize the project.",
7600
+ docUrl: "i18nNotFound"
7601
+ });
7602
+ }
7603
+ const buckets = getBuckets(i18nConfig);
7604
+ await executeKeyCommand(i18nConfig, buckets, options, {
7605
+ filterType: "ignoredKeys",
7606
+ displayName: "ignored"
7607
+ });
7608
+ } catch (error) {
7609
+ ora.fail(error.message);
7610
+ process.exit(1);
7611
+ }
7612
+ });
7613
+
7614
+ // src/cli/cmd/show/index.ts
7615
+ var show_default = new Command9().command("show").description("Display configuration, locales, and file paths").helpOption("-h, --help", "Show help").addCommand(config_default).addCommand(locale_default).addCommand(files_default).addCommand(locked_keys_default).addCommand(ignored_keys_default);
7616
+
7617
+ // src/cli/cmd/config/index.ts
7618
+ import { Command as Command13 } from "interactive-commander";
7619
+
7620
+ // src/cli/cmd/config/set.ts
7621
+ import { Command as Command10 } from "interactive-commander";
7622
+ import chalk2 from "chalk";
7623
+ import dedent from "dedent";
7624
+ import _26 from "lodash";
7625
+ var set_default = new Command10().name("set").description("Set or update a CLI setting in ~/.lingodotdevrc").addHelpText("afterAll", `
7626
+ Available keys:
7627
+ ${SETTINGS_KEYS.join("\n ")}`).argument(
7628
+ "<key>",
7629
+ "Configuration key to set (dot notation, e.g., auth.apiKey)"
7630
+ ).argument("<value>", "The configuration value to set").helpOption("-h, --help", "Show help").action(async (key, value) => {
7631
+ if (!SETTINGS_KEYS.includes(key)) {
7632
+ console.error(
7633
+ dedent`
7634
+ ${chalk2.red("\u2716")} Unknown configuration key: ${chalk2.bold(key)}
7635
+ Run ${chalk2.dim("lingo.dev config set --help")} to see available keys.
7636
+ `
7637
+ );
7638
+ process.exitCode = 1;
7639
+ return;
7640
+ }
7641
+ const current = loadSystemSettings();
7642
+ const updated = _26.cloneDeep(current);
7643
+ _26.set(updated, key, value);
7644
+ try {
7645
+ saveSettings(updated);
7646
+ console.log(`${chalk2.green("\u2714")} Set ${chalk2.bold(key)}`);
7647
+ } catch (err) {
7648
+ console.error(
7649
+ chalk2.red(
7650
+ `\u2716 Failed to save configuration: ${chalk2.dim(
7651
+ err instanceof Error ? err.message : String(err)
7652
+ )}`
7653
+ )
7654
+ );
7655
+ process.exitCode = 1;
7656
+ }
7657
+ });
7658
+
7659
+ // src/cli/cmd/config/unset.ts
7660
+ import { Command as Command11 } from "interactive-commander";
7661
+ import chalk3 from "chalk";
7662
+ import dedent2 from "dedent";
7663
+ import _27 from "lodash";
7664
+ var unset_default = new Command11().name("unset").description("Remove a CLI setting from ~/.lingodotdevrc").addHelpText("afterAll", `
7665
+ Available keys:
7666
+ ${SETTINGS_KEYS.join("\n ")}`).argument(
7667
+ "<key>",
7668
+ "Configuration key to remove (must match one of the available keys listed below)"
7669
+ ).helpOption("-h, --help", "Show help").action(async (key) => {
7670
+ if (!SETTINGS_KEYS.includes(key)) {
7671
+ console.error(
7672
+ dedent2`
7673
+ ${chalk3.red("\u2716")} Unknown configuration key: ${chalk3.bold(key)}
7674
+ Run ${chalk3.dim(
7675
+ "lingo.dev config unset --help"
7676
+ )} to see available keys.
7677
+ `
7678
+ );
7679
+ process.exitCode = 1;
7680
+ return;
7681
+ }
7682
+ const settings = loadSystemSettings();
7683
+ const currentValue = _27.get(settings, key);
7684
+ if (!_27.trim(String(currentValue || ""))) {
7685
+ console.log(`${chalk3.cyan("\u2139")} ${chalk3.bold(key)} is not set.`);
7686
+ return;
7687
+ } else {
7688
+ const updated = _27.cloneDeep(settings);
7689
+ _27.unset(updated, key);
7690
+ try {
7691
+ saveSettings(updated);
7692
+ console.log(
7693
+ `${chalk3.green("\u2714")} Removed configuration key ${chalk3.bold(key)}`
7694
+ );
7695
+ } catch (err) {
7696
+ console.error(
7697
+ chalk3.red(
7698
+ `\u2716 Failed to save configuration: ${chalk3.dim(
7699
+ err instanceof Error ? err.message : String(err)
7700
+ )}`
7701
+ )
7702
+ );
7703
+ process.exitCode = 1;
7704
+ }
7705
+ }
7706
+ });
7707
+
7708
+ // src/cli/cmd/config/get.ts
7709
+ import { Command as Command12 } from "interactive-commander";
7710
+ import chalk4 from "chalk";
7711
+ import _28 from "lodash";
7712
+ import dedent3 from "dedent";
7713
+ var get_default = new Command12().name("get").description("Display the value of a CLI setting from ~/.lingodotdevrc").addHelpText("afterAll", `
7714
+ Available keys:
7715
+ ${SETTINGS_KEYS.join("\n ")}`).argument(
7716
+ "<key>",
7717
+ "Configuration key to read (choose from the available keys listed below)"
7718
+ ).helpOption("-h, --help", "Show help").action(async (key) => {
7719
+ if (!SETTINGS_KEYS.includes(key)) {
7720
+ console.error(
7721
+ dedent3`
7722
+ ${chalk4.red("\u2716")} Unknown configuration key: ${chalk4.bold(key)}
7723
+ Run ${chalk4.dim("lingo.dev config get --help")} to see available keys.
7724
+ `
7725
+ );
7726
+ process.exitCode = 1;
7727
+ return;
7728
+ }
7729
+ const settings = loadSystemSettings();
7730
+ const value = _28.get(settings, key);
7731
+ if (!value) {
7732
+ console.log(`${chalk4.cyan("\u2139")} ${chalk4.bold(key)} is not set.`);
7733
+ return;
7734
+ }
7735
+ if (typeof value === "object") {
7736
+ console.log(JSON.stringify(value, null, 2));
7737
+ } else {
7738
+ console.log(value);
7739
+ }
7740
+ });
7741
+
7742
+ // src/cli/cmd/config/index.ts
7743
+ var config_default2 = new Command13().command("config").description(
7744
+ "Manage CLI settings (authentication, API keys) stored in ~/.lingodotdevrc"
7745
+ ).helpOption("-h, --help", "Show help").addCommand(set_default).addCommand(unset_default).addCommand(get_default);
7746
+
7616
7747
  // src/cli/cmd/i18n.ts
7748
+ import {
7749
+ bucketTypeSchema,
7750
+ localeCodeSchema,
7751
+ resolveOverriddenLocale as resolveOverriddenLocale4
7752
+ } from "@lingo.dev/_spec";
7753
+ import { Command as Command14 } from "interactive-commander";
7754
+ import Z3 from "zod";
7755
+ import _31 from "lodash";
7756
+ import Ora9 from "ora";
7617
7757
  import chalk6 from "chalk";
7618
7758
  import { createTwoFilesPatch } from "diff";
7619
7759
  import inquirer2 from "inquirer";
@@ -8065,7 +8205,7 @@ function createDeltaProcessor(fileKey) {
8065
8205
  }
8066
8206
 
8067
8207
  // src/cli/cmd/i18n.ts
8068
- var i18n_default = new Command12().command("i18n").description(
8208
+ var i18n_default = new Command14().command("i18n").description(
8069
8209
  "DEPRECATED: Run localization pipeline (prefer `run` command instead)"
8070
8210
  ).helpOption("-h, --help", "Show help").option(
8071
8211
  "--locale <locale>",
@@ -8104,7 +8244,7 @@ var i18n_default = new Command12().command("i18n").description(
8104
8244
  "Stop immediately on first error instead of continuing to process remaining buckets and locales (fail-fast mode)"
8105
8245
  ).action(async function(options) {
8106
8246
  updateGitignore();
8107
- const ora = Ora7();
8247
+ const ora = Ora9();
8108
8248
  let flags;
8109
8249
  try {
8110
8250
  flags = parseFlags(options);
@@ -8193,7 +8333,7 @@ var i18n_default = new Command12().command("i18n").description(
8193
8333
  ora.start("Creating i18n.lock...");
8194
8334
  for (const bucket of buckets) {
8195
8335
  for (const bucketPath of bucket.paths) {
8196
- const sourceLocale = resolveOverriddenLocale3(
8336
+ const sourceLocale = resolveOverriddenLocale4(
8197
8337
  i18nConfig.locale.source,
8198
8338
  bucketPath.delimiter
8199
8339
  );
@@ -8228,7 +8368,7 @@ var i18n_default = new Command12().command("i18n").description(
8228
8368
  let requiresUpdate = null;
8229
8369
  bucketLoop: for (const bucket of buckets) {
8230
8370
  for (const bucketPath of bucket.paths) {
8231
- const sourceLocale = resolveOverriddenLocale3(
8371
+ const sourceLocale = resolveOverriddenLocale4(
8232
8372
  i18nConfig.locale.source,
8233
8373
  bucketPath.delimiter
8234
8374
  );
@@ -8257,7 +8397,7 @@ var i18n_default = new Command12().command("i18n").description(
8257
8397
  break bucketLoop;
8258
8398
  }
8259
8399
  for (const _targetLocale of targetLocales) {
8260
- const targetLocale = resolveOverriddenLocale3(
8400
+ const targetLocale = resolveOverriddenLocale4(
8261
8401
  _targetLocale,
8262
8402
  bucketPath.delimiter
8263
8403
  );
@@ -8312,10 +8452,10 @@ var i18n_default = new Command12().command("i18n").description(
8312
8452
  console.log();
8313
8453
  ora.info(`Processing bucket: ${bucket.type}`);
8314
8454
  for (const bucketPath of bucket.paths) {
8315
- const bucketOra = Ora7({ indent: 2 }).info(
8455
+ const bucketOra = Ora9({ indent: 2 }).info(
8316
8456
  `Processing path: ${bucketPath.pathPattern}`
8317
8457
  );
8318
- const sourceLocale = resolveOverriddenLocale3(
8458
+ const sourceLocale = resolveOverriddenLocale4(
8319
8459
  i18nConfig.locale.source,
8320
8460
  bucketPath.delimiter
8321
8461
  );
@@ -8335,7 +8475,7 @@ var i18n_default = new Command12().command("i18n").description(
8335
8475
  await bucketLoader.init();
8336
8476
  let sourceData = await bucketLoader.pull(sourceLocale);
8337
8477
  for (const _targetLocale of targetLocales) {
8338
- const targetLocale = resolveOverriddenLocale3(
8478
+ const targetLocale = resolveOverriddenLocale4(
8339
8479
  _targetLocale,
8340
8480
  bucketPath.delimiter
8341
8481
  );
@@ -8360,7 +8500,7 @@ var i18n_default = new Command12().command("i18n").description(
8360
8500
  if (flags.key) {
8361
8501
  processableData = _31.pickBy(
8362
8502
  processableData,
8363
- (_35, key) => key === flags.key
8503
+ (_36, key) => key === flags.key
8364
8504
  );
8365
8505
  }
8366
8506
  if (flags.verbose) {
@@ -8717,9 +8857,9 @@ Editing value for: ${chalk6.cyan(key)}`);
8717
8857
  }
8718
8858
 
8719
8859
  // src/cli/cmd/lockfile.ts
8720
- import { Command as Command13 } from "interactive-commander";
8860
+ import { Command as Command15 } from "interactive-commander";
8721
8861
  import Z5 from "zod";
8722
- import Ora8 from "ora";
8862
+ import Ora10 from "ora";
8723
8863
 
8724
8864
  // src/cli/utils/lockfile.ts
8725
8865
  import fs12 from "fs";
@@ -8801,15 +8941,15 @@ var LockfileSchema = Z4.object({
8801
8941
  });
8802
8942
 
8803
8943
  // src/cli/cmd/lockfile.ts
8804
- import { resolveOverriddenLocale as resolveOverriddenLocale4 } from "@lingo.dev/_spec";
8805
- var lockfile_default = new Command13().command("lockfile").description(
8944
+ import { resolveOverriddenLocale as resolveOverriddenLocale5 } from "@lingo.dev/_spec";
8945
+ var lockfile_default = new Command15().command("lockfile").description(
8806
8946
  "Generate or refresh i18n.lock based on the current source locale content"
8807
8947
  ).helpOption("-h, --help", "Show help").option(
8808
8948
  "-f, --force",
8809
8949
  "Overwrite existing lockfile to reset translation tracking"
8810
8950
  ).action(async (options) => {
8811
8951
  const flags = flagsSchema.parse(options);
8812
- const ora = Ora8();
8952
+ const ora = Ora10();
8813
8953
  const lockfileHelper = createLockfileHelper();
8814
8954
  if (lockfileHelper.isLockfileExists() && !flags.force) {
8815
8955
  ora.warn(
@@ -8820,7 +8960,7 @@ var lockfile_default = new Command13().command("lockfile").description(
8820
8960
  const buckets = getBuckets(i18nConfig);
8821
8961
  for (const bucket of buckets) {
8822
8962
  for (const bucketConfig of bucket.paths) {
8823
- const sourceLocale = resolveOverriddenLocale4(
8963
+ const sourceLocale = resolveOverriddenLocale5(
8824
8964
  i18nConfig.locale.source,
8825
8965
  bucketConfig.delimiter
8826
8966
  );
@@ -8848,11 +8988,11 @@ var flagsSchema = Z5.object({
8848
8988
  });
8849
8989
 
8850
8990
  // src/cli/cmd/cleanup.ts
8851
- import { resolveOverriddenLocale as resolveOverriddenLocale5 } from "@lingo.dev/_spec";
8852
- import { Command as Command14 } from "interactive-commander";
8991
+ import { resolveOverriddenLocale as resolveOverriddenLocale6 } from "@lingo.dev/_spec";
8992
+ import { Command as Command16 } from "interactive-commander";
8853
8993
  import _33 from "lodash";
8854
- import Ora9 from "ora";
8855
- var cleanup_default = new Command14().command("cleanup").description(
8994
+ import Ora11 from "ora";
8995
+ var cleanup_default = new Command16().command("cleanup").description(
8856
8996
  "Remove translation keys from target locales that no longer exist in the source locale"
8857
8997
  ).helpOption("-h, --help", "Show help").option(
8858
8998
  "--locale <locale>",
@@ -8867,7 +9007,7 @@ var cleanup_default = new Command14().command("cleanup").description(
8867
9007
  "--verbose",
8868
9008
  "Print detailed output showing the specific keys to be removed for each locale"
8869
9009
  ).action(async function(options) {
8870
- const ora = Ora9();
9010
+ const ora = Ora11();
8871
9011
  const results = [];
8872
9012
  try {
8873
9013
  ora.start("Loading configuration...");
@@ -8885,11 +9025,11 @@ var cleanup_default = new Command14().command("cleanup").description(
8885
9025
  console.log();
8886
9026
  ora.info(`Processing bucket: ${bucket.type}`);
8887
9027
  for (const bucketConfig of bucket.paths) {
8888
- const sourceLocale = resolveOverriddenLocale5(
9028
+ const sourceLocale = resolveOverriddenLocale6(
8889
9029
  i18nConfig.locale.source,
8890
9030
  bucketConfig.delimiter
8891
9031
  );
8892
- const bucketOra = Ora9({ indent: 2 }).info(
9032
+ const bucketOra = Ora11({ indent: 2 }).info(
8893
9033
  `Processing path: ${bucketConfig.pathPattern}`
8894
9034
  );
8895
9035
  const bucketLoader = createBucketLoader(
@@ -8904,7 +9044,7 @@ var cleanup_default = new Command14().command("cleanup").description(
8904
9044
  const sourceData = await bucketLoader.pull(sourceLocale);
8905
9045
  const sourceKeys = Object.keys(sourceData);
8906
9046
  for (const _targetLocale of targetLocales) {
8907
- const targetLocale = resolveOverriddenLocale5(
9047
+ const targetLocale = resolveOverriddenLocale6(
8908
9048
  _targetLocale,
8909
9049
  bucketConfig.delimiter
8910
9050
  );
@@ -8982,14 +9122,14 @@ function displaySummary(results) {
8982
9122
  }
8983
9123
 
8984
9124
  // src/cli/cmd/mcp.ts
8985
- import { Command as Command15 } from "interactive-commander";
9125
+ import { Command as Command17 } from "interactive-commander";
8986
9126
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
8987
9127
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
8988
9128
  import Z6 from "zod";
8989
9129
  import { ReplexicaEngine } from "@lingo.dev/_sdk";
8990
- var mcp_default = new Command15().command("mcp").description(
9130
+ var mcp_default = new Command17().command("mcp").description(
8991
9131
  "Start a Model Context Protocol (MCP) server for AI assistant integration"
8992
- ).helpOption("-h, --help", "Show help").action(async (_35, program) => {
9132
+ ).helpOption("-h, --help", "Show help").action(async (_36, program) => {
8993
9133
  const apiKey = program.args[0];
8994
9134
  const settings = getSettings(apiKey);
8995
9135
  if (!settings.auth.apiKey) {
@@ -9037,7 +9177,7 @@ var mcp_default = new Command15().command("mcp").description(
9037
9177
  });
9038
9178
 
9039
9179
  // src/cli/cmd/ci/index.ts
9040
- import { Command as Command17 } from "interactive-commander";
9180
+ import { Command as Command19 } from "interactive-commander";
9041
9181
  import createOra from "ora";
9042
9182
 
9043
9183
  // src/cli/cmd/ci/flows/pull-request.ts
@@ -9064,7 +9204,7 @@ function escapeShellArg(arg) {
9064
9204
  }
9065
9205
 
9066
9206
  // src/cli/cmd/run/index.ts
9067
- import { Command as Command16 } from "interactive-commander";
9207
+ import { Command as Command18 } from "interactive-commander";
9068
9208
  import { exec } from "child_process";
9069
9209
  import path17 from "path";
9070
9210
  import { fileURLToPath } from "url";
@@ -9451,7 +9591,7 @@ async function setup(input2) {
9451
9591
  // src/cli/cmd/run/plan.ts
9452
9592
  import chalk11 from "chalk";
9453
9593
  import { Listr as Listr2 } from "listr2";
9454
- import { resolveOverriddenLocale as resolveOverriddenLocale6 } from "@lingo.dev/_spec";
9594
+ import { resolveOverriddenLocale as resolveOverriddenLocale7 } from "@lingo.dev/_spec";
9455
9595
  async function plan(input2) {
9456
9596
  console.log(chalk11.hex(colors.orange)("[Planning]"));
9457
9597
  let buckets = getBuckets(input2.config);
@@ -9532,12 +9672,12 @@ async function plan(input2) {
9532
9672
  continue;
9533
9673
  }
9534
9674
  }
9535
- const sourceLocale = resolveOverriddenLocale6(
9675
+ const sourceLocale = resolveOverriddenLocale7(
9536
9676
  _sourceLocale,
9537
9677
  bucketPath.delimiter
9538
9678
  );
9539
9679
  for (const _targetLocale of _targetLocales) {
9540
- const targetLocale = resolveOverriddenLocale6(
9680
+ const targetLocale = resolveOverriddenLocale7(
9541
9681
  _targetLocale,
9542
9682
  bucketPath.delimiter
9543
9683
  );
@@ -9616,7 +9756,7 @@ async function execute(input2) {
9616
9756
  const workerTasks = [];
9617
9757
  for (let i = 0; i < workersCount; i++) {
9618
9758
  const assignedTasks = ctx.tasks.filter(
9619
- (_35, idx) => idx % workersCount === i
9759
+ (_36, idx) => idx % workersCount === i
9620
9760
  );
9621
9761
  workerTasks.push(
9622
9762
  createWorkerTask({
@@ -9987,6 +10127,150 @@ var flagsSchema2 = z2.object({
9987
10127
  sound: z2.boolean().optional()
9988
10128
  });
9989
10129
 
10130
+ // src/cli/cmd/run/frozen.ts
10131
+ import chalk14 from "chalk";
10132
+ import { Listr as Listr4 } from "listr2";
10133
+ import _35 from "lodash";
10134
+ import { resolveOverriddenLocale as resolveOverriddenLocale8 } from "@lingo.dev/_spec";
10135
+ async function frozen(input2) {
10136
+ console.log(chalk14.hex(colors.orange)("[Frozen]"));
10137
+ let buckets = getBuckets(input2.config);
10138
+ if (input2.flags.bucket?.length) {
10139
+ buckets = buckets.filter((b) => input2.flags.bucket.includes(b.type));
10140
+ }
10141
+ if (input2.flags.file?.length) {
10142
+ buckets = buckets.map((bucket) => {
10143
+ const paths = bucket.paths.filter(
10144
+ (p) => input2.flags.file.some(
10145
+ (f) => p.pathPattern.includes(f) || minimatch(p.pathPattern, f)
10146
+ )
10147
+ );
10148
+ return { ...bucket, paths };
10149
+ }).filter((bucket) => bucket.paths.length > 0);
10150
+ }
10151
+ const _sourceLocale = input2.flags.sourceLocale || input2.config.locale.source;
10152
+ const _targetLocales = input2.flags.targetLocale || input2.config.locale.targets;
10153
+ return new Listr4(
10154
+ [
10155
+ {
10156
+ title: "Setting up localization cache",
10157
+ task: async (_ctx, task) => {
10158
+ const checkLockfileProcessor = createDeltaProcessor("");
10159
+ const lockfileExists = await checkLockfileProcessor.checkIfLockExists();
10160
+ if (!lockfileExists) {
10161
+ for (const bucket of buckets) {
10162
+ for (const bucketPath of bucket.paths) {
10163
+ const resolvedSourceLocale = resolveOverriddenLocale8(
10164
+ _sourceLocale,
10165
+ bucketPath.delimiter
10166
+ );
10167
+ const loader = createBucketLoader(
10168
+ bucket.type,
10169
+ bucketPath.pathPattern,
10170
+ {
10171
+ defaultLocale: resolvedSourceLocale,
10172
+ injectLocale: bucket.injectLocale,
10173
+ formatter: input2.config.formatter
10174
+ },
10175
+ bucket.lockedKeys,
10176
+ bucket.lockedPatterns,
10177
+ bucket.ignoredKeys
10178
+ );
10179
+ loader.setDefaultLocale(resolvedSourceLocale);
10180
+ await loader.init();
10181
+ const sourceData = await loader.pull(_sourceLocale);
10182
+ const delta = createDeltaProcessor(bucketPath.pathPattern);
10183
+ const checksums = await delta.createChecksums(sourceData);
10184
+ await delta.saveChecksums(checksums);
10185
+ }
10186
+ }
10187
+ task.title = "Localization cache initialized";
10188
+ } else {
10189
+ task.title = "Localization cache loaded";
10190
+ }
10191
+ }
10192
+ },
10193
+ {
10194
+ title: "Validating frozen state",
10195
+ enabled: () => !!input2.flags.frozen,
10196
+ task: async (_ctx, task) => {
10197
+ for (const bucket of buckets) {
10198
+ for (const bucketPath of bucket.paths) {
10199
+ const resolvedSourceLocale = resolveOverriddenLocale8(
10200
+ _sourceLocale,
10201
+ bucketPath.delimiter
10202
+ );
10203
+ const loader = createBucketLoader(
10204
+ bucket.type,
10205
+ bucketPath.pathPattern,
10206
+ {
10207
+ defaultLocale: resolvedSourceLocale,
10208
+ returnUnlocalizedKeys: true,
10209
+ injectLocale: bucket.injectLocale
10210
+ },
10211
+ bucket.lockedKeys
10212
+ );
10213
+ loader.setDefaultLocale(resolvedSourceLocale);
10214
+ await loader.init();
10215
+ const { unlocalizable: srcUnlocalizable, ...src } = await loader.pull(_sourceLocale);
10216
+ const delta = createDeltaProcessor(bucketPath.pathPattern);
10217
+ const sourceChecksums = await delta.createChecksums(src);
10218
+ const savedChecksums = await delta.loadChecksums();
10219
+ const updatedSourceData = _35.pickBy(
10220
+ src,
10221
+ (value, key) => sourceChecksums[key] !== savedChecksums[key]
10222
+ );
10223
+ if (Object.keys(updatedSourceData).length > 0) {
10224
+ throw new Error(
10225
+ `Localization data has changed; please update i18n.lock or run without --frozen. Details: Source file has been updated.`
10226
+ );
10227
+ }
10228
+ for (const _tgt of _targetLocales) {
10229
+ const resolvedTargetLocale = resolveOverriddenLocale8(
10230
+ _tgt,
10231
+ bucketPath.delimiter
10232
+ );
10233
+ const { unlocalizable: tgtUnlocalizable, ...tgt } = await loader.pull(resolvedTargetLocale);
10234
+ const missingKeys = _35.difference(
10235
+ Object.keys(src),
10236
+ Object.keys(tgt)
10237
+ );
10238
+ if (missingKeys.length > 0) {
10239
+ throw new Error(
10240
+ `Localization data has changed; please update i18n.lock or run without --frozen. Details: Target file is missing translations.`
10241
+ );
10242
+ }
10243
+ const extraKeys = _35.difference(
10244
+ Object.keys(tgt),
10245
+ Object.keys(src)
10246
+ );
10247
+ if (extraKeys.length > 0) {
10248
+ throw new Error(
10249
+ `Localization data has changed; please update i18n.lock or run without --frozen. Details: Target file has extra translations not present in the source file.`
10250
+ );
10251
+ }
10252
+ const unlocalizableDataDiff = !_35.isEqual(
10253
+ srcUnlocalizable,
10254
+ tgtUnlocalizable
10255
+ );
10256
+ if (unlocalizableDataDiff) {
10257
+ throw new Error(
10258
+ `Localization data has changed; please update i18n.lock or run without --frozen. Details: Unlocalizable data (such as booleans, dates, URLs, etc.) do not match.`
10259
+ );
10260
+ }
10261
+ }
10262
+ }
10263
+ }
10264
+ task.title = "No lockfile updates required";
10265
+ }
10266
+ }
10267
+ ],
10268
+ {
10269
+ rendererOptions: commonTaskRendererOptions
10270
+ }
10271
+ ).run(input2);
10272
+ }
10273
+
9990
10274
  // src/cli/cmd/run/_utils.ts
9991
10275
  async function determineAuthId(ctx) {
9992
10276
  const isByokMode = !!ctx.config?.provider;
@@ -10029,7 +10313,7 @@ function playSound(type) {
10029
10313
  setTimeout(resolve, 3e3);
10030
10314
  });
10031
10315
  }
10032
- var run_default = new Command16().command("run").description("Run localization pipeline").helpOption("-h, --help", "Show help").option(
10316
+ var run_default = new Command18().command("run").description("Run localization pipeline").helpOption("-h, --help", "Show help").option(
10033
10317
  "--source-locale <source-locale>",
10034
10318
  "Override the source locale from i18n.json for this run"
10035
10319
  ).option(
@@ -10051,6 +10335,9 @@ var run_default = new Command16().command("run").description("Run localization p
10051
10335
  ).option(
10052
10336
  "--force",
10053
10337
  "Force re-translation of all keys, bypassing change detection. Useful when you want to regenerate translations with updated AI models or translation settings"
10338
+ ).option(
10339
+ "--frozen",
10340
+ "Validate translations are up-to-date without making changes - fails if source files, target files, or lockfile are out of sync. Ideal for CI/CD to ensure translation consistency before deployment"
10054
10341
  ).option(
10055
10342
  "--api-key <api-key>",
10056
10343
  "Override API key from settings or environment variables"
@@ -10093,6 +10380,8 @@ var run_default = new Command16().command("run").description("Run localization p
10093
10380
  await renderSpacer();
10094
10381
  await plan(ctx);
10095
10382
  await renderSpacer();
10383
+ await frozen(ctx);
10384
+ await renderSpacer();
10096
10385
  await execute(ctx);
10097
10386
  await renderSpacer();
10098
10387
  await renderSummary(ctx.results);
@@ -10772,7 +11061,7 @@ var getPlatformKit = () => {
10772
11061
  };
10773
11062
 
10774
11063
  // src/cli/cmd/ci/index.ts
10775
- var ci_default = new Command17().command("ci").description("Run localization pipeline in CI/CD environment").helpOption("-h, --help", "Show help").option(
11064
+ var ci_default = new Command19().command("ci").description("Run localization pipeline in CI/CD environment").helpOption("-h, --help", "Show help").option(
10776
11065
  "--parallel [boolean]",
10777
11066
  "Process translations concurrently for faster execution. Defaults to false",
10778
11067
  parseBooleanArg
@@ -10858,12 +11147,12 @@ function parseBooleanArg(val) {
10858
11147
  import {
10859
11148
  bucketTypeSchema as bucketTypeSchema4,
10860
11149
  localeCodeSchema as localeCodeSchema3,
10861
- resolveOverriddenLocale as resolveOverriddenLocale7
11150
+ resolveOverriddenLocale as resolveOverriddenLocale9
10862
11151
  } from "@lingo.dev/_spec";
10863
- import { Command as Command18 } from "interactive-commander";
11152
+ import { Command as Command20 } from "interactive-commander";
10864
11153
  import Z11 from "zod";
10865
- import Ora10 from "ora";
10866
- import chalk14 from "chalk";
11154
+ import Ora12 from "ora";
11155
+ import chalk15 from "chalk";
10867
11156
  import Table from "cli-table3";
10868
11157
 
10869
11158
  // src/cli/utils/exit-gracefully.ts
@@ -10900,7 +11189,7 @@ function checkForPendingOperations() {
10900
11189
  }
10901
11190
 
10902
11191
  // src/cli/cmd/status.ts
10903
- var status_default = new Command18().command("status").description("Show the status of the localization process").helpOption("-h, --help", "Show help").option(
11192
+ var status_default = new Command20().command("status").description("Show the status of the localization process").helpOption("-h, --help", "Show help").option(
10904
11193
  "--locale <locale>",
10905
11194
  "Limit the report to specific target locales from i18n.json. Repeat the flag to include multiple locales. Defaults to all configured target locales",
10906
11195
  (val, prev) => prev ? [...prev, val] : [val]
@@ -10921,7 +11210,7 @@ var status_default = new Command18().command("status").description("Show the sta
10921
11210
  "--api-key <api-key>",
10922
11211
  "Override the API key from settings or environment variables for this run"
10923
11212
  ).action(async function(options) {
10924
- const ora = Ora10();
11213
+ const ora = Ora12();
10925
11214
  const flags = parseFlags2(options);
10926
11215
  let authId = null;
10927
11216
  try {
@@ -11002,10 +11291,10 @@ var status_default = new Command18().command("status").description("Show the sta
11002
11291
  console.log();
11003
11292
  ora.info(`Analyzing bucket: ${bucket.type}`);
11004
11293
  for (const bucketPath of bucket.paths) {
11005
- const bucketOra = Ora10({ indent: 2 }).info(
11294
+ const bucketOra = Ora12({ indent: 2 }).info(
11006
11295
  `Analyzing path: ${bucketPath.pathPattern}`
11007
11296
  );
11008
- const sourceLocale = resolveOverriddenLocale7(
11297
+ const sourceLocale = resolveOverriddenLocale9(
11009
11298
  i18nConfig.locale.source,
11010
11299
  bucketPath.delimiter
11011
11300
  );
@@ -11052,7 +11341,7 @@ var status_default = new Command18().command("status").description("Show the sta
11052
11341
  }
11053
11342
  fileStats[filePath].wordCount = sourceWordCount;
11054
11343
  for (const _targetLocale of targetLocales) {
11055
- const targetLocale = resolveOverriddenLocale7(
11344
+ const targetLocale = resolveOverriddenLocale9(
11056
11345
  _targetLocale,
11057
11346
  bucketPath.delimiter
11058
11347
  );
@@ -11079,7 +11368,7 @@ var status_default = new Command18().command("status").description("Show the sta
11079
11368
  (totalWordCount.get(_targetLocale) || 0) + sourceWordCount
11080
11369
  );
11081
11370
  bucketOra.succeed(
11082
- `[${sourceLocale} -> ${targetLocale}] ${chalk14.red(
11371
+ `[${sourceLocale} -> ${targetLocale}] ${chalk15.red(
11083
11372
  `0% complete`
11084
11373
  )} (0/${sourceKeys.length} keys) - file not found`
11085
11374
  );
@@ -11124,30 +11413,30 @@ var status_default = new Command18().command("status").description("Show the sta
11124
11413
  const completionPercent = (completeKeys.length / totalKeysInFile * 100).toFixed(1);
11125
11414
  if (missingKeys.length === 0 && updatedKeys.length === 0) {
11126
11415
  bucketOra.succeed(
11127
- `[${sourceLocale} -> ${targetLocale}] ${chalk14.green(
11416
+ `[${sourceLocale} -> ${targetLocale}] ${chalk15.green(
11128
11417
  `100% complete`
11129
11418
  )} (${completeKeys.length}/${totalKeysInFile} keys)`
11130
11419
  );
11131
11420
  } else {
11132
- const message = `[${sourceLocale} -> ${targetLocale}] ${parseFloat(completionPercent) > 50 ? chalk14.yellow(`${completionPercent}% complete`) : chalk14.red(`${completionPercent}% complete`)} (${completeKeys.length}/${totalKeysInFile} keys)`;
11421
+ const message = `[${sourceLocale} -> ${targetLocale}] ${parseFloat(completionPercent) > 50 ? chalk15.yellow(`${completionPercent}% complete`) : chalk15.red(`${completionPercent}% complete`)} (${completeKeys.length}/${totalKeysInFile} keys)`;
11133
11422
  bucketOra.succeed(message);
11134
11423
  if (flags.verbose) {
11135
11424
  if (missingKeys.length > 0) {
11136
11425
  console.log(
11137
- ` ${chalk14.red(`Missing:`)} ${missingKeys.length} keys, ~${wordsToTranslate} words`
11426
+ ` ${chalk15.red(`Missing:`)} ${missingKeys.length} keys, ~${wordsToTranslate} words`
11138
11427
  );
11139
11428
  console.log(
11140
- ` ${chalk14.red(`Missing:`)} ${missingKeys.length} keys, ~${wordsToTranslate} words`
11429
+ ` ${chalk15.red(`Missing:`)} ${missingKeys.length} keys, ~${wordsToTranslate} words`
11141
11430
  );
11142
11431
  console.log(
11143
- ` ${chalk14.dim(
11432
+ ` ${chalk15.dim(
11144
11433
  `Example missing: ${missingKeys.slice(0, 2).join(", ")}${missingKeys.length > 2 ? "..." : ""}`
11145
11434
  )}`
11146
11435
  );
11147
11436
  }
11148
11437
  if (updatedKeys.length > 0) {
11149
11438
  console.log(
11150
- ` ${chalk14.yellow(`Updated:`)} ${updatedKeys.length} keys that changed in source`
11439
+ ` ${chalk15.yellow(`Updated:`)} ${updatedKeys.length} keys that changed in source`
11151
11440
  );
11152
11441
  }
11153
11442
  }
@@ -11166,22 +11455,22 @@ var status_default = new Command18().command("status").description("Show the sta
11166
11455
  );
11167
11456
  const totalCompletedKeys = totalSourceKeyCount - totalKeysNeedingTranslation / targetLocales.length;
11168
11457
  console.log();
11169
- ora.succeed(chalk14.green(`Localization status completed.`));
11170
- console.log(chalk14.bold.cyan(`
11458
+ ora.succeed(chalk15.green(`Localization status completed.`));
11459
+ console.log(chalk15.bold.cyan(`
11171
11460
  \u2554\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\u2557`));
11172
- console.log(chalk14.bold.cyan(`\u2551 LOCALIZATION STATUS REPORT \u2551`));
11173
- console.log(chalk14.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`));
11174
- console.log(chalk14.bold(`
11461
+ console.log(chalk15.bold.cyan(`\u2551 LOCALIZATION STATUS REPORT \u2551`));
11462
+ console.log(chalk15.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`));
11463
+ console.log(chalk15.bold(`
11175
11464
  \u{1F4DD} SOURCE CONTENT:`));
11176
11465
  console.log(
11177
- `\u2022 Source language: ${chalk14.green(i18nConfig.locale.source)}`
11466
+ `\u2022 Source language: ${chalk15.green(i18nConfig.locale.source)}`
11178
11467
  );
11179
11468
  console.log(
11180
- `\u2022 Source keys: ${chalk14.yellow(
11469
+ `\u2022 Source keys: ${chalk15.yellow(
11181
11470
  totalSourceKeyCount.toString()
11182
11471
  )} keys across all files`
11183
11472
  );
11184
- console.log(chalk14.bold(`
11473
+ console.log(chalk15.bold(`
11185
11474
  \u{1F310} LANGUAGE BY LANGUAGE BREAKDOWN:`));
11186
11475
  const table = new Table({
11187
11476
  head: [
@@ -11211,19 +11500,19 @@ var status_default = new Command18().command("status").description("Show the sta
11211
11500
  let statusColor;
11212
11501
  if (stats.missing === totalSourceKeyCount) {
11213
11502
  statusText = "\u{1F534} Not started";
11214
- statusColor = chalk14.red;
11503
+ statusColor = chalk15.red;
11215
11504
  } else if (stats.missing === 0 && stats.updated === 0) {
11216
11505
  statusText = "\u2705 Complete";
11217
- statusColor = chalk14.green;
11506
+ statusColor = chalk15.green;
11218
11507
  } else if (parseFloat(percentComplete) > 80) {
11219
11508
  statusText = "\u{1F7E1} Almost done";
11220
- statusColor = chalk14.yellow;
11509
+ statusColor = chalk15.yellow;
11221
11510
  } else if (parseFloat(percentComplete) > 0) {
11222
11511
  statusText = "\u{1F7E0} In progress";
11223
- statusColor = chalk14.yellow;
11512
+ statusColor = chalk15.yellow;
11224
11513
  } else {
11225
11514
  statusText = "\u{1F534} Not started";
11226
- statusColor = chalk14.red;
11515
+ statusColor = chalk15.red;
11227
11516
  }
11228
11517
  const words = totalWordCount.get(locale) || 0;
11229
11518
  totalWordsToTranslate += words;
@@ -11231,17 +11520,17 @@ var status_default = new Command18().command("status").description("Show the sta
11231
11520
  locale,
11232
11521
  statusColor(statusText),
11233
11522
  `${stats.complete}/${totalSourceKeyCount} (${percentComplete}%)`,
11234
- stats.missing > 0 ? chalk14.red(stats.missing.toString()) : "0",
11235
- stats.updated > 0 ? chalk14.yellow(stats.updated.toString()) : "0",
11236
- totalNeeded > 0 ? chalk14.magenta(totalNeeded.toString()) : "0",
11523
+ stats.missing > 0 ? chalk15.red(stats.missing.toString()) : "0",
11524
+ stats.updated > 0 ? chalk15.yellow(stats.updated.toString()) : "0",
11525
+ totalNeeded > 0 ? chalk15.magenta(totalNeeded.toString()) : "0",
11237
11526
  words > 0 ? `~${words.toLocaleString()}` : "0"
11238
11527
  ]);
11239
11528
  }
11240
11529
  console.log(table.toString());
11241
- console.log(chalk14.bold(`
11530
+ console.log(chalk15.bold(`
11242
11531
  \u{1F4CA} USAGE ESTIMATE:`));
11243
11532
  console.log(
11244
- `\u2022 WORDS TO BE CONSUMED: ~${chalk14.yellow.bold(
11533
+ `\u2022 WORDS TO BE CONSUMED: ~${chalk15.yellow.bold(
11245
11534
  totalWordsToTranslate.toLocaleString()
11246
11535
  )} words across all languages`
11247
11536
  );
@@ -11259,11 +11548,11 @@ var status_default = new Command18().command("status").description("Show the sta
11259
11548
  }
11260
11549
  }
11261
11550
  if (flags.confirm && Object.keys(fileStats).length > 0) {
11262
- console.log(chalk14.bold(`
11551
+ console.log(chalk15.bold(`
11263
11552
  \u{1F4D1} BREAKDOWN BY FILE:`));
11264
11553
  Object.entries(fileStats).sort((a, b) => b[1].wordCount - a[1].wordCount).forEach(([path19, stats]) => {
11265
11554
  if (stats.sourceKeys === 0) return;
11266
- console.log(chalk14.bold(`
11555
+ console.log(chalk15.bold(`
11267
11556
  \u2022 ${path19}:`));
11268
11557
  console.log(
11269
11558
  ` ${stats.sourceKeys} source keys, ~${stats.wordCount.toLocaleString()} source words`
@@ -11283,13 +11572,13 @@ var status_default = new Command18().command("status").description("Show the sta
11283
11572
  const total = stats.sourceKeys;
11284
11573
  const completion = (complete / total * 100).toFixed(1);
11285
11574
  let status = "\u2705 Complete";
11286
- let statusColor = chalk14.green;
11575
+ let statusColor = chalk15.green;
11287
11576
  if (langStats.missing === total) {
11288
11577
  status = "\u274C Not started";
11289
- statusColor = chalk14.red;
11578
+ statusColor = chalk15.red;
11290
11579
  } else if (langStats.missing > 0 || langStats.updated > 0) {
11291
11580
  status = `\u26A0\uFE0F ${completion}% complete`;
11292
- statusColor = chalk14.yellow;
11581
+ statusColor = chalk15.yellow;
11293
11582
  }
11294
11583
  let details = "";
11295
11584
  if (langStats.missing > 0 || langStats.updated > 0) {
@@ -11313,16 +11602,16 @@ var status_default = new Command18().command("status").description("Show the sta
11313
11602
  const missingLanguages = targetLocales.filter(
11314
11603
  (locale) => languageStats[locale].complete === 0
11315
11604
  );
11316
- console.log(chalk14.bold.green(`
11605
+ console.log(chalk15.bold.green(`
11317
11606
  \u{1F4A1} OPTIMIZATION TIPS:`));
11318
11607
  if (missingLanguages.length > 0) {
11319
11608
  console.log(
11320
- `\u2022 ${chalk14.yellow(missingLanguages.join(", "))} ${missingLanguages.length === 1 ? "has" : "have"} no translations yet`
11609
+ `\u2022 ${chalk15.yellow(missingLanguages.join(", "))} ${missingLanguages.length === 1 ? "has" : "have"} no translations yet`
11321
11610
  );
11322
11611
  }
11323
11612
  if (completeLanguages.length > 0) {
11324
11613
  console.log(
11325
- `\u2022 ${chalk14.green(completeLanguages.join(", "))} ${completeLanguages.length === 1 ? "is" : "are"} completely translated`
11614
+ `\u2022 ${chalk15.green(completeLanguages.join(", "))} ${completeLanguages.length === 1 ? "is" : "are"} completely translated`
11326
11615
  );
11327
11616
  }
11328
11617
  if (targetLocales.length > 1) {
@@ -11403,10 +11692,10 @@ function validateParams2(i18nConfig, flags) {
11403
11692
  }
11404
11693
 
11405
11694
  // src/cli/cmd/may-the-fourth.ts
11406
- import { Command as Command19 } from "interactive-commander";
11695
+ import { Command as Command21 } from "interactive-commander";
11407
11696
  import * as cp from "node:child_process";
11408
11697
  import figlet2 from "figlet";
11409
- import chalk15 from "chalk";
11698
+ import chalk16 from "chalk";
11410
11699
  import { vice as vice2 } from "gradient-string";
11411
11700
  var colors2 = {
11412
11701
  orange: "#ff6600",
@@ -11416,11 +11705,11 @@ var colors2 = {
11416
11705
  grey: "#808080",
11417
11706
  red: "#ff0000"
11418
11707
  };
11419
- var may_the_fourth_default = new Command19().command("may-the-fourth").description("May the Fourth be with you").helpOption("-h, --help", "Show help").action(async () => {
11708
+ var may_the_fourth_default = new Command21().command("may-the-fourth").description("May the Fourth be with you").helpOption("-h, --help", "Show help").action(async () => {
11420
11709
  await renderClear2();
11421
11710
  await renderBanner2();
11422
11711
  await renderSpacer2();
11423
- console.log(chalk15.hex(colors2.yellow)("Loading the Star Wars movie..."));
11712
+ console.log(chalk16.hex(colors2.yellow)("Loading the Star Wars movie..."));
11424
11713
  await renderSpacer2();
11425
11714
  await new Promise((resolve, reject) => {
11426
11715
  const ssh = cp.spawn("ssh", ["starwarstel.net"], {
@@ -11439,12 +11728,12 @@ var may_the_fourth_default = new Command19().command("may-the-fourth").descripti
11439
11728
  });
11440
11729
  await renderSpacer2();
11441
11730
  console.log(
11442
- `${chalk15.hex(colors2.green)("We hope you enjoyed it! :)")} ${chalk15.hex(
11731
+ `${chalk16.hex(colors2.green)("We hope you enjoyed it! :)")} ${chalk16.hex(
11443
11732
  colors2.blue
11444
11733
  )("May the Fourth be with you! \u{1F680}")}`
11445
11734
  );
11446
11735
  await renderSpacer2();
11447
- console.log(chalk15.dim(`---`));
11736
+ console.log(chalk16.dim(`---`));
11448
11737
  await renderSpacer2();
11449
11738
  await renderHero2();
11450
11739
  });
@@ -11467,24 +11756,24 @@ async function renderBanner2() {
11467
11756
  }
11468
11757
  async function renderHero2() {
11469
11758
  console.log(
11470
- `\u26A1\uFE0F ${chalk15.hex(colors2.green)(
11759
+ `\u26A1\uFE0F ${chalk16.hex(colors2.green)(
11471
11760
  "Lingo.dev"
11472
11761
  )} - open-source, AI-powered i18n CLI for web & mobile localization.`
11473
11762
  );
11474
11763
  console.log(" ");
11475
- console.log(chalk15.hex(colors2.blue)("\u{1F4DA} Docs: https://lingo.dev/go/docs"));
11764
+ console.log(chalk16.hex(colors2.blue)("\u{1F4DA} Docs: https://lingo.dev/go/docs"));
11476
11765
  console.log(
11477
- chalk15.hex(colors2.blue)("\u2B50 Star the repo: https://lingo.dev/go/gh")
11766
+ chalk16.hex(colors2.blue)("\u2B50 Star the repo: https://lingo.dev/go/gh")
11478
11767
  );
11479
11768
  console.log(
11480
- chalk15.hex(colors2.blue)("\u{1F3AE} Join Discord: https://lingo.dev/go/discord")
11769
+ chalk16.hex(colors2.blue)("\u{1F3AE} Join Discord: https://lingo.dev/go/discord")
11481
11770
  );
11482
11771
  }
11483
11772
 
11484
11773
  // package.json
11485
11774
  var package_default = {
11486
11775
  name: "lingo.dev",
11487
- version: "0.112.0",
11776
+ version: "0.113.0",
11488
11777
  description: "Lingo.dev CLI",
11489
11778
  private: false,
11490
11779
  publishConfig: {
@@ -11733,11 +12022,11 @@ var package_default = {
11733
12022
  };
11734
12023
 
11735
12024
  // src/cli/cmd/purge.ts
11736
- import { Command as Command20 } from "interactive-commander";
11737
- import Ora11 from "ora";
11738
- import { resolveOverriddenLocale as resolveOverriddenLocale8 } from "@lingo.dev/_spec";
12025
+ import { Command as Command22 } from "interactive-commander";
12026
+ import Ora13 from "ora";
12027
+ import { resolveOverriddenLocale as resolveOverriddenLocale10 } from "@lingo.dev/_spec";
11739
12028
  import { confirm as confirm3 } from "@inquirer/prompts";
11740
- var purge_default = new Command20().command("purge").description(
12029
+ var purge_default = new Command22().command("purge").description(
11741
12030
  "WARNING: Permanently delete translation entries from bucket path patterns defined in i18n.json. This is a destructive operation that cannot be undone. Without any filters, ALL managed keys will be removed from EVERY target locale."
11742
12031
  ).helpOption("-h, --help", "Show help").option(
11743
12032
  "--bucket <bucket>",
@@ -11757,7 +12046,7 @@ var purge_default = new Command20().command("purge").description(
11757
12046
  "--yes-really",
11758
12047
  "Bypass safety confirmations for destructive operations. Use with extreme caution - this will delete translation keys without asking for confirmation. Intended for automated scripts and CI environments only."
11759
12048
  ).action(async function(options) {
11760
- const ora = Ora11();
12049
+ const ora = Ora13();
11761
12050
  try {
11762
12051
  ora.start("Loading configuration...");
11763
12052
  const i18nConfig = getConfig();
@@ -11791,11 +12080,11 @@ var purge_default = new Command20().command("purge").description(
11791
12080
  ora.info(`Processing bucket: ${bucket.type}`);
11792
12081
  for (const bucketPath of bucket.paths) {
11793
12082
  for (const _targetLocale of targetLocales) {
11794
- const targetLocale = resolveOverriddenLocale8(
12083
+ const targetLocale = resolveOverriddenLocale10(
11795
12084
  _targetLocale,
11796
12085
  bucketPath.delimiter
11797
12086
  );
11798
- const bucketOra = Ora11({ indent: 2 }).start(
12087
+ const bucketOra = Ora13({ indent: 2 }).start(
11799
12088
  `Processing path: ${bucketPath.pathPattern} [${targetLocale}]`
11800
12089
  );
11801
12090
  try {