@codefast/cli 0.5.0-canary.5 → 1.0.0-canary.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (274) hide show
  1. package/README.md +106 -480
  2. package/dist/arrange/analyze.js +25 -0
  3. package/dist/arrange/analyze.js.map +1 -0
  4. package/dist/arrange/cli-schema.js +29 -0
  5. package/dist/arrange/cli-schema.js.map +1 -0
  6. package/dist/arrange/command.js +170 -0
  7. package/dist/arrange/command.js.map +1 -0
  8. package/dist/arrange/domain/analyze-service.js +122 -0
  9. package/dist/arrange/domain/analyze-service.js.map +1 -0
  10. package/dist/arrange/domain/ast/ast-node.js +240 -0
  11. package/dist/arrange/domain/ast/ast-node.js.map +1 -0
  12. package/dist/arrange/domain/ast/collectors-cn.js +81 -0
  13. package/dist/arrange/domain/ast/collectors-cn.js.map +1 -0
  14. package/dist/arrange/domain/ast/collectors-jsx.js +24 -0
  15. package/dist/arrange/domain/ast/collectors-jsx.js.map +1 -0
  16. package/dist/arrange/domain/ast/collectors-tv.js +319 -0
  17. package/dist/arrange/domain/ast/collectors-tv.js.map +1 -0
  18. package/dist/arrange/domain/ast/helpers.js +151 -0
  19. package/dist/arrange/domain/ast/helpers.js.map +1 -0
  20. package/dist/arrange/domain/ast/simplify-targets.js +161 -0
  21. package/dist/arrange/domain/ast/simplify-targets.js.map +1 -0
  22. package/dist/arrange/domain/ast/targets.js +182 -0
  23. package/dist/arrange/domain/ast/targets.js.map +1 -0
  24. package/dist/arrange/domain/constants.js +225 -0
  25. package/dist/arrange/domain/constants.js.map +1 -0
  26. package/dist/arrange/domain/grouping-service.js +128 -0
  27. package/dist/arrange/domain/grouping-service.js.map +1 -0
  28. package/dist/arrange/domain/grouping.js +435 -0
  29. package/dist/arrange/domain/grouping.js.map +1 -0
  30. package/dist/arrange/domain/imports.js +160 -0
  31. package/dist/arrange/domain/imports.js.map +1 -0
  32. package/dist/arrange/domain/source-text-formatters.js +100 -0
  33. package/dist/arrange/domain/source-text-formatters.js.map +1 -0
  34. package/dist/arrange/domain/tailwind-token.js +50 -0
  35. package/dist/arrange/domain/tailwind-token.js.map +1 -0
  36. package/dist/arrange/domain/token-classifier.js +448 -0
  37. package/dist/arrange/domain/token-classifier.js.map +1 -0
  38. package/dist/arrange/domain/types.js +11 -0
  39. package/dist/arrange/domain/types.js.map +1 -0
  40. package/dist/arrange/output.js +120 -0
  41. package/dist/arrange/output.js.map +1 -0
  42. package/dist/arrange/process-file.js +44 -0
  43. package/dist/arrange/process-file.js.map +1 -0
  44. package/dist/arrange/resolve-target.js +33 -0
  45. package/dist/arrange/resolve-target.js.map +1 -0
  46. package/dist/arrange/scan-target.js +30 -0
  47. package/dist/arrange/scan-target.js.map +1 -0
  48. package/dist/arrange/simplify-process-file.js +29 -0
  49. package/dist/arrange/simplify-process-file.js.map +1 -0
  50. package/dist/arrange/simplify-sync.js +29 -0
  51. package/dist/arrange/simplify-sync.js.map +1 -0
  52. package/dist/arrange/source-parse.js +17 -0
  53. package/dist/arrange/source-parse.js.map +1 -0
  54. package/dist/arrange/suggest.js +14 -0
  55. package/dist/arrange/suggest.js.map +1 -0
  56. package/dist/arrange/sync.js +48 -0
  57. package/dist/arrange/sync.js.map +1 -0
  58. package/dist/arrange/typescript-ast-translator.js +455 -0
  59. package/dist/arrange/typescript-ast-translator.js.map +1 -0
  60. package/dist/arrange/workspace.js +31 -0
  61. package/dist/arrange/workspace.js.map +1 -0
  62. package/dist/audit/cli-schema.js +22 -0
  63. package/dist/audit/cli-schema.js.map +1 -0
  64. package/dist/audit/command.js +60 -0
  65. package/dist/audit/command.js.map +1 -0
  66. package/dist/audit/domain/audit-file.js +101 -0
  67. package/dist/audit/domain/audit-file.js.map +1 -0
  68. package/dist/audit/domain/mappings.js +103 -0
  69. package/dist/audit/domain/mappings.js.map +1 -0
  70. package/dist/audit/domain/tokenize.js +83 -0
  71. package/dist/audit/domain/tokenize.js.map +1 -0
  72. package/dist/audit/domain/types.js +2 -0
  73. package/dist/audit/domain/types.js.map +1 -0
  74. package/dist/audit/output.js +44 -0
  75. package/dist/audit/output.js.map +1 -0
  76. package/dist/audit/prepare.js +42 -0
  77. package/dist/audit/prepare.js.map +1 -0
  78. package/dist/audit/run.js +57 -0
  79. package/dist/audit/run.js.map +1 -0
  80. package/dist/{bin.mjs → bin.js} +2 -4
  81. package/dist/bin.js.map +1 -0
  82. package/dist/cli.js +45 -0
  83. package/dist/cli.js.map +1 -0
  84. package/dist/core/cli/format-error.js +19 -0
  85. package/dist/core/cli/format-error.js.map +1 -0
  86. package/dist/core/cli/global-options.js +10 -0
  87. package/dist/core/cli/global-options.js.map +1 -0
  88. package/dist/core/cli/positional.js +9 -0
  89. package/dist/core/cli/positional.js.map +1 -0
  90. package/dist/core/cli/result-handle.js +69 -0
  91. package/dist/core/cli/result-handle.js.map +1 -0
  92. package/dist/core/config/loader.js +88 -0
  93. package/dist/core/config/loader.js.map +1 -0
  94. package/dist/core/config/schema.js +97 -0
  95. package/dist/core/config/schema.js.map +1 -0
  96. package/dist/core/config/warnings.js +12 -0
  97. package/dist/core/config/warnings.js.map +1 -0
  98. package/dist/core/config.js +18 -0
  99. package/dist/core/config.js.map +1 -0
  100. package/dist/core/errors.js +58 -0
  101. package/dist/core/errors.js.map +1 -0
  102. package/dist/core/exit-codes.js +15 -0
  103. package/dist/core/exit-codes.js.map +1 -0
  104. package/dist/core/filesystem/node.js +33 -0
  105. package/dist/core/filesystem/node.js.map +1 -0
  106. package/dist/core/filesystem/port.js +2 -0
  107. package/dist/core/filesystem/port.js.map +1 -0
  108. package/dist/core/glob.js +20 -0
  109. package/dist/core/glob.js.map +1 -0
  110. package/dist/core/logger.js +13 -0
  111. package/dist/core/logger.js.map +1 -0
  112. package/dist/core/result.js +16 -0
  113. package/dist/core/result.js.map +1 -0
  114. package/dist/core/schema-parse.js +21 -0
  115. package/dist/core/schema-parse.js.map +1 -0
  116. package/dist/core/source-text-edit.js +62 -0
  117. package/dist/core/source-text-edit.js.map +1 -0
  118. package/dist/core/verbose-diagnostics.js +9 -0
  119. package/dist/core/verbose-diagnostics.js.map +1 -0
  120. package/dist/core/workspace/resolver.js +208 -0
  121. package/dist/core/workspace/resolver.js.map +1 -0
  122. package/dist/core/workspace/typescript-walk.js +41 -0
  123. package/dist/core/workspace/typescript-walk.js.map +1 -0
  124. package/dist/mirror/cli-result.js +20 -0
  125. package/dist/mirror/cli-result.js.map +1 -0
  126. package/dist/mirror/cli-schema.js +11 -0
  127. package/dist/mirror/cli-schema.js.map +1 -0
  128. package/dist/mirror/command.js +73 -0
  129. package/dist/mirror/command.js.map +1 -0
  130. package/dist/mirror/dist-filesystem-impl.js +53 -0
  131. package/dist/mirror/dist-filesystem-impl.js.map +1 -0
  132. package/dist/mirror/domain/constants.js +21 -0
  133. package/dist/mirror/domain/constants.js.map +1 -0
  134. package/dist/mirror/domain/dirent-guard.js +16 -0
  135. package/dist/mirror/domain/dirent-guard.js.map +1 -0
  136. package/dist/mirror/domain/dist-filesystem.js +2 -0
  137. package/dist/mirror/domain/dist-filesystem.js.map +1 -0
  138. package/dist/mirror/domain/errors.js +19 -0
  139. package/dist/mirror/domain/errors.js.map +1 -0
  140. package/dist/mirror/domain/exports.js +284 -0
  141. package/dist/mirror/domain/exports.js.map +1 -0
  142. package/dist/mirror/domain/package-display-name.js +10 -0
  143. package/dist/mirror/domain/package-display-name.js.map +1 -0
  144. package/dist/mirror/domain/path-normalizer.js +8 -0
  145. package/dist/mirror/domain/path-normalizer.js.map +1 -0
  146. package/dist/mirror/domain/types.js +2 -0
  147. package/dist/mirror/domain/types.js.map +1 -0
  148. package/dist/mirror/output.js +47 -0
  149. package/dist/mirror/output.js.map +1 -0
  150. package/dist/mirror/package-path.js +40 -0
  151. package/dist/mirror/package-path.js.map +1 -0
  152. package/dist/mirror/prepare.js +37 -0
  153. package/dist/mirror/prepare.js.map +1 -0
  154. package/dist/mirror/supplement-exports.js +157 -0
  155. package/dist/mirror/supplement-exports.js.map +1 -0
  156. package/dist/mirror/sync-reporter.js +125 -0
  157. package/dist/mirror/sync-reporter.js.map +1 -0
  158. package/dist/mirror/sync-types.js +2 -0
  159. package/dist/mirror/sync-types.js.map +1 -0
  160. package/dist/mirror/sync-workspace-package.js +117 -0
  161. package/dist/mirror/sync-workspace-package.js.map +1 -0
  162. package/dist/mirror/sync.js +90 -0
  163. package/dist/mirror/sync.js.map +1 -0
  164. package/dist/mirror/write-exports.js +145 -0
  165. package/dist/mirror/write-exports.js.map +1 -0
  166. package/dist/tag/cli-result.js +12 -0
  167. package/dist/tag/cli-result.js.map +1 -0
  168. package/dist/tag/cli-schema.js +13 -0
  169. package/dist/tag/cli-schema.js.map +1 -0
  170. package/dist/tag/command.js +69 -0
  171. package/dist/tag/command.js.map +1 -0
  172. package/dist/tag/domain/types.js +2 -0
  173. package/dist/tag/domain/types.js.map +1 -0
  174. package/dist/tag/output.js +101 -0
  175. package/dist/tag/output.js.map +1 -0
  176. package/dist/tag/prepare.js +30 -0
  177. package/dist/tag/prepare.js.map +1 -0
  178. package/dist/tag/resolve-target-path.js +14 -0
  179. package/dist/tag/resolve-target-path.js.map +1 -0
  180. package/dist/tag/since-writer.js +231 -0
  181. package/dist/tag/since-writer.js.map +1 -0
  182. package/dist/tag/sync.js +166 -0
  183. package/dist/tag/sync.js.map +1 -0
  184. package/dist/tag/target-candidates.js +79 -0
  185. package/dist/tag/target-candidates.js.map +1 -0
  186. package/dist/tag/target-runner.js +25 -0
  187. package/dist/tag/target-runner.js.map +1 -0
  188. package/dist/tag/version-resolver.js +28 -0
  189. package/dist/tag/version-resolver.js.map +1 -0
  190. package/package.json +27 -21
  191. package/dist/arrange/analyze.mjs +0 -24
  192. package/dist/arrange/cli-schema.mjs +0 -27
  193. package/dist/arrange/command.mjs +0 -130
  194. package/dist/arrange/domain/analyze-service.mjs +0 -102
  195. package/dist/arrange/domain/ast/ast-node.mjs +0 -215
  196. package/dist/arrange/domain/ast/collectors-cn.mjs +0 -64
  197. package/dist/arrange/domain/ast/collectors-jsx.mjs +0 -23
  198. package/dist/arrange/domain/ast/collectors-tv.mjs +0 -189
  199. package/dist/arrange/domain/ast/helpers.mjs +0 -108
  200. package/dist/arrange/domain/ast/simplify-targets.mjs +0 -109
  201. package/dist/arrange/domain/ast/targets.mjs +0 -134
  202. package/dist/arrange/domain/constants.mjs +0 -213
  203. package/dist/arrange/domain/grouping-service.mjs +0 -121
  204. package/dist/arrange/domain/grouping.mjs +0 -338
  205. package/dist/arrange/domain/imports.mjs +0 -107
  206. package/dist/arrange/domain/source-text-formatters.mjs +0 -88
  207. package/dist/arrange/domain/tailwind-token.mjs +0 -40
  208. package/dist/arrange/domain/token-classifier.mjs +0 -218
  209. package/dist/arrange/domain/types.mjs +0 -1
  210. package/dist/arrange/output.mjs +0 -87
  211. package/dist/arrange/process-file.mjs +0 -42
  212. package/dist/arrange/resolve-target.mjs +0 -24
  213. package/dist/arrange/scan-target.mjs +0 -29
  214. package/dist/arrange/simplify-process-file.mjs +0 -35
  215. package/dist/arrange/simplify-sync.mjs +0 -32
  216. package/dist/arrange/source-parse.mjs +0 -18
  217. package/dist/arrange/suggest.mjs +0 -15
  218. package/dist/arrange/sync.mjs +0 -51
  219. package/dist/arrange/typescript-ast-translator.mjs +0 -354
  220. package/dist/arrange/workspace.mjs +0 -31
  221. package/dist/cli.mjs +0 -34
  222. package/dist/core/cli/format-error.mjs +0 -15
  223. package/dist/core/cli/global-options.mjs +0 -10
  224. package/dist/core/cli/positional.mjs +0 -11
  225. package/dist/core/cli/result-handle.mjs +0 -51
  226. package/dist/core/config/loader.mjs +0 -79
  227. package/dist/core/config/schema.mjs +0 -60
  228. package/dist/core/config/warnings.mjs +0 -12
  229. package/dist/core/config.mjs +0 -19
  230. package/dist/core/errors.mjs +0 -35
  231. package/dist/core/exit-codes.mjs +0 -17
  232. package/dist/core/filesystem/node.mjs +0 -32
  233. package/dist/core/filesystem/port.mjs +0 -1
  234. package/dist/core/glob.mjs +0 -20
  235. package/dist/core/logger.mjs +0 -15
  236. package/dist/core/result.mjs +0 -21
  237. package/dist/core/schema-parse.mjs +0 -18
  238. package/dist/core/source-text-edit.mjs +0 -56
  239. package/dist/core/verbose-diagnostics.mjs +0 -11
  240. package/dist/core/workspace/resolver.mjs +0 -177
  241. package/dist/core/workspace/typescript-walk.mjs +0 -36
  242. package/dist/mirror/cli-result.mjs +0 -22
  243. package/dist/mirror/cli-schema.mjs +0 -13
  244. package/dist/mirror/command.mjs +0 -58
  245. package/dist/mirror/dist-filesystem-impl.mjs +0 -42
  246. package/dist/mirror/domain/constants.mjs +0 -31
  247. package/dist/mirror/domain/dirent-guard.mjs +0 -16
  248. package/dist/mirror/domain/dist-filesystem.mjs +0 -1
  249. package/dist/mirror/domain/errors.mjs +0 -21
  250. package/dist/mirror/domain/exports.mjs +0 -226
  251. package/dist/mirror/domain/package-display-name.mjs +0 -12
  252. package/dist/mirror/domain/path-normalizer.mjs +0 -10
  253. package/dist/mirror/domain/types.mjs +0 -1
  254. package/dist/mirror/output.mjs +0 -48
  255. package/dist/mirror/package-path.mjs +0 -32
  256. package/dist/mirror/prepare.mjs +0 -33
  257. package/dist/mirror/supplement-exports.mjs +0 -114
  258. package/dist/mirror/sync-reporter.mjs +0 -107
  259. package/dist/mirror/sync-types.mjs +0 -1
  260. package/dist/mirror/sync-workspace-package.mjs +0 -109
  261. package/dist/mirror/sync.mjs +0 -88
  262. package/dist/mirror/write-exports.mjs +0 -94
  263. package/dist/tag/cli-result.mjs +0 -11
  264. package/dist/tag/cli-schema.mjs +0 -15
  265. package/dist/tag/command.mjs +0 -56
  266. package/dist/tag/domain/types.mjs +0 -1
  267. package/dist/tag/output.mjs +0 -87
  268. package/dist/tag/prepare.mjs +0 -29
  269. package/dist/tag/resolve-target-path.mjs +0 -12
  270. package/dist/tag/since-writer.mjs +0 -131
  271. package/dist/tag/sync.mjs +0 -149
  272. package/dist/tag/target-candidates.mjs +0 -68
  273. package/dist/tag/target-runner.mjs +0 -26
  274. 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 {};
@@ -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 };
@@ -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 };
@@ -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 };