lingo.dev 0.92.6 → 0.92.8

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
@@ -850,46 +850,67 @@ import Ora4 from "ora";
850
850
  import _5 from "lodash";
851
851
  import path9 from "path";
852
852
  import { glob as glob2 } from "glob";
853
- import { resolveOverriddenLocale } from "@lingo.dev/_spec";
853
+ import {
854
+ resolveOverriddenLocale
855
+ } from "@lingo.dev/_spec";
854
856
  function getBuckets(i18nConfig) {
855
- const result = Object.entries(i18nConfig.buckets).map(([bucketType, bucketEntry]) => {
856
- const includeItems = bucketEntry.include.map((item) => resolveBucketItem(item));
857
- const excludeItems = bucketEntry.exclude?.map((item) => resolveBucketItem(item));
858
- const config = {
859
- type: bucketType,
860
- paths: extractPathPatterns(i18nConfig.locale.source, includeItems, excludeItems)
861
- };
862
- if (bucketEntry.injectLocale) {
863
- config.injectLocale = bucketEntry.injectLocale;
864
- }
865
- if (bucketEntry.lockedKeys) {
866
- config.lockedKeys = bucketEntry.lockedKeys;
867
- }
868
- if (bucketEntry.lockedPatterns) {
869
- config.lockedPatterns = bucketEntry.lockedPatterns;
857
+ const result = Object.entries(i18nConfig.buckets).map(
858
+ ([bucketType, bucketEntry]) => {
859
+ const includeItems = bucketEntry.include.map(
860
+ (item) => resolveBucketItem(item)
861
+ );
862
+ const excludeItems = bucketEntry.exclude?.map(
863
+ (item) => resolveBucketItem(item)
864
+ );
865
+ const config = {
866
+ type: bucketType,
867
+ paths: extractPathPatterns(
868
+ i18nConfig.locale.source,
869
+ includeItems,
870
+ excludeItems
871
+ )
872
+ };
873
+ if (bucketEntry.injectLocale) {
874
+ config.injectLocale = bucketEntry.injectLocale;
875
+ }
876
+ if (bucketEntry.lockedKeys) {
877
+ config.lockedKeys = bucketEntry.lockedKeys;
878
+ }
879
+ if (bucketEntry.lockedPatterns) {
880
+ config.lockedPatterns = bucketEntry.lockedPatterns;
881
+ }
882
+ if (bucketEntry.ignoredKeys) {
883
+ config.ignoredKeys = bucketEntry.ignoredKeys;
884
+ }
885
+ return config;
870
886
  }
871
- return config;
872
- });
887
+ );
873
888
  return result;
874
889
  }
875
890
  function extractPathPatterns(sourceLocale, include, exclude) {
876
891
  const includedPatterns = include.flatMap(
877
- (pattern) => expandPlaceholderedGlob(pattern.path, resolveOverriddenLocale(sourceLocale, pattern.delimiter)).map(
878
- (pathPattern) => ({
879
- pathPattern,
880
- delimiter: pattern.delimiter
881
- })
882
- )
892
+ (pattern) => expandPlaceholderedGlob(
893
+ pattern.path,
894
+ resolveOverriddenLocale(sourceLocale, pattern.delimiter)
895
+ ).map((pathPattern) => ({
896
+ pathPattern,
897
+ delimiter: pattern.delimiter
898
+ }))
883
899
  );
884
900
  const excludedPatterns = exclude?.flatMap(
885
- (pattern) => expandPlaceholderedGlob(pattern.path, resolveOverriddenLocale(sourceLocale, pattern.delimiter)).map(
886
- (pathPattern) => ({
887
- pathPattern,
888
- delimiter: pattern.delimiter
889
- })
890
- )
901
+ (pattern) => expandPlaceholderedGlob(
902
+ pattern.path,
903
+ resolveOverriddenLocale(sourceLocale, pattern.delimiter)
904
+ ).map((pathPattern) => ({
905
+ pathPattern,
906
+ delimiter: pattern.delimiter
907
+ }))
908
+ );
909
+ const result = _5.differenceBy(
910
+ includedPatterns,
911
+ excludedPatterns ?? [],
912
+ (item) => item.pathPattern
891
913
  );
892
- const result = _5.differenceBy(includedPatterns, excludedPatterns ?? [], (item) => item.pathPattern);
893
914
  return result;
894
915
  }
895
916
  function expandPlaceholderedGlob(_pathPattern, sourceLocale) {
@@ -908,12 +929,15 @@ function expandPlaceholderedGlob(_pathPattern, sourceLocale) {
908
929
  });
909
930
  }
910
931
  const pathPatternChunks = pathPattern.split(path9.sep);
911
- const localeSegmentIndexes = pathPatternChunks.reduce((indexes, segment, index) => {
912
- if (segment.includes("[locale]")) {
913
- indexes.push(index);
914
- }
915
- return indexes;
916
- }, []);
932
+ const localeSegmentIndexes = pathPatternChunks.reduce(
933
+ (indexes, segment, index) => {
934
+ if (segment.includes("[locale]")) {
935
+ indexes.push(index);
936
+ }
937
+ return indexes;
938
+ },
939
+ []
940
+ );
917
941
  const sourcePathPattern = pathPattern.replaceAll(/\[locale\]/g, sourceLocale);
918
942
  const sourcePaths = glob2.sync(sourcePathPattern, { follow: true, withFileTypes: true }).filter((file) => file.isFile() || file.isSymbolicLink()).map((file) => file.fullpath()).map((fullpath) => path9.relative(process.cwd(), fullpath));
919
943
  const placeholderedPaths = sourcePaths.map((sourcePath) => {
@@ -1001,7 +1025,7 @@ import {
1001
1025
  } from "@lingo.dev/_spec";
1002
1026
  import { Command as Command6 } from "interactive-commander";
1003
1027
  import Z3 from "zod";
1004
- import _24 from "lodash";
1028
+ import _25 from "lodash";
1005
1029
  import * as path14 from "path";
1006
1030
  import Ora5 from "ora";
1007
1031
 
@@ -1226,7 +1250,7 @@ function createTextFileLoader(pathPattern) {
1226
1250
  const trimmedResult = result.trim();
1227
1251
  return trimmedResult;
1228
1252
  },
1229
- async push(locale, data, _27, originalLocale) {
1253
+ async push(locale, data, _28, originalLocale) {
1230
1254
  const draftPath = pathPattern.replaceAll("[locale]", locale);
1231
1255
  const finalPath = path10.resolve(draftPath);
1232
1256
  const dirPath = path10.dirname(finalPath);
@@ -1752,7 +1776,7 @@ function createPropertiesLoader() {
1752
1776
  return result;
1753
1777
  },
1754
1778
  async push(locale, payload) {
1755
- const result = Object.entries(payload).filter(([_27, value]) => value != null).map(([key, value]) => `${key}=${value}`).join("\n");
1779
+ const result = Object.entries(payload).filter(([_28, value]) => value != null).map(([key, value]) => `${key}=${value}`).join("\n");
1756
1780
  return result;
1757
1781
  }
1758
1782
  });
@@ -2019,10 +2043,10 @@ function createUnlocalizableLoader(isCacheRestore = false, returnUnlocalizedKeys
2019
2043
  }
2020
2044
  }
2021
2045
  return false;
2022
- }).map(([key, _27]) => key);
2023
- const result = _10.omitBy(input2, (_27, key) => passthroughKeys.includes(key));
2046
+ }).map(([key, _28]) => key);
2047
+ const result = _10.omitBy(input2, (_28, key) => passthroughKeys.includes(key));
2024
2048
  if (returnUnlocalizedKeys) {
2025
- result.unlocalizable = _10.omitBy(input2, (_27, key) => !passthroughKeys.includes(key));
2049
+ result.unlocalizable = _10.omitBy(input2, (_28, key) => !passthroughKeys.includes(key));
2026
2050
  }
2027
2051
  return result;
2028
2052
  },
@@ -3653,8 +3677,23 @@ function createMdxLockedPatternsLoader(defaultPatterns) {
3653
3677
  });
3654
3678
  }
3655
3679
 
3680
+ // src/cli/loaders/ignored-keys.ts
3681
+ import _23 from "lodash";
3682
+ function createIgnoredKeysLoader(ignoredKeys) {
3683
+ return createLoader({
3684
+ pull: async (locale, data) => {
3685
+ const result = _23.chain(data).omit(ignoredKeys).value();
3686
+ return result;
3687
+ },
3688
+ push: async (locale, data, originalInput, originalLocale, pullInput) => {
3689
+ const result = _23.merge({}, data, _23.pick(pullInput, ignoredKeys));
3690
+ return result;
3691
+ }
3692
+ });
3693
+ }
3694
+
3656
3695
  // src/cli/loaders/index.ts
3657
- function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys, lockedPatterns) {
3696
+ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys, lockedPatterns, ignoredKeys) {
3658
3697
  switch (bucketType) {
3659
3698
  default:
3660
3699
  throw new Error(`Unsupported bucket type: ${bucketType}`);
@@ -3913,6 +3952,8 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys,
3913
3952
  createTypescriptLoader(),
3914
3953
  createFlatLoader(),
3915
3954
  createSyncLoader(),
3955
+ createLockedKeysLoader(lockedKeys || [], options.isCacheRestore),
3956
+ createIgnoredKeysLoader(ignoredKeys || []),
3916
3957
  createUnlocalizableLoader(
3917
3958
  options.isCacheRestore,
3918
3959
  options.returnUnlocalizedKeys
@@ -4070,18 +4111,6 @@ async function trackEvent(distinctId, event, properties) {
4070
4111
  try {
4071
4112
  const actualId = distinctId || `device-${machineIdSync()}`;
4072
4113
  const { PostHog } = await import("posthog-node");
4073
- const safeProperties = properties ? JSON.parse(
4074
- JSON.stringify(properties, (key, value) => {
4075
- if (value instanceof Error) {
4076
- return {
4077
- name: value.name,
4078
- message: value.message,
4079
- stack: value.stack
4080
- };
4081
- }
4082
- return value;
4083
- })
4084
- ) : {};
4085
4114
  const posthog = new PostHog(
4086
4115
  "phc_eR0iSoQufBxNY36k0f0T15UvHJdTfHlh8rJcxsfhfXk",
4087
4116
  {
@@ -4094,7 +4123,7 @@ async function trackEvent(distinctId, event, properties) {
4094
4123
  distinctId: actualId,
4095
4124
  event,
4096
4125
  properties: {
4097
- ...safeProperties,
4126
+ ...properties,
4098
4127
  meta: {
4099
4128
  version: process.env.npm_package_version,
4100
4129
  isCi: process.env.CI === "true"
@@ -4110,7 +4139,7 @@ async function trackEvent(distinctId, event, properties) {
4110
4139
  }
4111
4140
 
4112
4141
  // src/cli/utils/delta.ts
4113
- import _23 from "lodash";
4142
+ import _24 from "lodash";
4114
4143
  import z from "zod";
4115
4144
 
4116
4145
  // src/cli/utils/fs.ts
@@ -4159,9 +4188,9 @@ function createDeltaProcessor(fileKey) {
4159
4188
  return checkIfFileExists(lockfilePath);
4160
4189
  },
4161
4190
  async calculateDelta(params) {
4162
- let added = _23.difference(Object.keys(params.sourceData), Object.keys(params.targetData));
4163
- let removed = _23.difference(Object.keys(params.targetData), Object.keys(params.sourceData));
4164
- const updated = _23.filter(Object.keys(params.sourceData), (key) => {
4191
+ let added = _24.difference(Object.keys(params.sourceData), Object.keys(params.targetData));
4192
+ let removed = _24.difference(Object.keys(params.targetData), Object.keys(params.sourceData));
4193
+ const updated = _24.filter(Object.keys(params.sourceData), (key) => {
4165
4194
  return md5(params.sourceData[key]) !== params.checksums[key] && params.checksums[key];
4166
4195
  });
4167
4196
  const renamed = [];
@@ -4210,7 +4239,7 @@ function createDeltaProcessor(fileKey) {
4210
4239
  await this.saveLock(lockfileData);
4211
4240
  },
4212
4241
  async createChecksums(sourceData) {
4213
- const checksums = _23.mapValues(sourceData, (value) => md5(value));
4242
+ const checksums = _24.mapValues(sourceData, (value) => md5(value));
4214
4243
  return checksums;
4215
4244
  }
4216
4245
  };
@@ -4340,7 +4369,8 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
4340
4369
  injectLocale: bucket.injectLocale
4341
4370
  },
4342
4371
  bucket.lockedKeys,
4343
- bucket.lockedPatterns
4372
+ bucket.lockedPatterns,
4373
+ bucket.ignoredKeys
4344
4374
  );
4345
4375
  bucketLoader.setDefaultLocale(sourceLocale);
4346
4376
  await bucketLoader.init();
@@ -4449,7 +4479,7 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
4449
4479
  const deltaProcessor = createDeltaProcessor(bucketPath.pathPattern);
4450
4480
  const sourceChecksums = await deltaProcessor.createChecksums(sourceData);
4451
4481
  const savedChecksums = await deltaProcessor.loadChecksums();
4452
- const updatedSourceData = _24.pickBy(
4482
+ const updatedSourceData = _25.pickBy(
4453
4483
  sourceData,
4454
4484
  (value, key) => sourceChecksums[key] !== savedChecksums[key]
4455
4485
  );
@@ -4463,15 +4493,15 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
4463
4493
  bucketPath.delimiter
4464
4494
  );
4465
4495
  const { unlocalizable: targetUnlocalizable, ...targetData } = await bucketLoader.pull(targetLocale);
4466
- const missingKeys = _24.difference(
4496
+ const missingKeys = _25.difference(
4467
4497
  Object.keys(sourceData),
4468
4498
  Object.keys(targetData)
4469
4499
  );
4470
- const extraKeys = _24.difference(
4500
+ const extraKeys = _25.difference(
4471
4501
  Object.keys(targetData),
4472
4502
  Object.keys(sourceData)
4473
4503
  );
4474
- const unlocalizableDataDiff = !_24.isEqual(
4504
+ const unlocalizableDataDiff = !_25.isEqual(
4475
4505
  sourceUnlocalizable,
4476
4506
  targetUnlocalizable
4477
4507
  );
@@ -4527,7 +4557,8 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
4527
4557
  injectLocale: bucket.injectLocale
4528
4558
  },
4529
4559
  bucket.lockedKeys,
4530
- bucket.lockedPatterns
4560
+ bucket.lockedPatterns,
4561
+ bucket.ignoredKeys
4531
4562
  );
4532
4563
  bucketLoader.setDefaultLocale(sourceLocale);
4533
4564
  await bucketLoader.init();
@@ -4552,13 +4583,13 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
4552
4583
  targetData,
4553
4584
  checksums: checksums2
4554
4585
  });
4555
- let processableData = _24.chain(sourceData).entries().filter(
4586
+ let processableData = _25.chain(sourceData).entries().filter(
4556
4587
  ([key, value]) => delta.added.includes(key) || delta.updated.includes(key) || !!flags.force
4557
4588
  ).fromPairs().value();
4558
4589
  if (flags.key) {
4559
- processableData = _24.pickBy(
4590
+ processableData = _25.pickBy(
4560
4591
  processableData,
4561
- (_27, key) => key === flags.key
4592
+ (_28, key) => key === flags.key
4562
4593
  );
4563
4594
  }
4564
4595
  if (flags.verbose) {
@@ -4599,7 +4630,7 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
4599
4630
  if (flags.verbose) {
4600
4631
  bucketOra.info(JSON.stringify(processedTargetData, null, 2));
4601
4632
  }
4602
- let finalTargetData = _24.merge(
4633
+ let finalTargetData = _25.merge(
4603
4634
  {},
4604
4635
  sourceData,
4605
4636
  targetData,
@@ -4620,7 +4651,7 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
4620
4651
  `Applying changes to ${bucketPath} (${targetLocale})`
4621
4652
  );
4622
4653
  }
4623
- const finalDiffSize = _24.chain(finalTargetData).omitBy((value, key) => value === targetData[key]).size().value();
4654
+ const finalDiffSize = _25.chain(finalTargetData).omitBy((value, key) => value === targetData[key]).size().value();
4624
4655
  await bucketLoader.push(targetLocale, finalTargetData);
4625
4656
  if (finalDiffSize > 0 || flags.force) {
4626
4657
  bucketOra.succeed(
@@ -4668,6 +4699,9 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
4668
4699
  });
4669
4700
  } else {
4670
4701
  ora.warn("Localization completed with errors.");
4702
+ trackEvent(authId || "unknown", "cmd.i18n.error", {
4703
+ flags
4704
+ });
4671
4705
  }
4672
4706
  } catch (error) {
4673
4707
  ora.fail(error.message);
@@ -4788,7 +4822,7 @@ Reviewing changes for ${chalk.blue(args.pathPattern)} (${chalk.yellow(args.targe
4788
4822
  return args.currentData;
4789
4823
  }
4790
4824
  const customData = { ...args.currentData };
4791
- const changes = _24.reduce(
4825
+ const changes = _25.reduce(
4792
4826
  args.proposedData,
4793
4827
  (result, value, key) => {
4794
4828
  if (args.currentData[key] !== value) {
@@ -4861,7 +4895,7 @@ import path15 from "path";
4861
4895
  import Z4 from "zod";
4862
4896
  import YAML5 from "yaml";
4863
4897
  import { MD5 as MD52 } from "object-hash";
4864
- import _25 from "lodash";
4898
+ import _26 from "lodash";
4865
4899
  function createLockfileHelper() {
4866
4900
  return {
4867
4901
  isLockfileExists: () => {
@@ -4871,23 +4905,23 @@ function createLockfileHelper() {
4871
4905
  registerSourceData: (pathPattern, sourceData) => {
4872
4906
  const lockfile = _loadLockfile();
4873
4907
  const sectionKey = MD52(pathPattern);
4874
- const sectionChecksums = _25.mapValues(sourceData, (value) => MD52(value));
4908
+ const sectionChecksums = _26.mapValues(sourceData, (value) => MD52(value));
4875
4909
  lockfile.checksums[sectionKey] = sectionChecksums;
4876
4910
  _saveLockfile(lockfile);
4877
4911
  },
4878
4912
  registerPartialSourceData: (pathPattern, partialSourceData) => {
4879
4913
  const lockfile = _loadLockfile();
4880
4914
  const sectionKey = MD52(pathPattern);
4881
- const sectionChecksums = _25.mapValues(partialSourceData, (value) => MD52(value));
4882
- lockfile.checksums[sectionKey] = _25.merge({}, lockfile.checksums[sectionKey] ?? {}, sectionChecksums);
4915
+ const sectionChecksums = _26.mapValues(partialSourceData, (value) => MD52(value));
4916
+ lockfile.checksums[sectionKey] = _26.merge({}, lockfile.checksums[sectionKey] ?? {}, sectionChecksums);
4883
4917
  _saveLockfile(lockfile);
4884
4918
  },
4885
4919
  extractUpdatedData: (pathPattern, sourceData) => {
4886
4920
  const lockfile = _loadLockfile();
4887
4921
  const sectionKey = MD52(pathPattern);
4888
- const currentChecksums = _25.mapValues(sourceData, (value) => MD52(value));
4922
+ const currentChecksums = _26.mapValues(sourceData, (value) => MD52(value));
4889
4923
  const savedChecksums = lockfile.checksums[sectionKey] || {};
4890
- const updatedData = _25.pickBy(sourceData, (value, key) => savedChecksums[key] !== currentChecksums[key]);
4924
+ const updatedData = _26.pickBy(sourceData, (value, key) => savedChecksums[key] !== currentChecksums[key]);
4891
4925
  return updatedData;
4892
4926
  }
4893
4927
  };
@@ -4957,7 +4991,7 @@ var flagsSchema = Z5.object({
4957
4991
  // src/cli/cmd/cleanup.ts
4958
4992
  import { resolveOverriddenLocale as resolveOverriddenLocale5 } from "@lingo.dev/_spec";
4959
4993
  import { Command as Command8 } from "interactive-commander";
4960
- import _26 from "lodash";
4994
+ import _27 from "lodash";
4961
4995
  import Ora7 from "ora";
4962
4996
  var cleanup_default = new Command8().command("cleanup").description("Remove keys from target files that do not exist in the source file").helpOption("-h, --help", "Show help").option("--locale <locale>", "Specific locale to cleanup").option("--bucket <bucket>", "Specific bucket to cleanup").option("--dry-run", "Show what would be removed without making changes").option(
4963
4997
  "--verbose",
@@ -4993,7 +5027,7 @@ var cleanup_default = new Command8().command("cleanup").description("Remove keys
4993
5027
  try {
4994
5028
  const targetData = await bucketLoader.pull(targetLocale);
4995
5029
  const targetKeys = Object.keys(targetData);
4996
- const keysToRemove = _26.difference(targetKeys, sourceKeys);
5030
+ const keysToRemove = _27.difference(targetKeys, sourceKeys);
4997
5031
  if (keysToRemove.length === 0) {
4998
5032
  bucketOra.succeed(`[${targetLocale}] No keys to remove`);
4999
5033
  continue;
@@ -5002,7 +5036,7 @@ var cleanup_default = new Command8().command("cleanup").description("Remove keys
5002
5036
  bucketOra.info(`[${targetLocale}] Keys to remove: ${JSON.stringify(keysToRemove, null, 2)}`);
5003
5037
  }
5004
5038
  if (!options.dryRun) {
5005
- const cleanedData = _26.pick(targetData, sourceKeys);
5039
+ const cleanedData = _27.pick(targetData, sourceKeys);
5006
5040
  await bucketLoader.push(targetLocale, cleanedData);
5007
5041
  bucketOra.succeed(`[${targetLocale}] Removed ${keysToRemove.length} keys`);
5008
5042
  } else {
@@ -5057,7 +5091,7 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
5057
5091
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
5058
5092
  import Z6 from "zod";
5059
5093
  import { ReplexicaEngine } from "@lingo.dev/_sdk";
5060
- var mcp_default = new Command9().command("mcp").description("Use Lingo.dev model context provider with your AI agent").helpOption("-h, --help", "Show help").action(async (_27, program) => {
5094
+ var mcp_default = new Command9().command("mcp").description("Use Lingo.dev model context provider with your AI agent").helpOption("-h, --help", "Show help").action(async (_28, program) => {
5061
5095
  const apiKey = program.args[0];
5062
5096
  const settings = getSettings(apiKey);
5063
5097
  if (!settings.auth.apiKey) {
@@ -6311,7 +6345,7 @@ async function renderHero() {
6311
6345
  // package.json
6312
6346
  var package_default = {
6313
6347
  name: "lingo.dev",
6314
- version: "0.92.6",
6348
+ version: "0.92.8",
6315
6349
  description: "Lingo.dev CLI",
6316
6350
  private: false,
6317
6351
  publishConfig: {