lingo.dev 0.81.0 → 0.82.1

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
@@ -862,6 +862,9 @@ function getBuckets(i18nConfig) {
862
862
  if (bucketEntry.injectLocale) {
863
863
  config.injectLocale = bucketEntry.injectLocale;
864
864
  }
865
+ if (bucketEntry.lockedKeys) {
866
+ config.lockedKeys = bucketEntry.lockedKeys;
867
+ }
865
868
  return config;
866
869
  });
867
870
  return result;
@@ -991,7 +994,7 @@ var show_default = new Command5().command("show").description("Prints out the cu
991
994
  import { bucketTypeSchema, localeCodeSchema, resolveOverriddenLocale as resolveOverriddenLocale3 } from "@lingo.dev/_spec";
992
995
  import { Command as Command6 } from "interactive-commander";
993
996
  import Z3 from "zod";
994
- import _20 from "lodash";
997
+ import _21 from "lodash";
995
998
  import * as path15 from "path";
996
999
  import Ora5 from "ora";
997
1000
 
@@ -1199,7 +1202,7 @@ function createTextFileLoader(pathPattern) {
1199
1202
  const trimmedResult = result.trim();
1200
1203
  return trimmedResult;
1201
1204
  },
1202
- async push(locale, data, _23, originalLocale) {
1205
+ async push(locale, data, _24, originalLocale) {
1203
1206
  const draftPath = pathPattern.replaceAll("[locale]", locale);
1204
1207
  const finalPath = path10.resolve(draftPath);
1205
1208
  const dirPath = path10.dirname(finalPath);
@@ -1641,7 +1644,7 @@ function createPropertiesLoader() {
1641
1644
  return result;
1642
1645
  },
1643
1646
  async push(locale, payload) {
1644
- const result = Object.entries(payload).filter(([_23, value]) => value != null).map(([key, value]) => `${key}=${value}`).join("\n");
1647
+ const result = Object.entries(payload).filter(([_24, value]) => value != null).map(([key, value]) => `${key}=${value}`).join("\n");
1645
1648
  return result;
1646
1649
  }
1647
1650
  });
@@ -1890,10 +1893,10 @@ function createUnlocalizableLoader(isCacheRestore = false, returnUnlocalizedKeys
1890
1893
  }
1891
1894
  }
1892
1895
  return false;
1893
- }).map(([key, _23]) => key);
1894
- const result = _10.omitBy(input2, (_23, key) => passthroughKeys.includes(key));
1896
+ }).map(([key, _24]) => key);
1897
+ const result = _10.omitBy(input2, (_24, key) => passthroughKeys.includes(key));
1895
1898
  if (returnUnlocalizedKeys) {
1896
- result.unlocalizable = _10.omitBy(input2, (_23, key) => !passthroughKeys.includes(key));
1899
+ result.unlocalizable = _10.omitBy(input2, (_24, key) => !passthroughKeys.includes(key));
1897
1900
  }
1898
1901
  return result;
1899
1902
  },
@@ -3006,8 +3009,24 @@ function createInjectLocaleLoader(injectLocaleKeys) {
3006
3009
  });
3007
3010
  }
3008
3011
 
3012
+ // src/cli/loaders/locked-keys.ts
3013
+ import _19 from "lodash";
3014
+ function createLockedKeysLoader(lockedKeys, isCacheRestore = false) {
3015
+ return createLoader({
3016
+ pull: async (locale, data) => _19.chain(data).pickBy((value, key) => !lockedKeys.some((lockedKey) => key.startsWith(lockedKey))).value(),
3017
+ push: async (locale, data, originalInput) => {
3018
+ const lockedSubObject = _19.chain(originalInput).pickBy((value, key) => lockedKeys.some((lockedKey) => key.startsWith(lockedKey))).value();
3019
+ if (isCacheRestore) {
3020
+ return _19.merge({}, data, lockedSubObject);
3021
+ } else {
3022
+ return _19.merge({}, originalInput, data, lockedSubObject);
3023
+ }
3024
+ }
3025
+ });
3026
+ }
3027
+
3009
3028
  // src/cli/loaders/index.ts
3010
- function createBucketLoader(bucketType, bucketPathPattern, options) {
3029
+ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys) {
3011
3030
  switch (bucketType) {
3012
3031
  default:
3013
3032
  throw new Error(`Unsupported bucket type: ${bucketType}`);
@@ -3042,6 +3061,7 @@ function createBucketLoader(bucketType, bucketPathPattern, options) {
3042
3061
  createJsonLoader(),
3043
3062
  createInjectLocaleLoader(options.injectLocale),
3044
3063
  createFlatLoader(),
3064
+ createLockedKeysLoader(lockedKeys || [], options.isCacheRestore),
3045
3065
  createSyncLoader(),
3046
3066
  createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys)
3047
3067
  );
@@ -3101,6 +3121,7 @@ function createBucketLoader(bucketType, bucketPathPattern, options) {
3101
3121
  createPrettierLoader({ parser: "yaml", bucketPathPattern }),
3102
3122
  createYamlLoader(),
3103
3123
  createFlatLoader(),
3124
+ createLockedKeysLoader(lockedKeys || [], options.isCacheRestore),
3104
3125
  createSyncLoader(),
3105
3126
  createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys)
3106
3127
  );
@@ -3392,27 +3413,33 @@ async function trackEvent(distinctId, event, properties) {
3392
3413
  if (process.env.DO_NOT_TRACK) {
3393
3414
  return;
3394
3415
  }
3395
- const posthog = new PostHog("phc_eR0iSoQufBxNY36k0f0T15UvHJdTfHlh8rJcxsfhfXk", {
3396
- host: "https://eu.i.posthog.com",
3397
- flushAt: 1,
3398
- flushInterval: 0
3399
- });
3400
- await posthog.capture({
3401
- distinctId,
3402
- event,
3403
- properties: {
3404
- ...properties,
3405
- meta: {
3406
- version: process.env.npm_package_version,
3407
- isCi: process.env.CI === "true"
3416
+ try {
3417
+ const posthog = new PostHog("phc_eR0iSoQufBxNY36k0f0T15UvHJdTfHlh8rJcxsfhfXk", {
3418
+ host: "https://eu.i.posthog.com",
3419
+ flushAt: 1,
3420
+ flushInterval: 0
3421
+ });
3422
+ await posthog.capture({
3423
+ distinctId,
3424
+ event,
3425
+ properties: {
3426
+ ...properties,
3427
+ meta: {
3428
+ version: process.env.npm_package_version,
3429
+ isCi: process.env.CI === "true"
3430
+ }
3408
3431
  }
3432
+ });
3433
+ await posthog.shutdown();
3434
+ } catch (error) {
3435
+ if (process.env.DEBUG) {
3436
+ console.error(error);
3409
3437
  }
3410
- });
3411
- await posthog.shutdown();
3438
+ }
3412
3439
  }
3413
3440
 
3414
3441
  // src/cli/utils/delta.ts
3415
- import _19 from "lodash";
3442
+ import _20 from "lodash";
3416
3443
  import z from "zod";
3417
3444
  import { MD5 } from "object-hash";
3418
3445
 
@@ -3462,9 +3489,9 @@ function createDeltaProcessor(fileKey) {
3462
3489
  return checkIfFileExists(lockfilePath);
3463
3490
  },
3464
3491
  async calculateDelta(params) {
3465
- let added = _19.difference(Object.keys(params.sourceData), Object.keys(params.targetData));
3466
- let removed = _19.difference(Object.keys(params.targetData), Object.keys(params.sourceData));
3467
- const updated = _19.filter(Object.keys(params.sourceData), (key) => {
3492
+ let added = _20.difference(Object.keys(params.sourceData), Object.keys(params.targetData));
3493
+ let removed = _20.difference(Object.keys(params.targetData), Object.keys(params.sourceData));
3494
+ const updated = _20.filter(Object.keys(params.sourceData), (key) => {
3468
3495
  return MD5(params.sourceData[key]) !== params.checksums[key] && params.checksums[key];
3469
3496
  });
3470
3497
  const renamed = [];
@@ -3513,7 +3540,7 @@ function createDeltaProcessor(fileKey) {
3513
3540
  await this.saveLock(lockfileData);
3514
3541
  },
3515
3542
  async createChecksums(sourceData) {
3516
- const checksums = _19.mapValues(sourceData, (value) => MD5(value));
3543
+ const checksums = _20.mapValues(sourceData, (value) => MD5(value));
3517
3544
  return checksums;
3518
3545
  }
3519
3546
  };
@@ -3593,11 +3620,16 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
3593
3620
  for (const bucket of buckets) {
3594
3621
  for (const bucketPath of bucket.paths) {
3595
3622
  const sourceLocale = resolveOverriddenLocale3(i18nConfig.locale.source, bucketPath.delimiter);
3596
- const bucketLoader = createBucketLoader(bucket.type, bucketPath.pathPattern, {
3597
- isCacheRestore: false,
3598
- defaultLocale: sourceLocale,
3599
- injectLocale: bucket.injectLocale
3600
- });
3623
+ const bucketLoader = createBucketLoader(
3624
+ bucket.type,
3625
+ bucketPath.pathPattern,
3626
+ {
3627
+ isCacheRestore: false,
3628
+ defaultLocale: sourceLocale,
3629
+ injectLocale: bucket.injectLocale
3630
+ },
3631
+ bucket.lockedKeys
3632
+ );
3601
3633
  bucketLoader.setDefaultLocale(sourceLocale);
3602
3634
  await bucketLoader.init();
3603
3635
  const sourceData = await bucketLoader.pull(i18nConfig.locale.source);
@@ -3673,11 +3705,16 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
3673
3705
  const bucketOra = Ora5({ indent: 4 });
3674
3706
  bucketOra.info(`Processing path: ${bucketPath.pathPattern}`);
3675
3707
  const sourceLocale = resolveOverriddenLocale3(i18nConfig.locale.source, bucketPath.delimiter);
3676
- const bucketLoader = createBucketLoader(bucket.type, bucketPath.pathPattern, {
3677
- isCacheRestore: true,
3678
- defaultLocale: sourceLocale,
3679
- injectLocale: bucket.injectLocale
3680
- });
3708
+ const bucketLoader = createBucketLoader(
3709
+ bucket.type,
3710
+ bucketPath.pathPattern,
3711
+ {
3712
+ isCacheRestore: true,
3713
+ defaultLocale: sourceLocale,
3714
+ injectLocale: bucket.injectLocale
3715
+ },
3716
+ bucket.lockedKeys
3717
+ );
3681
3718
  bucketLoader.setDefaultLocale(sourceLocale);
3682
3719
  await bucketLoader.init();
3683
3720
  const sourceData = await bucketLoader.pull(sourceLocale);
@@ -3714,12 +3751,17 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
3714
3751
  bucketLoop: for (const bucket of buckets) {
3715
3752
  for (const bucketPath of bucket.paths) {
3716
3753
  const sourceLocale = resolveOverriddenLocale3(i18nConfig.locale.source, bucketPath.delimiter);
3717
- const bucketLoader = createBucketLoader(bucket.type, bucketPath.pathPattern, {
3718
- isCacheRestore: false,
3719
- defaultLocale: sourceLocale,
3720
- returnUnlocalizedKeys: true,
3721
- injectLocale: bucket.injectLocale
3722
- });
3754
+ const bucketLoader = createBucketLoader(
3755
+ bucket.type,
3756
+ bucketPath.pathPattern,
3757
+ {
3758
+ isCacheRestore: false,
3759
+ defaultLocale: sourceLocale,
3760
+ returnUnlocalizedKeys: true,
3761
+ injectLocale: bucket.injectLocale
3762
+ },
3763
+ bucket.lockedKeys
3764
+ );
3723
3765
  bucketLoader.setDefaultLocale(sourceLocale);
3724
3766
  await bucketLoader.init();
3725
3767
  const { unlocalizable: sourceUnlocalizable, ...sourceData } = await bucketLoader.pull(
@@ -3728,7 +3770,7 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
3728
3770
  const deltaProcessor = createDeltaProcessor(bucketPath.pathPattern);
3729
3771
  const sourceChecksums = await deltaProcessor.createChecksums(sourceData);
3730
3772
  const savedChecksums = await deltaProcessor.loadChecksums();
3731
- const updatedSourceData = _20.pickBy(
3773
+ const updatedSourceData = _21.pickBy(
3732
3774
  sourceData,
3733
3775
  (value, key) => sourceChecksums[key] !== savedChecksums[key]
3734
3776
  );
@@ -3739,9 +3781,9 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
3739
3781
  for (const _targetLocale of targetLocales) {
3740
3782
  const targetLocale = resolveOverriddenLocale3(_targetLocale, bucketPath.delimiter);
3741
3783
  const { unlocalizable: targetUnlocalizable, ...targetData } = await bucketLoader.pull(targetLocale);
3742
- const missingKeys = _20.difference(Object.keys(sourceData), Object.keys(targetData));
3743
- const extraKeys = _20.difference(Object.keys(targetData), Object.keys(sourceData));
3744
- const unlocalizableDataDiff = !_20.isEqual(sourceUnlocalizable, targetUnlocalizable);
3784
+ const missingKeys = _21.difference(Object.keys(sourceData), Object.keys(targetData));
3785
+ const extraKeys = _21.difference(Object.keys(targetData), Object.keys(sourceData));
3786
+ const unlocalizableDataDiff = !_21.isEqual(sourceUnlocalizable, targetUnlocalizable);
3745
3787
  if (missingKeys.length > 0) {
3746
3788
  requiresUpdate = "missing";
3747
3789
  break bucketLoop;
@@ -3778,11 +3820,16 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
3778
3820
  for (const bucketPath of bucket.paths) {
3779
3821
  const bucketOra = Ora5({ indent: 2 }).info(`Processing path: ${bucketPath.pathPattern}`);
3780
3822
  const sourceLocale = resolveOverriddenLocale3(i18nConfig.locale.source, bucketPath.delimiter);
3781
- const bucketLoader = createBucketLoader(bucket.type, bucketPath.pathPattern, {
3782
- isCacheRestore: false,
3783
- defaultLocale: sourceLocale,
3784
- injectLocale: bucket.injectLocale
3785
- });
3823
+ const bucketLoader = createBucketLoader(
3824
+ bucket.type,
3825
+ bucketPath.pathPattern,
3826
+ {
3827
+ isCacheRestore: false,
3828
+ defaultLocale: sourceLocale,
3829
+ injectLocale: bucket.injectLocale
3830
+ },
3831
+ bucket.lockedKeys
3832
+ );
3786
3833
  bucketLoader.setDefaultLocale(sourceLocale);
3787
3834
  await bucketLoader.init();
3788
3835
  let sourceData = await bucketLoader.pull(sourceLocale);
@@ -3799,9 +3846,9 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
3799
3846
  targetData,
3800
3847
  checksums: checksums2
3801
3848
  });
3802
- let processableData = _20.chain(sourceData).entries().filter(([key, value]) => delta.added.includes(key) || delta.updated.includes(key) || !!flags.force).fromPairs().value();
3849
+ let processableData = _21.chain(sourceData).entries().filter(([key, value]) => delta.added.includes(key) || delta.updated.includes(key) || !!flags.force).fromPairs().value();
3803
3850
  if (flags.key) {
3804
- processableData = _20.pickBy(processableData, (_23, key) => key === flags.key);
3851
+ processableData = _21.pickBy(processableData, (_24, key) => key === flags.key);
3805
3852
  }
3806
3853
  if (flags.verbose) {
3807
3854
  bucketOra.info(JSON.stringify(processableData, null, 2));
@@ -3838,7 +3885,7 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
3838
3885
  if (flags.verbose) {
3839
3886
  bucketOra.info(JSON.stringify(processedTargetData, null, 2));
3840
3887
  }
3841
- let finalTargetData = _20.merge({}, sourceData, targetData, processedTargetData);
3888
+ let finalTargetData = _21.merge({}, sourceData, targetData, processedTargetData);
3842
3889
  if (flags.interactive) {
3843
3890
  bucketOra.stop();
3844
3891
  const reviewedData = await reviewChanges({
@@ -3852,7 +3899,7 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
3852
3899
  finalTargetData = reviewedData;
3853
3900
  bucketOra.start(`Applying changes to ${bucketPath} (${targetLocale})`);
3854
3901
  }
3855
- const finalDiffSize = _20.chain(finalTargetData).omitBy((value, key) => value === targetData[key]).size().value();
3902
+ const finalDiffSize = _21.chain(finalTargetData).omitBy((value, key) => value === targetData[key]).size().value();
3856
3903
  await bucketLoader.push(targetLocale, finalTargetData);
3857
3904
  if (finalDiffSize > 0 || flags.force) {
3858
3905
  bucketOra.succeed(`[${sourceLocale} -> ${targetLocale}] Localization completed`);
@@ -4012,7 +4059,7 @@ Reviewing changes for ${chalk.blue(args.pathPattern)} (${chalk.yellow(args.targe
4012
4059
  return args.currentData;
4013
4060
  }
4014
4061
  const customData = { ...args.currentData };
4015
- const changes = _20.reduce(
4062
+ const changes = _21.reduce(
4016
4063
  args.proposedData,
4017
4064
  (result, value, key) => {
4018
4065
  if (args.currentData[key] !== value) {
@@ -4071,7 +4118,7 @@ import path16 from "path";
4071
4118
  import Z4 from "zod";
4072
4119
  import YAML4 from "yaml";
4073
4120
  import { MD5 as MD52 } from "object-hash";
4074
- import _21 from "lodash";
4121
+ import _22 from "lodash";
4075
4122
  function createLockfileHelper() {
4076
4123
  return {
4077
4124
  isLockfileExists: () => {
@@ -4081,23 +4128,23 @@ function createLockfileHelper() {
4081
4128
  registerSourceData: (pathPattern, sourceData) => {
4082
4129
  const lockfile = _loadLockfile();
4083
4130
  const sectionKey = MD52(pathPattern);
4084
- const sectionChecksums = _21.mapValues(sourceData, (value) => MD52(value));
4131
+ const sectionChecksums = _22.mapValues(sourceData, (value) => MD52(value));
4085
4132
  lockfile.checksums[sectionKey] = sectionChecksums;
4086
4133
  _saveLockfile(lockfile);
4087
4134
  },
4088
4135
  registerPartialSourceData: (pathPattern, partialSourceData) => {
4089
4136
  const lockfile = _loadLockfile();
4090
4137
  const sectionKey = MD52(pathPattern);
4091
- const sectionChecksums = _21.mapValues(partialSourceData, (value) => MD52(value));
4092
- lockfile.checksums[sectionKey] = _21.merge({}, lockfile.checksums[sectionKey] ?? {}, sectionChecksums);
4138
+ const sectionChecksums = _22.mapValues(partialSourceData, (value) => MD52(value));
4139
+ lockfile.checksums[sectionKey] = _22.merge({}, lockfile.checksums[sectionKey] ?? {}, sectionChecksums);
4093
4140
  _saveLockfile(lockfile);
4094
4141
  },
4095
4142
  extractUpdatedData: (pathPattern, sourceData) => {
4096
4143
  const lockfile = _loadLockfile();
4097
4144
  const sectionKey = MD52(pathPattern);
4098
- const currentChecksums = _21.mapValues(sourceData, (value) => MD52(value));
4145
+ const currentChecksums = _22.mapValues(sourceData, (value) => MD52(value));
4099
4146
  const savedChecksums = lockfile.checksums[sectionKey] || {};
4100
- const updatedData = _21.pickBy(sourceData, (value, key) => savedChecksums[key] !== currentChecksums[key]);
4147
+ const updatedData = _22.pickBy(sourceData, (value, key) => savedChecksums[key] !== currentChecksums[key]);
4101
4148
  return updatedData;
4102
4149
  }
4103
4150
  };
@@ -4167,7 +4214,7 @@ var flagsSchema = Z5.object({
4167
4214
  // src/cli/cmd/cleanup.ts
4168
4215
  import { resolveOverriddenLocale as resolveOverriddenLocale5 } from "@lingo.dev/_spec";
4169
4216
  import { Command as Command8 } from "interactive-commander";
4170
- import _22 from "lodash";
4217
+ import _23 from "lodash";
4171
4218
  import Ora7 from "ora";
4172
4219
  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(
4173
4220
  "--verbose",
@@ -4203,7 +4250,7 @@ var cleanup_default = new Command8().command("cleanup").description("Remove keys
4203
4250
  try {
4204
4251
  const targetData = await bucketLoader.pull(targetLocale);
4205
4252
  const targetKeys = Object.keys(targetData);
4206
- const keysToRemove = _22.difference(targetKeys, sourceKeys);
4253
+ const keysToRemove = _23.difference(targetKeys, sourceKeys);
4207
4254
  if (keysToRemove.length === 0) {
4208
4255
  bucketOra.succeed(`[${targetLocale}] No keys to remove`);
4209
4256
  continue;
@@ -4212,7 +4259,7 @@ var cleanup_default = new Command8().command("cleanup").description("Remove keys
4212
4259
  bucketOra.info(`[${targetLocale}] Keys to remove: ${JSON.stringify(keysToRemove, null, 2)}`);
4213
4260
  }
4214
4261
  if (!options.dryRun) {
4215
- const cleanedData = _22.pick(targetData, sourceKeys);
4262
+ const cleanedData = _23.pick(targetData, sourceKeys);
4216
4263
  await bucketLoader.push(targetLocale, cleanedData);
4217
4264
  bucketOra.succeed(`[${targetLocale}] Removed ${keysToRemove.length} keys`);
4218
4265
  } else {
@@ -4267,7 +4314,7 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
4267
4314
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
4268
4315
  import Z6 from "zod";
4269
4316
  import { ReplexicaEngine } from "@lingo.dev/_sdk";
4270
- 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 (_23, program) => {
4317
+ 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 (_24, program) => {
4271
4318
  const apiKey = program.args[0];
4272
4319
  const settings = getSettings(apiKey);
4273
4320
  if (!settings.auth.apiKey) {
@@ -4931,7 +4978,7 @@ var ci_default = new Command10().command("ci").description("Run Lingo.dev CI/CD
4931
4978
  // package.json
4932
4979
  var package_default = {
4933
4980
  name: "lingo.dev",
4934
- version: "0.81.0",
4981
+ version: "0.82.1",
4935
4982
  description: "Lingo.dev CLI",
4936
4983
  private: false,
4937
4984
  publishConfig: {