@codefast/cli 0.5.0-canary.5 → 0.5.0-canary.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 +106 -480
- package/dist/arrange/analyze.js +25 -0
- package/dist/arrange/analyze.js.map +1 -0
- package/dist/arrange/cli-schema.js +29 -0
- package/dist/arrange/cli-schema.js.map +1 -0
- package/dist/arrange/command.js +170 -0
- package/dist/arrange/command.js.map +1 -0
- package/dist/arrange/domain/analyze-service.js +122 -0
- package/dist/arrange/domain/analyze-service.js.map +1 -0
- package/dist/arrange/domain/ast/ast-node.js +240 -0
- package/dist/arrange/domain/ast/ast-node.js.map +1 -0
- package/dist/arrange/domain/ast/collectors-cn.js +81 -0
- package/dist/arrange/domain/ast/collectors-cn.js.map +1 -0
- package/dist/arrange/domain/ast/collectors-jsx.js +24 -0
- package/dist/arrange/domain/ast/collectors-jsx.js.map +1 -0
- package/dist/arrange/domain/ast/collectors-tv.js +319 -0
- package/dist/arrange/domain/ast/collectors-tv.js.map +1 -0
- package/dist/arrange/domain/ast/helpers.js +151 -0
- package/dist/arrange/domain/ast/helpers.js.map +1 -0
- package/dist/arrange/domain/ast/simplify-targets.js +161 -0
- package/dist/arrange/domain/ast/simplify-targets.js.map +1 -0
- package/dist/arrange/domain/ast/targets.js +182 -0
- package/dist/arrange/domain/ast/targets.js.map +1 -0
- package/dist/arrange/domain/constants.js +225 -0
- package/dist/arrange/domain/constants.js.map +1 -0
- package/dist/arrange/domain/grouping-service.js +128 -0
- package/dist/arrange/domain/grouping-service.js.map +1 -0
- package/dist/arrange/domain/grouping.js +435 -0
- package/dist/arrange/domain/grouping.js.map +1 -0
- package/dist/arrange/domain/imports.js +160 -0
- package/dist/arrange/domain/imports.js.map +1 -0
- package/dist/arrange/domain/source-text-formatters.js +100 -0
- package/dist/arrange/domain/source-text-formatters.js.map +1 -0
- package/dist/arrange/domain/tailwind-token.js +50 -0
- package/dist/arrange/domain/tailwind-token.js.map +1 -0
- package/dist/arrange/domain/token-classifier.js +448 -0
- package/dist/arrange/domain/token-classifier.js.map +1 -0
- package/dist/arrange/domain/types.js +11 -0
- package/dist/arrange/domain/types.js.map +1 -0
- package/dist/arrange/output.js +120 -0
- package/dist/arrange/output.js.map +1 -0
- package/dist/arrange/process-file.js +44 -0
- package/dist/arrange/process-file.js.map +1 -0
- package/dist/arrange/resolve-target.js +33 -0
- package/dist/arrange/resolve-target.js.map +1 -0
- package/dist/arrange/scan-target.js +30 -0
- package/dist/arrange/scan-target.js.map +1 -0
- package/dist/arrange/simplify-process-file.js +29 -0
- package/dist/arrange/simplify-process-file.js.map +1 -0
- package/dist/arrange/simplify-sync.js +29 -0
- package/dist/arrange/simplify-sync.js.map +1 -0
- package/dist/arrange/source-parse.js +17 -0
- package/dist/arrange/source-parse.js.map +1 -0
- package/dist/arrange/suggest.js +14 -0
- package/dist/arrange/suggest.js.map +1 -0
- package/dist/arrange/sync.js +48 -0
- package/dist/arrange/sync.js.map +1 -0
- package/dist/arrange/typescript-ast-translator.js +455 -0
- package/dist/arrange/typescript-ast-translator.js.map +1 -0
- package/dist/arrange/workspace.js +31 -0
- package/dist/arrange/workspace.js.map +1 -0
- package/dist/audit/cli-schema.js +22 -0
- package/dist/audit/cli-schema.js.map +1 -0
- package/dist/audit/command.js +60 -0
- package/dist/audit/command.js.map +1 -0
- package/dist/audit/domain/audit-file.js +101 -0
- package/dist/audit/domain/audit-file.js.map +1 -0
- package/dist/audit/domain/mappings.js +103 -0
- package/dist/audit/domain/mappings.js.map +1 -0
- package/dist/audit/domain/tokenize.js +83 -0
- package/dist/audit/domain/tokenize.js.map +1 -0
- package/dist/audit/domain/types.js +2 -0
- package/dist/audit/domain/types.js.map +1 -0
- package/dist/audit/output.js +44 -0
- package/dist/audit/output.js.map +1 -0
- package/dist/audit/prepare.js +42 -0
- package/dist/audit/prepare.js.map +1 -0
- package/dist/audit/run.js +57 -0
- package/dist/audit/run.js.map +1 -0
- package/dist/{bin.mjs → bin.js} +2 -4
- package/dist/bin.js.map +1 -0
- package/dist/cli.js +45 -0
- package/dist/cli.js.map +1 -0
- package/dist/core/cli/format-error.js +19 -0
- package/dist/core/cli/format-error.js.map +1 -0
- package/dist/core/cli/global-options.js +10 -0
- package/dist/core/cli/global-options.js.map +1 -0
- package/dist/core/cli/positional.js +9 -0
- package/dist/core/cli/positional.js.map +1 -0
- package/dist/core/cli/result-handle.js +69 -0
- package/dist/core/cli/result-handle.js.map +1 -0
- package/dist/core/config/loader.js +88 -0
- package/dist/core/config/loader.js.map +1 -0
- package/dist/core/config/schema.js +97 -0
- package/dist/core/config/schema.js.map +1 -0
- package/dist/core/config/warnings.js +12 -0
- package/dist/core/config/warnings.js.map +1 -0
- package/dist/core/config.js +18 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/errors.js +58 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/exit-codes.js +15 -0
- package/dist/core/exit-codes.js.map +1 -0
- package/dist/core/filesystem/node.js +33 -0
- package/dist/core/filesystem/node.js.map +1 -0
- package/dist/core/filesystem/port.js +2 -0
- package/dist/core/filesystem/port.js.map +1 -0
- package/dist/core/glob.js +20 -0
- package/dist/core/glob.js.map +1 -0
- package/dist/core/logger.js +13 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/result.js +16 -0
- package/dist/core/result.js.map +1 -0
- package/dist/core/schema-parse.js +21 -0
- package/dist/core/schema-parse.js.map +1 -0
- package/dist/core/source-text-edit.js +62 -0
- package/dist/core/source-text-edit.js.map +1 -0
- package/dist/core/verbose-diagnostics.js +9 -0
- package/dist/core/verbose-diagnostics.js.map +1 -0
- package/dist/core/workspace/resolver.js +208 -0
- package/dist/core/workspace/resolver.js.map +1 -0
- package/dist/core/workspace/typescript-walk.js +41 -0
- package/dist/core/workspace/typescript-walk.js.map +1 -0
- package/dist/mirror/cli-result.js +20 -0
- package/dist/mirror/cli-result.js.map +1 -0
- package/dist/mirror/cli-schema.js +11 -0
- package/dist/mirror/cli-schema.js.map +1 -0
- package/dist/mirror/command.js +73 -0
- package/dist/mirror/command.js.map +1 -0
- package/dist/mirror/dist-filesystem-impl.js +53 -0
- package/dist/mirror/dist-filesystem-impl.js.map +1 -0
- package/dist/mirror/domain/constants.js +21 -0
- package/dist/mirror/domain/constants.js.map +1 -0
- package/dist/mirror/domain/dirent-guard.js +16 -0
- package/dist/mirror/domain/dirent-guard.js.map +1 -0
- package/dist/mirror/domain/dist-filesystem.js +2 -0
- package/dist/mirror/domain/dist-filesystem.js.map +1 -0
- package/dist/mirror/domain/errors.js +19 -0
- package/dist/mirror/domain/errors.js.map +1 -0
- package/dist/mirror/domain/exports.js +284 -0
- package/dist/mirror/domain/exports.js.map +1 -0
- package/dist/mirror/domain/package-display-name.js +10 -0
- package/dist/mirror/domain/package-display-name.js.map +1 -0
- package/dist/mirror/domain/path-normalizer.js +8 -0
- package/dist/mirror/domain/path-normalizer.js.map +1 -0
- package/dist/mirror/domain/types.js +2 -0
- package/dist/mirror/domain/types.js.map +1 -0
- package/dist/mirror/output.js +47 -0
- package/dist/mirror/output.js.map +1 -0
- package/dist/mirror/package-path.js +40 -0
- package/dist/mirror/package-path.js.map +1 -0
- package/dist/mirror/prepare.js +37 -0
- package/dist/mirror/prepare.js.map +1 -0
- package/dist/mirror/supplement-exports.js +157 -0
- package/dist/mirror/supplement-exports.js.map +1 -0
- package/dist/mirror/sync-reporter.js +125 -0
- package/dist/mirror/sync-reporter.js.map +1 -0
- package/dist/mirror/sync-types.js +2 -0
- package/dist/mirror/sync-types.js.map +1 -0
- package/dist/mirror/sync-workspace-package.js +117 -0
- package/dist/mirror/sync-workspace-package.js.map +1 -0
- package/dist/mirror/sync.js +90 -0
- package/dist/mirror/sync.js.map +1 -0
- package/dist/mirror/write-exports.js +145 -0
- package/dist/mirror/write-exports.js.map +1 -0
- package/dist/tag/cli-result.js +12 -0
- package/dist/tag/cli-result.js.map +1 -0
- package/dist/tag/cli-schema.js +13 -0
- package/dist/tag/cli-schema.js.map +1 -0
- package/dist/tag/command.js +69 -0
- package/dist/tag/command.js.map +1 -0
- package/dist/tag/domain/types.js +2 -0
- package/dist/tag/domain/types.js.map +1 -0
- package/dist/tag/output.js +101 -0
- package/dist/tag/output.js.map +1 -0
- package/dist/tag/prepare.js +30 -0
- package/dist/tag/prepare.js.map +1 -0
- package/dist/tag/resolve-target-path.js +14 -0
- package/dist/tag/resolve-target-path.js.map +1 -0
- package/dist/tag/since-writer.js +231 -0
- package/dist/tag/since-writer.js.map +1 -0
- package/dist/tag/sync.js +166 -0
- package/dist/tag/sync.js.map +1 -0
- package/dist/tag/target-candidates.js +79 -0
- package/dist/tag/target-candidates.js.map +1 -0
- package/dist/tag/target-runner.js +25 -0
- package/dist/tag/target-runner.js.map +1 -0
- package/dist/tag/version-resolver.js +28 -0
- package/dist/tag/version-resolver.js.map +1 -0
- package/package.json +25 -20
- package/dist/arrange/analyze.mjs +0 -24
- package/dist/arrange/cli-schema.mjs +0 -27
- package/dist/arrange/command.mjs +0 -130
- package/dist/arrange/domain/analyze-service.mjs +0 -102
- package/dist/arrange/domain/ast/ast-node.mjs +0 -215
- package/dist/arrange/domain/ast/collectors-cn.mjs +0 -64
- package/dist/arrange/domain/ast/collectors-jsx.mjs +0 -23
- package/dist/arrange/domain/ast/collectors-tv.mjs +0 -189
- package/dist/arrange/domain/ast/helpers.mjs +0 -108
- package/dist/arrange/domain/ast/simplify-targets.mjs +0 -109
- package/dist/arrange/domain/ast/targets.mjs +0 -134
- package/dist/arrange/domain/constants.mjs +0 -213
- package/dist/arrange/domain/grouping-service.mjs +0 -121
- package/dist/arrange/domain/grouping.mjs +0 -338
- package/dist/arrange/domain/imports.mjs +0 -107
- package/dist/arrange/domain/source-text-formatters.mjs +0 -88
- package/dist/arrange/domain/tailwind-token.mjs +0 -40
- package/dist/arrange/domain/token-classifier.mjs +0 -218
- package/dist/arrange/domain/types.mjs +0 -1
- package/dist/arrange/output.mjs +0 -87
- package/dist/arrange/process-file.mjs +0 -42
- package/dist/arrange/resolve-target.mjs +0 -24
- package/dist/arrange/scan-target.mjs +0 -29
- package/dist/arrange/simplify-process-file.mjs +0 -35
- package/dist/arrange/simplify-sync.mjs +0 -32
- package/dist/arrange/source-parse.mjs +0 -18
- package/dist/arrange/suggest.mjs +0 -15
- package/dist/arrange/sync.mjs +0 -51
- package/dist/arrange/typescript-ast-translator.mjs +0 -354
- package/dist/arrange/workspace.mjs +0 -31
- package/dist/cli.mjs +0 -34
- package/dist/core/cli/format-error.mjs +0 -15
- package/dist/core/cli/global-options.mjs +0 -10
- package/dist/core/cli/positional.mjs +0 -11
- package/dist/core/cli/result-handle.mjs +0 -51
- package/dist/core/config/loader.mjs +0 -79
- package/dist/core/config/schema.mjs +0 -60
- package/dist/core/config/warnings.mjs +0 -12
- package/dist/core/config.mjs +0 -19
- package/dist/core/errors.mjs +0 -35
- package/dist/core/exit-codes.mjs +0 -17
- package/dist/core/filesystem/node.mjs +0 -32
- package/dist/core/filesystem/port.mjs +0 -1
- package/dist/core/glob.mjs +0 -20
- package/dist/core/logger.mjs +0 -15
- package/dist/core/result.mjs +0 -21
- package/dist/core/schema-parse.mjs +0 -18
- package/dist/core/source-text-edit.mjs +0 -56
- package/dist/core/verbose-diagnostics.mjs +0 -11
- package/dist/core/workspace/resolver.mjs +0 -177
- package/dist/core/workspace/typescript-walk.mjs +0 -36
- package/dist/mirror/cli-result.mjs +0 -22
- package/dist/mirror/cli-schema.mjs +0 -13
- package/dist/mirror/command.mjs +0 -58
- package/dist/mirror/dist-filesystem-impl.mjs +0 -42
- package/dist/mirror/domain/constants.mjs +0 -31
- package/dist/mirror/domain/dirent-guard.mjs +0 -16
- package/dist/mirror/domain/dist-filesystem.mjs +0 -1
- package/dist/mirror/domain/errors.mjs +0 -21
- package/dist/mirror/domain/exports.mjs +0 -226
- package/dist/mirror/domain/package-display-name.mjs +0 -12
- package/dist/mirror/domain/path-normalizer.mjs +0 -10
- package/dist/mirror/domain/types.mjs +0 -1
- package/dist/mirror/output.mjs +0 -48
- package/dist/mirror/package-path.mjs +0 -32
- package/dist/mirror/prepare.mjs +0 -33
- package/dist/mirror/supplement-exports.mjs +0 -114
- package/dist/mirror/sync-reporter.mjs +0 -107
- package/dist/mirror/sync-types.mjs +0 -1
- package/dist/mirror/sync-workspace-package.mjs +0 -109
- package/dist/mirror/sync.mjs +0 -88
- package/dist/mirror/write-exports.mjs +0 -94
- package/dist/tag/cli-result.mjs +0 -11
- package/dist/tag/cli-schema.mjs +0 -15
- package/dist/tag/command.mjs +0 -56
- package/dist/tag/domain/types.mjs +0 -1
- package/dist/tag/output.mjs +0 -87
- package/dist/tag/prepare.mjs +0 -29
- package/dist/tag/resolve-target-path.mjs +0 -12
- package/dist/tag/since-writer.mjs +0 -131
- package/dist/tag/sync.mjs +0 -149
- package/dist/tag/target-candidates.mjs +0 -68
- package/dist/tag/target-runner.mjs +0 -26
- package/dist/tag/version-resolver.mjs +0 -25
|
@@ -1,218 +0,0 @@
|
|
|
1
|
-
import { COMPATIBLE_BUCKET_SETS, RESPONSIVE_PREFIX, STATE_PREFIXES } from "./constants.mjs";
|
|
2
|
-
import { indexOfFirstVariantColon, stripVariants } from "./tailwind-token.mjs";
|
|
3
|
-
//#region src/arrange/domain/token-classifier.ts
|
|
4
|
-
/**
|
|
5
|
-
* Bare-token classification is **total** (always returns a {@link Bucket}). The `Result` pattern
|
|
6
|
-
* (`isOk` / `isErr`) belongs at arrange use-case / I/O boundaries, not on this hot path.
|
|
7
|
-
*
|
|
8
|
-
* Variant stems not covered by a single entry in STATE_PREFIXES (compound `has-*`,
|
|
9
|
-
* numbered `nth-*`, media features, v4 `in-[…]`, child selectors `*` / `**`, …).
|
|
10
|
-
* When these are missed, `isStateToken` is false and the variant is stripped — the
|
|
11
|
-
* utility is then bucketed as if it were unconditional, which breaks preview grouping.
|
|
12
|
-
*/
|
|
13
|
-
function isCompoundOrMediaVariantPrefix(prefix) {
|
|
14
|
-
if (prefix === "*" || prefix === "**") return true;
|
|
15
|
-
if (prefix === "inert") return true;
|
|
16
|
-
if (prefix.startsWith("has-")) return true;
|
|
17
|
-
if (prefix.startsWith("in-[")) return true;
|
|
18
|
-
if (/^nth(?:-last)?(?:-of-type)?(?:-\d+|-\[)/.test(prefix) || /^nth-of-type-\d+$/.test(prefix) || /^nth-last-of-type-\d+$/.test(prefix)) return true;
|
|
19
|
-
if (/^(?:user-valid|user-invalid|contrast-more|contrast-less|forced-colors|inverted-colors)$/.test(prefix)) return true;
|
|
20
|
-
if (/^(?:any-)?pointer-(?:fine|coarse|none)$/.test(prefix)) return true;
|
|
21
|
-
if (/^(?:portrait|landscape|noscript)$/.test(prefix)) return true;
|
|
22
|
-
return false;
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Outermost variant segment: first `:` at bracket depth 0 → text before it.
|
|
26
|
-
*/
|
|
27
|
-
function firstLeadingVariantPrefix(token) {
|
|
28
|
-
const colonIdx = indexOfFirstVariantColon(token);
|
|
29
|
-
if (colonIdx === -1) return;
|
|
30
|
-
return token.slice(0, colonIdx);
|
|
31
|
-
}
|
|
32
|
-
function isSelectorVariantToken(token) {
|
|
33
|
-
const prefix = firstLeadingVariantPrefix(token);
|
|
34
|
-
if (prefix === void 0) return false;
|
|
35
|
-
if (prefix === "*" || prefix === "**") return true;
|
|
36
|
-
if (prefix.startsWith("has-")) return true;
|
|
37
|
-
if (prefix.startsWith("in-[")) return true;
|
|
38
|
-
if (prefix.startsWith("group-[")) return true;
|
|
39
|
-
if (prefix.startsWith("peer-[")) return true;
|
|
40
|
-
if (prefix.startsWith("not-[")) return true;
|
|
41
|
-
return false;
|
|
42
|
-
}
|
|
43
|
-
function isStateToken(token) {
|
|
44
|
-
const prefix = firstLeadingVariantPrefix(token);
|
|
45
|
-
if (prefix === void 0) return false;
|
|
46
|
-
if (RESPONSIVE_PREFIX.test(token)) return true;
|
|
47
|
-
if (STATE_PREFIXES.has(prefix)) return true;
|
|
48
|
-
if (prefix.startsWith("data-[")) return true;
|
|
49
|
-
if (prefix.startsWith("aria-[")) return true;
|
|
50
|
-
if (prefix.startsWith("supports-[")) return true;
|
|
51
|
-
if (prefix.startsWith("in-data-")) return true;
|
|
52
|
-
if (/^data-(?!\[)/.test(prefix)) return true;
|
|
53
|
-
if (prefix.startsWith("aria-")) return true;
|
|
54
|
-
if (/^(group|peer)-/.test(prefix)) return true;
|
|
55
|
-
if (prefix.startsWith("not-")) return true;
|
|
56
|
-
if (isCompoundOrMediaVariantPrefix(prefix)) return true;
|
|
57
|
-
if (prefix.startsWith("[") && prefix.endsWith("]")) return true;
|
|
58
|
-
return false;
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* Secondary sort inside the **composite** bucket: opacity / blend / isolation →
|
|
62
|
-
* 3D context → 3D transforms → 2D transforms → filters → will-change.
|
|
63
|
-
*
|
|
64
|
-
* @since 0.3.16-canary.0
|
|
65
|
-
*/
|
|
66
|
-
function compositeSecondaryOrder(bareUtility) {
|
|
67
|
-
const b = bareUtility;
|
|
68
|
-
if (/^opacity(?:-|$)/.test(b) || b.startsWith("mix-blend-") || /^isolation(?:-|$)/.test(b) || b === "isolate") return 0;
|
|
69
|
-
if (b === "transform-3d" || /^perspective(?:-|$)/.test(b)) return 10;
|
|
70
|
-
if (/^rotate-[xyz](?:-|$)/.test(b) || /^translate-z(?:-|$)/.test(b) || /^scale-z(?:-|$)/.test(b)) return 20;
|
|
71
|
-
if (/^translate(?:-|$)/.test(b) || /^scale(?:-|$)/.test(b) || /^rotate(?:-|$)/.test(b) || /^skew(?:-|$)/.test(b)) return 30;
|
|
72
|
-
if (/^transform(?:-(?:gpu|cpu|none))?$/.test(b)) return 35;
|
|
73
|
-
if (/^blur(?:-|$)/.test(b) || b.startsWith("backdrop-") || /^filter(?:-|$)/.test(b) || b.startsWith("brightness-") || b.startsWith("contrast-") || /^grayscale(?:-|$)/.test(b) || b.startsWith("hue-rotate-") || /^invert(?:-|$)/.test(b) || b.startsWith("saturate-") || /^sepia(?:-|$)/.test(b)) return 40;
|
|
74
|
-
if (b.startsWith("will-change")) return 50;
|
|
75
|
-
return 99;
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* Classify a **bare** utility (no `hover:` / `md:` / … prefixes).
|
|
79
|
-
*/
|
|
80
|
-
function classifyBareUtility(bareUtility) {
|
|
81
|
-
const b = bareUtility;
|
|
82
|
-
if (/^@container(?:\/[a-z][a-z0-9-]*)?$/i.test(b)) return "existence";
|
|
83
|
-
if (/^(?:hidden|contents|sr-only|not-sr-only|list-item|flow-root)$/.test(b) || /^(?:block|inline-block|inline)$/.test(b)) return "existence";
|
|
84
|
-
if (/^table(?:$|-)/.test(b)) return "existence";
|
|
85
|
-
if (b.startsWith("contain-")) return "existence";
|
|
86
|
-
if (/^(?:group|peer)(?:\/[a-z][a-z0-9-]*)?$/.test(b)) return "existence";
|
|
87
|
-
if (/^(?:static|relative|absolute|fixed|sticky)$/.test(b)) return "position";
|
|
88
|
-
if (/^-?(?:inset|top|right|bottom|left|start|end)(?:-|\/|$)/.test(b) || /^-?(?:inset-x|inset-y|inset-s|inset-e)-/.test(b)) return "position";
|
|
89
|
-
if (/^-?z-/.test(b) || b === "z-auto") return "position";
|
|
90
|
-
if (/^(?:flex|inline-flex|grid|inline-grid|subgrid|masonry)(?:$|-)/.test(b) || /^(?:items|justify|justify-items|justify-self|content|self|place|place-content|place-items|place-self)-/.test(b) || /^-?(?:gap|space-[xy]|col-|row-|grid-|auto-cols|auto-rows|order-|order$)/.test(b) || /^-?(?:auto-flow|grid-flow)-/.test(b) || /^(?:columns-|break-after|break-before|break-inside)-/.test(b) || /^(?:float|clear)-/.test(b) || /^(?:wrap-|flex-wrap|flex-nowrap|flex-row|flex-col|flex-auto|flex-initial|flex-none|flex-1|flex-\[)/.test(b) || /^container$/.test(b)) return "layout";
|
|
91
|
-
if (/^-?(?:w|h|min-w|max-w|min-h|max-h|size|aspect|shrink|grow|basis)-/.test(b) || /^(?:shrink|grow)(?:$|-)/.test(b) || /^-?overflow-/.test(b) || /^-?object-/.test(b)) return "sizing";
|
|
92
|
-
if (/^-?(?:p|px|py|pt|pb|pl|pr|ps|pe|m|mx|my|mt|mb|ml|mr|ms|me)-/.test(b)) return "spacing";
|
|
93
|
-
if (/^-?(?:rounded|border|ring|divide|inset-ring)(?:-|\/|$)/.test(b) || /^(?:rounded|border|ring|divide|inset-ring)$/.test(b) || b.startsWith("ring-offset-")) return "shape";
|
|
94
|
-
if (/^-?bg-/.test(b) || /^(?:from|via|to)(?:-|\/|$)/.test(b) || /^bg-(?:linear|radial|conic)-/.test(b) || /^-?mask-/.test(b) || /^-?(?:fill|stroke)-/.test(b)) return "background";
|
|
95
|
-
if (/^-?(?:shadow|inset-shadow|drop-shadow|text-shadow)(?:-|\/|$)/.test(b) || /^(?:shadow|inset-shadow)$/.test(b) || /^-?outline(?:-|\/|$)/.test(b) || /^outline$/.test(b)) return "shadow";
|
|
96
|
-
if (/^-?(?:font|leading|tracking|list|indent|align|decoration|underline-offset|text-wrap|text-balance|text-pretty)-/.test(b) || /^-?(?:text-(?!shadow))/.test(b) || /^-?(?:whitespace|break|line-clamp|hyphens)-/.test(b) || /^(?:antialiased|subpixel-antialiased|italic|not-italic|overline|line-through|underline|no-underline|uppercase|lowercase|capitalize|normal-case|truncate|text-wrap|text-balance|text-pretty)$/.test(b) || b.startsWith("text-wrap-") || /^tabular-nums$|^slashed-zero$|^lining-nums$|^oldstyle-nums$|^proportional-nums$/.test(b)) return "typography";
|
|
97
|
-
if (/^opacity(?:-|$)/.test(b) || b.startsWith("mix-blend-") || /^isolation(?:-|$)/.test(b) || b === "isolate" || /^transform(?:-(?:gpu|cpu|none))?$/.test(b) || /^-?(?:translate|scale|rotate|skew)-/.test(b) || /^perspective(?:-|$)/.test(b) || b === "transform-3d" || /^blur(?:-|$)/.test(b) || b.startsWith("backdrop-") || /^filter(?:-|$)/.test(b) || b.startsWith("brightness-") || b.startsWith("contrast-") || /^grayscale(?:-|$)/.test(b) || b.startsWith("hue-rotate-") || /^invert(?:-|$)/.test(b) || b.startsWith("saturate-") || /^sepia(?:-|$)/.test(b) || b.startsWith("will-change")) return "composite";
|
|
98
|
-
if (/^(?:transition|duration|ease|delay|animate)(?:-|$)/.test(b) || b.startsWith("ease-")) return "motion";
|
|
99
|
-
if (/^(?:cursor|pointer-events|select|touch|scroll|scroll-m|scroll-p|overscroll|snap|resize|field-sizing|appearance|scheme|color-scheme|accent|caret)(?:-|$)/.test(b) || /^(?:cursor|select|resize)$/.test(b) || b.startsWith("scroll-behavior") || b.startsWith("scroll-snap") || b.startsWith("touch-action") || b === "inert") return "behavior";
|
|
100
|
-
return "other";
|
|
101
|
-
}
|
|
102
|
-
/**
|
|
103
|
-
* Arbitrary **parent** selectors (`[&…]`, `[&>a]:…`, slot forms with `&` inside the bracket)
|
|
104
|
-
* scope utilities to descendants — bucket as `selector` so they chunk apart from base layout/typography
|
|
105
|
-
* and are labeled distinctly from interactive `state` variants (`hover:`, `data-[…]:`, …).
|
|
106
|
-
* Pure arbitrary **properties** (`[--x]:`, `[color:red]`) have no `&` in the leading `[…]` segment.
|
|
107
|
-
*/
|
|
108
|
-
function isArbitraryParentSelectorStateToken(token) {
|
|
109
|
-
if (token.startsWith("[&")) return true;
|
|
110
|
-
if (!token.startsWith("[")) return false;
|
|
111
|
-
const colonIdx = indexOfFirstVariantColon(token);
|
|
112
|
-
if (colonIdx === -1 || colonIdx === 0 || token[colonIdx - 1] !== "]") return false;
|
|
113
|
-
return token.slice(0, colonIdx).includes("&");
|
|
114
|
-
}
|
|
115
|
-
/**
|
|
116
|
-
* @since 0.3.16-canary.0
|
|
117
|
-
*/
|
|
118
|
-
function classifyToken(token) {
|
|
119
|
-
if (isArbitraryParentSelectorStateToken(token)) return "selector";
|
|
120
|
-
if (isSelectorVariantToken(token)) return "selector";
|
|
121
|
-
if (/^@container(?:\/[a-z][a-z0-9-]*)?$/i.test(token)) return "existence";
|
|
122
|
-
if (token.startsWith("[")) {
|
|
123
|
-
const splitIdx = indexOfFirstVariantColon(token);
|
|
124
|
-
if (splitIdx === -1) return "arbitrary";
|
|
125
|
-
if (splitIdx === 0 || token[splitIdx - 1] !== "]") return "arbitrary";
|
|
126
|
-
}
|
|
127
|
-
if (firstLeadingVariantPrefix(token) === "starting") return "starting";
|
|
128
|
-
if (isStateToken(token)) return "state";
|
|
129
|
-
return classifyBareUtility(stripVariants(token));
|
|
130
|
-
}
|
|
131
|
-
/**
|
|
132
|
-
* Stable key for `data-[…]` variants so unrelated selectors stay split, while
|
|
133
|
-
* **branching on the full bracket** (e.g. `data-[vaul-drawer-direction=bottom]`
|
|
134
|
-
* vs `=left`) keeps direction-specific utilities in separate state groups.
|
|
135
|
-
*/
|
|
136
|
-
function dataAttributeStem(token) {
|
|
137
|
-
const match = token.match(/^data-\[([^\]]*)\]/);
|
|
138
|
-
return match ? `data-[${match[1]}]` : "data";
|
|
139
|
-
}
|
|
140
|
-
/**
|
|
141
|
-
* Same idea as {@link dataAttributeStem} for `aria-[…]:` variants.
|
|
142
|
-
*/
|
|
143
|
-
function ariaAttributeStem(token) {
|
|
144
|
-
const match = token.match(/^aria-\[([^\]]*)\]/);
|
|
145
|
-
return match ? `aria-[${match[1]}]` : "aria";
|
|
146
|
-
}
|
|
147
|
-
/**
|
|
148
|
-
* `in-data-[…]:` — normalize on the full bracket expression like {@link dataAttributeStem}.
|
|
149
|
-
*/
|
|
150
|
-
function inDataAttributeStem(token) {
|
|
151
|
-
const match = token.match(/^in-data-\[([^\]]*)\]/);
|
|
152
|
-
return match ? `in-data-[${match[1]}]` : "in-data";
|
|
153
|
-
}
|
|
154
|
-
/**
|
|
155
|
-
* Stable key for splitting adjacent `state` / `starting` tokens in {@link suggestCnGroups}
|
|
156
|
-
* (`selector` uses {@link selectorKey}).
|
|
157
|
-
* Uses the **full variant stack** (every `:` segment outside `[…]`), not only the
|
|
158
|
-
* outermost prefix, so `@md/foo:[&>*]:w-auto` and `@md/foo:has-[…]:mt-px` stay in
|
|
159
|
-
* separate groups while `hover:opacity` still keys as `hover` + `opacity`…
|
|
160
|
-
*
|
|
161
|
-
* `data-[…]` / `aria-[…]` normalize the first segment via {@link dataAttributeStem} /
|
|
162
|
-
* {@link ariaAttributeStem} (full token required for bracket capture).
|
|
163
|
-
*
|
|
164
|
-
* @since 0.3.16-canary.0
|
|
165
|
-
*/
|
|
166
|
-
function stateKey(token) {
|
|
167
|
-
const layers = [];
|
|
168
|
-
let rest = token;
|
|
169
|
-
while (rest.length > 0) {
|
|
170
|
-
const colonIdx = indexOfFirstVariantColon(rest);
|
|
171
|
-
if (colonIdx === -1) break;
|
|
172
|
-
layers.push(rest.slice(0, colonIdx));
|
|
173
|
-
rest = rest.slice(colonIdx + 1);
|
|
174
|
-
}
|
|
175
|
-
if (layers.length === 0) return token;
|
|
176
|
-
const firstLayer = layers[0];
|
|
177
|
-
if (firstLayer === void 0) return token;
|
|
178
|
-
if (firstLayer.startsWith("data-[")) layers[0] = dataAttributeStem(token);
|
|
179
|
-
else if (firstLayer.startsWith("aria-[")) layers[0] = ariaAttributeStem(token);
|
|
180
|
-
else if (firstLayer.startsWith("in-data-[")) layers[0] = inDataAttributeStem(token);
|
|
181
|
-
return layers.join("");
|
|
182
|
-
}
|
|
183
|
-
const SELECTOR_KEY_SEP = "";
|
|
184
|
-
/**
|
|
185
|
-
* Variant key for {@link Bucket} `"selector"` tokens in {@link suggestCnGroups}.
|
|
186
|
-
* Reuses {@link stateKey} layer splitting, then normalizes common Radix SVG patterns so
|
|
187
|
-
* `[&_svg]:…` and `[&_svg:not([class*='size-'])]:…` stay in one chunk.
|
|
188
|
-
*
|
|
189
|
-
* @since 0.3.16-canary.0
|
|
190
|
-
*/
|
|
191
|
-
function selectorKey(token) {
|
|
192
|
-
return stateKey(token).split(SELECTOR_KEY_SEP).map(normalizeSelectorVariantLayer).join(SELECTOR_KEY_SEP);
|
|
193
|
-
}
|
|
194
|
-
function normalizeSelectorVariantLayer(layer) {
|
|
195
|
-
if (layer === "[&_svg:not([class*='size-'])]") return "[&_svg]";
|
|
196
|
-
return layer;
|
|
197
|
-
}
|
|
198
|
-
/**
|
|
199
|
-
* @since 0.3.16-canary.0
|
|
200
|
-
*/
|
|
201
|
-
function bucketsCompatible(a, b) {
|
|
202
|
-
if (a === b) return true;
|
|
203
|
-
return COMPATIBLE_BUCKET_SETS.some((bucketSet) => bucketSet.has(a) && bucketSet.has(b));
|
|
204
|
-
}
|
|
205
|
-
/**
|
|
206
|
-
* Like {@link bucketsCompatible}, but never merge two distinct state / starting / selector variant blobs.
|
|
207
|
-
*
|
|
208
|
-
* @since 0.3.16-canary.0
|
|
209
|
-
*/
|
|
210
|
-
function bucketsMergeCompatible(a, b) {
|
|
211
|
-
if (a === "state" && b === "state") return false;
|
|
212
|
-
if (a === "starting" && b === "starting") return false;
|
|
213
|
-
if (a === "selector" && b === "selector") return false;
|
|
214
|
-
if (a === "arbitrary" || b === "arbitrary") return false;
|
|
215
|
-
return bucketsCompatible(a, b);
|
|
216
|
-
}
|
|
217
|
-
//#endregion
|
|
218
|
-
export { bucketsCompatible, bucketsMergeCompatible, classifyToken, compositeSecondaryOrder, selectorKey, stateKey };
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/dist/arrange/output.mjs
DELETED
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import "./domain/constants.mjs";
|
|
2
|
-
import { lineOf } from "./domain/ast/helpers.mjs";
|
|
3
|
-
import { logger } from "../core/logger.mjs";
|
|
4
|
-
import path from "node:path";
|
|
5
|
-
//#region src/arrange/output.ts
|
|
6
|
-
/**
|
|
7
|
-
* @since 0.3.16-canary.0
|
|
8
|
-
*/
|
|
9
|
-
function printAnalyzeReport(resolvedTargetPath, report) {
|
|
10
|
-
logger.out(`Path: ${path.resolve(resolvedTargetPath)}`);
|
|
11
|
-
logger.out(`.ts/.tsx files: ${report.files}`);
|
|
12
|
-
logger.out(`cn(...) call sites: ${report.cnCallExpressions}`);
|
|
13
|
-
logger.out(`tv(...) call sites: ${report.tvCallExpressions}`);
|
|
14
|
-
logger.out(`\nLong cn(...) string literals (≥18 tokens — consider splitting arguments): ${report.longCnStringLiterals.length}`);
|
|
15
|
-
for (const findingEntry of report.longCnStringLiterals.slice(0, 40)) logger.out(` ${findingEntry.file}:${findingEntry.line} (${findingEntry.tokenCount} tokens) ${findingEntry.preview}`);
|
|
16
|
-
if (report.longCnStringLiterals.length > 40) logger.out(` … and ${report.longCnStringLiterals.length - 40} more`);
|
|
17
|
-
logger.out(`\nLong tv({...}) string literals in base/variants/… (≥18 tokens): ${report.longTvStringLiterals.length}`);
|
|
18
|
-
for (const findingEntry of report.longTvStringLiterals.slice(0, 40)) logger.out(` ${findingEntry.file}:${findingEntry.line} (${findingEntry.tokenCount} tokens) ${findingEntry.preview}`);
|
|
19
|
-
if (report.longTvStringLiterals.length > 40) logger.out(` … and ${report.longTvStringLiterals.length - 40} more`);
|
|
20
|
-
logger.out(`\nJSX className="..." or className={'...'} (static strings, ≥18 tokens): ${report.longJsxClassNameLiterals.length}`);
|
|
21
|
-
for (const findingEntry of report.longJsxClassNameLiterals.slice(0, 40)) logger.out(` ${findingEntry.file}:${findingEntry.line} (${findingEntry.tokenCount} tokens) ${findingEntry.preview}`);
|
|
22
|
-
if (report.longJsxClassNameLiterals.length > 40) logger.out(` … and ${report.longJsxClassNameLiterals.length - 40} more`);
|
|
23
|
-
logger.out(`\ncn(...) nested inside tv({...}) (prefer a string or array — preview/apply can rewrite): ${report.cnInsideTvCalls.length}`);
|
|
24
|
-
for (const findingEntry of report.cnInsideTvCalls.slice(0, 40)) logger.out(` ${findingEntry.file}:${findingEntry.line} (${findingEntry.argCount} args) ${findingEntry.preview}`);
|
|
25
|
-
if (report.cnInsideTvCalls.length > 40) logger.out(` … and ${report.cnInsideTvCalls.length - 40} more`);
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* @since 0.3.16-canary.0
|
|
29
|
-
*/
|
|
30
|
-
function printSyncResult(result, write) {
|
|
31
|
-
logger.out(`\nTotal: ${result.filePaths.length} file(s), ${result.totalFound} site(s) (cn/tv/JSX className) to review.`);
|
|
32
|
-
if (write) logger.out(`Applied: ${result.totalChanged} site(s) updated.`);
|
|
33
|
-
else logger.out(`(Re-run without --dry-run to write changes, or "pnpm cli:arrange" / "pnpm exec codefast arrange")`);
|
|
34
|
-
if (write ? result.totalChanged > 0 : result.totalFound > 0) logger.out("Note: class order may change across concern groups — smoke-test the UI if you rely on cascade order.");
|
|
35
|
-
if (result.hookError !== null) logger.err(result.hookError);
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* @since 0.3.16-canary.0
|
|
39
|
-
*/
|
|
40
|
-
function printSimplifyResult(result, write) {
|
|
41
|
-
logger.out(`\nTotal: ${result.filePaths.length} file(s), ${result.totalFound} site(s) to simplify.`);
|
|
42
|
-
if (write) logger.out(`Applied: ${result.totalChanged} site(s) updated.`);
|
|
43
|
-
else logger.out(`(Run "simplify" to write changes, or "pnpm cli:arrange-simplify" / "pnpm exec codefast arrange simplify")`);
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* @since 0.3.16-canary.0
|
|
47
|
-
*/
|
|
48
|
-
function printGroupFilePreviewFromWork(work) {
|
|
49
|
-
printGroupFilePreviewBody({
|
|
50
|
-
filePath: work.filePath,
|
|
51
|
-
reportTotal: work.reportTotal,
|
|
52
|
-
cnInTvNoReplacement: work.cnInTvNoReplacement,
|
|
53
|
-
cnInTvCalls: work.cnInTvCalls,
|
|
54
|
-
unwrapReplacementByCall: work.unwrapReplacementByCall,
|
|
55
|
-
sourceText: work.sourceText,
|
|
56
|
-
domainSf: work.domainSfForLineNumbers,
|
|
57
|
-
unwrapEdits: work.unwrapEdits,
|
|
58
|
-
plannedGroupEdits: work.plannedGroupEdits
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
function printGroupFilePreviewBody(args) {
|
|
62
|
-
const { filePath, reportTotal, cnInTvNoReplacement, cnInTvCalls, unwrapReplacementByCall, sourceText, domainSf, unwrapEdits, plannedGroupEdits } = args;
|
|
63
|
-
let header = `\n── ${filePath} (${reportTotal} site(s)`;
|
|
64
|
-
if (cnInTvNoReplacement > 0) header += `; plus ${cnInTvNoReplacement} cn() inside tv left unchanged (0 args)`;
|
|
65
|
-
header += `) ──`;
|
|
66
|
-
logger.out(header);
|
|
67
|
-
for (const call of cnInTvCalls) {
|
|
68
|
-
const replacement = unwrapReplacementByCall.get(call);
|
|
69
|
-
if (replacement === void 0) {
|
|
70
|
-
logger.out(` Line ${lineOf(domainSf, call)} [tv ⊃ cn]: cn(...) has no arguments — skipped`);
|
|
71
|
-
continue;
|
|
72
|
-
}
|
|
73
|
-
const start = call.pos;
|
|
74
|
-
const end = call.end;
|
|
75
|
-
if (sourceText.slice(start, end) === replacement) continue;
|
|
76
|
-
logger.out(` Line ${lineOf(domainSf, call)} [tv ⊃ cn → string/array]:`);
|
|
77
|
-
logger.out(` ${replacement.split("\n").join("\n ")}`);
|
|
78
|
-
}
|
|
79
|
-
if (unwrapEdits.length > 0 && plannedGroupEdits.length > 0) logger.out(" ([cn] / [tv] / [JSX className] lines below reflect content after unwrap of cn inside tv.)");
|
|
80
|
-
for (const plan of plannedGroupEdits) {
|
|
81
|
-
logger.out(` Line ${lineOf(plan.lineSf, plan.reportNode)} [${plan.label}]:`);
|
|
82
|
-
logger.out(` ${plan.replacement.split("\n").join("\n ")}`);
|
|
83
|
-
logger.out(` // Buckets: ${JSON.stringify(plan.bucketSummary)}`);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
//#endregion
|
|
87
|
-
export { printAnalyzeReport, printGroupFilePreviewFromWork, printSimplifyResult, printSyncResult };
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import { parseDomainSourceFile } from "./source-parse.mjs";
|
|
2
|
-
import { ensureCnImport } from "./domain/imports.mjs";
|
|
3
|
-
import { buildGroupFileUnwrapState, countPersistedGroupFileEdits, groupFileDryRunNoEdits, groupFileEditsTouchJsxCn, groupFilePreviewTotals, groupFileWorkHasNothingToReport, mergeGroupFileBodyText, tryBuildGroupFileWorkPlan } from "./domain/grouping-service.mjs";
|
|
4
|
-
//#region src/arrange/process-file.ts
|
|
5
|
-
/**
|
|
6
|
-
* @since 0.3.16-canary.0
|
|
7
|
-
*/
|
|
8
|
-
function processArrangeGroupFile(fs, args) {
|
|
9
|
-
const { filePath, options } = args;
|
|
10
|
-
const sourceText = fs.readFileSync(filePath, "utf8");
|
|
11
|
-
const domainSfInitial = parseDomainSourceFile(filePath, sourceText);
|
|
12
|
-
const unwrap = buildGroupFileUnwrapState(domainSfInitial, sourceText);
|
|
13
|
-
const work = tryBuildGroupFileWorkPlan({
|
|
14
|
-
filePath,
|
|
15
|
-
sourceText,
|
|
16
|
-
domainSfInitial,
|
|
17
|
-
domainSfGrouped: parseDomainSourceFile(filePath, unwrap.textAfterUnwrap),
|
|
18
|
-
withClassName: options.withClassName,
|
|
19
|
-
unwrap
|
|
20
|
-
});
|
|
21
|
-
if (work === null) return groupFileDryRunNoEdits(filePath);
|
|
22
|
-
if (!options.write) {
|
|
23
|
-
if (groupFileWorkHasNothingToReport(work)) return groupFileDryRunNoEdits(filePath);
|
|
24
|
-
return {
|
|
25
|
-
...groupFilePreviewTotals(work),
|
|
26
|
-
workPlan: work
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
const persistedEditCount = countPersistedGroupFileEdits(work);
|
|
30
|
-
let newText = mergeGroupFileBodyText(work);
|
|
31
|
-
if (persistedEditCount > 0) {
|
|
32
|
-
if (groupFileEditsTouchJsxCn(work)) newText = ensureCnImport(parseDomainSourceFile(filePath, newText), options.cnImport);
|
|
33
|
-
fs.writeFileSync(filePath, newText, "utf8");
|
|
34
|
-
}
|
|
35
|
-
return {
|
|
36
|
-
filePath,
|
|
37
|
-
totalFound: persistedEditCount + work.cnInTvNoReplacement,
|
|
38
|
-
changed: persistedEditCount
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
//#endregion
|
|
42
|
-
export { processArrangeGroupFile };
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
|
-
//#region src/arrange/resolve-target.ts
|
|
3
|
-
const packageJsonFileName = "package.json";
|
|
4
|
-
/**
|
|
5
|
-
* @since 0.3.16-canary.0
|
|
6
|
-
*/
|
|
7
|
-
function resolveArrangeTargetPath(fs, args) {
|
|
8
|
-
const explicitTargetPath = args.rawTarget ? path.isAbsolute(args.rawTarget) ? path.resolve(args.rawTarget) : path.resolve(args.currentWorkingDirectory, args.rawTarget) : void 0;
|
|
9
|
-
if (explicitTargetPath) return fs.canonicalPathSync(explicitTargetPath);
|
|
10
|
-
const resolvedDefaultTarget = findNearestPackageDirectory(fs, args.currentWorkingDirectory) ?? args.currentWorkingDirectory;
|
|
11
|
-
return fs.canonicalPathSync(resolvedDefaultTarget);
|
|
12
|
-
}
|
|
13
|
-
function findNearestPackageDirectory(fs, currentWorkingDirectory) {
|
|
14
|
-
let currentDir = path.resolve(currentWorkingDirectory);
|
|
15
|
-
while (true) {
|
|
16
|
-
const packageJsonPath = path.join(currentDir, packageJsonFileName);
|
|
17
|
-
if (fs.existsSync(packageJsonPath)) return currentDir;
|
|
18
|
-
const parentDirectory = path.dirname(currentDir);
|
|
19
|
-
if (parentDirectory === currentDir) return;
|
|
20
|
-
currentDir = parentDirectory;
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
//#endregion
|
|
24
|
-
export { resolveArrangeTargetPath };
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { messageFrom } from "../core/errors.mjs";
|
|
2
|
-
import { logger } from "../core/logger.mjs";
|
|
3
|
-
import { walkTsxFiles } from "../core/workspace/typescript-walk.mjs";
|
|
4
|
-
import path from "node:path";
|
|
5
|
-
//#region src/arrange/scan-target.ts
|
|
6
|
-
const TEST_FILE_PATTERN = /\.(?:test|spec)\.[cm]?[jt]sx?$/;
|
|
7
|
-
/**
|
|
8
|
-
* Test/spec files are excluded from directory scans: arrange rewrites class strings,
|
|
9
|
-
* and a `cn(...)` inside an assertion (e.g. `expect(cn("a", "b"))`) is intentional test
|
|
10
|
-
* data, not styling to reformat. An explicit single-file target is still honored.
|
|
11
|
-
*/
|
|
12
|
-
function isTestFile(filePath) {
|
|
13
|
-
return TEST_FILE_PATTERN.test(path.basename(filePath));
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* @since 0.3.16-canary.0
|
|
17
|
-
*/
|
|
18
|
-
function scanArrangeTargets(fs, targetPath) {
|
|
19
|
-
const resolvedTargetPath = path.resolve(targetPath);
|
|
20
|
-
if (fs.statSync(resolvedTargetPath).isDirectory()) try {
|
|
21
|
-
return walkTsxFiles(resolvedTargetPath, fs).filter((filePath) => !isTestFile(filePath));
|
|
22
|
-
} catch (caughtError) {
|
|
23
|
-
logger.err(`[file-walker] ${messageFrom(caughtError)}`);
|
|
24
|
-
throw caughtError;
|
|
25
|
-
}
|
|
26
|
-
return [resolvedTargetPath];
|
|
27
|
-
}
|
|
28
|
-
//#endregion
|
|
29
|
-
export { scanArrangeTargets };
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { applyEditsDescending } from "../core/source-text-edit.mjs";
|
|
2
|
-
import { parseDomainSourceFile } from "./source-parse.mjs";
|
|
3
|
-
import { collectSimplifyTargets } from "./domain/ast/simplify-targets.mjs";
|
|
4
|
-
import { dropCnImportIfUnused } from "./domain/imports.mjs";
|
|
5
|
-
//#region src/arrange/simplify-process-file.ts
|
|
6
|
-
/**
|
|
7
|
-
* @since 0.3.16-canary.0
|
|
8
|
-
*/
|
|
9
|
-
function processArrangeSimplifyFile(fs, args) {
|
|
10
|
-
const { filePath, write } = args;
|
|
11
|
-
const sourceText = fs.readFileSync(filePath, "utf8");
|
|
12
|
-
const meaningful = collectSimplifyTargets(parseDomainSourceFile(filePath, sourceText)).filter((edit) => sourceText.slice(edit.start, edit.end) !== edit.replacement);
|
|
13
|
-
const textAfterEdits = meaningful.length > 0 ? applyEditsDescending(sourceText, meaningful) : sourceText;
|
|
14
|
-
const textAfterImportDrop = dropCnImportIfUnused(parseDomainSourceFile(filePath, textAfterEdits));
|
|
15
|
-
const importDropped = textAfterImportDrop !== textAfterEdits;
|
|
16
|
-
const totalFound = meaningful.length + (importDropped ? 1 : 0);
|
|
17
|
-
if (totalFound === 0) return {
|
|
18
|
-
filePath,
|
|
19
|
-
totalFound: 0,
|
|
20
|
-
changed: 0
|
|
21
|
-
};
|
|
22
|
-
if (!write) return {
|
|
23
|
-
filePath,
|
|
24
|
-
totalFound,
|
|
25
|
-
changed: 0
|
|
26
|
-
};
|
|
27
|
-
fs.writeFileSync(filePath, textAfterImportDrop, "utf8");
|
|
28
|
-
return {
|
|
29
|
-
filePath,
|
|
30
|
-
totalFound,
|
|
31
|
-
changed: totalFound
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
//#endregion
|
|
35
|
-
export { processArrangeSimplifyFile };
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { scanArrangeTargets } from "./scan-target.mjs";
|
|
2
|
-
import { ok } from "../core/result.mjs";
|
|
3
|
-
import { processArrangeSimplifyFile } from "./simplify-process-file.mjs";
|
|
4
|
-
//#region src/arrange/simplify-sync.ts
|
|
5
|
-
/**
|
|
6
|
-
* @since 0.3.16-canary.0
|
|
7
|
-
*/
|
|
8
|
-
async function runArrangeSimplify(fs, args) {
|
|
9
|
-
const filePaths = scanArrangeTargets(fs, args.targetPath);
|
|
10
|
-
const modifiedFiles = [];
|
|
11
|
-
let totalFound = 0;
|
|
12
|
-
let totalChanged = 0;
|
|
13
|
-
for (const filePath of filePaths) {
|
|
14
|
-
const result = processArrangeSimplifyFile(fs, {
|
|
15
|
-
filePath,
|
|
16
|
-
write: args.write
|
|
17
|
-
});
|
|
18
|
-
totalFound += result.totalFound;
|
|
19
|
-
totalChanged += result.changed;
|
|
20
|
-
if (result.changed > 0) modifiedFiles.push(result.filePath);
|
|
21
|
-
}
|
|
22
|
-
return ok({
|
|
23
|
-
filePaths,
|
|
24
|
-
modifiedFiles,
|
|
25
|
-
totalFound,
|
|
26
|
-
totalChanged,
|
|
27
|
-
hookError: null,
|
|
28
|
-
previewPlans: []
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
//#endregion
|
|
32
|
-
export { runArrangeSimplify };
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { messageFrom } from "../core/errors.mjs";
|
|
2
|
-
import { logger } from "../core/logger.mjs";
|
|
3
|
-
import { TypeScriptAstTranslator } from "./typescript-ast-translator.mjs";
|
|
4
|
-
//#region src/arrange/source-parse.ts
|
|
5
|
-
const translator = new TypeScriptAstTranslator();
|
|
6
|
-
/**
|
|
7
|
-
* @since 0.3.16-canary.0
|
|
8
|
-
*/
|
|
9
|
-
function parseDomainSourceFile(filePath, sourceText) {
|
|
10
|
-
try {
|
|
11
|
-
return translator.translateSourceFile(filePath, sourceText);
|
|
12
|
-
} catch (caughtError) {
|
|
13
|
-
logger.err(`[domain-source-parser] ${messageFrom(caughtError)}`);
|
|
14
|
-
throw caughtError;
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
//#endregion
|
|
18
|
-
export { parseDomainSourceFile };
|
package/dist/arrange/suggest.mjs
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { formatArray, formatCnCall } from "./domain/source-text-formatters.mjs";
|
|
2
|
-
import { suggestCnGroups, summarizeGroupBucketLabels } from "./domain/grouping.mjs";
|
|
3
|
-
//#region src/arrange/suggest.ts
|
|
4
|
-
/**
|
|
5
|
-
* @since 0.3.16-canary.0
|
|
6
|
-
*/
|
|
7
|
-
function suggestCnGroupsFromCli(request) {
|
|
8
|
-
const groups = suggestCnGroups(request.inlineClasses);
|
|
9
|
-
return {
|
|
10
|
-
primaryLine: request.emitTvStyleArray ? formatArray(groups) : formatCnCall(groups, { trailingClassName: request.trailingClassName }),
|
|
11
|
-
bucketsCommentLine: `// Buckets: ${JSON.stringify(summarizeGroupBucketLabels(groups))}`
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
|
-
//#endregion
|
|
15
|
-
export { suggestCnGroupsFromCli };
|
package/dist/arrange/sync.mjs
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { messageFrom } from "../core/errors.mjs";
|
|
2
|
-
import { scanArrangeTargets } from "./scan-target.mjs";
|
|
3
|
-
import { ok } from "../core/result.mjs";
|
|
4
|
-
import { processArrangeGroupFile } from "./process-file.mjs";
|
|
5
|
-
//#region src/arrange/sync.ts
|
|
6
|
-
async function runOnAfterWriteHook(hook, modifiedFiles) {
|
|
7
|
-
if (!hook || modifiedFiles.length === 0) return null;
|
|
8
|
-
try {
|
|
9
|
-
await hook({ files: modifiedFiles });
|
|
10
|
-
return null;
|
|
11
|
-
} catch (caughtHookError) {
|
|
12
|
-
return `[arrange] onAfterWrite hook failed: ${messageFrom(caughtHookError)}`;
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* @since 0.3.16-canary.0
|
|
17
|
-
*/
|
|
18
|
-
async function runArrangeSync(fs, request) {
|
|
19
|
-
const filePaths = scanArrangeTargets(fs, request.targetPath);
|
|
20
|
-
const modifiedFiles = [];
|
|
21
|
-
const previewPlans = [];
|
|
22
|
-
let totalFound = 0;
|
|
23
|
-
let totalChanged = 0;
|
|
24
|
-
const groupOptions = {
|
|
25
|
-
write: request.write,
|
|
26
|
-
withClassName: !!request.withClassName,
|
|
27
|
-
cnImport: request.cnImport
|
|
28
|
-
};
|
|
29
|
-
for (const filePath of filePaths) {
|
|
30
|
-
const fileProcessResult = processArrangeGroupFile(fs, {
|
|
31
|
-
filePath,
|
|
32
|
-
options: groupOptions
|
|
33
|
-
});
|
|
34
|
-
totalFound += fileProcessResult.totalFound;
|
|
35
|
-
totalChanged += fileProcessResult.changed;
|
|
36
|
-
if (fileProcessResult.changed > 0) modifiedFiles.push(fileProcessResult.filePath);
|
|
37
|
-
if (fileProcessResult.workPlan) previewPlans.push(fileProcessResult.workPlan);
|
|
38
|
-
}
|
|
39
|
-
const arrangeConfig = request.config;
|
|
40
|
-
const hookError = request.write && modifiedFiles.length > 0 ? await runOnAfterWriteHook(arrangeConfig?.onAfterWrite, modifiedFiles) : null;
|
|
41
|
-
return ok({
|
|
42
|
-
filePaths,
|
|
43
|
-
modifiedFiles,
|
|
44
|
-
totalFound,
|
|
45
|
-
totalChanged,
|
|
46
|
-
hookError,
|
|
47
|
-
previewPlans
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
//#endregion
|
|
51
|
-
export { runArrangeSync };
|