@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.
- package/README.md +218 -0
- package/dist/analyzer/file-collector.d.ts +21 -0
- package/dist/analyzer/file-collector.d.ts.map +1 -0
- package/dist/analyzer/file-collector.js +82 -0
- package/dist/analyzer/file-collector.js.map +1 -0
- package/dist/analyzer/index.d.ts +15 -0
- package/dist/analyzer/index.d.ts.map +1 -0
- package/dist/analyzer/index.js +66 -0
- package/dist/analyzer/index.js.map +1 -0
- package/dist/analyzer/rules/index.d.ts +7 -0
- package/dist/analyzer/rules/index.d.ts.map +1 -0
- package/dist/analyzer/rules/index.js +7 -0
- package/dist/analyzer/rules/index.js.map +1 -0
- package/dist/analyzer/rules/jsx-attribute.d.ts +12 -0
- package/dist/analyzer/rules/jsx-attribute.d.ts.map +1 -0
- package/dist/analyzer/rules/jsx-attribute.js +78 -0
- package/dist/analyzer/rules/jsx-attribute.js.map +1 -0
- package/dist/analyzer/rules/jsx-text.d.ts +12 -0
- package/dist/analyzer/rules/jsx-text.d.ts.map +1 -0
- package/dist/analyzer/rules/jsx-text.js +45 -0
- package/dist/analyzer/rules/jsx-text.js.map +1 -0
- package/dist/analyzer/rules/ternary-locale.d.ts +12 -0
- package/dist/analyzer/rules/ternary-locale.d.ts.map +1 -0
- package/dist/analyzer/rules/ternary-locale.js +49 -0
- package/dist/analyzer/rules/ternary-locale.js.map +1 -0
- package/dist/analyzer/types.d.ts +47 -0
- package/dist/analyzer/types.d.ts.map +1 -0
- package/dist/analyzer/types.js +5 -0
- package/dist/analyzer/types.js.map +1 -0
- package/dist/commands/scan.d.ts +6 -0
- package/dist/commands/scan.d.ts.map +1 -0
- package/dist/commands/scan.js +74 -0
- package/dist/commands/scan.js.map +1 -0
- package/dist/context/detector.d.ts +12 -0
- package/dist/context/detector.d.ts.map +1 -0
- package/dist/context/detector.js +180 -0
- package/dist/context/detector.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/dist/reporters/eslint-style.d.ts +11 -0
- package/dist/reporters/eslint-style.d.ts.map +1 -0
- package/dist/reporters/eslint-style.js +61 -0
- package/dist/reporters/eslint-style.js.map +1 -0
- package/dist/reporters/json.d.ts +9 -0
- package/dist/reporters/json.d.ts.map +1 -0
- package/dist/reporters/json.js +35 -0
- package/dist/reporters/json.js.map +1 -0
- package/dist/utils/colors.d.ts +25 -0
- package/dist/utils/colors.d.ts.map +1 -0
- package/dist/utils/colors.js +40 -0
- package/dist/utils/colors.js.map +1 -0
- package/dist/utils/text.d.ts +12 -0
- package/dist/utils/text.d.ts.map +1 -0
- package/dist/utils/text.js +49 -0
- package/dist/utils/text.js.map +1 -0
- 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
|
+
}
|