lingo.dev 0.92.2 → 0.92.4

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
@@ -3132,46 +3132,52 @@ function parseVueFile(input2) {
3132
3132
  return { before, after, i18n };
3133
3133
  }
3134
3134
 
3135
- // src/cli/loaders/typescript.ts
3135
+ // src/cli/loaders/typescript/index.ts
3136
3136
  import { parse as parse2 } from "@babel/parser";
3137
- import traverse from "@babel/traverse";
3138
- import * as t from "@babel/types";
3139
- import generate from "@babel/generator";
3140
- import { flatten as flatten2, unflatten as unflatten2 } from "flat";
3141
3137
  import _18 from "lodash";
3138
+ import babelTraverseModule from "@babel/traverse";
3139
+ import * as t from "@babel/types";
3140
+ import babelGenerateModule from "@babel/generator";
3141
+
3142
+ // src/cli/loaders/typescript/cjs-interop.ts
3143
+ function resolveCjsExport(mod, name = "module") {
3144
+ if (typeof mod === "function" || typeof mod !== "object" || mod === null) {
3145
+ return mod;
3146
+ }
3147
+ if ("default" in mod && typeof mod.default !== "undefined") {
3148
+ return mod.default;
3149
+ }
3150
+ console.error(
3151
+ `[resolveCjsExport] Unable to determine default export for ${name}.`,
3152
+ "Received value:",
3153
+ mod
3154
+ );
3155
+ throw new Error(`Failed to resolve default export for ${name}.`);
3156
+ }
3157
+
3158
+ // src/cli/loaders/typescript/index.ts
3159
+ var traverse = resolveCjsExport(babelTraverseModule, "@babel/traverse");
3160
+ var generate = resolveCjsExport(babelGenerateModule, "@babel/generator");
3142
3161
  function createTypescriptLoader() {
3143
3162
  return createLoader({
3144
3163
  pull: async (locale, input2) => {
3145
3164
  if (!input2) {
3146
3165
  return {};
3147
3166
  }
3148
- try {
3149
- const ast = parseTypeScript(input2);
3150
- const extractedStrings = extractStringsFromDefaultExport(ast);
3151
- return flattenExtractedStrings(extractedStrings);
3152
- } catch (error) {
3153
- console.error("Error parsing TypeScript file:", error);
3154
- return {};
3155
- }
3167
+ const ast = parseTypeScript(input2);
3168
+ const extractedStrings = extractStringsFromDefaultExport(ast);
3169
+ return extractedStrings;
3156
3170
  },
3157
3171
  push: async (locale, data, originalInput, defaultLocale, pullInput, pullOutput) => {
3158
- if (!data) {
3159
- return "";
3160
- }
3161
- const input2 = originalInput;
3162
- try {
3163
- const ast = parseTypeScript(input2);
3164
- const nestedData = unflattenStringData(data);
3165
- const modified = updateStringsInDefaultExport(ast, nestedData);
3166
- if (!modified) {
3167
- return input2;
3172
+ const ast = parseTypeScript(originalInput || "");
3173
+ const finalData = _18.merge({}, pullOutput, data);
3174
+ updateStringsInDefaultExport(ast, finalData);
3175
+ const { code } = generate(ast, {
3176
+ jsescOption: {
3177
+ minimal: true
3168
3178
  }
3169
- const { code } = generate(ast);
3170
- return code;
3171
- } catch (error) {
3172
- console.error("Error updating TypeScript file:", error);
3173
- return input2;
3174
- }
3179
+ });
3180
+ return code;
3175
3181
  }
3176
3182
  });
3177
3183
  }
@@ -3181,167 +3187,159 @@ function parseTypeScript(input2) {
3181
3187
  plugins: ["typescript"]
3182
3188
  });
3183
3189
  }
3184
- function flattenExtractedStrings(obj) {
3185
- const flattened = flatten2(obj, { delimiter: "/" });
3186
- return Object.entries(flattened).reduce((acc, [key, value]) => {
3187
- if (typeof value === "string") {
3188
- acc[key] = value;
3189
- }
3190
- return acc;
3191
- }, {});
3192
- }
3193
- function unflattenStringData(data) {
3194
- return unflatten2(data, { delimiter: "/" });
3195
- }
3196
3190
  function extractStringsFromDefaultExport(ast) {
3197
- const result = {};
3191
+ let extracted = {};
3198
3192
  traverse(ast, {
3199
3193
  ExportDefaultDeclaration(path17) {
3200
- if (t.isObjectExpression(path17.node.declaration)) {
3201
- extractStringsFromObjectExpression(path17.node.declaration, result, "");
3202
- } else if (t.isIdentifier(path17.node.declaration)) {
3203
- extractStringsFromExportedIdentifier(path17, result, "");
3194
+ const { declaration } = path17.node;
3195
+ const decl = unwrapTSAsExpression(declaration);
3196
+ if (t.isObjectExpression(decl)) {
3197
+ extracted = objectExpressionToObject(decl);
3198
+ } else if (t.isArrayExpression(decl)) {
3199
+ extracted = arrayExpressionToArray(decl);
3200
+ } else if (t.isIdentifier(decl)) {
3201
+ const binding = path17.scope.bindings[decl.name];
3202
+ if (binding && t.isVariableDeclarator(binding.path.node) && binding.path.node.init) {
3203
+ const initRaw = binding.path.node.init;
3204
+ const init = initRaw ? unwrapTSAsExpression(initRaw) : initRaw;
3205
+ if (t.isObjectExpression(init)) {
3206
+ extracted = objectExpressionToObject(init);
3207
+ } else if (t.isArrayExpression(init)) {
3208
+ extracted = arrayExpressionToArray(init);
3209
+ }
3210
+ }
3204
3211
  }
3205
3212
  }
3206
3213
  });
3207
- return result;
3214
+ return extracted;
3208
3215
  }
3209
- function extractStringsFromObjectExpression(objectExpression, result, path17) {
3216
+ function unwrapTSAsExpression(node) {
3217
+ let current = node;
3218
+ while (t.isTSAsExpression(current)) {
3219
+ current = current.expression;
3220
+ }
3221
+ return current;
3222
+ }
3223
+ function objectExpressionToObject(objectExpression) {
3224
+ const obj = {};
3210
3225
  objectExpression.properties.forEach((prop) => {
3211
- if (t.isObjectProperty(prop)) {
3212
- const key = getPropertyKey(prop);
3213
- const currentPath = path17 ? `${path17}/${key}` : key;
3214
- if (t.isStringLiteral(prop.value)) {
3215
- _18.set(result, currentPath, prop.value.value);
3216
- } else if (t.isObjectExpression(prop.value)) {
3217
- extractStringsFromObjectExpression(prop.value, result, currentPath);
3218
- } else if (t.isArrayExpression(prop.value)) {
3219
- extractStringsFromArrayExpression(prop.value, result, currentPath);
3226
+ if (!t.isObjectProperty(prop)) return;
3227
+ const key = getPropertyKey(prop);
3228
+ if (t.isStringLiteral(prop.value)) {
3229
+ obj[key] = prop.value.value;
3230
+ } else if (t.isObjectExpression(prop.value)) {
3231
+ const nested = objectExpressionToObject(prop.value);
3232
+ if (Object.keys(nested).length > 0) {
3233
+ obj[key] = nested;
3234
+ }
3235
+ } else if (t.isArrayExpression(prop.value)) {
3236
+ const arr = arrayExpressionToArray(prop.value);
3237
+ if (arr.length > 0) {
3238
+ obj[key] = arr;
3220
3239
  }
3221
3240
  }
3222
3241
  });
3242
+ return obj;
3223
3243
  }
3224
- function extractStringsFromArrayExpression(arrayExpression, result, path17) {
3225
- arrayExpression.elements.forEach((element, index) => {
3226
- const currentPath = `${path17}/${index}`;
3244
+ function arrayExpressionToArray(arrayExpression) {
3245
+ const arr = [];
3246
+ arrayExpression.elements.forEach((element) => {
3247
+ if (!element) return;
3227
3248
  if (t.isStringLiteral(element)) {
3228
- _18.set(result, currentPath, element.value);
3249
+ arr.push(element.value);
3229
3250
  } else if (t.isObjectExpression(element)) {
3230
- extractStringsFromObjectExpression(element, result, currentPath);
3251
+ const nestedObj = objectExpressionToObject(element);
3252
+ arr.push(nestedObj);
3231
3253
  } else if (t.isArrayExpression(element)) {
3232
- extractStringsFromArrayExpression(element, result, currentPath);
3254
+ arr.push(arrayExpressionToArray(element));
3233
3255
  }
3234
3256
  });
3235
- }
3236
- function extractStringsFromExportedIdentifier(path17, result, basePath) {
3237
- const exportName = path17.node.declaration.name;
3238
- const binding = path17.scope.bindings[exportName];
3239
- if (binding && binding.path.node) {
3240
- const bindingPath = binding.path;
3241
- if (t.isVariableDeclarator(bindingPath.node) && bindingPath.node.init) {
3242
- if (t.isObjectExpression(bindingPath.node.init)) {
3243
- extractStringsFromObjectExpression(bindingPath.node.init, result, basePath);
3244
- } else if (t.isArrayExpression(bindingPath.node.init)) {
3245
- extractStringsFromArrayExpression(bindingPath.node.init, result, basePath);
3246
- }
3247
- }
3248
- }
3257
+ return arr;
3249
3258
  }
3250
3259
  function updateStringsInDefaultExport(ast, data) {
3251
3260
  let modified = false;
3252
3261
  traverse(ast, {
3253
3262
  ExportDefaultDeclaration(path17) {
3254
- if (t.isObjectExpression(path17.node.declaration)) {
3255
- modified = updateStringsInObjectExpression(path17.node.declaration, data, "") || modified;
3256
- } else if (t.isIdentifier(path17.node.declaration)) {
3257
- modified = updateStringsInExportedIdentifier(path17, data, "") || modified;
3263
+ const { declaration } = path17.node;
3264
+ const decl = unwrapTSAsExpression(declaration);
3265
+ if (t.isObjectExpression(decl)) {
3266
+ modified = updateStringsInObjectExpression(decl, data) || modified;
3267
+ } else if (t.isArrayExpression(decl)) {
3268
+ if (Array.isArray(data)) {
3269
+ modified = updateStringsInArrayExpression(decl, data) || modified;
3270
+ }
3271
+ } else if (t.isIdentifier(decl)) {
3272
+ modified = updateStringsInExportedIdentifier(path17, data) || modified;
3258
3273
  }
3259
3274
  }
3260
3275
  });
3261
3276
  return modified;
3262
3277
  }
3263
- function updateStringsInObjectExpression(objectExpression, data, path17) {
3278
+ function updateStringsInObjectExpression(objectExpression, data) {
3264
3279
  let modified = false;
3265
3280
  objectExpression.properties.forEach((prop) => {
3266
- if (t.isObjectProperty(prop)) {
3267
- const key = getPropertyKey(prop);
3268
- const currentPath = path17 ? `${path17}/${key}` : key;
3269
- if (t.isStringLiteral(prop.value)) {
3270
- if (data[currentPath] !== void 0) {
3271
- prop.value.value = data[currentPath];
3272
- modified = true;
3273
- } else if (path17 === "" && data[key] !== void 0) {
3274
- prop.value.value = data[key];
3275
- modified = true;
3276
- }
3277
- } else if (t.isObjectExpression(prop.value)) {
3278
- if (data[key] && typeof data[key] === "object") {
3279
- const subModified = updateStringsInObjectExpression(prop.value, data[key], "");
3280
- modified = subModified || modified;
3281
- } else {
3282
- const subModified = updateStringsInObjectExpression(prop.value, data, currentPath);
3283
- modified = subModified || modified;
3284
- }
3285
- } else if (t.isArrayExpression(prop.value)) {
3286
- if (data[key] && Array.isArray(data[key])) {
3287
- const subModified = updateStringsInArrayExpression(prop.value, data[key], "");
3288
- modified = subModified || modified;
3289
- } else {
3290
- const subModified = updateStringsInArrayExpression(prop.value, data, currentPath);
3291
- modified = subModified || modified;
3292
- }
3281
+ if (!t.isObjectProperty(prop)) return;
3282
+ const key = getPropertyKey(prop);
3283
+ const incomingVal = data?.[key];
3284
+ if (incomingVal === void 0) {
3285
+ return;
3286
+ }
3287
+ if (t.isStringLiteral(prop.value) && typeof incomingVal === "string") {
3288
+ if (prop.value.value !== incomingVal) {
3289
+ prop.value.value = incomingVal;
3290
+ modified = true;
3293
3291
  }
3292
+ } else if (t.isObjectExpression(prop.value) && typeof incomingVal === "object" && !Array.isArray(incomingVal)) {
3293
+ const subModified = updateStringsInObjectExpression(
3294
+ prop.value,
3295
+ incomingVal
3296
+ );
3297
+ modified = subModified || modified;
3298
+ } else if (t.isArrayExpression(prop.value) && Array.isArray(incomingVal)) {
3299
+ const subModified = updateStringsInArrayExpression(
3300
+ prop.value,
3301
+ incomingVal
3302
+ );
3303
+ modified = subModified || modified;
3294
3304
  }
3295
3305
  });
3296
3306
  return modified;
3297
3307
  }
3298
- function updateStringsInArrayExpression(arrayExpression, data, path17) {
3308
+ function updateStringsInArrayExpression(arrayExpression, incoming) {
3299
3309
  let modified = false;
3300
3310
  arrayExpression.elements.forEach((element, index) => {
3301
- const currentPath = `${path17}/${index}`;
3302
- if (t.isStringLiteral(element)) {
3303
- if (Array.isArray(data) && data[index] !== void 0) {
3304
- element.value = data[index];
3305
- modified = true;
3306
- } else if (!Array.isArray(data) && data[currentPath] !== void 0) {
3307
- element.value = data[currentPath];
3311
+ if (!element) return;
3312
+ const incomingVal = incoming?.[index];
3313
+ if (incomingVal === void 0) return;
3314
+ if (t.isStringLiteral(element) && typeof incomingVal === "string") {
3315
+ if (element.value !== incomingVal) {
3316
+ element.value = incomingVal;
3308
3317
  modified = true;
3309
3318
  }
3310
- } else if (t.isObjectExpression(element)) {
3311
- if (Array.isArray(data) && data[index] && typeof data[index] === "object") {
3312
- const subModified = updateStringsInObjectExpression(element, data[index], "");
3313
- modified = subModified || modified;
3314
- } else {
3315
- const subModified = updateStringsInObjectExpression(element, data, currentPath);
3316
- modified = subModified || modified;
3317
- }
3318
- } else if (t.isArrayExpression(element)) {
3319
- if (Array.isArray(data) && data[index] && Array.isArray(data[index])) {
3320
- const subModified = updateStringsInArrayExpression(element, data[index], "");
3321
- modified = subModified || modified;
3322
- } else {
3323
- const subModified = updateStringsInArrayExpression(element, data, currentPath);
3324
- modified = subModified || modified;
3325
- }
3319
+ } else if (t.isObjectExpression(element) && typeof incomingVal === "object" && !Array.isArray(incomingVal)) {
3320
+ const subModified = updateStringsInObjectExpression(element, incomingVal);
3321
+ modified = subModified || modified;
3322
+ } else if (t.isArrayExpression(element) && Array.isArray(incomingVal)) {
3323
+ const subModified = updateStringsInArrayExpression(element, incomingVal);
3324
+ modified = subModified || modified;
3326
3325
  }
3327
3326
  });
3328
3327
  return modified;
3329
3328
  }
3330
- function updateStringsInExportedIdentifier(path17, data, basePath) {
3331
- let modified = false;
3329
+ function updateStringsInExportedIdentifier(path17, data) {
3332
3330
  const exportName = path17.node.declaration.name;
3333
3331
  const binding = path17.scope.bindings[exportName];
3334
- if (binding && binding.path.node) {
3335
- const bindingPath = binding.path;
3336
- if (t.isVariableDeclarator(bindingPath.node) && bindingPath.node.init) {
3337
- if (t.isObjectExpression(bindingPath.node.init)) {
3338
- modified = updateStringsInObjectExpression(bindingPath.node.init, data, basePath) || modified;
3339
- } else if (t.isArrayExpression(bindingPath.node.init)) {
3340
- modified = updateStringsInArrayExpression(bindingPath.node.init, data, basePath) || modified;
3341
- }
3332
+ if (!binding || !binding.path.node) return false;
3333
+ if (t.isVariableDeclarator(binding.path.node) && binding.path.node.init) {
3334
+ const initRaw = binding.path.node.init;
3335
+ const init = initRaw ? unwrapTSAsExpression(initRaw) : initRaw;
3336
+ if (t.isObjectExpression(init)) {
3337
+ return updateStringsInObjectExpression(init, data);
3338
+ } else if (t.isArrayExpression(init)) {
3339
+ return updateStringsInArrayExpression(init, data);
3342
3340
  }
3343
3341
  }
3344
- return modified;
3342
+ return false;
3345
3343
  }
3346
3344
  function getPropertyKey(prop) {
3347
3345
  if (t.isIdentifier(prop.key)) {
@@ -4043,11 +4041,14 @@ function withExponentialBackoff(fn, maxAttempts = 3, baseDelay = 1e3) {
4043
4041
  }
4044
4042
 
4045
4043
  // src/cli/utils/observability.ts
4044
+ import pkg from "node-machine-id";
4045
+ var { machineIdSync } = pkg;
4046
4046
  async function trackEvent(distinctId, event, properties) {
4047
4047
  if (process.env.DO_NOT_TRACK) {
4048
4048
  return;
4049
4049
  }
4050
4050
  try {
4051
+ const actualId = distinctId || `device-${machineIdSync()}`;
4051
4052
  const { PostHog } = await import("posthog-node");
4052
4053
  const safeProperties = properties ? JSON.parse(
4053
4054
  JSON.stringify(properties, (key, value) => {
@@ -4070,7 +4071,7 @@ async function trackEvent(distinctId, event, properties) {
4070
4071
  }
4071
4072
  );
4072
4073
  await posthog.capture({
4073
- distinctId,
4074
+ distinctId: actualId,
4074
4075
  event,
4075
4076
  properties: {
4076
4077
  ...safeProperties,
@@ -4196,7 +4197,7 @@ function createDeltaProcessor(fileKey) {
4196
4197
  }
4197
4198
 
4198
4199
  // src/cli/cmd/i18n.ts
4199
- import { flatten as flatten3, unflatten as unflatten3 } from "flat";
4200
+ import { flatten as flatten2, unflatten as unflatten2 } from "flat";
4200
4201
  var i18n_default = new Command6().command("i18n").description("Run Localization engine").helpOption("-h, --help", "Show help").option(
4201
4202
  "--locale <locale>",
4202
4203
  "Locale to process",
@@ -4256,9 +4257,15 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
4256
4257
  validateParams(i18nConfig, flags);
4257
4258
  ora.succeed("Localization configuration is valid");
4258
4259
  ora.start("Connecting to Lingo.dev Localization Engine...");
4259
- const auth = await validateAuth(settings);
4260
- authId = auth.id;
4261
- ora.succeed(`Authenticated as ${auth.email}`);
4260
+ const isByokMode = i18nConfig?.provider && i18nConfig.provider.id !== "lingo";
4261
+ if (isByokMode) {
4262
+ authId = null;
4263
+ ora.succeed("Using external provider (BYOK mode)");
4264
+ } else {
4265
+ const auth = await validateAuth(settings);
4266
+ authId = auth.id;
4267
+ ora.succeed(`Authenticated as ${auth.email}`);
4268
+ }
4262
4269
  trackEvent(authId, "cmd.i18n.start", {
4263
4270
  i18nConfig,
4264
4271
  flags
@@ -4346,7 +4353,7 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
4346
4353
  );
4347
4354
  const sourceContent = tryReadFile(sourcePath, null);
4348
4355
  const sourceData = JSON.parse(sourceContent || "{}");
4349
- const sourceFlattenedData = flatten3(sourceData, {
4356
+ const sourceFlattenedData = flatten2(sourceData, {
4350
4357
  delimiter: "/",
4351
4358
  transformKey(key) {
4352
4359
  return encodeURIComponent(key);
@@ -4363,7 +4370,7 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
4363
4370
  );
4364
4371
  const targetContent = tryReadFile(targetPath, null);
4365
4372
  const targetData = JSON.parse(targetContent || "{}");
4366
- const targetFlattenedData = flatten3(targetData, {
4373
+ const targetFlattenedData = flatten2(targetData, {
4367
4374
  delimiter: "/",
4368
4375
  transformKey(key) {
4369
4376
  return encodeURIComponent(key);
@@ -4382,7 +4389,7 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
4382
4389
  targetFlattenedData[newKey] = targetFlattenedData[oldKey];
4383
4390
  delete targetFlattenedData[oldKey];
4384
4391
  }
4385
- const updatedTargetData = unflatten3(targetFlattenedData, {
4392
+ const updatedTargetData = unflatten2(targetFlattenedData, {
4386
4393
  delimiter: "/",
4387
4394
  transformKey(key) {
4388
4395
  return decodeURIComponent(key);
@@ -4635,7 +4642,7 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
4635
4642
  console.log();
4636
4643
  if (!hasErrors) {
4637
4644
  ora.succeed("Localization completed.");
4638
- trackEvent(auth.id, "cmd.i18n.success", {
4645
+ trackEvent(authId, "cmd.i18n.success", {
4639
4646
  i18nConfig,
4640
4647
  flags
4641
4648
  });
@@ -6284,7 +6291,7 @@ async function renderHero() {
6284
6291
  // package.json
6285
6292
  var package_default = {
6286
6293
  name: "lingo.dev",
6287
- version: "0.92.2",
6294
+ version: "0.92.4",
6288
6295
  description: "Lingo.dev CLI",
6289
6296
  private: false,
6290
6297
  publishConfig: {