@quaso-i18n/cli 1.0.0-rc.2 → 1.0.0-rc.2.main.g10f765b

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/quaso.mjs +71 -5
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quaso-i18n/cli",
3
- "version": "1.0.0-rc.2",
3
+ "version": "1.0.0-rc.2.main.g10f765b",
4
4
  "description": "The command line of Quaso, localization for i18next JSON files: upload, download, status and import, from a laptop, from CI and for AI agents",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/quaso.mjs CHANGED
@@ -1208,7 +1208,11 @@ var QuasoConfig = s.object({
1208
1208
  minItems: 1
1209
1209
  }),
1210
1210
  limits: s.array(LengthLimit).optional().describe("Maximum lengths, such as for app store fields (FMT-4). They win over limits set on the website."),
1211
- pluralExclusions: s.array(PluralExclusion).optional()
1211
+ pluralExclusions: s.array(PluralExclusion).optional(),
1212
+ untranslated: s.enum([
1213
+ "source",
1214
+ "omit"
1215
+ ]).optional().describe("What download writes for untranslated strings: the source text (default) or nothing, for apps that fall back to the source language themselves")
1212
1216
  });
1213
1217
 
1214
1218
  // packages/core/src/api.ts
@@ -1310,7 +1314,11 @@ var FileVersionQuery = s.object({
1310
1314
  var ExportQuery = s.object({
1311
1315
  languages: s.array(LanguageTag).optional(),
1312
1316
  files: s.array(FilePath).optional(),
1313
- at: PublicationTime.optional()
1317
+ at: PublicationTime.optional(),
1318
+ untranslated: s.enum([
1319
+ "source",
1320
+ "omit"
1321
+ ]).optional().describe("Untranslated entries as the English (default) or left out")
1314
1322
  });
1315
1323
  var ImportRequest = s.object({
1316
1324
  language: LanguageTag,
@@ -1323,6 +1331,7 @@ var ImportRequest = s.object({
1323
1331
  ]),
1324
1332
  overwrite: s.boolean().optional().describe("Also replace blue (proofread) translations"),
1325
1333
  keepIdentical: s.boolean().optional().describe("Keep values identical to the English"),
1334
+ allowQaErrors: s.boolean().optional().describe("Import values that fail the quality checks, flagged, instead of refusing them"),
1326
1335
  dryRun: s.boolean().optional()
1327
1336
  });
1328
1337
  var JobScope = s.object({
@@ -1332,6 +1341,7 @@ var JobScope = s.object({
1332
1341
  maxItems: 5e3
1333
1342
  }).optional().describe("Only these strings"),
1334
1343
  retranslate: s.boolean().optional().describe("Also re-translate green strings (never blue ones, LLM-4)"),
1344
+ qa: s.boolean().optional().describe("Also re-translate the green translations that fail the quality checks"),
1335
1345
  outdated: s.boolean().optional().describe("Update outdated green translations and propose updates for outdated blue ones (default true)"),
1336
1346
  instruction: s.string({
1337
1347
  maxLength: 4e3
@@ -1602,7 +1612,31 @@ var ProjectSettings = s.object({
1602
1612
  suffix: s.string({
1603
1613
  minLength: 1,
1604
1614
  maxLength: 10
1605
- })
1615
+ }),
1616
+ extra: s.array(s.object({
1617
+ prefix: s.string({
1618
+ minLength: 1,
1619
+ maxLength: 10
1620
+ }),
1621
+ suffix: s.string({
1622
+ minLength: 1,
1623
+ maxLength: 10
1624
+ })
1625
+ }), {
1626
+ maxItems: 10
1627
+ }).optional().describe("Delimiters of placeholders the app fills in itself, such as { and } for {name}"),
1628
+ optional: s.array(s.object({
1629
+ placeholder: s.string({
1630
+ minLength: 1,
1631
+ maxLength: 100
1632
+ }),
1633
+ languages: s.array(LanguageTag, {
1634
+ minItems: 1,
1635
+ maxItems: 200
1636
+ })
1637
+ }), {
1638
+ maxItems: 50
1639
+ }).optional().describe("Placeholders some languages may leave out, such as {article}")
1606
1640
  }),
1607
1641
  logoUrl: s.string({
1608
1642
  maxLength: 2e3
@@ -1767,7 +1801,7 @@ var ReviewLanguageRequestRequest = s.object({
1767
1801
  // package.json
1768
1802
  var package_default = {
1769
1803
  name: "quaso-workspace",
1770
- version: "1.0.0-rc.2",
1804
+ version: "1.0.0-rc.2.main.g10f765b",
1771
1805
  private: true,
1772
1806
  type: "module",
1773
1807
  license: "MIT",
@@ -7608,7 +7642,8 @@ var download = {
7608
7642
  query: {
7609
7643
  languages,
7610
7644
  files: askFiles ? wanted : void 0,
7611
- at
7645
+ at,
7646
+ untranslated: project.config.untranslated
7612
7647
  },
7613
7648
  timeoutMs: LONG_TIMEOUT_MS
7614
7649
  });
@@ -8006,6 +8041,11 @@ var importCommand = {
8006
8041
  type: "boolean",
8007
8042
  description: "Keep values identical to the English instead of skipping them"
8008
8043
  },
8044
+ {
8045
+ name: "allow-qa-errors",
8046
+ type: "boolean",
8047
+ description: "Import values that fail the quality checks, with their QA errors, instead of refusing them"
8048
+ },
8009
8049
  {
8010
8050
  name: "dry-run",
8011
8051
  type: "boolean",
@@ -8062,6 +8102,7 @@ var importCommand = {
8062
8102
  languages: [],
8063
8103
  withoutFiles: [],
8064
8104
  refused: [],
8105
+ flagged: [],
8065
8106
  unknownKeys: [],
8066
8107
  invalid: [],
8067
8108
  failed: []
@@ -8108,6 +8149,7 @@ var importCommand = {
8108
8149
  };
8109
8150
  if (flag(ctx.args, "overwrite")) request.overwrite = true;
8110
8151
  if (flag(ctx.args, "keep-identical")) request.keepIdentical = true;
8152
+ if (flag(ctx.args, "allow-qa-errors")) request.allowQaErrors = true;
8111
8153
  if (dryRun) request.dryRun = true;
8112
8154
  let result;
8113
8155
  try {
@@ -8149,6 +8191,17 @@ var importCommand = {
8149
8191
  });
8150
8192
  }
8151
8193
  }
8194
+ for (const flagged of result.flagged ?? []) {
8195
+ for (const check of errorChecks(flagged.checks)) {
8196
+ summary.flagged.push({
8197
+ file: pathOf(flagged.file),
8198
+ key: flagged.key,
8199
+ language: flagged.language,
8200
+ check: check.check,
8201
+ message: checkMessage(check)
8202
+ });
8203
+ }
8204
+ }
8152
8205
  for (const unknown of result.unknownKeys) {
8153
8206
  summary.unknownKeys.push({
8154
8207
  file: pathOf(unknown.file),
@@ -8220,8 +8273,14 @@ function renderImport(out, summary) {
8220
8273
  if (result.skippedIdentical > 0) {
8221
8274
  parts.push(`${result.skippedIdentical} identical to the English (skipped)`);
8222
8275
  }
8276
+ if (result.skippedEmpty > 0) parts.push(`${result.skippedEmpty} empty (skipped)`);
8277
+ if (result.droppedForms > 0) {
8278
+ parts.push(`${result.droppedForms} unused plural forms dropped`);
8279
+ }
8223
8280
  if (result.skippedBlue > 0) parts.push(`${result.skippedBlue} proofread kept`);
8224
8281
  if (result.refused.length > 0) parts.push(red(`${result.refused.length} refused`));
8282
+ const flagged = result.flagged ?? [];
8283
+ if (flagged.length > 0) parts.push(yellow(`${flagged.length} with QA errors`));
8225
8284
  if (result.unknownKeys.length > 0) parts.push(`${result.unknownKeys.length} unknown keys`);
8226
8285
  out.print(`${bold(result.language.padEnd(6))} ${parts.join(", ")}`);
8227
8286
  for (const file of result.unknownFiles) {
@@ -8246,6 +8305,7 @@ function renderImport(out, summary) {
8246
8305
  out.print(dim("The other languages were imported; import these again with --language."));
8247
8306
  }
8248
8307
  section("Refused by the quality checks", summary.refused);
8308
+ section("Imported with QA errors (fix them on the instance)", summary.flagged);
8249
8309
  section("Keys the English doesn't have", summary.unknownKeys);
8250
8310
  section("Files that can't be read (fix them and import again)", summary.invalid);
8251
8311
  if (summary.refused.length > 0 && !summary.dryRun) {
@@ -8279,6 +8339,11 @@ var translate = {
8279
8339
  type: "boolean",
8280
8340
  description: "Also translate green (not proofread) strings again; blue ones never change"
8281
8341
  },
8342
+ {
8343
+ name: "qa",
8344
+ type: "boolean",
8345
+ description: "Also translate again the green strings that fail the quality checks, such as imported ones"
8346
+ },
8282
8347
  {
8283
8348
  name: "instruction",
8284
8349
  type: "string",
@@ -8341,6 +8406,7 @@ var translate = {
8341
8406
  };
8342
8407
  if (files) request.files = files;
8343
8408
  if (flag(ctx.args, "retranslate")) request.retranslate = true;
8409
+ if (flag(ctx.args, "qa")) request.qa = true;
8344
8410
  const instruction = option(ctx.args, "instruction");
8345
8411
  if (instruction !== void 0 && instruction.trim() !== "") request.instruction = instruction;
8346
8412
  const model = option(ctx.args, "model");