@better-i18n/cli 0.1.0 → 0.1.2

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/README.md CHANGED
@@ -27,7 +27,7 @@ Hardcoded strings slip into codebases easily. Finding them manually is tedious.
27
27
  # Global install
28
28
  npm install -g @better-i18n/cli
29
29
 
30
- # Or use with npx (no install)
30
+ # Or use with npx (no install needed)
31
31
  npx @better-i18n/cli scan
32
32
 
33
33
  # Or add to your project
@@ -43,93 +43,167 @@ better-i18n scan
43
43
  # That's it! The CLI auto-detects your i18n.config.ts
44
44
  ```
45
45
 
46
- ## Usage
46
+ ## Features
47
47
 
48
- ```bash
49
- # Scan specific directory
50
- better-i18n scan --dir ./src
48
+ - ✅ **Auto-config detection** - Reads your existing `i18n.config.ts`
49
+ - **Smart filtering** - Ignores CSS classes, URLs, constants, HTML entities
50
+ - **Glob patterns** - Exclude test files, stories, UI components
51
+ - ✅ **Clickable output** - File paths are Cmd+clickable in VS Code terminal
52
+ - ✅ **CI/CD ready** - JSON output, exit codes, staged files support
53
+ - ✅ **Fast** - Scans 100+ files in <100ms
54
+
55
+ ## Example Output
56
+
57
+ ```
58
+ $ better-i18n scan
59
+
60
+ ✓ Project: better-i18n/landing
61
+ ✓ Found 57 files
51
62
 
52
- # JSON output (for CI/tooling)
53
- better-i18n scan --format json
63
+ components/sign-up.tsx (11)
64
+ 24:13 missing "Create an account" i18n/jsx-text
65
+ 32:22 missing "Name" i18n/jsx-text
66
+ 40:22 missing "Email" i18n/jsx-text
54
67
 
55
- # CI mode (exit code 1 if issues found)
56
- better-i18n scan --ci
68
+ components/contact.tsx (9)
69
+ 24:59 missing "Contact us" i18n/jsx-text
70
+ 31:22 missing "Message" i18n/jsx-text
57
71
 
58
- # Only scan git staged files (for pre-commit hooks)
59
- better-i18n scan --staged
72
+ 87 problems (87 missing translations)
60
73
 
61
- # Verbose output
62
- better-i18n scan --verbose
74
+ Scanned 57 files in 0.07s
63
75
  ```
64
76
 
65
- ## Example Output
77
+ **Cmd+Click** on any file path to jump directly to the issue in VS Code!
66
78
 
67
- ```
68
- $ better-i18n scan
79
+ ## Commands & Options
69
80
 
70
- Project: acme/web-app
71
- ✓ Found 45 files
81
+ ### `better-i18n scan`
72
82
 
73
- src/components/Header.tsx
74
- 12:8 warning "Welcome back" i18n/jsx-text
75
- 15:18 warning "Profile picture" i18n/jsx-attribute
83
+ Scan your codebase for hardcoded strings.
76
84
 
77
- src/pages/login.tsx
78
- 23:15 error locale === 'en' ? ... : ... i18n/ternary-locale
85
+ ```bash
86
+ # Basic usage
87
+ better-i18n scan
88
+
89
+ # Scan specific directory
90
+ better-i18n scan --dir ./src
91
+
92
+ # Output formats
93
+ better-i18n scan --format json # JSON output for CI/tooling
94
+ better-i18n scan --format eslint # Human-readable (default)
79
95
 
80
- 3 problems (1 error, 2 warnings)
96
+ # CI/CD integration
97
+ better-i18n scan --ci # Exit with code 1 if issues found
98
+ better-i18n scan --staged # Only scan git staged files
81
99
 
82
- Scanned 45 files in 0.23s
100
+ # Debug
101
+ better-i18n scan --verbose # Show detailed output
83
102
  ```
84
103
 
85
104
  ## Detection Rules
86
105
 
87
- | Rule | Severity | What it catches |
88
- |------|----------|-----------------|
89
- | `jsx-text` | warning | Hardcoded text inside JSX elements |
90
- | `jsx-attribute` | warning | Hardcoded `title`, `alt`, `placeholder`, `aria-label` |
91
- | `ternary-locale` | error | `locale === 'en' ? 'Hello' : 'Hola'` anti-pattern |
106
+ | Rule | Severity | What it catches | Example |
107
+ |------|----------|-----------------|---------|
108
+ | `jsx-text` | missing | Hardcoded text in JSX | `<h1>Hello</h1>` |
109
+ | `jsx-attribute` | missing | Hardcoded attributes | `<img alt="Logo" />` |
110
+ | `ternary-locale` | error | Locale-based ternaries | `locale === 'en' ? 'Hi' : 'Hola'` |
111
+
112
+ ### Automatically Ignored
113
+
114
+ - HTML entities: `&quot;`, `&amp;`, `&#39;`
115
+ - CSS classes: `className="flex items-center"`
116
+ - URLs: `href="https://example.com"`
117
+ - Paths: `/api/users`
118
+ - Numbers: `42`, `3.14`, `100%`
119
+ - Constants: `SCREAMING_CASE`
120
+ - Symbols: `→`, `•`, `...`
92
121
 
93
122
  ## Configuration
94
123
 
95
- The CLI automatically reads your `i18n.config.ts` file. No extra config needed!
124
+ Create or update your `i18n.config.ts`:
96
125
 
97
126
  ```ts
98
- // i18n.config.ts
99
- import { createI18n } from "@better-i18n/next";
100
-
101
- export const { useTranslation, I18nProvider } = createI18n({
102
- project: "your-org/your-project",
103
- defaultLocale: "en",
104
-
105
- // Optional: customize lint behavior
127
+ export const project = "your-org/your-project";
128
+ export const defaultLocale = "en";
129
+
130
+ export const i18nWorkspaceConfig = {
131
+ project,
132
+ defaultLocale,
106
133
  lint: {
134
+ // Files to scan (defaults: ["src", "app", "components", "pages"])
107
135
  include: ["src/**/*.tsx", "app/**/*.tsx"],
108
- exclude: ["**/*.test.tsx", "**/*.stories.tsx"],
136
+
137
+ // Files to ignore (automatically merges with defaults)
138
+ exclude: [
139
+ "**/skeletons.tsx", // Mock/demo components
140
+ "**/*.stories.tsx", // Storybook files
141
+ "**/*.test.tsx", // Test files
142
+ "**/components/ui/**", // UI library components
143
+ ],
144
+
145
+ // Rule configuration (optional)
109
146
  rules: {
110
147
  "jsx-text": "warning",
111
- "jsx-attribute": "warning",
148
+ "jsx-attribute": "warning",
112
149
  "ternary-locale": "error",
113
150
  },
114
151
  },
115
- });
152
+ };
116
153
  ```
117
154
 
118
- ### Lint Options
155
+ ### Config Options
119
156
 
120
157
  | Option | Type | Description |
121
158
  |--------|------|-------------|
122
- | `include` | `string[]` | Glob patterns for files to scan |
123
- | `exclude` | `string[]` | Glob patterns for files to ignore |
124
- | `rules` | `object` | Rule severity: `"error"`, `"warning"`, or `"off"` |
159
+ | `include` | `string[]` | Glob patterns for files to scan (default: `["src", "app", "components", "pages"]`) |
160
+ | `exclude` | `string[]` | Glob patterns to ignore (merges with defaults: `node_modules`, `.next`, etc.) |
161
+ | `rules` | `object` | Set severity: `"error"` \| `"warning"` \| `"off"` |
162
+
163
+ ## Usage Scenarios
164
+
165
+ ### 1. Local Development
166
+
167
+ Add to your `package.json`:
125
168
 
126
- ## CI/CD Integration
169
+ ```json
170
+ {
171
+ "scripts": {
172
+ "lint": "next lint && better-i18n scan --ci",
173
+ "lint:i18n": "better-i18n scan"
174
+ }
175
+ }
176
+ ```
177
+
178
+ Run before commits:
179
+ ```bash
180
+ npm run lint:i18n
181
+ ```
182
+
183
+ ### 2. Pre-commit Hook
184
+
185
+ Install [Husky](https://typicode.github.io/husky/):
186
+
187
+ ```bash
188
+ npx husky init
189
+ echo "npx @better-i18n/cli scan --staged --ci" > .husky/pre-commit
190
+ ```
191
+
192
+ Or with [lint-staged](https://github.com/lint-staged/lint-staged):
193
+
194
+ ```json
195
+ {
196
+ "lint-staged": {
197
+ "*.{tsx,jsx}": ["better-i18n scan --ci"]
198
+ }
199
+ }
200
+ ```
127
201
 
128
- ### GitHub Actions
202
+ ### 3. GitHub Actions CI
129
203
 
130
204
  ```yaml
131
- # .github/workflows/i18n-lint.yml
132
- name: i18n Lint
205
+ # .github/workflows/i18n-check.yml
206
+ name: i18n Check
133
207
 
134
208
  on: [push, pull_request]
135
209
 
@@ -141,77 +215,167 @@ jobs:
141
215
  - uses: actions/setup-node@v4
142
216
  with:
143
217
  node-version: '20'
144
- - run: npx @better-i18n/cli scan --ci
218
+ - run: npx @better-i18n/cli scan --ci --format json
145
219
  ```
146
220
 
147
- ### Pre-commit Hook
221
+ ### 4. VS Code Integration
148
222
 
149
- With [Husky](https://typicode.github.io/husky/):
150
-
151
- ```bash
152
- # .husky/pre-commit
153
- npx @better-i18n/cli scan --staged --ci
154
- ```
155
-
156
- Or with [lint-staged](https://github.com/lint-staged/lint-staged):
223
+ Add to `.vscode/tasks.json`:
157
224
 
158
225
  ```json
159
226
  {
160
- "lint-staged": {
161
- "*.{tsx,jsx}": ["better-i18n scan --ci"]
162
- }
227
+ "version": "2.0.0",
228
+ "tasks": [
229
+ {
230
+ "label": "i18n: Check translations",
231
+ "type": "shell",
232
+ "command": "npx @better-i18n/cli scan",
233
+ "problemMatcher": [],
234
+ "presentation": {
235
+ "reveal": "always",
236
+ "panel": "new"
237
+ }
238
+ }
239
+ ]
163
240
  }
164
241
  ```
165
242
 
243
+ Run with: `Cmd+Shift+P` → `Tasks: Run Task` → `i18n: Check translations`
244
+
245
+ ### 5. Monorepo Usage
246
+
247
+ ```bash
248
+ # Scan specific package
249
+ cd packages/web-app
250
+ better-i18n scan
251
+
252
+ # Or from root with --dir
253
+ better-i18n scan --dir packages/web-app
254
+ ```
255
+
256
+ Each package can have its own `i18n.config.ts`.
257
+
166
258
  ## JSON Output
167
259
 
168
- Use `--format json` for programmatic access:
260
+ Use `--format json` for programmatic integration:
169
261
 
170
262
  ```bash
171
- better-i18n scan --format json
263
+ better-i18n scan --format json > i18n-report.json
172
264
  ```
173
265
 
174
266
  ```json
175
267
  {
176
268
  "project": {
177
- "workspaceId": "acme",
178
- "projectSlug": "web-app",
269
+ "workspaceId": "better-i18n",
270
+ "projectSlug": "landing",
179
271
  "defaultLocale": "en"
180
272
  },
181
- "files": 45,
273
+ "files": 57,
182
274
  "issues": [
183
275
  {
184
- "file": "src/components/Header.tsx",
185
- "line": 12,
186
- "column": 8,
187
- "text": "Welcome back",
276
+ "file": "components/sign-up.tsx",
277
+ "line": 24,
278
+ "column": 13,
279
+ "text": "Create an account",
188
280
  "type": "jsx-text",
189
281
  "severity": "warning",
190
- "message": "Hardcoded text in JSX"
282
+ "message": "Hardcoded text: \"Create an account\"",
283
+ "suggestedKey": "signUp.createAnAccount"
191
284
  }
192
285
  ],
193
- "duration": 234
286
+ "duration": 67
287
+ }
288
+ ```
289
+
290
+ ### JSON Schema
291
+
292
+ ```ts
293
+ interface ScanResult {
294
+ project?: {
295
+ workspaceId: string;
296
+ projectSlug: string;
297
+ defaultLocale: string;
298
+ };
299
+ files: number;
300
+ issues: Issue[];
301
+ duration: number;
194
302
  }
303
+
304
+ interface Issue {
305
+ file: string; // Relative path
306
+ line: number; // Line number
307
+ column: number; // Column number
308
+ text: string; // Hardcoded text
309
+ type: "jsx-text" | "jsx-attribute" | "ternary-locale";
310
+ severity: "error" | "warning";
311
+ message: string; // Human-readable message
312
+ suggestedKey?: string; // Auto-generated translation key
313
+ }
314
+ ```
315
+
316
+ ## Advanced Usage
317
+
318
+ ### Custom Scripts
319
+
320
+ ```bash
321
+ # Count missing translations
322
+ better-i18n scan --format json | jq '.issues | length'
323
+
324
+ # Get unique files with issues
325
+ better-i18n scan --format json | jq -r '.issues[].file' | sort -u
326
+
327
+ # Filter only errors
328
+ better-i18n scan --format json | jq '.issues[] | select(.severity == "error")'
195
329
  ```
196
330
 
197
- ## What Gets Ignored
331
+ ### Combine with Other Tools
198
332
 
199
- The CLI is smart about ignoring non-translatable content:
333
+ ```bash
334
+ # Run with TypeScript checks
335
+ tsc --noEmit && better-i18n scan --ci
336
+
337
+ # Run with ESLint
338
+ eslint . && better-i18n scan --ci
200
339
 
201
- - CSS class names: `className="flex items-center"`
202
- - URLs: `href="https://example.com"`
203
- - ✅ Numbers and constants
204
- - ✅ Import paths
205
- - ✅ Code identifiers
206
- - ✅ Single characters and punctuation
340
+ # Parallel execution
341
+ npm-run-all --parallel typecheck lint:eslint lint:i18n
342
+ ```
343
+
344
+ ## Troubleshooting
345
+
346
+ ### Config not detected
347
+
348
+ Make sure your `i18n.config.ts` exports either:
349
+ - `export const project = "org/slug"`
350
+ - `export const i18nWorkspaceConfig = { project: "org/slug" }`
351
+
352
+ ### Too many false positives
353
+
354
+ Add exclusions to your config:
355
+ ```ts
356
+ exclude: [
357
+ "**/*.stories.tsx",
358
+ "**/demo/**",
359
+ "**/examples/**",
360
+ ]
361
+ ```
362
+
363
+ ### Clickable links not working
364
+
365
+ Make sure you're using VS Code's integrated terminal. External terminals may not support clickable file paths.
207
366
 
208
367
  ## Part of Better i18n
209
368
 
210
369
  This CLI is part of the [Better i18n](https://better-i18n.com) ecosystem:
211
370
 
212
371
  - **[@better-i18n/next](https://www.npmjs.com/package/@better-i18n/next)** - Next.js i18n SDK
213
- - **[@better-i18n/cli](https://www.npmjs.com/package/@better-i18n/cli)** - This CLI
372
+ - **[@better-i18n/cli](https://www.npmjs.com/package/@better-i18n/cli)** - This CLI tool
214
373
  - **[Dashboard](https://better-i18n.com)** - Visual translation management
374
+ - **[MCP Server](https://github.com/better-i18n/better-i18n)** - AI-powered translation assistant
375
+
376
+ ## Contributing
377
+
378
+ Found a bug or have a feature request? [Open an issue](https://github.com/better-i18n/better-i18n/issues).
215
379
 
216
380
  ## License
217
381
 
@@ -1 +1 @@
1
- {"version":3,"file":"file-collector.d.ts","sourceRoot":"","sources":["../../src/analyzer/file-collector.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAeD;;GAEG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAyB7E;AA+BD;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAAE,GACjB,OAAO,CAmBT"}
1
+ {"version":3,"file":"file-collector.d.ts","sourceRoot":"","sources":["../../src/analyzer/file-collector.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAeD;;GAEG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAqC7E;AA2CD;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAAE,GACjB,OAAO,CAmDT"}
@@ -21,20 +21,25 @@ const DEFAULT_EXTENSIONS = [".tsx", ".jsx"];
21
21
  * Collect files to analyze
22
22
  */
23
23
  export async function collectFiles(options) {
24
- const { rootDir, include = DEFAULT_INCLUDE, exclude = DEFAULT_EXCLUDE, extensions = DEFAULT_EXTENSIONS, } = options;
24
+ const { rootDir, include = DEFAULT_INCLUDE, extensions = DEFAULT_EXTENSIONS, } = options;
25
+ // Merge default excludes with user-provided excludes
26
+ const allExcludes = [...DEFAULT_EXCLUDE, ...(options.exclude || [])];
25
27
  const files = [];
26
- const excludeSet = new Set(exclude);
28
+ // Directory names to exclude (no glob)
29
+ const excludeSet = new Set(allExcludes.filter((e) => !e.includes("*")));
30
+ // Glob patterns to exclude
31
+ const globPatterns = allExcludes.filter((e) => e.includes("*"));
27
32
  // Check which include directories exist
28
33
  const existingDirs = include.filter((dir) => existsSync(join(rootDir, dir)));
29
34
  // If no include dirs exist, scan root
30
35
  const dirsToScan = existingDirs.length > 0 ? existingDirs : ["."];
31
36
  for (const dir of dirsToScan) {
32
37
  const fullDir = join(rootDir, dir);
33
- collectFromDir(fullDir, rootDir, files, excludeSet, extensions);
38
+ collectFromDir(fullDir, rootDir, files, excludeSet, extensions, globPatterns);
34
39
  }
35
40
  return files;
36
41
  }
37
- function collectFromDir(dir, rootDir, files, excludeSet, extensions) {
42
+ function collectFromDir(dir, rootDir, files, excludeSet, extensions, globPatterns = []) {
38
43
  try {
39
44
  const entries = readdirSync(dir, { withFileTypes: true });
40
45
  for (const entry of entries) {
@@ -42,11 +47,17 @@ function collectFromDir(dir, rootDir, files, excludeSet, extensions) {
42
47
  continue;
43
48
  const fullPath = join(dir, entry.name);
44
49
  if (entry.isDirectory()) {
45
- collectFromDir(fullPath, rootDir, files, excludeSet, extensions);
50
+ // Check if directory matches glob pattern like **/components/ui/**
51
+ if (shouldExcludeFile(fullPath, globPatterns))
52
+ continue;
53
+ collectFromDir(fullPath, rootDir, files, excludeSet, extensions, globPatterns);
46
54
  }
47
55
  else if (entry.isFile()) {
48
56
  const ext = entry.name.slice(entry.name.lastIndexOf("."));
49
57
  if (extensions.includes(ext)) {
58
+ // Check if file matches glob pattern
59
+ if (shouldExcludeFile(fullPath, globPatterns))
60
+ continue;
50
61
  files.push(fullPath);
51
62
  }
52
63
  }
@@ -62,17 +73,45 @@ function collectFromDir(dir, rootDir, files, excludeSet, extensions) {
62
73
  export function shouldExcludeFile(filePath, patterns) {
63
74
  const fileName = filePath.split("/").pop() || "";
64
75
  for (const pattern of patterns) {
65
- if (pattern.startsWith("**/*.")) {
76
+ // Handle **/filename.ext pattern (match filename anywhere)
77
+ if (pattern.startsWith("**/") && !pattern.slice(3).includes("/")) {
78
+ const filePattern = pattern.slice(3); // Remove **/
79
+ if (filePattern.includes("*")) {
80
+ // Convert glob to regex: *.stories.tsx -> .*\.stories\.tsx
81
+ const regex = new RegExp("^" + filePattern.replace(/\./g, "\\.").replace(/\*/g, ".*") + "$");
82
+ if (regex.test(fileName))
83
+ return true;
84
+ }
85
+ else if (fileName === filePattern) {
86
+ return true;
87
+ }
88
+ }
89
+ // Handle **/dir/** pattern (match directory path)
90
+ else if (pattern.startsWith("**/") && pattern.endsWith("/**")) {
91
+ const dirName = pattern.slice(3, -3); // Remove **/ and /**
92
+ if (filePath.includes(`/${dirName}/`) ||
93
+ filePath.includes(`${dirName}/`)) {
94
+ return true;
95
+ }
96
+ }
97
+ // Handle **/*.ext pattern (match extension)
98
+ else if (pattern.startsWith("**/*.")) {
66
99
  const ext = pattern.slice(4);
67
100
  if (fileName.endsWith(ext))
68
101
  return true;
69
102
  }
103
+ // Handle simple glob
70
104
  else if (pattern.includes("*")) {
71
- // Simple glob matching
72
- const regex = new RegExp("^" + pattern.replace(/\*/g, ".*").replace(/\?/g, ".") + "$");
73
- if (regex.test(fileName))
105
+ const regex = new RegExp("^" +
106
+ pattern
107
+ .replace(/\./g, "\\.")
108
+ .replace(/\*\*/g, ".*")
109
+ .replace(/\*/g, "[^/]*") +
110
+ "$");
111
+ if (regex.test(filePath) || regex.test(fileName))
74
112
  return true;
75
113
  }
114
+ // Simple string match
76
115
  else if (filePath.includes(pattern)) {
77
116
  return true;
78
117
  }
@@ -1 +1 @@
1
- {"version":3,"file":"file-collector.js","sourceRoot":"","sources":["../../src/analyzer/file-collector.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"file-collector.js","sourceRoot":"","sources":["../../src/analyzer/file-collector.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"jsx-text.d.ts","sourceRoot":"","sources":["../../../src/analyzer/rules/jsx-text.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAetD;;GAEG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,EAAE,CAAC,OAAO,EAChB,GAAG,EAAE,WAAW,GACf,KAAK,GAAG,IAAI,CAwBd"}
1
+ {"version":3,"file":"jsx-text.d.ts","sourceRoot":"","sources":["../../../src/analyzer/rules/jsx-text.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAiBtD;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,WAAW,GAAG,KAAK,GAAG,IAAI,CAwB7E"}
@@ -15,6 +15,8 @@ const IGNORE_PATTERNS = [
15
15
  /^https?:\/\//, // URLs
16
16
  /^\//, // Paths
17
17
  /^[a-z-]+$/, // CSS-like (lowercase with hyphens only)
18
+ /^&[a-z]+;$/, // HTML entities like &quot; &amp; &nbsp;
19
+ /^&#\d+;$/, // Numeric HTML entities like &#39;
18
20
  ];
19
21
  /**
20
22
  * Check JSX text node for hardcoded strings
@@ -1 +1 @@
1
- {"version":3,"file":"jsx-text.js","sourceRoot":"","sources":["../../../src/analyzer/rules/jsx-text.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,sBAAsB,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAGvE;;GAEG;AACH,MAAM,eAAe,GAAG;IACtB,eAAe,EAAE,kBAAkB;IACnC,oCAAoC,EAAE,eAAe;IACrD,gBAAgB,EAAE,+BAA+B;IACjD,WAAW,EAAE,iBAAiB;IAC9B,cAAc,EAAE,OAAO;IACvB,KAAK,EAAE,QAAQ;IACf,WAAW,EAAE,yCAAyC;CACvD,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,YAAY,CAC1B,IAAgB,EAChB,GAAgB;IAEhB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IAE9B,2BAA2B;IAC3B,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAE3C,wBAAwB;IACxB,KAAK,MAAM,OAAO,IAAI,eAAe,EAAE,CAAC;QACtC,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;IACtC,CAAC;IAED,eAAe;IACf,MAAM,GAAG,GAAG,GAAG,CAAC,UAAU,CAAC,6BAA6B,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;IAE1E,OAAO;QACL,IAAI,EAAE,GAAG,CAAC,QAAQ;QAClB,IAAI,EAAE,GAAG,CAAC,IAAI,GAAG,CAAC;QAClB,MAAM,EAAE,GAAG,CAAC,SAAS,GAAG,CAAC;QACzB,IAAI;QACJ,IAAI,EAAE,UAAU;QAChB,QAAQ,EAAE,SAAS;QACnB,OAAO,EAAE,oBAAoB,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG;QAClD,YAAY,EAAE,sBAAsB,CAAC,IAAI,EAAE,GAAG,CAAC,QAAQ,CAAC;KACzD,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"jsx-text.js","sourceRoot":"","sources":["../../../src/analyzer/rules/jsx-text.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,sBAAsB,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAGvE;;GAEG;AACH,MAAM,eAAe,GAAG;IACtB,eAAe,EAAE,kBAAkB;IACnC,oCAAoC,EAAE,eAAe;IACrD,gBAAgB,EAAE,+BAA+B;IACjD,WAAW,EAAE,iBAAiB;IAC9B,cAAc,EAAE,OAAO;IACvB,KAAK,EAAE,QAAQ;IACf,WAAW,EAAE,yCAAyC;IACtD,YAAY,EAAE,yCAAyC;IACvD,UAAU,EAAE,mCAAmC;CAChD,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,IAAgB,EAAE,GAAgB;IAC7D,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IAE9B,2BAA2B;IAC3B,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAE3C,wBAAwB;IACxB,KAAK,MAAM,OAAO,IAAI,eAAe,EAAE,CAAC;QACtC,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;IACtC,CAAC;IAED,eAAe;IACf,MAAM,GAAG,GAAG,GAAG,CAAC,UAAU,CAAC,6BAA6B,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;IAE1E,OAAO;QACL,IAAI,EAAE,GAAG,CAAC,QAAQ;QAClB,IAAI,EAAE,GAAG,CAAC,IAAI,GAAG,CAAC;QAClB,MAAM,EAAE,GAAG,CAAC,SAAS,GAAG,CAAC;QACzB,IAAI;QACJ,IAAI,EAAE,UAAU;QAChB,QAAQ,EAAE,SAAS;QACnB,OAAO,EAAE,oBAAoB,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG;QAClD,YAAY,EAAE,sBAAsB,CAAC,IAAI,EAAE,GAAG,CAAC,QAAQ,CAAC;KACzD,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"ternary-locale.d.ts","sourceRoot":"","sources":["../../../src/analyzer/rules/ternary-locale.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAEtD;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,EAAE,CAAC,qBAAqB,EAC9B,GAAG,EAAE,WAAW,GACf,KAAK,GAAG,IAAI,CA4Cd"}
1
+ {"version":3,"file":"ternary-locale.d.ts","sourceRoot":"","sources":["../../../src/analyzer/rules/ternary-locale.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAEtD;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,EAAE,CAAC,qBAAqB,EAC9B,GAAG,EAAE,WAAW,GACf,KAAK,GAAG,IAAI,CAgDd"}
@@ -4,7 +4,7 @@
4
4
  * Detects anti-pattern: locale === 'en' ? 'Hello' : 'Merhaba'
5
5
  */
6
6
  import ts from "typescript";
7
- import { truncate } from "../../utils/text.js";
7
+ import { generateKeyFromContext, truncate } from "../../utils/text.js";
8
8
  /**
9
9
  * Check conditional expression for locale-based ternary
10
10
  */
@@ -35,6 +35,9 @@ export function checkTernaryLocale(node, ctx) {
35
35
  const text = hasStringTrue
36
36
  ? node.whenTrue.text
37
37
  : node.whenFalse.text;
38
+ // Ignore empty strings (common in URL construction: locale === 'en' ? '' : locale + '/')
39
+ if (text.trim() === "")
40
+ return null;
38
41
  const pos = ctx.sourceFile.getLineAndCharacterOfPosition(node.getStart());
39
42
  return {
40
43
  file: ctx.filePath,
@@ -44,6 +47,7 @@ export function checkTernaryLocale(node, ctx) {
44
47
  type: "ternary-locale",
45
48
  severity: "error", // This is an anti-pattern, so error
46
49
  message: `Locale ternary pattern detected: "${truncate(text, 30)}"`,
50
+ suggestedKey: generateKeyFromContext(text, ctx.filePath),
47
51
  };
48
52
  }
49
53
  //# sourceMappingURL=ternary-locale.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ternary-locale.js","sourceRoot":"","sources":["../../../src/analyzer/rules/ternary-locale.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAG/C;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAChC,IAA8B,EAC9B,GAAgB;IAEhB,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;IAEjC,8BAA8B;IAC9B,IAAI,CAAC,EAAE,CAAC,kBAAkB,CAAC,SAAS,CAAC;QAAE,OAAO,IAAI,CAAC;IAEnD,iCAAiC;IACjC,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC;IAC5B,IAAI,kBAAkB,GAAG,KAAK,CAAC;IAE/B,qCAAqC;IACrC,IAAI,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QACpD,kBAAkB,GAAG,IAAI,CAAC;IAC5B,CAAC;IAED,kEAAkE;IAClE,IAAI,EAAE,CAAC,0BAA0B,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QACvE,kBAAkB,GAAG,IAAI,CAAC;IAC5B,CAAC;IAED,IAAI,CAAC,kBAAkB;QAAE,OAAO,IAAI,CAAC;IAErC,8CAA8C;IAC9C,MAAM,aAAa,GAAG,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACxD,MAAM,cAAc,GAAG,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAE1D,IAAI,CAAC,aAAa,IAAI,CAAC,cAAc;QAAE,OAAO,IAAI,CAAC;IAEnD,uBAAuB;IACvB,MAAM,IAAI,GAAG,aAAa;QACxB,CAAC,CAAE,IAAI,CAAC,QAA6B,CAAC,IAAI;QAC1C,CAAC,CAAE,IAAI,CAAC,SAA8B,CAAC,IAAI,CAAC;IAE9C,MAAM,GAAG,GAAG,GAAG,CAAC,UAAU,CAAC,6BAA6B,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;IAE1E,OAAO;QACL,IAAI,EAAE,GAAG,CAAC,QAAQ;QAClB,IAAI,EAAE,GAAG,CAAC,IAAI,GAAG,CAAC;QAClB,MAAM,EAAE,GAAG,CAAC,SAAS,GAAG,CAAC;QACzB,IAAI;QACJ,IAAI,EAAE,gBAAgB;QACtB,QAAQ,EAAE,OAAO,EAAE,oCAAoC;QACvD,OAAO,EAAE,qCAAqC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG;KACpE,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"ternary-locale.js","sourceRoot":"","sources":["../../../src/analyzer/rules/ternary-locale.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAE,sBAAsB,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAGvE;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAChC,IAA8B,EAC9B,GAAgB;IAEhB,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;IAEjC,8BAA8B;IAC9B,IAAI,CAAC,EAAE,CAAC,kBAAkB,CAAC,SAAS,CAAC;QAAE,OAAO,IAAI,CAAC;IAEnD,iCAAiC;IACjC,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC;IAC5B,IAAI,kBAAkB,GAAG,KAAK,CAAC;IAE/B,qCAAqC;IACrC,IAAI,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QACpD,kBAAkB,GAAG,IAAI,CAAC;IAC5B,CAAC;IAED,kEAAkE;IAClE,IAAI,EAAE,CAAC,0BAA0B,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QACvE,kBAAkB,GAAG,IAAI,CAAC;IAC5B,CAAC;IAED,IAAI,CAAC,kBAAkB;QAAE,OAAO,IAAI,CAAC;IAErC,8CAA8C;IAC9C,MAAM,aAAa,GAAG,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACxD,MAAM,cAAc,GAAG,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAE1D,IAAI,CAAC,aAAa,IAAI,CAAC,cAAc;QAAE,OAAO,IAAI,CAAC;IAEnD,uBAAuB;IACvB,MAAM,IAAI,GAAG,aAAa;QACxB,CAAC,CAAE,IAAI,CAAC,QAA6B,CAAC,IAAI;QAC1C,CAAC,CAAE,IAAI,CAAC,SAA8B,CAAC,IAAI,CAAC;IAE9C,yFAAyF;IACzF,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC;IAEpC,MAAM,GAAG,GAAG,GAAG,CAAC,UAAU,CAAC,6BAA6B,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;IAE1E,OAAO;QACL,IAAI,EAAE,GAAG,CAAC,QAAQ;QAClB,IAAI,EAAE,GAAG,CAAC,IAAI,GAAG,CAAC;QAClB,MAAM,EAAE,GAAG,CAAC,SAAS,GAAG,CAAC;QACzB,IAAI;QACJ,IAAI,EAAE,gBAAgB;QACtB,QAAQ,EAAE,OAAO,EAAE,oCAAoC;QACvD,OAAO,EAAE,qCAAqC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG;QACnE,YAAY,EAAE,sBAAsB,CAAC,IAAI,EAAE,GAAG,CAAC,QAAQ,CAAC;KACzD,CAAC;AACJ,CAAC"}
@@ -18,6 +18,7 @@ export interface RuleContext {
18
18
  export interface ScanOptions {
19
19
  dir?: string;
20
20
  format: "eslint" | "json";
21
+ maxIssues?: number;
21
22
  fix?: boolean;
22
23
  ci?: boolean;
23
24
  staged?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/analyzer/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,UAAU,GAAG,eAAe,GAAG,gBAAgB,GAAG,iBAAiB,CAAC;IAC1E,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,OAAO,YAAY,EAAE,UAAU,CAAC;CAC7C;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,QAAQ,GAAG,MAAM,CAAC;IAC1B,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,SAAS,GAAG,KAAK,CAAC,CAAC;IACpD,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/analyzer/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,UAAU,GAAG,eAAe,GAAG,gBAAgB,GAAG,iBAAiB,CAAC;IAC1E,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,OAAO,YAAY,EAAE,UAAU,CAAC;CAC7C;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,QAAQ,GAAG,MAAM,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,SAAS,GAAG,KAAK,CAAC,CAAC;IACpD,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB"}
@@ -1 +1 @@
1
- {"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../../src/commands/scan.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAS,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAM/D,wBAAsB,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CA2ErE"}
1
+ {"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../../src/commands/scan.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAS,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAM/D,wBAAsB,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CA6ErE"}
@@ -58,7 +58,9 @@ export async function scanCommand(options) {
58
58
  });
59
59
  }
60
60
  else {
61
- reportEslintStyle(allIssues, rootDir);
61
+ // Default max issues to 100 if not specified
62
+ const maxIssues = options.maxIssues ?? 100;
63
+ reportEslintStyle(allIssues, rootDir, maxIssues);
62
64
  // Summary
63
65
  console.log();
64
66
  if (allIssues.length === 0) {
@@ -1 +1 @@
1
- {"version":3,"file":"scan.js","sourceRoot":"","sources":["../../src/commands/scan.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"scan.js","sourceRoot":"","sources":["../../src/commands/scan.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"detector.d.ts","sourceRoot":"","sources":["../../src/context/detector.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAc,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEvE;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,QAAQ,GAAE,MAAsB,GAC/B,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAehC"}
1
+ {"version":3,"file":"detector.d.ts","sourceRoot":"","sources":["../../src/context/detector.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAc,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEvE;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,QAAQ,GAAE,MAAsB,GAC/B,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAqBhC"}
@@ -11,11 +11,18 @@ import { dirname, join } from "node:path";
11
11
  */
12
12
  export async function detectProjectContext(startDir = process.cwd()) {
13
13
  try {
14
+ // First check the startDir itself for i18n.config.ts
15
+ const localConfig = findConfigFile(startDir);
16
+ if (localConfig) {
17
+ return parseI18nConfig(localConfig);
18
+ }
19
+ // Then check workspace root
14
20
  const workspaceRoot = findWorkspaceRoot(startDir);
15
- // Search for files with i18n config
16
- const configFile = findConfigFile(workspaceRoot);
17
- if (configFile) {
18
- return parseI18nConfig(configFile);
21
+ if (workspaceRoot !== startDir) {
22
+ const configFile = findConfigFile(workspaceRoot);
23
+ if (configFile) {
24
+ return parseI18nConfig(configFile);
25
+ }
19
26
  }
20
27
  }
21
28
  catch (error) {
@@ -57,14 +64,26 @@ function findWorkspaceRoot(startDir) {
57
64
  /**
58
65
  * Search for i18n config files
59
66
  */
60
- function findConfigFile(workspaceRoot) {
67
+ function findConfigFile(searchRoot) {
68
+ // First look for i18n.config.ts directly in search root
69
+ const directConfigs = ["i18n.config.ts", "i18n.config.js"];
70
+ for (const configName of directConfigs) {
71
+ const configPath = join(searchRoot, configName);
72
+ if (existsSync(configPath)) {
73
+ return configPath;
74
+ }
75
+ }
76
+ // Then search subdirectories
61
77
  const files = [];
78
+ let foundConfig = null;
62
79
  function searchDir(dir, depth = 0) {
63
- if (depth > 5)
80
+ if (depth > 5 || foundConfig)
64
81
  return;
65
82
  try {
66
83
  const entries = readdirSync(dir);
67
84
  for (const entry of entries) {
85
+ if (foundConfig)
86
+ return;
68
87
  if (["node_modules", ".git", "dist", "build", ".next"].includes(entry)) {
69
88
  continue;
70
89
  }
@@ -74,8 +93,8 @@ function findConfigFile(workspaceRoot) {
74
93
  searchDir(fullPath, depth + 1);
75
94
  }
76
95
  else if (/i18n\.config\.(ts|js)$/.test(entry)) {
77
- // Direct i18n.config.ts file - highest priority
78
- return fullPath;
96
+ foundConfig = fullPath;
97
+ return;
79
98
  }
80
99
  else if (/\.(ts|tsx|js|jsx)$/.test(entry)) {
81
100
  files.push(fullPath);
@@ -86,17 +105,11 @@ function findConfigFile(workspaceRoot) {
86
105
  // Ignore permission errors
87
106
  }
88
107
  }
89
- // First look for i18n.config.ts directly
90
- const directConfigs = ["i18n.config.ts", "i18n.config.js"];
91
- for (const configName of directConfigs) {
92
- const configPath = join(workspaceRoot, configName);
93
- if (existsSync(configPath)) {
94
- return configPath;
95
- }
108
+ searchDir(searchRoot);
109
+ if (foundConfig) {
110
+ return foundConfig;
96
111
  }
97
- // Then search subdirectories
98
- searchDir(workspaceRoot);
99
- // Search for createI18n import
112
+ // Search for createI18n import as fallback
100
113
  for (const file of files) {
101
114
  try {
102
115
  const content = readFileSync(file, "utf-8");
@@ -116,13 +129,27 @@ function findConfigFile(workspaceRoot) {
116
129
  */
117
130
  function parseI18nConfig(filePath) {
118
131
  const content = readFileSync(filePath, "utf-8");
119
- // Try project: "org/slug" format
132
+ // Try project = "org/slug" format (exported const)
133
+ const projectConstMatch = content.match(/(?:export\s+)?const\s+project\s*=\s*['"]([^'"]+\/[^'"]+)['"]/);
134
+ if (projectConstMatch) {
135
+ const [workspaceId, projectSlug] = projectConstMatch[1].split("/");
136
+ const localeMatch = content.match(/defaultLocale[:\s]*['"]([^'"]+)['"]/);
137
+ const cdnMatch = content.match(/cdnBaseUrl[:\s]*['"]([^'"]+)['"]/);
138
+ const lint = parseLintConfig(content);
139
+ return {
140
+ workspaceId,
141
+ projectSlug,
142
+ defaultLocale: localeMatch?.[1] || "en",
143
+ cdnBaseUrl: cdnMatch?.[1],
144
+ lint,
145
+ };
146
+ }
147
+ // Try project: "org/slug" format (object property)
120
148
  const projectMatch = content.match(/project:\s*['"]([^'"]+\/[^'"]+)['"]/);
121
149
  if (projectMatch) {
122
150
  const [workspaceId, projectSlug] = projectMatch[1].split("/");
123
151
  const localeMatch = content.match(/defaultLocale:\s*['"]([^'"]+)['"]/);
124
152
  const cdnMatch = content.match(/cdnBaseUrl:\s*['"]([^'"]+)['"]/);
125
- // Try to parse lint config
126
153
  const lint = parseLintConfig(content);
127
154
  return {
128
155
  workspaceId,
@@ -153,9 +180,7 @@ function parseI18nConfig(filePath) {
153
180
  * Parse optional lint config from file content
154
181
  */
155
182
  function parseLintConfig(content) {
156
- // Simple regex-based parsing for lint config
157
- // In real implementation, could use AST parsing
158
- if (!content.includes("lint:")) {
183
+ if (!content.includes("lint:") && !content.includes("lint =")) {
159
184
  return undefined;
160
185
  }
161
186
  const config = {};
@@ -1 +1 @@
1
- {"version":3,"file":"detector.js","sourceRoot":"","sources":["../../src/context/detector.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"detector.js","sourceRoot":"","sources":["../../src/context/detector.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -10,12 +10,13 @@ import { scanCommand } from "./commands/scan.js";
10
10
  program
11
11
  .name("better-i18n")
12
12
  .description("Detect hardcoded strings in your React/Next.js app")
13
- .version("0.1.0");
13
+ .version("0.1.1");
14
14
  program
15
15
  .command("scan")
16
16
  .description("Scan source files for untranslated strings")
17
17
  .option("-d, --dir <path>", "Directory to scan (default: current directory)")
18
18
  .option("-f, --format <type>", "Output format: eslint, json", "eslint")
19
+ .option("--max-issues <number>", "Maximum number of issues to display (default: 100)", parseInt)
19
20
  .option("--fix", "Auto-fix: wrap hardcoded text with t()")
20
21
  .option("--ci", "CI mode: exit with error code if issues found")
21
22
  .option("--staged", "Only scan git staged files")
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;AAEjD,OAAO;KACJ,IAAI,CAAC,aAAa,CAAC;KACnB,WAAW,CAAC,oDAAoD,CAAC;KACjE,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,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,CAAC,KAAK,EAAE,CAAC"}
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;AAEjD,OAAO;KACJ,IAAI,CAAC,aAAa,CAAC;KACnB,WAAW,CAAC,oDAAoD,CAAC;KACjE,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,CAAC,KAAK,EAAE,CAAC"}
@@ -1,11 +1,11 @@
1
1
  /**
2
2
  * ESLint-style terminal reporter
3
3
  *
4
- * Formats issues in familiar ESLint output format
4
+ * VS Code terminal auto-detects "path:line:column" format and makes it Cmd+clickable
5
5
  */
6
6
  import type { Issue } from "../analyzer/types.js";
7
7
  /**
8
8
  * Report issues in ESLint-style format
9
9
  */
10
- export declare function reportEslintStyle(issues: Issue[], rootDir: string): void;
10
+ export declare function reportEslintStyle(issues: Issue[], rootDir: string, maxIssues?: number): void;
11
11
  //# sourceMappingURL=eslint-style.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"eslint-style.d.ts","sourceRoot":"","sources":["../../src/reporters/eslint-style.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAUlD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CA6CxE"}
1
+ {"version":3,"file":"eslint-style.d.ts","sourceRoot":"","sources":["../../src/reporters/eslint-style.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAGlD;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,KAAK,EAAE,EACf,OAAO,EAAE,MAAM,EACf,SAAS,CAAC,EAAE,MAAM,GACjB,IAAI,CA4EN"}
@@ -1,52 +1,66 @@
1
1
  /**
2
2
  * ESLint-style terminal reporter
3
3
  *
4
- * Formats issues in familiar ESLint output format
4
+ * VS Code terminal auto-detects "path:line:column" format and makes it Cmd+clickable
5
5
  */
6
6
  import { relative } from "node:path";
7
- import { bold, dim, red, underline, yellow, } from "../utils/colors.js";
7
+ import { bold, cyan, dim, red, yellow } from "../utils/colors.js";
8
8
  /**
9
9
  * Report issues in ESLint-style format
10
10
  */
11
- export function reportEslintStyle(issues, rootDir) {
11
+ export function reportEslintStyle(issues, rootDir, maxIssues) {
12
12
  if (issues.length === 0)
13
13
  return;
14
+ const totalIssues = issues.length;
15
+ const displayIssues = maxIssues ? issues.slice(0, maxIssues) : issues;
16
+ const hasMore = maxIssues && totalIssues > maxIssues;
14
17
  // Group by file
15
18
  const byFile = new Map();
16
- for (const issue of issues) {
19
+ for (const issue of displayIssues) {
17
20
  const existing = byFile.get(issue.file) || [];
18
21
  existing.push(issue);
19
22
  byFile.set(issue.file, existing);
20
23
  }
21
24
  let errorCount = 0;
22
- let warningCount = 0;
23
- // Print each file
25
+ let missingCount = 0;
26
+ // Print each file's issues grouped by file
24
27
  for (const [file, fileIssues] of byFile.entries()) {
25
28
  const relPath = relative(rootDir, file);
26
29
  console.log();
27
- console.log(underline(relPath));
30
+ // File header: blue filename + issue count
31
+ const count = dim(`(${fileIssues.length})`);
32
+ console.log(`${cyan(relPath)} ${count}`);
28
33
  for (const issue of fileIssues) {
34
+ // Format: " line:col severity message rule"
35
+ // Full path clickable: relPath:line:col
29
36
  const loc = dim(`${issue.line}:${issue.column}`);
30
- const severity = issue.severity === "error" ? red("error") : yellow("warning");
37
+ const severity = issue.severity === "error" ? red("error") : yellow("missing");
38
+ const text = truncateForDisplay(issue.text, 40);
31
39
  const rule = dim(`i18n/${issue.type}`);
32
- const text = truncateForDisplay(issue.text, 50);
33
40
  console.log(` ${loc} ${severity} ${text} ${rule}`);
34
41
  if (issue.severity === "error") {
35
42
  errorCount++;
36
43
  }
37
44
  else {
38
- warningCount++;
45
+ missingCount++;
39
46
  }
40
47
  }
41
48
  }
42
- // Summary
43
- console.log();
44
- const total = errorCount + warningCount;
49
+ // Show "and X more" message if truncated
50
+ if (hasMore) {
51
+ const remaining = totalIssues - maxIssues;
52
+ console.log();
53
+ console.log(dim(`... and ${remaining} more problem${remaining > 1 ? "s" : ""}`));
54
+ }
55
+ // Summary - use total counts, not just displayed
56
+ const totalErrorCount = issues.filter((i) => i.severity === "error").length;
57
+ const totalMissingCount = issues.filter((i) => i.severity === "warning").length;
58
+ const total = totalErrorCount + totalMissingCount;
45
59
  const summary = [];
46
- if (errorCount > 0)
47
- summary.push(red(`${errorCount} error${errorCount > 1 ? "s" : ""}`));
48
- if (warningCount > 0)
49
- summary.push(yellow(`${warningCount} warning${warningCount > 1 ? "s" : ""}`));
60
+ if (totalErrorCount > 0)
61
+ summary.push(red(`${totalErrorCount} error${totalErrorCount > 1 ? "s" : ""}`));
62
+ if (totalMissingCount > 0)
63
+ summary.push(yellow(`${totalMissingCount} missing translation${totalMissingCount > 1 ? "s" : ""}`));
50
64
  console.log(bold(`✖ ${total} problem${total > 1 ? "s" : ""} (${summary.join(", ")})`));
51
65
  }
52
66
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"eslint-style.js","sourceRoot":"","sources":["../../src/reporters/eslint-style.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"eslint-style.js","sourceRoot":"","sources":["../../src/reporters/eslint-style.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@better-i18n/cli",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "CLI tool for detecting hardcoded strings in React/Next.js apps",
5
5
  "license": "MIT",
6
6
  "type": "module",