@codefast/cli 0.3.7-canary.0 → 0.3.12
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 +60 -299
- package/dist/bin.d.ts +3 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +5 -0
- package/dist/commands/arrange.d.ts +3 -0
- package/dist/commands/arrange.d.ts.map +1 -0
- package/dist/commands/arrange.js +114 -0
- package/dist/commands/mirror.d.ts +4 -0
- package/dist/commands/mirror.d.ts.map +1 -0
- package/dist/commands/mirror.js +63 -0
- package/dist/lib/arrange/analyze.d.ts +4 -0
- package/dist/lib/arrange/analyze.d.ts.map +1 -0
- package/dist/lib/arrange/analyze.js +105 -0
- package/dist/lib/arrange/ast/collectors-cn.d.ts +10 -0
- package/dist/lib/arrange/ast/collectors-cn.d.ts.map +1 -0
- package/dist/lib/arrange/ast/collectors-cn.js +84 -0
- package/dist/lib/arrange/ast/collectors-jsx.d.ts +4 -0
- package/dist/lib/arrange/ast/collectors-jsx.d.ts.map +1 -0
- package/dist/lib/arrange/ast/collectors-jsx.js +18 -0
- package/dist/lib/arrange/ast/collectors-tv.d.ts +13 -0
- package/dist/lib/arrange/ast/collectors-tv.d.ts.map +1 -0
- package/dist/lib/arrange/ast/collectors-tv.js +273 -0
- package/dist/lib/arrange/ast/targets.d.ts +8 -0
- package/dist/lib/arrange/ast/targets.d.ts.map +1 -0
- package/dist/lib/arrange/ast/targets.js +143 -0
- package/dist/lib/arrange/ast/utils.d.ts +36 -0
- package/dist/lib/arrange/ast/utils.d.ts.map +1 -0
- package/dist/lib/arrange/ast/utils.js +138 -0
- package/dist/lib/arrange/constants.d.ts +68 -0
- package/dist/lib/arrange/constants.d.ts.map +1 -0
- package/dist/lib/arrange/constants.js +179 -0
- package/dist/lib/arrange/errors.d.ts +14 -0
- package/dist/lib/arrange/errors.d.ts.map +1 -0
- package/dist/lib/arrange/errors.js +16 -0
- package/dist/lib/arrange/formatters.d.ts +16 -0
- package/dist/lib/arrange/formatters.d.ts.map +1 -0
- package/dist/lib/arrange/formatters.js +57 -0
- package/dist/lib/arrange/group-file.d.ts +4 -0
- package/dist/lib/arrange/group-file.d.ts.map +1 -0
- package/dist/lib/arrange/group-file.js +115 -0
- package/dist/lib/arrange/grouping.d.ts +41 -0
- package/dist/lib/arrange/grouping.d.ts.map +1 -0
- package/dist/lib/arrange/grouping.js +280 -0
- package/dist/lib/arrange/imports.d.ts +6 -0
- package/dist/lib/arrange/imports.d.ts.map +1 -0
- package/dist/lib/arrange/imports.js +74 -0
- package/dist/lib/arrange/report.d.ts +4 -0
- package/dist/lib/arrange/report.d.ts.map +1 -0
- package/dist/lib/arrange/report.js +37 -0
- package/dist/lib/arrange/run-target.d.ts +4 -0
- package/dist/lib/arrange/run-target.d.ts.map +1 -0
- package/dist/lib/arrange/run-target.js +28 -0
- package/dist/lib/arrange/tokenizer.d.ts +37 -0
- package/dist/lib/arrange/tokenizer.d.ts.map +1 -0
- package/dist/lib/arrange/tokenizer.js +390 -0
- package/dist/lib/arrange/types.d.ts +104 -0
- package/dist/lib/arrange/types.d.ts.map +1 -0
- package/dist/lib/arrange/types.js +7 -0
- package/dist/lib/arrange/walk.d.ts +4 -0
- package/dist/lib/arrange/walk.d.ts.map +1 -0
- package/dist/lib/arrange/walk.js +34 -0
- package/dist/lib/arrange.d.ts +41 -0
- package/dist/lib/arrange.d.ts.map +1 -0
- package/dist/lib/arrange.js +38 -0
- package/dist/lib/infra/fs-contract.d.ts +28 -0
- package/dist/lib/infra/fs-contract.d.ts.map +1 -0
- package/dist/lib/infra/fs-contract.js +1 -0
- package/dist/lib/infra/node-io.d.ts +4 -0
- package/dist/lib/infra/node-io.d.ts.map +1 -0
- package/dist/lib/infra/node-io.js +27 -0
- package/dist/lib/mirror/config.d.ts +7 -0
- package/dist/lib/mirror/config.d.ts.map +1 -0
- package/dist/lib/mirror/config.js +146 -0
- package/dist/lib/mirror/constants.d.ts +10 -0
- package/dist/lib/mirror/constants.d.ts.map +1 -0
- package/dist/lib/mirror/constants.js +13 -0
- package/dist/lib/mirror/engine.d.ts +12 -0
- package/dist/lib/mirror/engine.d.ts.map +1 -0
- package/dist/lib/mirror/engine.js +248 -0
- package/dist/lib/mirror/errors.d.ts +10 -0
- package/dist/lib/mirror/errors.d.ts.map +1 -0
- package/dist/lib/mirror/errors.js +12 -0
- package/dist/lib/mirror/package-filter.d.ts +8 -0
- package/dist/lib/mirror/package-filter.d.ts.map +1 -0
- package/dist/lib/mirror/package-filter.js +33 -0
- package/dist/lib/mirror/reporter.d.ts +24 -0
- package/dist/lib/mirror/reporter.d.ts.map +1 -0
- package/dist/lib/mirror/reporter.js +126 -0
- package/dist/lib/mirror/sync.d.ts +4 -0
- package/dist/lib/mirror/sync.d.ts.map +1 -0
- package/dist/lib/mirror/sync.js +135 -0
- package/dist/lib/mirror/types.d.ts +81 -0
- package/dist/lib/mirror/types.d.ts.map +1 -0
- package/dist/lib/mirror/types.js +1 -0
- package/dist/lib/mirror/update-pkg.d.ts +13 -0
- package/dist/lib/mirror/update-pkg.d.ts.map +1 -0
- package/dist/lib/mirror/update-pkg.js +39 -0
- package/dist/lib/mirror/workspace-packages.d.ts +26 -0
- package/dist/lib/mirror/workspace-packages.d.ts.map +1 -0
- package/dist/lib/mirror/workspace-packages.js +160 -0
- package/dist/lib/mirror.d.ts +7 -0
- package/dist/lib/mirror.d.ts.map +1 -0
- package/dist/lib/mirror.js +5 -0
- package/dist/lib/repo-root.d.ts +7 -0
- package/dist/lib/repo-root.d.ts.map +1 -0
- package/dist/lib/repo-root.js +23 -0
- package/dist/lib/shared/utils.d.ts +9 -0
- package/dist/lib/shared/utils.d.ts.map +1 -0
- package/dist/lib/shared/utils.js +12 -0
- package/dist/program.d.ts +4 -0
- package/dist/program.d.ts.map +1 -0
- package/dist/program.js +38 -0
- package/package.json +42 -53
- package/CHANGELOG.md +0 -15
- package/dist/cjs/index.cjs +0 -2
- package/dist/cjs/src/index.d.ts +0 -3
- package/dist/cjs/src/index.d.ts.map +0 -1
- package/dist/esm/index.js +0 -2
- package/dist/esm/src/index.d.ts +0 -3
- package/dist/esm/src/index.d.ts.map +0 -1
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import ts from "typescript";
|
|
2
|
+
import { LONG_STRING_TOKEN_THRESHOLD } from "#lib/arrange/constants";
|
|
3
|
+
import { tokenizeClassString } from "#lib/arrange/tokenizer";
|
|
4
|
+
import { forEachStringLiteralInClassExpression } from "#lib/arrange/ast/collectors-cn";
|
|
5
|
+
import { jsxClassNameStaticLiteral } from "#lib/arrange/ast/collectors-jsx";
|
|
6
|
+
import { collectCnCallsInsideTv, traverseTvObject } from "#lib/arrange/ast/collectors-tv";
|
|
7
|
+
import { buildKnownCnTvBindings, isCnOrTvIdentifier, lineOf } from "#lib/arrange/ast/utils";
|
|
8
|
+
import { walkTsxFiles } from "#lib/arrange/walk";
|
|
9
|
+
function analyzeCnCall(sf, call, report) {
|
|
10
|
+
for (const arg of call.arguments) {
|
|
11
|
+
forEachStringLiteralInClassExpression(arg, (lit) => {
|
|
12
|
+
const text = lit.text;
|
|
13
|
+
const tokenCount = tokenizeClassString(text).length;
|
|
14
|
+
if (tokenCount >= LONG_STRING_TOKEN_THRESHOLD) {
|
|
15
|
+
report.longCnStringLiterals.push({
|
|
16
|
+
file: sf.fileName,
|
|
17
|
+
line: lineOf(sf, lit),
|
|
18
|
+
tokenCount,
|
|
19
|
+
preview: text.length > 72 ? `${text.slice(0, 72)}…` : text,
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function visitCallExpressionForArrangeAnalyze(node, sf, sourceText, knownBindings, report) {
|
|
26
|
+
if (isCnOrTvIdentifier(node.expression, "cn", knownBindings)) {
|
|
27
|
+
report.cnCallExpressions++;
|
|
28
|
+
analyzeCnCall(sf, node, report);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
if (!isCnOrTvIdentifier(node.expression, "tv", knownBindings))
|
|
32
|
+
return;
|
|
33
|
+
report.tvCallExpressions++;
|
|
34
|
+
const arg0 = node.arguments[0];
|
|
35
|
+
if (!arg0 || !ts.isObjectLiteralExpression(arg0))
|
|
36
|
+
return;
|
|
37
|
+
for (const nestedCn of collectCnCallsInsideTv(sf, arg0, knownBindings, 0)) {
|
|
38
|
+
const src = sourceText.slice(nestedCn.getStart(sf), nestedCn.getEnd());
|
|
39
|
+
const preview = src.length > 72 ? `${src.slice(0, 72)}…` : src;
|
|
40
|
+
report.cnInsideTvCalls.push({
|
|
41
|
+
file: sf.fileName,
|
|
42
|
+
line: lineOf(sf, nestedCn),
|
|
43
|
+
argCount: nestedCn.arguments.length,
|
|
44
|
+
preview,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
traverseTvObject(sf, arg0, (strNode) => {
|
|
48
|
+
const text = strNode.text;
|
|
49
|
+
const tokenCount = tokenizeClassString(text).length;
|
|
50
|
+
if (tokenCount >= LONG_STRING_TOKEN_THRESHOLD) {
|
|
51
|
+
report.longTvStringLiterals.push({
|
|
52
|
+
file: sf.fileName,
|
|
53
|
+
line: lineOf(sf, strNode),
|
|
54
|
+
tokenCount,
|
|
55
|
+
preview: text.length > 72 ? `${text.slice(0, 72)}…` : text,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
}, 0, knownBindings);
|
|
59
|
+
}
|
|
60
|
+
function visitJsxAttributeForArrangeAnalyze(node, sf, filePath, report) {
|
|
61
|
+
if (!filePath.endsWith(".tsx"))
|
|
62
|
+
return;
|
|
63
|
+
const parsed = jsxClassNameStaticLiteral(node);
|
|
64
|
+
if (!parsed)
|
|
65
|
+
return;
|
|
66
|
+
const text = parsed.lit.text;
|
|
67
|
+
const tokenCount = tokenizeClassString(text).length;
|
|
68
|
+
if (tokenCount >= LONG_STRING_TOKEN_THRESHOLD) {
|
|
69
|
+
report.longJsxClassNameLiterals.push({
|
|
70
|
+
file: sf.fileName,
|
|
71
|
+
line: lineOf(sf, parsed.lit),
|
|
72
|
+
tokenCount,
|
|
73
|
+
preview: text.length > 72 ? `${text.slice(0, 72)}…` : text,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
export function analyzeDirectory(target, fs) {
|
|
78
|
+
const report = {
|
|
79
|
+
files: 0,
|
|
80
|
+
cnCallExpressions: 0,
|
|
81
|
+
tvCallExpressions: 0,
|
|
82
|
+
cnInsideTvCalls: [],
|
|
83
|
+
longCnStringLiterals: [],
|
|
84
|
+
longTvStringLiterals: [],
|
|
85
|
+
longJsxClassNameLiterals: [],
|
|
86
|
+
};
|
|
87
|
+
const files = fs.statSync(target).isDirectory() ? walkTsxFiles(target, fs) : [target];
|
|
88
|
+
for (const filePath of files) {
|
|
89
|
+
const sourceText = fs.readFileSync(filePath, "utf8");
|
|
90
|
+
const sf = ts.createSourceFile(filePath, sourceText, ts.ScriptTarget.Latest, true, filePath.endsWith(".tsx") ? ts.ScriptKind.TSX : ts.ScriptKind.TS);
|
|
91
|
+
report.files++;
|
|
92
|
+
const knownBindings = buildKnownCnTvBindings(sf);
|
|
93
|
+
const visit = (node) => {
|
|
94
|
+
if (ts.isCallExpression(node)) {
|
|
95
|
+
visitCallExpressionForArrangeAnalyze(node, sf, sourceText, knownBindings, report);
|
|
96
|
+
}
|
|
97
|
+
if (ts.isJsxAttribute(node)) {
|
|
98
|
+
visitJsxAttributeForArrangeAnalyze(node, sf, filePath, report);
|
|
99
|
+
}
|
|
100
|
+
ts.forEachChild(node, visit);
|
|
101
|
+
};
|
|
102
|
+
visit(sf);
|
|
103
|
+
}
|
|
104
|
+
return report;
|
|
105
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import ts from "typescript";
|
|
2
|
+
import type { ForEachStringLiteralInClassExpressionOptions, TailwindClassLiteral } from "#lib/arrange/types";
|
|
3
|
+
export declare function forEachStringLiteralInClassExpression(expr: ts.Expression, sink: (node: TailwindClassLiteral) => void, depth?: number, options?: ForEachStringLiteralInClassExpressionOptions): void;
|
|
4
|
+
export declare function isUnsafeLiteralForCnStyleApplySplit(node: TailwindClassLiteral): boolean;
|
|
5
|
+
export declare const CN_APPLY_LITERAL_WALK_OPTS: ForEachStringLiteralInClassExpressionOptions;
|
|
6
|
+
export declare function collectUnconditionalTailwindLiteralsFromCnArguments(args: ts.NodeArray<ts.Expression>): TailwindClassLiteral[];
|
|
7
|
+
export declare function mergeCnUnconditionalLiteralPoolForTest(argsSnippet: string, options?: {
|
|
8
|
+
callee?: string;
|
|
9
|
+
}): string;
|
|
10
|
+
//# sourceMappingURL=collectors-cn.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collectors-cn.d.ts","sourceRoot":"","sources":["../../../../src/lib/arrange/ast/collectors-cn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,OAAO,KAAK,EACV,4CAA4C,EAC5C,oBAAoB,EACrB,MAAM,oBAAoB,CAAC;AAE5B,wBAAgB,qCAAqC,CACnD,IAAI,EAAE,EAAE,CAAC,UAAU,EACnB,IAAI,EAAE,CAAC,IAAI,EAAE,oBAAoB,KAAK,IAAI,EAC1C,KAAK,SAAI,EACT,OAAO,CAAC,EAAE,4CAA4C,GACrD,IAAI,CA4CN;AAED,wBAAgB,mCAAmC,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAEvF;AAED,eAAO,MAAM,0BAA0B,EAAE,4CAExC,CAAC;AAEF,wBAAgB,mDAAmD,CACjE,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,UAAU,CAAC,GAChC,oBAAoB,EAAE,CAqBxB;AAED,wBAAgB,sCAAsC,CACpD,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAC5B,MAAM,CAyBR"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import ts from "typescript";
|
|
2
|
+
import { MAX_CLASS_EXPR_DEPTH } from "#lib/arrange/constants";
|
|
3
|
+
export function forEachStringLiteralInClassExpression(expr, sink, depth = 0, options) {
|
|
4
|
+
if (depth > MAX_CLASS_EXPR_DEPTH)
|
|
5
|
+
return;
|
|
6
|
+
if (ts.isStringLiteral(expr) || ts.isNoSubstitutionTemplateLiteral(expr)) {
|
|
7
|
+
sink(expr);
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
if (ts.isParenthesizedExpression(expr)) {
|
|
11
|
+
forEachStringLiteralInClassExpression(expr.expression, sink, depth + 1, options);
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
if (ts.isAsExpression(expr) || ts.isSatisfiesExpression(expr)) {
|
|
15
|
+
forEachStringLiteralInClassExpression(expr.expression, sink, depth + 1, options);
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
if (ts.isNonNullExpression(expr)) {
|
|
19
|
+
forEachStringLiteralInClassExpression(expr.expression, sink, depth + 1, options);
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
if (ts.isConditionalExpression(expr)) {
|
|
23
|
+
if (options?.descendIntoConditional === false) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
forEachStringLiteralInClassExpression(expr.whenTrue, sink, depth + 1, options);
|
|
27
|
+
forEachStringLiteralInClassExpression(expr.whenFalse, sink, depth + 1, options);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
if (ts.isBinaryExpression(expr) && expr.operatorToken.kind === ts.SyntaxKind.PlusToken) {
|
|
31
|
+
forEachStringLiteralInClassExpression(expr.left, sink, depth + 1, options);
|
|
32
|
+
forEachStringLiteralInClassExpression(expr.right, sink, depth + 1, options);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
if (ts.isArrayLiteralExpression(expr)) {
|
|
36
|
+
for (const el of expr.elements) {
|
|
37
|
+
if (ts.isSpreadElement(el))
|
|
38
|
+
continue;
|
|
39
|
+
forEachStringLiteralInClassExpression(el, sink, depth + 1, options);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
export function isUnsafeLiteralForCnStyleApplySplit(node) {
|
|
44
|
+
return ts.isArrayLiteralExpression(node.parent);
|
|
45
|
+
}
|
|
46
|
+
export const CN_APPLY_LITERAL_WALK_OPTS = {
|
|
47
|
+
descendIntoConditional: false,
|
|
48
|
+
};
|
|
49
|
+
export function collectUnconditionalTailwindLiteralsFromCnArguments(args) {
|
|
50
|
+
const staticLits = [];
|
|
51
|
+
for (const arg of args) {
|
|
52
|
+
if (ts.isStringLiteral(arg) || ts.isNoSubstitutionTemplateLiteral(arg)) {
|
|
53
|
+
if (!isUnsafeLiteralForCnStyleApplySplit(arg)) {
|
|
54
|
+
staticLits.push(arg);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
forEachStringLiteralInClassExpression(arg, (lit) => {
|
|
59
|
+
if (!isUnsafeLiteralForCnStyleApplySplit(lit)) {
|
|
60
|
+
staticLits.push(lit);
|
|
61
|
+
}
|
|
62
|
+
}, 0, CN_APPLY_LITERAL_WALK_OPTS);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return staticLits;
|
|
66
|
+
}
|
|
67
|
+
export function mergeCnUnconditionalLiteralPoolForTest(argsSnippet, options) {
|
|
68
|
+
const callee = options?.callee ?? "cn";
|
|
69
|
+
const sourceText = `${callee}(${argsSnippet});`;
|
|
70
|
+
const sf = ts.createSourceFile("mergeCnUnconditionalLiteralPoolForTest.ts", sourceText, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
|
|
71
|
+
const stmt = sf.statements[0];
|
|
72
|
+
if (!ts.isExpressionStatement(stmt)) {
|
|
73
|
+
throw new Error("expected expression statement");
|
|
74
|
+
}
|
|
75
|
+
const call = stmt.expression;
|
|
76
|
+
if (!ts.isCallExpression(call) ||
|
|
77
|
+
!ts.isIdentifier(call.expression) ||
|
|
78
|
+
call.expression.text !== callee) {
|
|
79
|
+
throw new Error(`expected ${callee}(...) call`);
|
|
80
|
+
}
|
|
81
|
+
return collectUnconditionalTailwindLiteralsFromCnArguments(call.arguments)
|
|
82
|
+
.map((n) => n.text)
|
|
83
|
+
.join(" ");
|
|
84
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collectors-jsx.d.ts","sourceRoot":"","sources":["../../../../src/lib/arrange/ast/collectors-jsx.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAE7D,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,GAAG,kBAAkB,GAAG,SAAS,CAe/F"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import ts from "typescript";
|
|
2
|
+
export function jsxClassNameStaticLiteral(attr) {
|
|
3
|
+
if (!ts.isIdentifier(attr.name) || attr.name.text !== "className")
|
|
4
|
+
return undefined;
|
|
5
|
+
const init = attr.initializer;
|
|
6
|
+
if (!init)
|
|
7
|
+
return undefined;
|
|
8
|
+
if (ts.isStringLiteral(init) || ts.isNoSubstitutionTemplateLiteral(init)) {
|
|
9
|
+
return { lit: init, valueNode: init };
|
|
10
|
+
}
|
|
11
|
+
if (ts.isJsxExpression(init) && init.expression) {
|
|
12
|
+
const innerExpr = init.expression;
|
|
13
|
+
if (ts.isStringLiteral(innerExpr) || ts.isNoSubstitutionTemplateLiteral(innerExpr)) {
|
|
14
|
+
return { lit: innerExpr, valueNode: init };
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return undefined;
|
|
18
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import ts from "typescript";
|
|
2
|
+
import type { StringNode, TailwindClassLiteral } from "#lib/arrange/types";
|
|
3
|
+
type StringNodeVisitor = (node: TailwindClassLiteral, sf: ts.SourceFile, cnCall?: ts.CallExpression) => void;
|
|
4
|
+
export declare function traverseTvObject(sf: ts.SourceFile, obj: ts.ObjectLiteralExpression, visitor: StringNodeVisitor, depth?: number, knownBindings?: Set<string>): void;
|
|
5
|
+
export declare function collectCnCallsInsideTv(sf: ts.SourceFile, obj: ts.ObjectLiteralExpression, knownBindings: Set<string>, depth?: number): ts.CallExpression[];
|
|
6
|
+
export declare function listAllCnCallsInsideTvInSourceFile(sf: ts.SourceFile, knownBindings: Set<string>): ts.CallExpression[];
|
|
7
|
+
export declare function makeStringNode(nodes: TailwindClassLiteral[], sf: ts.SourceFile, isTvContext: boolean, cnCall?: ts.CallExpression): StringNode;
|
|
8
|
+
export declare function slotClassString(item: StringNode): string;
|
|
9
|
+
export declare function emitTvSlot(lits: TailwindClassLiteral[], sf: ts.SourceFile, cnCall: ts.CallExpression | undefined, results: StringNode[], seenNodePos: Set<number>): void;
|
|
10
|
+
export declare function collectTvSlots(sf: ts.SourceFile, obj: ts.ObjectLiteralExpression, knownBindings: Set<string>, results: StringNode[], seenNodePos: Set<number>, depth?: number): void;
|
|
11
|
+
export declare function collectGroupableStringNodes(sf: ts.SourceFile): StringNode[];
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=collectors-tv.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collectors-tv.d.ts","sourceRoot":"","sources":["../../../../src/lib/arrange/ast/collectors-tv.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAQ5B,OAAO,KAAK,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAQ3E,KAAK,iBAAiB,GAAG,CACvB,IAAI,EAAE,oBAAoB,EAC1B,EAAE,EAAE,EAAE,CAAC,UAAU,EACjB,MAAM,CAAC,EAAE,EAAE,CAAC,cAAc,KACvB,IAAI,CAAC;AAEV,wBAAgB,gBAAgB,CAC9B,EAAE,EAAE,EAAE,CAAC,UAAU,EACjB,GAAG,EAAE,EAAE,CAAC,uBAAuB,EAC/B,OAAO,EAAE,iBAAiB,EAC1B,KAAK,SAAI,EACT,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAC1B,IAAI,CA+DN;AAED,wBAAgB,sBAAsB,CACpC,EAAE,EAAE,EAAE,CAAC,UAAU,EACjB,GAAG,EAAE,EAAE,CAAC,uBAAuB,EAC/B,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,EAC1B,KAAK,SAAI,GACR,EAAE,CAAC,cAAc,EAAE,CAqCrB;AAED,wBAAgB,kCAAkC,CAChD,EAAE,EAAE,EAAE,CAAC,UAAU,EACjB,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,GACzB,EAAE,CAAC,cAAc,EAAE,CAarB;AAED,wBAAgB,cAAc,CAC5B,KAAK,EAAE,oBAAoB,EAAE,EAC7B,EAAE,EAAE,EAAE,CAAC,UAAU,EACjB,WAAW,EAAE,OAAO,EACpB,MAAM,CAAC,EAAE,EAAE,CAAC,cAAc,GACzB,UAAU,CAUZ;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAExD;AAED,wBAAgB,UAAU,CACxB,IAAI,EAAE,oBAAoB,EAAE,EAC5B,EAAE,EAAE,EAAE,CAAC,UAAU,EACjB,MAAM,EAAE,EAAE,CAAC,cAAc,GAAG,SAAS,EACrC,OAAO,EAAE,UAAU,EAAE,EACrB,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,GACvB,IAAI,CASN;AAED,wBAAgB,cAAc,CAC5B,EAAE,EAAE,EAAE,CAAC,UAAU,EACjB,GAAG,EAAE,EAAE,CAAC,uBAAuB,EAC/B,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,EAC1B,OAAO,EAAE,UAAU,EAAE,EACrB,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,EACxB,KAAK,SAAI,GACR,IAAI,CA+FN;AAED,wBAAgB,2BAA2B,CAAC,EAAE,EAAE,EAAE,CAAC,UAAU,GAAG,UAAU,EAAE,CAiC3E"}
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
import ts from "typescript";
|
|
2
|
+
import { APPLY_MIN_TOKENS, MAX_OBJECT_DEPTH } from "#lib/arrange/constants";
|
|
3
|
+
import { CN_APPLY_LITERAL_WALK_OPTS, collectUnconditionalTailwindLiteralsFromCnArguments, forEachStringLiteralInClassExpression, isUnsafeLiteralForCnStyleApplySplit, } from "#lib/arrange/ast/collectors-cn";
|
|
4
|
+
import { tokenizeClassString } from "#lib/arrange/tokenizer";
|
|
5
|
+
import { buildKnownCnTvBindings, isCnOrTvIdentifier, propertyAssignmentNameText, } from "#lib/arrange/ast/utils";
|
|
6
|
+
export function traverseTvObject(sf, obj, visitor, depth = 0, knownBindings) {
|
|
7
|
+
if (depth > MAX_OBJECT_DEPTH)
|
|
8
|
+
return;
|
|
9
|
+
for (const prop of obj.properties) {
|
|
10
|
+
if (!ts.isPropertyAssignment(prop))
|
|
11
|
+
continue;
|
|
12
|
+
const init = prop.initializer;
|
|
13
|
+
if (ts.isStringLiteral(init) || ts.isNoSubstitutionTemplateLiteral(init)) {
|
|
14
|
+
visitor(init, sf, undefined);
|
|
15
|
+
}
|
|
16
|
+
else if (ts.isArrayLiteralExpression(init)) {
|
|
17
|
+
for (const el of init.elements) {
|
|
18
|
+
if (ts.isSpreadElement(el))
|
|
19
|
+
continue;
|
|
20
|
+
if (ts.isStringLiteral(el) || ts.isNoSubstitutionTemplateLiteral(el)) {
|
|
21
|
+
visitor(el, sf, undefined);
|
|
22
|
+
}
|
|
23
|
+
else if (ts.isCallExpression(el) &&
|
|
24
|
+
isCnOrTvIdentifier(el.expression, "cn", knownBindings)) {
|
|
25
|
+
for (const arg of el.arguments) {
|
|
26
|
+
forEachStringLiteralInClassExpression(arg, (lit) => {
|
|
27
|
+
visitor(lit, sf, el);
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
else if (ts.isObjectLiteralExpression(el)) {
|
|
32
|
+
for (const inner of el.properties) {
|
|
33
|
+
if (!ts.isPropertyAssignment(inner))
|
|
34
|
+
continue;
|
|
35
|
+
const propName = propertyAssignmentNameText(inner);
|
|
36
|
+
if (propName !== "className" && propName !== "class")
|
|
37
|
+
continue;
|
|
38
|
+
const innerInit = inner.initializer;
|
|
39
|
+
if (ts.isStringLiteral(innerInit) || ts.isNoSubstitutionTemplateLiteral(innerInit)) {
|
|
40
|
+
visitor(innerInit, sf, undefined);
|
|
41
|
+
}
|
|
42
|
+
else if (ts.isArrayLiteralExpression(innerInit)) {
|
|
43
|
+
for (const innerEl of innerInit.elements) {
|
|
44
|
+
if (ts.isSpreadElement(innerEl))
|
|
45
|
+
continue;
|
|
46
|
+
if (ts.isStringLiteral(innerEl) || ts.isNoSubstitutionTemplateLiteral(innerEl)) {
|
|
47
|
+
visitor(innerEl, sf, undefined);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
else if (ts.isCallExpression(innerInit) &&
|
|
52
|
+
isCnOrTvIdentifier(innerInit.expression, "cn", knownBindings)) {
|
|
53
|
+
for (const arg of innerInit.arguments) {
|
|
54
|
+
forEachStringLiteralInClassExpression(arg, (lit) => {
|
|
55
|
+
visitor(lit, sf, innerInit);
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
else if (ts.isObjectLiteralExpression(init)) {
|
|
64
|
+
traverseTvObject(sf, init, visitor, depth + 1, knownBindings);
|
|
65
|
+
}
|
|
66
|
+
else if (ts.isCallExpression(init) &&
|
|
67
|
+
isCnOrTvIdentifier(init.expression, "cn", knownBindings)) {
|
|
68
|
+
for (const arg of init.arguments) {
|
|
69
|
+
forEachStringLiteralInClassExpression(arg, (lit) => {
|
|
70
|
+
visitor(lit, sf, init);
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
export function collectCnCallsInsideTv(sf, obj, knownBindings, depth = 0) {
|
|
77
|
+
if (depth > MAX_OBJECT_DEPTH)
|
|
78
|
+
return [];
|
|
79
|
+
const calls = [];
|
|
80
|
+
for (const prop of obj.properties) {
|
|
81
|
+
if (!ts.isPropertyAssignment(prop))
|
|
82
|
+
continue;
|
|
83
|
+
const init = prop.initializer;
|
|
84
|
+
if (ts.isArrayLiteralExpression(init)) {
|
|
85
|
+
for (const el of init.elements) {
|
|
86
|
+
if (ts.isSpreadElement(el))
|
|
87
|
+
continue;
|
|
88
|
+
if (ts.isCallExpression(el) && isCnOrTvIdentifier(el.expression, "cn", knownBindings)) {
|
|
89
|
+
calls.push(el);
|
|
90
|
+
}
|
|
91
|
+
else if (ts.isObjectLiteralExpression(el)) {
|
|
92
|
+
for (const inner of el.properties) {
|
|
93
|
+
if (!ts.isPropertyAssignment(inner))
|
|
94
|
+
continue;
|
|
95
|
+
const propName = propertyAssignmentNameText(inner);
|
|
96
|
+
if (propName !== "className" && propName !== "class")
|
|
97
|
+
continue;
|
|
98
|
+
const innerInit = inner.initializer;
|
|
99
|
+
if (ts.isCallExpression(innerInit) &&
|
|
100
|
+
isCnOrTvIdentifier(innerInit.expression, "cn", knownBindings)) {
|
|
101
|
+
calls.push(innerInit);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
else if (ts.isObjectLiteralExpression(init)) {
|
|
108
|
+
calls.push(...collectCnCallsInsideTv(sf, init, knownBindings, depth + 1));
|
|
109
|
+
}
|
|
110
|
+
else if (ts.isCallExpression(init) &&
|
|
111
|
+
isCnOrTvIdentifier(init.expression, "cn", knownBindings)) {
|
|
112
|
+
calls.push(init);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return calls;
|
|
116
|
+
}
|
|
117
|
+
export function listAllCnCallsInsideTvInSourceFile(sf, knownBindings) {
|
|
118
|
+
const calls = [];
|
|
119
|
+
const visit = (node) => {
|
|
120
|
+
if (ts.isCallExpression(node) && isCnOrTvIdentifier(node.expression, "tv", knownBindings)) {
|
|
121
|
+
const arg0 = node.arguments[0];
|
|
122
|
+
if (arg0 && ts.isObjectLiteralExpression(arg0)) {
|
|
123
|
+
calls.push(...collectCnCallsInsideTv(sf, arg0, knownBindings, 0));
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
ts.forEachChild(node, visit);
|
|
127
|
+
};
|
|
128
|
+
visit(sf);
|
|
129
|
+
return calls;
|
|
130
|
+
}
|
|
131
|
+
export function makeStringNode(nodes, sf, isTvContext, cnCall) {
|
|
132
|
+
return {
|
|
133
|
+
nodes,
|
|
134
|
+
sf,
|
|
135
|
+
isTvContext,
|
|
136
|
+
cnCall,
|
|
137
|
+
get node() {
|
|
138
|
+
return this.nodes[0];
|
|
139
|
+
},
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
export function slotClassString(item) {
|
|
143
|
+
return item.nodes.map((n) => n.text).join(" ");
|
|
144
|
+
}
|
|
145
|
+
export function emitTvSlot(lits, sf, cnCall, results, seenNodePos) {
|
|
146
|
+
if (lits.length === 0)
|
|
147
|
+
return;
|
|
148
|
+
const firstPos = lits[0].getStart(sf);
|
|
149
|
+
if (seenNodePos.has(firstPos))
|
|
150
|
+
return;
|
|
151
|
+
seenNodePos.add(firstPos);
|
|
152
|
+
const totalTokens = lits.reduce((s, n) => s + tokenizeClassString(n.text).length, 0);
|
|
153
|
+
if (totalTokens < APPLY_MIN_TOKENS)
|
|
154
|
+
return;
|
|
155
|
+
results.push(makeStringNode(lits, sf, true, cnCall));
|
|
156
|
+
}
|
|
157
|
+
export function collectTvSlots(sf, obj, knownBindings, results, seenNodePos, depth = 0) {
|
|
158
|
+
if (depth > MAX_OBJECT_DEPTH)
|
|
159
|
+
return;
|
|
160
|
+
for (const prop of obj.properties) {
|
|
161
|
+
if (!ts.isPropertyAssignment(prop))
|
|
162
|
+
continue;
|
|
163
|
+
const init = prop.initializer;
|
|
164
|
+
if (ts.isStringLiteral(init) || ts.isNoSubstitutionTemplateLiteral(init)) {
|
|
165
|
+
emitTvSlot([init], sf, undefined, results, seenNodePos);
|
|
166
|
+
}
|
|
167
|
+
else if (ts.isArrayLiteralExpression(init)) {
|
|
168
|
+
const arrayPos = init.getStart(sf);
|
|
169
|
+
if (seenNodePos.has(arrayPos))
|
|
170
|
+
continue;
|
|
171
|
+
seenNodePos.add(arrayPos);
|
|
172
|
+
const staticLits = [];
|
|
173
|
+
for (const el of init.elements) {
|
|
174
|
+
if (ts.isSpreadElement(el))
|
|
175
|
+
continue;
|
|
176
|
+
if (ts.isStringLiteral(el) || ts.isNoSubstitutionTemplateLiteral(el)) {
|
|
177
|
+
staticLits.push(el);
|
|
178
|
+
}
|
|
179
|
+
else if (ts.isCallExpression(el) &&
|
|
180
|
+
isCnOrTvIdentifier(el.expression, "cn", knownBindings)) {
|
|
181
|
+
for (const arg of el.arguments) {
|
|
182
|
+
forEachStringLiteralInClassExpression(arg, (lit) => {
|
|
183
|
+
if (!isUnsafeLiteralForCnStyleApplySplit(lit))
|
|
184
|
+
staticLits.push(lit);
|
|
185
|
+
}, 0, CN_APPLY_LITERAL_WALK_OPTS);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
else if (ts.isObjectLiteralExpression(el)) {
|
|
189
|
+
for (const inner of el.properties) {
|
|
190
|
+
if (!ts.isPropertyAssignment(inner))
|
|
191
|
+
continue;
|
|
192
|
+
const propName = propertyAssignmentNameText(inner);
|
|
193
|
+
if (propName !== "className" && propName !== "class")
|
|
194
|
+
continue;
|
|
195
|
+
const innerInit = inner.initializer;
|
|
196
|
+
if (ts.isStringLiteral(innerInit) || ts.isNoSubstitutionTemplateLiteral(innerInit)) {
|
|
197
|
+
emitTvSlot([innerInit], sf, undefined, results, seenNodePos);
|
|
198
|
+
}
|
|
199
|
+
else if (ts.isArrayLiteralExpression(innerInit)) {
|
|
200
|
+
const innerLits = [];
|
|
201
|
+
for (const innerEl of innerInit.elements) {
|
|
202
|
+
if (!ts.isSpreadElement(innerEl) &&
|
|
203
|
+
(ts.isStringLiteral(innerEl) || ts.isNoSubstitutionTemplateLiteral(innerEl))) {
|
|
204
|
+
innerLits.push(innerEl);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
emitTvSlot(innerLits, sf, undefined, results, seenNodePos);
|
|
208
|
+
}
|
|
209
|
+
else if (ts.isCallExpression(innerInit) &&
|
|
210
|
+
isCnOrTvIdentifier(innerInit.expression, "cn", knownBindings)) {
|
|
211
|
+
const cnLits = [];
|
|
212
|
+
for (const arg of innerInit.arguments) {
|
|
213
|
+
forEachStringLiteralInClassExpression(arg, (lit) => {
|
|
214
|
+
if (!isUnsafeLiteralForCnStyleApplySplit(lit))
|
|
215
|
+
cnLits.push(lit);
|
|
216
|
+
}, 0, CN_APPLY_LITERAL_WALK_OPTS);
|
|
217
|
+
}
|
|
218
|
+
emitTvSlot(cnLits, sf, innerInit, results, seenNodePos);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
if (staticLits.length > 0) {
|
|
224
|
+
emitTvSlot(staticLits, sf, undefined, results, seenNodePos);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
else if (ts.isObjectLiteralExpression(init)) {
|
|
228
|
+
collectTvSlots(sf, init, knownBindings, results, seenNodePos, depth + 1);
|
|
229
|
+
}
|
|
230
|
+
else if (ts.isCallExpression(init) &&
|
|
231
|
+
isCnOrTvIdentifier(init.expression, "cn", knownBindings)) {
|
|
232
|
+
const cnLits = [];
|
|
233
|
+
for (const arg of init.arguments) {
|
|
234
|
+
forEachStringLiteralInClassExpression(arg, (lit) => {
|
|
235
|
+
if (!isUnsafeLiteralForCnStyleApplySplit(lit))
|
|
236
|
+
cnLits.push(lit);
|
|
237
|
+
}, 0, CN_APPLY_LITERAL_WALK_OPTS);
|
|
238
|
+
}
|
|
239
|
+
emitTvSlot(cnLits, sf, init, results, seenNodePos);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
export function collectGroupableStringNodes(sf) {
|
|
244
|
+
const results = [];
|
|
245
|
+
const seenNodePos = new Set();
|
|
246
|
+
const knownBindings = buildKnownCnTvBindings(sf);
|
|
247
|
+
const visit = (node) => {
|
|
248
|
+
if (ts.isCallExpression(node)) {
|
|
249
|
+
if (isCnOrTvIdentifier(node.expression, "cn", knownBindings)) {
|
|
250
|
+
const callPos = node.getStart(sf);
|
|
251
|
+
if (seenNodePos.has(callPos)) {
|
|
252
|
+
ts.forEachChild(node, visit);
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
seenNodePos.add(callPos);
|
|
256
|
+
const staticLits = collectUnconditionalTailwindLiteralsFromCnArguments(node.arguments);
|
|
257
|
+
const totalTokens = staticLits.reduce((s, n) => s + tokenizeClassString(n.text).length, 0);
|
|
258
|
+
if (staticLits.length > 0 && totalTokens >= APPLY_MIN_TOKENS) {
|
|
259
|
+
results.push(makeStringNode(staticLits, sf, false, node));
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
else if (isCnOrTvIdentifier(node.expression, "tv", knownBindings)) {
|
|
263
|
+
const arg0 = node.arguments[0];
|
|
264
|
+
if (arg0 && ts.isObjectLiteralExpression(arg0)) {
|
|
265
|
+
collectTvSlots(sf, arg0, knownBindings, results, seenNodePos);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
ts.forEachChild(node, visit);
|
|
270
|
+
};
|
|
271
|
+
visit(sf);
|
|
272
|
+
return results;
|
|
273
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import ts from "typescript";
|
|
2
|
+
import type { GroupTarget, PlannedGroupEdit, StringNode } from "#lib/arrange/types";
|
|
3
|
+
export declare function targetReplaceStart(target: GroupTarget): number;
|
|
4
|
+
export declare function collectLongJsxClassNameTargets(sf: ts.SourceFile): GroupTarget[];
|
|
5
|
+
export declare function collectGroupTargets(sf: ts.SourceFile, filePath: string): GroupTarget[];
|
|
6
|
+
export declare function formatCnCallReplacement(item: StringNode, sourceText: string, withClassName: boolean): string;
|
|
7
|
+
export declare function planGroupEditForTarget(target: GroupTarget, textAfterUnwrap: string, withClassName: boolean): PlannedGroupEdit | undefined;
|
|
8
|
+
//# sourceMappingURL=targets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"targets.d.ts","sourceRoot":"","sources":["../../../../src/lib/arrange/ast/targets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAY5B,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAOpF,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAO9D;AAED,wBAAgB,8BAA8B,CAAC,EAAE,EAAE,EAAE,CAAC,UAAU,GAAG,WAAW,EAAE,CAkB/E;AAED,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,EAAE,CAAC,UAAU,EAAE,QAAQ,EAAE,MAAM,GAAG,WAAW,EAAE,CAItF;AAED,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,UAAU,EAChB,UAAU,EAAE,MAAM,EAClB,aAAa,EAAE,OAAO,GACrB,MAAM,CA2CR;AAED,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,WAAW,EACnB,eAAe,EAAE,MAAM,EACvB,aAAa,EAAE,OAAO,GACrB,gBAAgB,GAAG,SAAS,CAyE9B"}
|