lingo.dev 0.111.10 → 0.111.12

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
@@ -1060,9 +1060,9 @@ function makeGitlabInitializer(spinner) {
1060
1060
 
1061
1061
  // src/cli/cmd/init.ts
1062
1062
  import open2 from "open";
1063
- var openUrl = (path18) => {
1063
+ var openUrl = (path19) => {
1064
1064
  const settings = getSettings(void 0);
1065
- open2(`${settings.auth.webUrl}${path18}`, { wait: false });
1065
+ open2(`${settings.auth.webUrl}${path19}`, { wait: false });
1066
1066
  };
1067
1067
  var throwHelpError = (option, value) => {
1068
1068
  if (value === "help") {
@@ -1499,8 +1499,8 @@ var files_default = new Command6().command("files").description(
1499
1499
  } else if (type.target) {
1500
1500
  result.push(...targetPaths);
1501
1501
  }
1502
- result.forEach((path18) => {
1503
- console.log(path18);
1502
+ result.forEach((path19) => {
1503
+ console.log(path19);
1504
1504
  });
1505
1505
  }
1506
1506
  }
@@ -1829,8 +1829,8 @@ function extractCommentsFromJsonc(jsoncString) {
1829
1829
  const keyMatch = line.match(/^\s*["']?([^"':,\s]+)["']?\s*:/);
1830
1830
  if (keyMatch) {
1831
1831
  const key = keyMatch[1];
1832
- const path18 = contextStack.map((ctx) => ctx.key).filter(Boolean);
1833
- keyInfo = { key, path: path18 };
1832
+ const path19 = contextStack.map((ctx) => ctx.key).filter(Boolean);
1833
+ keyInfo = { key, path: path19 };
1834
1834
  }
1835
1835
  } else {
1836
1836
  keyInfo = findAssociatedKey(lines, commentData.lineIndex, contextStack);
@@ -1914,8 +1914,8 @@ function findAssociatedKey(lines, commentLineIndex, contextStack) {
1914
1914
  const keyMatch = line.match(/^\s*["']?([^"':,\s]+)["']?\s*:/);
1915
1915
  if (keyMatch) {
1916
1916
  const key = keyMatch[1];
1917
- const path18 = contextStack.map((ctx) => ctx.key).filter(Boolean);
1918
- return { key, path: path18 };
1917
+ const path19 = contextStack.map((ctx) => ctx.key).filter(Boolean);
1918
+ return { key, path: path19 };
1919
1919
  }
1920
1920
  }
1921
1921
  return { key: null, path: [] };
@@ -1934,9 +1934,9 @@ function updateContext(contextStack, line, parsedJson) {
1934
1934
  }
1935
1935
  }
1936
1936
  }
1937
- function setCommentAtPath(comments, path18, key, hint) {
1937
+ function setCommentAtPath(comments, path19, key, hint) {
1938
1938
  let current = comments;
1939
- for (const pathKey of path18) {
1939
+ for (const pathKey of path19) {
1940
1940
  if (!current[pathKey]) {
1941
1941
  current[pathKey] = {};
1942
1942
  }
@@ -2597,9 +2597,9 @@ function createHtmlLoader() {
2597
2597
  const bDepth = b.split("/").length;
2598
2598
  return aDepth - bDepth;
2599
2599
  });
2600
- paths.forEach((path18) => {
2601
- const value = data[path18];
2602
- const [nodePath, attribute] = path18.split("#");
2600
+ paths.forEach((path19) => {
2601
+ const value = data[path19];
2602
+ const [nodePath, attribute] = path19.split("#");
2603
2603
  const [rootTag, ...indices] = nodePath.split("/");
2604
2604
  let parent = rootTag === "head" ? document.head : document.body;
2605
2605
  let current = parent;
@@ -2928,36 +2928,99 @@ function _removeLocale(input2, locale) {
2928
2928
  return { ...input2, strings: newStrings };
2929
2929
  }
2930
2930
 
2931
- // src/cli/loaders/prettier.ts
2932
- import path11 from "path";
2931
+ // src/cli/loaders/unlocalizable.ts
2932
+ import _13 from "lodash";
2933
+ import _isUrl from "is-url";
2934
+ import { isValid, parseISO } from "date-fns";
2935
+ function createUnlocalizableLoader(returnUnlocalizedKeys = false) {
2936
+ return createLoader({
2937
+ async pull(locale, input2) {
2938
+ const unlocalizableKeys = _getUnlocalizableKeys(input2);
2939
+ const result = _13.omitBy(
2940
+ input2,
2941
+ (_35, key) => unlocalizableKeys.includes(key)
2942
+ );
2943
+ if (returnUnlocalizedKeys) {
2944
+ result.unlocalizable = _13.omitBy(
2945
+ input2,
2946
+ (_35, key) => !unlocalizableKeys.includes(key)
2947
+ );
2948
+ }
2949
+ return result;
2950
+ },
2951
+ async push(locale, data, originalInput) {
2952
+ const unlocalizableKeys = _getUnlocalizableKeys(originalInput);
2953
+ const result = _13.merge(
2954
+ {},
2955
+ data,
2956
+ _13.omitBy(originalInput, (_35, key) => !unlocalizableKeys.includes(key))
2957
+ );
2958
+ return result;
2959
+ }
2960
+ });
2961
+ }
2962
+ function _isSystemId(v) {
2963
+ return /^(?=.*[A-Z])(?=.*[a-z])(?=.*\d)[A-Za-z0-9]{22}$/.test(v);
2964
+ }
2965
+ function _isIsoDate(v) {
2966
+ return isValid(parseISO(v));
2967
+ }
2968
+ function _getUnlocalizableKeys(input2) {
2969
+ const rules = {
2970
+ isEmpty: (v) => _13.isEmpty(v),
2971
+ isNumber: (v) => typeof v === "number" || /^[0-9]+$/.test(v),
2972
+ isBoolean: (v) => _13.isBoolean(v),
2973
+ isIsoDate: (v) => _13.isString(v) && _isIsoDate(v),
2974
+ isSystemId: (v) => _13.isString(v) && _isSystemId(v),
2975
+ isUrl: (v) => _13.isString(v) && _isUrl(v)
2976
+ };
2977
+ if (!input2) {
2978
+ return [];
2979
+ }
2980
+ return Object.entries(input2).filter(([key, value]) => {
2981
+ for (const [ruleName, rule] of Object.entries(rules)) {
2982
+ if (rule(value)) {
2983
+ return true;
2984
+ }
2985
+ }
2986
+ return false;
2987
+ }).map(([key, _35]) => key);
2988
+ }
2989
+
2990
+ // src/cli/loaders/formatters/prettier.ts
2933
2991
  import prettier from "prettier";
2934
- function createPrettierLoader(options) {
2992
+
2993
+ // src/cli/loaders/formatters/_base.ts
2994
+ import path11 from "path";
2995
+ function createBaseFormatterLoader(options, formatFn) {
2935
2996
  const stage = options.stage || "both";
2997
+ const formatData = async (locale, data) => {
2998
+ const draftPath = options.bucketPathPattern.replaceAll("[locale]", locale);
2999
+ const finalPath = path11.resolve(draftPath);
3000
+ return await formatFn(data, finalPath);
3001
+ };
2936
3002
  return createLoader({
2937
3003
  async pull(locale, data) {
2938
3004
  if (!["pull", "both"].includes(stage)) {
2939
3005
  return data;
2940
3006
  }
2941
- const draftPath = options.bucketPathPattern.replaceAll(
2942
- "[locale]",
2943
- locale
2944
- );
2945
- const finalPath = path11.resolve(draftPath);
2946
- return await formatDataWithPrettier(data, finalPath, options);
3007
+ return await formatData(locale, data);
2947
3008
  },
2948
3009
  async push(locale, data) {
2949
3010
  if (!["push", "both"].includes(stage)) {
2950
3011
  return data;
2951
3012
  }
2952
- const draftPath = options.bucketPathPattern.replaceAll(
2953
- "[locale]",
2954
- locale
2955
- );
2956
- const finalPath = path11.resolve(draftPath);
2957
- return await formatDataWithPrettier(data, finalPath, options);
3013
+ return await formatData(locale, data);
2958
3014
  }
2959
3015
  });
2960
3016
  }
3017
+
3018
+ // src/cli/loaders/formatters/prettier.ts
3019
+ function createPrettierLoader(options) {
3020
+ return createBaseFormatterLoader(options, async (data, filePath) => {
3021
+ return await formatDataWithPrettier(data, filePath, options);
3022
+ });
3023
+ }
2961
3024
  async function loadPrettierConfig(filePath) {
2962
3025
  try {
2963
3026
  const config = await prettier.resolveConfig(filePath);
@@ -3000,63 +3063,89 @@ async function formatDataWithPrettier(data, filePath, options) {
3000
3063
  }
3001
3064
  }
3002
3065
 
3003
- // src/cli/loaders/unlocalizable.ts
3004
- import _13 from "lodash";
3005
- import _isUrl from "is-url";
3006
- import { isValid, parseISO } from "date-fns";
3007
- function createUnlocalizableLoader(returnUnlocalizedKeys = false) {
3008
- return createLoader({
3009
- async pull(locale, input2) {
3010
- const unlocalizableKeys = _getUnlocalizableKeys(input2);
3011
- const result = _13.omitBy(
3012
- input2,
3013
- (_35, key) => unlocalizableKeys.includes(key)
3014
- );
3015
- if (returnUnlocalizedKeys) {
3016
- result.unlocalizable = _13.omitBy(
3017
- input2,
3018
- (_35, key) => !unlocalizableKeys.includes(key)
3066
+ // src/cli/loaders/formatters/biome.ts
3067
+ import path12 from "path";
3068
+ import fs9 from "fs/promises";
3069
+ import { Biome, Distribution } from "@biomejs/js-api";
3070
+ var shownWarnings = /* @__PURE__ */ new Set();
3071
+ function createBiomeLoader(options) {
3072
+ return createBaseFormatterLoader(options, async (data, filePath) => {
3073
+ return await formatDataWithBiome(data, filePath, options);
3074
+ });
3075
+ }
3076
+ async function findBiomeConfig(startPath) {
3077
+ let currentDir = path12.dirname(startPath);
3078
+ const root = path12.parse(currentDir).root;
3079
+ while (currentDir !== root) {
3080
+ for (const configName of ["biome.json", "biome.jsonc"]) {
3081
+ const configPath = path12.join(currentDir, configName);
3082
+ try {
3083
+ await fs9.access(configPath);
3084
+ return configPath;
3085
+ } catch {
3086
+ }
3087
+ }
3088
+ const parentDir = path12.dirname(currentDir);
3089
+ if (parentDir === currentDir) break;
3090
+ currentDir = parentDir;
3091
+ }
3092
+ return null;
3093
+ }
3094
+ async function formatDataWithBiome(data, filePath, options) {
3095
+ let configPath = null;
3096
+ try {
3097
+ const biome = await Biome.create({
3098
+ distribution: Distribution.NODE
3099
+ });
3100
+ const openResult = biome.openProject(".");
3101
+ const projectKey = openResult.projectKey;
3102
+ configPath = await findBiomeConfig(filePath);
3103
+ if (!configPath && !options.alwaysFormat) {
3104
+ return data;
3105
+ }
3106
+ if (configPath) {
3107
+ const configContent = await fs9.readFile(configPath, "utf-8");
3108
+ try {
3109
+ const config = JSON.parse(configContent);
3110
+ biome.applyConfiguration(projectKey, config);
3111
+ } catch (parseError) {
3112
+ throw new Error(
3113
+ `Invalid Biome configuration in ${configPath}: ${parseError instanceof Error ? parseError.message : "JSON parse error"}`
3019
3114
  );
3020
3115
  }
3021
- return result;
3022
- },
3023
- async push(locale, data, originalInput) {
3024
- const unlocalizableKeys = _getUnlocalizableKeys(originalInput);
3025
- const result = _13.merge(
3026
- {},
3027
- data,
3028
- _13.omitBy(originalInput, (_35, key) => !unlocalizableKeys.includes(key))
3116
+ }
3117
+ const formatted = biome.formatContent(projectKey, data, {
3118
+ filePath
3119
+ });
3120
+ return formatted.content;
3121
+ } catch (error) {
3122
+ const ext2 = path12.extname(filePath);
3123
+ if (!shownWarnings.has(ext2)) {
3124
+ shownWarnings.add(ext2);
3125
+ console.log();
3126
+ console.log(
3127
+ `\u26A0\uFE0F Biome does not support ${ext2} files - skipping formatting`
3029
3128
  );
3030
- return result;
3129
+ if (error instanceof Error && error.message) {
3130
+ console.log(` ${error.message}`);
3131
+ }
3031
3132
  }
3032
- });
3033
- }
3034
- function _isSystemId(v) {
3035
- return /^(?=.*[A-Z])(?=.*[a-z])(?=.*\d)[A-Za-z0-9]{22}$/.test(v);
3036
- }
3037
- function _isIsoDate(v) {
3038
- return isValid(parseISO(v));
3133
+ return data;
3134
+ }
3039
3135
  }
3040
- function _getUnlocalizableKeys(input2) {
3041
- const rules = {
3042
- isEmpty: (v) => _13.isEmpty(v),
3043
- isNumber: (v) => typeof v === "number" || /^[0-9]+$/.test(v),
3044
- isBoolean: (v) => _13.isBoolean(v),
3045
- isIsoDate: (v) => _13.isString(v) && _isIsoDate(v),
3046
- isSystemId: (v) => _13.isString(v) && _isSystemId(v),
3047
- isUrl: (v) => _13.isString(v) && _isUrl(v)
3048
- };
3049
- if (!input2) {
3050
- return [];
3136
+
3137
+ // src/cli/loaders/formatters/index.ts
3138
+ function createFormatterLoader(formatterType, parser, bucketPathPattern) {
3139
+ if (formatterType === void 0) {
3140
+ return createPrettierLoader({ parser, bucketPathPattern });
3051
3141
  }
3052
- return Object.entries(input2).filter(([key, value]) => {
3053
- for (const [ruleName, rule] of Object.entries(rules)) {
3054
- if (rule(value)) {
3055
- return true;
3056
- }
3057
- }
3058
- return false;
3059
- }).map(([key, _35]) => key);
3142
+ if (formatterType === "prettier") {
3143
+ return createPrettierLoader({ parser, bucketPathPattern });
3144
+ }
3145
+ if (formatterType === "biome") {
3146
+ return createBiomeLoader({ bucketPathPattern });
3147
+ }
3148
+ throw new Error(`Unknown formatter: ${formatterType}`);
3060
3149
  }
3061
3150
 
3062
3151
  // src/cli/loaders/po/index.ts
@@ -3677,7 +3766,7 @@ function createSrtLoader() {
3677
3766
  }
3678
3767
 
3679
3768
  // src/cli/loaders/dato/index.ts
3680
- import fs9 from "fs";
3769
+ import fs10 from "fs";
3681
3770
  import JSON52 from "json5";
3682
3771
 
3683
3772
  // src/cli/loaders/dato/_base.ts
@@ -4242,24 +4331,24 @@ function createRawDatoValue(parsedDatoValue, originalRawDatoValue, isClean = fal
4242
4331
  }
4243
4332
  function serializeStructuredText(rawStructuredText) {
4244
4333
  return serializeStructuredTextNode(rawStructuredText);
4245
- function serializeStructuredTextNode(node, path18 = [], acc = {}) {
4334
+ function serializeStructuredTextNode(node, path19 = [], acc = {}) {
4246
4335
  if ("document" in node) {
4247
4336
  return serializeStructuredTextNode(
4248
4337
  node.document,
4249
- [...path18, "document"],
4338
+ [...path19, "document"],
4250
4339
  acc
4251
4340
  );
4252
4341
  }
4253
4342
  if (!_18.isNil(node.value)) {
4254
- acc[[...path18, "value"].join(".")] = node.value;
4343
+ acc[[...path19, "value"].join(".")] = node.value;
4255
4344
  } else if (_18.get(node, "type") === "block") {
4256
- acc[[...path18, "item"].join(".")] = serializeBlock(node.item);
4345
+ acc[[...path19, "item"].join(".")] = serializeBlock(node.item);
4257
4346
  }
4258
4347
  if (node.children) {
4259
4348
  for (let i = 0; i < node.children.length; i++) {
4260
4349
  serializeStructuredTextNode(
4261
4350
  node.children[i],
4262
- [...path18, i.toString()],
4351
+ [...path19, i.toString()],
4263
4352
  acc
4264
4353
  );
4265
4354
  }
@@ -4326,8 +4415,8 @@ function deserializeBlockList(parsedBlockList, originalRawBlockList, isClean = f
4326
4415
  }
4327
4416
  function deserializeStructuredText(parsedStructuredText, originalRawStructuredText) {
4328
4417
  const result = _18.cloneDeep(originalRawStructuredText);
4329
- for (const [path18, value] of _18.entries(parsedStructuredText)) {
4330
- const realPath = _18.chain(path18.split(".")).flatMap((s) => !_18.isNaN(_18.toNumber(s)) ? ["children", s] : s).value();
4418
+ for (const [path19, value] of _18.entries(parsedStructuredText)) {
4419
+ const realPath = _18.chain(path19.split(".")).flatMap((s) => !_18.isNaN(_18.toNumber(s)) ? ["children", s] : s).value();
4331
4420
  const deserializedValue = createRawDatoValue(
4332
4421
  value,
4333
4422
  _18.get(originalRawStructuredText, realPath),
@@ -4364,12 +4453,12 @@ function _isVideo(rawDatoValue) {
4364
4453
  // src/cli/loaders/dato/index.ts
4365
4454
  function createDatoLoader(configFilePath) {
4366
4455
  try {
4367
- const configContent = fs9.readFileSync(configFilePath, "utf-8");
4456
+ const configContent = fs10.readFileSync(configFilePath, "utf-8");
4368
4457
  const datoConfig = datoConfigSchema.parse(JSON52.parse(configContent));
4369
4458
  return composeLoaders(
4370
4459
  createDatoApiLoader(
4371
4460
  datoConfig,
4372
- (updatedConfig) => fs9.writeFileSync(
4461
+ (updatedConfig) => fs10.writeFileSync(
4373
4462
  configFilePath,
4374
4463
  JSON52.stringify(updatedConfig, null, 2)
4375
4464
  )
@@ -4753,15 +4842,15 @@ function parseTypeScript(input2) {
4753
4842
  function extractStringsFromDefaultExport(ast) {
4754
4843
  let extracted = {};
4755
4844
  traverse(ast, {
4756
- ExportDefaultDeclaration(path18) {
4757
- const { declaration } = path18.node;
4845
+ ExportDefaultDeclaration(path19) {
4846
+ const { declaration } = path19.node;
4758
4847
  const decl = unwrapTSAsExpression(declaration);
4759
4848
  if (t.isObjectExpression(decl)) {
4760
4849
  extracted = objectExpressionToObject(decl);
4761
4850
  } else if (t.isArrayExpression(decl)) {
4762
4851
  extracted = arrayExpressionToArray(decl);
4763
4852
  } else if (t.isIdentifier(decl)) {
4764
- const binding = path18.scope.bindings[decl.name];
4853
+ const binding = path19.scope.bindings[decl.name];
4765
4854
  if (binding && t.isVariableDeclarator(binding.path.node) && binding.path.node.init) {
4766
4855
  const initRaw = binding.path.node.init;
4767
4856
  const init = initRaw ? unwrapTSAsExpression(initRaw) : initRaw;
@@ -4826,8 +4915,8 @@ function arrayExpressionToArray(arrayExpression) {
4826
4915
  function updateStringsInDefaultExport(ast, data) {
4827
4916
  let modified = false;
4828
4917
  traverse(ast, {
4829
- ExportDefaultDeclaration(path18) {
4830
- const { declaration } = path18.node;
4918
+ ExportDefaultDeclaration(path19) {
4919
+ const { declaration } = path19.node;
4831
4920
  const decl = unwrapTSAsExpression(declaration);
4832
4921
  if (t.isObjectExpression(decl)) {
4833
4922
  modified = updateStringsInObjectExpression(decl, data) || modified;
@@ -4836,7 +4925,7 @@ function updateStringsInDefaultExport(ast, data) {
4836
4925
  modified = updateStringsInArrayExpression(decl, data) || modified;
4837
4926
  }
4838
4927
  } else if (t.isIdentifier(decl)) {
4839
- modified = updateStringsInExportedIdentifier(path18, data) || modified;
4928
+ modified = updateStringsInExportedIdentifier(path19, data) || modified;
4840
4929
  }
4841
4930
  }
4842
4931
  });
@@ -4907,9 +4996,9 @@ function updateStringsInArrayExpression(arrayExpression, incoming) {
4907
4996
  });
4908
4997
  return modified;
4909
4998
  }
4910
- function updateStringsInExportedIdentifier(path18, data) {
4911
- const exportName = path18.node.declaration.name;
4912
- const binding = path18.scope.bindings[exportName];
4999
+ function updateStringsInExportedIdentifier(path19, data) {
5000
+ const exportName = path19.node.declaration.name;
5001
+ const binding = path19.scope.bindings[exportName];
4913
5002
  if (!binding || !binding.path.node) return false;
4914
5003
  if (t.isVariableDeclarator(binding.path.node) && binding.path.node.init) {
4915
5004
  const initRaw = binding.path.node.init;
@@ -5815,11 +5904,11 @@ var qmarksTestNoExtDot = ([$0]) => {
5815
5904
  return (f) => f.length === len && f !== "." && f !== "..";
5816
5905
  };
5817
5906
  var defaultPlatform = typeof process === "object" && process ? typeof process.env === "object" && process.env && process.env.__MINIMATCH_TESTING_PLATFORM__ || process.platform : "posix";
5818
- var path12 = {
5907
+ var path13 = {
5819
5908
  win32: { sep: "\\" },
5820
5909
  posix: { sep: "/" }
5821
5910
  };
5822
- var sep = defaultPlatform === "win32" ? path12.win32.sep : path12.posix.sep;
5911
+ var sep = defaultPlatform === "win32" ? path13.win32.sep : path13.posix.sep;
5823
5912
  minimatch.sep = sep;
5824
5913
  var GLOBSTAR = Symbol("globstar **");
5825
5914
  minimatch.GLOBSTAR = GLOBSTAR;
@@ -6511,11 +6600,11 @@ function _getAllKeys(obj, prefix = "") {
6511
6600
  let keys = [];
6512
6601
  for (const key in obj) {
6513
6602
  if (!Object.prototype.hasOwnProperty.call(obj, key)) continue;
6514
- const path18 = prefix ? `${prefix}.${key}` : key;
6603
+ const path19 = prefix ? `${prefix}.${key}` : key;
6515
6604
  if (typeof obj[key] === "object" && obj[key] !== null && !Array.isArray(obj[key])) {
6516
- keys = keys.concat(_getAllKeys(obj[key], path18));
6605
+ keys = keys.concat(_getAllKeys(obj[key], path19));
6517
6606
  } else {
6518
- keys.push(path18);
6607
+ keys.push(path19);
6519
6608
  }
6520
6609
  }
6521
6610
  return keys;
@@ -7028,19 +7117,19 @@ function createJsonDictionaryLoader() {
7028
7117
  );
7029
7118
  return input2;
7030
7119
  }
7031
- function walk(obj, dataNode, path18 = []) {
7120
+ function walk(obj, dataNode, path19 = []) {
7032
7121
  if (Array.isArray(obj) && Array.isArray(dataNode)) {
7033
7122
  obj.forEach(
7034
- (item, idx) => walk(item, dataNode[idx], [...path18, String(idx)])
7123
+ (item, idx) => walk(item, dataNode[idx], [...path19, String(idx)])
7035
7124
  );
7036
7125
  } else if (obj && typeof obj === "object" && dataNode && typeof dataNode === "object" && !Array.isArray(dataNode)) {
7037
7126
  for (const key of Object.keys(obj)) {
7038
7127
  if (dataNode.hasOwnProperty(key)) {
7039
- walk(obj[key], dataNode[key], [...path18, key]);
7128
+ walk(obj[key], dataNode[key], [...path19, key]);
7040
7129
  }
7041
7130
  }
7042
7131
  } else if (obj && typeof obj === "object" && !Array.isArray(obj) && typeof dataNode === "string") {
7043
- setNestedLocale(input2, path18, locale, dataNode, originalLocale);
7132
+ setNestedLocale(input2, path19, locale, dataNode, originalLocale);
7044
7133
  }
7045
7134
  }
7046
7135
  walk(input2, data);
@@ -7068,14 +7157,14 @@ function extractTranslatables(obj, locale) {
7068
7157
  function isTranslatableObject(obj, locale) {
7069
7158
  return obj && typeof obj === "object" && !Array.isArray(obj) && Object.prototype.hasOwnProperty.call(obj, locale);
7070
7159
  }
7071
- function setNestedLocale(obj, path18, locale, value, originalLocale) {
7160
+ function setNestedLocale(obj, path19, locale, value, originalLocale) {
7072
7161
  let curr = obj;
7073
- for (let i = 0; i < path18.length - 1; i++) {
7074
- const key = path18[i];
7162
+ for (let i = 0; i < path19.length - 1; i++) {
7163
+ const key = path19[i];
7075
7164
  if (!(key in curr)) curr[key] = {};
7076
7165
  curr = curr[key];
7077
7166
  }
7078
- const last = path18[path18.length - 1];
7167
+ const last = path19[path19.length - 1];
7079
7168
  if (curr[last] && typeof curr[last] === "object") {
7080
7169
  curr[last][locale] = value;
7081
7170
  if (originalLocale && curr[last][originalLocale]) {
@@ -7118,7 +7207,7 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys,
7118
7207
  case "html":
7119
7208
  return composeLoaders(
7120
7209
  createTextFileLoader(bucketPathPattern),
7121
- createPrettierLoader({ parser: "html", bucketPathPattern }),
7210
+ createFormatterLoader(options.formatter, "html", bucketPathPattern),
7122
7211
  createHtmlLoader(),
7123
7212
  createSyncLoader(),
7124
7213
  createUnlocalizableLoader(options.returnUnlocalizedKeys)
@@ -7133,7 +7222,7 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys,
7133
7222
  case "json":
7134
7223
  return composeLoaders(
7135
7224
  createTextFileLoader(bucketPathPattern),
7136
- createPrettierLoader({ parser: "json", bucketPathPattern }),
7225
+ createFormatterLoader(options.formatter, "json", bucketPathPattern),
7137
7226
  createJsonLoader(),
7138
7227
  createEnsureKeyOrderLoader(),
7139
7228
  createFlatLoader(),
@@ -7167,7 +7256,7 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys,
7167
7256
  case "markdown":
7168
7257
  return composeLoaders(
7169
7258
  createTextFileLoader(bucketPathPattern),
7170
- createPrettierLoader({ parser: "markdown", bucketPathPattern }),
7259
+ createFormatterLoader(options.formatter, "markdown", bucketPathPattern),
7171
7260
  createMarkdownLoader(),
7172
7261
  createSyncLoader(),
7173
7262
  createUnlocalizableLoader(options.returnUnlocalizedKeys)
@@ -7175,10 +7264,7 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys,
7175
7264
  case "mdx":
7176
7265
  return composeLoaders(
7177
7266
  createTextFileLoader(bucketPathPattern),
7178
- createPrettierLoader({
7179
- parser: "mdx",
7180
- bucketPathPattern
7181
- }),
7267
+ createFormatterLoader(options.formatter, "mdx", bucketPathPattern),
7182
7268
  createMdxCodePlaceholderLoader(),
7183
7269
  createMdxLockedPatternsLoader(lockedPatterns),
7184
7270
  createMdxFrontmatterSplitLoader(),
@@ -7239,7 +7325,7 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys,
7239
7325
  case "yaml":
7240
7326
  return composeLoaders(
7241
7327
  createTextFileLoader(bucketPathPattern),
7242
- createPrettierLoader({ parser: "yaml", bucketPathPattern }),
7328
+ createFormatterLoader(options.formatter, "yaml", bucketPathPattern),
7243
7329
  createYamlLoader(),
7244
7330
  createFlatLoader(),
7245
7331
  createEnsureKeyOrderLoader(),
@@ -7250,7 +7336,7 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys,
7250
7336
  case "yaml-root-key":
7251
7337
  return composeLoaders(
7252
7338
  createTextFileLoader(bucketPathPattern),
7253
- createPrettierLoader({ parser: "yaml", bucketPathPattern }),
7339
+ createFormatterLoader(options.formatter, "yaml", bucketPathPattern),
7254
7340
  createYamlLoader(),
7255
7341
  createRootKeyLoader(true),
7256
7342
  createFlatLoader(),
@@ -7261,7 +7347,7 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys,
7261
7347
  case "flutter":
7262
7348
  return composeLoaders(
7263
7349
  createTextFileLoader(bucketPathPattern),
7264
- createPrettierLoader({ parser: "json", bucketPathPattern }),
7350
+ createFormatterLoader(options.formatter, "json", bucketPathPattern),
7265
7351
  createJsonLoader(),
7266
7352
  createEnsureKeyOrderLoader(),
7267
7353
  createFlutterLoader(),
@@ -7330,7 +7416,11 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys,
7330
7416
  case "typescript":
7331
7417
  return composeLoaders(
7332
7418
  createTextFileLoader(bucketPathPattern),
7333
- createPrettierLoader({ parser: "typescript", bucketPathPattern }),
7419
+ createFormatterLoader(
7420
+ options.formatter,
7421
+ "typescript",
7422
+ bucketPathPattern
7423
+ ),
7334
7424
  createTypescriptLoader(),
7335
7425
  createFlatLoader(),
7336
7426
  createEnsureKeyOrderLoader(),
@@ -7349,7 +7439,7 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys,
7349
7439
  case "json-dictionary":
7350
7440
  return composeLoaders(
7351
7441
  createTextFileLoader(bucketPathPattern),
7352
- createPrettierLoader({ parser: "json", bucketPathPattern }),
7442
+ createFormatterLoader(options.formatter, "json", bucketPathPattern),
7353
7443
  createJsonLoader(),
7354
7444
  createJsonDictionaryLoader(),
7355
7445
  createEnsureKeyOrderLoader(),
@@ -7694,29 +7784,29 @@ import _30 from "lodash";
7694
7784
  import z from "zod";
7695
7785
 
7696
7786
  // src/cli/utils/fs.ts
7697
- import * as fs10 from "fs";
7698
- import * as path13 from "path";
7787
+ import * as fs11 from "fs";
7788
+ import * as path14 from "path";
7699
7789
  function tryReadFile(filePath, defaultValue = null) {
7700
7790
  try {
7701
- const content = fs10.readFileSync(filePath, "utf-8");
7791
+ const content = fs11.readFileSync(filePath, "utf-8");
7702
7792
  return content;
7703
7793
  } catch (error) {
7704
7794
  return defaultValue;
7705
7795
  }
7706
7796
  }
7707
7797
  function writeFile(filePath, content) {
7708
- const dir = path13.dirname(filePath);
7709
- if (!fs10.existsSync(dir)) {
7710
- fs10.mkdirSync(dir, { recursive: true });
7798
+ const dir = path14.dirname(filePath);
7799
+ if (!fs11.existsSync(dir)) {
7800
+ fs11.mkdirSync(dir, { recursive: true });
7711
7801
  }
7712
- fs10.writeFileSync(filePath, content);
7802
+ fs11.writeFileSync(filePath, content);
7713
7803
  }
7714
7804
  function checkIfFileExists(filePath) {
7715
- return fs10.existsSync(filePath);
7805
+ return fs11.existsSync(filePath);
7716
7806
  }
7717
7807
 
7718
7808
  // src/cli/utils/delta.ts
7719
- import * as path14 from "path";
7809
+ import * as path15 from "path";
7720
7810
  import YAML4 from "yaml";
7721
7811
  var LockSchema = z.object({
7722
7812
  version: z.literal(1).default(1),
@@ -7733,7 +7823,7 @@ var LockSchema = z.object({
7733
7823
  ).default({})
7734
7824
  });
7735
7825
  function createDeltaProcessor(fileKey) {
7736
- const lockfilePath = path14.join(process.cwd(), "i18n.lock");
7826
+ const lockfilePath = path15.join(process.cwd(), "i18n.lock");
7737
7827
  return {
7738
7828
  async checkIfLockExists() {
7739
7829
  return checkIfFileExists(lockfilePath);
@@ -7911,7 +8001,7 @@ var i18n_default = new Command12().command("i18n").description(
7911
8001
  if (flags.file?.length) {
7912
8002
  buckets = buckets.map((bucket) => {
7913
8003
  const paths = bucket.paths.filter(
7914
- (path18) => flags.file.find((file) => path18.pathPattern?.includes(file))
8004
+ (path19) => flags.file.find((file) => path19.pathPattern?.includes(file))
7915
8005
  );
7916
8006
  return { ...bucket, paths };
7917
8007
  }).filter((bucket) => bucket.paths.length > 0);
@@ -7926,8 +8016,8 @@ var i18n_default = new Command12().command("i18n").description(
7926
8016
  ora.info(`\x1B[36mProcessing only filtered buckets:\x1B[0m`);
7927
8017
  buckets.map((bucket) => {
7928
8018
  ora.info(` ${bucket.type}:`);
7929
- bucket.paths.forEach((path18) => {
7930
- ora.info(` - ${path18.pathPattern}`);
8019
+ bucket.paths.forEach((path19) => {
8020
+ ora.info(` - ${path19.pathPattern}`);
7931
8021
  });
7932
8022
  });
7933
8023
  }
@@ -7949,7 +8039,8 @@ var i18n_default = new Command12().command("i18n").description(
7949
8039
  bucketPath.pathPattern,
7950
8040
  {
7951
8041
  defaultLocale: sourceLocale,
7952
- injectLocale: bucket.injectLocale
8042
+ injectLocale: bucket.injectLocale,
8043
+ formatter: i18nConfig.formatter
7953
8044
  },
7954
8045
  bucket.lockedKeys,
7955
8046
  bucket.lockedPatterns,
@@ -8070,7 +8161,8 @@ var i18n_default = new Command12().command("i18n").description(
8070
8161
  bucketPath.pathPattern,
8071
8162
  {
8072
8163
  defaultLocale: sourceLocale,
8073
- injectLocale: bucket.injectLocale
8164
+ injectLocale: bucket.injectLocale,
8165
+ formatter: i18nConfig.formatter
8074
8166
  },
8075
8167
  bucket.lockedKeys,
8076
8168
  bucket.lockedPatterns,
@@ -8467,8 +8559,8 @@ import Z5 from "zod";
8467
8559
  import Ora8 from "ora";
8468
8560
 
8469
8561
  // src/cli/utils/lockfile.ts
8470
- import fs11 from "fs";
8471
- import path15 from "path";
8562
+ import fs12 from "fs";
8563
+ import path16 from "path";
8472
8564
  import Z4 from "zod";
8473
8565
  import YAML5 from "yaml";
8474
8566
  import { MD5 as MD52 } from "object-hash";
@@ -8477,7 +8569,7 @@ function createLockfileHelper() {
8477
8569
  return {
8478
8570
  isLockfileExists: () => {
8479
8571
  const lockfilePath = _getLockfilePath();
8480
- return fs11.existsSync(lockfilePath);
8572
+ return fs12.existsSync(lockfilePath);
8481
8573
  },
8482
8574
  registerSourceData: (pathPattern, sourceData) => {
8483
8575
  const lockfile = _loadLockfile();
@@ -8514,20 +8606,20 @@ function createLockfileHelper() {
8514
8606
  };
8515
8607
  function _loadLockfile() {
8516
8608
  const lockfilePath = _getLockfilePath();
8517
- if (!fs11.existsSync(lockfilePath)) {
8609
+ if (!fs12.existsSync(lockfilePath)) {
8518
8610
  return LockfileSchema.parse({});
8519
8611
  }
8520
- const content = fs11.readFileSync(lockfilePath, "utf-8");
8612
+ const content = fs12.readFileSync(lockfilePath, "utf-8");
8521
8613
  const result = LockfileSchema.parse(YAML5.parse(content));
8522
8614
  return result;
8523
8615
  }
8524
8616
  function _saveLockfile(lockfile) {
8525
8617
  const lockfilePath = _getLockfilePath();
8526
8618
  const content = YAML5.stringify(lockfile);
8527
- fs11.writeFileSync(lockfilePath, content);
8619
+ fs12.writeFileSync(lockfilePath, content);
8528
8620
  }
8529
8621
  function _getLockfilePath() {
8530
- return path15.join(process.cwd(), "i18n.lock");
8622
+ return path16.join(process.cwd(), "i18n.lock");
8531
8623
  }
8532
8624
  }
8533
8625
  var LockfileSchema = Z4.object({
@@ -8573,7 +8665,8 @@ var lockfile_default = new Command13().command("lockfile").description(
8573
8665
  bucket.type,
8574
8666
  bucketConfig.pathPattern,
8575
8667
  {
8576
- defaultLocale: sourceLocale
8668
+ defaultLocale: sourceLocale,
8669
+ formatter: i18nConfig.formatter
8577
8670
  }
8578
8671
  );
8579
8672
  bucketLoader.setDefaultLocale(sourceLocale);
@@ -8640,7 +8733,8 @@ var cleanup_default = new Command14().command("cleanup").description(
8640
8733
  bucket.type,
8641
8734
  bucketConfig.pathPattern,
8642
8735
  {
8643
- defaultLocale: sourceLocale
8736
+ defaultLocale: sourceLocale,
8737
+ formatter: i18nConfig.formatter
8644
8738
  }
8645
8739
  );
8646
8740
  bucketLoader.setDefaultLocale(sourceLocale);
@@ -8788,7 +8882,7 @@ import { execSync as execSync2 } from "child_process";
8788
8882
 
8789
8883
  // src/cli/cmd/ci/flows/in-branch.ts
8790
8884
  import { execSync } from "child_process";
8791
- import path17 from "path";
8885
+ import path18 from "path";
8792
8886
 
8793
8887
  // src/cli/cmd/ci/flows/_base.ts
8794
8888
  var IntegrationFlow = class {
@@ -8809,7 +8903,7 @@ function escapeShellArg(arg) {
8809
8903
  // src/cli/cmd/run/index.ts
8810
8904
  import { Command as Command16 } from "interactive-commander";
8811
8905
  import { exec } from "child_process";
8812
- import path16 from "path";
8906
+ import path17 from "path";
8813
8907
  import { fileURLToPath } from "url";
8814
8908
  import os2 from "os";
8815
8909
 
@@ -9266,7 +9360,8 @@ async function plan(input2) {
9266
9360
  injectLocale: bucket.injectLocale || [],
9267
9361
  lockedKeys: bucket.lockedKeys || [],
9268
9362
  lockedPatterns: bucket.lockedPatterns || [],
9269
- onlyKeys: input2.flags.key || []
9363
+ onlyKeys: input2.flags.key || [],
9364
+ formatter: input2.config.formatter
9270
9365
  });
9271
9366
  }
9272
9367
  }
@@ -9387,7 +9482,8 @@ function createLoaderForTask(assignedTask) {
9387
9482
  assignedTask.bucketPathPattern,
9388
9483
  {
9389
9484
  defaultLocale: assignedTask.sourceLocale,
9390
- injectLocale: assignedTask.injectLocale
9485
+ injectLocale: assignedTask.injectLocale,
9486
+ formatter: assignedTask.formatter
9391
9487
  },
9392
9488
  assignedTask.lockedKeys,
9393
9489
  assignedTask.lockedPatterns
@@ -9555,14 +9651,14 @@ async function watch2(ctx) {
9555
9651
  pollInterval: 100
9556
9652
  }
9557
9653
  });
9558
- watcher.on("change", (path18) => {
9559
- handleFileChange(path18, state, ctx);
9654
+ watcher.on("change", (path19) => {
9655
+ handleFileChange(path19, state, ctx);
9560
9656
  });
9561
- watcher.on("add", (path18) => {
9562
- handleFileChange(path18, state, ctx);
9657
+ watcher.on("add", (path19) => {
9658
+ handleFileChange(path19, state, ctx);
9563
9659
  });
9564
- watcher.on("unlink", (path18) => {
9565
- handleFileChange(path18, state, ctx);
9660
+ watcher.on("unlink", (path19) => {
9661
+ handleFileChange(path19, state, ctx);
9566
9662
  });
9567
9663
  watcher.on("error", (error) => {
9568
9664
  console.error(
@@ -9694,12 +9790,12 @@ async function determineAuthId(ctx) {
9694
9790
  }
9695
9791
 
9696
9792
  // src/cli/cmd/run/index.ts
9697
- var __dirname = path16.dirname(fileURLToPath(import.meta.url));
9793
+ var __dirname = path17.dirname(fileURLToPath(import.meta.url));
9698
9794
  function playSound(type) {
9699
9795
  const platform = os2.platform();
9700
9796
  return new Promise((resolve) => {
9701
- const assetDir = path16.join(__dirname, "../assets");
9702
- const soundFiles = [path16.join(assetDir, `${type}.mp3`)];
9797
+ const assetDir = path17.join(__dirname, "../assets");
9798
+ const soundFiles = [path17.join(assetDir, `${type}.mp3`)];
9703
9799
  let command = "";
9704
9800
  if (platform === "linux") {
9705
9801
  command = soundFiles.map(
@@ -9893,7 +9989,7 @@ var InBranchFlow = class extends IntegrationFlow {
9893
9989
  return false;
9894
9990
  }
9895
9991
  }
9896
- const workingDir = path17.resolve(
9992
+ const workingDir = path18.resolve(
9897
9993
  process.cwd(),
9898
9994
  this.platformKit.config.workingDir
9899
9995
  );
@@ -10651,8 +10747,8 @@ var status_default = new Command18().command("status").description("Show the sta
10651
10747
  if (flags.file?.length) {
10652
10748
  buckets = buckets.map((bucket) => {
10653
10749
  const paths = bucket.paths.filter(
10654
- (path18) => flags.file.find(
10655
- (file) => path18.pathPattern?.includes(file) || path18.pathPattern?.match(file) || minimatch(path18.pathPattern, file)
10750
+ (path19) => flags.file.find(
10751
+ (file) => path19.pathPattern?.includes(file) || path19.pathPattern?.match(file) || minimatch(path19.pathPattern, file)
10656
10752
  )
10657
10753
  );
10658
10754
  return { ...bucket, paths };
@@ -10666,8 +10762,8 @@ var status_default = new Command18().command("status").description("Show the sta
10666
10762
  ora.info(`\x1B[36mProcessing only filtered buckets:\x1B[0m`);
10667
10763
  buckets.map((bucket) => {
10668
10764
  ora.info(` ${bucket.type}:`);
10669
- bucket.paths.forEach((path18) => {
10670
- ora.info(` - ${path18.pathPattern}`);
10765
+ bucket.paths.forEach((path19) => {
10766
+ ora.info(` - ${path19.pathPattern}`);
10671
10767
  });
10672
10768
  });
10673
10769
  }
@@ -10705,7 +10801,8 @@ var status_default = new Command18().command("status").description("Show the sta
10705
10801
  bucketPath.pathPattern,
10706
10802
  {
10707
10803
  defaultLocale: sourceLocale,
10708
- injectLocale: bucket.injectLocale
10804
+ injectLocale: bucket.injectLocale,
10805
+ formatter: i18nConfig.formatter
10709
10806
  },
10710
10807
  bucket.lockedKeys
10711
10808
  );
@@ -10951,10 +11048,10 @@ var status_default = new Command18().command("status").description("Show the sta
10951
11048
  if (flags.confirm && Object.keys(fileStats).length > 0) {
10952
11049
  console.log(chalk14.bold(`
10953
11050
  \u{1F4D1} BREAKDOWN BY FILE:`));
10954
- Object.entries(fileStats).sort((a, b) => b[1].wordCount - a[1].wordCount).forEach(([path18, stats]) => {
11051
+ Object.entries(fileStats).sort((a, b) => b[1].wordCount - a[1].wordCount).forEach(([path19, stats]) => {
10955
11052
  if (stats.sourceKeys === 0) return;
10956
11053
  console.log(chalk14.bold(`
10957
- \u2022 ${path18}:`));
11054
+ \u2022 ${path19}:`));
10958
11055
  console.log(
10959
11056
  ` ${stats.sourceKeys} source keys, ~${stats.wordCount.toLocaleString()} source words`
10960
11057
  );
@@ -11174,7 +11271,7 @@ async function renderHero2() {
11174
11271
  // package.json
11175
11272
  var package_default = {
11176
11273
  name: "lingo.dev",
11177
- version: "0.111.10",
11274
+ version: "0.111.12",
11178
11275
  description: "Lingo.dev CLI",
11179
11276
  private: false,
11180
11277
  publishConfig: {
@@ -11304,6 +11401,8 @@ var package_default = {
11304
11401
  "@babel/parser": "^7.27.1",
11305
11402
  "@babel/traverse": "^7.27.4",
11306
11403
  "@babel/types": "^7.27.1",
11404
+ "@biomejs/js-api": "^3.0.0",
11405
+ "@biomejs/wasm-nodejs": "^2.2.4",
11307
11406
  "@datocms/cma-client-node": "^4.0.1",
11308
11407
  "@gitbeaker/rest": "^39.34.3",
11309
11408
  "@inkjs/ui": "^2.0.0",
@@ -11491,7 +11590,8 @@ var purge_default = new Command20().command("purge").description(
11491
11590
  bucketPath.pathPattern,
11492
11591
  {
11493
11592
  defaultLocale: sourceLocale,
11494
- injectLocale: bucket.injectLocale
11593
+ injectLocale: bucket.injectLocale,
11594
+ formatter: i18nConfig.formatter
11495
11595
  },
11496
11596
  bucket.lockedKeys,
11497
11597
  bucket.lockedPatterns,