@better-i18n/cli 0.2.2 → 0.2.4

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 (44) hide show
  1. package/README.md +53 -0
  2. package/dist/analyzer/index.d.ts.map +1 -1
  3. package/dist/analyzer/index.js +25 -0
  4. package/dist/analyzer/index.js.map +1 -1
  5. package/dist/analyzer/types.d.ts +1 -0
  6. package/dist/analyzer/types.d.ts.map +1 -1
  7. package/dist/commands/doctor.d.ts +2 -0
  8. package/dist/commands/doctor.d.ts.map +1 -1
  9. package/dist/commands/doctor.js +9 -4
  10. package/dist/commands/doctor.js.map +1 -1
  11. package/dist/context/detector.js +16 -0
  12. package/dist/context/detector.js.map +1 -1
  13. package/dist/doctor/index.d.ts +2 -0
  14. package/dist/doctor/index.d.ts.map +1 -1
  15. package/dist/doctor/index.js +109 -9
  16. package/dist/doctor/index.js.map +1 -1
  17. package/dist/doctor/score.d.ts +12 -6
  18. package/dist/doctor/score.d.ts.map +1 -1
  19. package/dist/doctor/score.js +41 -14
  20. package/dist/doctor/score.js.map +1 -1
  21. package/dist/index.js +3 -1
  22. package/dist/index.js.map +1 -1
  23. package/dist/reporters/doctor-eslint.d.ts.map +1 -1
  24. package/dist/reporters/doctor-eslint.js +60 -16
  25. package/dist/reporters/doctor-eslint.js.map +1 -1
  26. package/dist/reporters/doctor-report.d.ts +9 -4
  27. package/dist/reporters/doctor-report.d.ts.map +1 -1
  28. package/dist/reporters/doctor-report.js +70 -10
  29. package/dist/reporters/doctor-report.js.map +1 -1
  30. package/dist/rules/categories.d.ts.map +1 -1
  31. package/dist/rules/categories.js +9 -0
  32. package/dist/rules/categories.js.map +1 -1
  33. package/dist/rules/health/missing-translations.js +2 -2
  34. package/dist/rules/health/missing-translations.js.map +1 -1
  35. package/dist/rules/health/orphan-keys.js +2 -2
  36. package/dist/rules/health/orphan-keys.js.map +1 -1
  37. package/dist/rules/health/placeholder-mismatch.js +3 -3
  38. package/dist/rules/health/placeholder-mismatch.js.map +1 -1
  39. package/dist/rules/registry.d.ts +2 -0
  40. package/dist/rules/registry.d.ts.map +1 -1
  41. package/dist/utils/key-comparison.d.ts.map +1 -1
  42. package/dist/utils/key-comparison.js +5 -1
  43. package/dist/utils/key-comparison.js.map +1 -1
  44. package/package.json +1 -1
@@ -7,12 +7,18 @@
7
7
  * per occurrence because each hardcoded string is an independent task
8
8
  * that requires its own t() wrapping.
9
9
  *
10
- * Overall score: 100 - (errors x 3.0) - (warnings x 0.15)
11
- * Category score: 100 - (errors x 5.0) - (warnings x 0.5)
10
+ * Overall score: 100 - (errors x 3.0) - Σ min(ruleWarnings x 0.15, 20)
11
+ * Category score: 100 - (errors x 5.0) - Σ min(ruleWarnings x 0.5, 80)
12
+ *
13
+ * Per-rule warning cap: Each rule can penalize the overall score by at most
14
+ * MAX_RULE_WARNING_PENALTY (20) points, and each category by at most
15
+ * MAX_RULE_CAT_PENALTY (80) points. This prevents a single rule with
16
+ * thousands of warnings (e.g. missing-in-remote) from zeroing the score.
17
+ * Errors are NOT capped.
12
18
  *
13
19
  * Calibration targets:
14
20
  * 0E, 0W → 100
15
- * 0E, 104W → 84
21
+ * 0E, 104W → 84 (single rule, cap threshold = 133)
16
22
  * 10E, 20W → 67
17
23
  * 5E, 0W → 85
18
24
  * 1E, 0W → 97
@@ -22,10 +28,14 @@
22
28
  const ERROR_PENALTY = 3.0;
23
29
  /** Per-occurrence penalty for warnings on the overall score */
24
30
  const WARNING_PENALTY = 0.15;
31
+ /** Max penalty any single rule's warnings can contribute to the overall score */
32
+ const MAX_RULE_WARNING_PENALTY = 20;
25
33
  /** Per-occurrence penalty for errors within a category */
26
34
  const CAT_ERROR_PENALTY = 5.0;
27
35
  /** Per-occurrence penalty for warnings within a category */
28
36
  const CAT_WARNING_PENALTY = 0.5;
37
+ /** Max penalty any single rule's warnings can contribute to a category score */
38
+ const MAX_RULE_CAT_PENALTY = 80;
29
39
  /** Default pass/fail threshold */
30
40
  const PASS_THRESHOLD = 70;
31
41
  // ── Calculator ──────────────────────────────────────────────────────
@@ -33,31 +43,41 @@ const PASS_THRESHOLD = 70;
33
43
  * Calculate health score from diagnostics.
34
44
  *
35
45
  * Algorithm:
36
- * 1. Count total errors and warnings (info ignored)
37
- * 2. Overall = 100 - (errors x 3.0) - (warnings x 0.15), clamped [0,100]
38
- * 3. Per category = 100 - (catErrors x 5.0) - (catWarnings x 0.5), clamped [0,100]
46
+ * 1. Count total errors and per-rule warnings (info ignored)
47
+ * 2. Overall = 100 - (errors x 3.0) - Σ min(ruleWarnings x 0.15, 20), clamped [0,100]
48
+ * 3. Per category = 100 - (catErrors x 5.0) - Σ min(ruleWarnings x 0.5, 80), clamped [0,100]
39
49
  * 4. passed = overall >= threshold
40
50
  */
41
51
  export function calculateHealthScore(diagnostics, passThreshold = PASS_THRESHOLD) {
42
52
  // Count totals
43
53
  let totalErrors = 0;
44
- let totalWarnings = 0;
54
+ // Per-rule warning counts (for capped overall penalty)
55
+ const ruleWarningCounts = new Map();
45
56
  // Count per category
46
57
  const catErrors = new Map();
47
- const catWarnings = new Map();
58
+ // Per-category, per-rule warning counts (for capped category penalty)
59
+ const catRuleWarnings = new Map();
48
60
  for (const d of diagnostics) {
49
61
  if (d.severity === "error") {
50
62
  totalErrors++;
51
63
  catErrors.set(d.category, (catErrors.get(d.category) || 0) + 1);
52
64
  }
53
65
  else if (d.severity === "warning") {
54
- totalWarnings++;
55
- catWarnings.set(d.category, (catWarnings.get(d.category) || 0) + 1);
66
+ ruleWarningCounts.set(d.rule, (ruleWarningCounts.get(d.rule) || 0) + 1);
67
+ if (!catRuleWarnings.has(d.category)) {
68
+ catRuleWarnings.set(d.category, new Map());
69
+ }
70
+ const ruleMap = catRuleWarnings.get(d.category);
71
+ ruleMap.set(d.rule, (ruleMap.get(d.rule) || 0) + 1);
56
72
  }
57
73
  // "info" diagnostics don't affect score
58
74
  }
59
- // Overall score — flat, occurrence-based
60
- const rawTotal = 100 - totalErrors * ERROR_PENALTY - totalWarnings * WARNING_PENALTY;
75
+ // Overall score — per-rule capped warning penalty
76
+ let totalWarningPenalty = 0;
77
+ for (const count of ruleWarningCounts.values()) {
78
+ totalWarningPenalty += Math.min(count * WARNING_PENALTY, MAX_RULE_WARNING_PENALTY);
79
+ }
80
+ const rawTotal = 100 - totalErrors * ERROR_PENALTY - totalWarningPenalty;
61
81
  const total = clamp(Math.round(rawTotal));
62
82
  // Per-category scores
63
83
  const allCategories = [
@@ -70,8 +90,15 @@ export function calculateHealthScore(diagnostics, passThreshold = PASS_THRESHOLD
70
90
  const categories = {};
71
91
  for (const cat of allCategories) {
72
92
  const errors = catErrors.get(cat) || 0;
73
- const warnings = catWarnings.get(cat) || 0;
74
- const rawCat = 100 - errors * CAT_ERROR_PENALTY - warnings * CAT_WARNING_PENALTY;
93
+ // Sum per-rule capped warning penalties for this category
94
+ let catWarningPenalty = 0;
95
+ const ruleMap = catRuleWarnings.get(cat);
96
+ if (ruleMap) {
97
+ for (const count of ruleMap.values()) {
98
+ catWarningPenalty += Math.min(count * CAT_WARNING_PENALTY, MAX_RULE_CAT_PENALTY);
99
+ }
100
+ }
101
+ const rawCat = 100 - errors * CAT_ERROR_PENALTY - catWarningPenalty;
75
102
  categories[cat] = clamp(Math.round(rawCat));
76
103
  }
77
104
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"score.js","sourceRoot":"","sources":["../../src/doctor/score.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAIH,uEAAuE;AAEvE,6DAA6D;AAC7D,MAAM,aAAa,GAAG,GAAG,CAAC;AAC1B,+DAA+D;AAC/D,MAAM,eAAe,GAAG,IAAI,CAAC;AAE7B,0DAA0D;AAC1D,MAAM,iBAAiB,GAAG,GAAG,CAAC;AAC9B,4DAA4D;AAC5D,MAAM,mBAAmB,GAAG,GAAG,CAAC;AAEhC,kCAAkC;AAClC,MAAM,cAAc,GAAG,EAAE,CAAC;AAe1B,uEAAuE;AAEvE;;;;;;;;GAQG;AACH,MAAM,UAAU,oBAAoB,CAClC,WAA6B,EAC7B,aAAa,GAAG,cAAc;IAE9B,eAAe;IACf,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,IAAI,aAAa,GAAG,CAAC,CAAC;IAEtB,qBAAqB;IACrB,MAAM,SAAS,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC5C,MAAM,WAAW,GAAG,IAAI,GAAG,EAAkB,CAAC;IAE9C,KAAK,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;QAC5B,IAAI,CAAC,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;YAC3B,WAAW,EAAE,CAAC;YACd,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAClE,CAAC;aAAM,IAAI,CAAC,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;YACpC,aAAa,EAAE,CAAC;YAChB,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACtE,CAAC;QACD,wCAAwC;IAC1C,CAAC;IAED,yCAAyC;IACzC,MAAM,QAAQ,GACZ,GAAG,GAAG,WAAW,GAAG,aAAa,GAAG,aAAa,GAAG,eAAe,CAAC;IACtE,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;IAE1C,sBAAsB;IACtB,MAAM,aAAa,GAAG;QACpB,UAAU;QACV,SAAS;QACT,MAAM;QACN,WAAW;QACX,aAAa;KACd,CAAC;IAEF,MAAM,UAAU,GAA2B,EAAE,CAAC;IAE9C,KAAK,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC;QAChC,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACvC,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAE3C,MAAM,MAAM,GACV,GAAG,GAAG,MAAM,GAAG,iBAAiB,GAAG,QAAQ,GAAG,mBAAmB,CAAC;QACpE,UAAU,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;IAC9C,CAAC;IAED,OAAO;QACL,KAAK;QACL,UAAU;QACV,MAAM,EAAE,KAAK,IAAI,aAAa;QAC9B,aAAa;KACd,CAAC;AACJ,CAAC;AAED,uEAAuE;AAEvE,SAAS,KAAK,CAAC,KAAa,EAAE,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,GAAG;IAC9C,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;AAC7C,CAAC"}
1
+ {"version":3,"file":"score.js","sourceRoot":"","sources":["../../src/doctor/score.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -61,9 +61,11 @@ program
61
61
  .option("-d, --dir <path>", "Directory to scan (default: current directory)")
62
62
  .option("-f, --format <type>", "Output format: eslint, json", "eslint")
63
63
  .option("--ci", "CI mode: exit with error code if health score below threshold")
64
- .option("--report", "Upload results to Better i18n portal (requires GitHub Actions OIDC)")
64
+ .option("--report", "Upload results to Better i18n portal (requires GitHub Actions OIDC or --api-key)")
65
+ .option("--api-key <key>", "Better Auth API key for non-GitHub CI (local dev, GitLab, Jenkins)")
65
66
  .option("--skip-code", "Skip AST code analysis (hardcoded strings)")
66
67
  .option("--skip-health", "Skip translation file health checks")
68
+ .option("--skip-sync", "Skip remote CDN comparison")
67
69
  .option("--verbose", "Show detailed output")
68
70
  .action(doctorCommand);
69
71
  program.parse();
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EACL,YAAY,EACZ,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,OAAO;KACJ,IAAI,CAAC,aAAa,CAAC;KACnB,WAAW,CACV,sEAAsE,CACvE;KACA,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,4CAA4C,CAAC;KACzD,MAAM,CAAC,kBAAkB,EAAE,gDAAgD,CAAC;KAC5E,MAAM,CAAC,qBAAqB,EAAE,6BAA6B,EAAE,QAAQ,CAAC;KACtE,MAAM,CACL,uBAAuB,EACvB,oDAAoD,EACpD,QAAQ,CACT;KACA,MAAM,CAAC,OAAO,EAAE,wCAAwC,CAAC;KACzD,MAAM,CAAC,MAAM,EAAE,+CAA+C,CAAC;KAC/D,MAAM,CAAC,UAAU,EAAE,4BAA4B,CAAC;KAChD,MAAM,CAAC,WAAW,EAAE,sBAAsB,CAAC;KAC3C,MAAM,CAAC,WAAW,CAAC,CAAC;AAEvB,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,uDAAuD,CAAC;KACpE,MAAM,CAAC,kBAAkB,EAAE,gDAAgD,CAAC;KAC5E,MAAM,CAAC,qBAAqB,EAAE,6BAA6B,EAAE,QAAQ,CAAC;KACtE,MAAM,CAAC,WAAW,EAAE,0CAA0C,CAAC;KAC/D,MAAM,CAAC,WAAW,EAAE,sBAAsB,CAAC;KAC3C,MAAM,CAAC,WAAW,CAAC,CAAC;AAEvB,8CAA8C;AAC9C,OAAO;KACJ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,6DAA6D,CAAC;KAC1E,MAAM,CAAC,kBAAkB,EAAE,gDAAgD,CAAC;KAC5E,MAAM,CAAC,qBAAqB,EAAE,6BAA6B,EAAE,QAAQ,CAAC;KACtE,MAAM,CAAC,WAAW,EAAE,sBAAsB,CAAC;KAC3C,MAAM,CAAC,YAAY,CAAC,CAAC;AAExB,OAAO;KACJ,OAAO,CAAC,eAAe,CAAC;KACxB,WAAW,CAAC,gEAAgE,CAAC;KAC7E,MAAM,CAAC,kBAAkB,EAAE,gDAAgD,CAAC;KAC5E,MAAM,CAAC,qBAAqB,EAAE,6BAA6B,EAAE,QAAQ,CAAC;KACtE,MAAM,CAAC,WAAW,EAAE,sBAAsB,CAAC;KAC3C,MAAM,CAAC,mBAAmB,CAAC,CAAC;AAE/B,OAAO;KACJ,OAAO,CAAC,cAAc,CAAC;KACvB,WAAW,CACV,wEAAwE,CACzE;KACA,MAAM,CAAC,kBAAkB,EAAE,gDAAgD,CAAC;KAC5E,MAAM,CAAC,qBAAqB,EAAE,6BAA6B,EAAE,QAAQ,CAAC;KACtE,MAAM,CAAC,WAAW,EAAE,sBAAsB,CAAC;KAC3C,MAAM,CAAC,kBAAkB,CAAC,CAAC;AAE9B,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,gFAAgF,CAAC;KAC7F,MAAM,CAAC,kBAAkB,EAAE,gDAAgD,CAAC;KAC5E,MAAM,CAAC,qBAAqB,EAAE,6BAA6B,EAAE,QAAQ,CAAC;KACtE,MAAM,CAAC,MAAM,EAAE,+DAA+D,CAAC;KAC/E,MAAM,CAAC,UAAU,EAAE,qEAAqE,CAAC;KACzF,MAAM,CAAC,aAAa,EAAE,4CAA4C,CAAC;KACnE,MAAM,CAAC,eAAe,EAAE,qCAAqC,CAAC;KAC9D,MAAM,CAAC,WAAW,EAAE,sBAAsB,CAAC;KAC3C,MAAM,CAAC,aAAa,CAAC,CAAC;AAEzB,OAAO,CAAC,KAAK,EAAE,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"doctor-eslint.d.ts","sourceRoot":"","sources":["../../src/reporters/doctor-eslint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AA0FvD;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,EAAE,OAAO,UAAQ,GAAG,IAAI,CAmGxE"}
1
+ {"version":3,"file":"doctor-eslint.d.ts","sourceRoot":"","sources":["../../src/reporters/doctor-eslint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAqHvD;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,EAAE,OAAO,UAAQ,GAAG,IAAI,CA2HxE"}
@@ -56,12 +56,21 @@ function renderCategoryLine(category, score, count) {
56
56
  const countStr = count > 0 ? dim(` (${count} issues)`) : dim(" (clean)");
57
57
  return ` ${dim(padded)} ${colorFn(scoreStr)}${countStr}`;
58
58
  }
59
+ // ── Display Limits ──────────────────────────────────────────────────
60
+ const MAX_RULE_GROUPS = 5;
61
+ const MAX_ITEMS_PER_GROUP = 5;
62
+ const MAX_ITEMS_PER_GROUP_VERBOSE = 20;
59
63
  // ── Diagnostic Helpers (react-doctor pattern) ───────────────────────
60
64
  const SEVERITY_ORDER = {
61
65
  error: 0,
62
66
  warning: 1,
63
67
  info: 2,
64
68
  };
69
+ /** Rules that produce key-based diagnostics (namespace/key format) */
70
+ const KEY_BASED_RULES = new Set([
71
+ "missing-in-remote",
72
+ "unused-remote-key",
73
+ ]);
65
74
  function colorizeBySeverity(text, severity) {
66
75
  if (severity === "error")
67
76
  return red(text);
@@ -69,9 +78,13 @@ function colorizeBySeverity(text, severity) {
69
78
  return yellow(text);
70
79
  return dim(text);
71
80
  }
72
- function sortBySeverity(groups) {
81
+ function sortBySeverityAndCount(groups) {
73
82
  return [...groups].sort(([, a], [, b]) => {
74
- return (SEVERITY_ORDER[a[0].severity] ?? 2) - (SEVERITY_ORDER[b[0].severity] ?? 2);
83
+ const sevDiff = (SEVERITY_ORDER[a[0].severity] ?? 2) -
84
+ (SEVERITY_ORDER[b[0].severity] ?? 2);
85
+ if (sevDiff !== 0)
86
+ return sevDiff;
87
+ return b.length - a.length; // more issues first
75
88
  });
76
89
  }
77
90
  function buildFileLineMap(diagnostics) {
@@ -84,6 +97,16 @@ function buildFileLineMap(diagnostics) {
84
97
  }
85
98
  return fileLines;
86
99
  }
100
+ function buildKeyEntries(diagnostics) {
101
+ const entries = [];
102
+ for (const d of diagnostics) {
103
+ if (d.key) {
104
+ const prefix = d.namespace ? `${d.namespace}/` : "";
105
+ entries.push(`${prefix}${d.key}`);
106
+ }
107
+ }
108
+ return entries;
109
+ }
87
110
  // ── Main Reporter ───────────────────────────────────────────────────
88
111
  /**
89
112
  * Print ESLint-style report to stdout.
@@ -95,12 +118,15 @@ export function reportEslint(report, verbose = false) {
95
118
  const { score, summary, diagnostics } = report;
96
119
  // ── Header Box ──────────────────────────────────────────────────
97
120
  console.log();
98
- console.log(bold("┌─────────────────────────────────────────────┐"));
99
- console.log(bold("│") + " i18n Doctor Report" + " ".repeat(25) + bold("│"));
100
- console.log(bold("├─────────────────────────────────────────────┤"));
101
- console.log(bold("│") + " " + renderScoreBar(score.total) + " " + bold("│"));
102
- console.log(bold("│") + " " + (score.passed ? green("PASSED") : red("FAILED")) + dim(` (threshold: ${score.passThreshold})`) + " ".repeat(10) + bold("│"));
103
- console.log(bold("└─────────────────────────────────────────────┘"));
121
+ console.log(bold("╭──────────────────────────────────────────────╮"));
122
+ console.log(bold("│") + " " + bold("│"));
123
+ console.log(bold("") + " 🌐 " + bold("better-i18n") + dim(" · i18n Doctor Report") + " " + bold("│"));
124
+ console.log(bold("│") + dim(" hello · hola · 你好 · こんにちは · 안녕") + " " + bold("│"));
125
+ console.log(bold("│") + " " + bold("│"));
126
+ console.log(bold("├──────────────────────────────────────────────┤"));
127
+ console.log(bold("│") + " " + renderScoreBar(score.total) + " " + bold("│"));
128
+ console.log(bold("│") + " " + (score.passed ? green("PASSED") : red("FAILED")) + dim(` (threshold: ${score.passThreshold})`) + " ".repeat(11) + bold("│"));
129
+ console.log(bold("╰──────────────────────────────────────────────╯"));
104
130
  console.log();
105
131
  // ── Category Breakdown ──────────────────────────────────────────
106
132
  console.log(bold("Category Scores:"));
@@ -138,9 +164,12 @@ export function reportEslint(report, verbose = false) {
138
164
  existing.push(d);
139
165
  byRule.set(d.rule, existing);
140
166
  }
141
- // Sort: errors first, then warnings
142
- const sortedGroups = sortBySeverity([...byRule.entries()]);
143
- for (const [, diags] of sortedGroups) {
167
+ // Sort: errors first, then by count descending
168
+ const sortedGroups = sortBySeverityAndCount([...byRule.entries()]);
169
+ const visibleGroups = sortedGroups.slice(0, MAX_RULE_GROUPS);
170
+ const hiddenGroupCount = sortedGroups.length - visibleGroups.length;
171
+ const maxItems = verbose ? MAX_ITEMS_PER_GROUP_VERBOSE : MAX_ITEMS_PER_GROUP;
172
+ for (const [rule, diags] of visibleGroups) {
144
173
  const first = diags[0];
145
174
  const icon = colorizeBySeverity(first.severity === "error" ? "✗" : "⚠", first.severity);
146
175
  const count = diags.length;
@@ -153,13 +182,24 @@ export function reportEslint(report, verbose = false) {
153
182
  if (first.help) {
154
183
  console.log(dim(` ${first.help}`));
155
184
  }
156
- // File:line listing (verbose or always for small sets)
157
- if (verbose || count <= 5) {
158
- const maxFiles = 10;
185
+ // Key-based rules: show namespace/key entries
186
+ if (KEY_BASED_RULES.has(rule)) {
187
+ const keys = buildKeyEntries(diags);
188
+ const shown = keys.slice(0, maxItems);
189
+ const hiddenKeys = keys.length - shown.length;
190
+ for (const key of shown) {
191
+ console.log(dim(` ${key}`));
192
+ }
193
+ if (hiddenKeys > 0) {
194
+ console.log(dim(` ... and ${hiddenKeys} more`));
195
+ }
196
+ }
197
+ else {
198
+ // File-based rules: show file:line entries
159
199
  const fileLines = buildFileLineMap(diags);
160
200
  const entries = [...fileLines.entries()];
161
- const shown = entries.slice(0, maxFiles);
162
- const hiddenFiles = entries.length - maxFiles;
201
+ const shown = entries.slice(0, maxItems);
202
+ const hiddenFiles = entries.length - shown.length;
163
203
  for (const [filePath, lines] of shown) {
164
204
  const lineLabel = lines.length > 0 ? `: ${lines.join(", ")}` : "";
165
205
  console.log(dim(` ${filePath}${lineLabel}`));
@@ -170,6 +210,10 @@ export function reportEslint(report, verbose = false) {
170
210
  }
171
211
  console.log();
172
212
  }
213
+ if (hiddenGroupCount > 0) {
214
+ console.log(dim(` ... and ${hiddenGroupCount} more rules`));
215
+ console.log();
216
+ }
173
217
  }
174
218
  }
175
219
  //# sourceMappingURL=doctor-eslint.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"doctor-eslint.js","sourceRoot":"","sources":["../../src/reporters/doctor-eslint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAIzE,wEAAwE;AAExE,SAAS,cAAc,CAAC,KAAa;IACnC,MAAM,KAAK,GAAG,EAAE,CAAC;IACjB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC;IACjD,MAAM,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;IAE7B,IAAI,KAA4B,CAAC;IACjC,IAAI,KAAa,CAAC;IAElB,IAAI,KAAK,IAAI,EAAE,EAAE,CAAC;QAChB,KAAK,GAAG,KAAK,CAAC;QACd,KAAK,GAAG,IAAI,CAAC;IACf,CAAC;SAAM,IAAI,KAAK,IAAI,EAAE,EAAE,CAAC;QACvB,KAAK,GAAG,KAAK,CAAC;QACd,KAAK,GAAG,GAAG,CAAC;IACd,CAAC;SAAM,IAAI,KAAK,IAAI,EAAE,EAAE,CAAC;QACvB,KAAK,GAAG,IAAI,CAAC;QACb,KAAK,GAAG,GAAG,CAAC;IACd,CAAC;SAAM,IAAI,KAAK,IAAI,EAAE,EAAE,CAAC;QACvB,KAAK,GAAG,MAAM,CAAC;QACf,KAAK,GAAG,GAAG,CAAC;IACd,CAAC;SAAM,CAAC;QACN,KAAK,GAAG,GAAG,CAAC;QACZ,KAAK,GAAG,GAAG,CAAC;IACd,CAAC;IAED,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IAC/D,OAAO,GAAG,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;AACxE,CAAC;AAED,uEAAuE;AAEvE,SAAS,kBAAkB,CACzB,QAAgB,EAChB,KAAa,EACb,KAAa;IAEb,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACnC,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAE3C,IAAI,OAA8B,CAAC;IACnC,IAAI,KAAK,IAAI,EAAE;QAAE,OAAO,GAAG,KAAK,CAAC;SAC5B,IAAI,KAAK,IAAI,EAAE;QAAE,OAAO,GAAG,IAAI,CAAC;SAChC,IAAI,KAAK,IAAI,EAAE;QAAE,OAAO,GAAG,MAAM,CAAC;;QAClC,OAAO,GAAG,GAAG,CAAC;IAEnB,MAAM,QAAQ,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACzE,OAAO,KAAK,GAAG,CAAC,MAAM,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,QAAQ,EAAE,CAAC;AAC5D,CAAC;AAED,uEAAuE;AAEvE,MAAM,cAAc,GAA2B;IAC7C,KAAK,EAAE,CAAC;IACR,OAAO,EAAE,CAAC;IACV,IAAI,EAAE,CAAC;CACR,CAAC;AAEF,SAAS,kBAAkB,CAAC,IAAY,EAAE,QAAgB;IACxD,IAAI,QAAQ,KAAK,OAAO;QAAE,OAAO,GAAG,CAAC,IAAI,CAAC,CAAC;IAC3C,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC;IAChD,OAAO,GAAG,CAAC,IAAI,CAAC,CAAC;AACnB,CAAC;AAED,SAAS,cAAc,CACrB,MAAoC;IAEpC,OAAO,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,CACrB,CAAC,CAAC,EAAE,CAAC,CAA6B,EAAE,CAAC,EAAE,CAAC,CAA6B,EAAE,EAAE;QACvE,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;IACrF,CAAC,CACF,CAAC;AACJ,CAAC;AAED,SAAS,gBAAgB,CAAC,WAA6B;IACrD,MAAM,SAAS,GAAG,IAAI,GAAG,EAAoB,CAAC;IAC9C,KAAK,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;QAC5B,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QAC9C,IAAI,CAAC,CAAC,IAAI,GAAG,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACnC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IACnC,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,uEAAuE;AAEvE;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,MAAoB,EAAE,OAAO,GAAG,KAAK;IAChE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,MAAM,CAAC;IAE/C,mEAAmE;IACnE,OAAO,CAAC,GAAG,EAAE,CAAC;IACd,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,iDAAiD,CAAC,CAAC,CAAC;IACrE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,sBAAsB,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7E,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,iDAAiD,CAAC,CAAC,CAAC;IACrE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,cAAc,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACnF,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,GAAG,GAAG,CAAC,gBAAgB,KAAK,CAAC,aAAa,GAAG,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5J,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,iDAAiD,CAAC,CAAC,CAAC;IACrE,OAAO,CAAC,GAAG,EAAE,CAAC;IAEd,mEAAmE;IACnE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC;IACtC,MAAM,UAAU,GAAG,CAAC,UAAU,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,aAAa,CAAC,CAAC;IAC/E,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAG,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC;QAC9C,MAAM,KAAK,GAAG,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC3C,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,GAAG,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC;IACxD,CAAC;IACD,OAAO,CAAC,GAAG,EAAE,CAAC;IAEd,mEAAmE;IACnE,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,MAAM,SAAS,CAAC,CAAC,CAAC;IACpE,IAAI,OAAO,CAAC,QAAQ,GAAG,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,QAAQ,WAAW,CAAC,CAAC,CAAC;IAC7E,IAAI,OAAO,CAAC,KAAK,GAAG,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC;IAEhE,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrB,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACvC,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC,CAAC;IAC3C,CAAC;IAED,OAAO,CAAC,GAAG,CACT,GAAG,CACD,KAAK,OAAO,CAAC,YAAY,mBAAmB,OAAO,CAAC,WAAW,kBAAkB,OAAO,CAAC,cAAc,UAAU,CAClH,CACF,CAAC;IACF,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,kBAAkB,CAAC,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7E,OAAO,CAAC,GAAG,EAAE,CAAC;IAEd,mEAAmE;IACnE,MAAM,UAAU,GAAG,WAAW,CAAC,MAAM,CACnC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,IAAI,CAAC,CAAC,QAAQ,KAAK,SAAS,CAC1D,CAAC;IAEF,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1B,gBAAgB;QAChB,MAAM,MAAM,GAAG,IAAI,GAAG,EAA4B,CAAC;QACnD,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;YAC3B,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YAC1C,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACjB,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAC/B,CAAC;QAED,oCAAoC;QACpC,MAAM,YAAY,GAAG,cAAc,CAAC,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAE3D,KAAK,MAAM,CAAC,EAAE,KAAK,CAAC,IAAI,YAAY,EAAE,CAAC;YACrC,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACvB,MAAM,IAAI,GAAG,kBAAkB,CAC7B,KAAK,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EACtC,KAAK,CAAC,QAAQ,CACf,CAAC;YACF,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC;YAC3B,MAAM,UAAU,GAAG,KAAK,GAAG,CAAC;gBAC1B,CAAC,CAAC,kBAAkB,CAAC,KAAK,KAAK,GAAG,EAAE,KAAK,CAAC,QAAQ,CAAC;gBACnD,CAAC,CAAC,EAAE,CAAC;YAEP,oBAAoB;YACpB,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,GAAG,UAAU,EAAE,CAAC,CAAC;YAEvD,uBAAuB;YACvB,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;gBACf,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;YACxC,CAAC;YAED,uDAAuD;YACvD,IAAI,OAAO,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;gBAC1B,MAAM,QAAQ,GAAG,EAAE,CAAC;gBACpB,MAAM,SAAS,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;gBAC1C,MAAM,OAAO,GAAG,CAAC,GAAG,SAAS,CAAC,OAAO,EAAE,CAAC,CAAC;gBACzC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;gBACzC,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,GAAG,QAAQ,CAAC;gBAE9C,KAAK,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,KAAK,EAAE,CAAC;oBACtC,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBAClE,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,QAAQ,GAAG,SAAS,EAAE,CAAC,CAAC,CAAC;gBAClD,CAAC;gBACD,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;oBACpB,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,eAAe,WAAW,aAAa,CAAC,CAAC,CAAC;gBAC5D,CAAC;YACH,CAAC;YAED,OAAO,CAAC,GAAG,EAAE,CAAC;QAChB,CAAC;IACH,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"doctor-eslint.js","sourceRoot":"","sources":["../../src/reporters/doctor-eslint.ts"],"names":[],"mappings":"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"}
@@ -2,10 +2,14 @@
2
2
  * Doctor Report — API Reporter
3
3
  *
4
4
  * Sends a DoctorReport to the Better i18n API for storage and trend tracking.
5
- * Authentication is via GitHub Actions OIDC — no API keys needed.
6
5
  *
7
- * Graceful degradation: if OIDC is unavailable (running locally, missing
8
- * permissions), it warns and returns null instead of failing.
6
+ * Two auth paths:
7
+ * 1. API key (--api-key flag) for local dev, GitLab, Jenkins, etc.
8
+ * Uses Better Auth API key via x-api-key header.
9
+ * Reads project context from i18n.config.ts to build X-Doctor-Project header.
10
+ * 2. GitHub Actions OIDC (default) — no API keys needed in GitHub Actions.
11
+ *
12
+ * Graceful degradation: if auth is unavailable, it warns and returns null.
9
13
  */
10
14
  import type { DoctorReport } from "../doctor/index.js";
11
15
  interface ReportResult {
@@ -16,8 +20,9 @@ interface ReportResult {
16
20
  * POST a doctor report to the Better i18n API.
17
21
  *
18
22
  * @param report - The DoctorReport to upload
23
+ * @param apiKey - Optional Better Auth API key for non-OIDC auth (--api-key flag)
19
24
  * @returns Report ID and dashboard URL, or null if reporting failed/unavailable
20
25
  */
21
- export declare function reportToApi(report: DoctorReport): Promise<ReportResult | null>;
26
+ export declare function reportToApi(report: DoctorReport, apiKey?: string): Promise<ReportResult | null>;
22
27
  export {};
23
28
  //# sourceMappingURL=doctor-report.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"doctor-report.d.ts","sourceRoot":"","sources":["../../src/reporters/doctor-report.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAKvD,UAAU,YAAY;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;;;GAKG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,YAAY,GACnB,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CA4D9B"}
1
+ {"version":3,"file":"doctor-report.d.ts","sourceRoot":"","sources":["../../src/reporters/doctor-report.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAMvD,UAAU,YAAY;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;;;;GAMG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,YAAY,EACpB,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAU9B"}
@@ -2,24 +2,86 @@
2
2
  * Doctor Report — API Reporter
3
3
  *
4
4
  * Sends a DoctorReport to the Better i18n API for storage and trend tracking.
5
- * Authentication is via GitHub Actions OIDC — no API keys needed.
6
5
  *
7
- * Graceful degradation: if OIDC is unavailable (running locally, missing
8
- * permissions), it warns and returns null instead of failing.
6
+ * Two auth paths:
7
+ * 1. API key (--api-key flag) for local dev, GitLab, Jenkins, etc.
8
+ * Uses Better Auth API key via x-api-key header.
9
+ * Reads project context from i18n.config.ts to build X-Doctor-Project header.
10
+ * 2. GitHub Actions OIDC (default) — no API keys needed in GitHub Actions.
11
+ *
12
+ * Graceful degradation: if auth is unavailable, it warns and returns null.
9
13
  */
14
+ import { detectProjectContext } from "../context/detector.js";
10
15
  import { fetchGitHubOidcToken, isGitHubActionsWithOidc } from "../context/oidc.js";
11
16
  const DEFAULT_API_URL = "https://api.better-i18n.com";
12
17
  /**
13
18
  * POST a doctor report to the Better i18n API.
14
19
  *
15
20
  * @param report - The DoctorReport to upload
21
+ * @param apiKey - Optional Better Auth API key for non-OIDC auth (--api-key flag)
16
22
  * @returns Report ID and dashboard URL, or null if reporting failed/unavailable
17
23
  */
18
- export async function reportToApi(report) {
19
- // 1. Check if we can get an OIDC token
24
+ export async function reportToApi(report, apiKey) {
25
+ const apiUrl = process.env.BETTER_I18N_API_URL || DEFAULT_API_URL;
26
+ // ── API key auth path ──────────────────────────────────────────
27
+ if (apiKey) {
28
+ return reportWithApiKey(report, apiKey, apiUrl);
29
+ }
30
+ // ── OIDC auth path (GitHub Actions) ──────────────────────────
31
+ return reportWithOidc(report, apiUrl);
32
+ }
33
+ /**
34
+ * Report using Better Auth API key + X-Doctor-Project header.
35
+ * Reads org/project slug from i18n.config.ts.
36
+ */
37
+ async function reportWithApiKey(report, apiKey, apiUrl) {
38
+ // Detect project context from i18n.config.ts
39
+ const context = await detectProjectContext(process.cwd(), true);
40
+ if (!context?.workspaceId || !context?.projectSlug) {
41
+ console.warn(" Warning: Could not detect project context from i18n.config.ts.\n" +
42
+ " Ensure your config has: project: \"orgSlug/projectSlug\"\n" +
43
+ " Skipping report upload.");
44
+ return null;
45
+ }
46
+ const doctorProject = `${context.workspaceId}/${context.projectSlug}`;
47
+ try {
48
+ const response = await fetch(`${apiUrl}/api/doctor/report`, {
49
+ method: "POST",
50
+ headers: {
51
+ "Content-Type": "application/json",
52
+ "x-api-key": apiKey,
53
+ "X-Doctor-Project": doctorProject,
54
+ },
55
+ body: JSON.stringify(report),
56
+ });
57
+ if (!response.ok) {
58
+ const errorText = await response.text().catch(() => "Unknown error");
59
+ console.warn(` Warning: Report upload failed (${response.status}): ${errorText}`);
60
+ return null;
61
+ }
62
+ const data = (await response.json());
63
+ if (!data.reportId) {
64
+ console.warn(" Warning: Unexpected API response. Skipping.");
65
+ return null;
66
+ }
67
+ return {
68
+ reportId: data.reportId,
69
+ url: data.url || `https://dash.better-i18n.com/${context.workspaceId}/${context.projectSlug}/integrations/doctor?reportId=${data.reportId}`,
70
+ };
71
+ }
72
+ catch (error) {
73
+ console.warn(` Warning: Report upload failed: ${error instanceof Error ? error.message : String(error)}`);
74
+ return null;
75
+ }
76
+ }
77
+ /**
78
+ * Report using GitHub Actions OIDC token (original flow).
79
+ */
80
+ async function reportWithOidc(report, apiUrl) {
20
81
  if (!isGitHubActionsWithOidc()) {
21
- console.warn(" Warning: --report requires GitHub Actions with OIDC.\n" +
22
- " Add `permissions: id-token: write` to your workflow.\n" +
82
+ console.warn(" Warning: --report requires GitHub Actions OIDC or --api-key flag.\n" +
83
+ " For GitHub Actions: add `permissions: id-token: write` to your workflow.\n" +
84
+ " For local/non-GitHub CI: use --api-key <your-better-auth-api-key>\n" +
23
85
  " Skipping report upload.");
24
86
  return null;
25
87
  }
@@ -28,8 +90,6 @@ export async function reportToApi(report) {
28
90
  console.warn(" Warning: Failed to fetch OIDC token. Skipping report upload.");
29
91
  return null;
30
92
  }
31
- // 2. Send report to API
32
- const apiUrl = process.env.BETTER_I18N_API_URL || DEFAULT_API_URL;
33
93
  try {
34
94
  const response = await fetch(`${apiUrl}/api/doctor/report`, {
35
95
  method: "POST",
@@ -51,7 +111,7 @@ export async function reportToApi(report) {
51
111
  }
52
112
  return {
53
113
  reportId: data.reportId,
54
- url: data.url || `${apiUrl}/doctor/${data.reportId}`,
114
+ url: data.url || "https://dash.better-i18n.com",
55
115
  };
56
116
  }
57
117
  catch (error) {
@@ -1 +1 @@
1
- {"version":3,"file":"doctor-report.js","sourceRoot":"","sources":["../../src/reporters/doctor-report.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAEnF,MAAM,eAAe,GAAG,6BAA6B,CAAC;AAOtD;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,MAAoB;IAEpB,uCAAuC;IACvC,IAAI,CAAC,uBAAuB,EAAE,EAAE,CAAC;QAC/B,OAAO,CAAC,IAAI,CACV,0DAA0D;YAC1D,0DAA0D;YAC1D,2BAA2B,CAC5B,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,oBAAoB,CAAC,aAAa,CAAC,CAAC;IACxD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CAAC,IAAI,CACV,gEAAgE,CACjE,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,wBAAwB;IACxB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,eAAe,CAAC;IAElE,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,MAAM,oBAAoB,EAAE;YAC1D,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,aAAa,EAAE,UAAU,KAAK,EAAE;aACjC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;SAC7B,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC,CAAC;YACrE,OAAO,CAAC,IAAI,CACV,oCAAoC,QAAQ,CAAC,MAAM,MAAM,SAAS,EAAE,CACrE,CAAC;YACF,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAGlC,CAAC;QAEF,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnB,OAAO,CAAC,IAAI,CAAC,+CAA+C,CAAC,CAAC;YAC9D,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO;YACL,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,GAAG,MAAM,WAAW,IAAI,CAAC,QAAQ,EAAE;SACrD,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CACV,oCAAoC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAC7F,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"doctor-report.js","sourceRoot":"","sources":["../../src/reporters/doctor-report.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"categories.d.ts","sourceRoot":"","sources":["../../src/rules/categories.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,CAgBxE,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CA4BhD,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,CAgB5E,CAAC"}
1
+ {"version":3,"file":"categories.d.ts","sourceRoot":"","sources":["../../src/rules/categories.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,CAoBxE,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAkChD,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,CAoB5E,CAAC"}
@@ -25,6 +25,9 @@ export const RULE_CATEGORY_MAP = {
25
25
  "key-naming": "Structure",
26
26
  "namespace-structure": "Structure",
27
27
  "file-format": "Structure",
28
+ // ── Sync Rules (remote CDN comparison) ───────────────────────────
29
+ "missing-in-remote": "Coverage",
30
+ "unused-remote-key": "Performance",
28
31
  // ── Code Rules (AST analysis, from existing analyzer) ─────────────
29
32
  "jsx-text": "Code",
30
33
  "jsx-attribute": "Code",
@@ -47,6 +50,9 @@ export const RULE_HELP_MAP = {
47
50
  "key-naming": "Use consistent naming convention within each namespace (e.g., camelCase or snake_case, not mixed)",
48
51
  "namespace-structure": "Maintain consistent namespace depth across translation files for predictable key organization",
49
52
  "file-format": "Fix malformed JSON or encoding issues in translation files",
53
+ // ── Sync Rules ────────────────────────────────────────────────────
54
+ "missing-in-remote": "Key found in code but not in remote translations. Run sync or add the key in the editor",
55
+ "unused-remote-key": "Key exists in remote but not used in code. Consider removing it to reduce bundle size",
50
56
  // ── Code Rules ────────────────────────────────────────────────────
51
57
  "jsx-text": "Wrap hardcoded JSX text with t() function call for translation support",
52
58
  "jsx-attribute": "Use t() for translatable attributes like title, alt, placeholder, aria-label",
@@ -70,6 +76,9 @@ export const RULE_DEFAULT_SEVERITY = {
70
76
  "key-naming": "warning",
71
77
  "namespace-structure": "info",
72
78
  "file-format": "error",
79
+ // Sync rules
80
+ "missing-in-remote": "warning",
81
+ "unused-remote-key": "info",
73
82
  // Code rules
74
83
  "jsx-text": "warning",
75
84
  "jsx-attribute": "warning",
@@ -1 +1 @@
1
- {"version":3,"file":"categories.js","sourceRoot":"","sources":["../../src/rules/categories.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAA+C;IAC3E,qEAAqE;IACrE,sBAAsB,EAAE,UAAU;IAClC,aAAa,EAAE,aAAa;IAC5B,sBAAsB,EAAE,SAAS;IACjC,oBAAoB,EAAE,SAAS;IAC/B,YAAY,EAAE,WAAW;IACzB,qBAAqB,EAAE,WAAW;IAClC,aAAa,EAAE,WAAW;IAE1B,qEAAqE;IACrE,UAAU,EAAE,MAAM;IAClB,eAAe,EAAE,MAAM;IACvB,gBAAgB,EAAE,MAAM;IACxB,eAAe,EAAE,MAAM;IACvB,iBAAiB,EAAE,MAAM;CAC1B,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,aAAa,GAA2B;IACnD,qEAAqE;IACrE,sBAAsB,EACpB,qFAAqF;IACvF,aAAa,EACX,sFAAsF;IACxF,sBAAsB,EACpB,2HAA2H;IAC7H,oBAAoB,EAClB,yFAAyF;IAC3F,YAAY,EACV,mGAAmG;IACrG,qBAAqB,EACnB,+FAA+F;IACjG,aAAa,EACX,4DAA4D;IAE9D,qEAAqE;IACrE,UAAU,EACR,wEAAwE;IAC1E,eAAe,EACb,8EAA8E;IAChF,gBAAgB,EACd,wFAAwF;IAC1F,eAAe,EACb,mEAAmE;IACrE,iBAAiB,EACf,sEAAsE;CACzE,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAA+C;IAC/E,oEAAoE;IACpE,sBAAsB,EAAE,OAAO;IAC/B,aAAa,EAAE,SAAS;IACxB,sBAAsB,EAAE,OAAO;IAC/B,oBAAoB,EAAE,SAAS;IAC/B,YAAY,EAAE,SAAS;IACvB,qBAAqB,EAAE,MAAM;IAC7B,aAAa,EAAE,OAAO;IAEtB,aAAa;IACb,UAAU,EAAE,SAAS;IACrB,eAAe,EAAE,SAAS;IAC1B,gBAAgB,EAAE,OAAO;IACzB,eAAe,EAAE,SAAS;IAC1B,iBAAiB,EAAE,SAAS;CAC7B,CAAC"}
1
+ {"version":3,"file":"categories.js","sourceRoot":"","sources":["../../src/rules/categories.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAA+C;IAC3E,qEAAqE;IACrE,sBAAsB,EAAE,UAAU;IAClC,aAAa,EAAE,aAAa;IAC5B,sBAAsB,EAAE,SAAS;IACjC,oBAAoB,EAAE,SAAS;IAC/B,YAAY,EAAE,WAAW;IACzB,qBAAqB,EAAE,WAAW;IAClC,aAAa,EAAE,WAAW;IAE1B,oEAAoE;IACpE,mBAAmB,EAAE,UAAU;IAC/B,mBAAmB,EAAE,aAAa;IAElC,qEAAqE;IACrE,UAAU,EAAE,MAAM;IAClB,eAAe,EAAE,MAAM;IACvB,gBAAgB,EAAE,MAAM;IACxB,eAAe,EAAE,MAAM;IACvB,iBAAiB,EAAE,MAAM;CAC1B,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,aAAa,GAA2B;IACnD,qEAAqE;IACrE,sBAAsB,EACpB,qFAAqF;IACvF,aAAa,EACX,sFAAsF;IACxF,sBAAsB,EACpB,2HAA2H;IAC7H,oBAAoB,EAClB,yFAAyF;IAC3F,YAAY,EACV,mGAAmG;IACrG,qBAAqB,EACnB,+FAA+F;IACjG,aAAa,EACX,4DAA4D;IAE9D,qEAAqE;IACrE,mBAAmB,EACjB,yFAAyF;IAC3F,mBAAmB,EACjB,uFAAuF;IAEzF,qEAAqE;IACrE,UAAU,EACR,wEAAwE;IAC1E,eAAe,EACb,8EAA8E;IAChF,gBAAgB,EACd,wFAAwF;IAC1F,eAAe,EACb,mEAAmE;IACrE,iBAAiB,EACf,sEAAsE;CACzE,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAA+C;IAC/E,oEAAoE;IACpE,sBAAsB,EAAE,OAAO;IAC/B,aAAa,EAAE,SAAS;IACxB,sBAAsB,EAAE,OAAO;IAC/B,oBAAoB,EAAE,SAAS;IAC/B,YAAY,EAAE,SAAS;IACvB,qBAAqB,EAAE,MAAM;IAC7B,aAAa,EAAE,OAAO;IAEtB,aAAa;IACb,mBAAmB,EAAE,SAAS;IAC9B,mBAAmB,EAAE,MAAM;IAE3B,aAAa;IACb,UAAU,EAAE,SAAS;IACrB,eAAe,EAAE,SAAS;IAC1B,gBAAgB,EAAE,OAAO;IACzB,eAAe,EAAE,SAAS;IAC1B,iBAAiB,EAAE,SAAS;CAC7B,CAAC"}
@@ -15,7 +15,7 @@ export const missingTranslationsRule = {
15
15
  defaultSeverity: "error",
16
16
  description: "Detect keys present in source locale but missing in target locales",
17
17
  run(context) {
18
- const { sourceLocale, targetLocales, translations } = context;
18
+ const { sourceLocale, targetLocales, translations, localeFilePaths } = context;
19
19
  const sourceKeys = translations[sourceLocale];
20
20
  if (!sourceKeys)
21
21
  return [];
@@ -27,7 +27,7 @@ export const missingTranslationsRule = {
27
27
  if (!(key in targetKeys)) {
28
28
  const namespace = key.split(".")[0] || "default";
29
29
  diagnostics.push({
30
- filePath: `${targetLocale}.json`,
30
+ filePath: localeFilePaths?.[targetLocale] ?? `${targetLocale}.json`,
31
31
  line: 0,
32
32
  column: 0,
33
33
  rule: RULE_ID,
@@ -1 +1 @@
1
- {"version":3,"file":"missing-translations.js","sourceRoot":"","sources":["../../../src/rules/health/missing-translations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAOpE,MAAM,OAAO,GAAG,sBAAsB,CAAC;AAEvC,MAAM,CAAC,MAAM,uBAAuB,GAAe;IACjD,EAAE,EAAE,OAAO;IACX,eAAe,EAAE,OAAO;IACxB,WAAW,EACT,oEAAoE;IAEtE,GAAG,CAAC,OAA0B;QAC5B,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC;QAE9D,MAAM,UAAU,GAAG,YAAY,CAAC,YAAY,CAAC,CAAC;QAC9C,IAAI,CAAC,UAAU;YAAE,OAAO,EAAE,CAAC;QAE3B,MAAM,WAAW,GAAqB,EAAE,CAAC;QACzC,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAE7C,KAAK,MAAM,YAAY,IAAI,aAAa,EAAE,CAAC;YACzC,MAAM,UAAU,GAAG,YAAY,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;YAEpD,KAAK,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;gBAC/B,IAAI,CAAC,CAAC,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC;oBACzB,MAAM,SAAS,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC;oBAEjD,WAAW,CAAC,IAAI,CAAC;wBACf,QAAQ,EAAE,GAAG,YAAY,OAAO;wBAChC,IAAI,EAAE,CAAC;wBACP,MAAM,EAAE,CAAC;wBACT,IAAI,EAAE,OAAO;wBACb,QAAQ,EAAE,iBAAiB,CAAC,OAAO,CAAC,IAAI,UAAU;wBAClD,QAAQ,EAAE,IAAI,CAAC,eAAe;wBAC9B,OAAO,EAAE,QAAQ,GAAG,2BAA2B,YAAY,GAAG;wBAC9D,IAAI,EAAE,aAAa,CAAC,OAAO,CAAC,IAAI,EAAE;wBAClC,GAAG;wBACH,SAAS;wBACT,QAAQ,EAAE,YAAY;qBACvB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,WAAW,CAAC;IACrB,CAAC;CACF,CAAC"}
1
+ {"version":3,"file":"missing-translations.js","sourceRoot":"","sources":["../../../src/rules/health/missing-translations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAOpE,MAAM,OAAO,GAAG,sBAAsB,CAAC;AAEvC,MAAM,CAAC,MAAM,uBAAuB,GAAe;IACjD,EAAE,EAAE,OAAO;IACX,eAAe,EAAE,OAAO;IACxB,WAAW,EACT,oEAAoE;IAEtE,GAAG,CAAC,OAA0B;QAC5B,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC;QAE/E,MAAM,UAAU,GAAG,YAAY,CAAC,YAAY,CAAC,CAAC;QAC9C,IAAI,CAAC,UAAU;YAAE,OAAO,EAAE,CAAC;QAE3B,MAAM,WAAW,GAAqB,EAAE,CAAC;QACzC,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAE7C,KAAK,MAAM,YAAY,IAAI,aAAa,EAAE,CAAC;YACzC,MAAM,UAAU,GAAG,YAAY,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;YAEpD,KAAK,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;gBAC/B,IAAI,CAAC,CAAC,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC;oBACzB,MAAM,SAAS,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC;oBAEjD,WAAW,CAAC,IAAI,CAAC;wBACf,QAAQ,EAAE,eAAe,EAAE,CAAC,YAAY,CAAC,IAAI,GAAG,YAAY,OAAO;wBACnE,IAAI,EAAE,CAAC;wBACP,MAAM,EAAE,CAAC;wBACT,IAAI,EAAE,OAAO;wBACb,QAAQ,EAAE,iBAAiB,CAAC,OAAO,CAAC,IAAI,UAAU;wBAClD,QAAQ,EAAE,IAAI,CAAC,eAAe;wBAC9B,OAAO,EAAE,QAAQ,GAAG,2BAA2B,YAAY,GAAG;wBAC9D,IAAI,EAAE,aAAa,CAAC,OAAO,CAAC,IAAI,EAAE;wBAClC,GAAG;wBACH,SAAS;wBACT,QAAQ,EAAE,YAAY;qBACvB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,WAAW,CAAC;IACrB,CAAC;CACF,CAAC"}
@@ -18,7 +18,7 @@ export const orphanKeysRule = {
18
18
  defaultSeverity: "warning",
19
19
  description: "Detect translation keys not referenced in code (dead translations)",
20
20
  run(context) {
21
- const { sourceLocale, translations, codeKeys } = context;
21
+ const { sourceLocale, translations, codeKeys, localeFilePaths } = context;
22
22
  // If no code keys were collected, skip — we can't determine orphans
23
23
  // without knowing what code actually uses.
24
24
  if (codeKeys.size === 0)
@@ -31,7 +31,7 @@ export const orphanKeysRule = {
31
31
  if (!codeKeys.has(key)) {
32
32
  const namespace = key.split(".")[0] || "default";
33
33
  diagnostics.push({
34
- filePath: `${sourceLocale}.json`,
34
+ filePath: localeFilePaths?.[sourceLocale] ?? `${sourceLocale}.json`,
35
35
  line: 0,
36
36
  column: 0,
37
37
  rule: RULE_ID,
@@ -1 +1 @@
1
- {"version":3,"file":"orphan-keys.js","sourceRoot":"","sources":["../../../src/rules/health/orphan-keys.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAOpE,MAAM,OAAO,GAAG,aAAa,CAAC;AAE9B,MAAM,CAAC,MAAM,cAAc,GAAe;IACxC,EAAE,EAAE,OAAO;IACX,eAAe,EAAE,SAAS;IAC1B,WAAW,EACT,oEAAoE;IAEtE,GAAG,CAAC,OAA0B;QAC5B,MAAM,EAAE,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;QAEzD,oEAAoE;QACpE,2CAA2C;QAC3C,IAAI,QAAQ,CAAC,IAAI,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QAEnC,MAAM,UAAU,GAAG,YAAY,CAAC,YAAY,CAAC,CAAC;QAC9C,IAAI,CAAC,UAAU;YAAE,OAAO,EAAE,CAAC;QAE3B,MAAM,WAAW,GAAqB,EAAE,CAAC;QAEzC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;YAC1C,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;gBACvB,MAAM,SAAS,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC;gBAEjD,WAAW,CAAC,IAAI,CAAC;oBACf,QAAQ,EAAE,GAAG,YAAY,OAAO;oBAChC,IAAI,EAAE,CAAC;oBACP,MAAM,EAAE,CAAC;oBACT,IAAI,EAAE,OAAO;oBACb,QAAQ,EAAE,iBAAiB,CAAC,OAAO,CAAC,IAAI,aAAa;oBACrD,QAAQ,EAAE,IAAI,CAAC,eAAe;oBAC9B,OAAO,EAAE,QAAQ,GAAG,kDAAkD;oBACtE,IAAI,EAAE,aAAa,CAAC,OAAO,CAAC,IAAI,EAAE;oBAClC,GAAG;oBACH,SAAS;iBACV,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO,WAAW,CAAC;IACrB,CAAC;CACF,CAAC"}
1
+ {"version":3,"file":"orphan-keys.js","sourceRoot":"","sources":["../../../src/rules/health/orphan-keys.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAOpE,MAAM,OAAO,GAAG,aAAa,CAAC;AAE9B,MAAM,CAAC,MAAM,cAAc,GAAe;IACxC,EAAE,EAAE,OAAO;IACX,eAAe,EAAE,SAAS;IAC1B,WAAW,EACT,oEAAoE;IAEtE,GAAG,CAAC,OAA0B;QAC5B,MAAM,EAAE,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC;QAE1E,oEAAoE;QACpE,2CAA2C;QAC3C,IAAI,QAAQ,CAAC,IAAI,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QAEnC,MAAM,UAAU,GAAG,YAAY,CAAC,YAAY,CAAC,CAAC;QAC9C,IAAI,CAAC,UAAU;YAAE,OAAO,EAAE,CAAC;QAE3B,MAAM,WAAW,GAAqB,EAAE,CAAC;QAEzC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;YAC1C,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;gBACvB,MAAM,SAAS,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC;gBAEjD,WAAW,CAAC,IAAI,CAAC;oBACf,QAAQ,EAAE,eAAe,EAAE,CAAC,YAAY,CAAC,IAAI,GAAG,YAAY,OAAO;oBACnE,IAAI,EAAE,CAAC;oBACP,MAAM,EAAE,CAAC;oBACT,IAAI,EAAE,OAAO;oBACb,QAAQ,EAAE,iBAAiB,CAAC,OAAO,CAAC,IAAI,aAAa;oBACrD,QAAQ,EAAE,IAAI,CAAC,eAAe;oBAC9B,OAAO,EAAE,QAAQ,GAAG,kDAAkD;oBACtE,IAAI,EAAE,aAAa,CAAC,OAAO,CAAC,IAAI,EAAE;oBAClC,GAAG;oBACH,SAAS;iBACV,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO,WAAW,CAAC;IACrB,CAAC;CACF,CAAC"}
@@ -60,7 +60,7 @@ export const placeholderMismatchRule = {
60
60
  defaultSeverity: "error",
61
61
  description: "Detect placeholder mismatches between source and target translations",
62
62
  run(context) {
63
- const { sourceLocale, targetLocales, translations } = context;
63
+ const { sourceLocale, targetLocales, translations, localeFilePaths } = context;
64
64
  const sourceKeys = translations[sourceLocale];
65
65
  if (!sourceKeys)
66
66
  return [];
@@ -80,7 +80,7 @@ export const placeholderMismatchRule = {
80
80
  for (const ph of sourcePh) {
81
81
  if (!targetPh.includes(ph)) {
82
82
  diagnostics.push({
83
- filePath: `${targetLocale}.json`,
83
+ filePath: localeFilePaths?.[targetLocale] ?? `${targetLocale}.json`,
84
84
  line: 0,
85
85
  column: 0,
86
86
  rule: RULE_ID,
@@ -98,7 +98,7 @@ export const placeholderMismatchRule = {
98
98
  for (const ph of targetPh) {
99
99
  if (!sourcePh.includes(ph)) {
100
100
  diagnostics.push({
101
- filePath: `${targetLocale}.json`,
101
+ filePath: localeFilePaths?.[targetLocale] ?? `${targetLocale}.json`,
102
102
  line: 0,
103
103
  column: 0,
104
104
  rule: RULE_ID,