@better-i18n/cli 0.1.7 → 0.2.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.
Files changed (142) hide show
  1. package/dist/analyzer/dynamic-matcher.d.ts +53 -0
  2. package/dist/analyzer/dynamic-matcher.d.ts.map +1 -0
  3. package/dist/analyzer/dynamic-matcher.js +93 -0
  4. package/dist/analyzer/dynamic-matcher.js.map +1 -0
  5. package/dist/analyzer/index.d.ts +13 -4
  6. package/dist/analyzer/index.d.ts.map +1 -1
  7. package/dist/analyzer/index.js +165 -22
  8. package/dist/analyzer/index.js.map +1 -1
  9. package/dist/analyzer/rules/data-structure.d.ts +13 -0
  10. package/dist/analyzer/rules/data-structure.d.ts.map +1 -0
  11. package/dist/analyzer/rules/data-structure.js +264 -0
  12. package/dist/analyzer/rules/data-structure.js.map +1 -0
  13. package/dist/analyzer/rules/index.d.ts +10 -7
  14. package/dist/analyzer/rules/index.d.ts.map +1 -1
  15. package/dist/analyzer/rules/index.js +10 -7
  16. package/dist/analyzer/rules/index.js.map +1 -1
  17. package/dist/analyzer/rules/jsx-text.js +1 -1
  18. package/dist/analyzer/rules/jsx-text.js.map +1 -1
  19. package/dist/analyzer/rules/translation-function.d.ts.map +1 -1
  20. package/dist/analyzer/rules/translation-function.js +94 -6
  21. package/dist/analyzer/rules/translation-function.js.map +1 -1
  22. package/dist/analyzer/types.d.ts +28 -3
  23. package/dist/analyzer/types.d.ts.map +1 -1
  24. package/dist/commands/check.d.ts +14 -0
  25. package/dist/commands/check.d.ts.map +1 -0
  26. package/dist/commands/check.js +70 -0
  27. package/dist/commands/check.js.map +1 -0
  28. package/dist/commands/doctor.d.ts +20 -0
  29. package/dist/commands/doctor.d.ts.map +1 -0
  30. package/dist/commands/doctor.js +77 -0
  31. package/dist/commands/doctor.js.map +1 -0
  32. package/dist/commands/sync.d.ts +1 -0
  33. package/dist/commands/sync.d.ts.map +1 -1
  34. package/dist/commands/sync.js +158 -272
  35. package/dist/commands/sync.js.map +1 -1
  36. package/dist/context/detector.js +1 -1
  37. package/dist/context/detector.js.map +1 -1
  38. package/dist/context/oidc.d.ts +33 -0
  39. package/dist/context/oidc.d.ts.map +1 -0
  40. package/dist/context/oidc.js +63 -0
  41. package/dist/context/oidc.js.map +1 -0
  42. package/dist/doctor/index.d.ts +65 -0
  43. package/dist/doctor/index.d.ts.map +1 -0
  44. package/dist/doctor/index.js +252 -0
  45. package/dist/doctor/index.js.map +1 -0
  46. package/dist/doctor/project-discovery.d.ts +37 -0
  47. package/dist/doctor/project-discovery.d.ts.map +1 -0
  48. package/dist/doctor/project-discovery.js +140 -0
  49. package/dist/doctor/project-discovery.js.map +1 -0
  50. package/dist/doctor/score.d.ts +41 -0
  51. package/dist/doctor/score.d.ts.map +1 -0
  52. package/dist/doctor/score.js +107 -0
  53. package/dist/doctor/score.js.map +1 -0
  54. package/dist/index.js +35 -0
  55. package/dist/index.js.map +1 -1
  56. package/dist/reporters/doctor-eslint.d.ts +17 -0
  57. package/dist/reporters/doctor-eslint.d.ts.map +1 -0
  58. package/dist/reporters/doctor-eslint.js +139 -0
  59. package/dist/reporters/doctor-eslint.js.map +1 -0
  60. package/dist/reporters/doctor-json.d.ts +12 -0
  61. package/dist/reporters/doctor-json.d.ts.map +1 -0
  62. package/dist/reporters/doctor-json.js +21 -0
  63. package/dist/reporters/doctor-json.js.map +1 -0
  64. package/dist/reporters/doctor-report.d.ts +23 -0
  65. package/dist/reporters/doctor-report.d.ts.map +1 -0
  66. package/dist/reporters/doctor-report.js +62 -0
  67. package/dist/reporters/doctor-report.js.map +1 -0
  68. package/dist/reporters/eslint-style.js +4 -4
  69. package/dist/reporters/eslint-style.js.map +1 -1
  70. package/dist/rules/categories.d.ts +36 -0
  71. package/dist/rules/categories.d.ts.map +1 -0
  72. package/dist/rules/categories.js +80 -0
  73. package/dist/rules/categories.js.map +1 -0
  74. package/dist/rules/code/index.d.ts +9 -0
  75. package/dist/rules/code/index.d.ts.map +1 -0
  76. package/dist/rules/code/index.js +9 -0
  77. package/dist/rules/code/index.js.map +1 -0
  78. package/dist/rules/code/jsx-attribute.d.ts +12 -0
  79. package/dist/rules/code/jsx-attribute.d.ts.map +1 -0
  80. package/dist/rules/code/jsx-attribute.js +78 -0
  81. package/dist/rules/code/jsx-attribute.js.map +1 -0
  82. package/dist/rules/code/jsx-text.d.ts +12 -0
  83. package/dist/rules/code/jsx-text.d.ts.map +1 -0
  84. package/dist/rules/code/jsx-text.js +47 -0
  85. package/dist/rules/code/jsx-text.js.map +1 -0
  86. package/dist/rules/code/string-variable.d.ts +13 -0
  87. package/dist/rules/code/string-variable.d.ts.map +1 -0
  88. package/dist/rules/code/string-variable.js +185 -0
  89. package/dist/rules/code/string-variable.js.map +1 -0
  90. package/dist/rules/code/ternary-locale.d.ts +12 -0
  91. package/dist/rules/code/ternary-locale.d.ts.map +1 -0
  92. package/dist/rules/code/ternary-locale.js +53 -0
  93. package/dist/rules/code/ternary-locale.js.map +1 -0
  94. package/dist/rules/code/toast-message.d.ts +13 -0
  95. package/dist/rules/code/toast-message.d.ts.map +1 -0
  96. package/dist/rules/code/toast-message.js +101 -0
  97. package/dist/rules/code/toast-message.js.map +1 -0
  98. package/dist/rules/extraction/data-structure.d.ts +13 -0
  99. package/dist/rules/extraction/data-structure.d.ts.map +1 -0
  100. package/dist/rules/extraction/data-structure.js +212 -0
  101. package/dist/rules/extraction/data-structure.js.map +1 -0
  102. package/dist/rules/extraction/index.d.ts +6 -0
  103. package/dist/rules/extraction/index.d.ts.map +1 -0
  104. package/dist/rules/extraction/index.js +6 -0
  105. package/dist/rules/extraction/index.js.map +1 -0
  106. package/dist/rules/extraction/translation-function.d.ts +12 -0
  107. package/dist/rules/extraction/translation-function.d.ts.map +1 -0
  108. package/dist/rules/extraction/translation-function.js +153 -0
  109. package/dist/rules/extraction/translation-function.js.map +1 -0
  110. package/dist/rules/health/index.d.ts +16 -0
  111. package/dist/rules/health/index.d.ts.map +1 -0
  112. package/dist/rules/health/index.js +22 -0
  113. package/dist/rules/health/index.js.map +1 -0
  114. package/dist/rules/health/missing-translations.d.ts +13 -0
  115. package/dist/rules/health/missing-translations.d.ts.map +1 -0
  116. package/dist/rules/health/missing-translations.js +48 -0
  117. package/dist/rules/health/missing-translations.js.map +1 -0
  118. package/dist/rules/health/orphan-keys.d.ts +16 -0
  119. package/dist/rules/health/orphan-keys.d.ts.map +1 -0
  120. package/dist/rules/health/orphan-keys.js +50 -0
  121. package/dist/rules/health/orphan-keys.js.map +1 -0
  122. package/dist/rules/health/placeholder-mismatch.d.ts +32 -0
  123. package/dist/rules/health/placeholder-mismatch.d.ts.map +1 -0
  124. package/dist/rules/health/placeholder-mismatch.js +120 -0
  125. package/dist/rules/health/placeholder-mismatch.js.map +1 -0
  126. package/dist/rules/registry.d.ts +84 -0
  127. package/dist/rules/registry.d.ts.map +1 -0
  128. package/dist/rules/registry.js +11 -0
  129. package/dist/rules/registry.js.map +1 -0
  130. package/dist/utils/cdn-client.d.ts +30 -0
  131. package/dist/utils/cdn-client.d.ts.map +1 -0
  132. package/dist/utils/cdn-client.js +59 -0
  133. package/dist/utils/cdn-client.js.map +1 -0
  134. package/dist/utils/json-keys.d.ts +60 -0
  135. package/dist/utils/json-keys.d.ts.map +1 -0
  136. package/dist/utils/json-keys.js +103 -0
  137. package/dist/utils/json-keys.js.map +1 -0
  138. package/dist/utils/key-comparison.d.ts +67 -0
  139. package/dist/utils/key-comparison.d.ts.map +1 -0
  140. package/dist/utils/key-comparison.js +299 -0
  141. package/dist/utils/key-comparison.js.map +1 -0
  142. package/package.json +2 -2
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Dynamic pattern matching utility
3
+ *
4
+ * Matches dynamic key patterns (e.g., 'plans.${x}.name') against remote keys
5
+ */
6
+ /**
7
+ * Convert a dynamic pattern to a regex
8
+ * Examples:
9
+ * 'plans.${planKey}.name' -> /^plans\..*?\.name$/
10
+ * '${namespace}.title' -> /^.*?\.title$/
11
+ * 'workflow.steps.${key}.title' -> /^workflow\.steps\..*?\.title$/
12
+ */
13
+ export declare function patternToRegex(pattern: string): RegExp;
14
+ /**
15
+ * Extract static segments from a pattern
16
+ * Examples:
17
+ * 'plans.${x}.name' -> { prefix: 'plans', suffix: 'name', hasPrefix: true, hasSuffix: true }
18
+ * '${namespace}.title' -> { prefix: '', suffix: 'title', hasPrefix: false, hasSuffix: true }
19
+ */
20
+ export declare function extractStaticSegments(pattern: string): {
21
+ prefix: string;
22
+ suffix: string;
23
+ hasPrefix: boolean;
24
+ hasSuffix: boolean;
25
+ };
26
+ /**
27
+ * Match a dynamic pattern against remote keys
28
+ * Returns all matching keys
29
+ *
30
+ * @param pattern - Dynamic pattern like 'plans.${x}.name'
31
+ * @param remoteKeys - Array of all remote keys
32
+ * @returns Array of matching remote keys
33
+ */
34
+ export declare function matchDynamicPattern(pattern: string, remoteKeys: string[]): string[];
35
+ /**
36
+ * Group dynamic patterns by their static prefix for efficient matching
37
+ * This helps identify which remote keys might be accessed by dynamic patterns
38
+ *
39
+ * @param patterns - Array of dynamic patterns
40
+ * @returns Map of prefix -> patterns with that prefix
41
+ */
42
+ export declare function groupPatternsByPrefix(patterns: string[]): Map<string, string[]>;
43
+ /**
44
+ * Check if a pattern is ambiguous (matches too many keys)
45
+ * This helps identify patterns that need manual review
46
+ *
47
+ * @param pattern - Dynamic pattern
48
+ * @param matchCount - Number of keys matched by this pattern
49
+ * @param threshold - Maximum number of matches to consider reasonable (default: 50)
50
+ * @returns True if the pattern is ambiguous
51
+ */
52
+ export declare function isAmbiguousPattern(pattern: string, matchCount: number, threshold?: number): boolean;
53
+ //# sourceMappingURL=dynamic-matcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dynamic-matcher.d.ts","sourceRoot":"","sources":["../../src/analyzer/dynamic-matcher.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAatD;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG;IACtD,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;CACpB,CAiBA;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAGnF;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAc/E;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,SAAS,GAAE,MAAW,GACrB,OAAO,CAOT"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Dynamic pattern matching utility
3
+ *
4
+ * Matches dynamic key patterns (e.g., 'plans.${x}.name') against remote keys
5
+ */
6
+ /**
7
+ * Convert a dynamic pattern to a regex
8
+ * Examples:
9
+ * 'plans.${planKey}.name' -> /^plans\..*?\.name$/
10
+ * '${namespace}.title' -> /^.*?\.title$/
11
+ * 'workflow.steps.${key}.title' -> /^workflow\.steps\..*?\.title$/
12
+ */
13
+ export function patternToRegex(pattern) {
14
+ // First, replace ${variable} with a placeholder that won't be escaped
15
+ const placeholder = '\x00WILDCARD\x00';
16
+ let regexPattern = pattern.replace(/\$\{[^}]+\}/g, placeholder);
17
+ // Escape special regex characters (including dots)
18
+ regexPattern = regexPattern.replace(/[.+?^${}()|[\]\\]/g, '\\$&');
19
+ // Replace placeholder with .*? (non-greedy wildcard)
20
+ regexPattern = regexPattern.replace(new RegExp(placeholder.replace(/\\/g, '\\\\'), 'g'), '.*?');
21
+ // Return regex with anchors
22
+ return new RegExp(`^${regexPattern}$`);
23
+ }
24
+ /**
25
+ * Extract static segments from a pattern
26
+ * Examples:
27
+ * 'plans.${x}.name' -> { prefix: 'plans', suffix: 'name', hasPrefix: true, hasSuffix: true }
28
+ * '${namespace}.title' -> { prefix: '', suffix: 'title', hasPrefix: false, hasSuffix: true }
29
+ */
30
+ export function extractStaticSegments(pattern) {
31
+ // Find first ${}
32
+ const firstDynamic = pattern.indexOf('${');
33
+ const prefix = firstDynamic > 0 ? pattern.substring(0, firstDynamic) : '';
34
+ const hasPrefix = firstDynamic > 0;
35
+ // Find last }
36
+ const lastDynamic = pattern.lastIndexOf('}');
37
+ const suffix = lastDynamic < pattern.length - 1 ? pattern.substring(lastDynamic + 1) : '';
38
+ const hasSuffix = lastDynamic < pattern.length - 1;
39
+ return {
40
+ prefix: prefix.replace(/\.$/, ''), // Remove trailing dot
41
+ suffix: suffix.replace(/^\./, ''), // Remove leading dot
42
+ hasPrefix,
43
+ hasSuffix,
44
+ };
45
+ }
46
+ /**
47
+ * Match a dynamic pattern against remote keys
48
+ * Returns all matching keys
49
+ *
50
+ * @param pattern - Dynamic pattern like 'plans.${x}.name'
51
+ * @param remoteKeys - Array of all remote keys
52
+ * @returns Array of matching remote keys
53
+ */
54
+ export function matchDynamicPattern(pattern, remoteKeys) {
55
+ const regex = patternToRegex(pattern);
56
+ return remoteKeys.filter(key => regex.test(key));
57
+ }
58
+ /**
59
+ * Group dynamic patterns by their static prefix for efficient matching
60
+ * This helps identify which remote keys might be accessed by dynamic patterns
61
+ *
62
+ * @param patterns - Array of dynamic patterns
63
+ * @returns Map of prefix -> patterns with that prefix
64
+ */
65
+ export function groupPatternsByPrefix(patterns) {
66
+ const groups = new Map();
67
+ for (const pattern of patterns) {
68
+ const { prefix } = extractStaticSegments(pattern);
69
+ const groupKey = prefix || '(no-prefix)';
70
+ if (!groups.has(groupKey)) {
71
+ groups.set(groupKey, []);
72
+ }
73
+ groups.get(groupKey).push(pattern);
74
+ }
75
+ return groups;
76
+ }
77
+ /**
78
+ * Check if a pattern is ambiguous (matches too many keys)
79
+ * This helps identify patterns that need manual review
80
+ *
81
+ * @param pattern - Dynamic pattern
82
+ * @param matchCount - Number of keys matched by this pattern
83
+ * @param threshold - Maximum number of matches to consider reasonable (default: 50)
84
+ * @returns True if the pattern is ambiguous
85
+ */
86
+ export function isAmbiguousPattern(pattern, matchCount, threshold = 50) {
87
+ // Pattern starting with ${} is always ambiguous
88
+ if (pattern.startsWith('${')) {
89
+ return matchCount > 10;
90
+ }
91
+ return matchCount > threshold;
92
+ }
93
+ //# sourceMappingURL=dynamic-matcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dynamic-matcher.js","sourceRoot":"","sources":["../../src/analyzer/dynamic-matcher.ts"],"names":[],"mappings":"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"}
@@ -4,18 +4,27 @@
4
4
  * Parses TypeScript/JSX files and applies detection rules
5
5
  */
6
6
  import type { Issue, LintConfig } from "./types.js";
7
+ interface AnalyzerStats {
8
+ dynamicKeys: number;
9
+ dynamicNamespaces: number;
10
+ unboundTranslators: number;
11
+ rootScopedTranslators: number;
12
+ dataStructureKeys?: number;
13
+ dataStructureScopes?: number;
14
+ }
7
15
  /**
8
16
  * Analyze a single file for hardcoded strings
9
17
  */
10
- export declare function analyzeFile(filePath: string, config?: LintConfig): Promise<{
18
+ export declare function analyzeFile(filePath: string, config?: LintConfig, verbose?: boolean): Promise<{
11
19
  issues: Issue[];
12
- stats: any;
20
+ stats: AnalyzerStats;
13
21
  }>;
14
22
  /**
15
23
  * Analyze source text (useful for testing)
16
24
  */
17
- export declare function analyzeSourceText(sourceText: string, filePath: string, config?: LintConfig): {
25
+ export declare function analyzeSourceText(sourceText: string, filePath: string, config?: LintConfig, verbose?: boolean): {
18
26
  issues: Issue[];
19
- stats: any;
27
+ stats: AnalyzerStats;
20
28
  };
29
+ export {};
21
30
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/analyzer/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAYH,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAe,MAAM,YAAY,CAAC;AAEjE;;GAEG;AACH,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,UAAU,GAClB,OAAO,CAAC;IAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAAC,KAAK,EAAE,GAAG,CAAA;CAAE,CAAC,CAG1C;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,UAAU,GAClB;IAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAAC,KAAK,EAAE,GAAG,CAAA;CAAE,CAqNjC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/analyzer/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAaH,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAe,MAAM,YAAY,CAAC;AAGjE,UAAU,aAAa;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AASD;;GAEG;AACH,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,UAAU,EACnB,OAAO,CAAC,EAAE,OAAO,GAChB,OAAO,CAAC;IAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAAC,KAAK,EAAE,aAAa,CAAA;CAAE,CAAC,CAGpD;AAqCD;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,UAAU,EACnB,OAAO,CAAC,EAAE,OAAO,GAChB;IAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAAC,KAAK,EAAE,aAAa,CAAA;CAAE,CA2V3C"}
@@ -5,18 +5,47 @@
5
5
  */
6
6
  import { readFileSync } from "node:fs";
7
7
  import ts from "typescript";
8
- import { checkJsxAttribute, checkJsxText, checkStringVariable, checkTernaryLocale, checkToastMessage, checkTranslationFunction, } from "./rules/index.js";
8
+ import { checkDataStructure, checkJsxAttribute, checkJsxText, checkStringVariable, checkTernaryLocale, checkToastMessage, checkTranslationFunction, } from "./rules/index.js";
9
9
  /**
10
10
  * Analyze a single file for hardcoded strings
11
11
  */
12
- export async function analyzeFile(filePath, config) {
12
+ export async function analyzeFile(filePath, config, verbose) {
13
13
  const sourceText = readFileSync(filePath, "utf-8");
14
- return analyzeSourceText(sourceText, filePath, config);
14
+ return analyzeSourceText(sourceText, filePath, config, verbose);
15
+ }
16
+ /**
17
+ * Extract keys from @i18n-keys comments
18
+ * Examples:
19
+ * // @i18n-keys: pricing.plans.free.name, pricing.plans.pro.name
20
+ * /* @i18n-keys: common.title, common.description *\/
21
+ */
22
+ function extractAnnotatedKeys(sourceText) {
23
+ const keys = [];
24
+ // Match single-line comments: // @i18n-keys: key1, key2
25
+ const singleLineRegex = /\/\/\s*@i18n-keys:\s*([^\n]+)/g;
26
+ let match;
27
+ while ((match = singleLineRegex.exec(sourceText)) !== null) {
28
+ const keyList = match[1].trim();
29
+ const parsedKeys = keyList.split(',').map(k => k.trim()).filter(Boolean);
30
+ keys.push(...parsedKeys);
31
+ }
32
+ // Match multi-line comments: /* @i18n-keys: key1, key2 */
33
+ const multiLineRegex = /\/\*\s*@i18n-keys:\s*([^*]*)\*\//g;
34
+ while ((match = multiLineRegex.exec(sourceText)) !== null) {
35
+ const keyList = match[1].trim();
36
+ // Handle both comma-separated and line-separated keys
37
+ const parsedKeys = keyList
38
+ .split(/[,\n]/)
39
+ .map(k => k.trim().replace(/^-\s*/, '')) // Remove leading dashes for bullet lists
40
+ .filter(Boolean);
41
+ keys.push(...parsedKeys);
42
+ }
43
+ return keys;
15
44
  }
16
45
  /**
17
46
  * Analyze source text (useful for testing)
18
47
  */
19
- export function analyzeSourceText(sourceText, filePath, config) {
48
+ export function analyzeSourceText(sourceText, filePath, config, verbose) {
20
49
  const sourceFile = ts.createSourceFile(filePath, sourceText, ts.ScriptTarget.Latest, true, getScriptKind(filePath));
21
50
  const issues = [];
22
51
  const stats = {
@@ -24,26 +53,29 @@ export function analyzeSourceText(sourceText, filePath, config) {
24
53
  dynamicNamespaces: 0,
25
54
  unboundTranslators: 0,
26
55
  rootScopedTranslators: 0,
56
+ dataStructureKeys: 0,
57
+ dataStructureScopes: 0,
27
58
  };
28
- // Lexical scope stack: each element is a map of identifier -> NamespaceBinding
29
- // NamespaceBinding type is imported from types.js
30
- const scopeStack = [{}];
31
- function pushScope() {
32
- scopeStack.push({});
33
- }
34
- function popScope() {
35
- scopeStack.pop();
36
- }
37
- function getCurrentBindings() {
38
- const combined = {};
39
- for (const scope of scopeStack) {
40
- Object.assign(combined, scope);
41
- }
42
- return combined;
59
+ // Extract annotated keys from comments
60
+ const annotatedKeys = extractAnnotatedKeys(sourceText);
61
+ if (annotatedKeys.length > 0 && verbose) {
62
+ console.log(`[VERBOSE] Found ${annotatedKeys.length} annotated keys in ${filePath}`);
43
63
  }
44
- function registerBinding(name, binding) {
45
- scopeStack[scopeStack.length - 1][name] = binding;
64
+ // Add annotated keys as static translation keys
65
+ for (const key of annotatedKeys) {
66
+ issues.push({
67
+ file: filePath,
68
+ line: 0, // We don't track exact line for annotations
69
+ column: 0,
70
+ text: key,
71
+ type: "string-variable",
72
+ severity: "info",
73
+ message: `Annotated translation key: "${key}"`,
74
+ key,
75
+ bindingType: "unbound",
76
+ });
46
77
  }
78
+ // Helper function to detect binding from initializer (used in both pre-scan and main scan)
47
79
  function detectBinding(initializer) {
48
80
  // Unwrap await
49
81
  const call = ts.isAwaitExpression(initializer)
@@ -104,6 +136,80 @@ export function analyzeSourceText(sourceText, filePath, config) {
104
136
  }
105
137
  return null;
106
138
  }
139
+ // Pre-scan to find all useTranslations calls in the file
140
+ // This enables file-level namespace inference for data structures
141
+ const fileNamespaces = [];
142
+ // Lightweight namespace extraction (doesn't modify stats)
143
+ function extractNamespace(initializer) {
144
+ const call = ts.isAwaitExpression(initializer)
145
+ ? initializer.expression
146
+ : initializer;
147
+ if (!ts.isCallExpression(call))
148
+ return null;
149
+ const funcName = getIdentifierName(call.expression);
150
+ // Handle useTranslations/useTranslation
151
+ if (funcName === "useTranslations" || funcName === "useTranslation") {
152
+ if (call.arguments.length > 0 && ts.isStringLiteral(call.arguments[0])) {
153
+ return call.arguments[0].text;
154
+ }
155
+ }
156
+ // Handle getTranslations
157
+ if (funcName === "getTranslations") {
158
+ const arg = call.arguments[0];
159
+ if (arg) {
160
+ if (ts.isStringLiteral(arg)) {
161
+ return arg.text;
162
+ }
163
+ if (ts.isObjectLiteralExpression(arg)) {
164
+ const nsProp = arg.properties.find((p) => (ts.isPropertyAssignment(p) || ts.isShorthandPropertyAssignment(p)) &&
165
+ ts.isIdentifier(p.name) &&
166
+ p.name.text === "namespace");
167
+ if (nsProp && ts.isPropertyAssignment(nsProp) && ts.isStringLiteral(nsProp.initializer)) {
168
+ return nsProp.initializer.text;
169
+ }
170
+ }
171
+ }
172
+ }
173
+ return null;
174
+ }
175
+ function preScan(node) {
176
+ if (ts.isVariableDeclaration(node) && node.initializer) {
177
+ const namespace = extractNamespace(node.initializer);
178
+ if (namespace) {
179
+ fileNamespaces.push(namespace);
180
+ if (verbose) {
181
+ console.log(`[VERBOSE] Pre-scan found namespace: "${namespace}"`);
182
+ }
183
+ }
184
+ }
185
+ ts.forEachChild(node, preScan);
186
+ }
187
+ preScan(sourceFile);
188
+ if (fileNamespaces.length > 0 && verbose) {
189
+ console.log(`[VERBOSE] File-level namespaces: [${fileNamespaces.join(", ")}]`);
190
+ }
191
+ // Lexical scope stack: each element is a map of identifier -> NamespaceBinding
192
+ const scopeStack = [{}];
193
+ // Track if we're in a translation-aware function (has 't' parameter)
194
+ let translationScopeDepth = 0;
195
+ // Track if we're inside a data structure to avoid duplicate detection
196
+ let insideDataStructure = false;
197
+ function pushScope() {
198
+ scopeStack.push({});
199
+ }
200
+ function popScope() {
201
+ scopeStack.pop();
202
+ }
203
+ function getCurrentBindings() {
204
+ const combined = {};
205
+ for (const scope of scopeStack) {
206
+ Object.assign(combined, scope);
207
+ }
208
+ return combined;
209
+ }
210
+ function registerBinding(name, binding) {
211
+ scopeStack[scopeStack.length - 1][name] = binding;
212
+ }
107
213
  // Check if rules are enabled
108
214
  const rules = config?.rules || {};
109
215
  const jsxTextEnabled = rules["jsx-text"] !== "off";
@@ -111,12 +217,29 @@ export function analyzeSourceText(sourceText, filePath, config) {
111
217
  const ternaryEnabled = rules["ternary-locale"] !== "off";
112
218
  const toastEnabled = rules["toast-message"] !== "off";
113
219
  const stringVarEnabled = rules["string-variable"] !== "off";
220
+ const dataStructureEnabled = config?.dataStructureDetection?.enabled !== false;
114
221
  function visit(node) {
115
222
  let pushed = false;
223
+ let isTranslationScope = false;
116
224
  // Scoping nodes: functions, blocks
117
225
  if (ts.isFunctionLike(node) || ts.isBlock(node)) {
118
226
  pushScope();
119
227
  pushed = true;
228
+ // Check if this function has a 't' parameter (translation-aware)
229
+ if (ts.isFunctionLike(node)) {
230
+ const hasTParameter = node.parameters.some((param) => {
231
+ if (ts.isIdentifier(param.name)) {
232
+ return param.name.text === "t" || /^t[A-Z]/.test(param.name.text);
233
+ }
234
+ return false;
235
+ });
236
+ if (hasTParameter) {
237
+ isTranslationScope = true;
238
+ translationScopeDepth++;
239
+ if (stats && stats.dataStructureScopes !== undefined)
240
+ stats.dataStructureScopes++;
241
+ }
242
+ }
120
243
  }
121
244
  // Detect bindings in VariableDeclarations
122
245
  if (ts.isVariableDeclaration(node) && node.initializer) {
@@ -152,6 +275,9 @@ export function analyzeSourceText(sourceText, filePath, config) {
152
275
  sourceFile,
153
276
  namespaceMap: getCurrentBindings(),
154
277
  stats,
278
+ verbose,
279
+ translationScope: translationScopeDepth > 0 || Object.keys(getCurrentBindings()).length > 0,
280
+ fileNamespaces,
155
281
  };
156
282
  // JSX Text
157
283
  if (jsxTextEnabled && ts.isJsxText(node)) {
@@ -189,9 +315,26 @@ export function analyzeSourceText(sourceText, filePath, config) {
189
315
  if (issue)
190
316
  issues.push(issue);
191
317
  }
318
+ // Data structure detection
319
+ const wasInsideDataStructure = insideDataStructure;
320
+ if (dataStructureEnabled && !insideDataStructure) {
321
+ if (ts.isObjectLiteralExpression(node) || ts.isArrayLiteralExpression(node)) {
322
+ insideDataStructure = true;
323
+ const dataIssues = checkDataStructure(node, ctx, config?.dataStructureDetection);
324
+ issues.push(...dataIssues);
325
+ }
326
+ }
192
327
  ts.forEachChild(node, visit);
193
- if (pushed)
328
+ // Reset data structure tracking after visiting children
329
+ if (wasInsideDataStructure !== insideDataStructure) {
330
+ insideDataStructure = wasInsideDataStructure;
331
+ }
332
+ if (pushed) {
194
333
  popScope();
334
+ if (isTranslationScope) {
335
+ translationScopeDepth--;
336
+ }
337
+ }
195
338
  }
196
339
  visit(sourceFile);
197
340
  return { issues, stats };
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/analyzer/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/analyzer/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Data structure detection rule
3
+ *
4
+ * Detects translation keys stored in data structures (arrays, objects)
5
+ * Uses property name heuristics to identify translation-relevant strings
6
+ */
7
+ import ts from "typescript";
8
+ import type { DataStructureConfig, Issue, RuleContext } from "../types.js";
9
+ /**
10
+ * Check data structures for translation keys
11
+ */
12
+ export declare function checkDataStructure(node: ts.ObjectLiteralExpression | ts.ArrayLiteralExpression, ctx: RuleContext, config?: DataStructureConfig): Issue[];
13
+ //# sourceMappingURL=data-structure.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-structure.d.ts","sourceRoot":"","sources":["../../../src/analyzer/rules/data-structure.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAkO3E;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,EAAE,CAAC,uBAAuB,GAAG,EAAE,CAAC,sBAAsB,EAC5D,GAAG,EAAE,WAAW,EAChB,MAAM,CAAC,EAAE,mBAAmB,GAC3B,KAAK,EAAE,CA4GT"}