lingo.dev 0.80.1 → 0.81.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/build/cli.cjs CHANGED
@@ -1,4 +1,4 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }// src/cli/index.ts
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }// src/cli/index.ts
2
2
  var _dotenv = require('dotenv'); var _dotenv2 = _interopRequireDefault(_dotenv);
3
3
  var _interactivecommander = require('interactive-commander');
4
4
  var _figlet = require('figlet'); var _figlet2 = _interopRequireDefault(_figlet);
@@ -14,9 +14,9 @@ var _promises = require('readline/promises'); var _promises2 = _interopRequireDe
14
14
 
15
15
  // src/cli/utils/settings.ts
16
16
  var _os = require('os'); var _os2 = _interopRequireDefault(_os);
17
- var _path = require('path'); var _path2 = _interopRequireDefault(_path);
17
+ var _path = require('path'); var path15 = _interopRequireWildcard(_path); var path13 = _interopRequireWildcard(_path); var path14 = _interopRequireWildcard(_path);
18
18
  var _zod = require('zod'); var _zod2 = _interopRequireDefault(_zod);
19
- var _fs = require('fs'); var _fs2 = _interopRequireDefault(_fs);
19
+ var _fs = require('fs'); var fs11 = _interopRequireWildcard(_fs);
20
20
  var _ini = require('ini'); var _ini2 = _interopRequireDefault(_ini);
21
21
  function getSettings(explicitApiKey) {
22
22
  const env = _loadEnv();
@@ -26,9 +26,9 @@ function getSettings(explicitApiKey) {
26
26
  _envVarsInfo();
27
27
  return {
28
28
  auth: {
29
- apiKey: explicitApiKey || env.LINGODOTDEV_API_KEY || _optionalChain([systemFile, 'access', _23 => _23.auth, 'optionalAccess', _24 => _24.apiKey]) || defaults.auth.apiKey,
30
- apiUrl: env.LINGODOTDEV_API_URL || _optionalChain([systemFile, 'access', _25 => _25.auth, 'optionalAccess', _26 => _26.apiUrl]) || defaults.auth.apiUrl,
31
- webUrl: env.LINGODOTDEV_WEB_URL || _optionalChain([systemFile, 'access', _27 => _27.auth, 'optionalAccess', _28 => _28.webUrl]) || defaults.auth.webUrl
29
+ apiKey: explicitApiKey || env.LINGODOTDEV_API_KEY || _optionalChain([systemFile, 'access', _24 => _24.auth, 'optionalAccess', _25 => _25.apiKey]) || defaults.auth.apiKey,
30
+ apiUrl: env.LINGODOTDEV_API_URL || _optionalChain([systemFile, 'access', _26 => _26.auth, 'optionalAccess', _27 => _27.apiUrl]) || defaults.auth.apiUrl,
31
+ webUrl: env.LINGODOTDEV_WEB_URL || _optionalChain([systemFile, 'access', _28 => _28.auth, 'optionalAccess', _29 => _29.webUrl]) || defaults.auth.webUrl
32
32
  }
33
33
  };
34
34
  }
@@ -60,7 +60,7 @@ function _loadEnv() {
60
60
  }
61
61
  function _loadSystemFile() {
62
62
  const settingsFilePath = _getSettingsFilePath();
63
- const content = _fs2.default.existsSync(settingsFilePath) ? _fs2.default.readFileSync(settingsFilePath, "utf-8") : "";
63
+ const content = fs11.default.existsSync(settingsFilePath) ? fs11.default.readFileSync(settingsFilePath, "utf-8") : "";
64
64
  const data = _ini2.default.parse(content);
65
65
  return _zod2.default.object({
66
66
  auth: _zod2.default.object({
@@ -73,12 +73,12 @@ function _loadSystemFile() {
73
73
  function _saveSystemFile(settings) {
74
74
  const settingsFilePath = _getSettingsFilePath();
75
75
  const content = _ini2.default.stringify(settings);
76
- _fs2.default.writeFileSync(settingsFilePath, content);
76
+ fs11.default.writeFileSync(settingsFilePath, content);
77
77
  }
78
78
  function _getSettingsFilePath() {
79
79
  const settingsFile = ".lingodotdevrc";
80
80
  const homedir = _os2.default.homedir();
81
- const settingsFilePath = _path2.default.join(homedir, settingsFile);
81
+ const settingsFilePath = path15.default.join(homedir, settingsFile);
82
82
  return settingsFilePath;
83
83
  }
84
84
  function _legacyEnvVarWarning() {
@@ -99,7 +99,7 @@ Please use LINGODOTDEV_API_KEY instead.
99
99
  function _envVarsInfo() {
100
100
  const env = _loadEnv();
101
101
  const systemFile = _loadSystemFile();
102
- if (env.LINGODOTDEV_API_KEY && _optionalChain([systemFile, 'access', _29 => _29.auth, 'optionalAccess', _30 => _30.apiKey])) {
102
+ if (env.LINGODOTDEV_API_KEY && _optionalChain([systemFile, 'access', _30 => _30.auth, 'optionalAccess', _31 => _31.apiKey])) {
103
103
  console.info(
104
104
  "\x1B[36m%s\x1B[0m",
105
105
  `\u2139\uFE0F Using LINGODOTDEV_API_KEY env var instead of credentials from login flow (saved in .lingodotdevrc)`
@@ -154,7 +154,7 @@ function createAuthenticator(params) {
154
154
  });
155
155
  if (res.ok) {
156
156
  const payload = await res.json();
157
- if (!_optionalChain([payload, 'optionalAccess', _31 => _31.email])) {
157
+ if (!_optionalChain([payload, 'optionalAccess', _32 => _32.email])) {
158
158
  return null;
159
159
  }
160
160
  return {
@@ -257,11 +257,11 @@ var _lodash = require('lodash'); var _lodash2 = _interopRequireDefault(_lodash);
257
257
  var __spec = require('@lingo.dev/_spec');
258
258
  function getConfig(resave = true) {
259
259
  const configFilePath = _getConfigFilePath();
260
- const configFileExists = _fs2.default.existsSync(configFilePath);
260
+ const configFileExists = fs11.default.existsSync(configFilePath);
261
261
  if (!configFileExists) {
262
262
  return null;
263
263
  }
264
- const fileContents = _fs2.default.readFileSync(configFilePath, "utf8");
264
+ const fileContents = fs11.default.readFileSync(configFilePath, "utf8");
265
265
  const rawConfig = JSON.parse(fileContents);
266
266
  const result = __spec.parseI18nConfig.call(void 0, rawConfig);
267
267
  const didConfigChange = !_lodash2.default.isEqual(rawConfig, result);
@@ -273,11 +273,11 @@ function getConfig(resave = true) {
273
273
  function saveConfig(config) {
274
274
  const configFilePath = _getConfigFilePath();
275
275
  const serialized = JSON.stringify(config, null, 2);
276
- _fs2.default.writeFileSync(configFilePath, serialized);
276
+ fs11.default.writeFileSync(configFilePath, serialized);
277
277
  return config;
278
278
  }
279
279
  function _getConfigFilePath() {
280
- return _path2.default.join(process.cwd(), "i18n.json");
280
+ return path15.default.join(process.cwd(), "i18n.json");
281
281
  }
282
282
 
283
283
  // src/cli/cmd/init.ts
@@ -362,7 +362,7 @@ function findLocaleFilesForFilename(fileName) {
362
362
  });
363
363
  const localeFilesAndPatterns = localeFiles.map((file) => ({
364
364
  file,
365
- pattern: _path2.default.join(_path2.default.dirname(file), pattern)
365
+ pattern: path15.default.join(path15.default.dirname(file), pattern)
366
366
  }));
367
367
  const grouppedFilesAndPatterns = _lodash2.default.groupBy(localeFilesAndPatterns, "pattern");
368
368
  const patterns = Object.keys(grouppedFilesAndPatterns);
@@ -382,10 +382,10 @@ function ensurePatterns(patterns, source) {
382
382
  }
383
383
  patterns.forEach((pattern) => {
384
384
  const filePath = pattern.replace("[locale]", source);
385
- if (!_fs2.default.existsSync(filePath)) {
386
- const defaultContent = getDefaultContent(_path2.default.extname(filePath), source);
387
- _fs2.default.mkdirSync(_path2.default.dirname(filePath), { recursive: true });
388
- _fs2.default.writeFileSync(filePath, defaultContent);
385
+ if (!fs11.default.existsSync(filePath)) {
386
+ const defaultContent = getDefaultContent(path15.default.extname(filePath), source);
387
+ fs11.default.mkdirSync(path15.default.dirname(filePath), { recursive: true });
388
+ fs11.default.writeFileSync(filePath, defaultContent);
389
389
  }
390
390
  });
391
391
  }
@@ -464,31 +464,31 @@ function updateGitignore() {
464
464
  if (!projectRoot) {
465
465
  return;
466
466
  }
467
- const gitignorePath = _path2.default.join(projectRoot, ".gitignore");
468
- if (!_fs2.default.existsSync(gitignorePath)) {
467
+ const gitignorePath = path15.default.join(projectRoot, ".gitignore");
468
+ if (!fs11.default.existsSync(gitignorePath)) {
469
469
  return;
470
470
  }
471
- const gitignore = _fs2.default.readFileSync(gitignorePath, "utf8").split("\n");
471
+ const gitignore = fs11.default.readFileSync(gitignorePath, "utf8").split("\n");
472
472
  const cacheIsIgnored = gitignore.includes(cacheFile);
473
473
  if (!cacheIsIgnored) {
474
474
  let content = "";
475
- content = _fs2.default.readFileSync(gitignorePath, "utf8");
475
+ content = fs11.default.readFileSync(gitignorePath, "utf8");
476
476
  if (content !== "" && !content.endsWith("\n")) {
477
477
  content += "\n";
478
478
  }
479
479
  content += `${cacheFile}
480
480
  `;
481
- _fs2.default.writeFileSync(gitignorePath, content);
481
+ fs11.default.writeFileSync(gitignorePath, content);
482
482
  }
483
483
  }
484
484
  function findCurrentProjectRoot() {
485
485
  let currentDir = process.cwd();
486
- while (currentDir !== _path2.default.parse(currentDir).root) {
487
- const gitDirPath = _path2.default.join(currentDir, ".git");
488
- if (_fs2.default.existsSync(gitDirPath) && _fs2.default.lstatSync(gitDirPath).isDirectory()) {
486
+ while (currentDir !== path15.default.parse(currentDir).root) {
487
+ const gitDirPath = path15.default.join(currentDir, ".git");
488
+ if (fs11.default.existsSync(gitDirPath) && fs11.default.lstatSync(gitDirPath).isDirectory()) {
489
489
  return currentDir;
490
490
  }
491
- currentDir = _path2.default.dirname(currentDir);
491
+ currentDir = path15.default.dirname(currentDir);
492
492
  }
493
493
  return null;
494
494
  }
@@ -530,24 +530,24 @@ function makePlatformInitializer(config, spinner) {
530
530
  return {
531
531
  name: config.name,
532
532
  isEnabled: () => {
533
- const filePath = _path2.default.join(process.cwd(), config.checkPath);
534
- return _fs2.default.existsSync(filePath);
533
+ const filePath = path15.default.join(process.cwd(), config.checkPath);
534
+ return fs11.default.existsSync(filePath);
535
535
  },
536
536
  init: async () => {
537
- const filePath = _path2.default.join(process.cwd(), config.ciConfigPath);
538
- const dirPath = _path2.default.dirname(filePath);
539
- if (!_fs2.default.existsSync(dirPath)) {
540
- _fs2.default.mkdirSync(dirPath, { recursive: true });
537
+ const filePath = path15.default.join(process.cwd(), config.ciConfigPath);
538
+ const dirPath = path15.default.dirname(filePath);
539
+ if (!fs11.default.existsSync(dirPath)) {
540
+ fs11.default.mkdirSync(dirPath, { recursive: true });
541
541
  }
542
542
  let canWrite = true;
543
- if (_fs2.default.existsSync(filePath)) {
543
+ if (fs11.default.existsSync(filePath)) {
544
544
  canWrite = await _prompts.confirm.call(void 0, {
545
545
  message: `File ${filePath} already exists. Do you want to overwrite it?`,
546
546
  default: false
547
547
  });
548
548
  }
549
549
  if (canWrite) {
550
- _fs2.default.writeFileSync(filePath, config.ciConfigContent);
550
+ fs11.default.writeFileSync(filePath, config.ciConfigContent);
551
551
  spinner.succeed(`CI/CD initialized for ${config.name}`);
552
552
  } else {
553
553
  spinner.warn(`CI/CD not initialized for ${config.name}`);
@@ -621,9 +621,9 @@ function makeGitlabInitializer(spinner) {
621
621
 
622
622
  // src/cli/cmd/init.ts
623
623
 
624
- var openUrl = (path15) => {
624
+ var openUrl = (path18) => {
625
625
  const settings = getSettings(void 0);
626
- _open2.default.call(void 0, `${settings.auth.webUrl}${path15}`, { wait: false });
626
+ _open2.default.call(void 0, `${settings.auth.webUrl}${path18}`, { wait: false });
627
627
  };
628
628
  var throwHelpError = (option, value) => {
629
629
  if (value === "help") {
@@ -669,8 +669,8 @@ var init_default = new (0, _interactivecommander.InteractiveCommand)().command("
669
669
  const values = value.includes(",") ? value.split(",") : value.split(" ");
670
670
  for (const p of values) {
671
671
  try {
672
- const dirPath = _path2.default.dirname(p);
673
- const stats = _fs2.default.statSync(dirPath);
672
+ const dirPath = path15.default.dirname(p);
673
+ const stats = fs11.default.statSync(dirPath);
674
674
  if (!stats.isDirectory()) {
675
675
  throw new Error(`${dirPath} is not a directory`);
676
676
  }
@@ -774,7 +774,7 @@ var init_default = new (0, _interactivecommander.InteractiveCommand)().command("
774
774
  });
775
775
  const auth2 = await newAuthenticator.whoami();
776
776
  if (auth2) {
777
- _ora2.default.call(void 0, ).succeed(`Authenticated as ${_optionalChain([auth2, 'optionalAccess', _32 => _32.email])}`);
777
+ _ora2.default.call(void 0, ).succeed(`Authenticated as ${_optionalChain([auth2, 'optionalAccess', _33 => _33.email])}`);
778
778
  } else {
779
779
  _ora2.default.call(void 0, ).fail("Authentication failed.");
780
780
  }
@@ -806,12 +806,12 @@ var config_default = new (0, _interactivecommander.Command)().command("config").
806
806
  console.log(JSON.stringify(config, null, 2));
807
807
  });
808
808
  function loadReplexicaFileConfig() {
809
- const replexicaConfigPath = _path2.default.resolve(process.cwd(), "i18n.json");
810
- const fileExists = _fs2.default.existsSync(replexicaConfigPath);
809
+ const replexicaConfigPath = path15.default.resolve(process.cwd(), "i18n.json");
810
+ const fileExists = fs11.default.existsSync(replexicaConfigPath);
811
811
  if (!fileExists) {
812
812
  return void 0;
813
813
  }
814
- const fileContent = _fs2.default.readFileSync(replexicaConfigPath, "utf-8");
814
+ const fileContent = fs11.default.readFileSync(replexicaConfigPath, "utf-8");
815
815
  const replexicaFileConfig = JSON.parse(fileContent);
816
816
  return replexicaFileConfig;
817
817
  }
@@ -854,7 +854,7 @@ var locale_default = new (0, _interactivecommander.Command)().command("locale").
854
854
  function getBuckets(i18nConfig) {
855
855
  const result = Object.entries(i18nConfig.buckets).map(([bucketType, bucketEntry]) => {
856
856
  const includeItems = bucketEntry.include.map((item) => resolveBucketItem(item));
857
- const excludeItems = _optionalChain([bucketEntry, 'access', _33 => _33.exclude, 'optionalAccess', _34 => _34.map, 'call', _35 => _35((item) => resolveBucketItem(item))]);
857
+ const excludeItems = _optionalChain([bucketEntry, 'access', _34 => _34.exclude, 'optionalAccess', _35 => _35.map, 'call', _36 => _36((item) => resolveBucketItem(item))]);
858
858
  const config = {
859
859
  type: bucketType,
860
860
  paths: extractPathPatterns(i18nConfig.locale.source, includeItems, excludeItems)
@@ -875,7 +875,7 @@ function extractPathPatterns(sourceLocale, include, exclude) {
875
875
  })
876
876
  )
877
877
  );
878
- const excludedPatterns = _optionalChain([exclude, 'optionalAccess', _36 => _36.flatMap, 'call', _37 => _37(
878
+ const excludedPatterns = _optionalChain([exclude, 'optionalAccess', _37 => _37.flatMap, 'call', _38 => _38(
879
879
  (pattern) => expandPlaceholderedGlob(pattern.path, __spec.resolveOverriddenLocale.call(void 0, sourceLocale, pattern.delimiter)).map(
880
880
  (pathPattern) => ({
881
881
  pathPattern,
@@ -887,9 +887,9 @@ function extractPathPatterns(sourceLocale, include, exclude) {
887
887
  return result;
888
888
  }
889
889
  function expandPlaceholderedGlob(_pathPattern, sourceLocale) {
890
- const absolutePathPattern = _path2.default.resolve(_pathPattern);
891
- const pathPattern = _path2.default.relative(process.cwd(), absolutePathPattern);
892
- if (_path2.default.relative(process.cwd(), pathPattern).startsWith("..")) {
890
+ const absolutePathPattern = path15.default.resolve(_pathPattern);
891
+ const pathPattern = path15.default.relative(process.cwd(), absolutePathPattern);
892
+ if (path15.default.relative(process.cwd(), pathPattern).startsWith("..")) {
893
893
  throw new CLIError({
894
894
  message: `Invalid path pattern: ${pathPattern}. Path pattern must be within the current working directory.`,
895
895
  docUrl: "invalidPathPattern"
@@ -901,7 +901,7 @@ function expandPlaceholderedGlob(_pathPattern, sourceLocale) {
901
901
  docUrl: "invalidPathPattern"
902
902
  });
903
903
  }
904
- const pathPatternChunks = pathPattern.split(_path2.default.sep);
904
+ const pathPatternChunks = pathPattern.split(path15.default.sep);
905
905
  const localeSegmentIndexes = pathPatternChunks.reduce((indexes, segment, index) => {
906
906
  if (segment.includes("[locale]")) {
907
907
  indexes.push(index);
@@ -909,9 +909,9 @@ function expandPlaceholderedGlob(_pathPattern, sourceLocale) {
909
909
  return indexes;
910
910
  }, []);
911
911
  const sourcePathPattern = pathPattern.replaceAll(/\[locale\]/g, sourceLocale);
912
- const sourcePaths = _glob.glob.sync(sourcePathPattern, { follow: true, withFileTypes: true }).filter((file) => file.isFile() || file.isSymbolicLink()).map((file) => file.fullpath()).map((fullpath) => _path2.default.relative(process.cwd(), fullpath));
912
+ const sourcePaths = _glob.glob.sync(sourcePathPattern, { follow: true, withFileTypes: true }).filter((file) => file.isFile() || file.isSymbolicLink()).map((file) => file.fullpath()).map((fullpath) => path15.default.relative(process.cwd(), fullpath));
913
913
  const placeholderedPaths = sourcePaths.map((sourcePath) => {
914
- const sourcePathChunks = sourcePath.split(_path2.default.sep);
914
+ const sourcePathChunks = sourcePath.split(path15.default.sep);
915
915
  localeSegmentIndexes.forEach((localeSegmentIndex) => {
916
916
  const pathPatternChunk = pathPatternChunks[localeSegmentIndex];
917
917
  const sourcePathChunk = sourcePathChunks[localeSegmentIndex];
@@ -925,7 +925,7 @@ function expandPlaceholderedGlob(_pathPattern, sourceLocale) {
925
925
  sourcePathChunks[localeSegmentIndex] = placeholderedSegment;
926
926
  }
927
927
  });
928
- const placeholderedPath = sourcePathChunks.join(_path2.default.sep);
928
+ const placeholderedPath = sourcePathChunks.join(path15.default.sep);
929
929
  return placeholderedPath;
930
930
  });
931
931
  return placeholderedPaths;
@@ -967,8 +967,8 @@ var files_default = new (0, _interactivecommander.Command)().command("files").de
967
967
  } else if (type.target) {
968
968
  result.push(...targetPaths);
969
969
  }
970
- result.forEach((path15) => {
971
- console.log(path15);
970
+ result.forEach((path18) => {
971
+ console.log(path18);
972
972
  });
973
973
  }
974
974
  }
@@ -994,17 +994,18 @@ var show_default = new (0, _interactivecommander.Command)().command("show").desc
994
994
 
995
995
 
996
996
 
997
+
997
998
  // src/cli/loaders/_utils.ts
998
999
  function composeLoaders(...loaders) {
999
1000
  return {
1000
1001
  init: async () => {
1001
1002
  for (const loader of loaders) {
1002
- await _optionalChain([loader, 'access', _38 => _38.init, 'optionalCall', _39 => _39()]);
1003
+ await _optionalChain([loader, 'access', _39 => _39.init, 'optionalCall', _40 => _40()]);
1003
1004
  }
1004
1005
  },
1005
1006
  setDefaultLocale(locale) {
1006
1007
  for (const loader of loaders) {
1007
- _optionalChain([loader, 'access', _40 => _40.setDefaultLocale, 'optionalCall', _41 => _41(locale)]);
1008
+ _optionalChain([loader, 'access', _41 => _41.setDefaultLocale, 'optionalCall', _42 => _42(locale)]);
1008
1009
  }
1009
1010
  return this;
1010
1011
  },
@@ -1035,7 +1036,7 @@ function createLoader(lDefinition) {
1035
1036
  if (state.initCtx) {
1036
1037
  return state.initCtx;
1037
1038
  }
1038
- state.initCtx = await _optionalChain([lDefinition, 'access', _42 => _42.init, 'optionalCall', _43 => _43()]);
1039
+ state.initCtx = await _optionalChain([lDefinition, 'access', _43 => _43.init, 'optionalCall', _44 => _44()]);
1039
1040
  return state.initCtx;
1040
1041
  },
1041
1042
  setDefaultLocale(locale) {
@@ -1124,7 +1125,7 @@ function createNormalizeLoader() {
1124
1125
  return normalized;
1125
1126
  },
1126
1127
  push: async (locale, data, originalInput) => {
1127
- const keysMap = _nullishCoalesce(_optionalChain([originalInput, 'optionalAccess', _44 => _44.keysMap]), () => ( {}));
1128
+ const keysMap = _nullishCoalesce(_optionalChain([originalInput, 'optionalAccess', _45 => _45.keysMap]), () => ( {}));
1128
1129
  const input2 = mapDenormalizedKeys(data, keysMap);
1129
1130
  const denormalized = _flat.unflatten.call(void 0, input2, {
1130
1131
  delimiter: "/",
@@ -1198,10 +1199,10 @@ function createTextFileLoader(pathPattern) {
1198
1199
  const trimmedResult = result.trim();
1199
1200
  return trimmedResult;
1200
1201
  },
1201
- async push(locale, data, _22, originalLocale) {
1202
+ async push(locale, data, _23, originalLocale) {
1202
1203
  const draftPath = pathPattern.replaceAll("[locale]", locale);
1203
- const finalPath = _path2.default.resolve(draftPath);
1204
- const dirPath = _path2.default.dirname(finalPath);
1204
+ const finalPath = path15.default.resolve(draftPath);
1205
+ const dirPath = path15.default.dirname(finalPath);
1205
1206
  await _promises4.default.mkdir(dirPath, { recursive: true });
1206
1207
  const trimmedPayload = data.trim();
1207
1208
  const trailingNewLine = await getTrailingNewLine(pathPattern, locale, originalLocale);
@@ -1215,7 +1216,7 @@ function createTextFileLoader(pathPattern) {
1215
1216
  }
1216
1217
  async function readFileForLocale(pathPattern, locale) {
1217
1218
  const draftPath = pathPattern.replaceAll("[locale]", locale);
1218
- const finalPath = _path2.default.resolve(draftPath);
1219
+ const finalPath = path15.default.resolve(draftPath);
1219
1220
  const exists = await _promises4.default.access(finalPath).then(() => true).catch(() => false);
1220
1221
  if (!exists) {
1221
1222
  return "";
@@ -1227,8 +1228,8 @@ async function getTrailingNewLine(pathPattern, locale, originalLocale) {
1227
1228
  if (!templateData) {
1228
1229
  templateData = await readFileForLocale(pathPattern, originalLocale);
1229
1230
  }
1230
- if (_optionalChain([templateData, 'optionalAccess', _45 => _45.match, 'call', _46 => _46(/[\r\n]$/)])) {
1231
- const ending = _optionalChain([templateData, 'optionalAccess', _47 => _47.includes, 'call', _48 => _48("\r\n")]) ? "\r\n" : _optionalChain([templateData, 'optionalAccess', _49 => _49.includes, 'call', _50 => _50("\r")]) ? "\r" : "\n";
1231
+ if (_optionalChain([templateData, 'optionalAccess', _46 => _46.match, 'call', _47 => _47(/[\r\n]$/)])) {
1232
+ const ending = _optionalChain([templateData, 'optionalAccess', _48 => _48.includes, 'call', _49 => _49("\r\n")]) ? "\r\n" : _optionalChain([templateData, 'optionalAccess', _50 => _50.includes, 'call', _51 => _51("\r")]) ? "\r" : "\n";
1232
1233
  return ending;
1233
1234
  }
1234
1235
  return "";
@@ -1483,7 +1484,7 @@ function createHtmlLoader() {
1483
1484
  break;
1484
1485
  }
1485
1486
  const siblings = Array.from(parent.childNodes).filter(
1486
- (n) => n.nodeType === 1 || n.nodeType === 3 && _optionalChain([n, 'access', _51 => _51.textContent, 'optionalAccess', _52 => _52.trim, 'call', _53 => _53()])
1487
+ (n) => n.nodeType === 1 || n.nodeType === 3 && _optionalChain([n, 'access', _52 => _52.textContent, 'optionalAccess', _53 => _53.trim, 'call', _54 => _54()])
1487
1488
  );
1488
1489
  const index = siblings.indexOf(current);
1489
1490
  if (index !== -1) {
@@ -1518,11 +1519,11 @@ function createHtmlLoader() {
1518
1519
  result[getPath(element, attr)] = value;
1519
1520
  }
1520
1521
  });
1521
- Array.from(element.childNodes).filter((n) => n.nodeType === 1 || n.nodeType === 3 && _optionalChain([n, 'access', _54 => _54.textContent, 'optionalAccess', _55 => _55.trim, 'call', _56 => _56()])).forEach(processNode);
1522
+ Array.from(element.childNodes).filter((n) => n.nodeType === 1 || n.nodeType === 3 && _optionalChain([n, 'access', _55 => _55.textContent, 'optionalAccess', _56 => _56.trim, 'call', _57 => _57()])).forEach(processNode);
1522
1523
  }
1523
1524
  };
1524
- Array.from(document.head.childNodes).filter((n) => n.nodeType === 1 || n.nodeType === 3 && _optionalChain([n, 'access', _57 => _57.textContent, 'optionalAccess', _58 => _58.trim, 'call', _59 => _59()])).forEach(processNode);
1525
- Array.from(document.body.childNodes).filter((n) => n.nodeType === 1 || n.nodeType === 3 && _optionalChain([n, 'access', _60 => _60.textContent, 'optionalAccess', _61 => _61.trim, 'call', _62 => _62()])).forEach(processNode);
1525
+ Array.from(document.head.childNodes).filter((n) => n.nodeType === 1 || n.nodeType === 3 && _optionalChain([n, 'access', _58 => _58.textContent, 'optionalAccess', _59 => _59.trim, 'call', _60 => _60()])).forEach(processNode);
1526
+ Array.from(document.body.childNodes).filter((n) => n.nodeType === 1 || n.nodeType === 3 && _optionalChain([n, 'access', _61 => _61.textContent, 'optionalAccess', _62 => _62.trim, 'call', _63 => _63()])).forEach(processNode);
1526
1527
  return result;
1527
1528
  },
1528
1529
  async push(locale, data, originalInput) {
@@ -1535,16 +1536,16 @@ function createHtmlLoader() {
1535
1536
  const bDepth = b.split("/").length;
1536
1537
  return aDepth - bDepth;
1537
1538
  });
1538
- paths.forEach((path15) => {
1539
- const value = data[path15];
1540
- const [nodePath, attribute] = path15.split("#");
1539
+ paths.forEach((path18) => {
1540
+ const value = data[path18];
1541
+ const [nodePath, attribute] = path18.split("#");
1541
1542
  const [rootTag, ...indices] = nodePath.split("/");
1542
1543
  let parent = rootTag === "head" ? document.head : document.body;
1543
1544
  let current = parent;
1544
1545
  for (let i = 0; i < indices.length; i++) {
1545
1546
  const index = parseInt(indices[i]);
1546
1547
  const siblings = Array.from(parent.childNodes).filter(
1547
- (n) => n.nodeType === 1 || n.nodeType === 3 && _optionalChain([n, 'access', _63 => _63.textContent, 'optionalAccess', _64 => _64.trim, 'call', _65 => _65()])
1548
+ (n) => n.nodeType === 1 || n.nodeType === 3 && _optionalChain([n, 'access', _64 => _64.textContent, 'optionalAccess', _65 => _65.trim, 'call', _66 => _66()])
1548
1549
  );
1549
1550
  if (index >= siblings.length) {
1550
1551
  if (i === indices.length - 1) {
@@ -1595,7 +1596,7 @@ function createMarkdownLoader() {
1595
1596
  yaml: yamlEngine
1596
1597
  }
1597
1598
  });
1598
- const sections = content.split(SECTION_REGEX).map((section) => _nullishCoalesce(_optionalChain([section, 'optionalAccess', _66 => _66.trim, 'call', _67 => _67()]), () => ( ""))).filter(Boolean);
1599
+ const sections = content.split(SECTION_REGEX).map((section) => _nullishCoalesce(_optionalChain([section, 'optionalAccess', _67 => _67.trim, 'call', _68 => _68()]), () => ( ""))).filter(Boolean);
1599
1600
  return {
1600
1601
  ...Object.fromEntries(
1601
1602
  sections.map((section, index) => [`${MD_SECTION_PREFIX}${index}`, section]).filter(([, section]) => Boolean(section))
@@ -1607,7 +1608,7 @@ function createMarkdownLoader() {
1607
1608
  const frontmatter = Object.fromEntries(
1608
1609
  Object.entries(data).filter(([key]) => key.startsWith(FM_ATTR_PREFIX)).map(([key, value]) => [key.replace(FM_ATTR_PREFIX, ""), value])
1609
1610
  );
1610
- let content = Object.entries(data).filter(([key]) => key.startsWith(MD_SECTION_PREFIX)).sort(([a], [b]) => Number(a.split("-").pop()) - Number(b.split("-").pop())).map(([, value]) => _nullishCoalesce(_optionalChain([value, 'optionalAccess', _68 => _68.trim, 'call', _69 => _69()]), () => ( ""))).filter(Boolean).join("\n\n");
1611
+ let content = Object.entries(data).filter(([key]) => key.startsWith(MD_SECTION_PREFIX)).sort(([a], [b]) => Number(a.split("-").pop()) - Number(b.split("-").pop())).map(([, value]) => _nullishCoalesce(_optionalChain([value, 'optionalAccess', _69 => _69.trim, 'call', _70 => _70()]), () => ( ""))).filter(Boolean).join("\n\n");
1611
1612
  if (Object.keys(frontmatter).length > 0) {
1612
1613
  content = `
1613
1614
  ${content}`;
@@ -1640,7 +1641,7 @@ function createPropertiesLoader() {
1640
1641
  return result;
1641
1642
  },
1642
1643
  async push(locale, payload) {
1643
- const result = Object.entries(payload).filter(([_22, value]) => value != null).map(([key, value]) => `${key}=${value}`).join("\n");
1644
+ const result = Object.entries(payload).filter(([_23, value]) => value != null).map(([key, value]) => `${key}=${value}`).join("\n");
1644
1645
  return result;
1645
1646
  }
1646
1647
  });
@@ -1651,7 +1652,7 @@ function isSkippableLine(line) {
1651
1652
  function parsePropertyLine(line) {
1652
1653
  const [key, ...valueParts] = line.split("=");
1653
1654
  return {
1654
- key: _optionalChain([key, 'optionalAccess', _70 => _70.trim, 'call', _71 => _71()]) || "",
1655
+ key: _optionalChain([key, 'optionalAccess', _71 => _71.trim, 'call', _72 => _72()]) || "",
1655
1656
  value: valueParts.join("=").trim()
1656
1657
  };
1657
1658
  }
@@ -1737,7 +1738,7 @@ function createXcodeXcstringsLoader(defaultLocale) {
1737
1738
  if (rootTranslationEntity.shouldTranslate === false) {
1738
1739
  continue;
1739
1740
  }
1740
- const langTranslationEntity = _optionalChain([rootTranslationEntity, 'optionalAccess', _72 => _72.localizations, 'optionalAccess', _73 => _73[locale]]);
1741
+ const langTranslationEntity = _optionalChain([rootTranslationEntity, 'optionalAccess', _73 => _73.localizations, 'optionalAccess', _74 => _74[locale]]);
1741
1742
  if (langTranslationEntity) {
1742
1743
  if ("stringUnit" in langTranslationEntity) {
1743
1744
  resultData[translationKey] = langTranslationEntity.stringUnit.value;
@@ -1746,7 +1747,7 @@ function createXcodeXcstringsLoader(defaultLocale) {
1746
1747
  resultData[translationKey] = {};
1747
1748
  const pluralForms = langTranslationEntity.variations.plural;
1748
1749
  for (const form in pluralForms) {
1749
- if (_optionalChain([pluralForms, 'access', _74 => _74[form], 'optionalAccess', _75 => _75.stringUnit, 'optionalAccess', _76 => _76.value])) {
1750
+ if (_optionalChain([pluralForms, 'access', _75 => _75[form], 'optionalAccess', _76 => _76.stringUnit, 'optionalAccess', _77 => _77.value])) {
1750
1751
  resultData[translationKey][form] = pluralForms[form].stringUnit.value;
1751
1752
  }
1752
1753
  }
@@ -1770,7 +1771,7 @@ function createXcodeXcstringsLoader(defaultLocale) {
1770
1771
  const hasDoNotTranslateFlag = originalInput && originalInput.strings && originalInput.strings[key] && originalInput.strings[key].shouldTranslate === false;
1771
1772
  if (typeof value === "string") {
1772
1773
  langDataToMerge.strings[key] = {
1773
- extractionState: _optionalChain([originalInput, 'optionalAccess', _77 => _77.strings, 'optionalAccess', _78 => _78[key], 'optionalAccess', _79 => _79.extractionState]),
1774
+ extractionState: _optionalChain([originalInput, 'optionalAccess', _78 => _78.strings, 'optionalAccess', _79 => _79[key], 'optionalAccess', _80 => _80.extractionState]),
1774
1775
  localizations: {
1775
1776
  [locale]: {
1776
1777
  stringUnit: {
@@ -1824,7 +1825,7 @@ function createPrettierLoader(options) {
1824
1825
  },
1825
1826
  async push(locale, data) {
1826
1827
  const draftPath = options.bucketPathPattern.replaceAll("[locale]", locale);
1827
- const finalPath = _path2.default.resolve(draftPath);
1828
+ const finalPath = path15.default.resolve(draftPath);
1828
1829
  const prettierConfig = await loadPrettierConfig(finalPath);
1829
1830
  if (!prettierConfig) {
1830
1831
  return data;
@@ -1889,10 +1890,10 @@ function createUnlocalizableLoader(isCacheRestore = false, returnUnlocalizedKeys
1889
1890
  }
1890
1891
  }
1891
1892
  return false;
1892
- }).map(([key, _22]) => key);
1893
- const result = _lodash2.default.omitBy(input2, (_22, key) => passthroughKeys.includes(key));
1893
+ }).map(([key, _23]) => key);
1894
+ const result = _lodash2.default.omitBy(input2, (_23, key) => passthroughKeys.includes(key));
1894
1895
  if (returnUnlocalizedKeys) {
1895
- result.unlocalizable = _lodash2.default.omitBy(input2, (_22, key) => !passthroughKeys.includes(key));
1896
+ result.unlocalizable = _lodash2.default.omitBy(input2, (_23, key) => !passthroughKeys.includes(key));
1896
1897
  }
1897
1898
  return result;
1898
1899
  },
@@ -1931,7 +1932,7 @@ function createPoDataLoader(params) {
1931
1932
  Object.entries(entries).forEach(([msgid, entry]) => {
1932
1933
  if (msgid && entry.msgid) {
1933
1934
  const context = entry.msgctxt || "";
1934
- const fullEntry = _optionalChain([parsedPo, 'access', _80 => _80.translations, 'access', _81 => _81[context], 'optionalAccess', _82 => _82[msgid]]);
1935
+ const fullEntry = _optionalChain([parsedPo, 'access', _81 => _81.translations, 'access', _82 => _82[context], 'optionalAccess', _83 => _83[msgid]]);
1935
1936
  if (fullEntry) {
1936
1937
  result[msgid] = fullEntry;
1937
1938
  }
@@ -1941,7 +1942,7 @@ function createPoDataLoader(params) {
1941
1942
  return result;
1942
1943
  },
1943
1944
  async push(locale, data, originalInput) {
1944
- const sections = _optionalChain([originalInput, 'optionalAccess', _83 => _83.split, 'call', _84 => _84("\n\n"), 'access', _85 => _85.filter, 'call', _86 => _86(Boolean)]) || [];
1945
+ const sections = _optionalChain([originalInput, 'optionalAccess', _84 => _84.split, 'call', _85 => _85("\n\n"), 'access', _86 => _86.filter, 'call', _87 => _87(Boolean)]) || [];
1945
1946
  const result = sections.map((section) => {
1946
1947
  const sectionPo = _gettextparser2.default.po.parse(section);
1947
1948
  const contextKey = _lodash2.default.keys(sectionPo.translations)[0];
@@ -1983,7 +1984,7 @@ function createPoContentLoader() {
1983
1984
  entry.msgid,
1984
1985
  {
1985
1986
  ...entry,
1986
- msgstr: [_optionalChain([data, 'access', _87 => _87[entry.msgid], 'optionalAccess', _88 => _88.singular]), _optionalChain([data, 'access', _89 => _89[entry.msgid], 'optionalAccess', _90 => _90.plural]) || null].filter(Boolean)
1987
+ msgstr: [_optionalChain([data, 'access', _88 => _88[entry.msgid], 'optionalAccess', _89 => _89.singular]), _optionalChain([data, 'access', _90 => _90[entry.msgid], 'optionalAccess', _91 => _91.plural]) || null].filter(Boolean)
1987
1988
  }
1988
1989
  ]).fromPairs().value();
1989
1990
  return result;
@@ -2229,7 +2230,7 @@ function createDatoClient(params) {
2229
2230
  only_valid: "true",
2230
2231
  ids: !records.length ? void 0 : records.join(",")
2231
2232
  }
2232
- }).catch((error) => Promise.reject(_optionalChain([error, 'optionalAccess', _91 => _91.response, 'optionalAccess', _92 => _92.body, 'optionalAccess', _93 => _93.data, 'optionalAccess', _94 => _94[0]]) || error));
2233
+ }).catch((error) => Promise.reject(_optionalChain([error, 'optionalAccess', _92 => _92.response, 'optionalAccess', _93 => _93.body, 'optionalAccess', _94 => _94.data, 'optionalAccess', _95 => _95[0]]) || error));
2233
2234
  },
2234
2235
  findRecordsForModel: async (modelId, records) => {
2235
2236
  try {
@@ -2239,9 +2240,9 @@ function createDatoClient(params) {
2239
2240
  filter: {
2240
2241
  type: modelId,
2241
2242
  only_valid: "true",
2242
- ids: !_optionalChain([records, 'optionalAccess', _95 => _95.length]) ? void 0 : records.join(",")
2243
+ ids: !_optionalChain([records, 'optionalAccess', _96 => _96.length]) ? void 0 : records.join(",")
2243
2244
  }
2244
- }).catch((error) => Promise.reject(_optionalChain([error, 'optionalAccess', _96 => _96.response, 'optionalAccess', _97 => _97.body, 'optionalAccess', _98 => _98.data, 'optionalAccess', _99 => _99[0]]) || error));
2245
+ }).catch((error) => Promise.reject(_optionalChain([error, 'optionalAccess', _97 => _97.response, 'optionalAccess', _98 => _98.body, 'optionalAccess', _99 => _99.data, 'optionalAccess', _100 => _100[0]]) || error));
2245
2246
  return result;
2246
2247
  } catch (_error) {
2247
2248
  throw new Error(
@@ -2255,9 +2256,9 @@ function createDatoClient(params) {
2255
2256
  },
2256
2257
  updateRecord: async (id, payload) => {
2257
2258
  try {
2258
- await dato.items.update(id, payload).catch((error) => Promise.reject(_optionalChain([error, 'optionalAccess', _100 => _100.response, 'optionalAccess', _101 => _101.body, 'optionalAccess', _102 => _102.data, 'optionalAccess', _103 => _103[0]]) || error));
2259
+ await dato.items.update(id, payload).catch((error) => Promise.reject(_optionalChain([error, 'optionalAccess', _101 => _101.response, 'optionalAccess', _102 => _102.body, 'optionalAccess', _103 => _103.data, 'optionalAccess', _104 => _104[0]]) || error));
2259
2260
  } catch (_error) {
2260
- if (_optionalChain([_error, 'optionalAccess', _104 => _104.attributes, 'optionalAccess', _105 => _105.details, 'optionalAccess', _106 => _106.message])) {
2261
+ if (_optionalChain([_error, 'optionalAccess', _105 => _105.attributes, 'optionalAccess', _106 => _106.details, 'optionalAccess', _107 => _107.message])) {
2261
2262
  throw new Error(
2262
2263
  [
2263
2264
  `${_error.attributes.details.message}`,
@@ -2278,9 +2279,9 @@ function createDatoClient(params) {
2278
2279
  },
2279
2280
  enableFieldLocalization: async (args) => {
2280
2281
  try {
2281
- await dato.fields.update(`${args.modelId}::${args.fieldId}`, { localized: true }).catch((error) => Promise.reject(_optionalChain([error, 'optionalAccess', _107 => _107.response, 'optionalAccess', _108 => _108.body, 'optionalAccess', _109 => _109.data, 'optionalAccess', _110 => _110[0]]) || error));
2282
+ await dato.fields.update(`${args.modelId}::${args.fieldId}`, { localized: true }).catch((error) => Promise.reject(_optionalChain([error, 'optionalAccess', _108 => _108.response, 'optionalAccess', _109 => _109.body, 'optionalAccess', _110 => _110.data, 'optionalAccess', _111 => _111[0]]) || error));
2282
2283
  } catch (_error) {
2283
- if (_optionalChain([_error, 'optionalAccess', _111 => _111.attributes, 'optionalAccess', _112 => _112.code]) === "NOT_FOUND") {
2284
+ if (_optionalChain([_error, 'optionalAccess', _112 => _112.attributes, 'optionalAccess', _113 => _113.code]) === "NOT_FOUND") {
2284
2285
  throw new Error(
2285
2286
  [
2286
2287
  `Field "${args.fieldId}" not found in model "${args.modelId}".`,
@@ -2288,7 +2289,7 @@ function createDatoClient(params) {
2288
2289
  ].join("\n\n")
2289
2290
  );
2290
2291
  }
2291
- if (_optionalChain([_error, 'optionalAccess', _113 => _113.attributes, 'optionalAccess', _114 => _114.details, 'optionalAccess', _115 => _115.message])) {
2292
+ if (_optionalChain([_error, 'optionalAccess', _114 => _114.attributes, 'optionalAccess', _115 => _115.details, 'optionalAccess', _116 => _116.message])) {
2292
2293
  throw new Error(
2293
2294
  [`${_error.attributes.details.message}`, `Error: ${JSON.stringify(_error, null, 2)}`].join("\n\n")
2294
2295
  );
@@ -2354,7 +2355,7 @@ function createDatoApiLoader(config, onConfigUpdate) {
2354
2355
  }
2355
2356
  }
2356
2357
  const records = await dato.findRecordsForModel(modelId);
2357
- const recordChoices = createRecordChoices(records, _optionalChain([config, 'access', _116 => _116.models, 'access', _117 => _117[modelId], 'optionalAccess', _118 => _118.records]) || [], project);
2358
+ const recordChoices = createRecordChoices(records, _optionalChain([config, 'access', _117 => _117.models, 'access', _118 => _118[modelId], 'optionalAccess', _119 => _119.records]) || [], project);
2358
2359
  const selectedRecords = await promptRecordSelection(modelName, recordChoices);
2359
2360
  result.models[modelId].records = records.filter((record) => selectedRecords.includes(record.id));
2360
2361
  updatedConfig.models[modelId].records = selectedRecords;
@@ -2366,14 +2367,14 @@ function createDatoApiLoader(config, onConfigUpdate) {
2366
2367
  },
2367
2368
  async pull(locale, input2, initCtx) {
2368
2369
  const result = {};
2369
- for (const modelId of _lodash2.default.keys(_optionalChain([initCtx, 'optionalAccess', _119 => _119.models]) || {})) {
2370
- let records = _optionalChain([initCtx, 'optionalAccess', _120 => _120.models, 'access', _121 => _121[modelId], 'access', _122 => _122.records]) || [];
2370
+ for (const modelId of _lodash2.default.keys(_optionalChain([initCtx, 'optionalAccess', _120 => _120.models]) || {})) {
2371
+ let records = _optionalChain([initCtx, 'optionalAccess', _121 => _121.models, 'access', _122 => _122[modelId], 'access', _123 => _123.records]) || [];
2371
2372
  const recordIds = records.map((record) => record.id);
2372
2373
  records = await dato.findRecords(recordIds);
2373
2374
  console.log(`Fetched ${records.length} records for model ${modelId}`);
2374
2375
  if (records.length > 0) {
2375
2376
  result[modelId] = {
2376
- fields: _optionalChain([initCtx, 'optionalAccess', _123 => _123.models, 'optionalAccess', _124 => _124[modelId], 'optionalAccess', _125 => _125.fields]) || [],
2377
+ fields: _optionalChain([initCtx, 'optionalAccess', _124 => _124.models, 'optionalAccess', _125 => _125[modelId], 'optionalAccess', _126 => _126.fields]) || [],
2377
2378
  records
2378
2379
  };
2379
2380
  }
@@ -2432,7 +2433,7 @@ function createRecordChoices(records, selectedIds = [], project) {
2432
2433
  return records.map((record) => ({
2433
2434
  name: `${record.id} - https://${project.internal_domain}/editor/item_types/${record.item_type.id}/items/${record.id}`,
2434
2435
  value: record.id,
2435
- checked: _optionalChain([selectedIds, 'optionalAccess', _126 => _126.includes, 'call', _127 => _127(record.id)])
2436
+ checked: _optionalChain([selectedIds, 'optionalAccess', _127 => _127.includes, 'call', _128 => _128(record.id)])
2436
2437
  }));
2437
2438
  }
2438
2439
  async function promptRecordSelection(modelName, choices) {
@@ -2583,18 +2584,18 @@ function createRawDatoValue(parsedDatoValue, originalRawDatoValue, isClean = fal
2583
2584
  }
2584
2585
  function serializeStructuredText(rawStructuredText) {
2585
2586
  return serializeStructuredTextNode(rawStructuredText);
2586
- function serializeStructuredTextNode(node, path15 = [], acc = {}) {
2587
+ function serializeStructuredTextNode(node, path18 = [], acc = {}) {
2587
2588
  if ("document" in node) {
2588
- return serializeStructuredTextNode(node.document, [...path15, "document"], acc);
2589
+ return serializeStructuredTextNode(node.document, [...path18, "document"], acc);
2589
2590
  }
2590
2591
  if (!_lodash2.default.isNil(node.value)) {
2591
- acc[[...path15, "value"].join(".")] = node.value;
2592
+ acc[[...path18, "value"].join(".")] = node.value;
2592
2593
  } else if (_lodash2.default.get(node, "type") === "block") {
2593
- acc[[...path15, "item"].join(".")] = serializeBlock(node.item);
2594
+ acc[[...path18, "item"].join(".")] = serializeBlock(node.item);
2594
2595
  }
2595
2596
  if (node.children) {
2596
2597
  for (let i = 0; i < node.children.length; i++) {
2597
- serializeStructuredTextNode(node.children[i], [...path15, i.toString()], acc);
2598
+ serializeStructuredTextNode(node.children[i], [...path18, i.toString()], acc);
2598
2599
  }
2599
2600
  }
2600
2601
  return acc;
@@ -2653,8 +2654,8 @@ function deserializeBlockList(parsedBlockList, originalRawBlockList, isClean = f
2653
2654
  }
2654
2655
  function deserializeStructuredText(parsedStructuredText, originalRawStructuredText) {
2655
2656
  const result = _lodash2.default.cloneDeep(originalRawStructuredText);
2656
- for (const [path15, value] of _lodash2.default.entries(parsedStructuredText)) {
2657
- const realPath = _lodash2.default.chain(path15.split(".")).flatMap((s) => !_lodash2.default.isNaN(_lodash2.default.toNumber(s)) ? ["children", s] : s).value();
2657
+ for (const [path18, value] of _lodash2.default.entries(parsedStructuredText)) {
2658
+ const realPath = _lodash2.default.chain(path18.split(".")).flatMap((s) => !_lodash2.default.isNaN(_lodash2.default.toNumber(s)) ? ["children", s] : s).value();
2658
2659
  const deserializedValue = createRawDatoValue(value, _lodash2.default.get(originalRawStructuredText, realPath), true);
2659
2660
  _lodash2.default.set(result, realPath, deserializedValue);
2660
2661
  }
@@ -2679,12 +2680,12 @@ function _isVideo(rawDatoValue) {
2679
2680
  // src/cli/loaders/dato/index.ts
2680
2681
  function createDatoLoader(configFilePath) {
2681
2682
  try {
2682
- const configContent = _fs2.default.readFileSync(configFilePath, "utf-8");
2683
+ const configContent = fs11.default.readFileSync(configFilePath, "utf-8");
2683
2684
  const datoConfig = datoConfigSchema.parse(_json52.default.parse(configContent));
2684
2685
  return composeLoaders(
2685
2686
  createDatoApiLoader(
2686
2687
  datoConfig,
2687
- (updatedConfig) => _fs2.default.writeFileSync(configFilePath, _json52.default.stringify(updatedConfig, null, 2))
2688
+ (updatedConfig) => fs11.default.writeFileSync(configFilePath, _json52.default.stringify(updatedConfig, null, 2))
2688
2689
  ),
2689
2690
  createDatoFilterLoader(),
2690
2691
  createDatoExtractLoader()
@@ -2699,7 +2700,7 @@ var _nodewebvtt = require('node-webvtt'); var _nodewebvtt2 = _interopRequireDefa
2699
2700
  function createVttLoader() {
2700
2701
  return createLoader({
2701
2702
  async pull(locale, input2) {
2702
- const vtt = _optionalChain([_nodewebvtt2.default, 'access', _128 => _128.parse, 'call', _129 => _129(input2), 'optionalAccess', _130 => _130.cues]);
2703
+ const vtt = _optionalChain([_nodewebvtt2.default, 'access', _129 => _129.parse, 'call', _130 => _130(input2), 'optionalAccess', _131 => _131.cues]);
2703
2704
  if (Object.keys(vtt).length === 0) {
2704
2705
  return {};
2705
2706
  } else {
@@ -2752,7 +2753,7 @@ function variableExtractLoader(params) {
2752
2753
  for (let i = 0; i < matches.length; i++) {
2753
2754
  const match = matches[i];
2754
2755
  const currentValue = result[key].value;
2755
- const newValue = _optionalChain([currentValue, 'optionalAccess', _131 => _131.replace, 'call', _132 => _132(match, `{variable:${i}}`)]);
2756
+ const newValue = _optionalChain([currentValue, 'optionalAccess', _132 => _132.replace, 'call', _133 => _133(match, `{variable:${i}}`)]);
2756
2757
  result[key].value = newValue;
2757
2758
  result[key].variables[i] = match;
2758
2759
  }
@@ -2766,7 +2767,7 @@ function variableExtractLoader(params) {
2766
2767
  for (let i = 0; i < valueObj.variables.length; i++) {
2767
2768
  const variable = valueObj.variables[i];
2768
2769
  const currentValue = result[key];
2769
- const newValue = _optionalChain([currentValue, 'optionalAccess', _133 => _133.replace, 'call', _134 => _134(`{variable:${i}}`, variable)]);
2770
+ const newValue = _optionalChain([currentValue, 'optionalAccess', _134 => _134.replace, 'call', _135 => _135(`{variable:${i}}`, variable)]);
2770
2771
  result[key] = newValue;
2771
2772
  }
2772
2773
  }
@@ -2947,7 +2948,7 @@ function createVueJsonLoader() {
2947
2948
  return createLoader({
2948
2949
  pull: async (locale, input2, ctx) => {
2949
2950
  const parsed = parseVueFile(input2);
2950
- return _nullishCoalesce(_optionalChain([parsed, 'optionalAccess', _135 => _135.i18n, 'optionalAccess', _136 => _136[locale]]), () => ( {}));
2951
+ return _nullishCoalesce(_optionalChain([parsed, 'optionalAccess', _136 => _136.i18n, 'optionalAccess', _137 => _137[locale]]), () => ( {}));
2951
2952
  },
2952
2953
  push: async (locale, data, originalInput) => {
2953
2954
  const parsed = parseVueFile(_nullishCoalesce(originalInput, () => ( "")));
@@ -3179,75 +3180,6 @@ function createBucketLoader(bucketType, bucketPathPattern, options) {
3179
3180
  }
3180
3181
  }
3181
3182
 
3182
- // src/cli/utils/lockfile.ts
3183
-
3184
-
3185
-
3186
-
3187
- var _objecthash = require('object-hash');
3188
-
3189
- function createLockfileHelper() {
3190
- return {
3191
- isLockfileExists: () => {
3192
- const lockfilePath = _getLockfilePath();
3193
- return _fs2.default.existsSync(lockfilePath);
3194
- },
3195
- registerSourceData: (pathPattern, sourceData) => {
3196
- const lockfile = _loadLockfile();
3197
- const sectionKey = _objecthash.MD5.call(void 0, pathPattern);
3198
- const sectionChecksums = _lodash2.default.mapValues(sourceData, (value) => _objecthash.MD5.call(void 0, value));
3199
- lockfile.checksums[sectionKey] = sectionChecksums;
3200
- _saveLockfile(lockfile);
3201
- },
3202
- registerPartialSourceData: (pathPattern, partialSourceData) => {
3203
- const lockfile = _loadLockfile();
3204
- const sectionKey = _objecthash.MD5.call(void 0, pathPattern);
3205
- const sectionChecksums = _lodash2.default.mapValues(partialSourceData, (value) => _objecthash.MD5.call(void 0, value));
3206
- lockfile.checksums[sectionKey] = _lodash2.default.merge({}, _nullishCoalesce(lockfile.checksums[sectionKey], () => ( {})), sectionChecksums);
3207
- _saveLockfile(lockfile);
3208
- },
3209
- extractUpdatedData: (pathPattern, sourceData) => {
3210
- const lockfile = _loadLockfile();
3211
- const sectionKey = _objecthash.MD5.call(void 0, pathPattern);
3212
- const currentChecksums = _lodash2.default.mapValues(sourceData, (value) => _objecthash.MD5.call(void 0, value));
3213
- const savedChecksums = lockfile.checksums[sectionKey] || {};
3214
- const updatedData = _lodash2.default.pickBy(sourceData, (value, key) => savedChecksums[key] !== currentChecksums[key]);
3215
- return updatedData;
3216
- }
3217
- };
3218
- function _loadLockfile() {
3219
- const lockfilePath = _getLockfilePath();
3220
- if (!_fs2.default.existsSync(lockfilePath)) {
3221
- return LockfileSchema.parse({});
3222
- }
3223
- const content = _fs2.default.readFileSync(lockfilePath, "utf-8");
3224
- const result = LockfileSchema.parse(_yaml2.default.parse(content));
3225
- return result;
3226
- }
3227
- function _saveLockfile(lockfile) {
3228
- const lockfilePath = _getLockfilePath();
3229
- const content = _yaml2.default.stringify(lockfile);
3230
- _fs2.default.writeFileSync(lockfilePath, content);
3231
- }
3232
- function _getLockfilePath() {
3233
- return _path2.default.join(process.cwd(), "i18n.lock");
3234
- }
3235
- }
3236
- var LockfileSchema = _zod2.default.object({
3237
- version: _zod2.default.literal(1).default(1),
3238
- checksums: _zod2.default.record(
3239
- _zod2.default.string(),
3240
- // localizable files' keys
3241
- _zod2.default.record(
3242
- // checksums hashmap
3243
- _zod2.default.string(),
3244
- // key
3245
- _zod2.default.string()
3246
- // checksum of the key's value in the source locale
3247
- ).default({})
3248
- ).default({})
3249
- });
3250
-
3251
3183
  // src/cli/cmd/i18n.ts
3252
3184
  var _chalk = require('chalk'); var _chalk2 = _interopRequireDefault(_chalk);
3253
3185
  var _diff = require('diff');
@@ -3286,26 +3218,26 @@ function getNormalizedCache() {
3286
3218
  function deleteCache() {
3287
3219
  const cacheFilePath = _getCacheFilePath();
3288
3220
  try {
3289
- _fs2.default.unlinkSync(cacheFilePath);
3221
+ fs11.default.unlinkSync(cacheFilePath);
3290
3222
  } catch (e) {
3291
3223
  }
3292
3224
  }
3293
3225
  function _loadCache() {
3294
3226
  const cacheFilePath = _getCacheFilePath();
3295
- if (!_fs2.default.existsSync(cacheFilePath)) {
3227
+ if (!fs11.default.existsSync(cacheFilePath)) {
3296
3228
  return [];
3297
3229
  }
3298
- const content = _fs2.default.readFileSync(cacheFilePath, "utf-8");
3230
+ const content = fs11.default.readFileSync(cacheFilePath, "utf-8");
3299
3231
  const result = _parseJSONLines(content);
3300
3232
  return result;
3301
3233
  }
3302
3234
  function _appendToCache(rows) {
3303
3235
  const cacheFilePath = _getCacheFilePath();
3304
3236
  const lines = _buildJSONLines(rows);
3305
- _fs2.default.appendFileSync(cacheFilePath, lines);
3237
+ fs11.default.appendFileSync(cacheFilePath, lines);
3306
3238
  }
3307
3239
  function _getCacheFilePath() {
3308
- return _path2.default.join(process.cwd(), "i18n.cache");
3240
+ return path15.default.join(process.cwd(), "i18n.cache");
3309
3241
  }
3310
3242
  function _buildJSONLines(rows) {
3311
3243
  return rows.map((row) => JSON.stringify(row)).join("\n") + "\n";
@@ -3325,6 +3257,9 @@ function _tryParseJSON(line) {
3325
3257
  var __sdk = require('@lingo.dev/_sdk');
3326
3258
  function createLingoLocalizer(params) {
3327
3259
  return async (input2, onProgress) => {
3260
+ if (!Object.keys(input2.processableData).length) {
3261
+ return input2.processableData;
3262
+ }
3328
3263
  const lingo = new (0, __sdk.LingoDotDevEngine)({
3329
3264
  apiKey: params.apiKey,
3330
3265
  apiUrl: params.apiUrl
@@ -3345,10 +3280,13 @@ function createLingoLocalizer(params) {
3345
3280
  };
3346
3281
  }
3347
3282
 
3348
- // src/cli/processor/openai.ts
3283
+ // src/cli/processor/basic.ts
3349
3284
  var _ai = require('ai');
3350
3285
  function createBasicTranslator(model, systemPrompt) {
3351
3286
  return async (input2, onProgress) => {
3287
+ if (!Object.keys(input2.processableData).length) {
3288
+ return input2.processableData;
3289
+ }
3352
3290
  if (!process.env.OPENAI_API_KEY) {
3353
3291
  throw new Error("OPENAI_API_KEY is not set");
3354
3292
  }
@@ -3393,7 +3331,7 @@ function createBasicTranslator(model, systemPrompt) {
3393
3331
  ]
3394
3332
  });
3395
3333
  const result = JSON.parse(response.text);
3396
- return result;
3334
+ return _optionalChain([result, 'optionalAccess', _138 => _138.data]) || {};
3397
3335
  };
3398
3336
  }
3399
3337
 
@@ -3411,7 +3349,7 @@ function createProcessor(provider, params) {
3411
3349
  }
3412
3350
  }
3413
3351
  function getPureModelProvider(provider) {
3414
- switch (_optionalChain([provider, 'optionalAccess', _137 => _137.id])) {
3352
+ switch (_optionalChain([provider, 'optionalAccess', _139 => _139.id])) {
3415
3353
  case "openai":
3416
3354
  if (!process.env.OPENAI_API_KEY) {
3417
3355
  throw new Error("OPENAI_API_KEY is not set.");
@@ -3428,7 +3366,7 @@ function getPureModelProvider(provider) {
3428
3366
  apiKey: process.env.ANTHROPIC_API_KEY
3429
3367
  })(provider.model);
3430
3368
  default:
3431
- throw new Error(`Unsupported provider: ${_optionalChain([provider, 'optionalAccess', _138 => _138.id])}`);
3369
+ throw new Error(`Unsupported provider: ${_optionalChain([provider, 'optionalAccess', _140 => _140.id])}`);
3432
3370
  }
3433
3371
  }
3434
3372
 
@@ -3462,12 +3400,127 @@ async function trackEvent(distinctId, event, properties) {
3462
3400
  await posthog.capture({
3463
3401
  distinctId,
3464
3402
  event,
3465
- properties
3403
+ properties: {
3404
+ ...properties,
3405
+ meta: {
3406
+ version: process.env.npm_package_version,
3407
+ isCi: process.env.CI === "true"
3408
+ }
3409
+ }
3466
3410
  });
3467
3411
  await posthog.shutdown();
3468
3412
  }
3469
3413
 
3414
+ // src/cli/utils/delta.ts
3415
+
3416
+
3417
+ var _objecthash = require('object-hash');
3418
+
3419
+ // src/cli/utils/fs.ts
3420
+
3421
+
3422
+ function tryReadFile(filePath, defaultValue = null) {
3423
+ try {
3424
+ const content = fs11.readFileSync(filePath, "utf-8");
3425
+ return content;
3426
+ } catch (error) {
3427
+ return defaultValue;
3428
+ }
3429
+ }
3430
+ function writeFile(filePath, content) {
3431
+ const dir = path13.dirname(filePath);
3432
+ if (!fs11.existsSync(dir)) {
3433
+ fs11.mkdirSync(dir, { recursive: true });
3434
+ }
3435
+ fs11.writeFileSync(filePath, content);
3436
+ }
3437
+ function checkIfFileExists(filePath) {
3438
+ return fs11.existsSync(filePath);
3439
+ }
3440
+
3441
+ // src/cli/utils/delta.ts
3442
+
3443
+
3444
+ var LockSchema = _zod2.default.object({
3445
+ version: _zod2.default.literal(1).default(1),
3446
+ checksums: _zod2.default.record(
3447
+ _zod2.default.string(),
3448
+ // localizable files' keys
3449
+ // checksums hashmap
3450
+ _zod2.default.record(
3451
+ // key
3452
+ _zod2.default.string(),
3453
+ // checksum of the key's value in the source locale
3454
+ _zod2.default.string()
3455
+ ).default({})
3456
+ ).default({})
3457
+ });
3458
+ function createDeltaProcessor(fileKey) {
3459
+ const lockfilePath = path14.join(process.cwd(), "i18n.lock");
3460
+ return {
3461
+ async checkIfLockExists() {
3462
+ return checkIfFileExists(lockfilePath);
3463
+ },
3464
+ async calculateDelta(params) {
3465
+ let added = _lodash2.default.difference(Object.keys(params.sourceData), Object.keys(params.targetData));
3466
+ let removed = _lodash2.default.difference(Object.keys(params.targetData), Object.keys(params.sourceData));
3467
+ const updated = _lodash2.default.filter(Object.keys(params.sourceData), (key) => {
3468
+ return _objecthash.MD5.call(void 0, params.sourceData[key]) !== params.checksums[key] && params.checksums[key];
3469
+ });
3470
+ const renamed = [];
3471
+ for (const addedKey of added) {
3472
+ const addedHash = _objecthash.MD5.call(void 0, params.sourceData[addedKey]);
3473
+ for (const removedKey of removed) {
3474
+ if (params.checksums[removedKey] === addedHash) {
3475
+ renamed.push([removedKey, addedKey]);
3476
+ break;
3477
+ }
3478
+ }
3479
+ }
3480
+ added = added.filter((key) => !renamed.some(([oldKey, newKey]) => newKey === key));
3481
+ removed = removed.filter((key) => !renamed.some(([oldKey, newKey]) => oldKey === key));
3482
+ const hasChanges = [added.length > 0, removed.length > 0, updated.length > 0, renamed.length > 0].some((v) => v);
3483
+ return {
3484
+ added,
3485
+ removed,
3486
+ updated,
3487
+ renamed,
3488
+ hasChanges
3489
+ };
3490
+ },
3491
+ async loadLock() {
3492
+ const lockfileContent = tryReadFile(lockfilePath, null);
3493
+ const lockfileYaml = lockfileContent ? _yaml2.default.parse(lockfileContent) : null;
3494
+ const lockfileData = lockfileYaml ? LockSchema.parse(lockfileYaml) : {
3495
+ version: 1,
3496
+ checksums: {}
3497
+ };
3498
+ return lockfileData;
3499
+ },
3500
+ async saveLock(lockData) {
3501
+ const lockfileYaml = _yaml2.default.stringify(lockData);
3502
+ writeFile(lockfilePath, lockfileYaml);
3503
+ },
3504
+ async loadChecksums() {
3505
+ const id = _objecthash.MD5.call(void 0, fileKey);
3506
+ const lockfileData = await this.loadLock();
3507
+ return lockfileData.checksums[id] || {};
3508
+ },
3509
+ async saveChecksums(checksums) {
3510
+ const id = _objecthash.MD5.call(void 0, fileKey);
3511
+ const lockfileData = await this.loadLock();
3512
+ lockfileData.checksums[id] = checksums;
3513
+ await this.saveLock(lockfileData);
3514
+ },
3515
+ async createChecksums(sourceData) {
3516
+ const checksums = _lodash2.default.mapValues(sourceData, (value) => _objecthash.MD5.call(void 0, value));
3517
+ return checksums;
3518
+ }
3519
+ };
3520
+ }
3521
+
3470
3522
  // src/cli/cmd/i18n.ts
3523
+
3471
3524
  var i18n_default = new (0, _interactivecommander.Command)().command("i18n").description("Run Localization engine").helpOption("-h, --help", "Show help").option("--locale <locale>", "Locale to process", (val, prev) => prev ? [...prev, val] : [val]).option("--bucket <bucket>", "Bucket to process", (val, prev) => prev ? [...prev, val] : [val]).option(
3472
3525
  "--key <key>",
3473
3526
  "Key to process. Process only a specific translation key, useful for debugging or updating a single entry"
@@ -3509,13 +3562,13 @@ var i18n_default = new (0, _interactivecommander.Command)().command("i18n").desc
3509
3562
  flags
3510
3563
  });
3511
3564
  let buckets = getBuckets(i18nConfig);
3512
- if (_optionalChain([flags, 'access', _139 => _139.bucket, 'optionalAccess', _140 => _140.length])) {
3565
+ if (_optionalChain([flags, 'access', _141 => _141.bucket, 'optionalAccess', _142 => _142.length])) {
3513
3566
  buckets = buckets.filter((bucket) => flags.bucket.includes(bucket.type));
3514
3567
  }
3515
3568
  ora.succeed("Buckets retrieved");
3516
- if (_optionalChain([flags, 'access', _141 => _141.file, 'optionalAccess', _142 => _142.length])) {
3569
+ if (_optionalChain([flags, 'access', _143 => _143.file, 'optionalAccess', _144 => _144.length])) {
3517
3570
  buckets = buckets.map((bucket) => {
3518
- const paths = bucket.paths.filter((path15) => flags.file.find((file) => _optionalChain([path15, 'access', _143 => _143.pathPattern, 'optionalAccess', _144 => _144.match, 'call', _145 => _145(file)])));
3571
+ const paths = bucket.paths.filter((path18) => flags.file.find((file) => _optionalChain([path18, 'access', _145 => _145.pathPattern, 'optionalAccess', _146 => _146.match, 'call', _147 => _147(file)])));
3519
3572
  return { ...bucket, paths };
3520
3573
  }).filter((bucket) => bucket.paths.length > 0);
3521
3574
  if (buckets.length === 0) {
@@ -3525,16 +3578,17 @@ var i18n_default = new (0, _interactivecommander.Command)().command("i18n").desc
3525
3578
  ora.info(`\x1B[36mProcessing only filtered buckets:\x1B[0m`);
3526
3579
  buckets.map((bucket) => {
3527
3580
  ora.info(` ${bucket.type}:`);
3528
- bucket.paths.forEach((path15) => {
3529
- ora.info(` - ${path15.pathPattern}`);
3581
+ bucket.paths.forEach((path18) => {
3582
+ ora.info(` - ${path18.pathPattern}`);
3530
3583
  });
3531
3584
  });
3532
3585
  }
3533
3586
  }
3534
- const targetLocales = _optionalChain([flags, 'access', _146 => _146.locale, 'optionalAccess', _147 => _147.length]) ? flags.locale : i18nConfig.locale.targets;
3535
- const lockfileHelper = createLockfileHelper();
3536
- ora.start("Ensuring i18n.lock exists...");
3537
- if (!lockfileHelper.isLockfileExists()) {
3587
+ const targetLocales = _optionalChain([flags, 'access', _148 => _148.locale, 'optionalAccess', _149 => _149.length]) ? flags.locale : i18nConfig.locale.targets;
3588
+ ora.start("Setting up localization cache...");
3589
+ const checkLockfileProcessor = createDeltaProcessor("");
3590
+ const lockfileExists = await checkLockfileProcessor.checkIfLockExists();
3591
+ if (!lockfileExists) {
3538
3592
  ora.start("Creating i18n.lock...");
3539
3593
  for (const bucket of buckets) {
3540
3594
  for (const bucketPath of bucket.paths) {
@@ -3547,12 +3601,66 @@ var i18n_default = new (0, _interactivecommander.Command)().command("i18n").desc
3547
3601
  bucketLoader.setDefaultLocale(sourceLocale);
3548
3602
  await bucketLoader.init();
3549
3603
  const sourceData = await bucketLoader.pull(i18nConfig.locale.source);
3550
- lockfileHelper.registerSourceData(bucketPath.pathPattern, sourceData);
3604
+ const deltaProcessor = createDeltaProcessor(bucketPath.pathPattern);
3605
+ const checksums = await deltaProcessor.createChecksums(sourceData);
3606
+ await deltaProcessor.saveChecksums(checksums);
3551
3607
  }
3552
3608
  }
3553
- ora.succeed("i18n.lock created");
3609
+ ora.succeed("Localization cache initialized");
3554
3610
  } else {
3555
- ora.succeed("i18n.lock loaded");
3611
+ ora.succeed("Localization cache loaded");
3612
+ }
3613
+ for (const bucket of buckets) {
3614
+ if (bucket.type !== "json") {
3615
+ continue;
3616
+ }
3617
+ ora.start("Validating localization state...");
3618
+ for (const bucketPath of bucket.paths) {
3619
+ const sourceLocale = __spec.resolveOverriddenLocale.call(void 0, i18nConfig.locale.source, bucketPath.delimiter);
3620
+ const deltaProcessor = createDeltaProcessor(bucketPath.pathPattern);
3621
+ const sourcePath = path15.join(process.cwd(), bucketPath.pathPattern.replace("[locale]", sourceLocale));
3622
+ const sourceContent = tryReadFile(sourcePath, null);
3623
+ const sourceData = JSON.parse(sourceContent || "{}");
3624
+ const sourceFlattenedData = _flat.flatten.call(void 0, sourceData, {
3625
+ delimiter: "/",
3626
+ transformKey(key) {
3627
+ return encodeURIComponent(key);
3628
+ }
3629
+ });
3630
+ for (const _targetLocale of targetLocales) {
3631
+ const targetLocale = __spec.resolveOverriddenLocale.call(void 0, _targetLocale, bucketPath.delimiter);
3632
+ const targetPath = path15.join(process.cwd(), bucketPath.pathPattern.replace("[locale]", targetLocale));
3633
+ const targetContent = tryReadFile(targetPath, null);
3634
+ const targetData = JSON.parse(targetContent || "{}");
3635
+ const targetFlattenedData = _flat.flatten.call(void 0, targetData, {
3636
+ delimiter: "/",
3637
+ transformKey(key) {
3638
+ return encodeURIComponent(key);
3639
+ }
3640
+ });
3641
+ const checksums = await deltaProcessor.loadChecksums();
3642
+ const delta = await deltaProcessor.calculateDelta({
3643
+ sourceData: sourceFlattenedData,
3644
+ targetData: targetFlattenedData,
3645
+ checksums
3646
+ });
3647
+ if (!delta.hasChanges) {
3648
+ continue;
3649
+ }
3650
+ for (const [oldKey, newKey] of delta.renamed) {
3651
+ targetFlattenedData[newKey] = targetFlattenedData[oldKey];
3652
+ delete targetFlattenedData[oldKey];
3653
+ }
3654
+ const updatedTargetData = _flat.unflatten.call(void 0, targetFlattenedData, {
3655
+ delimiter: "/",
3656
+ transformKey(key) {
3657
+ return decodeURIComponent(key);
3658
+ }
3659
+ });
3660
+ await writeFile(targetPath, JSON.stringify(updatedTargetData, null, 2));
3661
+ }
3662
+ }
3663
+ ora.succeed("Localization state check completed");
3556
3664
  }
3557
3665
  const cache = getNormalizedCache();
3558
3666
  if (cache) {
@@ -3584,7 +3692,9 @@ var i18n_default = new (0, _interactivecommander.Command)().command("i18n").desc
3584
3692
  }
3585
3693
  }
3586
3694
  await bucketLoader.push(targetLocale, targetData);
3587
- lockfileHelper.registerPartialSourceData(bucketPath.pathPattern, cachedSourceData);
3695
+ const deltaProcessor = createDeltaProcessor(bucketPath.pathPattern);
3696
+ const checksums = await deltaProcessor.createChecksums(cachedSourceData);
3697
+ await deltaProcessor.saveChecksums(checksums);
3588
3698
  bucketOra.succeed(
3589
3699
  `[${sourceLocale} -> ${targetLocale}] Recovered ${Object.keys(cachedSourceData).length} entries from cache`
3590
3700
  );
@@ -3615,7 +3725,13 @@ var i18n_default = new (0, _interactivecommander.Command)().command("i18n").desc
3615
3725
  const { unlocalizable: sourceUnlocalizable, ...sourceData } = await bucketLoader.pull(
3616
3726
  i18nConfig.locale.source
3617
3727
  );
3618
- const updatedSourceData = lockfileHelper.extractUpdatedData(bucketPath.pathPattern, sourceData);
3728
+ const deltaProcessor = createDeltaProcessor(bucketPath.pathPattern);
3729
+ const sourceChecksums = await deltaProcessor.createChecksums(sourceData);
3730
+ const savedChecksums = await deltaProcessor.loadChecksums();
3731
+ const updatedSourceData = _lodash2.default.pickBy(
3732
+ sourceData,
3733
+ (value, key) => sourceChecksums[key] !== savedChecksums[key]
3734
+ );
3619
3735
  if (Object.keys(updatedSourceData).length > 0) {
3620
3736
  requiresUpdate = "updated";
3621
3737
  break bucketLoop;
@@ -3675,15 +3791,17 @@ var i18n_default = new (0, _interactivecommander.Command)().command("i18n").desc
3675
3791
  try {
3676
3792
  bucketOra.start(`[${sourceLocale} -> ${targetLocale}] (0%) Localization in progress...`);
3677
3793
  sourceData = await bucketLoader.pull(sourceLocale);
3678
- const updatedSourceData = flags.force ? sourceData : lockfileHelper.extractUpdatedData(bucketPath.pathPattern, sourceData);
3679
3794
  const targetData = await bucketLoader.pull(targetLocale);
3680
- let processableData = calculateDataDelta({
3795
+ const deltaProcessor2 = createDeltaProcessor(bucketPath.pathPattern);
3796
+ const checksums2 = await deltaProcessor2.loadChecksums();
3797
+ const delta = await deltaProcessor2.calculateDelta({
3681
3798
  sourceData,
3682
- updatedSourceData,
3683
- targetData
3799
+ targetData,
3800
+ checksums: checksums2
3684
3801
  });
3802
+ let processableData = _lodash2.default.chain(sourceData).entries().filter(([key, value]) => delta.added.includes(key) || delta.updated.includes(key) || !!flags.force).fromPairs().value();
3685
3803
  if (flags.key) {
3686
- processableData = _lodash2.default.pickBy(processableData, (_22, key) => key === flags.key);
3804
+ processableData = _lodash2.default.pickBy(processableData, (_23, key) => key === flags.key);
3687
3805
  }
3688
3806
  if (flags.verbose) {
3689
3807
  bucketOra.info(JSON.stringify(processableData, null, 2));
@@ -3751,7 +3869,9 @@ var i18n_default = new (0, _interactivecommander.Command)().command("i18n").desc
3751
3869
  }
3752
3870
  }
3753
3871
  }
3754
- lockfileHelper.registerSourceData(bucketPath.pathPattern, sourceData);
3872
+ const deltaProcessor = createDeltaProcessor(bucketPath.pathPattern);
3873
+ const checksums = await deltaProcessor.createChecksums(sourceData);
3874
+ await deltaProcessor.saveChecksums(checksums);
3755
3875
  }
3756
3876
  } catch (_error) {
3757
3877
  const error = new Error(`Failed to process bucket ${bucket.type}: ${_error.message}`);
@@ -3786,12 +3906,6 @@ var i18n_default = new (0, _interactivecommander.Command)().command("i18n").desc
3786
3906
  process.exit(1);
3787
3907
  }
3788
3908
  });
3789
- function calculateDataDelta(args) {
3790
- const newKeys = _lodash2.default.difference(Object.keys(args.sourceData), Object.keys(args.targetData));
3791
- const updatedKeys = Object.keys(args.updatedSourceData);
3792
- const result = _lodash2.default.chain(args.sourceData).pickBy((value, key) => newKeys.includes(key) || updatedKeys.includes(key)).value();
3793
- return result;
3794
- }
3795
3909
  function parseFlags(options) {
3796
3910
  return _zod2.default.object({
3797
3911
  apiKey: _zod2.default.string().optional(),
@@ -3838,12 +3952,12 @@ function validateParams(i18nConfig, flags) {
3838
3952
  message: "No buckets found in i18n.json. Please add at least one bucket containing i18n content.",
3839
3953
  docUrl: "bucketNotFound"
3840
3954
  });
3841
- } else if (_optionalChain([flags, 'access', _148 => _148.locale, 'optionalAccess', _149 => _149.some, 'call', _150 => _150((locale) => !i18nConfig.locale.targets.includes(locale))])) {
3955
+ } else if (_optionalChain([flags, 'access', _150 => _150.locale, 'optionalAccess', _151 => _151.some, 'call', _152 => _152((locale) => !i18nConfig.locale.targets.includes(locale))])) {
3842
3956
  throw new CLIError({
3843
3957
  message: `One or more specified locales do not exist in i18n.json locale.targets. Please add them to the list and try again.`,
3844
3958
  docUrl: "localeTargetNotFound"
3845
3959
  });
3846
- } else if (_optionalChain([flags, 'access', _151 => _151.bucket, 'optionalAccess', _152 => _152.some, 'call', _153 => _153((bucket) => !i18nConfig.buckets[bucket])])) {
3960
+ } else if (_optionalChain([flags, 'access', _153 => _153.bucket, 'optionalAccess', _154 => _154.some, 'call', _155 => _155((bucket) => !i18nConfig.buckets[bucket])])) {
3847
3961
  throw new CLIError({
3848
3962
  message: `One or more specified buckets do not exist in i18n.json. Please add them to the list and try again.`,
3849
3963
  docUrl: "bucketNotFound"
@@ -3951,6 +4065,77 @@ Editing value for: ${_chalk2.default.cyan(key)}`);
3951
4065
 
3952
4066
 
3953
4067
 
4068
+ // src/cli/utils/lockfile.ts
4069
+
4070
+
4071
+
4072
+
4073
+
4074
+
4075
+ function createLockfileHelper() {
4076
+ return {
4077
+ isLockfileExists: () => {
4078
+ const lockfilePath = _getLockfilePath();
4079
+ return fs11.default.existsSync(lockfilePath);
4080
+ },
4081
+ registerSourceData: (pathPattern, sourceData) => {
4082
+ const lockfile = _loadLockfile();
4083
+ const sectionKey = _objecthash.MD5.call(void 0, pathPattern);
4084
+ const sectionChecksums = _lodash2.default.mapValues(sourceData, (value) => _objecthash.MD5.call(void 0, value));
4085
+ lockfile.checksums[sectionKey] = sectionChecksums;
4086
+ _saveLockfile(lockfile);
4087
+ },
4088
+ registerPartialSourceData: (pathPattern, partialSourceData) => {
4089
+ const lockfile = _loadLockfile();
4090
+ const sectionKey = _objecthash.MD5.call(void 0, pathPattern);
4091
+ const sectionChecksums = _lodash2.default.mapValues(partialSourceData, (value) => _objecthash.MD5.call(void 0, value));
4092
+ lockfile.checksums[sectionKey] = _lodash2.default.merge({}, _nullishCoalesce(lockfile.checksums[sectionKey], () => ( {})), sectionChecksums);
4093
+ _saveLockfile(lockfile);
4094
+ },
4095
+ extractUpdatedData: (pathPattern, sourceData) => {
4096
+ const lockfile = _loadLockfile();
4097
+ const sectionKey = _objecthash.MD5.call(void 0, pathPattern);
4098
+ const currentChecksums = _lodash2.default.mapValues(sourceData, (value) => _objecthash.MD5.call(void 0, value));
4099
+ const savedChecksums = lockfile.checksums[sectionKey] || {};
4100
+ const updatedData = _lodash2.default.pickBy(sourceData, (value, key) => savedChecksums[key] !== currentChecksums[key]);
4101
+ return updatedData;
4102
+ }
4103
+ };
4104
+ function _loadLockfile() {
4105
+ const lockfilePath = _getLockfilePath();
4106
+ if (!fs11.default.existsSync(lockfilePath)) {
4107
+ return LockfileSchema.parse({});
4108
+ }
4109
+ const content = fs11.default.readFileSync(lockfilePath, "utf-8");
4110
+ const result = LockfileSchema.parse(_yaml2.default.parse(content));
4111
+ return result;
4112
+ }
4113
+ function _saveLockfile(lockfile) {
4114
+ const lockfilePath = _getLockfilePath();
4115
+ const content = _yaml2.default.stringify(lockfile);
4116
+ fs11.default.writeFileSync(lockfilePath, content);
4117
+ }
4118
+ function _getLockfilePath() {
4119
+ return path15.default.join(process.cwd(), "i18n.lock");
4120
+ }
4121
+ }
4122
+ var LockfileSchema = _zod2.default.object({
4123
+ version: _zod2.default.literal(1).default(1),
4124
+ checksums: _zod2.default.record(
4125
+ _zod2.default.string(),
4126
+ // localizable files' keys
4127
+ _zod2.default.record(
4128
+ // checksums hashmap
4129
+ _zod2.default.string(),
4130
+ // key
4131
+ _zod2.default.string()
4132
+ // checksum of the key's value in the source locale
4133
+ ).default({})
4134
+ ).default({})
4135
+ });
4136
+
4137
+ // src/cli/cmd/lockfile.ts
4138
+
3954
4139
  var lockfile_default = new (0, _interactivecommander.Command)().command("lockfile").description("Create a lockfile if it does not exist").helpOption("-h, --help", "Show help").option("-f, --force", "Force create a lockfile").action(async (options) => {
3955
4140
  const flags = flagsSchema.parse(options);
3956
4141
  const ora = _ora2.default.call(void 0, );
@@ -4082,7 +4267,7 @@ var _stdiojs = require('@modelcontextprotocol/sdk/server/stdio.js');
4082
4267
  var _mcpjs = require('@modelcontextprotocol/sdk/server/mcp.js');
4083
4268
 
4084
4269
 
4085
- var mcp_default = new (0, _interactivecommander.Command)().command("mcp").description("Use Lingo.dev model context provider with your AI agent").helpOption("-h, --help", "Show help").action(async (_22, program) => {
4270
+ var mcp_default = new (0, _interactivecommander.Command)().command("mcp").description("Use Lingo.dev model context provider with your AI agent").helpOption("-h, --help", "Show help").action(async (_23, program) => {
4086
4271
  const apiKey = program.args[0];
4087
4272
  const settings = getSettings(apiKey);
4088
4273
  if (!settings.auth.apiKey) {
@@ -4205,7 +4390,7 @@ var InBranchFlow = class extends IntegrationFlow {
4205
4390
  _child_process.execSync.call(void 0, `git config --global safe.directory ${process.cwd()}`);
4206
4391
  _child_process.execSync.call(void 0, `git config user.name "${gitConfig.userName}"`);
4207
4392
  _child_process.execSync.call(void 0, `git config user.email "${gitConfig.userEmail}"`);
4208
- _optionalChain([this, 'access', _154 => _154.platformKit, 'optionalAccess', _155 => _155.gitConfig, 'call', _156 => _156()]);
4393
+ _optionalChain([this, 'access', _156 => _156.platformKit, 'optionalAccess', _157 => _157.gitConfig, 'call', _158 => _158()]);
4209
4394
  _child_process.execSync.call(void 0, `git fetch origin ${baseBranchName}`, { stdio: "inherit" });
4210
4395
  _child_process.execSync.call(void 0, `git checkout ${baseBranchName} --`, { stdio: "inherit" });
4211
4396
  if (!processOwnCommits) {
@@ -4218,7 +4403,7 @@ var InBranchFlow = class extends IntegrationFlow {
4218
4403
  return false;
4219
4404
  }
4220
4405
  }
4221
- const workingDir = _path2.default.resolve(process.cwd(), this.platformKit.config.workingDir);
4406
+ const workingDir = path15.default.resolve(process.cwd(), this.platformKit.config.workingDir);
4222
4407
  if (workingDir !== process.cwd()) {
4223
4408
  this.ora.info(`Changing to working directory: ${this.platformKit.config.workingDir}`);
4224
4409
  process.chdir(workingDir);
@@ -4230,7 +4415,7 @@ var InBranchFlow = class extends IntegrationFlow {
4230
4415
  // ../../action/src/flows/pull-request.ts
4231
4416
  var PullRequestFlow = class extends InBranchFlow {
4232
4417
  async preRun() {
4233
- const canContinue = await _optionalChain([super.preRun.bind(this), 'optionalCall', _157 => _157()]);
4418
+ const canContinue = await _optionalChain([super.preRun.bind(this), 'optionalCall', _159 => _159()]);
4234
4419
  if (!canContinue) {
4235
4420
  return false;
4236
4421
  }
@@ -4393,9 +4578,15 @@ var _bitbucket = require('bitbucket'); var _bitbucket2 = _interopRequireDefault(
4393
4578
 
4394
4579
  // ../../action/src/platforms/_base.ts
4395
4580
 
4581
+
4396
4582
  var defaultMessage = "feat: update translations via @lingodotdev";
4397
4583
  var PlatformKit = class {
4398
- gitConfig() {
4584
+ gitConfig(token, repoUrl) {
4585
+ if (token && repoUrl) {
4586
+ _child_process.execSync.call(void 0, `git remote set-url origin ${repoUrl}`, {
4587
+ stdio: "inherit"
4588
+ });
4589
+ }
4399
4590
  }
4400
4591
  get config() {
4401
4592
  const env = _zod2.default.object({
@@ -4442,10 +4633,10 @@ var BitbucketPlatformKit = class extends PlatformKit {
4442
4633
  repo_slug: this.platformConfig.repositoryName,
4443
4634
  state: "OPEN"
4444
4635
  }).then(({ data: { values } }) => {
4445
- return _optionalChain([values, 'optionalAccess', _158 => _158.find, 'call', _159 => _159(
4446
- ({ source, destination }) => _optionalChain([source, 'optionalAccess', _160 => _160.branch, 'optionalAccess', _161 => _161.name]) === branch && _optionalChain([destination, 'optionalAccess', _162 => _162.branch, 'optionalAccess', _163 => _163.name]) === this.platformConfig.baseBranchName
4636
+ return _optionalChain([values, 'optionalAccess', _160 => _160.find, 'call', _161 => _161(
4637
+ ({ source, destination }) => _optionalChain([source, 'optionalAccess', _162 => _162.branch, 'optionalAccess', _163 => _163.name]) === branch && _optionalChain([destination, 'optionalAccess', _164 => _164.branch, 'optionalAccess', _165 => _165.name]) === this.platformConfig.baseBranchName
4447
4638
  )]);
4448
- }).then((pr) => _optionalChain([pr, 'optionalAccess', _164 => _164.id]));
4639
+ }).then((pr) => _optionalChain([pr, 'optionalAccess', _166 => _166.id]));
4449
4640
  }
4450
4641
  async closePullRequest({ pullRequestNumber }) {
4451
4642
  await this.bb.repositories.declinePullRequest({
@@ -4509,7 +4700,6 @@ var BitbucketPlatformKit = class extends PlatformKit {
4509
4700
  // ../../action/src/platforms/github.ts
4510
4701
  var _octokit2 = require('octokit');
4511
4702
 
4512
-
4513
4703
  var GitHubPlatformKit = class extends PlatformKit {
4514
4704
 
4515
4705
  get octokit() {
@@ -4532,7 +4722,7 @@ var GitHubPlatformKit = class extends PlatformKit {
4532
4722
  repo: this.platformConfig.repositoryName,
4533
4723
  base: this.platformConfig.baseBranchName,
4534
4724
  state: "open"
4535
- }).then(({ data }) => data[0]).then((pr) => _optionalChain([pr, 'optionalAccess', _165 => _165.number]));
4725
+ }).then(({ data }) => data[0]).then((pr) => _optionalChain([pr, 'optionalAccess', _167 => _167.number]));
4536
4726
  }
4537
4727
  async closePullRequest({ pullRequestNumber }) {
4538
4728
  await this.octokit.rest.pulls.update({
@@ -4566,9 +4756,7 @@ var GitHubPlatformKit = class extends PlatformKit {
4566
4756
  if (ghToken && processOwnCommits) {
4567
4757
  console.log("Using provided GH_TOKEN. This will trigger your CI/CD pipeline to run again.");
4568
4758
  const url = `https://${ghToken}@github.com/${repositoryOwner}/${repositoryName}.git`;
4569
- _child_process.execSync.call(void 0, `git remote set-url origin ${url}`, {
4570
- stdio: "inherit"
4571
- });
4759
+ super.gitConfig(ghToken, url);
4572
4760
  }
4573
4761
  }
4574
4762
  get platformConfig() {
@@ -4596,7 +4784,6 @@ var GitHubPlatformKit = class extends PlatformKit {
4596
4784
  // ../../action/src/platforms/gitlab.ts
4597
4785
  var _rest = require('@gitbeaker/rest');
4598
4786
 
4599
-
4600
4787
  var gl = new (0, _rest.Gitlab)({ token: "" });
4601
4788
  var GitlabPlatformKit = class extends PlatformKit {
4602
4789
 
@@ -4648,7 +4835,7 @@ var GitlabPlatformKit = class extends PlatformKit {
4648
4835
  sourceBranch: branch,
4649
4836
  state: "opened"
4650
4837
  });
4651
- return _optionalChain([mergeRequests, 'access', _166 => _166[0], 'optionalAccess', _167 => _167.iid]);
4838
+ return _optionalChain([mergeRequests, 'access', _168 => _168[0], 'optionalAccess', _169 => _169.iid]);
4652
4839
  }
4653
4840
  async closePullRequest({ pullRequestNumber }) {
4654
4841
  await this.gitlab.MergeRequests.edit(this.platformConfig.gitlabProjectId, pullRequestNumber, {
@@ -4671,10 +4858,9 @@ var GitlabPlatformKit = class extends PlatformKit {
4671
4858
  await this.gitlab.MergeRequestNotes.create(this.platformConfig.gitlabProjectId, pullRequestNumber, body);
4672
4859
  }
4673
4860
  gitConfig() {
4674
- const url = `https://oauth2:${this.platformConfig.glToken}@gitlab.com/${this.platformConfig.repositoryOwner}/${this.platformConfig.repositoryName}.git`;
4675
- _child_process.execSync.call(void 0, `git remote set-url origin ${url}`, {
4676
- stdio: "inherit"
4677
- });
4861
+ const glToken = this.platformConfig.glToken;
4862
+ const url = `https://oauth2:${glToken}@gitlab.com/${this.platformConfig.repositoryOwner}/${this.platformConfig.repositoryName}.git`;
4863
+ super.gitConfig(glToken, url);
4678
4864
  }
4679
4865
  buildPullRequestUrl(pullRequestNumber) {
4680
4866
  return `https://gitlab.com/${this.platformConfig.repositoryOwner}/${this.platformConfig.repositoryName}/-/merge_requests/${pullRequestNumber}`;
@@ -4702,7 +4888,7 @@ async function main() {
4702
4888
  const { isPullRequestMode } = platformKit.config;
4703
4889
  ora.info(`Pull request mode: ${isPullRequestMode ? "on" : "off"}`);
4704
4890
  const flow = isPullRequestMode ? new PullRequestFlow(ora, platformKit) : new InBranchFlow(ora, platformKit);
4705
- const canRun = await _optionalChain([flow, 'access', _168 => _168.preRun, 'optionalCall', _169 => _169()]);
4891
+ const canRun = await _optionalChain([flow, 'access', _170 => _170.preRun, 'optionalCall', _171 => _171()]);
4706
4892
  if (canRun === false) {
4707
4893
  return;
4708
4894
  }
@@ -4710,7 +4896,7 @@ async function main() {
4710
4896
  if (!hasChanges) {
4711
4897
  return;
4712
4898
  }
4713
- await _optionalChain([flow, 'access', _170 => _170.postRun, 'optionalCall', _171 => _171()]);
4899
+ await _optionalChain([flow, 'access', _172 => _172.postRun, 'optionalCall', _173 => _173()]);
4714
4900
  }
4715
4901
 
4716
4902
  // src/cli/cmd/ci.ts
@@ -4732,7 +4918,7 @@ var ci_default = new (0, _interactivecommander.Command)().command("ci").descript
4732
4918
  }
4733
4919
  const env = {
4734
4920
  LINGODOTDEV_API_KEY: settings.auth.apiKey,
4735
- LINGODOTDEV_PULL_REQUEST: _optionalChain([options, 'access', _172 => _172.pullRequest, 'optionalAccess', _173 => _173.toString, 'call', _174 => _174()]) || "false",
4921
+ LINGODOTDEV_PULL_REQUEST: _optionalChain([options, 'access', _174 => _174.pullRequest, 'optionalAccess', _175 => _175.toString, 'call', _176 => _176()]) || "false",
4736
4922
  ...options.commitMessage && { LINGODOTDEV_COMMIT_MESSAGE: options.commitMessage },
4737
4923
  ...options.pullRequestTitle && { LINGODOTDEV_PULL_REQUEST_TITLE: options.pullRequestTitle },
4738
4924
  ...options.workingDirectory && { LINGODOTDEV_WORKING_DIRECTORY: options.workingDirectory },
@@ -4745,7 +4931,7 @@ var ci_default = new (0, _interactivecommander.Command)().command("ci").descript
4745
4931
  // package.json
4746
4932
  var package_default = {
4747
4933
  name: "lingo.dev",
4748
- version: "0.80.1",
4934
+ version: "0.81.0",
4749
4935
  description: "Lingo.dev CLI",
4750
4936
  private: false,
4751
4937
  publishConfig: {