@better-i18n/cli 0.1.4 ā 0.1.6
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 +39 -54
- package/dist/analyzer/index.d.ts +8 -2
- package/dist/analyzer/index.d.ts.map +1 -1
- package/dist/analyzer/index.js +148 -3
- package/dist/analyzer/index.js.map +1 -1
- package/dist/analyzer/rules/index.d.ts +2 -0
- package/dist/analyzer/rules/index.d.ts.map +1 -1
- package/dist/analyzer/rules/index.js +2 -0
- package/dist/analyzer/rules/index.js.map +1 -1
- package/dist/analyzer/rules/string-variable.d.ts +13 -0
- package/dist/analyzer/rules/string-variable.d.ts.map +1 -0
- package/dist/analyzer/rules/string-variable.js +187 -0
- package/dist/analyzer/rules/string-variable.js.map +1 -0
- package/dist/analyzer/rules/toast-message.d.ts +13 -0
- package/dist/analyzer/rules/toast-message.d.ts.map +1 -0
- package/dist/analyzer/rules/toast-message.js +103 -0
- package/dist/analyzer/rules/toast-message.js.map +1 -0
- package/dist/analyzer/rules/translation-function.d.ts.map +1 -1
- package/dist/analyzer/rules/translation-function.js +36 -21
- package/dist/analyzer/rules/translation-function.js.map +1 -1
- package/dist/analyzer/types.d.ts +17 -1
- package/dist/analyzer/types.d.ts.map +1 -1
- package/dist/commands/scan.d.ts.map +1 -1
- package/dist/commands/scan.js +21 -2
- package/dist/commands/scan.js.map +1 -1
- package/dist/commands/sync.d.ts +12 -0
- package/dist/commands/sync.d.ts.map +1 -0
- package/dist/commands/sync.js +583 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +8 -10
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/commands/extract-keys.d.ts +0 -13
- package/dist/commands/extract-keys.d.ts.map +0 -1
- package/dist/commands/extract-keys.js +0 -418
- package/dist/commands/extract-keys.js.map +0 -1
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Toast message detection rule
|
|
3
|
+
*
|
|
4
|
+
* Detects hardcoded strings in toast function calls
|
|
5
|
+
* Works with: react-hot-toast, sonner, react-toastify
|
|
6
|
+
*/
|
|
7
|
+
import ts from "typescript";
|
|
8
|
+
import { generateKeyFromContext, truncate } from "../../utils/text.js";
|
|
9
|
+
/**
|
|
10
|
+
* Toast function names to detect
|
|
11
|
+
*/
|
|
12
|
+
const TOAST_FUNCTIONS = new Set([
|
|
13
|
+
"toast",
|
|
14
|
+
"success",
|
|
15
|
+
"error",
|
|
16
|
+
"warning",
|
|
17
|
+
"info",
|
|
18
|
+
"loading",
|
|
19
|
+
]);
|
|
20
|
+
/**
|
|
21
|
+
* Toast method names (for toast.error(), toast.success(), etc.)
|
|
22
|
+
*/
|
|
23
|
+
const TOAST_METHODS = new Set([
|
|
24
|
+
"success",
|
|
25
|
+
"error",
|
|
26
|
+
"warning",
|
|
27
|
+
"info",
|
|
28
|
+
"loading",
|
|
29
|
+
"promise",
|
|
30
|
+
"custom",
|
|
31
|
+
]);
|
|
32
|
+
/**
|
|
33
|
+
* Check for toast function calls with hardcoded strings
|
|
34
|
+
*/
|
|
35
|
+
export function checkToastMessage(node, ctx) {
|
|
36
|
+
const funcName = getToastFunctionName(node);
|
|
37
|
+
if (!funcName)
|
|
38
|
+
return null;
|
|
39
|
+
// Get the first argument
|
|
40
|
+
const args = node.arguments;
|
|
41
|
+
if (args.length === 0)
|
|
42
|
+
return null;
|
|
43
|
+
const firstArg = args[0];
|
|
44
|
+
// Handle string literal: toast("Hello")
|
|
45
|
+
if (ts.isStringLiteral(firstArg)) {
|
|
46
|
+
return createIssue(firstArg, firstArg.text, ctx);
|
|
47
|
+
}
|
|
48
|
+
// Handle template literal: toast(`Hello`)
|
|
49
|
+
if (ts.isNoSubstitutionTemplateLiteral(firstArg)) {
|
|
50
|
+
return createIssue(firstArg, firstArg.text, ctx);
|
|
51
|
+
}
|
|
52
|
+
// Handle JSX element as first arg (some toast libs support this)
|
|
53
|
+
// We don't flag JSX since it's handled by jsx-text rule
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Get toast function name from call expression
|
|
58
|
+
* Handles: toast(), toast.error(), toast.success(), etc.
|
|
59
|
+
*/
|
|
60
|
+
function getToastFunctionName(node) {
|
|
61
|
+
const expr = node.expression;
|
|
62
|
+
// Simple call: toast("message")
|
|
63
|
+
if (ts.isIdentifier(expr)) {
|
|
64
|
+
const name = expr.text;
|
|
65
|
+
if (name === "toast" || TOAST_FUNCTIONS.has(name)) {
|
|
66
|
+
return name;
|
|
67
|
+
}
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
// Method call: toast.error("message"), toast.success("message")
|
|
71
|
+
if (ts.isPropertyAccessExpression(expr) &&
|
|
72
|
+
ts.isIdentifier(expr.expression)) {
|
|
73
|
+
const objName = expr.expression.text;
|
|
74
|
+
const methodName = expr.name.text;
|
|
75
|
+
if (objName === "toast" && TOAST_METHODS.has(methodName)) {
|
|
76
|
+
return `toast.${methodName}`;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Create an issue for a detected hardcoded toast message
|
|
83
|
+
*/
|
|
84
|
+
function createIssue(node, text, ctx) {
|
|
85
|
+
// Skip very short strings
|
|
86
|
+
if (!text || text.length <= 2)
|
|
87
|
+
return null;
|
|
88
|
+
// Skip strings that look like technical identifiers
|
|
89
|
+
if (/^[a-z_]+$/.test(text))
|
|
90
|
+
return null;
|
|
91
|
+
const pos = ctx.sourceFile.getLineAndCharacterOfPosition(node.getStart());
|
|
92
|
+
return {
|
|
93
|
+
file: ctx.filePath,
|
|
94
|
+
line: pos.line + 1,
|
|
95
|
+
column: pos.character + 1,
|
|
96
|
+
text,
|
|
97
|
+
type: "toast-message",
|
|
98
|
+
severity: "warning",
|
|
99
|
+
message: `Hardcoded toast: "${truncate(text, 40)}"`,
|
|
100
|
+
suggestedKey: generateKeyFromContext(text, ctx.filePath),
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=toast-message.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toast-message.js","sourceRoot":"","sources":["../../../src/analyzer/rules/toast-message.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"translation-function.d.ts","sourceRoot":"","sources":["../../../src/analyzer/rules/translation-function.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAOtD;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,EAAE,CAAC,cAAc,EACvB,GAAG,EAAE,WAAW,GACf,KAAK,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"translation-function.d.ts","sourceRoot":"","sources":["../../../src/analyzer/rules/translation-function.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAOtD;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,EAAE,CAAC,cAAc,EACvB,GAAG,EAAE,WAAW,GACf,KAAK,GAAG,IAAI,CAmDd"}
|
|
@@ -12,20 +12,33 @@ const TRANSLATION_FUNCTIONS = new Set(["t", "useTranslation"]);
|
|
|
12
12
|
* Check for translation function calls
|
|
13
13
|
*/
|
|
14
14
|
export function checkTranslationFunction(node, ctx) {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
const bindingId = getBindingIdentifier(node);
|
|
16
|
+
if (!bindingId)
|
|
17
|
+
return null;
|
|
18
|
+
// Check if this identifier is bound to a translation namespace
|
|
19
|
+
const binding = ctx.namespaceMap?.[bindingId];
|
|
20
|
+
// If not bound and not a known global/default translation function, skip
|
|
21
|
+
if (!binding && !TRANSLATION_FUNCTIONS.has(bindingId)) {
|
|
22
|
+
if (ctx.stats)
|
|
23
|
+
ctx.stats.unboundTranslators++;
|
|
18
24
|
return null;
|
|
19
25
|
}
|
|
20
|
-
// Get the first argument (
|
|
26
|
+
// Get the first argument (translation key)
|
|
21
27
|
const args = node.arguments;
|
|
22
|
-
if (args.length === 0)
|
|
28
|
+
if (args.length === 0)
|
|
23
29
|
return null;
|
|
24
|
-
}
|
|
25
30
|
const firstArg = args[0];
|
|
26
31
|
// Handle string literal: t("auth.login")
|
|
27
32
|
if (ts.isStringLiteral(firstArg)) {
|
|
28
33
|
const pos = ctx.sourceFile.getLineAndCharacterOfPosition(firstArg.getStart());
|
|
34
|
+
let key = firstArg.text;
|
|
35
|
+
// Apply namespace prefix if bound to a specific namespace
|
|
36
|
+
if (binding?.type === "bound-scoped" && binding.namespace) {
|
|
37
|
+
const prefix = binding.namespace;
|
|
38
|
+
if (!key.startsWith(`${prefix}.`)) {
|
|
39
|
+
key = `${prefix}.${key}`;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
29
42
|
return {
|
|
30
43
|
file: ctx.filePath,
|
|
31
44
|
line: pos.line + 1,
|
|
@@ -33,33 +46,35 @@ export function checkTranslationFunction(node, ctx) {
|
|
|
33
46
|
text: firstArg.text,
|
|
34
47
|
type: "string-variable",
|
|
35
48
|
severity: "info",
|
|
36
|
-
message: `Translation key: "${
|
|
37
|
-
key
|
|
49
|
+
message: `Translation key: "${key}"`,
|
|
50
|
+
key,
|
|
51
|
+
bindingType: binding?.type || "unbound",
|
|
52
|
+
namespace: binding?.namespace,
|
|
38
53
|
};
|
|
39
54
|
}
|
|
40
|
-
// Handle template literal
|
|
41
|
-
if (
|
|
42
|
-
|
|
43
|
-
return null;
|
|
44
|
-
}
|
|
45
|
-
// Handle identifier: t(keyVar) - can't extract statically
|
|
55
|
+
// Handle template literal or dynamic keys
|
|
56
|
+
if (ctx.stats)
|
|
57
|
+
ctx.stats.dynamicKeys++;
|
|
46
58
|
return null;
|
|
47
59
|
}
|
|
48
60
|
/**
|
|
49
|
-
* Extract
|
|
61
|
+
* Extract the binding identifier from a call expression.
|
|
62
|
+
* Handles: t(), t.raw(), t.rich(), t.has()
|
|
50
63
|
*/
|
|
51
|
-
function
|
|
64
|
+
function getBindingIdentifier(node) {
|
|
52
65
|
const expr = node.expression;
|
|
53
66
|
// Simple identifier: t()
|
|
54
67
|
if (ts.isIdentifier(expr)) {
|
|
55
68
|
return expr.text;
|
|
56
69
|
}
|
|
57
|
-
// Property access:
|
|
58
|
-
if (ts.isPropertyAccessExpression(expr)
|
|
59
|
-
|
|
70
|
+
// Property access: t.raw(), t.rich(), t.has()
|
|
71
|
+
if (ts.isPropertyAccessExpression(expr) &&
|
|
72
|
+
ts.isIdentifier(expr.expression)) {
|
|
73
|
+
const propName = expr.name.text;
|
|
74
|
+
if (["raw", "rich", "has"].includes(propName)) {
|
|
75
|
+
return expr.expression.text;
|
|
76
|
+
}
|
|
60
77
|
}
|
|
61
|
-
// Hook destructuring: const { t } = useTranslation(); t()
|
|
62
|
-
// Already handled by Identifier case above
|
|
63
78
|
return null;
|
|
64
79
|
}
|
|
65
80
|
//# sourceMappingURL=translation-function.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"translation-function.js","sourceRoot":"","sources":["../../../src/analyzer/rules/translation-function.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,YAAY,CAAC;AAG5B;;GAEG;AACH,MAAM,qBAAqB,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC,CAAC;AAE/D;;GAEG;AACH,MAAM,UAAU,wBAAwB,CACtC,IAAuB,EACvB,GAAgB;IAEhB,
|
|
1
|
+
{"version":3,"file":"translation-function.js","sourceRoot":"","sources":["../../../src/analyzer/rules/translation-function.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,YAAY,CAAC;AAG5B;;GAEG;AACH,MAAM,qBAAqB,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC,CAAC;AAE/D;;GAEG;AACH,MAAM,UAAU,wBAAwB,CACtC,IAAuB,EACvB,GAAgB;IAEhB,MAAM,SAAS,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;IAC7C,IAAI,CAAC,SAAS;QAAE,OAAO,IAAI,CAAC;IAE5B,+DAA+D;IAC/D,MAAM,OAAO,GAAG,GAAG,CAAC,YAAY,EAAE,CAAC,SAAS,CAAC,CAAC;IAE9C,yEAAyE;IACzE,IAAI,CAAC,OAAO,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;QACtD,IAAI,GAAG,CAAC,KAAK;YAAE,GAAG,CAAC,KAAK,CAAC,kBAAkB,EAAE,CAAC;QAC9C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,2CAA2C;IAC3C,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC;IAC5B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACnC,MAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IAEzB,yCAAyC;IACzC,IAAI,EAAE,CAAC,eAAe,CAAC,QAAQ,CAAC,EAAE,CAAC;QACjC,MAAM,GAAG,GAAG,GAAG,CAAC,UAAU,CAAC,6BAA6B,CACtD,QAAQ,CAAC,QAAQ,EAAE,CACpB,CAAC;QAEF,IAAI,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC;QAExB,0DAA0D;QAC1D,IAAI,OAAO,EAAE,IAAI,KAAK,cAAc,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;YAC1D,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;YACjC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,MAAM,GAAG,CAAC,EAAE,CAAC;gBAClC,GAAG,GAAG,GAAG,MAAM,IAAI,GAAG,EAAE,CAAC;YAC3B,CAAC;QACH,CAAC;QAED,OAAO;YACL,IAAI,EAAE,GAAG,CAAC,QAAQ;YAClB,IAAI,EAAE,GAAG,CAAC,IAAI,GAAG,CAAC;YAClB,MAAM,EAAE,GAAG,CAAC,SAAS,GAAG,CAAC;YACzB,IAAI,EAAE,QAAQ,CAAC,IAAI;YACnB,IAAI,EAAE,iBAAiB;YACvB,QAAQ,EAAE,MAAM;YAChB,OAAO,EAAE,qBAAqB,GAAG,GAAG;YACpC,GAAG;YACH,WAAW,EAAE,OAAO,EAAE,IAAI,IAAI,SAAS;YACvC,SAAS,EAAE,OAAO,EAAE,SAAS;SAC9B,CAAC;IACJ,CAAC;IAED,0CAA0C;IAC1C,IAAI,GAAG,CAAC,KAAK;QAAE,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;IACvC,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,SAAS,oBAAoB,CAAC,IAAuB;IACnD,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC;IAE7B,yBAAyB;IACzB,IAAI,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;IAED,8CAA8C;IAC9C,IACE,EAAE,CAAC,0BAA0B,CAAC,IAAI,CAAC;QACnC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,EAChC,CAAC;QACD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;QAChC,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC9C,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAC9B,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
|
package/dist/analyzer/types.d.ts
CHANGED
|
@@ -6,15 +6,31 @@ export interface Issue {
|
|
|
6
6
|
line: number;
|
|
7
7
|
column: number;
|
|
8
8
|
text: string;
|
|
9
|
-
type: "jsx-text" | "jsx-attribute" | "ternary-locale" | "string-variable";
|
|
9
|
+
type: "jsx-text" | "jsx-attribute" | "ternary-locale" | "string-variable" | "toast-message";
|
|
10
10
|
severity: "error" | "warning" | "info";
|
|
11
11
|
message: string;
|
|
12
12
|
suggestedKey?: string;
|
|
13
13
|
key?: string;
|
|
14
|
+
bindingType?: NamespaceBindingType;
|
|
15
|
+
namespace?: string;
|
|
16
|
+
}
|
|
17
|
+
export type NamespaceBindingType = "bound-scoped" | "root-scoped" | "unknown-scoped" | "unbound";
|
|
18
|
+
export interface NamespaceBinding {
|
|
19
|
+
type: NamespaceBindingType;
|
|
20
|
+
namespace?: string;
|
|
21
|
+
dynamic?: boolean;
|
|
22
|
+
}
|
|
23
|
+
export interface ScanStats {
|
|
24
|
+
dynamicKeys: number;
|
|
25
|
+
dynamicNamespaces: number;
|
|
26
|
+
unboundTranslators: number;
|
|
27
|
+
rootScopedTranslators: number;
|
|
14
28
|
}
|
|
15
29
|
export interface RuleContext {
|
|
16
30
|
filePath: string;
|
|
17
31
|
sourceFile: import("typescript").SourceFile;
|
|
32
|
+
namespaceMap?: Record<string, NamespaceBinding>;
|
|
33
|
+
stats?: ScanStats;
|
|
18
34
|
}
|
|
19
35
|
export interface ScanOptions {
|
|
20
36
|
dir?: string;
|
|
@@ -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;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/analyzer/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -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,
|
|
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,CAkGrE"}
|
package/dist/commands/scan.js
CHANGED
|
@@ -35,10 +35,22 @@ export async function scanCommand(options) {
|
|
|
35
35
|
// Step 3: Analyze files
|
|
36
36
|
spinner.start("Scanning for hardcoded strings...");
|
|
37
37
|
const allIssues = [];
|
|
38
|
+
const aggregatedStats = {
|
|
39
|
+
dynamicKeys: 0,
|
|
40
|
+
dynamicNamespaces: 0,
|
|
41
|
+
unboundTranslators: 0,
|
|
42
|
+
rootScopedTranslators: 0,
|
|
43
|
+
};
|
|
38
44
|
for (const file of files) {
|
|
39
45
|
try {
|
|
40
|
-
const issues = await analyzeFile(file, context?.lint);
|
|
41
|
-
|
|
46
|
+
const { issues, stats } = await analyzeFile(file, context?.lint);
|
|
47
|
+
// Filter out info-severity issues (translation keys) - scan only shows hardcoded strings
|
|
48
|
+
const hardcodedIssues = issues.filter((issue) => issue.severity !== "info");
|
|
49
|
+
allIssues.push(...hardcodedIssues);
|
|
50
|
+
aggregatedStats.dynamicKeys += stats.dynamicKeys || 0;
|
|
51
|
+
aggregatedStats.dynamicNamespaces += stats.dynamicNamespaces || 0;
|
|
52
|
+
aggregatedStats.unboundTranslators += stats.unboundTranslators || 0;
|
|
53
|
+
aggregatedStats.rootScopedTranslators += stats.rootScopedTranslators || 0;
|
|
42
54
|
}
|
|
43
55
|
catch (error) {
|
|
44
56
|
if (options.verbose) {
|
|
@@ -67,6 +79,13 @@ export async function scanCommand(options) {
|
|
|
67
79
|
console.log(green(bold("ā No hardcoded strings found")));
|
|
68
80
|
}
|
|
69
81
|
console.log(dim(`Scanned ${files.length} files in ${(duration / 1000).toFixed(2)}s`));
|
|
82
|
+
if (options.verbose) {
|
|
83
|
+
console.log(dim("\nš Scan Details:"));
|
|
84
|
+
console.log(` - Root-scoped translators: ${aggregatedStats.rootScopedTranslators}`);
|
|
85
|
+
console.log(` - Unbound translators: ${aggregatedStats.unboundTranslators}`);
|
|
86
|
+
console.log(` - Dynamic namespaces skipped: ${aggregatedStats.dynamicNamespaces}`);
|
|
87
|
+
console.log(` - Dynamic keys skipped: ${aggregatedStats.dynamicKeys}`);
|
|
88
|
+
}
|
|
70
89
|
}
|
|
71
90
|
// Exit with error code for CI
|
|
72
91
|
if (options.ci && allIssues.length > 0) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scan.js","sourceRoot":"","sources":["../../src/commands/scan.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAEtD,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAAoB;IACpD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,MAAM,OAAO,GAAG,GAAG,CAAC,EAAE,IAAI,EAAE,sBAAsB,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC;IAE7E,iCAAiC;IACjC,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAC7C,MAAM,OAAO,GAAG,MAAM,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAEpD,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,CAAC,OAAO,CACb,YAAY,IAAI,CAAC,OAAO,CAAC,WAAW,GAAG,GAAG,GAAG,OAAO,CAAC,WAAW,CAAC,EAAE,CACpE,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,IAAI,CAAC,yCAAyC,CAAC,CAAC;IAC1D,CAAC;IAED,wBAAwB;IACxB,OAAO,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;IACrC,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC;QAC/B,OAAO;QACP,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO;QAC/B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO;KAChC,CAAC,CAAC;IAEH,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;QAC5C,OAAO;IACT,CAAC;IAED,OAAO,CAAC,OAAO,CAAC,SAAS,KAAK,CAAC,MAAM,QAAQ,CAAC,CAAC;IAE/C,wBAAwB;IACxB,OAAO,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC;IACnD,MAAM,SAAS,GAAY,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"scan.js","sourceRoot":"","sources":["../../src/commands/scan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sync command
|
|
3
|
+
*
|
|
4
|
+
* Compares local t() calls with Better i18n cloud translations
|
|
5
|
+
*/
|
|
6
|
+
import type { ScanOptions } from "../analyzer/types.js";
|
|
7
|
+
export interface SyncOptions extends ScanOptions {
|
|
8
|
+
format: "eslint" | "json";
|
|
9
|
+
summary?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare function syncCommand(options: SyncOptions): Promise<void>;
|
|
12
|
+
//# sourceMappingURL=sync.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAAsB,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAI5E,MAAM,WAAW,WAAY,SAAQ,WAAW;IAC9C,MAAM,EAAE,QAAQ,GAAG,MAAM,CAAC;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,WAAW,iBAuPrD"}
|