@tolkbot/cli 0.5.0 → 0.6.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/dist/index.js +616 -184
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -5784,10 +5784,10 @@ var require_out4 = __commonJS({
|
|
|
5784
5784
|
});
|
|
5785
5785
|
|
|
5786
5786
|
// src/main.ts
|
|
5787
|
-
import { Command as
|
|
5787
|
+
import { Command as Command9, CommanderError, Option as Option2 } from "commander";
|
|
5788
5788
|
|
|
5789
5789
|
// package.json
|
|
5790
|
-
var version = "0.
|
|
5790
|
+
var version = "0.6.0";
|
|
5791
5791
|
|
|
5792
5792
|
// src/commands/auth/index.ts
|
|
5793
5793
|
import { Command } from "commander";
|
|
@@ -6315,7 +6315,7 @@ import { ConvexHttpClient } from "convex/browser";
|
|
|
6315
6315
|
var BACKEND_METHODS = /* @__PURE__ */ new Set(["query", "mutation", "action"]);
|
|
6316
6316
|
var client = null;
|
|
6317
6317
|
function getConvexClient() {
|
|
6318
|
-
client ??= new ConvexHttpClient(requireConvexUrl());
|
|
6318
|
+
client ??= new ConvexHttpClient(requireConvexUrl(), { logger: false });
|
|
6319
6319
|
return client;
|
|
6320
6320
|
}
|
|
6321
6321
|
function translateAuthError(error62, resolved) {
|
|
@@ -26823,6 +26823,75 @@ var SUPPORTED_LOCALES = [
|
|
|
26823
26823
|
"eu",
|
|
26824
26824
|
"gl"
|
|
26825
26825
|
];
|
|
26826
|
+
var LOCALE_NAMES = {
|
|
26827
|
+
en: "English",
|
|
26828
|
+
"en-us": "English (US)",
|
|
26829
|
+
"en-gb": "English (UK)",
|
|
26830
|
+
"en-au": "English (Australia)",
|
|
26831
|
+
"en-ca": "English (Canada)",
|
|
26832
|
+
es: "Spanish",
|
|
26833
|
+
"es-es": "Spanish (Spain)",
|
|
26834
|
+
"es-mx": "Spanish (Mexico)",
|
|
26835
|
+
"es-ar": "Spanish (Argentina)",
|
|
26836
|
+
pt: "Portuguese",
|
|
26837
|
+
"pt-br": "Portuguese (Brazil)",
|
|
26838
|
+
"pt-pt": "Portuguese (Portugal)",
|
|
26839
|
+
zh: "Chinese",
|
|
26840
|
+
"zh-cn": "Chinese (Simplified)",
|
|
26841
|
+
"zh-tw": "Chinese (Traditional)",
|
|
26842
|
+
"zh-hk": "Chinese (Hong Kong)",
|
|
26843
|
+
fr: "French",
|
|
26844
|
+
"fr-fr": "French (France)",
|
|
26845
|
+
"fr-ca": "French (Canada)",
|
|
26846
|
+
de: "German",
|
|
26847
|
+
"de-de": "German (Germany)",
|
|
26848
|
+
"de-at": "German (Austria)",
|
|
26849
|
+
"de-ch": "German (Switzerland)",
|
|
26850
|
+
no: "Norwegian",
|
|
26851
|
+
nb: "Norwegian Bokm\xE5l",
|
|
26852
|
+
nn: "Norwegian Nynorsk",
|
|
26853
|
+
sv: "Swedish",
|
|
26854
|
+
da: "Danish",
|
|
26855
|
+
fi: "Finnish",
|
|
26856
|
+
is: "Icelandic",
|
|
26857
|
+
it: "Italian",
|
|
26858
|
+
nl: "Dutch",
|
|
26859
|
+
"nl-be": "Dutch (Belgium)",
|
|
26860
|
+
pl: "Polish",
|
|
26861
|
+
cs: "Czech",
|
|
26862
|
+
sk: "Slovak",
|
|
26863
|
+
hu: "Hungarian",
|
|
26864
|
+
ro: "Romanian",
|
|
26865
|
+
bg: "Bulgarian",
|
|
26866
|
+
hr: "Croatian",
|
|
26867
|
+
sl: "Slovenian",
|
|
26868
|
+
sr: "Serbian",
|
|
26869
|
+
uk: "Ukrainian",
|
|
26870
|
+
el: "Greek",
|
|
26871
|
+
tr: "Turkish",
|
|
26872
|
+
ru: "Russian",
|
|
26873
|
+
ja: "Japanese",
|
|
26874
|
+
ko: "Korean",
|
|
26875
|
+
th: "Thai",
|
|
26876
|
+
vi: "Vietnamese",
|
|
26877
|
+
id: "Indonesian",
|
|
26878
|
+
ms: "Malay",
|
|
26879
|
+
tl: "Tagalog",
|
|
26880
|
+
hi: "Hindi",
|
|
26881
|
+
bn: "Bengali",
|
|
26882
|
+
ta: "Tamil",
|
|
26883
|
+
ar: "Arabic",
|
|
26884
|
+
he: "Hebrew",
|
|
26885
|
+
fa: "Persian",
|
|
26886
|
+
af: "Afrikaans",
|
|
26887
|
+
sw: "Swahili",
|
|
26888
|
+
et: "Estonian",
|
|
26889
|
+
lv: "Latvian",
|
|
26890
|
+
lt: "Lithuanian",
|
|
26891
|
+
ca: "Catalan",
|
|
26892
|
+
eu: "Basque",
|
|
26893
|
+
gl: "Galician"
|
|
26894
|
+
};
|
|
26826
26895
|
var DEFAULT_BEHAVIORAL_SETTINGS = {
|
|
26827
26896
|
tonePreset: "formal",
|
|
26828
26897
|
toneInstructions: "Use a formal, professional tone. Avoid slang.",
|
|
@@ -31321,6 +31390,13 @@ var BILLING_BLOCKED = "BILLING_BLOCKED";
|
|
|
31321
31390
|
|
|
31322
31391
|
// ../shared/src/projects/localeSetup.ts
|
|
31323
31392
|
var LOCALE_SETUP_STALE_MS = 15 * 60 * 1e3;
|
|
31393
|
+
function localeSetupState(row, now) {
|
|
31394
|
+
if (!row) return "not-set-up";
|
|
31395
|
+
if (row.status === "onboarded") return "set-up";
|
|
31396
|
+
if (row.onboardingError !== void 0) return "failed";
|
|
31397
|
+
if (row.onboardingRequestedAt === void 0) return "not-set-up";
|
|
31398
|
+
return now - row.onboardingRequestedAt > LOCALE_SETUP_STALE_MS ? "failed" : "running";
|
|
31399
|
+
}
|
|
31324
31400
|
|
|
31325
31401
|
// ../shared/src/projects/index.ts
|
|
31326
31402
|
var PROJECT_ARCHIVED = "PROJECT_ARCHIVED";
|
|
@@ -31354,6 +31430,7 @@ var ERROR_CODES = {
|
|
|
31354
31430
|
login_failed: EXIT_CODES.failure,
|
|
31355
31431
|
// 2: usage
|
|
31356
31432
|
usage: EXIT_CODES.usage,
|
|
31433
|
+
unsupported_locale: EXIT_CODES.usage,
|
|
31357
31434
|
// 3: not authenticated, or not allowed
|
|
31358
31435
|
not_authenticated: EXIT_CODES.auth,
|
|
31359
31436
|
token_expired: EXIT_CODES.auth,
|
|
@@ -31676,24 +31753,377 @@ jobsCommand.command("cancel").description("Cancel a running translation job").ar
|
|
|
31676
31753
|
await runJobsCancel(validateOrExit(schema, { ...opts, jobId }));
|
|
31677
31754
|
});
|
|
31678
31755
|
|
|
31679
|
-
// src/commands/
|
|
31680
|
-
import { Command as Command4 } from "commander";
|
|
31756
|
+
// src/commands/languages/index.ts
|
|
31757
|
+
import { Command as Command4, Option } from "commander";
|
|
31681
31758
|
import { z as z6 } from "zod/v4";
|
|
31682
31759
|
|
|
31683
|
-
// src/commands/
|
|
31760
|
+
// src/commands/languages/add.tsx
|
|
31684
31761
|
import { Spinner as Spinner9 } from "@inkjs/ui";
|
|
31685
|
-
import { Box as Box12,
|
|
31762
|
+
import { Box as Box12, Text as Text12 } from "ink";
|
|
31763
|
+
|
|
31764
|
+
// src/commands/languages/languages-core.ts
|
|
31765
|
+
var DEFAULT_EXISTING_MODE = "trust";
|
|
31766
|
+
var MAX_SUGGESTIONS = 6;
|
|
31767
|
+
function editDistance(a, b) {
|
|
31768
|
+
let previous = Array.from({ length: b.length + 1 }, (_, i) => i);
|
|
31769
|
+
for (let i = 1; i <= a.length; i++) {
|
|
31770
|
+
const current = [i];
|
|
31771
|
+
for (let j = 1; j <= b.length; j++) {
|
|
31772
|
+
current[j] = Math.min(
|
|
31773
|
+
(previous[j] ?? 0) + 1,
|
|
31774
|
+
(current[j - 1] ?? 0) + 1,
|
|
31775
|
+
(previous[j - 1] ?? 0) + (a[i - 1] === b[j - 1] ? 0 : 1)
|
|
31776
|
+
);
|
|
31777
|
+
}
|
|
31778
|
+
previous = current;
|
|
31779
|
+
}
|
|
31780
|
+
return previous[b.length] ?? 0;
|
|
31781
|
+
}
|
|
31782
|
+
function closestLocales(input2) {
|
|
31783
|
+
const typed = input2.trim().toLowerCase().replace(/_/g, "-");
|
|
31784
|
+
const language = typed.split("-")[0] ?? "";
|
|
31785
|
+
const found = /* @__PURE__ */ new Set();
|
|
31786
|
+
for (const locale of SUPPORTED_LOCALES) {
|
|
31787
|
+
if (locale.split("-")[0] === language) found.add(locale);
|
|
31788
|
+
}
|
|
31789
|
+
if (typed.length >= 3) {
|
|
31790
|
+
for (const locale of SUPPORTED_LOCALES) {
|
|
31791
|
+
if (LOCALE_NAMES[locale].toLowerCase().includes(typed))
|
|
31792
|
+
found.add(locale);
|
|
31793
|
+
}
|
|
31794
|
+
}
|
|
31795
|
+
for (const locale of SUPPORTED_LOCALES) {
|
|
31796
|
+
if (editDistance(locale, typed) === 1) found.add(locale);
|
|
31797
|
+
}
|
|
31798
|
+
return [...found].slice(0, MAX_SUGGESTIONS);
|
|
31799
|
+
}
|
|
31800
|
+
function resolveLocales(inputs) {
|
|
31801
|
+
const resolved = [];
|
|
31802
|
+
const unsupported = [];
|
|
31803
|
+
for (const input2 of inputs) {
|
|
31804
|
+
const locale = canonicalGlossaryLocale(input2.trim());
|
|
31805
|
+
if (!locale) {
|
|
31806
|
+
unsupported.push(input2);
|
|
31807
|
+
continue;
|
|
31808
|
+
}
|
|
31809
|
+
if (!resolved.includes(locale)) resolved.push(locale);
|
|
31810
|
+
}
|
|
31811
|
+
if (unsupported.length === 0) return resolved;
|
|
31812
|
+
const lines = unsupported.map((input2) => {
|
|
31813
|
+
const close = closestLocales(input2);
|
|
31814
|
+
return close.length > 0 ? `For ${input2}, the closest supported codes are ${close.join(", ")}.` : `Nothing supported is close to ${input2}.`;
|
|
31815
|
+
});
|
|
31816
|
+
const anyWithout = unsupported.some((i) => closestLocales(i).length === 0);
|
|
31817
|
+
if (anyWithout) {
|
|
31818
|
+
lines.push(`Supported codes: ${SUPPORTED_LOCALES.join(", ")}.`);
|
|
31819
|
+
}
|
|
31820
|
+
throw new CliError(
|
|
31821
|
+
`TolkBot does not support ${unsupported.join(", ")}.`,
|
|
31822
|
+
lines.join(" "),
|
|
31823
|
+
"unsupported_locale"
|
|
31824
|
+
);
|
|
31825
|
+
}
|
|
31826
|
+
function planAdd(project, rows, locales, now) {
|
|
31827
|
+
const base = locales.find((l) => sameLocale(l, project.baseLanguage));
|
|
31828
|
+
if (base) {
|
|
31829
|
+
throw new UsageError(
|
|
31830
|
+
`${base} is the project's base language, so it cannot be added as a target.`,
|
|
31831
|
+
"Name a language to translate into."
|
|
31832
|
+
);
|
|
31833
|
+
}
|
|
31834
|
+
return locales.map((locale) => {
|
|
31835
|
+
const onProject = project.targetLanguages.some(
|
|
31836
|
+
(t) => sameLocale(t, locale)
|
|
31837
|
+
);
|
|
31838
|
+
if (!onProject)
|
|
31839
|
+
return { locale, action: "add", setup: "not-on-project" };
|
|
31840
|
+
const row = rows.find((r) => sameLocale(r.locale, locale));
|
|
31841
|
+
const setup = localeSetupState(row, now);
|
|
31842
|
+
const action = setup === "set-up" || setup === "running" ? "none" : "set_up";
|
|
31843
|
+
return { locale, action, setup };
|
|
31844
|
+
});
|
|
31845
|
+
}
|
|
31846
|
+
function targetsAfter(project, plan) {
|
|
31847
|
+
return [
|
|
31848
|
+
...project.targetLanguages,
|
|
31849
|
+
...plan.filter((p) => p.action === "add").map((p) => p.locale)
|
|
31850
|
+
];
|
|
31851
|
+
}
|
|
31852
|
+
function localeName(locale) {
|
|
31853
|
+
return LOCALE_NAMES[locale] ?? locale;
|
|
31854
|
+
}
|
|
31855
|
+
function describeOutcome(outcome) {
|
|
31856
|
+
const name = `${outcome.locale} (${localeName(outcome.locale)})`;
|
|
31857
|
+
switch (outcome.outcome) {
|
|
31858
|
+
case "added":
|
|
31859
|
+
return `\u2713 ${name} added and set up.`;
|
|
31860
|
+
case "set_up":
|
|
31861
|
+
return `\u2713 ${name} was on the project; now set up.`;
|
|
31862
|
+
case "unchanged":
|
|
31863
|
+
return outcome.setup === "running" ? `- ${name} is already on the project and being set up.` : `- ${name} is already on the project.`;
|
|
31864
|
+
case "failed":
|
|
31865
|
+
return `\u2717 ${name} is on the project, but setting it up failed: ${outcome.error}`;
|
|
31866
|
+
}
|
|
31867
|
+
}
|
|
31868
|
+
function describeNextSteps(ready, autoCreatePR) {
|
|
31869
|
+
if (ready.length === 0) return [];
|
|
31870
|
+
const lines = [
|
|
31871
|
+
"Next, fill the files now:",
|
|
31872
|
+
...ready.map((l) => ` ${translateCommand(l)}`)
|
|
31873
|
+
];
|
|
31874
|
+
if (autoCreatePR) {
|
|
31875
|
+
lines.push(
|
|
31876
|
+
"Or wait: pull requests are on for this project, so the next push that changes the base file opens one per language, with the keys that push added or changed."
|
|
31877
|
+
);
|
|
31878
|
+
}
|
|
31879
|
+
return lines;
|
|
31880
|
+
}
|
|
31881
|
+
function translateCommand(locale) {
|
|
31882
|
+
return `tolkbot translate --dst ${locale}`;
|
|
31883
|
+
}
|
|
31884
|
+
|
|
31885
|
+
// src/commands/languages/add.tsx
|
|
31686
31886
|
import { jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
31887
|
+
async function runLanguagesAdd(opts) {
|
|
31888
|
+
const locales = resolveLocales(opts.locales);
|
|
31889
|
+
const ctx = await loadPlanContext(process.cwd());
|
|
31890
|
+
const { project } = ctx;
|
|
31891
|
+
const ids = {
|
|
31892
|
+
organizationId: project.organizationId,
|
|
31893
|
+
projectId: project._id
|
|
31894
|
+
};
|
|
31895
|
+
const rows = await ctx.client.query(api.projectLocales.list, ids);
|
|
31896
|
+
const plan = planAdd(project, rows, locales, Date.now());
|
|
31897
|
+
const outcomes = [];
|
|
31898
|
+
const progress = renderTransient(
|
|
31899
|
+
/* @__PURE__ */ jsxs12(Box12, { children: [
|
|
31900
|
+
/* @__PURE__ */ jsx12(Spinner9, {}),
|
|
31901
|
+
/* @__PURE__ */ jsxs12(Text12, { children: [
|
|
31902
|
+
" ",
|
|
31903
|
+
"Adding ",
|
|
31904
|
+
locales.join(", "),
|
|
31905
|
+
" to ",
|
|
31906
|
+
project.name,
|
|
31907
|
+
"\u2026"
|
|
31908
|
+
] })
|
|
31909
|
+
] })
|
|
31910
|
+
);
|
|
31911
|
+
try {
|
|
31912
|
+
if (plan.some((p) => p.action === "add")) {
|
|
31913
|
+
await ctx.client.mutation(api.projects.update, {
|
|
31914
|
+
...ids,
|
|
31915
|
+
patch: {
|
|
31916
|
+
targetLanguages: targetsAfter(project, plan)
|
|
31917
|
+
}
|
|
31918
|
+
});
|
|
31919
|
+
}
|
|
31920
|
+
const client3 = await getAuthenticatedConvexClient();
|
|
31921
|
+
for (const { locale, action, setup } of plan) {
|
|
31922
|
+
if (action === "none") {
|
|
31923
|
+
outcomes.push({
|
|
31924
|
+
locale,
|
|
31925
|
+
outcome: "unchanged",
|
|
31926
|
+
setup: setup === "running" ? "running" : "set-up"
|
|
31927
|
+
});
|
|
31928
|
+
continue;
|
|
31929
|
+
}
|
|
31930
|
+
try {
|
|
31931
|
+
await client3.action(api.actions.onboardLocale.onboardLocale, {
|
|
31932
|
+
...ids,
|
|
31933
|
+
locale,
|
|
31934
|
+
mode: opts.existing
|
|
31935
|
+
});
|
|
31936
|
+
outcomes.push({
|
|
31937
|
+
locale,
|
|
31938
|
+
outcome: action === "add" ? "added" : "set_up"
|
|
31939
|
+
});
|
|
31940
|
+
} catch (error62) {
|
|
31941
|
+
outcomes.push({
|
|
31942
|
+
locale,
|
|
31943
|
+
outcome: "failed",
|
|
31944
|
+
error: toCliError(error62).baseMessage
|
|
31945
|
+
});
|
|
31946
|
+
}
|
|
31947
|
+
}
|
|
31948
|
+
} finally {
|
|
31949
|
+
progress.unmount();
|
|
31950
|
+
}
|
|
31951
|
+
const ready = outcomes.filter((o) => o.outcome === "added" || o.outcome === "set_up").map((o) => o.locale);
|
|
31952
|
+
const autoCreatePR = project.workflow?.autoCreatePR ?? DEFAULT_BEHAVIORAL_SETTINGS.workflow.autoCreatePR;
|
|
31953
|
+
const failed = outcomes.filter((o) => o.outcome === "failed");
|
|
31954
|
+
const payload = {
|
|
31955
|
+
project: { name: project.name, slug: project.slug },
|
|
31956
|
+
existing: opts.existing,
|
|
31957
|
+
changed: ready.length > 0 || plan.some((p) => p.action === "add"),
|
|
31958
|
+
languages: outcomes,
|
|
31959
|
+
targetLanguages: targetsAfter(project, plan),
|
|
31960
|
+
next: {
|
|
31961
|
+
translate: ready.map(translateCommand),
|
|
31962
|
+
pullRequestOnPush: autoCreatePR
|
|
31963
|
+
}
|
|
31964
|
+
};
|
|
31965
|
+
const failure2 = failed.length > 0 ? new CliError(
|
|
31966
|
+
`Setting up ${failed.map((o) => o.locale).join(", ")} failed.`,
|
|
31967
|
+
"Run the same command again to retry, or set it up from the project's Translations page."
|
|
31968
|
+
) : null;
|
|
31969
|
+
if (opts.json) {
|
|
31970
|
+
if (!failure2) jsonSuccess(payload);
|
|
31971
|
+
jsonResult(payload, 1);
|
|
31972
|
+
fail(failure2);
|
|
31973
|
+
}
|
|
31974
|
+
for (const outcome of outcomes) console.log(describeOutcome(outcome));
|
|
31975
|
+
if (!payload.changed) console.log("Nothing changed.");
|
|
31976
|
+
const next = describeNextSteps(ready, autoCreatePR);
|
|
31977
|
+
if (next.length > 0) {
|
|
31978
|
+
console.log("");
|
|
31979
|
+
for (const line of next) console.log(line);
|
|
31980
|
+
}
|
|
31981
|
+
if (failure2) fail(failure2);
|
|
31982
|
+
}
|
|
31983
|
+
|
|
31984
|
+
// src/commands/languages/list.ts
|
|
31985
|
+
var SETUP_WORDS = {
|
|
31986
|
+
"set-up": "set up",
|
|
31987
|
+
running: "being set up",
|
|
31988
|
+
failed: "setup failed",
|
|
31989
|
+
"not-set-up": "not set up"
|
|
31990
|
+
};
|
|
31991
|
+
async function runLanguagesList(opts) {
|
|
31992
|
+
const ctx = await loadPlanContext(process.cwd());
|
|
31993
|
+
const { project } = ctx;
|
|
31994
|
+
const rows = await ctx.client.query(api.projectLocales.list, {
|
|
31995
|
+
organizationId: project.organizationId,
|
|
31996
|
+
projectId: project._id
|
|
31997
|
+
});
|
|
31998
|
+
const scope = scopeOf(project);
|
|
31999
|
+
const files = await listLocaleFiles(ctx.root, scope);
|
|
32000
|
+
const sourceFiles = filesForLocale(files, project.baseLanguage);
|
|
32001
|
+
const found = (file2) => ({
|
|
32002
|
+
path: file2.relativePath,
|
|
32003
|
+
exists: true
|
|
32004
|
+
});
|
|
32005
|
+
const fromPattern = (locale) => {
|
|
32006
|
+
const existing = filesForLocale(files, locale);
|
|
32007
|
+
if (existing.length > 0) return existing.map(found);
|
|
32008
|
+
return [
|
|
32009
|
+
{
|
|
32010
|
+
path: replaceLocalePlaceholder(fullPattern(scope), locale),
|
|
32011
|
+
exists: false
|
|
32012
|
+
}
|
|
32013
|
+
];
|
|
32014
|
+
};
|
|
32015
|
+
const base = {
|
|
32016
|
+
locale: project.baseLanguage,
|
|
32017
|
+
name: localeName(project.baseLanguage),
|
|
32018
|
+
files: fromPattern(project.baseLanguage)
|
|
32019
|
+
};
|
|
32020
|
+
const now = Date.now();
|
|
32021
|
+
const targets = project.targetLanguages.map((locale) => ({
|
|
32022
|
+
locale,
|
|
32023
|
+
name: localeName(locale),
|
|
32024
|
+
setup: localeSetupState(
|
|
32025
|
+
rows.find((r) => sameLocale(r.locale, locale)),
|
|
32026
|
+
now
|
|
32027
|
+
),
|
|
32028
|
+
files: sourceFiles.length === 0 ? fromPattern(locale) : sourceFiles.map((source) => {
|
|
32029
|
+
const target = targetFileFor(
|
|
32030
|
+
source,
|
|
32031
|
+
locale,
|
|
32032
|
+
files,
|
|
32033
|
+
scope
|
|
32034
|
+
);
|
|
32035
|
+
return {
|
|
32036
|
+
path: target.relativePath,
|
|
32037
|
+
exists: target.existing !== null
|
|
32038
|
+
};
|
|
32039
|
+
})
|
|
32040
|
+
}));
|
|
32041
|
+
if (opts.json) {
|
|
32042
|
+
jsonSuccess({
|
|
32043
|
+
project: { name: project.name, slug: project.slug },
|
|
32044
|
+
pattern: fullPattern(scope),
|
|
32045
|
+
base,
|
|
32046
|
+
targets
|
|
32047
|
+
});
|
|
32048
|
+
}
|
|
32049
|
+
console.log(
|
|
32050
|
+
`${project.name} (${project.slug}), files ${fullPattern(scope)}`
|
|
32051
|
+
);
|
|
32052
|
+
console.log("");
|
|
32053
|
+
const printFiles = (language) => {
|
|
32054
|
+
for (const file2 of language.files) {
|
|
32055
|
+
console.log(
|
|
32056
|
+
` ${file2.path}${file2.exists ? "" : " (no file yet)"}`
|
|
32057
|
+
);
|
|
32058
|
+
}
|
|
32059
|
+
};
|
|
32060
|
+
console.log(`${base.locale} (${base.name}), base language`);
|
|
32061
|
+
printFiles(base);
|
|
32062
|
+
for (const target of targets) {
|
|
32063
|
+
console.log(
|
|
32064
|
+
`${target.locale} (${target.name}), ${SETUP_WORDS[target.setup]}`
|
|
32065
|
+
);
|
|
32066
|
+
printFiles(target);
|
|
32067
|
+
}
|
|
32068
|
+
if (targets.length === 0) {
|
|
32069
|
+
console.log("");
|
|
32070
|
+
console.log(
|
|
32071
|
+
"No target languages yet. Add one with 'tolkbot languages add <code>'."
|
|
32072
|
+
);
|
|
32073
|
+
}
|
|
32074
|
+
}
|
|
32075
|
+
|
|
32076
|
+
// src/commands/languages/index.ts
|
|
32077
|
+
var languagesCommand = new Command4("languages").description(
|
|
32078
|
+
"List the project's languages and add target languages"
|
|
32079
|
+
);
|
|
32080
|
+
var JSON_HELP2 = "Output as JSON (machine-readable)";
|
|
32081
|
+
languagesCommand.command("list").description(
|
|
32082
|
+
"The base language and the target languages, with the files each one maps to and whether they exist"
|
|
32083
|
+
).option("--json", JSON_HELP2).action(async (opts) => {
|
|
32084
|
+
const schema = z6.object({ json: z6.boolean().optional() });
|
|
32085
|
+
await runLanguagesList(validateOrExit(schema, opts));
|
|
32086
|
+
});
|
|
32087
|
+
languagesCommand.command("add").description(
|
|
32088
|
+
"Add target languages to the project and set them up, as the dashboard's Add language dialog does. Translating is 'tolkbot translate'"
|
|
32089
|
+
).argument("<locales...>", "Locale codes, e.g. nb de pt-BR").addOption(
|
|
32090
|
+
new Option(
|
|
32091
|
+
"--existing <mode>",
|
|
32092
|
+
"What to do with translations the repository already has: keep them as written by a person (trust), or flag them for review"
|
|
32093
|
+
).choices(["trust", "review"]).default(DEFAULT_EXISTING_MODE)
|
|
32094
|
+
).option("--json", JSON_HELP2).addHelpText(
|
|
32095
|
+
"after",
|
|
32096
|
+
`
|
|
32097
|
+
Examples:
|
|
32098
|
+
$ tolkbot languages add nb
|
|
32099
|
+
$ tolkbot languages add de fr --existing review`
|
|
32100
|
+
).action(async (locales, opts) => {
|
|
32101
|
+
const schema = z6.object({
|
|
32102
|
+
locales: z6.array(z6.string().min(1)).min(1),
|
|
32103
|
+
existing: z6.enum(["trust", "review"]),
|
|
32104
|
+
json: z6.boolean().optional()
|
|
32105
|
+
});
|
|
32106
|
+
await runLanguagesAdd(validateOrExit(schema, { ...opts, locales }));
|
|
32107
|
+
});
|
|
32108
|
+
|
|
32109
|
+
// src/commands/learnings/index.ts
|
|
32110
|
+
import { Command as Command5 } from "commander";
|
|
32111
|
+
import { z as z7 } from "zod/v4";
|
|
32112
|
+
|
|
32113
|
+
// src/commands/learnings/archive.tsx
|
|
32114
|
+
import { Spinner as Spinner10 } from "@inkjs/ui";
|
|
32115
|
+
import { Box as Box13, render as render12, Text as Text13 } from "ink";
|
|
32116
|
+
import { jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
31687
32117
|
function ArchiveUI({ state }) {
|
|
31688
32118
|
if (state.type === "archiving") {
|
|
31689
|
-
return /* @__PURE__ */
|
|
31690
|
-
/* @__PURE__ */
|
|
31691
|
-
/* @__PURE__ */
|
|
32119
|
+
return /* @__PURE__ */ jsxs13(Box13, { children: [
|
|
32120
|
+
/* @__PURE__ */ jsx13(Spinner10, {}),
|
|
32121
|
+
/* @__PURE__ */ jsx13(Text13, { children: " Archiving learning\u2026" })
|
|
31692
32122
|
] });
|
|
31693
32123
|
}
|
|
31694
|
-
return /* @__PURE__ */
|
|
31695
|
-
/* @__PURE__ */
|
|
31696
|
-
/* @__PURE__ */
|
|
32124
|
+
return /* @__PURE__ */ jsxs13(Box13, { children: [
|
|
32125
|
+
/* @__PURE__ */ jsx13(Text13, { color: "green", children: "\u2713" }),
|
|
32126
|
+
/* @__PURE__ */ jsx13(Text13, { children: " Learning archived" })
|
|
31697
32127
|
] });
|
|
31698
32128
|
}
|
|
31699
32129
|
async function runLearningsArchive(opts) {
|
|
@@ -31710,20 +32140,20 @@ async function runLearningsArchive(opts) {
|
|
|
31710
32140
|
jsonSuccess({ id: opts.id, ok: true });
|
|
31711
32141
|
}
|
|
31712
32142
|
const { unmount } = renderTransient(
|
|
31713
|
-
/* @__PURE__ */
|
|
32143
|
+
/* @__PURE__ */ jsx13(ArchiveUI, { state: { type: "archiving" } })
|
|
31714
32144
|
);
|
|
31715
32145
|
try {
|
|
31716
32146
|
await run();
|
|
31717
32147
|
} finally {
|
|
31718
32148
|
unmount();
|
|
31719
32149
|
}
|
|
31720
|
-
render12(/* @__PURE__ */
|
|
32150
|
+
render12(/* @__PURE__ */ jsx13(ArchiveUI, { state: { type: "success" } })).unmount();
|
|
31721
32151
|
}
|
|
31722
32152
|
|
|
31723
32153
|
// src/commands/learnings/list.tsx
|
|
31724
|
-
import { Spinner as
|
|
31725
|
-
import { Box as
|
|
31726
|
-
import { jsx as
|
|
32154
|
+
import { Spinner as Spinner11 } from "@inkjs/ui";
|
|
32155
|
+
import { Box as Box14, render as render13, Text as Text14 } from "ink";
|
|
32156
|
+
import { jsx as jsx14, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
31727
32157
|
var feedbackLabels = {
|
|
31728
32158
|
"incorrect-term": "Incorrect term",
|
|
31729
32159
|
"wrong-tone": "Wrong tone",
|
|
@@ -31733,47 +32163,47 @@ var feedbackLabels = {
|
|
|
31733
32163
|
};
|
|
31734
32164
|
function LearningsListUI({ state }) {
|
|
31735
32165
|
if (state.type === "loading") {
|
|
31736
|
-
return /* @__PURE__ */
|
|
31737
|
-
/* @__PURE__ */
|
|
31738
|
-
/* @__PURE__ */
|
|
32166
|
+
return /* @__PURE__ */ jsxs14(Box14, { children: [
|
|
32167
|
+
/* @__PURE__ */ jsx14(Spinner11, {}),
|
|
32168
|
+
/* @__PURE__ */ jsx14(Text14, { children: " Loading learnings\u2026" })
|
|
31739
32169
|
] });
|
|
31740
32170
|
}
|
|
31741
32171
|
const { learnings } = state;
|
|
31742
32172
|
if (learnings.length === 0) {
|
|
31743
|
-
return /* @__PURE__ */
|
|
32173
|
+
return /* @__PURE__ */ jsx14(Box14, { children: /* @__PURE__ */ jsx14(Text14, { dimColor: true, children: "No learnings found." }) });
|
|
31744
32174
|
}
|
|
31745
|
-
return /* @__PURE__ */
|
|
31746
|
-
/* @__PURE__ */
|
|
32175
|
+
return /* @__PURE__ */ jsxs14(Box14, { flexDirection: "column", children: [
|
|
32176
|
+
/* @__PURE__ */ jsx14(Box14, { marginBottom: 1, children: /* @__PURE__ */ jsxs14(Text14, { bold: true, children: [
|
|
31747
32177
|
learnings.length,
|
|
31748
32178
|
" learning",
|
|
31749
32179
|
learnings.length === 1 ? "" : "s"
|
|
31750
32180
|
] }) }),
|
|
31751
|
-
learnings.map((l) => /* @__PURE__ */
|
|
31752
|
-
/* @__PURE__ */
|
|
31753
|
-
/* @__PURE__ */
|
|
32181
|
+
learnings.map((l) => /* @__PURE__ */ jsxs14(Box14, { flexDirection: "column", marginBottom: 1, children: [
|
|
32182
|
+
/* @__PURE__ */ jsxs14(Box14, { gap: 1, children: [
|
|
32183
|
+
/* @__PURE__ */ jsxs14(Text14, { bold: true, children: [
|
|
31754
32184
|
l.srcLocale,
|
|
31755
32185
|
" \u2192 ",
|
|
31756
32186
|
l.dstLocale
|
|
31757
32187
|
] }),
|
|
31758
|
-
/* @__PURE__ */
|
|
32188
|
+
/* @__PURE__ */ jsxs14(Text14, { dimColor: true, children: [
|
|
31759
32189
|
"[",
|
|
31760
32190
|
feedbackLabels[l.feedbackType] ?? l.feedbackType,
|
|
31761
32191
|
"]"
|
|
31762
32192
|
] }),
|
|
31763
|
-
l.status === "archived" && /* @__PURE__ */
|
|
32193
|
+
l.status === "archived" && /* @__PURE__ */ jsx14(Text14, { color: "yellow", children: "[archived]" })
|
|
31764
32194
|
] }),
|
|
31765
|
-
/* @__PURE__ */
|
|
32195
|
+
/* @__PURE__ */ jsx14(Box14, { paddingLeft: 2, children: /* @__PURE__ */ jsxs14(Text14, { children: [
|
|
31766
32196
|
'"',
|
|
31767
32197
|
l.sourceText,
|
|
31768
32198
|
'" \u2192 "',
|
|
31769
32199
|
l.suggestedTranslation,
|
|
31770
32200
|
'"'
|
|
31771
32201
|
] }) }),
|
|
31772
|
-
l.reasoning && /* @__PURE__ */
|
|
32202
|
+
l.reasoning && /* @__PURE__ */ jsx14(Box14, { paddingLeft: 2, children: /* @__PURE__ */ jsxs14(Text14, { dimColor: true, children: [
|
|
31773
32203
|
"Reason: ",
|
|
31774
32204
|
l.reasoning
|
|
31775
32205
|
] }) }),
|
|
31776
|
-
/* @__PURE__ */
|
|
32206
|
+
/* @__PURE__ */ jsx14(Box14, { paddingLeft: 2, children: /* @__PURE__ */ jsxs14(Text14, { dimColor: true, children: [
|
|
31777
32207
|
"ID: ",
|
|
31778
32208
|
l._id
|
|
31779
32209
|
] }) })
|
|
@@ -31808,7 +32238,7 @@ async function runLearningsList(opts) {
|
|
|
31808
32238
|
});
|
|
31809
32239
|
}
|
|
31810
32240
|
const { unmount } = renderTransient(
|
|
31811
|
-
/* @__PURE__ */
|
|
32241
|
+
/* @__PURE__ */ jsx14(LearningsListUI, { state: { type: "loading" } })
|
|
31812
32242
|
);
|
|
31813
32243
|
let learnings;
|
|
31814
32244
|
try {
|
|
@@ -31817,24 +32247,24 @@ async function runLearningsList(opts) {
|
|
|
31817
32247
|
unmount();
|
|
31818
32248
|
}
|
|
31819
32249
|
render13(
|
|
31820
|
-
/* @__PURE__ */
|
|
32250
|
+
/* @__PURE__ */ jsx14(LearningsListUI, { state: { type: "success", learnings } })
|
|
31821
32251
|
).unmount();
|
|
31822
32252
|
}
|
|
31823
32253
|
|
|
31824
32254
|
// src/commands/learnings/remove.tsx
|
|
31825
|
-
import { Spinner as
|
|
31826
|
-
import { Box as
|
|
31827
|
-
import { jsx as
|
|
32255
|
+
import { Spinner as Spinner12 } from "@inkjs/ui";
|
|
32256
|
+
import { Box as Box15, render as render14, Text as Text15 } from "ink";
|
|
32257
|
+
import { jsx as jsx15, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
31828
32258
|
function RemoveUI2({ state }) {
|
|
31829
32259
|
if (state.type === "removing") {
|
|
31830
|
-
return /* @__PURE__ */
|
|
31831
|
-
/* @__PURE__ */
|
|
31832
|
-
/* @__PURE__ */
|
|
32260
|
+
return /* @__PURE__ */ jsxs15(Box15, { children: [
|
|
32261
|
+
/* @__PURE__ */ jsx15(Spinner12, {}),
|
|
32262
|
+
/* @__PURE__ */ jsx15(Text15, { children: " Removing learning\u2026" })
|
|
31833
32263
|
] });
|
|
31834
32264
|
}
|
|
31835
|
-
return /* @__PURE__ */
|
|
31836
|
-
/* @__PURE__ */
|
|
31837
|
-
/* @__PURE__ */
|
|
32265
|
+
return /* @__PURE__ */ jsxs15(Box15, { children: [
|
|
32266
|
+
/* @__PURE__ */ jsx15(Text15, { color: "green", children: "\u2713" }),
|
|
32267
|
+
/* @__PURE__ */ jsx15(Text15, { children: " Learning removed" })
|
|
31838
32268
|
] });
|
|
31839
32269
|
}
|
|
31840
32270
|
async function runLearningsRemove(opts) {
|
|
@@ -31851,62 +32281,62 @@ async function runLearningsRemove(opts) {
|
|
|
31851
32281
|
jsonSuccess({ id: opts.id, ok: true });
|
|
31852
32282
|
}
|
|
31853
32283
|
const { unmount } = renderTransient(
|
|
31854
|
-
/* @__PURE__ */
|
|
32284
|
+
/* @__PURE__ */ jsx15(RemoveUI2, { state: { type: "removing" } })
|
|
31855
32285
|
);
|
|
31856
32286
|
try {
|
|
31857
32287
|
await run();
|
|
31858
32288
|
} finally {
|
|
31859
32289
|
unmount();
|
|
31860
32290
|
}
|
|
31861
|
-
render14(/* @__PURE__ */
|
|
32291
|
+
render14(/* @__PURE__ */ jsx15(RemoveUI2, { state: { type: "success" } })).unmount();
|
|
31862
32292
|
}
|
|
31863
32293
|
|
|
31864
32294
|
// src/commands/learnings/show.tsx
|
|
31865
|
-
import { Spinner as
|
|
31866
|
-
import { Box as
|
|
31867
|
-
import { jsx as
|
|
32295
|
+
import { Spinner as Spinner13 } from "@inkjs/ui";
|
|
32296
|
+
import { Box as Box16, render as render15, Text as Text16 } from "ink";
|
|
32297
|
+
import { jsx as jsx16, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
31868
32298
|
function LearningShowUI({ state }) {
|
|
31869
32299
|
if (state.type === "loading") {
|
|
31870
|
-
return /* @__PURE__ */
|
|
31871
|
-
/* @__PURE__ */
|
|
31872
|
-
/* @__PURE__ */
|
|
32300
|
+
return /* @__PURE__ */ jsxs16(Box16, { children: [
|
|
32301
|
+
/* @__PURE__ */ jsx16(Spinner13, {}),
|
|
32302
|
+
/* @__PURE__ */ jsx16(Text16, { children: " Loading learning\u2026" })
|
|
31873
32303
|
] });
|
|
31874
32304
|
}
|
|
31875
32305
|
const { learning } = state;
|
|
31876
|
-
return /* @__PURE__ */
|
|
31877
|
-
/* @__PURE__ */
|
|
31878
|
-
/* @__PURE__ */
|
|
31879
|
-
/* @__PURE__ */
|
|
32306
|
+
return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", children: [
|
|
32307
|
+
/* @__PURE__ */ jsxs16(Box16, { gap: 1, children: [
|
|
32308
|
+
/* @__PURE__ */ jsx16(Text16, { bold: true, children: "Source text:" }),
|
|
32309
|
+
/* @__PURE__ */ jsx16(Text16, { children: learning.sourceText })
|
|
31880
32310
|
] }),
|
|
31881
|
-
/* @__PURE__ */
|
|
31882
|
-
/* @__PURE__ */
|
|
31883
|
-
/* @__PURE__ */
|
|
32311
|
+
/* @__PURE__ */ jsxs16(Box16, { gap: 1, children: [
|
|
32312
|
+
/* @__PURE__ */ jsx16(Text16, { bold: true, children: "Suggested translation:" }),
|
|
32313
|
+
/* @__PURE__ */ jsx16(Text16, { children: learning.suggestedTranslation })
|
|
31884
32314
|
] }),
|
|
31885
|
-
/* @__PURE__ */
|
|
31886
|
-
/* @__PURE__ */
|
|
31887
|
-
/* @__PURE__ */
|
|
32315
|
+
/* @__PURE__ */ jsxs16(Box16, { gap: 1, children: [
|
|
32316
|
+
/* @__PURE__ */ jsx16(Text16, { bold: true, children: "Locales:" }),
|
|
32317
|
+
/* @__PURE__ */ jsxs16(Text16, { children: [
|
|
31888
32318
|
learning.srcLocale,
|
|
31889
32319
|
" \u2192 ",
|
|
31890
32320
|
learning.dstLocale
|
|
31891
32321
|
] })
|
|
31892
32322
|
] }),
|
|
31893
|
-
/* @__PURE__ */
|
|
31894
|
-
/* @__PURE__ */
|
|
31895
|
-
/* @__PURE__ */
|
|
32323
|
+
/* @__PURE__ */ jsxs16(Box16, { gap: 1, children: [
|
|
32324
|
+
/* @__PURE__ */ jsx16(Text16, { bold: true, children: "Feedback type:" }),
|
|
32325
|
+
/* @__PURE__ */ jsx16(Text16, { children: learning.feedbackType })
|
|
31896
32326
|
] }),
|
|
31897
|
-
/* @__PURE__ */
|
|
31898
|
-
/* @__PURE__ */
|
|
31899
|
-
/* @__PURE__ */
|
|
32327
|
+
/* @__PURE__ */ jsxs16(Box16, { gap: 1, children: [
|
|
32328
|
+
/* @__PURE__ */ jsx16(Text16, { bold: true, children: "Reasoning:" }),
|
|
32329
|
+
/* @__PURE__ */ jsx16(Text16, { children: learning.reasoning })
|
|
31900
32330
|
] }),
|
|
31901
|
-
/* @__PURE__ */
|
|
31902
|
-
/* @__PURE__ */
|
|
31903
|
-
/* @__PURE__ */
|
|
32331
|
+
/* @__PURE__ */ jsxs16(Box16, { gap: 1, children: [
|
|
32332
|
+
/* @__PURE__ */ jsx16(Text16, { bold: true, children: "Status:" }),
|
|
32333
|
+
/* @__PURE__ */ jsx16(Text16, { color: learning.status === "active" ? "green" : "yellow", children: learning.status })
|
|
31904
32334
|
] }),
|
|
31905
|
-
/* @__PURE__ */
|
|
31906
|
-
/* @__PURE__ */
|
|
31907
|
-
/* @__PURE__ */
|
|
32335
|
+
/* @__PURE__ */ jsxs16(Box16, { gap: 1, children: [
|
|
32336
|
+
/* @__PURE__ */ jsx16(Text16, { bold: true, children: "Source:" }),
|
|
32337
|
+
/* @__PURE__ */ jsx16(Text16, { children: learning.source })
|
|
31908
32338
|
] }),
|
|
31909
|
-
/* @__PURE__ */
|
|
32339
|
+
/* @__PURE__ */ jsx16(Box16, { marginTop: 1, children: /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
|
|
31910
32340
|
"ID: ",
|
|
31911
32341
|
learning._id
|
|
31912
32342
|
] }) })
|
|
@@ -31944,7 +32374,7 @@ async function runLearningsShow(opts) {
|
|
|
31944
32374
|
});
|
|
31945
32375
|
}
|
|
31946
32376
|
const { unmount } = renderTransient(
|
|
31947
|
-
/* @__PURE__ */
|
|
32377
|
+
/* @__PURE__ */ jsx16(LearningShowUI, { state: { type: "loading" } })
|
|
31948
32378
|
);
|
|
31949
32379
|
let learning;
|
|
31950
32380
|
try {
|
|
@@ -31952,54 +32382,54 @@ async function runLearningsShow(opts) {
|
|
|
31952
32382
|
} finally {
|
|
31953
32383
|
unmount();
|
|
31954
32384
|
}
|
|
31955
|
-
render15(/* @__PURE__ */
|
|
32385
|
+
render15(/* @__PURE__ */ jsx16(LearningShowUI, { state: { type: "success", learning } })).unmount();
|
|
31956
32386
|
}
|
|
31957
32387
|
|
|
31958
32388
|
// src/commands/learnings/index.ts
|
|
31959
|
-
var learningsCommand = new
|
|
32389
|
+
var learningsCommand = new Command5("learnings").description(
|
|
31960
32390
|
"View and manage translation learnings"
|
|
31961
32391
|
);
|
|
31962
32392
|
learningsCommand.command("list").description("List translation learnings for the current project").option("--status <status>", "Filter by status (active or archived)").option("--limit <n>", "Max number of results", (v) => Number(v), 100).option("--json", "Output as JSON (machine-readable)").action(async (opts) => {
|
|
31963
|
-
const schema =
|
|
31964
|
-
status:
|
|
31965
|
-
limit:
|
|
31966
|
-
json:
|
|
32393
|
+
const schema = z7.object({
|
|
32394
|
+
status: z7.enum(["active", "archived"]).optional(),
|
|
32395
|
+
limit: z7.coerce.number().int().positive().default(100),
|
|
32396
|
+
json: z7.boolean().optional()
|
|
31967
32397
|
});
|
|
31968
32398
|
const parsed = validateOrExit(schema, opts);
|
|
31969
32399
|
await runLearningsList(parsed);
|
|
31970
32400
|
});
|
|
31971
32401
|
learningsCommand.command("show").description("Show details of a learning").requiredOption("--id <learningId>", "Learning ID").option("--json", "Output as JSON (machine-readable)").action(async (opts) => {
|
|
31972
|
-
const schema =
|
|
31973
|
-
id:
|
|
31974
|
-
json:
|
|
32402
|
+
const schema = z7.object({
|
|
32403
|
+
id: z7.string().min(1),
|
|
32404
|
+
json: z7.boolean().optional()
|
|
31975
32405
|
});
|
|
31976
32406
|
const parsed = validateOrExit(schema, opts);
|
|
31977
32407
|
await runLearningsShow(parsed);
|
|
31978
32408
|
});
|
|
31979
32409
|
learningsCommand.command("archive").description("Archive a learning (keeps it but excludes from translations)").requiredOption("--id <learningId>", "Learning ID").option("--json", "Output as JSON (machine-readable)").action(async (opts) => {
|
|
31980
|
-
const schema =
|
|
31981
|
-
id:
|
|
31982
|
-
json:
|
|
32410
|
+
const schema = z7.object({
|
|
32411
|
+
id: z7.string().min(1),
|
|
32412
|
+
json: z7.boolean().optional()
|
|
31983
32413
|
});
|
|
31984
32414
|
const parsed = validateOrExit(schema, opts);
|
|
31985
32415
|
await runLearningsArchive(parsed);
|
|
31986
32416
|
});
|
|
31987
32417
|
learningsCommand.command("remove").description("Permanently remove a learning").requiredOption("--id <learningId>", "Learning ID").option("--json", "Output as JSON (machine-readable)").action(async (opts) => {
|
|
31988
|
-
const schema =
|
|
31989
|
-
id:
|
|
31990
|
-
json:
|
|
32418
|
+
const schema = z7.object({
|
|
32419
|
+
id: z7.string().min(1),
|
|
32420
|
+
json: z7.boolean().optional()
|
|
31991
32421
|
});
|
|
31992
32422
|
const parsed = validateOrExit(schema, opts);
|
|
31993
32423
|
await runLearningsRemove(parsed);
|
|
31994
32424
|
});
|
|
31995
32425
|
|
|
31996
32426
|
// src/commands/status/index.ts
|
|
31997
|
-
import { Command as
|
|
31998
|
-
import { z as
|
|
32427
|
+
import { Command as Command6 } from "commander";
|
|
32428
|
+
import { z as z8 } from "zod/v4";
|
|
31999
32429
|
|
|
32000
32430
|
// src/commands/status/status.tsx
|
|
32001
|
-
import { Spinner as
|
|
32002
|
-
import { Box as
|
|
32431
|
+
import { Spinner as Spinner14 } from "@inkjs/ui";
|
|
32432
|
+
import { Box as Box17, Text as Text17 } from "ink";
|
|
32003
32433
|
|
|
32004
32434
|
// src/commands/status/status-core.ts
|
|
32005
32435
|
function fullKey4(namespace, key) {
|
|
@@ -32123,7 +32553,7 @@ function describeLanguage(language) {
|
|
|
32123
32553
|
}
|
|
32124
32554
|
|
|
32125
32555
|
// src/commands/status/status.tsx
|
|
32126
|
-
import { jsx as
|
|
32556
|
+
import { jsx as jsx17, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
32127
32557
|
var OFFLINE_HINT = "Without a login, 'tolkbot validate' checks the files on this machine.";
|
|
32128
32558
|
async function runStatus(opts) {
|
|
32129
32559
|
let ctx;
|
|
@@ -32143,9 +32573,9 @@ async function runStatus(opts) {
|
|
|
32143
32573
|
const srcLocale = project.baseLanguage;
|
|
32144
32574
|
const locales = project.targetLanguages;
|
|
32145
32575
|
const progress = renderTransient(
|
|
32146
|
-
/* @__PURE__ */
|
|
32147
|
-
/* @__PURE__ */
|
|
32148
|
-
/* @__PURE__ */
|
|
32576
|
+
/* @__PURE__ */ jsxs17(Box17, { children: [
|
|
32577
|
+
/* @__PURE__ */ jsx17(Spinner14, {}),
|
|
32578
|
+
/* @__PURE__ */ jsxs17(Text17, { children: [
|
|
32149
32579
|
" Reading the status of ",
|
|
32150
32580
|
project.name,
|
|
32151
32581
|
"\u2026"
|
|
@@ -32216,23 +32646,23 @@ async function runStatus(opts) {
|
|
|
32216
32646
|
}
|
|
32217
32647
|
|
|
32218
32648
|
// src/commands/status/index.ts
|
|
32219
|
-
var statusCommand = new
|
|
32649
|
+
var statusCommand = new Command6("status").description(
|
|
32220
32650
|
"Show what each language is missing, what waits for a person, the open pull requests and the credits left"
|
|
32221
32651
|
).option("--keys", "List the keys by name under each language").option(
|
|
32222
32652
|
"--exit-code",
|
|
32223
32653
|
"Exit 1 when any language has missing or changed keys"
|
|
32224
32654
|
).option("--json", "Output as JSON (machine-readable)").action(async (opts) => {
|
|
32225
|
-
const schema =
|
|
32226
|
-
keys:
|
|
32227
|
-
exitCode:
|
|
32228
|
-
json:
|
|
32655
|
+
const schema = z8.object({
|
|
32656
|
+
keys: z8.boolean().optional(),
|
|
32657
|
+
exitCode: z8.boolean().optional(),
|
|
32658
|
+
json: z8.boolean().optional()
|
|
32229
32659
|
});
|
|
32230
32660
|
await runStatus(validateOrExit(schema, opts));
|
|
32231
32661
|
});
|
|
32232
32662
|
|
|
32233
32663
|
// src/commands/telemetry.ts
|
|
32234
|
-
import { Command as
|
|
32235
|
-
import { z as
|
|
32664
|
+
import { Command as Command7 } from "commander";
|
|
32665
|
+
import { z as z9 } from "zod/v4";
|
|
32236
32666
|
var REASONS = {
|
|
32237
32667
|
env: `disabled by $${TELEMETRY_ENV_VAR}`,
|
|
32238
32668
|
"do-not-track": `disabled by $${DO_NOT_TRACK_ENV_VAR}`,
|
|
@@ -32253,12 +32683,12 @@ async function printStatus(json2) {
|
|
|
32253
32683
|
`Turn it off with \`tolkbot telemetry off\`, $${TELEMETRY_ENV_VAR}=0 or $${DO_NOT_TRACK_ENV_VAR}=1.`
|
|
32254
32684
|
);
|
|
32255
32685
|
}
|
|
32256
|
-
var telemetryCommand = new
|
|
32686
|
+
var telemetryCommand = new Command7("telemetry").description(
|
|
32257
32687
|
"Control anonymous usage reporting"
|
|
32258
32688
|
);
|
|
32259
32689
|
telemetryCommand.command("status", { isDefault: true }).description("Show whether telemetry is on and why").option("--json", "Output as JSON (machine-readable)").action(async (opts) => {
|
|
32260
32690
|
const parsed = validateOrExit(
|
|
32261
|
-
|
|
32691
|
+
z9.object({ json: z9.boolean().optional() }),
|
|
32262
32692
|
opts
|
|
32263
32693
|
);
|
|
32264
32694
|
await printStatus(parsed.json);
|
|
@@ -32275,8 +32705,8 @@ telemetryCommand.command("on").description("Resume reporting usage from this mac
|
|
|
32275
32705
|
});
|
|
32276
32706
|
|
|
32277
32707
|
// src/commands/translate/index.ts
|
|
32278
|
-
import { Command as
|
|
32279
|
-
import { z as
|
|
32708
|
+
import { Command as Command8 } from "commander";
|
|
32709
|
+
import { z as z10 } from "zod/v4";
|
|
32280
32710
|
|
|
32281
32711
|
// src/commands/translate/adopt.tsx
|
|
32282
32712
|
var STAMP_CHUNK2 = 200;
|
|
@@ -32326,7 +32756,7 @@ async function runAdopt(opts) {
|
|
|
32326
32756
|
if (locales.length === 0) {
|
|
32327
32757
|
throw opts.all ? new CliError(
|
|
32328
32758
|
"No target languages configured for this project.",
|
|
32329
|
-
|
|
32759
|
+
"Add one with 'tolkbot languages add <code>'.",
|
|
32330
32760
|
"no_target_languages"
|
|
32331
32761
|
) : new UsageError(
|
|
32332
32762
|
"Either --dst <locale> or --all must be provided."
|
|
@@ -32357,8 +32787,8 @@ async function runAdopt(opts) {
|
|
|
32357
32787
|
|
|
32358
32788
|
// src/commands/translate/edit.tsx
|
|
32359
32789
|
import path10 from "path";
|
|
32360
|
-
import { Spinner as
|
|
32361
|
-
import { Box as
|
|
32790
|
+
import { Spinner as Spinner15 } from "@inkjs/ui";
|
|
32791
|
+
import { Box as Box18, render as render16, Text as Text18 } from "ink";
|
|
32362
32792
|
|
|
32363
32793
|
// src/utils/locale-files.ts
|
|
32364
32794
|
import path9 from "path";
|
|
@@ -32396,25 +32826,25 @@ function resolveKeyInFile(key, targetFile, fileCount, namespace) {
|
|
|
32396
32826
|
}
|
|
32397
32827
|
|
|
32398
32828
|
// src/commands/translate/edit.tsx
|
|
32399
|
-
import { jsx as
|
|
32829
|
+
import { jsx as jsx18, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
32400
32830
|
function EditUI({ state }) {
|
|
32401
32831
|
if (state.type === "editing") {
|
|
32402
|
-
return /* @__PURE__ */
|
|
32403
|
-
/* @__PURE__ */
|
|
32404
|
-
/* @__PURE__ */
|
|
32832
|
+
return /* @__PURE__ */ jsxs18(Box18, { children: [
|
|
32833
|
+
/* @__PURE__ */ jsx18(Spinner15, {}),
|
|
32834
|
+
/* @__PURE__ */ jsx18(Text18, { children: " Editing translation\u2026" })
|
|
32405
32835
|
] });
|
|
32406
32836
|
}
|
|
32407
|
-
return /* @__PURE__ */
|
|
32408
|
-
/* @__PURE__ */
|
|
32409
|
-
/* @__PURE__ */
|
|
32410
|
-
/* @__PURE__ */
|
|
32837
|
+
return /* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", children: [
|
|
32838
|
+
/* @__PURE__ */ jsxs18(Box18, { children: [
|
|
32839
|
+
/* @__PURE__ */ jsx18(Text18, { color: "green", children: "\u2713" }),
|
|
32840
|
+
/* @__PURE__ */ jsxs18(Text18, { children: [
|
|
32411
32841
|
" ",
|
|
32412
32842
|
"Updated ",
|
|
32413
|
-
/* @__PURE__ */
|
|
32843
|
+
/* @__PURE__ */ jsx18(Text18, { bold: true, children: state.key })
|
|
32414
32844
|
] })
|
|
32415
32845
|
] }),
|
|
32416
|
-
/* @__PURE__ */
|
|
32417
|
-
/* @__PURE__ */
|
|
32846
|
+
/* @__PURE__ */ jsx18(Box18, { paddingLeft: 2, children: /* @__PURE__ */ jsx18(Text18, { dimColor: true, children: state.value }) }),
|
|
32847
|
+
/* @__PURE__ */ jsx18(Box18, { marginTop: 1, children: /* @__PURE__ */ jsxs18(Text18, { dimColor: true, children: [
|
|
32418
32848
|
"File: ",
|
|
32419
32849
|
state.filePath
|
|
32420
32850
|
] }) })
|
|
@@ -32471,20 +32901,20 @@ async function runEdit(opts) {
|
|
|
32471
32901
|
value: result2.value
|
|
32472
32902
|
});
|
|
32473
32903
|
}
|
|
32474
|
-
const { unmount } = renderTransient(/* @__PURE__ */
|
|
32904
|
+
const { unmount } = renderTransient(/* @__PURE__ */ jsx18(EditUI, { state: { type: "editing" } }));
|
|
32475
32905
|
let result;
|
|
32476
32906
|
try {
|
|
32477
32907
|
result = await performEdit(opts);
|
|
32478
32908
|
} finally {
|
|
32479
32909
|
unmount();
|
|
32480
32910
|
}
|
|
32481
|
-
render16(/* @__PURE__ */
|
|
32911
|
+
render16(/* @__PURE__ */ jsx18(EditUI, { state: { type: "success", ...result } })).unmount();
|
|
32482
32912
|
}
|
|
32483
32913
|
|
|
32484
32914
|
// src/commands/translate/translate.tsx
|
|
32485
|
-
import { Spinner as
|
|
32486
|
-
import { Box as
|
|
32487
|
-
import { jsx as
|
|
32915
|
+
import { Spinner as Spinner16 } from "@inkjs/ui";
|
|
32916
|
+
import { Box as Box19, Text as Text19 } from "ink";
|
|
32917
|
+
import { jsx as jsx19, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
32488
32918
|
function planOutput(plan) {
|
|
32489
32919
|
return {
|
|
32490
32920
|
...plan.summary,
|
|
@@ -32505,7 +32935,7 @@ function targetLocales(ctx, opts) {
|
|
|
32505
32935
|
if (locales.length === 0) {
|
|
32506
32936
|
throw new CliError(
|
|
32507
32937
|
"No target languages configured.",
|
|
32508
|
-
|
|
32938
|
+
"Add one with 'tolkbot languages add <code>'.",
|
|
32509
32939
|
"no_target_languages"
|
|
32510
32940
|
);
|
|
32511
32941
|
}
|
|
@@ -32525,7 +32955,7 @@ var NO_ESTIMATE = "No credit estimate exists for this project yet. Keys and char
|
|
|
32525
32955
|
async function runDryRun(ctx, srcLocale, dstLocales, opts) {
|
|
32526
32956
|
const languages = [];
|
|
32527
32957
|
const progress = renderTransient(
|
|
32528
|
-
/* @__PURE__ */
|
|
32958
|
+
/* @__PURE__ */ jsx19(Working, { text: `Planning ${dstLocales.join(", ")}\u2026` })
|
|
32529
32959
|
);
|
|
32530
32960
|
try {
|
|
32531
32961
|
for (const dstLocale of dstLocales) {
|
|
@@ -32603,9 +33033,9 @@ In all: ${total.keys} key(s), ${total.characters} characters.` + (balance === nu
|
|
|
32603
33033
|
console.log("Nothing was started. Run without --dry-run to translate.");
|
|
32604
33034
|
}
|
|
32605
33035
|
function Working({ text }) {
|
|
32606
|
-
return /* @__PURE__ */
|
|
32607
|
-
/* @__PURE__ */
|
|
32608
|
-
/* @__PURE__ */
|
|
33036
|
+
return /* @__PURE__ */ jsxs19(Box19, { children: [
|
|
33037
|
+
/* @__PURE__ */ jsx19(Spinner16, {}),
|
|
33038
|
+
/* @__PURE__ */ jsxs19(Text19, { children: [
|
|
32609
33039
|
" ",
|
|
32610
33040
|
text
|
|
32611
33041
|
] })
|
|
@@ -32616,7 +33046,7 @@ function progressText(dstLocale, summary) {
|
|
|
32616
33046
|
const done = summary.completed + summary.failed;
|
|
32617
33047
|
return `${dstLocale}: translating ${done}/${summary.total}\u2026`;
|
|
32618
33048
|
}
|
|
32619
|
-
function
|
|
33049
|
+
function describeOutcome2(outcome) {
|
|
32620
33050
|
const { dstLocale, status, keys, written } = outcome;
|
|
32621
33051
|
const wrote = written ? `, ${written.keys} written to ${written.files} file(s)` : "";
|
|
32622
33052
|
const notApplied = outcome.notApplied.length > 0 ? `, ${outcome.notApplied.length} not applied` : "";
|
|
@@ -32651,14 +33081,14 @@ async function runLanguages(ctx, srcLocale, dstLocales, opts) {
|
|
|
32651
33081
|
const report = (outcome) => {
|
|
32652
33082
|
outcomes.push(outcome);
|
|
32653
33083
|
if (json2) return;
|
|
32654
|
-
console.log(
|
|
33084
|
+
console.log(describeOutcome2(outcome));
|
|
32655
33085
|
for (const line of describeNotApplied(outcome.notApplied)) {
|
|
32656
33086
|
console.log(` ${line}`);
|
|
32657
33087
|
}
|
|
32658
33088
|
};
|
|
32659
33089
|
for (const dstLocale of dstLocales) {
|
|
32660
33090
|
const progress = renderTransient(
|
|
32661
|
-
/* @__PURE__ */
|
|
33091
|
+
/* @__PURE__ */ jsx19(Working, { text: `${dstLocale}: planning\u2026` })
|
|
32662
33092
|
);
|
|
32663
33093
|
try {
|
|
32664
33094
|
const { tasks, plan } = await generateTasks(
|
|
@@ -32691,7 +33121,7 @@ async function runLanguages(ctx, srcLocale, dstLocales, opts) {
|
|
|
32691
33121
|
printNotes(json2, leftOut);
|
|
32692
33122
|
continue;
|
|
32693
33123
|
}
|
|
32694
|
-
progress.rerender(/* @__PURE__ */
|
|
33124
|
+
progress.rerender(/* @__PURE__ */ jsx19(Working, { text: progressText(dstLocale, null) }));
|
|
32695
33125
|
let jobId;
|
|
32696
33126
|
try {
|
|
32697
33127
|
jobId = await startTranslationJob({
|
|
@@ -32728,7 +33158,7 @@ async function runLanguages(ctx, srcLocale, dstLocales, opts) {
|
|
|
32728
33158
|
project.organizationId,
|
|
32729
33159
|
jobId,
|
|
32730
33160
|
(latest) => progress.rerender(
|
|
32731
|
-
/* @__PURE__ */
|
|
33161
|
+
/* @__PURE__ */ jsx19(Working, { text: progressText(dstLocale, latest) })
|
|
32732
33162
|
)
|
|
32733
33163
|
);
|
|
32734
33164
|
} catch (error62) {
|
|
@@ -32753,7 +33183,7 @@ async function runLanguages(ctx, srcLocale, dstLocales, opts) {
|
|
|
32753
33183
|
};
|
|
32754
33184
|
if (summary.status !== "cancelled") {
|
|
32755
33185
|
progress.rerender(
|
|
32756
|
-
/* @__PURE__ */
|
|
33186
|
+
/* @__PURE__ */ jsx19(Working, { text: `${dstLocale}: writing the files\u2026` })
|
|
32757
33187
|
);
|
|
32758
33188
|
const applied = await applyJob(ctx, jobId);
|
|
32759
33189
|
finished.written = { files: applied.files, keys: applied.keys };
|
|
@@ -32817,7 +33247,7 @@ function checkTranslateOptions(opts) {
|
|
|
32817
33247
|
|
|
32818
33248
|
// src/commands/translate/index.ts
|
|
32819
33249
|
var RETRANSLATE_UNTRACKED_HELP = "Also retranslate translations TolkBot has no record of (kept by default)";
|
|
32820
|
-
var
|
|
33250
|
+
var translateCommand2 = new Command8("translate").description(
|
|
32821
33251
|
"Translate what is missing or changed, and write the results into your locale files"
|
|
32822
33252
|
).option(
|
|
32823
33253
|
"--src <locale>",
|
|
@@ -32833,31 +33263,31 @@ var translateCommand = new Command7("translate").description(
|
|
|
32833
33263
|
"Run 'tolkbot translate --help'. Jobs are under 'tolkbot jobs'."
|
|
32834
33264
|
);
|
|
32835
33265
|
}
|
|
32836
|
-
const schema =
|
|
32837
|
-
src:
|
|
32838
|
-
dst:
|
|
32839
|
-
all:
|
|
32840
|
-
dryRun:
|
|
32841
|
-
wait:
|
|
32842
|
-
retranslateUntracked:
|
|
32843
|
-
verbose:
|
|
32844
|
-
json:
|
|
33266
|
+
const schema = z10.object({
|
|
33267
|
+
src: z10.string().min(1).optional(),
|
|
33268
|
+
dst: z10.string().min(1).optional(),
|
|
33269
|
+
all: z10.boolean().optional(),
|
|
33270
|
+
dryRun: z10.boolean().optional(),
|
|
33271
|
+
wait: z10.boolean(),
|
|
33272
|
+
retranslateUntracked: z10.boolean().optional(),
|
|
33273
|
+
verbose: z10.boolean().optional(),
|
|
33274
|
+
json: z10.boolean().optional()
|
|
32845
33275
|
});
|
|
32846
33276
|
const parsed = validateOrExit(schema, opts);
|
|
32847
33277
|
checkTranslateOptions(parsed);
|
|
32848
33278
|
await runTranslate(parsed);
|
|
32849
33279
|
});
|
|
32850
|
-
|
|
33280
|
+
translateCommand2.command("adopt").description(
|
|
32851
33281
|
"Record existing translations TolkBot has no baseline for as reviewed, so they are kept until their source changes"
|
|
32852
33282
|
).option(
|
|
32853
33283
|
"--src <locale>",
|
|
32854
33284
|
"Source locale (defaults to the project's base language)"
|
|
32855
33285
|
).option("--dst <locale>", "Destination locale").option("--all", "Every target language").option("--json", "Output as JSON (machine-readable)").action(async (opts) => {
|
|
32856
|
-
const schema =
|
|
32857
|
-
src:
|
|
32858
|
-
dst:
|
|
32859
|
-
all:
|
|
32860
|
-
json:
|
|
33286
|
+
const schema = z10.object({
|
|
33287
|
+
src: z10.string().min(1).optional(),
|
|
33288
|
+
dst: z10.string().min(1).optional(),
|
|
33289
|
+
all: z10.boolean().optional(),
|
|
33290
|
+
json: z10.boolean().optional()
|
|
32861
33291
|
});
|
|
32862
33292
|
const parsed = validateOrExit(schema, opts);
|
|
32863
33293
|
if (parsed.dst && parsed.all) {
|
|
@@ -32865,20 +33295,20 @@ translateCommand.command("adopt").description(
|
|
|
32865
33295
|
}
|
|
32866
33296
|
await runAdopt(parsed);
|
|
32867
33297
|
});
|
|
32868
|
-
|
|
32869
|
-
const schema =
|
|
32870
|
-
key:
|
|
32871
|
-
locale:
|
|
32872
|
-
value:
|
|
32873
|
-
namespace:
|
|
32874
|
-
json:
|
|
33298
|
+
translateCommand2.command("edit").description("Edit a translation value in a locale file").requiredOption("--key <key>", "Translation key (e.g. common.hello)").requiredOption("--locale <locale>", "Target locale (e.g. fr, de)").requiredOption("--value <text>", "New translation value").option("--namespace <ns>", "Namespace to resolve file (if ambiguous)").option("--json", "Output as JSON (machine-readable)").action(async (opts) => {
|
|
33299
|
+
const schema = z10.object({
|
|
33300
|
+
key: z10.string().min(1),
|
|
33301
|
+
locale: z10.string().min(1),
|
|
33302
|
+
value: z10.string().min(1),
|
|
33303
|
+
namespace: z10.string().optional(),
|
|
33304
|
+
json: z10.boolean().optional()
|
|
32875
33305
|
});
|
|
32876
33306
|
const parsed = validateOrExit(schema, opts);
|
|
32877
33307
|
await runEdit(parsed);
|
|
32878
33308
|
});
|
|
32879
33309
|
|
|
32880
33310
|
// src/commands/validate.tsx
|
|
32881
|
-
import { Box as
|
|
33311
|
+
import { Box as Box20, render as render17, Text as Text20 } from "ink";
|
|
32882
33312
|
|
|
32883
33313
|
// ../ai/src/validators/placeholders.ts
|
|
32884
33314
|
var IDENTIFIER = /^[A-Za-z0-9_$][A-Za-z0-9_$.[\]-]*$/;
|
|
@@ -33971,7 +34401,7 @@ function finalize2(issues, stats, strict) {
|
|
|
33971
34401
|
}
|
|
33972
34402
|
|
|
33973
34403
|
// src/commands/validate.tsx
|
|
33974
|
-
import { jsx as
|
|
34404
|
+
import { jsx as jsx20, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
33975
34405
|
var LEVEL_COLOR = {
|
|
33976
34406
|
error: "red",
|
|
33977
34407
|
warning: "yellow",
|
|
@@ -33980,12 +34410,12 @@ var LEVEL_COLOR = {
|
|
|
33980
34410
|
var GUTTER = 9;
|
|
33981
34411
|
function IssueLine({ issue: issue2 }) {
|
|
33982
34412
|
const location = [issue2.file, issue2.key].filter(Boolean).join(" \xB7 ");
|
|
33983
|
-
return /* @__PURE__ */
|
|
33984
|
-
/* @__PURE__ */
|
|
33985
|
-
/* @__PURE__ */
|
|
33986
|
-
/* @__PURE__ */
|
|
34413
|
+
return /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", children: [
|
|
34414
|
+
/* @__PURE__ */ jsxs20(Box20, { children: [
|
|
34415
|
+
/* @__PURE__ */ jsx20(Box20, { width: GUTTER, flexShrink: 0, children: /* @__PURE__ */ jsx20(Text20, { color: LEVEL_COLOR[issue2.level], children: issue2.level }) }),
|
|
34416
|
+
/* @__PURE__ */ jsx20(Box20, { flexGrow: 1, children: /* @__PURE__ */ jsx20(Text20, { children: issue2.message }) })
|
|
33987
34417
|
] }),
|
|
33988
|
-
/* @__PURE__ */
|
|
34418
|
+
/* @__PURE__ */ jsx20(Box20, { marginLeft: GUTTER, children: /* @__PURE__ */ jsxs20(Text20, { dimColor: true, children: [
|
|
33989
34419
|
issue2.rule,
|
|
33990
34420
|
location ? ` \u2014 ${location}` : ""
|
|
33991
34421
|
] }) })
|
|
@@ -33994,20 +34424,20 @@ function IssueLine({ issue: issue2 }) {
|
|
|
33994
34424
|
function ReportUI({ report }) {
|
|
33995
34425
|
const { counts, stats } = report;
|
|
33996
34426
|
const summary = ["error", "warning", "info"].filter((level) => counts[level] > 0).map((level) => `${counts[level]} ${level}(s)`).join(", ");
|
|
33997
|
-
return /* @__PURE__ */
|
|
33998
|
-
/* @__PURE__ */
|
|
33999
|
-
/* @__PURE__ */
|
|
34000
|
-
/* @__PURE__ */
|
|
34427
|
+
return /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", children: [
|
|
34428
|
+
/* @__PURE__ */ jsxs20(Box20, { children: [
|
|
34429
|
+
/* @__PURE__ */ jsx20(Text20, { color: report.valid ? "green" : "red", children: report.valid ? "\u2713" : "\u2717" }),
|
|
34430
|
+
/* @__PURE__ */ jsxs20(Text20, { children: [
|
|
34001
34431
|
" Validation ",
|
|
34002
34432
|
report.valid ? "passed" : "failed"
|
|
34003
34433
|
] }),
|
|
34004
|
-
summary ? /* @__PURE__ */
|
|
34434
|
+
summary ? /* @__PURE__ */ jsxs20(Text20, { dimColor: true, children: [
|
|
34005
34435
|
" \u2014 ",
|
|
34006
34436
|
summary
|
|
34007
34437
|
] }) : null
|
|
34008
34438
|
] }),
|
|
34009
|
-
stats.locales.length > 0 && /* @__PURE__ */
|
|
34010
|
-
/* @__PURE__ */
|
|
34439
|
+
stats.locales.length > 0 && /* @__PURE__ */ jsxs20(Box20, { marginTop: 1, flexDirection: "column", children: [
|
|
34440
|
+
/* @__PURE__ */ jsxs20(Text20, { dimColor: true, children: [
|
|
34011
34441
|
stats.filesChecked,
|
|
34012
34442
|
" ",
|
|
34013
34443
|
stats.format,
|
|
@@ -34016,18 +34446,18 @@ function ReportUI({ report }) {
|
|
|
34016
34446
|
stats.totalKeys,
|
|
34017
34447
|
" keys"
|
|
34018
34448
|
] }),
|
|
34019
|
-
/* @__PURE__ */
|
|
34449
|
+
/* @__PURE__ */ jsxs20(Text20, { dimColor: true, children: [
|
|
34020
34450
|
"Locales: ",
|
|
34021
34451
|
stats.locales.join(", "),
|
|
34022
34452
|
stats.baseLocale ? ` (base: ${stats.baseLocale})` : ""
|
|
34023
34453
|
] }),
|
|
34024
|
-
stats.pattern && /* @__PURE__ */
|
|
34454
|
+
stats.pattern && /* @__PURE__ */ jsxs20(Text20, { dimColor: true, children: [
|
|
34025
34455
|
"Pattern: ",
|
|
34026
34456
|
stats.pattern
|
|
34027
34457
|
] })
|
|
34028
34458
|
] }),
|
|
34029
|
-
report.issues.length > 0 && /* @__PURE__ */
|
|
34030
|
-
!report.strict && counts.warning > 0 && report.valid && /* @__PURE__ */
|
|
34459
|
+
report.issues.length > 0 && /* @__PURE__ */ jsx20(Box20, { marginTop: 1, flexDirection: "column", gap: 1, children: report.issues.map((issue2, idx) => /* @__PURE__ */ jsx20(IssueLine, { issue: issue2 }, idx)) }),
|
|
34460
|
+
!report.strict && counts.warning > 0 && report.valid && /* @__PURE__ */ jsx20(Box20, { marginTop: 1, children: /* @__PURE__ */ jsx20(Text20, { dimColor: true, children: "Warnings did not fail this run. Use --strict to treat them as errors." }) })
|
|
34031
34461
|
] });
|
|
34032
34462
|
}
|
|
34033
34463
|
function emit(report, json2) {
|
|
@@ -34047,7 +34477,7 @@ function emit(report, json2) {
|
|
|
34047
34477
|
if (!report.valid) fail(validationFailure(report));
|
|
34048
34478
|
return;
|
|
34049
34479
|
}
|
|
34050
|
-
render17(/* @__PURE__ */
|
|
34480
|
+
render17(/* @__PURE__ */ jsx20(ReportUI, { report })).unmount();
|
|
34051
34481
|
process.exitCode = exitCode;
|
|
34052
34482
|
}
|
|
34053
34483
|
function validationFailure(report) {
|
|
@@ -34106,7 +34536,7 @@ function commandPath(command) {
|
|
|
34106
34536
|
return names.join(" ");
|
|
34107
34537
|
}
|
|
34108
34538
|
function buildProgram() {
|
|
34109
|
-
const program = new
|
|
34539
|
+
const program = new Command9().name("tolkbot").description("Localization workflow for your repo").version(version, "-v, --version", "Output the version number").helpOption("-h, --help", "Show help").helpCommand("help [command]", "Show help for a command").option("--token <token>", TOKEN_HELP).enablePositionalOptions();
|
|
34110
34540
|
program.hook("preAction", (_thisCommand, actionCommand) => {
|
|
34111
34541
|
const { token } = actionCommand.optsWithGlobals();
|
|
34112
34542
|
setTokenOverride(token);
|
|
@@ -34135,10 +34565,11 @@ function buildProgram() {
|
|
|
34135
34565
|
program.addCommand(authCommand);
|
|
34136
34566
|
program.addCommand(glossaryCommand);
|
|
34137
34567
|
program.addCommand(jobsCommand);
|
|
34568
|
+
program.addCommand(languagesCommand);
|
|
34138
34569
|
program.addCommand(learningsCommand);
|
|
34139
34570
|
program.addCommand(statusCommand);
|
|
34140
34571
|
program.addCommand(telemetryCommand);
|
|
34141
|
-
program.addCommand(
|
|
34572
|
+
program.addCommand(translateCommand2);
|
|
34142
34573
|
program.addHelpText("after", PROGRAM_HELP_FOOTER);
|
|
34143
34574
|
forEachCommand(program, (command) => {
|
|
34144
34575
|
if (command !== program) addTokenOption(command);
|
|
@@ -34154,7 +34585,7 @@ function forEachCommand(command, visit2) {
|
|
|
34154
34585
|
var TOKEN_HELP = `Auth token to use for this invocation (overrides $${TOKEN_ENV_VAR} and the stored token)`;
|
|
34155
34586
|
function addTokenOption(command) {
|
|
34156
34587
|
if (command.options.some((o) => o.long === "--token")) return;
|
|
34157
|
-
command.addOption(new
|
|
34588
|
+
command.addOption(new Option2("--token <token>", TOKEN_HELP).hideHelp());
|
|
34158
34589
|
}
|
|
34159
34590
|
function jsonOptionOf(command) {
|
|
34160
34591
|
return command.options.find((option) => option.long === "--json");
|
|
@@ -34195,6 +34626,7 @@ Examples:
|
|
|
34195
34626
|
$ tolkbot auth login
|
|
34196
34627
|
$ tolkbot init
|
|
34197
34628
|
$ tolkbot status
|
|
34629
|
+
$ tolkbot languages add nb
|
|
34198
34630
|
$ tolkbot translate --all
|
|
34199
34631
|
$ tolkbot translate --all --dry-run
|
|
34200
34632
|
$ tolkbot jobs list
|
package/package.json
CHANGED