@x18n/core 0.1.4 → 0.1.6

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.d.mts CHANGED
@@ -1340,6 +1340,13 @@ interface PromptOptions {
1340
1340
  readonly context?: boolean | undefined;
1341
1341
  /** Translate prompts: add stale translations (load history first). */
1342
1342
  readonly stale?: boolean | undefined;
1343
+ /** Translate prompts: add translations that checks report in the target locale, all of them (`true`) or of these check ids. */
1344
+ readonly check?: boolean | readonly string[] | undefined;
1345
+ }
1346
+ interface PromptIssue {
1347
+ /** Check id, for example `identical-to-source`. */
1348
+ readonly code: string;
1349
+ readonly message: string;
1343
1350
  }
1344
1351
  interface UsageContext {
1345
1352
  readonly path: string;
@@ -1354,6 +1361,8 @@ interface PromptItem {
1354
1361
  readonly existing: string | undefined;
1355
1362
  /** For a stale translation: the source value when the translation last changed, when known. */
1356
1363
  readonly previousSource?: string | undefined;
1364
+ /** With `check`: what the checks report for the current value. */
1365
+ readonly issues?: readonly PromptIssue[] | undefined;
1357
1366
  readonly context: readonly UsageContext[];
1358
1367
  }
1359
1368
  interface PromptData {
@@ -1780,4 +1789,4 @@ export declare function rangeContains(range: TextRange, offset: number): boolean
1780
1789
  /** Fast non-cryptographic string hash (cyrb53), as hex. */
1781
1790
  export declare function hashText(text: string): string;
1782
1791
  //#endregion
1783
- export type { Analysis, Answers, ApplyResult, ArgSource, BaselineSummary, Builtins, CacheStore, CallSpec, CapabilityConflict, Check, CheckContext, CheckIds, CheckLevel, CheckSetting, ConfigContext, ConfigDraft, ConfigOrigin, CreateProjectOptions, Decision, DecisionOption, DetectContext, Diagnostic, DiagnosticInput, Disposable, EditOp, Envelope, ErrorCode, ErrorInfo, ExtractItem, ExtractOptions, ExtractTemplate, Extractor, FileChange, FileEvent, FileScan, FinderContext, Fix, Format, FormatContext, FormatEntry, GlobOptions, GlossaryEntry, HardString, HistoryConfigs, HistoryContext, HistoryOptions, HistoryProvider, HistorySettings, Host, JsonObject, JsonPrimitive, JsonValue, KeyContext, KeyId, KeyInfo, KeyQuery, KeyString, KeyTarget, LazyFormat, LazyScanner, LibraryOptions, LineIndex, LinePosition, LocaleCode, LocaleCoverage, LocaleFinder, LocaleInfo, Location, Logger, ManifestReader, MemoryHost, Message, MessageChange, MessageHistory, MessageLeaf, MessageOp, MessageTree, NamespaceFromPath, NamespaceOptions, NodeRange, OverlayHost, ParamsSource, ParseResult, Placeholder, PlaceholderComparer, PlaceholderProblem, PlaceholderSyntax, Plan, Plugin, PluginConfigs, PluginFile, PluginLoader, PluginOption, PluginRegistry, PluginSpecifier, PluralForm, Preset, PresetDetection, PresetEntry, PresetExplanation, PresetFactory, PresetLoader, PresetOption, Project, ProjectChange, ProjectExplanation, PromptContext, PromptData, PromptDraft, PromptItem, PromptOptions, RegexScannerSpec, ReportInput, ReportSummary, Reporter, ReporterContext, ReporterLoader, ResolveConfigOptions, ResolvedConfig, Resource, ResourceBlock, ResourceCandidate, ResourceId, ResourceNode, ResourceSpec, ResourceTransform, ResourceTransformContext, ReviewAuthor, ReviewComment, ReviewData, ReviewFile, ReviewFilter, ReviewOptions, ReviewState, ReviewStore, ReviewThread, ReviewType, ScanContext, ScanResult, Scanner, ScannerEntry, SchemaIssue, Scope, SearchMatch, SearchOptions, SerializableConfig, Setup, Severity, SourceFile, TextEdit, TextRange, ThreadComment, TreeLeaf, Usage, UsageCandidate, UsageContext, UsageKind, UsageMatch, UsageOptions, UsageQuery, UserConfig, WireDiagnostic, WireRange, WriteOptions, X18nError };
1792
+ export type { Analysis, Answers, ApplyResult, ArgSource, BaselineSummary, Builtins, CacheStore, CallSpec, CapabilityConflict, Check, CheckContext, CheckIds, CheckLevel, CheckSetting, ConfigContext, ConfigDraft, ConfigOrigin, CreateProjectOptions, Decision, DecisionOption, DetectContext, Diagnostic, DiagnosticInput, Disposable, EditOp, Envelope, ErrorCode, ErrorInfo, ExtractItem, ExtractOptions, ExtractTemplate, Extractor, FileChange, FileEvent, FileScan, FinderContext, Fix, Format, FormatContext, FormatEntry, GlobOptions, GlossaryEntry, HardString, HistoryConfigs, HistoryContext, HistoryOptions, HistoryProvider, HistorySettings, Host, JsonObject, JsonPrimitive, JsonValue, KeyContext, KeyId, KeyInfo, KeyQuery, KeyString, KeyTarget, LazyFormat, LazyScanner, LibraryOptions, LineIndex, LinePosition, LocaleCode, LocaleCoverage, LocaleFinder, LocaleInfo, Location, Logger, ManifestReader, MemoryHost, Message, MessageChange, MessageHistory, MessageLeaf, MessageOp, MessageTree, NamespaceFromPath, NamespaceOptions, NodeRange, OverlayHost, ParamsSource, ParseResult, Placeholder, PlaceholderComparer, PlaceholderProblem, PlaceholderSyntax, Plan, Plugin, PluginConfigs, PluginFile, PluginLoader, PluginOption, PluginRegistry, PluginSpecifier, PluralForm, Preset, PresetDetection, PresetEntry, PresetExplanation, PresetFactory, PresetLoader, PresetOption, Project, ProjectChange, ProjectExplanation, PromptContext, PromptData, PromptDraft, PromptIssue, PromptItem, PromptOptions, RegexScannerSpec, ReportInput, ReportSummary, Reporter, ReporterContext, ReporterLoader, ResolveConfigOptions, ResolvedConfig, Resource, ResourceBlock, ResourceCandidate, ResourceId, ResourceNode, ResourceSpec, ResourceTransform, ResourceTransformContext, ReviewAuthor, ReviewComment, ReviewData, ReviewFile, ReviewFilter, ReviewOptions, ReviewState, ReviewStore, ReviewThread, ReviewType, ScanContext, ScanResult, Scanner, ScannerEntry, SchemaIssue, Scope, SearchMatch, SearchOptions, SerializableConfig, Setup, Severity, SourceFile, TextEdit, TextRange, ThreadComment, TreeLeaf, Usage, UsageCandidate, UsageContext, UsageKind, UsageMatch, UsageOptions, UsageQuery, UserConfig, WireDiagnostic, WireRange, WriteOptions, X18nError };
package/dist/index.mjs CHANGED
@@ -2438,13 +2438,28 @@ function contextOf(project, key) {
2438
2438
  }];
2439
2439
  });
2440
2440
  }
2441
+ /** The diagnostics of checks (all, or these ids) on values the locale has, by key. */
2442
+ function reportedValues(project, diagnostics, to, check) {
2443
+ const codes = check === true ? void 0 : new Set(check);
2444
+ const reported = /* @__PURE__ */ new Map();
2445
+ for (const diagnostic of diagnostics) {
2446
+ if (diagnostic.key === void 0 || diagnostic.locale !== to || codes && !codes.has(diagnostic.code)) continue;
2447
+ if (!text(project.message(diagnostic.key, to)?.value)) continue;
2448
+ const found = reported.get(diagnostic.key) ?? [];
2449
+ reported.set(diagnostic.key, found);
2450
+ found.push(diagnostic);
2451
+ }
2452
+ return reported;
2453
+ }
2441
2454
  /** Builds the parts of a translate or review prompt from project state. */
2442
2455
  function buildPrompt(project, kind, to, options, extra) {
2443
2456
  const from = project.sourceLocale;
2444
2457
  const match = typeof options.keys === "string" ? keyMatcher([options.keys]) : void 0;
2445
2458
  const list = Array.isArray(options.keys) ? new Set(options.keys) : void 0;
2446
- const outdated = new Set(project.analyze().coverage.find((c) => c.locale === to)?.outdated);
2459
+ const analysis = project.analyze();
2460
+ const outdated = new Set(analysis.coverage.find((c) => c.locale === to)?.outdated);
2447
2461
  const stale = (key) => outdated.has(key);
2462
+ const reported = kind === "translate" && options.check ? reportedValues(project, analysis.diagnostics, to, options.check) : /* @__PURE__ */ new Map();
2448
2463
  const candidates = project.keys({ namespace: options.namespace }).filter((key) => {
2449
2464
  if (match && !match(key)) return false;
2450
2465
  if (list && !list.has(key)) return false;
@@ -2452,7 +2467,7 @@ function buildPrompt(project, kind, to, options, extra) {
2452
2467
  if (source === void 0 || source === "") return false;
2453
2468
  const target = text(project.message(key, to)?.value);
2454
2469
  if (kind === "review") return target !== void 0 && target !== "";
2455
- return list !== void 0 || target === void 0 || target === "" || options.stale === true && stale(key);
2470
+ return list !== void 0 || target === void 0 || target === "" || options.stale === true && stale(key) || reported.has(key);
2456
2471
  });
2457
2472
  const start = Number(options.cursor ?? 0) || 0;
2458
2473
  const limit = options.limit ?? 50;
@@ -2466,6 +2481,7 @@ function buildPrompt(project, kind, to, options, extra) {
2466
2481
  };
2467
2482
  if (syntaxes.length > 0) draft.rules.push(`Keep every placeholder exactly as written (${syntaxes.map((s) => `\`${s.example ?? s.id}\``).join(", ")}); do not translate their names.`);
2468
2483
  draft.rules.push("Keep markup tags and their attributes as they are.", "Match the tone and wording of the existing messages in the target locale.", "Do not translate glossary terms marked \"do not translate\".");
2484
+ if (reported.size > 0) draft.rules.push(`A message with a reported problem has a current ${to} value: fix the problem. When the current value is right as it is, such as a word that is the same in both languages, leave the key out of the results.`);
2469
2485
  if (info.pluralCategories.length > 1) draft.notes.push(`${to} uses the plural categories ${info.pluralCategories.join(", ")}.`);
2470
2486
  for (const hook of extra.hooks) hook(draft, {
2471
2487
  sourceLocale: from,
@@ -2475,7 +2491,7 @@ function buildPrompt(project, kind, to, options, extra) {
2475
2491
  const examples = kind === "translate" ? project.keys().flatMap((key) => {
2476
2492
  const source = text(project.message(key, from)?.value);
2477
2493
  const target = text(project.message(key, to)?.value);
2478
- return source && target && !candidates.includes(key) ? [{
2494
+ return source && target && target !== source && !candidates.includes(key) ? [{
2479
2495
  key,
2480
2496
  source,
2481
2497
  target
@@ -2491,6 +2507,10 @@ function buildPrompt(project, kind, to, options, extra) {
2491
2507
  placeholders: [...new Set(syntaxes.flatMap((s) => s.find(source)).map((p) => p.text))],
2492
2508
  existing: text(project.message(key, to)?.value) || void 0,
2493
2509
  previousSource: previous === source ? void 0 : previous,
2510
+ issues: reported.get(key)?.map((d) => ({
2511
+ code: d.code,
2512
+ message: d.message
2513
+ })),
2494
2514
  context: options.context === false ? [] : contextOf(project, key)
2495
2515
  };
2496
2516
  });
@@ -2535,6 +2555,7 @@ function renderItem(item, to) {
2535
2555
  if (item.placeholders.length) out.push(`- Placeholders: ${item.placeholders.map((p) => `\`${p}\``).join(", ")}`);
2536
2556
  if (item.previousSource !== void 0) out.push(`- Source when ${to} last changed: ${JSON.stringify(item.previousSource)}`);
2537
2557
  if (item.existing !== void 0) out.push(`- Current ${to}: ${JSON.stringify(item.existing)}`);
2558
+ for (const issue of item.issues ?? []) out.push(`- Reported: ${issue.message} (\`${issue.code}\`)`);
2538
2559
  for (const context of item.context) out.push(`- Used in \`${context.path}:${context.line}\`:`, "", " ```", ...context.snippet.split("\n").map((line) => ` ${line}`), " ```");
2539
2560
  out.push("");
2540
2561
  return out;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@x18n/core",
3
3
  "type": "module",
4
- "version": "0.1.4",
4
+ "version": "0.1.6",
5
5
  "description": "Runtime-neutral engine of x18n: domain model, plugin API and project analysis",
6
6
  "author": "Anthony Fu <anthonyfu117@hotmail.com>",
7
7
  "license": "MIT",