lingo.dev 0.112.1 → 0.113.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 +304 -155
- package/build/cli.cjs.map +1 -1
- package/build/cli.mjs +211 -62
- package/build/cli.mjs.map +1 -1
- package/package.json +3 -3
package/build/cli.mjs
CHANGED
|
@@ -2016,7 +2016,7 @@ function createTextFileLoader(pathPattern) {
|
|
|
2016
2016
|
const trimmedResult = result.trim();
|
|
2017
2017
|
return trimmedResult;
|
|
2018
2018
|
},
|
|
2019
|
-
async push(locale, data,
|
|
2019
|
+
async push(locale, data, _36, originalLocale) {
|
|
2020
2020
|
const draftPath = pathPattern.replaceAll("[locale]", locale);
|
|
2021
2021
|
const finalPath = path10.resolve(draftPath);
|
|
2022
2022
|
const dirPath = path10.dirname(finalPath);
|
|
@@ -2722,7 +2722,7 @@ function createPropertiesLoader() {
|
|
|
2722
2722
|
return result;
|
|
2723
2723
|
},
|
|
2724
2724
|
async push(locale, payload) {
|
|
2725
|
-
const result = Object.entries(payload).filter(([
|
|
2725
|
+
const result = Object.entries(payload).filter(([_36, value]) => value != null).map(([key, value]) => `${key}=${value}`).join("\n");
|
|
2726
2726
|
return result;
|
|
2727
2727
|
}
|
|
2728
2728
|
});
|
|
@@ -2951,12 +2951,12 @@ function createUnlocalizableLoader(returnUnlocalizedKeys = false) {
|
|
|
2951
2951
|
const unlocalizableKeys = _getUnlocalizableKeys(input2);
|
|
2952
2952
|
const result = _10.omitBy(
|
|
2953
2953
|
input2,
|
|
2954
|
-
(
|
|
2954
|
+
(_36, key) => unlocalizableKeys.includes(key)
|
|
2955
2955
|
);
|
|
2956
2956
|
if (returnUnlocalizedKeys) {
|
|
2957
2957
|
result.unlocalizable = _10.omitBy(
|
|
2958
2958
|
input2,
|
|
2959
|
-
(
|
|
2959
|
+
(_36, key) => !unlocalizableKeys.includes(key)
|
|
2960
2960
|
);
|
|
2961
2961
|
}
|
|
2962
2962
|
return result;
|
|
@@ -2966,7 +2966,7 @@ function createUnlocalizableLoader(returnUnlocalizedKeys = false) {
|
|
|
2966
2966
|
const result = _10.merge(
|
|
2967
2967
|
{},
|
|
2968
2968
|
data,
|
|
2969
|
-
_10.omitBy(originalInput, (
|
|
2969
|
+
_10.omitBy(originalInput, (_36, key) => !unlocalizableKeys.includes(key))
|
|
2970
2970
|
);
|
|
2971
2971
|
return result;
|
|
2972
2972
|
}
|
|
@@ -2997,7 +2997,7 @@ function _getUnlocalizableKeys(input2) {
|
|
|
2997
2997
|
}
|
|
2998
2998
|
}
|
|
2999
2999
|
return false;
|
|
3000
|
-
}).map(([key,
|
|
3000
|
+
}).map(([key, _36]) => key);
|
|
3001
3001
|
}
|
|
3002
3002
|
|
|
3003
3003
|
// src/cli/loaders/formatters/prettier.ts
|
|
@@ -5729,7 +5729,7 @@ var AST = class _AST {
|
|
|
5729
5729
|
if (!this.type) {
|
|
5730
5730
|
const noEmpty = this.isStart() && this.isEnd();
|
|
5731
5731
|
const src = this.#parts.map((p) => {
|
|
5732
|
-
const [re,
|
|
5732
|
+
const [re, _36, hasMagic, uflag] = typeof p === "string" ? _AST.#parseGlob(p, this.#hasMagic, noEmpty) : p.toRegExpSource(allowDot);
|
|
5733
5733
|
this.#hasMagic = this.#hasMagic || hasMagic;
|
|
5734
5734
|
this.#uflag = this.#uflag || uflag;
|
|
5735
5735
|
return re;
|
|
@@ -5802,7 +5802,7 @@ var AST = class _AST {
|
|
|
5802
5802
|
if (typeof p === "string") {
|
|
5803
5803
|
throw new Error("string type in extglob ast??");
|
|
5804
5804
|
}
|
|
5805
|
-
const [re,
|
|
5805
|
+
const [re, _36, _hasMagic, uflag] = p.toRegExpSource(dot);
|
|
5806
5806
|
this.#uflag = this.#uflag || uflag;
|
|
5807
5807
|
return re;
|
|
5808
5808
|
}).filter((p) => !(this.isStart() && this.isEnd()) || !!p).join("|");
|
|
@@ -6047,7 +6047,7 @@ var Minimatch = class {
|
|
|
6047
6047
|
}
|
|
6048
6048
|
return false;
|
|
6049
6049
|
}
|
|
6050
|
-
debug(...
|
|
6050
|
+
debug(..._36) {
|
|
6051
6051
|
}
|
|
6052
6052
|
make() {
|
|
6053
6053
|
const pattern = this.pattern;
|
|
@@ -6069,7 +6069,7 @@ var Minimatch = class {
|
|
|
6069
6069
|
const rawGlobParts = this.globSet.map((s) => this.slashSplit(s));
|
|
6070
6070
|
this.globParts = this.preprocess(rawGlobParts);
|
|
6071
6071
|
this.debug(this.pattern, this.globParts);
|
|
6072
|
-
let set = this.globParts.map((s,
|
|
6072
|
+
let set = this.globParts.map((s, _36, __) => {
|
|
6073
6073
|
if (this.isWindows && this.windowsNoMagicRoot) {
|
|
6074
6074
|
const isUNC = s[0] === "" && s[1] === "" && (s[2] === "?" || !globMagic.test(s[2])) && !globMagic.test(s[3]);
|
|
6075
6075
|
const isDrive = /^[a-z]:/i.test(s[0]);
|
|
@@ -7108,7 +7108,7 @@ function createTxtLoader() {
|
|
|
7108
7108
|
const sortedEntries = Object.entries(payload).sort(
|
|
7109
7109
|
([a], [b]) => parseInt(a) - parseInt(b)
|
|
7110
7110
|
);
|
|
7111
|
-
return sortedEntries.map(([
|
|
7111
|
+
return sortedEntries.map(([_36, value]) => value).join("\n");
|
|
7112
7112
|
}
|
|
7113
7113
|
});
|
|
7114
7114
|
}
|
|
@@ -8500,7 +8500,7 @@ var i18n_default = new Command14().command("i18n").description(
|
|
|
8500
8500
|
if (flags.key) {
|
|
8501
8501
|
processableData = _31.pickBy(
|
|
8502
8502
|
processableData,
|
|
8503
|
-
(
|
|
8503
|
+
(_36, key) => key === flags.key
|
|
8504
8504
|
);
|
|
8505
8505
|
}
|
|
8506
8506
|
if (flags.verbose) {
|
|
@@ -9129,7 +9129,7 @@ import Z6 from "zod";
|
|
|
9129
9129
|
import { ReplexicaEngine } from "@lingo.dev/_sdk";
|
|
9130
9130
|
var mcp_default = new Command17().command("mcp").description(
|
|
9131
9131
|
"Start a Model Context Protocol (MCP) server for AI assistant integration"
|
|
9132
|
-
).helpOption("-h, --help", "Show help").action(async (
|
|
9132
|
+
).helpOption("-h, --help", "Show help").action(async (_36, program) => {
|
|
9133
9133
|
const apiKey = program.args[0];
|
|
9134
9134
|
const settings = getSettings(apiKey);
|
|
9135
9135
|
if (!settings.auth.apiKey) {
|
|
@@ -9756,7 +9756,7 @@ async function execute(input2) {
|
|
|
9756
9756
|
const workerTasks = [];
|
|
9757
9757
|
for (let i = 0; i < workersCount; i++) {
|
|
9758
9758
|
const assignedTasks = ctx.tasks.filter(
|
|
9759
|
-
(
|
|
9759
|
+
(_36, idx) => idx % workersCount === i
|
|
9760
9760
|
);
|
|
9761
9761
|
workerTasks.push(
|
|
9762
9762
|
createWorkerTask({
|
|
@@ -10127,6 +10127,150 @@ var flagsSchema2 = z2.object({
|
|
|
10127
10127
|
sound: z2.boolean().optional()
|
|
10128
10128
|
});
|
|
10129
10129
|
|
|
10130
|
+
// src/cli/cmd/run/frozen.ts
|
|
10131
|
+
import chalk14 from "chalk";
|
|
10132
|
+
import { Listr as Listr4 } from "listr2";
|
|
10133
|
+
import _35 from "lodash";
|
|
10134
|
+
import { resolveOverriddenLocale as resolveOverriddenLocale8 } from "@lingo.dev/_spec";
|
|
10135
|
+
async function frozen(input2) {
|
|
10136
|
+
console.log(chalk14.hex(colors.orange)("[Frozen]"));
|
|
10137
|
+
let buckets = getBuckets(input2.config);
|
|
10138
|
+
if (input2.flags.bucket?.length) {
|
|
10139
|
+
buckets = buckets.filter((b) => input2.flags.bucket.includes(b.type));
|
|
10140
|
+
}
|
|
10141
|
+
if (input2.flags.file?.length) {
|
|
10142
|
+
buckets = buckets.map((bucket) => {
|
|
10143
|
+
const paths = bucket.paths.filter(
|
|
10144
|
+
(p) => input2.flags.file.some(
|
|
10145
|
+
(f) => p.pathPattern.includes(f) || minimatch(p.pathPattern, f)
|
|
10146
|
+
)
|
|
10147
|
+
);
|
|
10148
|
+
return { ...bucket, paths };
|
|
10149
|
+
}).filter((bucket) => bucket.paths.length > 0);
|
|
10150
|
+
}
|
|
10151
|
+
const _sourceLocale = input2.flags.sourceLocale || input2.config.locale.source;
|
|
10152
|
+
const _targetLocales = input2.flags.targetLocale || input2.config.locale.targets;
|
|
10153
|
+
return new Listr4(
|
|
10154
|
+
[
|
|
10155
|
+
{
|
|
10156
|
+
title: "Setting up localization cache",
|
|
10157
|
+
task: async (_ctx, task) => {
|
|
10158
|
+
const checkLockfileProcessor = createDeltaProcessor("");
|
|
10159
|
+
const lockfileExists = await checkLockfileProcessor.checkIfLockExists();
|
|
10160
|
+
if (!lockfileExists) {
|
|
10161
|
+
for (const bucket of buckets) {
|
|
10162
|
+
for (const bucketPath of bucket.paths) {
|
|
10163
|
+
const resolvedSourceLocale = resolveOverriddenLocale8(
|
|
10164
|
+
_sourceLocale,
|
|
10165
|
+
bucketPath.delimiter
|
|
10166
|
+
);
|
|
10167
|
+
const loader = createBucketLoader(
|
|
10168
|
+
bucket.type,
|
|
10169
|
+
bucketPath.pathPattern,
|
|
10170
|
+
{
|
|
10171
|
+
defaultLocale: resolvedSourceLocale,
|
|
10172
|
+
injectLocale: bucket.injectLocale,
|
|
10173
|
+
formatter: input2.config.formatter
|
|
10174
|
+
},
|
|
10175
|
+
bucket.lockedKeys,
|
|
10176
|
+
bucket.lockedPatterns,
|
|
10177
|
+
bucket.ignoredKeys
|
|
10178
|
+
);
|
|
10179
|
+
loader.setDefaultLocale(resolvedSourceLocale);
|
|
10180
|
+
await loader.init();
|
|
10181
|
+
const sourceData = await loader.pull(_sourceLocale);
|
|
10182
|
+
const delta = createDeltaProcessor(bucketPath.pathPattern);
|
|
10183
|
+
const checksums = await delta.createChecksums(sourceData);
|
|
10184
|
+
await delta.saveChecksums(checksums);
|
|
10185
|
+
}
|
|
10186
|
+
}
|
|
10187
|
+
task.title = "Localization cache initialized";
|
|
10188
|
+
} else {
|
|
10189
|
+
task.title = "Localization cache loaded";
|
|
10190
|
+
}
|
|
10191
|
+
}
|
|
10192
|
+
},
|
|
10193
|
+
{
|
|
10194
|
+
title: "Validating frozen state",
|
|
10195
|
+
enabled: () => !!input2.flags.frozen,
|
|
10196
|
+
task: async (_ctx, task) => {
|
|
10197
|
+
for (const bucket of buckets) {
|
|
10198
|
+
for (const bucketPath of bucket.paths) {
|
|
10199
|
+
const resolvedSourceLocale = resolveOverriddenLocale8(
|
|
10200
|
+
_sourceLocale,
|
|
10201
|
+
bucketPath.delimiter
|
|
10202
|
+
);
|
|
10203
|
+
const loader = createBucketLoader(
|
|
10204
|
+
bucket.type,
|
|
10205
|
+
bucketPath.pathPattern,
|
|
10206
|
+
{
|
|
10207
|
+
defaultLocale: resolvedSourceLocale,
|
|
10208
|
+
returnUnlocalizedKeys: true,
|
|
10209
|
+
injectLocale: bucket.injectLocale
|
|
10210
|
+
},
|
|
10211
|
+
bucket.lockedKeys
|
|
10212
|
+
);
|
|
10213
|
+
loader.setDefaultLocale(resolvedSourceLocale);
|
|
10214
|
+
await loader.init();
|
|
10215
|
+
const { unlocalizable: srcUnlocalizable, ...src } = await loader.pull(_sourceLocale);
|
|
10216
|
+
const delta = createDeltaProcessor(bucketPath.pathPattern);
|
|
10217
|
+
const sourceChecksums = await delta.createChecksums(src);
|
|
10218
|
+
const savedChecksums = await delta.loadChecksums();
|
|
10219
|
+
const updatedSourceData = _35.pickBy(
|
|
10220
|
+
src,
|
|
10221
|
+
(value, key) => sourceChecksums[key] !== savedChecksums[key]
|
|
10222
|
+
);
|
|
10223
|
+
if (Object.keys(updatedSourceData).length > 0) {
|
|
10224
|
+
throw new Error(
|
|
10225
|
+
`Localization data has changed; please update i18n.lock or run without --frozen. Details: Source file has been updated.`
|
|
10226
|
+
);
|
|
10227
|
+
}
|
|
10228
|
+
for (const _tgt of _targetLocales) {
|
|
10229
|
+
const resolvedTargetLocale = resolveOverriddenLocale8(
|
|
10230
|
+
_tgt,
|
|
10231
|
+
bucketPath.delimiter
|
|
10232
|
+
);
|
|
10233
|
+
const { unlocalizable: tgtUnlocalizable, ...tgt } = await loader.pull(resolvedTargetLocale);
|
|
10234
|
+
const missingKeys = _35.difference(
|
|
10235
|
+
Object.keys(src),
|
|
10236
|
+
Object.keys(tgt)
|
|
10237
|
+
);
|
|
10238
|
+
if (missingKeys.length > 0) {
|
|
10239
|
+
throw new Error(
|
|
10240
|
+
`Localization data has changed; please update i18n.lock or run without --frozen. Details: Target file is missing translations.`
|
|
10241
|
+
);
|
|
10242
|
+
}
|
|
10243
|
+
const extraKeys = _35.difference(
|
|
10244
|
+
Object.keys(tgt),
|
|
10245
|
+
Object.keys(src)
|
|
10246
|
+
);
|
|
10247
|
+
if (extraKeys.length > 0) {
|
|
10248
|
+
throw new Error(
|
|
10249
|
+
`Localization data has changed; please update i18n.lock or run without --frozen. Details: Target file has extra translations not present in the source file.`
|
|
10250
|
+
);
|
|
10251
|
+
}
|
|
10252
|
+
const unlocalizableDataDiff = !_35.isEqual(
|
|
10253
|
+
srcUnlocalizable,
|
|
10254
|
+
tgtUnlocalizable
|
|
10255
|
+
);
|
|
10256
|
+
if (unlocalizableDataDiff) {
|
|
10257
|
+
throw new Error(
|
|
10258
|
+
`Localization data has changed; please update i18n.lock or run without --frozen. Details: Unlocalizable data (such as booleans, dates, URLs, etc.) do not match.`
|
|
10259
|
+
);
|
|
10260
|
+
}
|
|
10261
|
+
}
|
|
10262
|
+
}
|
|
10263
|
+
}
|
|
10264
|
+
task.title = "No lockfile updates required";
|
|
10265
|
+
}
|
|
10266
|
+
}
|
|
10267
|
+
],
|
|
10268
|
+
{
|
|
10269
|
+
rendererOptions: commonTaskRendererOptions
|
|
10270
|
+
}
|
|
10271
|
+
).run(input2);
|
|
10272
|
+
}
|
|
10273
|
+
|
|
10130
10274
|
// src/cli/cmd/run/_utils.ts
|
|
10131
10275
|
async function determineAuthId(ctx) {
|
|
10132
10276
|
const isByokMode = !!ctx.config?.provider;
|
|
@@ -10191,6 +10335,9 @@ var run_default = new Command18().command("run").description("Run localization p
|
|
|
10191
10335
|
).option(
|
|
10192
10336
|
"--force",
|
|
10193
10337
|
"Force re-translation of all keys, bypassing change detection. Useful when you want to regenerate translations with updated AI models or translation settings"
|
|
10338
|
+
).option(
|
|
10339
|
+
"--frozen",
|
|
10340
|
+
"Validate translations are up-to-date without making changes - fails if source files, target files, or lockfile are out of sync. Ideal for CI/CD to ensure translation consistency before deployment"
|
|
10194
10341
|
).option(
|
|
10195
10342
|
"--api-key <api-key>",
|
|
10196
10343
|
"Override API key from settings or environment variables"
|
|
@@ -10233,6 +10380,8 @@ var run_default = new Command18().command("run").description("Run localization p
|
|
|
10233
10380
|
await renderSpacer();
|
|
10234
10381
|
await plan(ctx);
|
|
10235
10382
|
await renderSpacer();
|
|
10383
|
+
await frozen(ctx);
|
|
10384
|
+
await renderSpacer();
|
|
10236
10385
|
await execute(ctx);
|
|
10237
10386
|
await renderSpacer();
|
|
10238
10387
|
await renderSummary(ctx.results);
|
|
@@ -10998,12 +11147,12 @@ function parseBooleanArg(val) {
|
|
|
10998
11147
|
import {
|
|
10999
11148
|
bucketTypeSchema as bucketTypeSchema4,
|
|
11000
11149
|
localeCodeSchema as localeCodeSchema3,
|
|
11001
|
-
resolveOverriddenLocale as
|
|
11150
|
+
resolveOverriddenLocale as resolveOverriddenLocale9
|
|
11002
11151
|
} from "@lingo.dev/_spec";
|
|
11003
11152
|
import { Command as Command20 } from "interactive-commander";
|
|
11004
11153
|
import Z11 from "zod";
|
|
11005
11154
|
import Ora12 from "ora";
|
|
11006
|
-
import
|
|
11155
|
+
import chalk15 from "chalk";
|
|
11007
11156
|
import Table from "cli-table3";
|
|
11008
11157
|
|
|
11009
11158
|
// src/cli/utils/exit-gracefully.ts
|
|
@@ -11145,7 +11294,7 @@ var status_default = new Command20().command("status").description("Show the sta
|
|
|
11145
11294
|
const bucketOra = Ora12({ indent: 2 }).info(
|
|
11146
11295
|
`Analyzing path: ${bucketPath.pathPattern}`
|
|
11147
11296
|
);
|
|
11148
|
-
const sourceLocale =
|
|
11297
|
+
const sourceLocale = resolveOverriddenLocale9(
|
|
11149
11298
|
i18nConfig.locale.source,
|
|
11150
11299
|
bucketPath.delimiter
|
|
11151
11300
|
);
|
|
@@ -11192,7 +11341,7 @@ var status_default = new Command20().command("status").description("Show the sta
|
|
|
11192
11341
|
}
|
|
11193
11342
|
fileStats[filePath].wordCount = sourceWordCount;
|
|
11194
11343
|
for (const _targetLocale of targetLocales) {
|
|
11195
|
-
const targetLocale =
|
|
11344
|
+
const targetLocale = resolveOverriddenLocale9(
|
|
11196
11345
|
_targetLocale,
|
|
11197
11346
|
bucketPath.delimiter
|
|
11198
11347
|
);
|
|
@@ -11219,7 +11368,7 @@ var status_default = new Command20().command("status").description("Show the sta
|
|
|
11219
11368
|
(totalWordCount.get(_targetLocale) || 0) + sourceWordCount
|
|
11220
11369
|
);
|
|
11221
11370
|
bucketOra.succeed(
|
|
11222
|
-
`[${sourceLocale} -> ${targetLocale}] ${
|
|
11371
|
+
`[${sourceLocale} -> ${targetLocale}] ${chalk15.red(
|
|
11223
11372
|
`0% complete`
|
|
11224
11373
|
)} (0/${sourceKeys.length} keys) - file not found`
|
|
11225
11374
|
);
|
|
@@ -11264,30 +11413,30 @@ var status_default = new Command20().command("status").description("Show the sta
|
|
|
11264
11413
|
const completionPercent = (completeKeys.length / totalKeysInFile * 100).toFixed(1);
|
|
11265
11414
|
if (missingKeys.length === 0 && updatedKeys.length === 0) {
|
|
11266
11415
|
bucketOra.succeed(
|
|
11267
|
-
`[${sourceLocale} -> ${targetLocale}] ${
|
|
11416
|
+
`[${sourceLocale} -> ${targetLocale}] ${chalk15.green(
|
|
11268
11417
|
`100% complete`
|
|
11269
11418
|
)} (${completeKeys.length}/${totalKeysInFile} keys)`
|
|
11270
11419
|
);
|
|
11271
11420
|
} else {
|
|
11272
|
-
const message = `[${sourceLocale} -> ${targetLocale}] ${parseFloat(completionPercent) > 50 ?
|
|
11421
|
+
const message = `[${sourceLocale} -> ${targetLocale}] ${parseFloat(completionPercent) > 50 ? chalk15.yellow(`${completionPercent}% complete`) : chalk15.red(`${completionPercent}% complete`)} (${completeKeys.length}/${totalKeysInFile} keys)`;
|
|
11273
11422
|
bucketOra.succeed(message);
|
|
11274
11423
|
if (flags.verbose) {
|
|
11275
11424
|
if (missingKeys.length > 0) {
|
|
11276
11425
|
console.log(
|
|
11277
|
-
` ${
|
|
11426
|
+
` ${chalk15.red(`Missing:`)} ${missingKeys.length} keys, ~${wordsToTranslate} words`
|
|
11278
11427
|
);
|
|
11279
11428
|
console.log(
|
|
11280
|
-
` ${
|
|
11429
|
+
` ${chalk15.red(`Missing:`)} ${missingKeys.length} keys, ~${wordsToTranslate} words`
|
|
11281
11430
|
);
|
|
11282
11431
|
console.log(
|
|
11283
|
-
` ${
|
|
11432
|
+
` ${chalk15.dim(
|
|
11284
11433
|
`Example missing: ${missingKeys.slice(0, 2).join(", ")}${missingKeys.length > 2 ? "..." : ""}`
|
|
11285
11434
|
)}`
|
|
11286
11435
|
);
|
|
11287
11436
|
}
|
|
11288
11437
|
if (updatedKeys.length > 0) {
|
|
11289
11438
|
console.log(
|
|
11290
|
-
` ${
|
|
11439
|
+
` ${chalk15.yellow(`Updated:`)} ${updatedKeys.length} keys that changed in source`
|
|
11291
11440
|
);
|
|
11292
11441
|
}
|
|
11293
11442
|
}
|
|
@@ -11306,22 +11455,22 @@ var status_default = new Command20().command("status").description("Show the sta
|
|
|
11306
11455
|
);
|
|
11307
11456
|
const totalCompletedKeys = totalSourceKeyCount - totalKeysNeedingTranslation / targetLocales.length;
|
|
11308
11457
|
console.log();
|
|
11309
|
-
ora.succeed(
|
|
11310
|
-
console.log(
|
|
11458
|
+
ora.succeed(chalk15.green(`Localization status completed.`));
|
|
11459
|
+
console.log(chalk15.bold.cyan(`
|
|
11311
11460
|
\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`));
|
|
11312
|
-
console.log(
|
|
11313
|
-
console.log(
|
|
11314
|
-
console.log(
|
|
11461
|
+
console.log(chalk15.bold.cyan(`\u2551 LOCALIZATION STATUS REPORT \u2551`));
|
|
11462
|
+
console.log(chalk15.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`));
|
|
11463
|
+
console.log(chalk15.bold(`
|
|
11315
11464
|
\u{1F4DD} SOURCE CONTENT:`));
|
|
11316
11465
|
console.log(
|
|
11317
|
-
`\u2022 Source language: ${
|
|
11466
|
+
`\u2022 Source language: ${chalk15.green(i18nConfig.locale.source)}`
|
|
11318
11467
|
);
|
|
11319
11468
|
console.log(
|
|
11320
|
-
`\u2022 Source keys: ${
|
|
11469
|
+
`\u2022 Source keys: ${chalk15.yellow(
|
|
11321
11470
|
totalSourceKeyCount.toString()
|
|
11322
11471
|
)} keys across all files`
|
|
11323
11472
|
);
|
|
11324
|
-
console.log(
|
|
11473
|
+
console.log(chalk15.bold(`
|
|
11325
11474
|
\u{1F310} LANGUAGE BY LANGUAGE BREAKDOWN:`));
|
|
11326
11475
|
const table = new Table({
|
|
11327
11476
|
head: [
|
|
@@ -11351,19 +11500,19 @@ var status_default = new Command20().command("status").description("Show the sta
|
|
|
11351
11500
|
let statusColor;
|
|
11352
11501
|
if (stats.missing === totalSourceKeyCount) {
|
|
11353
11502
|
statusText = "\u{1F534} Not started";
|
|
11354
|
-
statusColor =
|
|
11503
|
+
statusColor = chalk15.red;
|
|
11355
11504
|
} else if (stats.missing === 0 && stats.updated === 0) {
|
|
11356
11505
|
statusText = "\u2705 Complete";
|
|
11357
|
-
statusColor =
|
|
11506
|
+
statusColor = chalk15.green;
|
|
11358
11507
|
} else if (parseFloat(percentComplete) > 80) {
|
|
11359
11508
|
statusText = "\u{1F7E1} Almost done";
|
|
11360
|
-
statusColor =
|
|
11509
|
+
statusColor = chalk15.yellow;
|
|
11361
11510
|
} else if (parseFloat(percentComplete) > 0) {
|
|
11362
11511
|
statusText = "\u{1F7E0} In progress";
|
|
11363
|
-
statusColor =
|
|
11512
|
+
statusColor = chalk15.yellow;
|
|
11364
11513
|
} else {
|
|
11365
11514
|
statusText = "\u{1F534} Not started";
|
|
11366
|
-
statusColor =
|
|
11515
|
+
statusColor = chalk15.red;
|
|
11367
11516
|
}
|
|
11368
11517
|
const words = totalWordCount.get(locale) || 0;
|
|
11369
11518
|
totalWordsToTranslate += words;
|
|
@@ -11371,17 +11520,17 @@ var status_default = new Command20().command("status").description("Show the sta
|
|
|
11371
11520
|
locale,
|
|
11372
11521
|
statusColor(statusText),
|
|
11373
11522
|
`${stats.complete}/${totalSourceKeyCount} (${percentComplete}%)`,
|
|
11374
|
-
stats.missing > 0 ?
|
|
11375
|
-
stats.updated > 0 ?
|
|
11376
|
-
totalNeeded > 0 ?
|
|
11523
|
+
stats.missing > 0 ? chalk15.red(stats.missing.toString()) : "0",
|
|
11524
|
+
stats.updated > 0 ? chalk15.yellow(stats.updated.toString()) : "0",
|
|
11525
|
+
totalNeeded > 0 ? chalk15.magenta(totalNeeded.toString()) : "0",
|
|
11377
11526
|
words > 0 ? `~${words.toLocaleString()}` : "0"
|
|
11378
11527
|
]);
|
|
11379
11528
|
}
|
|
11380
11529
|
console.log(table.toString());
|
|
11381
|
-
console.log(
|
|
11530
|
+
console.log(chalk15.bold(`
|
|
11382
11531
|
\u{1F4CA} USAGE ESTIMATE:`));
|
|
11383
11532
|
console.log(
|
|
11384
|
-
`\u2022 WORDS TO BE CONSUMED: ~${
|
|
11533
|
+
`\u2022 WORDS TO BE CONSUMED: ~${chalk15.yellow.bold(
|
|
11385
11534
|
totalWordsToTranslate.toLocaleString()
|
|
11386
11535
|
)} words across all languages`
|
|
11387
11536
|
);
|
|
@@ -11399,11 +11548,11 @@ var status_default = new Command20().command("status").description("Show the sta
|
|
|
11399
11548
|
}
|
|
11400
11549
|
}
|
|
11401
11550
|
if (flags.confirm && Object.keys(fileStats).length > 0) {
|
|
11402
|
-
console.log(
|
|
11551
|
+
console.log(chalk15.bold(`
|
|
11403
11552
|
\u{1F4D1} BREAKDOWN BY FILE:`));
|
|
11404
11553
|
Object.entries(fileStats).sort((a, b) => b[1].wordCount - a[1].wordCount).forEach(([path19, stats]) => {
|
|
11405
11554
|
if (stats.sourceKeys === 0) return;
|
|
11406
|
-
console.log(
|
|
11555
|
+
console.log(chalk15.bold(`
|
|
11407
11556
|
\u2022 ${path19}:`));
|
|
11408
11557
|
console.log(
|
|
11409
11558
|
` ${stats.sourceKeys} source keys, ~${stats.wordCount.toLocaleString()} source words`
|
|
@@ -11423,13 +11572,13 @@ var status_default = new Command20().command("status").description("Show the sta
|
|
|
11423
11572
|
const total = stats.sourceKeys;
|
|
11424
11573
|
const completion = (complete / total * 100).toFixed(1);
|
|
11425
11574
|
let status = "\u2705 Complete";
|
|
11426
|
-
let statusColor =
|
|
11575
|
+
let statusColor = chalk15.green;
|
|
11427
11576
|
if (langStats.missing === total) {
|
|
11428
11577
|
status = "\u274C Not started";
|
|
11429
|
-
statusColor =
|
|
11578
|
+
statusColor = chalk15.red;
|
|
11430
11579
|
} else if (langStats.missing > 0 || langStats.updated > 0) {
|
|
11431
11580
|
status = `\u26A0\uFE0F ${completion}% complete`;
|
|
11432
|
-
statusColor =
|
|
11581
|
+
statusColor = chalk15.yellow;
|
|
11433
11582
|
}
|
|
11434
11583
|
let details = "";
|
|
11435
11584
|
if (langStats.missing > 0 || langStats.updated > 0) {
|
|
@@ -11453,16 +11602,16 @@ var status_default = new Command20().command("status").description("Show the sta
|
|
|
11453
11602
|
const missingLanguages = targetLocales.filter(
|
|
11454
11603
|
(locale) => languageStats[locale].complete === 0
|
|
11455
11604
|
);
|
|
11456
|
-
console.log(
|
|
11605
|
+
console.log(chalk15.bold.green(`
|
|
11457
11606
|
\u{1F4A1} OPTIMIZATION TIPS:`));
|
|
11458
11607
|
if (missingLanguages.length > 0) {
|
|
11459
11608
|
console.log(
|
|
11460
|
-
`\u2022 ${
|
|
11609
|
+
`\u2022 ${chalk15.yellow(missingLanguages.join(", "))} ${missingLanguages.length === 1 ? "has" : "have"} no translations yet`
|
|
11461
11610
|
);
|
|
11462
11611
|
}
|
|
11463
11612
|
if (completeLanguages.length > 0) {
|
|
11464
11613
|
console.log(
|
|
11465
|
-
`\u2022 ${
|
|
11614
|
+
`\u2022 ${chalk15.green(completeLanguages.join(", "))} ${completeLanguages.length === 1 ? "is" : "are"} completely translated`
|
|
11466
11615
|
);
|
|
11467
11616
|
}
|
|
11468
11617
|
if (targetLocales.length > 1) {
|
|
@@ -11546,7 +11695,7 @@ function validateParams2(i18nConfig, flags) {
|
|
|
11546
11695
|
import { Command as Command21 } from "interactive-commander";
|
|
11547
11696
|
import * as cp from "node:child_process";
|
|
11548
11697
|
import figlet2 from "figlet";
|
|
11549
|
-
import
|
|
11698
|
+
import chalk16 from "chalk";
|
|
11550
11699
|
import { vice as vice2 } from "gradient-string";
|
|
11551
11700
|
var colors2 = {
|
|
11552
11701
|
orange: "#ff6600",
|
|
@@ -11560,7 +11709,7 @@ var may_the_fourth_default = new Command21().command("may-the-fourth").descripti
|
|
|
11560
11709
|
await renderClear2();
|
|
11561
11710
|
await renderBanner2();
|
|
11562
11711
|
await renderSpacer2();
|
|
11563
|
-
console.log(
|
|
11712
|
+
console.log(chalk16.hex(colors2.yellow)("Loading the Star Wars movie..."));
|
|
11564
11713
|
await renderSpacer2();
|
|
11565
11714
|
await new Promise((resolve, reject) => {
|
|
11566
11715
|
const ssh = cp.spawn("ssh", ["starwarstel.net"], {
|
|
@@ -11579,12 +11728,12 @@ var may_the_fourth_default = new Command21().command("may-the-fourth").descripti
|
|
|
11579
11728
|
});
|
|
11580
11729
|
await renderSpacer2();
|
|
11581
11730
|
console.log(
|
|
11582
|
-
`${
|
|
11731
|
+
`${chalk16.hex(colors2.green)("We hope you enjoyed it! :)")} ${chalk16.hex(
|
|
11583
11732
|
colors2.blue
|
|
11584
11733
|
)("May the Fourth be with you! \u{1F680}")}`
|
|
11585
11734
|
);
|
|
11586
11735
|
await renderSpacer2();
|
|
11587
|
-
console.log(
|
|
11736
|
+
console.log(chalk16.dim(`---`));
|
|
11588
11737
|
await renderSpacer2();
|
|
11589
11738
|
await renderHero2();
|
|
11590
11739
|
});
|
|
@@ -11607,24 +11756,24 @@ async function renderBanner2() {
|
|
|
11607
11756
|
}
|
|
11608
11757
|
async function renderHero2() {
|
|
11609
11758
|
console.log(
|
|
11610
|
-
`\u26A1\uFE0F ${
|
|
11759
|
+
`\u26A1\uFE0F ${chalk16.hex(colors2.green)(
|
|
11611
11760
|
"Lingo.dev"
|
|
11612
11761
|
)} - open-source, AI-powered i18n CLI for web & mobile localization.`
|
|
11613
11762
|
);
|
|
11614
11763
|
console.log(" ");
|
|
11615
|
-
console.log(
|
|
11764
|
+
console.log(chalk16.hex(colors2.blue)("\u{1F4DA} Docs: https://lingo.dev/go/docs"));
|
|
11616
11765
|
console.log(
|
|
11617
|
-
|
|
11766
|
+
chalk16.hex(colors2.blue)("\u2B50 Star the repo: https://lingo.dev/go/gh")
|
|
11618
11767
|
);
|
|
11619
11768
|
console.log(
|
|
11620
|
-
|
|
11769
|
+
chalk16.hex(colors2.blue)("\u{1F3AE} Join Discord: https://lingo.dev/go/discord")
|
|
11621
11770
|
);
|
|
11622
11771
|
}
|
|
11623
11772
|
|
|
11624
11773
|
// package.json
|
|
11625
11774
|
var package_default = {
|
|
11626
11775
|
name: "lingo.dev",
|
|
11627
|
-
version: "0.
|
|
11776
|
+
version: "0.113.0",
|
|
11628
11777
|
description: "Lingo.dev CLI",
|
|
11629
11778
|
private: false,
|
|
11630
11779
|
publishConfig: {
|
|
@@ -11875,7 +12024,7 @@ var package_default = {
|
|
|
11875
12024
|
// src/cli/cmd/purge.ts
|
|
11876
12025
|
import { Command as Command22 } from "interactive-commander";
|
|
11877
12026
|
import Ora13 from "ora";
|
|
11878
|
-
import { resolveOverriddenLocale as
|
|
12027
|
+
import { resolveOverriddenLocale as resolveOverriddenLocale10 } from "@lingo.dev/_spec";
|
|
11879
12028
|
import { confirm as confirm3 } from "@inquirer/prompts";
|
|
11880
12029
|
var purge_default = new Command22().command("purge").description(
|
|
11881
12030
|
"WARNING: Permanently delete translation entries from bucket path patterns defined in i18n.json. This is a destructive operation that cannot be undone. Without any filters, ALL managed keys will be removed from EVERY target locale."
|
|
@@ -11931,7 +12080,7 @@ var purge_default = new Command22().command("purge").description(
|
|
|
11931
12080
|
ora.info(`Processing bucket: ${bucket.type}`);
|
|
11932
12081
|
for (const bucketPath of bucket.paths) {
|
|
11933
12082
|
for (const _targetLocale of targetLocales) {
|
|
11934
|
-
const targetLocale =
|
|
12083
|
+
const targetLocale = resolveOverriddenLocale10(
|
|
11935
12084
|
_targetLocale,
|
|
11936
12085
|
bucketPath.delimiter
|
|
11937
12086
|
);
|