@better-i18n/cli 0.1.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 (58) hide show
  1. package/README.md +218 -0
  2. package/dist/analyzer/file-collector.d.ts +21 -0
  3. package/dist/analyzer/file-collector.d.ts.map +1 -0
  4. package/dist/analyzer/file-collector.js +82 -0
  5. package/dist/analyzer/file-collector.js.map +1 -0
  6. package/dist/analyzer/index.d.ts +15 -0
  7. package/dist/analyzer/index.d.ts.map +1 -0
  8. package/dist/analyzer/index.js +66 -0
  9. package/dist/analyzer/index.js.map +1 -0
  10. package/dist/analyzer/rules/index.d.ts +7 -0
  11. package/dist/analyzer/rules/index.d.ts.map +1 -0
  12. package/dist/analyzer/rules/index.js +7 -0
  13. package/dist/analyzer/rules/index.js.map +1 -0
  14. package/dist/analyzer/rules/jsx-attribute.d.ts +12 -0
  15. package/dist/analyzer/rules/jsx-attribute.d.ts.map +1 -0
  16. package/dist/analyzer/rules/jsx-attribute.js +78 -0
  17. package/dist/analyzer/rules/jsx-attribute.js.map +1 -0
  18. package/dist/analyzer/rules/jsx-text.d.ts +12 -0
  19. package/dist/analyzer/rules/jsx-text.d.ts.map +1 -0
  20. package/dist/analyzer/rules/jsx-text.js +45 -0
  21. package/dist/analyzer/rules/jsx-text.js.map +1 -0
  22. package/dist/analyzer/rules/ternary-locale.d.ts +12 -0
  23. package/dist/analyzer/rules/ternary-locale.d.ts.map +1 -0
  24. package/dist/analyzer/rules/ternary-locale.js +49 -0
  25. package/dist/analyzer/rules/ternary-locale.js.map +1 -0
  26. package/dist/analyzer/types.d.ts +47 -0
  27. package/dist/analyzer/types.d.ts.map +1 -0
  28. package/dist/analyzer/types.js +5 -0
  29. package/dist/analyzer/types.js.map +1 -0
  30. package/dist/commands/scan.d.ts +6 -0
  31. package/dist/commands/scan.d.ts.map +1 -0
  32. package/dist/commands/scan.js +74 -0
  33. package/dist/commands/scan.js.map +1 -0
  34. package/dist/context/detector.d.ts +12 -0
  35. package/dist/context/detector.d.ts.map +1 -0
  36. package/dist/context/detector.js +180 -0
  37. package/dist/context/detector.js.map +1 -0
  38. package/dist/index.d.ts +9 -0
  39. package/dist/index.d.ts.map +1 -0
  40. package/dist/index.js +25 -0
  41. package/dist/index.js.map +1 -0
  42. package/dist/reporters/eslint-style.d.ts +11 -0
  43. package/dist/reporters/eslint-style.d.ts.map +1 -0
  44. package/dist/reporters/eslint-style.js +61 -0
  45. package/dist/reporters/eslint-style.js.map +1 -0
  46. package/dist/reporters/json.d.ts +9 -0
  47. package/dist/reporters/json.d.ts.map +1 -0
  48. package/dist/reporters/json.js +35 -0
  49. package/dist/reporters/json.js.map +1 -0
  50. package/dist/utils/colors.d.ts +25 -0
  51. package/dist/utils/colors.d.ts.map +1 -0
  52. package/dist/utils/colors.js +40 -0
  53. package/dist/utils/colors.js.map +1 -0
  54. package/dist/utils/text.d.ts +12 -0
  55. package/dist/utils/text.d.ts.map +1 -0
  56. package/dist/utils/text.js +49 -0
  57. package/dist/utils/text.js.map +1 -0
  58. package/package.json +59 -0
@@ -0,0 +1,40 @@
1
+ /**
2
+ * ANSI color utilities for terminal output
3
+ */
4
+ export const colors = {
5
+ reset: "\x1b[0m",
6
+ bold: "\x1b[1m",
7
+ dim: "\x1b[2m",
8
+ underline: "\x1b[4m",
9
+ // Foreground colors
10
+ red: "\x1b[31m",
11
+ green: "\x1b[32m",
12
+ yellow: "\x1b[33m",
13
+ blue: "\x1b[34m",
14
+ magenta: "\x1b[35m",
15
+ cyan: "\x1b[36m",
16
+ white: "\x1b[37m",
17
+ gray: "\x1b[90m",
18
+ };
19
+ export function red(text) {
20
+ return `${colors.red}${text}${colors.reset}`;
21
+ }
22
+ export function yellow(text) {
23
+ return `${colors.yellow}${text}${colors.reset}`;
24
+ }
25
+ export function green(text) {
26
+ return `${colors.green}${text}${colors.reset}`;
27
+ }
28
+ export function cyan(text) {
29
+ return `${colors.cyan}${text}${colors.reset}`;
30
+ }
31
+ export function dim(text) {
32
+ return `${colors.dim}${text}${colors.reset}`;
33
+ }
34
+ export function bold(text) {
35
+ return `${colors.bold}${text}${colors.reset}`;
36
+ }
37
+ export function underline(text) {
38
+ return `${colors.underline}${text}${colors.reset}`;
39
+ }
40
+ //# sourceMappingURL=colors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"colors.js","sourceRoot":"","sources":["../../src/utils/colors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,KAAK,EAAE,SAAS;IAChB,IAAI,EAAE,SAAS;IACf,GAAG,EAAE,SAAS;IACd,SAAS,EAAE,SAAS;IAEpB,oBAAoB;IACpB,GAAG,EAAE,UAAU;IACf,KAAK,EAAE,UAAU;IACjB,MAAM,EAAE,UAAU;IAClB,IAAI,EAAE,UAAU;IAChB,OAAO,EAAE,UAAU;IACnB,IAAI,EAAE,UAAU;IAChB,KAAK,EAAE,UAAU;IACjB,IAAI,EAAE,UAAU;CACR,CAAC;AAEX,MAAM,UAAU,GAAG,CAAC,IAAY;IAC9B,OAAO,GAAG,MAAM,CAAC,GAAG,GAAG,IAAI,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,IAAY;IACjC,OAAO,GAAG,MAAM,CAAC,MAAM,GAAG,IAAI,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,IAAY;IAChC,OAAO,GAAG,MAAM,CAAC,KAAK,GAAG,IAAI,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,IAAY;IAC/B,OAAO,GAAG,MAAM,CAAC,IAAI,GAAG,IAAI,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,GAAG,CAAC,IAAY;IAC9B,OAAO,GAAG,MAAM,CAAC,GAAG,GAAG,IAAI,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,IAAY;IAC/B,OAAO,GAAG,MAAM,CAAC,IAAI,GAAG,IAAI,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,OAAO,GAAG,MAAM,CAAC,SAAS,GAAG,IAAI,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;AACrD,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Text utility functions
3
+ */
4
+ /**
5
+ * Truncate text to a maximum length with ellipsis
6
+ */
7
+ export declare function truncate(str: string, maxLength: number): string;
8
+ /**
9
+ * Generate a suggested translation key from text and file path
10
+ */
11
+ export declare function generateKeyFromContext(text: string, filePath: string): string;
12
+ //# sourceMappingURL=text.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../src/utils/text.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAI/D;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,GACf,MAAM,CAqBR"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Text utility functions
3
+ */
4
+ /**
5
+ * Truncate text to a maximum length with ellipsis
6
+ */
7
+ export function truncate(str, maxLength) {
8
+ const cleaned = str.replace(/\s+/g, " ").trim();
9
+ if (cleaned.length <= maxLength)
10
+ return cleaned;
11
+ return cleaned.slice(0, maxLength - 1) + "…";
12
+ }
13
+ /**
14
+ * Generate a suggested translation key from text and file path
15
+ */
16
+ export function generateKeyFromContext(text, filePath) {
17
+ // Extract component/page name from file path
18
+ const pathParts = filePath
19
+ .replace(/\.(tsx|jsx|ts|js)$/, "")
20
+ .split("/")
21
+ .filter((p) => !["src", "app", "components", "pages", "index"].includes(p));
22
+ // Get last 2 meaningful parts (e.g., "auth/LoginForm" -> "auth.loginForm")
23
+ const contextParts = pathParts.slice(-2).map((p) => toCamelCase(p));
24
+ // Convert text to key-friendly format
25
+ const textKey = text
26
+ .toLowerCase()
27
+ .replace(/[^a-z0-9\s]/g, "")
28
+ .trim()
29
+ .split(/\s+/)
30
+ .slice(0, 4) // Max 4 words
31
+ .map((word, i) => (i === 0 ? word : capitalize(word)))
32
+ .join("");
33
+ return [...contextParts, textKey].join(".");
34
+ }
35
+ /**
36
+ * Convert string to camelCase
37
+ */
38
+ function toCamelCase(str) {
39
+ return str
40
+ .replace(/[-_](.)/g, (_, c) => c.toUpperCase())
41
+ .replace(/^(.)/, (_, c) => c.toLowerCase());
42
+ }
43
+ /**
44
+ * Capitalize first letter
45
+ */
46
+ function capitalize(str) {
47
+ return str.charAt(0).toUpperCase() + str.slice(1);
48
+ }
49
+ //# sourceMappingURL=text.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text.js","sourceRoot":"","sources":["../../src/utils/text.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,MAAM,UAAU,QAAQ,CAAC,GAAW,EAAE,SAAiB;IACrD,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAChD,IAAI,OAAO,CAAC,MAAM,IAAI,SAAS;QAAE,OAAO,OAAO,CAAC;IAChD,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;AAC/C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,sBAAsB,CACpC,IAAY,EACZ,QAAgB;IAEhB,6CAA6C;IAC7C,MAAM,SAAS,GAAG,QAAQ;SACvB,OAAO,CAAC,oBAAoB,EAAE,EAAE,CAAC;SACjC,KAAK,CAAC,GAAG,CAAC;SACV,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IAE9E,2EAA2E;IAC3E,MAAM,YAAY,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;IAEpE,sCAAsC;IACtC,MAAM,OAAO,GAAG,IAAI;SACjB,WAAW,EAAE;SACb,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC;SAC3B,IAAI,EAAE;SACN,KAAK,CAAC,KAAK,CAAC;SACZ,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,cAAc;SAC1B,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;SACrD,IAAI,CAAC,EAAE,CAAC,CAAC;IAEZ,OAAO,CAAC,GAAG,YAAY,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC9C,CAAC;AAED;;GAEG;AACH,SAAS,WAAW,CAAC,GAAW;IAC9B,OAAO,GAAG;SACP,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;SAC9C,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;AAChD,CAAC;AAED;;GAEG;AACH,SAAS,UAAU,CAAC,GAAW;IAC7B,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACpD,CAAC"}
package/package.json ADDED
@@ -0,0 +1,59 @@
1
+ {
2
+ "name": "@better-i18n/cli",
3
+ "version": "0.1.0",
4
+ "description": "CLI tool for detecting hardcoded strings in React/Next.js apps",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "bin": {
10
+ "better-i18n": "./dist/index.js"
11
+ },
12
+ "files": [
13
+ "dist",
14
+ "package.json",
15
+ "README.md"
16
+ ],
17
+ "publishConfig": {
18
+ "access": "public"
19
+ },
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "https://github.com/better-i18n/better-i18n.git",
23
+ "directory": "packages/cli"
24
+ },
25
+ "homepage": "https://better-i18n.com",
26
+ "bugs": {
27
+ "url": "https://github.com/better-i18n/better-i18n/issues"
28
+ },
29
+ "keywords": [
30
+ "i18n",
31
+ "internationalization",
32
+ "translation",
33
+ "lint",
34
+ "cli",
35
+ "react",
36
+ "nextjs",
37
+ "better-i18n"
38
+ ],
39
+ "scripts": {
40
+ "build": "tsc",
41
+ "dev": "bun run src/index.ts",
42
+ "typecheck": "tsc --noEmit",
43
+ "clean": "rm -rf dist",
44
+ "prepublishOnly": "npm run clean && npm run build"
45
+ },
46
+ "dependencies": {
47
+ "commander": "^12.1.0",
48
+ "glob": "^11.0.0",
49
+ "ora": "^8.1.1",
50
+ "typescript": "~5.9.2"
51
+ },
52
+ "devDependencies": {
53
+ "@repo/typescript-config": "workspace:*",
54
+ "@types/node": "^20.0.0"
55
+ },
56
+ "engines": {
57
+ "node": ">=18.0.0"
58
+ }
59
+ }