lingo.dev 0.84.0 → 0.85.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 +417 -2
- package/build/cli.cjs.map +1 -1
- package/build/cli.mjs +417 -2
- package/build/cli.mjs.map +1 -1
- package/package.json +2 -1
package/build/cli.mjs
CHANGED
|
@@ -5111,10 +5111,424 @@ var ci_default = new Command10().command("ci").description("Run Lingo.dev CI/CD
|
|
|
5111
5111
|
main();
|
|
5112
5112
|
});
|
|
5113
5113
|
|
|
5114
|
+
// src/cli/cmd/status.ts
|
|
5115
|
+
import { bucketTypeSchema as bucketTypeSchema3, localeCodeSchema as localeCodeSchema2, resolveOverriddenLocale as resolveOverriddenLocale6 } from "@lingo.dev/_spec";
|
|
5116
|
+
import { Command as Command11 } from "interactive-commander";
|
|
5117
|
+
import Z11 from "zod";
|
|
5118
|
+
import Ora8 from "ora";
|
|
5119
|
+
import chalk2 from "chalk";
|
|
5120
|
+
import Table from "cli-table3";
|
|
5121
|
+
var status_default = new Command11().command("status").description("Show the status of the localization process").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(
|
|
5122
|
+
"--file [files...]",
|
|
5123
|
+
"File to process. Process only a specific path, may contain asterisk * to match multiple files."
|
|
5124
|
+
).option("--force", "Ignore lockfile and process all keys, useful for estimating full re-translation").option("--verbose", "Show detailed output including key-level word counts").option("--api-key <api-key>", "Explicitly set the API key to use, override the default API key from settings").action(async function(options) {
|
|
5125
|
+
const ora = Ora8();
|
|
5126
|
+
const flags = parseFlags2(options);
|
|
5127
|
+
let authId = null;
|
|
5128
|
+
try {
|
|
5129
|
+
ora.start("Loading configuration...");
|
|
5130
|
+
const i18nConfig = getConfig();
|
|
5131
|
+
const settings = getSettings(flags.apiKey);
|
|
5132
|
+
ora.succeed("Configuration loaded");
|
|
5133
|
+
try {
|
|
5134
|
+
ora.start("Checking authentication status...");
|
|
5135
|
+
const auth = await tryAuthenticate(settings);
|
|
5136
|
+
if (auth) {
|
|
5137
|
+
authId = auth.id;
|
|
5138
|
+
ora.succeed(`Authenticated as ${auth.email}`);
|
|
5139
|
+
} else {
|
|
5140
|
+
ora.info(
|
|
5141
|
+
"Not authenticated. Continuing without authentication. (Run `lingo.dev auth --login` to authenticate)"
|
|
5142
|
+
);
|
|
5143
|
+
}
|
|
5144
|
+
} catch (error) {
|
|
5145
|
+
ora.info("Authentication failed. Continuing without authentication.");
|
|
5146
|
+
}
|
|
5147
|
+
ora.start("Validating localization configuration...");
|
|
5148
|
+
validateParams2(i18nConfig, flags);
|
|
5149
|
+
ora.succeed("Localization configuration is valid");
|
|
5150
|
+
trackEvent(authId || "status", "cmd.status.start", {
|
|
5151
|
+
i18nConfig,
|
|
5152
|
+
flags
|
|
5153
|
+
});
|
|
5154
|
+
let buckets = getBuckets(i18nConfig);
|
|
5155
|
+
if (flags.bucket?.length) {
|
|
5156
|
+
buckets = buckets.filter((bucket) => flags.bucket.includes(bucket.type));
|
|
5157
|
+
}
|
|
5158
|
+
ora.succeed("Buckets retrieved");
|
|
5159
|
+
if (flags.file?.length) {
|
|
5160
|
+
buckets = buckets.map((bucket) => {
|
|
5161
|
+
const paths = bucket.paths.filter((path18) => flags.file.find((file) => path18.pathPattern?.match(file)));
|
|
5162
|
+
return { ...bucket, paths };
|
|
5163
|
+
}).filter((bucket) => bucket.paths.length > 0);
|
|
5164
|
+
if (buckets.length === 0) {
|
|
5165
|
+
ora.fail("No buckets found. All buckets were filtered out by --file option.");
|
|
5166
|
+
process.exit(1);
|
|
5167
|
+
} else {
|
|
5168
|
+
ora.info(`\x1B[36mProcessing only filtered buckets:\x1B[0m`);
|
|
5169
|
+
buckets.map((bucket) => {
|
|
5170
|
+
ora.info(` ${bucket.type}:`);
|
|
5171
|
+
bucket.paths.forEach((path18) => {
|
|
5172
|
+
ora.info(` - ${path18.pathPattern}`);
|
|
5173
|
+
});
|
|
5174
|
+
});
|
|
5175
|
+
}
|
|
5176
|
+
}
|
|
5177
|
+
const targetLocales = flags.locale?.length ? flags.locale : i18nConfig.locale.targets;
|
|
5178
|
+
let totalSourceKeyCount = 0;
|
|
5179
|
+
let uniqueKeysToTranslate = 0;
|
|
5180
|
+
let totalExistingTranslations = 0;
|
|
5181
|
+
const totalWordCount = /* @__PURE__ */ new Map();
|
|
5182
|
+
const languageStats = {};
|
|
5183
|
+
for (const locale of targetLocales) {
|
|
5184
|
+
languageStats[locale] = {
|
|
5185
|
+
complete: 0,
|
|
5186
|
+
missing: 0,
|
|
5187
|
+
updated: 0,
|
|
5188
|
+
words: 0
|
|
5189
|
+
};
|
|
5190
|
+
totalWordCount.set(locale, 0);
|
|
5191
|
+
}
|
|
5192
|
+
const fileStats = {};
|
|
5193
|
+
for (const bucket of buckets) {
|
|
5194
|
+
try {
|
|
5195
|
+
console.log();
|
|
5196
|
+
ora.info(`Analyzing bucket: ${bucket.type}`);
|
|
5197
|
+
for (const bucketPath of bucket.paths) {
|
|
5198
|
+
const bucketOra = Ora8({ indent: 2 }).info(`Analyzing path: ${bucketPath.pathPattern}`);
|
|
5199
|
+
const sourceLocale = resolveOverriddenLocale6(i18nConfig.locale.source, bucketPath.delimiter);
|
|
5200
|
+
const bucketLoader = createBucketLoader(
|
|
5201
|
+
bucket.type,
|
|
5202
|
+
bucketPath.pathPattern,
|
|
5203
|
+
{
|
|
5204
|
+
isCacheRestore: false,
|
|
5205
|
+
defaultLocale: sourceLocale,
|
|
5206
|
+
injectLocale: bucket.injectLocale
|
|
5207
|
+
},
|
|
5208
|
+
bucket.lockedKeys
|
|
5209
|
+
);
|
|
5210
|
+
bucketLoader.setDefaultLocale(sourceLocale);
|
|
5211
|
+
await bucketLoader.init();
|
|
5212
|
+
const filePath = bucketPath.pathPattern;
|
|
5213
|
+
if (!fileStats[filePath]) {
|
|
5214
|
+
fileStats[filePath] = {
|
|
5215
|
+
path: filePath,
|
|
5216
|
+
sourceKeys: 0,
|
|
5217
|
+
wordCount: 0,
|
|
5218
|
+
languageStats: {}
|
|
5219
|
+
};
|
|
5220
|
+
for (const locale of targetLocales) {
|
|
5221
|
+
fileStats[filePath].languageStats[locale] = {
|
|
5222
|
+
complete: 0,
|
|
5223
|
+
missing: 0,
|
|
5224
|
+
updated: 0,
|
|
5225
|
+
words: 0
|
|
5226
|
+
};
|
|
5227
|
+
}
|
|
5228
|
+
}
|
|
5229
|
+
const sourceData = await bucketLoader.pull(sourceLocale);
|
|
5230
|
+
const sourceKeys = Object.keys(sourceData);
|
|
5231
|
+
fileStats[filePath].sourceKeys = sourceKeys.length;
|
|
5232
|
+
totalSourceKeyCount += sourceKeys.length;
|
|
5233
|
+
let sourceWordCount = 0;
|
|
5234
|
+
for (const key of sourceKeys) {
|
|
5235
|
+
const value = sourceData[key];
|
|
5236
|
+
if (typeof value === "string") {
|
|
5237
|
+
const words = value.trim().split(/\s+/).length;
|
|
5238
|
+
sourceWordCount += words;
|
|
5239
|
+
}
|
|
5240
|
+
}
|
|
5241
|
+
fileStats[filePath].wordCount = sourceWordCount;
|
|
5242
|
+
for (const _targetLocale of targetLocales) {
|
|
5243
|
+
const targetLocale = resolveOverriddenLocale6(_targetLocale, bucketPath.delimiter);
|
|
5244
|
+
bucketOra.start(`[${sourceLocale} -> ${targetLocale}] Analyzing translation status...`);
|
|
5245
|
+
let targetData = {};
|
|
5246
|
+
let fileExists = true;
|
|
5247
|
+
try {
|
|
5248
|
+
targetData = await bucketLoader.pull(targetLocale);
|
|
5249
|
+
} catch (error) {
|
|
5250
|
+
fileExists = false;
|
|
5251
|
+
bucketOra.info(
|
|
5252
|
+
`[${sourceLocale} -> ${targetLocale}] Target file not found, assuming all keys need translation.`
|
|
5253
|
+
);
|
|
5254
|
+
}
|
|
5255
|
+
if (!fileExists) {
|
|
5256
|
+
fileStats[filePath].languageStats[targetLocale].missing = sourceKeys.length;
|
|
5257
|
+
fileStats[filePath].languageStats[targetLocale].words = sourceWordCount;
|
|
5258
|
+
languageStats[targetLocale].missing += sourceKeys.length;
|
|
5259
|
+
languageStats[targetLocale].words += sourceWordCount;
|
|
5260
|
+
totalWordCount.set(targetLocale, (totalWordCount.get(targetLocale) || 0) + sourceWordCount);
|
|
5261
|
+
bucketOra.succeed(
|
|
5262
|
+
`[${sourceLocale} -> ${targetLocale}] ${chalk2.red(`0% complete`)} (0/${sourceKeys.length} keys) - file not found`
|
|
5263
|
+
);
|
|
5264
|
+
continue;
|
|
5265
|
+
}
|
|
5266
|
+
const deltaProcessor = createDeltaProcessor(bucketPath.pathPattern);
|
|
5267
|
+
const checksums = await deltaProcessor.loadChecksums();
|
|
5268
|
+
const delta = await deltaProcessor.calculateDelta({
|
|
5269
|
+
sourceData,
|
|
5270
|
+
targetData,
|
|
5271
|
+
checksums
|
|
5272
|
+
});
|
|
5273
|
+
const missingKeys = delta.added;
|
|
5274
|
+
const updatedKeys = delta.updated;
|
|
5275
|
+
const completeKeys = sourceKeys.filter((key) => !missingKeys.includes(key) && !updatedKeys.includes(key));
|
|
5276
|
+
let wordsToTranslate = 0;
|
|
5277
|
+
const keysToProcess = flags.force ? sourceKeys : [...missingKeys, ...updatedKeys];
|
|
5278
|
+
for (const key of keysToProcess) {
|
|
5279
|
+
const value = sourceData[String(key)];
|
|
5280
|
+
if (typeof value === "string") {
|
|
5281
|
+
const words = value.trim().split(/\s+/).length;
|
|
5282
|
+
wordsToTranslate += words;
|
|
5283
|
+
}
|
|
5284
|
+
}
|
|
5285
|
+
fileStats[filePath].languageStats[targetLocale].missing = missingKeys.length;
|
|
5286
|
+
fileStats[filePath].languageStats[targetLocale].updated = updatedKeys.length;
|
|
5287
|
+
fileStats[filePath].languageStats[targetLocale].complete = completeKeys.length;
|
|
5288
|
+
fileStats[filePath].languageStats[targetLocale].words = wordsToTranslate;
|
|
5289
|
+
languageStats[targetLocale].missing += missingKeys.length;
|
|
5290
|
+
languageStats[targetLocale].updated += updatedKeys.length;
|
|
5291
|
+
languageStats[targetLocale].complete += completeKeys.length;
|
|
5292
|
+
languageStats[targetLocale].words += wordsToTranslate;
|
|
5293
|
+
totalWordCount.set(targetLocale, (totalWordCount.get(targetLocale) || 0) + wordsToTranslate);
|
|
5294
|
+
const totalKeysInFile = sourceKeys.length;
|
|
5295
|
+
const completionPercent = (completeKeys.length / totalKeysInFile * 100).toFixed(1);
|
|
5296
|
+
if (missingKeys.length === 0 && updatedKeys.length === 0) {
|
|
5297
|
+
bucketOra.succeed(
|
|
5298
|
+
`[${sourceLocale} -> ${targetLocale}] ${chalk2.green(`100% complete`)} (${completeKeys.length}/${totalKeysInFile} keys)`
|
|
5299
|
+
);
|
|
5300
|
+
} else {
|
|
5301
|
+
const message = `[${sourceLocale} -> ${targetLocale}] ${parseFloat(completionPercent) > 50 ? chalk2.yellow(`${completionPercent}% complete`) : chalk2.red(`${completionPercent}% complete`)} (${completeKeys.length}/${totalKeysInFile} keys)`;
|
|
5302
|
+
bucketOra.succeed(message);
|
|
5303
|
+
if (flags.verbose) {
|
|
5304
|
+
if (missingKeys.length > 0) {
|
|
5305
|
+
console.log(` ${chalk2.red(`Missing:`)} ${missingKeys.length} keys, ~${wordsToTranslate} words`);
|
|
5306
|
+
console.log(
|
|
5307
|
+
` ${chalk2.dim(`Example missing: ${missingKeys.slice(0, 2).join(", ")}${missingKeys.length > 2 ? "..." : ""}`)}`
|
|
5308
|
+
);
|
|
5309
|
+
}
|
|
5310
|
+
if (updatedKeys.length > 0) {
|
|
5311
|
+
console.log(` ${chalk2.yellow(`Updated:`)} ${updatedKeys.length} keys that changed in source`);
|
|
5312
|
+
}
|
|
5313
|
+
}
|
|
5314
|
+
}
|
|
5315
|
+
}
|
|
5316
|
+
}
|
|
5317
|
+
} catch (error) {
|
|
5318
|
+
ora.fail(`Failed to analyze bucket ${bucket.type}: ${error.message}`);
|
|
5319
|
+
}
|
|
5320
|
+
}
|
|
5321
|
+
const totalKeysNeedingTranslation = Object.values(languageStats).reduce((sum, stats) => {
|
|
5322
|
+
return sum + stats.missing + stats.updated;
|
|
5323
|
+
}, 0);
|
|
5324
|
+
const totalCompletedKeys = totalSourceKeyCount - totalKeysNeedingTranslation / targetLocales.length;
|
|
5325
|
+
console.log();
|
|
5326
|
+
ora.succeed(chalk2.green(`Localization status completed.`));
|
|
5327
|
+
console.log(chalk2.bold.cyan(`
|
|
5328
|
+
\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557`));
|
|
5329
|
+
console.log(chalk2.bold.cyan(`\u2551 LOCALIZATION STATUS REPORT \u2551`));
|
|
5330
|
+
console.log(chalk2.bold.cyan(`\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D`));
|
|
5331
|
+
console.log(chalk2.bold(`
|
|
5332
|
+
\u{1F4DD} SOURCE CONTENT:`));
|
|
5333
|
+
console.log(`\u2022 Source language: ${chalk2.green(i18nConfig.locale.source)}`);
|
|
5334
|
+
console.log(`\u2022 Source keys: ${chalk2.yellow(totalSourceKeyCount.toString())} keys across all files`);
|
|
5335
|
+
console.log(chalk2.bold(`
|
|
5336
|
+
\u{1F310} LANGUAGE BY LANGUAGE BREAKDOWN:`));
|
|
5337
|
+
const table = new Table({
|
|
5338
|
+
head: ["Language", "Status", "Complete", "Missing", "Updated", "Words"],
|
|
5339
|
+
style: {
|
|
5340
|
+
head: ["white"],
|
|
5341
|
+
// White color for headers
|
|
5342
|
+
border: []
|
|
5343
|
+
// No color for borders
|
|
5344
|
+
},
|
|
5345
|
+
colWidths: [12, 20, 18, 12, 12, 15]
|
|
5346
|
+
// Explicit column widths, making Status column wider
|
|
5347
|
+
});
|
|
5348
|
+
let totalWordsToTranslate = 0;
|
|
5349
|
+
for (const locale of targetLocales) {
|
|
5350
|
+
const stats = languageStats[locale];
|
|
5351
|
+
const percentComplete = (stats.complete / totalSourceKeyCount * 100).toFixed(1);
|
|
5352
|
+
let statusText;
|
|
5353
|
+
let statusColor;
|
|
5354
|
+
if (stats.missing === totalSourceKeyCount) {
|
|
5355
|
+
statusText = "\u{1F534} Not started";
|
|
5356
|
+
statusColor = chalk2.red;
|
|
5357
|
+
} else if (stats.missing === 0 && stats.updated === 0) {
|
|
5358
|
+
statusText = "\u2705 Complete";
|
|
5359
|
+
statusColor = chalk2.green;
|
|
5360
|
+
} else if (parseFloat(percentComplete) > 80) {
|
|
5361
|
+
statusText = "\u{1F7E1} Almost done";
|
|
5362
|
+
statusColor = chalk2.yellow;
|
|
5363
|
+
} else if (parseFloat(percentComplete) > 0) {
|
|
5364
|
+
statusText = "\u{1F7E0} In progress";
|
|
5365
|
+
statusColor = chalk2.yellow;
|
|
5366
|
+
} else {
|
|
5367
|
+
statusText = "\u{1F534} Not started";
|
|
5368
|
+
statusColor = chalk2.red;
|
|
5369
|
+
}
|
|
5370
|
+
const words = totalWordCount.get(locale) || 0;
|
|
5371
|
+
totalWordsToTranslate += words;
|
|
5372
|
+
table.push([
|
|
5373
|
+
locale,
|
|
5374
|
+
statusColor(statusText),
|
|
5375
|
+
`${stats.complete}/${totalSourceKeyCount} (${percentComplete}%)`,
|
|
5376
|
+
stats.missing > 0 ? chalk2.red(stats.missing.toString()) : "0",
|
|
5377
|
+
stats.updated > 0 ? chalk2.yellow(stats.updated.toString()) : "0",
|
|
5378
|
+
words > 0 ? `~${words.toLocaleString()}` : "0"
|
|
5379
|
+
]);
|
|
5380
|
+
}
|
|
5381
|
+
console.log(table.toString());
|
|
5382
|
+
console.log(chalk2.bold(`
|
|
5383
|
+
\u{1F4CA} USAGE ESTIMATE:`));
|
|
5384
|
+
console.log(
|
|
5385
|
+
`\u2022 TOTAL: ~${chalk2.yellow.bold(totalWordsToTranslate.toLocaleString())} words to translate across all languages`
|
|
5386
|
+
);
|
|
5387
|
+
if (targetLocales.length > 1) {
|
|
5388
|
+
console.log(`\u2022 Per-language breakdown:`);
|
|
5389
|
+
for (const locale of targetLocales) {
|
|
5390
|
+
const words = totalWordCount.get(locale) || 0;
|
|
5391
|
+
const percent = (words / totalWordsToTranslate * 100).toFixed(1);
|
|
5392
|
+
console.log(` - ${locale}: ~${words.toLocaleString()} words (${percent}% of total)`);
|
|
5393
|
+
}
|
|
5394
|
+
}
|
|
5395
|
+
if (flags.confirm && Object.keys(fileStats).length > 0) {
|
|
5396
|
+
console.log(chalk2.bold(`
|
|
5397
|
+
\u{1F4D1} BREAKDOWN BY FILE:`));
|
|
5398
|
+
Object.entries(fileStats).sort((a, b) => b[1].wordCount - a[1].wordCount).forEach(([path18, stats]) => {
|
|
5399
|
+
if (stats.sourceKeys === 0) return;
|
|
5400
|
+
console.log(chalk2.bold(`
|
|
5401
|
+
\u2022 ${path18}:`));
|
|
5402
|
+
console.log(` ${stats.sourceKeys} source keys, ~${stats.wordCount.toLocaleString()} source words`);
|
|
5403
|
+
const fileTable = new Table({
|
|
5404
|
+
head: ["Language", "Status", "Details"],
|
|
5405
|
+
style: {
|
|
5406
|
+
head: ["white"],
|
|
5407
|
+
border: []
|
|
5408
|
+
},
|
|
5409
|
+
colWidths: [12, 20, 50]
|
|
5410
|
+
// Explicit column widths for file detail table
|
|
5411
|
+
});
|
|
5412
|
+
for (const locale of targetLocales) {
|
|
5413
|
+
const langStats = stats.languageStats[locale];
|
|
5414
|
+
const complete = langStats.complete;
|
|
5415
|
+
const total = stats.sourceKeys;
|
|
5416
|
+
const completion = (complete / total * 100).toFixed(1);
|
|
5417
|
+
let status = "\u2705 Complete";
|
|
5418
|
+
let statusColor = chalk2.green;
|
|
5419
|
+
if (langStats.missing === total) {
|
|
5420
|
+
status = "\u274C Not started";
|
|
5421
|
+
statusColor = chalk2.red;
|
|
5422
|
+
} else if (langStats.missing > 0 || langStats.updated > 0) {
|
|
5423
|
+
status = `\u26A0\uFE0F ${completion}% complete`;
|
|
5424
|
+
statusColor = chalk2.yellow;
|
|
5425
|
+
}
|
|
5426
|
+
let details = "";
|
|
5427
|
+
if (langStats.missing > 0 || langStats.updated > 0) {
|
|
5428
|
+
const parts = [];
|
|
5429
|
+
if (langStats.missing > 0) parts.push(`${langStats.missing} missing`);
|
|
5430
|
+
if (langStats.updated > 0) parts.push(`${langStats.updated} changed`);
|
|
5431
|
+
details = `${parts.join(", ")}, ~${langStats.words} words`;
|
|
5432
|
+
} else {
|
|
5433
|
+
details = "All keys translated";
|
|
5434
|
+
}
|
|
5435
|
+
fileTable.push([locale, statusColor(status), details]);
|
|
5436
|
+
}
|
|
5437
|
+
console.log(fileTable.toString());
|
|
5438
|
+
});
|
|
5439
|
+
}
|
|
5440
|
+
const completeLanguages = targetLocales.filter(
|
|
5441
|
+
(locale) => languageStats[locale].missing === 0 && languageStats[locale].updated === 0
|
|
5442
|
+
);
|
|
5443
|
+
const missingLanguages = targetLocales.filter((locale) => languageStats[locale].complete === 0);
|
|
5444
|
+
console.log(chalk2.bold.green(`
|
|
5445
|
+
\u{1F4A1} OPTIMIZATION TIPS:`));
|
|
5446
|
+
if (missingLanguages.length > 0) {
|
|
5447
|
+
console.log(
|
|
5448
|
+
`\u2022 ${chalk2.yellow(missingLanguages.join(", "))} ${missingLanguages.length === 1 ? "has" : "have"} no translations yet`
|
|
5449
|
+
);
|
|
5450
|
+
}
|
|
5451
|
+
if (completeLanguages.length > 0) {
|
|
5452
|
+
console.log(
|
|
5453
|
+
`\u2022 ${chalk2.green(completeLanguages.join(", "))} ${completeLanguages.length === 1 ? "is" : "are"} completely translated`
|
|
5454
|
+
);
|
|
5455
|
+
}
|
|
5456
|
+
if (targetLocales.length > 1) {
|
|
5457
|
+
console.log(`\u2022 Translating one language at a time reduces complexity`);
|
|
5458
|
+
console.log(`\u2022 Try 'lingo.dev@latest i18n --locale ${targetLocales[0]}' to process just one language`);
|
|
5459
|
+
}
|
|
5460
|
+
trackEvent(authId || "status", "cmd.status.success", {
|
|
5461
|
+
i18nConfig,
|
|
5462
|
+
flags,
|
|
5463
|
+
totalSourceKeyCount,
|
|
5464
|
+
languageStats,
|
|
5465
|
+
totalWordsToTranslate,
|
|
5466
|
+
authenticated: !!authId
|
|
5467
|
+
});
|
|
5468
|
+
} catch (error) {
|
|
5469
|
+
ora.fail(error.message);
|
|
5470
|
+
trackEvent(authId || "status", "cmd.status.error", {
|
|
5471
|
+
flags,
|
|
5472
|
+
error: error.message,
|
|
5473
|
+
authenticated: !!authId
|
|
5474
|
+
});
|
|
5475
|
+
process.exit(1);
|
|
5476
|
+
}
|
|
5477
|
+
});
|
|
5478
|
+
function parseFlags2(options) {
|
|
5479
|
+
return Z11.object({
|
|
5480
|
+
locale: Z11.array(localeCodeSchema2).optional(),
|
|
5481
|
+
bucket: Z11.array(bucketTypeSchema3).optional(),
|
|
5482
|
+
force: Z11.boolean().optional(),
|
|
5483
|
+
confirm: Z11.boolean().optional(),
|
|
5484
|
+
verbose: Z11.boolean().optional(),
|
|
5485
|
+
file: Z11.array(Z11.string()).optional(),
|
|
5486
|
+
apiKey: Z11.string().optional()
|
|
5487
|
+
}).parse(options);
|
|
5488
|
+
}
|
|
5489
|
+
async function tryAuthenticate(settings) {
|
|
5490
|
+
if (!settings.auth.apiKey) {
|
|
5491
|
+
return null;
|
|
5492
|
+
}
|
|
5493
|
+
try {
|
|
5494
|
+
const authenticator = createAuthenticator({
|
|
5495
|
+
apiKey: settings.auth.apiKey,
|
|
5496
|
+
apiUrl: settings.auth.apiUrl
|
|
5497
|
+
});
|
|
5498
|
+
const user = await authenticator.whoami();
|
|
5499
|
+
return user;
|
|
5500
|
+
} catch (error) {
|
|
5501
|
+
return null;
|
|
5502
|
+
}
|
|
5503
|
+
}
|
|
5504
|
+
function validateParams2(i18nConfig, flags) {
|
|
5505
|
+
if (!i18nConfig) {
|
|
5506
|
+
throw new CLIError({
|
|
5507
|
+
message: "i18n.json not found. Please run `lingo.dev init` to initialize the project.",
|
|
5508
|
+
docUrl: "i18nNotFound"
|
|
5509
|
+
});
|
|
5510
|
+
} else if (!i18nConfig.buckets || !Object.keys(i18nConfig.buckets).length) {
|
|
5511
|
+
throw new CLIError({
|
|
5512
|
+
message: "No buckets found in i18n.json. Please add at least one bucket containing i18n content.",
|
|
5513
|
+
docUrl: "bucketNotFound"
|
|
5514
|
+
});
|
|
5515
|
+
} else if (flags.locale?.some((locale) => !i18nConfig.locale.targets.includes(locale))) {
|
|
5516
|
+
throw new CLIError({
|
|
5517
|
+
message: `One or more specified locales do not exist in i18n.json locale.targets. Please add them to the list and try again.`,
|
|
5518
|
+
docUrl: "localeTargetNotFound"
|
|
5519
|
+
});
|
|
5520
|
+
} else if (flags.bucket?.some((bucket) => !i18nConfig.buckets[bucket])) {
|
|
5521
|
+
throw new CLIError({
|
|
5522
|
+
message: `One or more specified buckets do not exist in i18n.json. Please add them to the list and try again.`,
|
|
5523
|
+
docUrl: "bucketNotFound"
|
|
5524
|
+
});
|
|
5525
|
+
}
|
|
5526
|
+
}
|
|
5527
|
+
|
|
5114
5528
|
// package.json
|
|
5115
5529
|
var package_default = {
|
|
5116
5530
|
name: "lingo.dev",
|
|
5117
|
-
version: "0.
|
|
5531
|
+
version: "0.85.0",
|
|
5118
5532
|
description: "Lingo.dev CLI",
|
|
5119
5533
|
private: false,
|
|
5120
5534
|
publishConfig: {
|
|
@@ -5184,6 +5598,7 @@ var package_default = {
|
|
|
5184
5598
|
ai: "^4.3.2",
|
|
5185
5599
|
bitbucket: "^2.12.0",
|
|
5186
5600
|
chalk: "^5.4.1",
|
|
5601
|
+
"cli-table3": "^0.6.5",
|
|
5187
5602
|
cors: "^2.8.5",
|
|
5188
5603
|
"csv-parse": "^5.6.0",
|
|
5189
5604
|
"csv-stringify": "^6.5.2",
|
|
@@ -5289,7 +5704,7 @@ ${vice(
|
|
|
5289
5704
|
|
|
5290
5705
|
Star the the repo :) https://github.com/LingoDotDev/lingo.dev
|
|
5291
5706
|
`
|
|
5292
|
-
).version(`v${package_default.version}`, "-v, --version", "Show version").addCommand(init_default).interactive("-y, --no-interactive", "Disable interactive mode").addCommand(i18n_default).addCommand(auth_default).addCommand(show_default).addCommand(lockfile_default).addCommand(cleanup_default).addCommand(mcp_default).addCommand(ci_default).exitOverride((err) => {
|
|
5707
|
+
).version(`v${package_default.version}`, "-v, --version", "Show version").addCommand(init_default).interactive("-y, --no-interactive", "Disable interactive mode").addCommand(i18n_default).addCommand(auth_default).addCommand(show_default).addCommand(lockfile_default).addCommand(cleanup_default).addCommand(mcp_default).addCommand(ci_default).addCommand(status_default).exitOverride((err) => {
|
|
5293
5708
|
if (err.code === "commander.helpDisplayed" || err.code === "commander.version" || err.code === "commander.help") {
|
|
5294
5709
|
process.exit(0);
|
|
5295
5710
|
}
|