@codefast/cli 0.3.12 → 0.3.13-canary.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (225) hide show
  1. package/README.md +206 -51
  2. package/dist/analyze-DvtJ3j9m.mjs +92 -0
  3. package/dist/arrange-Bbh62DrU.mjs +107 -0
  4. package/dist/arrange-BqP2DI3w.mjs +8 -0
  5. package/dist/ast-helpers-MDRYuIAk.mjs +115 -0
  6. package/dist/{bin.js → bin.mjs} +4 -1
  7. package/dist/caught-unknown-message-CRhkDWO7.mjs +20 -0
  8. package/dist/collectors-cn-BS8TTQ8O.mjs +61 -0
  9. package/dist/collectors-jsx-D9tL2ZPM.mjs +20 -0
  10. package/dist/collectors-tv-D2PXZaRt.mjs +170 -0
  11. package/dist/colors-BjdkCfGK.mjs +12 -0
  12. package/dist/commands/arrange.mjs +2 -0
  13. package/dist/commands/mirror.mjs +2 -0
  14. package/dist/commands/mirror.test.mjs +48 -0
  15. package/dist/commands/tag.mjs +2 -0
  16. package/dist/config-DVia_f9a.mjs +3 -0
  17. package/dist/config-reporter-SCcWDZc1.mjs +10 -0
  18. package/dist/constants-AtPhF-Ct.mjs +169 -0
  19. package/dist/constants-Bq5wdyLC.mjs +8 -0
  20. package/dist/dirent-list-BSDeRG5i.mjs +14 -0
  21. package/dist/engine-CcWEHSCq.mjs +287 -0
  22. package/dist/engine-DRTdkc5u.mjs +236 -0
  23. package/dist/errors-CFH4w6ic.mjs +15 -0
  24. package/dist/errors-CpU1ogfA.mjs +19 -0
  25. package/dist/formatters-DGE8jJ53.mjs +52 -0
  26. package/dist/group-file-ClW7XdD6.mjs +113 -0
  27. package/dist/grouping-c1grpCQT.mjs +235 -0
  28. package/dist/imports-DSVq1xhB.mjs +54 -0
  29. package/dist/lib/arrange/application/analyze.mjs +2 -0
  30. package/dist/lib/arrange/application/analyze.test.mjs +171 -0
  31. package/dist/lib/arrange/application/group-file.mjs +2 -0
  32. package/dist/lib/arrange/application/group-file.test.mjs +273 -0
  33. package/dist/lib/arrange/application/run-target.mjs +2 -0
  34. package/dist/lib/arrange/application/run-target.test.mjs +97 -0
  35. package/dist/lib/arrange/domain/ast/ast-helpers.mjs +2 -0
  36. package/dist/lib/arrange/domain/ast/ast-helpers.test.mjs +148 -0
  37. package/dist/lib/arrange/domain/ast/collectors-cn.mjs +2 -0
  38. package/dist/lib/arrange/domain/ast/collectors-cn.test.mjs +58 -0
  39. package/dist/lib/arrange/domain/ast/collectors-jsx.mjs +2 -0
  40. package/dist/lib/arrange/domain/ast/collectors-jsx.test.mjs +20 -0
  41. package/dist/lib/arrange/domain/ast/collectors-tv.mjs +2 -0
  42. package/dist/lib/arrange/domain/ast/collectors-tv.test.mjs +145 -0
  43. package/dist/lib/arrange/domain/ast/targets.mjs +2 -0
  44. package/dist/lib/arrange/domain/ast/targets.test.mjs +50 -0
  45. package/dist/lib/arrange/domain/constants.mjs +2 -0
  46. package/dist/lib/arrange/domain/errors.mjs +2 -0
  47. package/dist/lib/arrange/domain/grouping.mjs +2 -0
  48. package/dist/lib/arrange/domain/grouping.test.mjs +186 -0
  49. package/dist/lib/arrange/domain/imports.mjs +2 -0
  50. package/dist/lib/arrange/domain/imports.test.mjs +48 -0
  51. package/dist/lib/arrange/domain/tokenizer.mjs +2 -0
  52. package/dist/lib/arrange/domain/tokenizer.test.mjs +165 -0
  53. package/dist/lib/arrange/index.mjs +16 -0
  54. package/dist/lib/arrange/infra/walk.mjs +2 -0
  55. package/dist/lib/arrange/infra/walk.test.mjs +50 -0
  56. package/dist/lib/arrange/presentation/formatters.mjs +2 -0
  57. package/dist/lib/arrange/presentation/formatters.test.mjs +73 -0
  58. package/dist/lib/arrange/presentation/report.mjs +2 -0
  59. package/dist/lib/config/domain/schema.mjs +2 -0
  60. package/dist/lib/config/index.mjs +4 -0
  61. package/dist/lib/config/infra/loader.mjs +2 -0
  62. package/dist/lib/config/infra/loader.test.mjs +116 -0
  63. package/dist/lib/infra/caught-unknown-message.mjs +2 -0
  64. package/dist/lib/infra/config-reporter.mjs +2 -0
  65. package/dist/lib/infra/node-io.mjs +2 -0
  66. package/dist/lib/infra/workspace/repo-root.mjs +2 -0
  67. package/dist/lib/infra/workspace/repo-root.test.mjs +45 -0
  68. package/dist/lib/mirror/application/engine.mjs +2 -0
  69. package/dist/lib/mirror/application/sync.mjs +2 -0
  70. package/dist/lib/mirror/application/sync.test.mjs +482 -0
  71. package/dist/lib/mirror/domain/constants.mjs +2 -0
  72. package/dist/lib/mirror/domain/errors.mjs +2 -0
  73. package/dist/lib/mirror/domain/types.mjs +1 -0
  74. package/dist/lib/mirror/index.mjs +3 -0
  75. package/dist/lib/mirror/infra/dirent-list.mjs +2 -0
  76. package/dist/lib/mirror/infra/dirent-list.test.mjs +18 -0
  77. package/dist/lib/mirror/infra/package-filter.mjs +2 -0
  78. package/dist/lib/mirror/infra/package-filter.test.mjs +32 -0
  79. package/dist/lib/mirror/infra/path-normalizer.mjs +2 -0
  80. package/dist/lib/mirror/infra/update-pkg.mjs +2 -0
  81. package/dist/lib/mirror/infra/workspace-packages.mjs +2 -0
  82. package/dist/lib/mirror/infra/workspace-packages.test.mjs +167 -0
  83. package/dist/lib/mirror/presentation/reporter.mjs +2 -0
  84. package/dist/lib/tag/application/engine.mjs +2 -0
  85. package/dist/lib/tag/application/engine.test.mjs +159 -0
  86. package/dist/lib/tag/domain/types.mjs +1 -0
  87. package/dist/lib/tag/index.mjs +5 -0
  88. package/dist/lib/tag/infra/target-resolver.mjs +2 -0
  89. package/dist/lib/tag/presentation/colors.mjs +2 -0
  90. package/dist/lib/tag/presentation/tag-presenter.mjs +2 -0
  91. package/dist/lib/tag/presentation/tag-presenter.test.mjs +29 -0
  92. package/dist/loader-DpN-zl5g.mjs +78 -0
  93. package/dist/mirror-CbGiLXKT.mjs +2 -0
  94. package/dist/mirror-DqJE3ejL.mjs +66 -0
  95. package/dist/node-io-DFRbHO6m.mjs +30 -0
  96. package/dist/package-filter-C_8ryqvz.mjs +26 -0
  97. package/dist/path-normalizer-D4ceBO3l.mjs +7 -0
  98. package/dist/program-DR-H4tH3.mjs +34 -0
  99. package/dist/program.mjs +2 -0
  100. package/dist/repo-root-HmtIEm6J.mjs +22 -0
  101. package/dist/report-DYxvw34T.mjs +24 -0
  102. package/dist/reporter-CwIe_tAM.mjs +108 -0
  103. package/dist/run-target-CJWrqNT4.mjs +65 -0
  104. package/dist/schema-Or8RAARd.mjs +25 -0
  105. package/dist/sync-e1Sp-shi.mjs +157 -0
  106. package/dist/tag-Cd9JujU5.mjs +2 -0
  107. package/dist/tag-hEKVZ_-7.mjs +58 -0
  108. package/dist/tag-presenter-Cs66UBsH.mjs +63 -0
  109. package/dist/target-resolver-CR3FXMTy.mjs +170 -0
  110. package/dist/targets-pCTslnFh.mjs +106 -0
  111. package/dist/tokenizer-CeZx73Zu.mjs +216 -0
  112. package/dist/update-pkg-CnGfjWBy.mjs +37 -0
  113. package/dist/walk-DjgQn66n.mjs +33 -0
  114. package/dist/workspace-packages-K2NYTHJq.mjs +159 -0
  115. package/package.json +11 -11
  116. package/dist/bin.d.ts +0 -3
  117. package/dist/bin.d.ts.map +0 -1
  118. package/dist/commands/arrange.d.ts +0 -3
  119. package/dist/commands/arrange.d.ts.map +0 -1
  120. package/dist/commands/arrange.js +0 -114
  121. package/dist/commands/mirror.d.ts +0 -4
  122. package/dist/commands/mirror.d.ts.map +0 -1
  123. package/dist/commands/mirror.js +0 -63
  124. package/dist/lib/arrange/analyze.d.ts +0 -4
  125. package/dist/lib/arrange/analyze.d.ts.map +0 -1
  126. package/dist/lib/arrange/analyze.js +0 -105
  127. package/dist/lib/arrange/ast/collectors-cn.d.ts +0 -10
  128. package/dist/lib/arrange/ast/collectors-cn.d.ts.map +0 -1
  129. package/dist/lib/arrange/ast/collectors-cn.js +0 -84
  130. package/dist/lib/arrange/ast/collectors-jsx.d.ts +0 -4
  131. package/dist/lib/arrange/ast/collectors-jsx.d.ts.map +0 -1
  132. package/dist/lib/arrange/ast/collectors-jsx.js +0 -18
  133. package/dist/lib/arrange/ast/collectors-tv.d.ts +0 -13
  134. package/dist/lib/arrange/ast/collectors-tv.d.ts.map +0 -1
  135. package/dist/lib/arrange/ast/collectors-tv.js +0 -273
  136. package/dist/lib/arrange/ast/targets.d.ts +0 -8
  137. package/dist/lib/arrange/ast/targets.d.ts.map +0 -1
  138. package/dist/lib/arrange/ast/targets.js +0 -143
  139. package/dist/lib/arrange/ast/utils.d.ts +0 -36
  140. package/dist/lib/arrange/ast/utils.d.ts.map +0 -1
  141. package/dist/lib/arrange/ast/utils.js +0 -138
  142. package/dist/lib/arrange/constants.d.ts +0 -68
  143. package/dist/lib/arrange/constants.d.ts.map +0 -1
  144. package/dist/lib/arrange/constants.js +0 -179
  145. package/dist/lib/arrange/errors.d.ts +0 -14
  146. package/dist/lib/arrange/errors.d.ts.map +0 -1
  147. package/dist/lib/arrange/errors.js +0 -16
  148. package/dist/lib/arrange/formatters.d.ts +0 -16
  149. package/dist/lib/arrange/formatters.d.ts.map +0 -1
  150. package/dist/lib/arrange/formatters.js +0 -57
  151. package/dist/lib/arrange/group-file.d.ts +0 -4
  152. package/dist/lib/arrange/group-file.d.ts.map +0 -1
  153. package/dist/lib/arrange/group-file.js +0 -115
  154. package/dist/lib/arrange/grouping.d.ts +0 -41
  155. package/dist/lib/arrange/grouping.d.ts.map +0 -1
  156. package/dist/lib/arrange/grouping.js +0 -280
  157. package/dist/lib/arrange/imports.d.ts +0 -6
  158. package/dist/lib/arrange/imports.d.ts.map +0 -1
  159. package/dist/lib/arrange/imports.js +0 -74
  160. package/dist/lib/arrange/report.d.ts +0 -4
  161. package/dist/lib/arrange/report.d.ts.map +0 -1
  162. package/dist/lib/arrange/report.js +0 -37
  163. package/dist/lib/arrange/run-target.d.ts +0 -4
  164. package/dist/lib/arrange/run-target.d.ts.map +0 -1
  165. package/dist/lib/arrange/run-target.js +0 -28
  166. package/dist/lib/arrange/tokenizer.d.ts +0 -37
  167. package/dist/lib/arrange/tokenizer.d.ts.map +0 -1
  168. package/dist/lib/arrange/tokenizer.js +0 -390
  169. package/dist/lib/arrange/types.d.ts +0 -104
  170. package/dist/lib/arrange/types.d.ts.map +0 -1
  171. package/dist/lib/arrange/types.js +0 -7
  172. package/dist/lib/arrange/walk.d.ts +0 -4
  173. package/dist/lib/arrange/walk.d.ts.map +0 -1
  174. package/dist/lib/arrange/walk.js +0 -34
  175. package/dist/lib/arrange.d.ts +0 -41
  176. package/dist/lib/arrange.d.ts.map +0 -1
  177. package/dist/lib/arrange.js +0 -38
  178. package/dist/lib/infra/fs-contract.d.ts +0 -28
  179. package/dist/lib/infra/fs-contract.d.ts.map +0 -1
  180. package/dist/lib/infra/node-io.d.ts +0 -4
  181. package/dist/lib/infra/node-io.d.ts.map +0 -1
  182. package/dist/lib/infra/node-io.js +0 -27
  183. package/dist/lib/mirror/config.d.ts +0 -7
  184. package/dist/lib/mirror/config.d.ts.map +0 -1
  185. package/dist/lib/mirror/config.js +0 -146
  186. package/dist/lib/mirror/constants.d.ts +0 -10
  187. package/dist/lib/mirror/constants.d.ts.map +0 -1
  188. package/dist/lib/mirror/constants.js +0 -13
  189. package/dist/lib/mirror/engine.d.ts +0 -12
  190. package/dist/lib/mirror/engine.d.ts.map +0 -1
  191. package/dist/lib/mirror/engine.js +0 -248
  192. package/dist/lib/mirror/errors.d.ts +0 -10
  193. package/dist/lib/mirror/errors.d.ts.map +0 -1
  194. package/dist/lib/mirror/errors.js +0 -12
  195. package/dist/lib/mirror/package-filter.d.ts +0 -8
  196. package/dist/lib/mirror/package-filter.d.ts.map +0 -1
  197. package/dist/lib/mirror/package-filter.js +0 -33
  198. package/dist/lib/mirror/reporter.d.ts +0 -24
  199. package/dist/lib/mirror/reporter.d.ts.map +0 -1
  200. package/dist/lib/mirror/reporter.js +0 -126
  201. package/dist/lib/mirror/sync.d.ts +0 -4
  202. package/dist/lib/mirror/sync.d.ts.map +0 -1
  203. package/dist/lib/mirror/sync.js +0 -135
  204. package/dist/lib/mirror/types.d.ts +0 -81
  205. package/dist/lib/mirror/types.d.ts.map +0 -1
  206. package/dist/lib/mirror/update-pkg.d.ts +0 -13
  207. package/dist/lib/mirror/update-pkg.d.ts.map +0 -1
  208. package/dist/lib/mirror/update-pkg.js +0 -39
  209. package/dist/lib/mirror/workspace-packages.d.ts +0 -26
  210. package/dist/lib/mirror/workspace-packages.d.ts.map +0 -1
  211. package/dist/lib/mirror/workspace-packages.js +0 -160
  212. package/dist/lib/mirror.d.ts +0 -7
  213. package/dist/lib/mirror.d.ts.map +0 -1
  214. package/dist/lib/mirror.js +0 -5
  215. package/dist/lib/repo-root.d.ts +0 -7
  216. package/dist/lib/repo-root.d.ts.map +0 -1
  217. package/dist/lib/repo-root.js +0 -23
  218. package/dist/lib/shared/utils.d.ts +0 -9
  219. package/dist/lib/shared/utils.d.ts.map +0 -1
  220. package/dist/lib/shared/utils.js +0 -12
  221. package/dist/program.d.ts +0 -4
  222. package/dist/program.d.ts.map +0 -1
  223. package/dist/program.js +0 -38
  224. /package/dist/lib/{infra/fs-contract.js → arrange/domain/types.mjs} +0 -0
  225. /package/dist/lib/{mirror/types.js → infra/fs-contract.mjs} +0 -0
@@ -0,0 +1,287 @@
1
+ import { t as messageFromCaughtUnknown } from "./caught-unknown-message-CRhkDWO7.mjs";
2
+ import { i as indentOfLineContaining, n as applyEditsDescending } from "./ast-helpers-MDRYuIAk.mjs";
3
+ import { n as walkTsxFiles } from "./walk-DjgQn66n.mjs";
4
+ import "./arrange-BqP2DI3w.mjs";
5
+ import { t as resolveTagTargetCandidates } from "./target-resolver-CR3FXMTy.mjs";
6
+ import path from "node:path";
7
+ import ts from "typescript";
8
+ //#region src/lib/tag/application/engine.ts
9
+ const PACKAGE_JSON = "package.json";
10
+ const VERSION_TAG = "@since";
11
+ function hasExportModifier(node) {
12
+ return (ts.canHaveModifiers(node) ? ts.getModifiers(node) : void 0)?.some((modifier) => modifier.kind === ts.SyntaxKind.ExportKeyword) ?? false;
13
+ }
14
+ function isTaggableDeclaration(node) {
15
+ return ts.isFunctionDeclaration(node) || ts.isClassDeclaration(node) || ts.isInterfaceDeclaration(node) || ts.isTypeAliasDeclaration(node) || ts.isEnumDeclaration(node) || ts.isVariableStatement(node);
16
+ }
17
+ function addDeclarationName(registry, name, declaration) {
18
+ if (!registry.has(name)) {
19
+ registry.set(name, new Set([declaration]));
20
+ return;
21
+ }
22
+ registry.get(name).add(declaration);
23
+ }
24
+ function collectLocalNamedDeclarations(sf) {
25
+ const declarations = /* @__PURE__ */ new Map();
26
+ for (const statement of sf.statements) {
27
+ if (ts.isFunctionDeclaration(statement) && statement.name) {
28
+ addDeclarationName(declarations, statement.name.text, statement);
29
+ continue;
30
+ }
31
+ if (ts.isClassDeclaration(statement) && statement.name) {
32
+ addDeclarationName(declarations, statement.name.text, statement);
33
+ continue;
34
+ }
35
+ if (ts.isInterfaceDeclaration(statement)) {
36
+ addDeclarationName(declarations, statement.name.text, statement);
37
+ continue;
38
+ }
39
+ if (ts.isTypeAliasDeclaration(statement)) {
40
+ addDeclarationName(declarations, statement.name.text, statement);
41
+ continue;
42
+ }
43
+ if (ts.isEnumDeclaration(statement)) {
44
+ addDeclarationName(declarations, statement.name.text, statement);
45
+ continue;
46
+ }
47
+ if (!ts.isVariableStatement(statement)) continue;
48
+ for (const declaration of statement.declarationList.declarations) if (ts.isIdentifier(declaration.name)) addDeclarationName(declarations, declaration.name.text, statement);
49
+ }
50
+ return declarations;
51
+ }
52
+ function collectExportedDeclarations(sf) {
53
+ const exported = /* @__PURE__ */ new Set();
54
+ const localNamed = collectLocalNamedDeclarations(sf);
55
+ for (const statement of sf.statements) {
56
+ if (isTaggableDeclaration(statement) && hasExportModifier(statement)) {
57
+ exported.add(statement);
58
+ continue;
59
+ }
60
+ if (ts.isExportDeclaration(statement) && !statement.moduleSpecifier && statement.exportClause && ts.isNamedExports(statement.exportClause)) {
61
+ for (const element of statement.exportClause.elements) {
62
+ const localName = element.propertyName?.text ?? element.name.text;
63
+ const declarations = localNamed.get(localName);
64
+ if (!declarations) continue;
65
+ for (const declaration of declarations) exported.add(declaration);
66
+ }
67
+ continue;
68
+ }
69
+ if (!ts.isExportAssignment(statement) || !ts.isIdentifier(statement.expression)) continue;
70
+ const declarations = localNamed.get(statement.expression.text);
71
+ if (!declarations) continue;
72
+ for (const declaration of declarations) exported.add(declaration);
73
+ }
74
+ return exported;
75
+ }
76
+ function makeJSDocSinceLine(existingComment, sourceText, version) {
77
+ const commentText = sourceText.slice(existingComment.pos, existingComment.end);
78
+ const baseIndent = indentOfLineContaining(sourceText, existingComment.pos);
79
+ const normalizedBodyLines = commentText.replace(/^\/\*\*\s?/, "").replace(/\s*\*\/$/, "").split("\n").map((line) => line.replace(/^\s*\*\s?/, "").replace(/\s+$/, "")).filter((line, lineIndex, lines) => {
80
+ if (line.length > 0) return true;
81
+ const hasNonEmptyBefore = lines.slice(0, lineIndex).some((value) => value.length > 0);
82
+ const hasNonEmptyAfter = lines.slice(lineIndex + 1).some((value) => value.length > 0);
83
+ return hasNonEmptyBefore && hasNonEmptyAfter;
84
+ });
85
+ const replacement = `/**\n${normalizedBodyLines.length > 0 ? `${normalizedBodyLines.map((line) => `${baseIndent} * ${line}`).join("\n")}\n${baseIndent} *\n` : ""}${baseIndent} * ${VERSION_TAG} ${version}\n${baseIndent} */`;
86
+ return {
87
+ start: existingComment.pos,
88
+ end: existingComment.end,
89
+ replacement
90
+ };
91
+ }
92
+ function makeSinceOnlyJSDocBlock(declarationIndent, version) {
93
+ return `/**\n${declarationIndent} * ${VERSION_TAG} ${version}\n${declarationIndent} */`;
94
+ }
95
+ function makeDeclarationSinceLine(declaration, sf, sourceText, version) {
96
+ if (ts.getJSDocTags(declaration).some((tag) => tag.tagName.text === "since")) return void 0;
97
+ const lastJsDoc = ts.getJSDocCommentsAndTags(declaration).filter(ts.isJSDoc).at(-1);
98
+ if (lastJsDoc) return makeJSDocSinceLine(lastJsDoc, sourceText, version);
99
+ const start = declaration.getStart(sf);
100
+ const indent = indentOfLineContaining(sourceText, start);
101
+ return {
102
+ start,
103
+ end: start,
104
+ replacement: `${indent}${makeSinceOnlyJSDocBlock(indent, version)}\n${indent}`
105
+ };
106
+ }
107
+ function applySinceTagsToFile(filePath, version, fs, write) {
108
+ const sourceText = fs.readFileSync(filePath, "utf8");
109
+ const sf = ts.createSourceFile(filePath, sourceText, ts.ScriptTarget.Latest, true, filePath.endsWith(".tsx") ? ts.ScriptKind.TSX : ts.ScriptKind.TS);
110
+ const edits = [];
111
+ for (const declaration of collectExportedDeclarations(sf)) {
112
+ const edit = makeDeclarationSinceLine(declaration, sf, sourceText, version);
113
+ if (edit) edits.push(edit);
114
+ }
115
+ if (edits.length > 0 && write) {
116
+ const updated = applyEditsDescending(sourceText, edits);
117
+ fs.writeFileSync(filePath, updated, "utf8");
118
+ }
119
+ return {
120
+ filePath,
121
+ taggedDeclarations: edits.length,
122
+ changed: edits.length > 0
123
+ };
124
+ }
125
+ function resolveNearestPackageVersion(targetPath, fs) {
126
+ const resolved = path.resolve(targetPath);
127
+ let current = fs.statSync(resolved).isDirectory() ? resolved : path.dirname(resolved);
128
+ while (true) {
129
+ const packageJsonPath = path.join(current, PACKAGE_JSON);
130
+ if (fs.existsSync(packageJsonPath)) {
131
+ const raw = fs.readFileSync(packageJsonPath, "utf8");
132
+ const version = JSON.parse(raw).version;
133
+ if (typeof version === "string" && version.length > 0) return version;
134
+ throw new Error(`Missing or invalid version in ${packageJsonPath}`);
135
+ }
136
+ const parent = path.dirname(current);
137
+ if (parent === current) break;
138
+ current = parent;
139
+ }
140
+ throw new Error(`Unable to locate ${PACKAGE_JSON} from target: ${targetPath}`);
141
+ }
142
+ function runTagOnTarget(targetPath, opts, fs) {
143
+ const resolvedTarget = path.resolve(targetPath);
144
+ const version = resolveNearestPackageVersion(resolvedTarget, fs);
145
+ const tsFiles = (fs.statSync(resolvedTarget).isDirectory() ? walkTsxFiles(resolvedTarget, fs) : [resolvedTarget]).filter((filePath) => filePath.endsWith(".ts") || filePath.endsWith(".tsx"));
146
+ const fileResults = tsFiles.map((filePath) => applySinceTagsToFile(filePath, version, fs, opts.write));
147
+ const filesChanged = fileResults.filter((result) => result.changed).length;
148
+ const taggedDeclarations = fileResults.reduce((sum, result) => sum + result.taggedDeclarations, 0);
149
+ return {
150
+ version,
151
+ filesScanned: tsFiles.length,
152
+ filesChanged,
153
+ taggedDeclarations,
154
+ fileResults
155
+ };
156
+ }
157
+ async function runTagOnAfterWriteHook(hook, modifiedFiles) {
158
+ if (!hook || modifiedFiles.length === 0) return null;
159
+ try {
160
+ await hook({ files: modifiedFiles });
161
+ return null;
162
+ } catch (caughtHookError) {
163
+ return `[tag] onAfterWrite hook failed: ${messageFromCaughtUnknown(caughtHookError)}`;
164
+ }
165
+ }
166
+ function summarizeVersions(targetResults) {
167
+ const distinctVersions = extractDistinctVersions(targetResults);
168
+ if (distinctVersions.size === 0) return "none";
169
+ if (distinctVersions.size > 1) return "mixed";
170
+ return [...distinctVersions][0];
171
+ }
172
+ function extractDistinctVersions(targetResults) {
173
+ return new Set(targetResults.map((targetResult) => targetResult.result?.version).filter((version) => typeof version === "string" && version.length > 0));
174
+ }
175
+ function chooseWorkspacePackageTargetPath(candidate, fs) {
176
+ if (candidate.source !== "workspace-package") return {
177
+ targetPath: candidate.candidatePath,
178
+ source: candidate.source
179
+ };
180
+ const preferredSourceDir = path.join(candidate.candidatePath, "src");
181
+ if (fs.existsSync(preferredSourceDir) && fs.statSync(preferredSourceDir).isDirectory()) return {
182
+ targetPath: preferredSourceDir,
183
+ source: "workspace-package-selected-src"
184
+ };
185
+ return {
186
+ targetPath: candidate.candidatePath,
187
+ source: "workspace-package-selected-root"
188
+ };
189
+ }
190
+ function resolveTargetSelection(candidate, rootDir, fs) {
191
+ const selectedTarget = chooseWorkspacePackageTargetPath(candidate, fs);
192
+ const rootRelativeTargetPath = path.relative(rootDir, selectedTarget.targetPath).split(path.sep).join("/");
193
+ return {
194
+ targetPath: selectedTarget.targetPath,
195
+ rootRelativeTargetPath: rootRelativeTargetPath || ".",
196
+ source: selectedTarget.source,
197
+ packageDir: candidate.packageDir,
198
+ packageName: candidate.packageName
199
+ };
200
+ }
201
+ function filterSkippedCandidates(targetCandidates, skipPackages) {
202
+ if (!skipPackages || skipPackages.length === 0) return {
203
+ includedCandidates: targetCandidates,
204
+ skippedPackages: []
205
+ };
206
+ const skipPackageSet = new Set(skipPackages);
207
+ const includedCandidates = [];
208
+ const skippedPackages = [];
209
+ for (const candidate of targetCandidates) {
210
+ const packageName = candidate.packageName;
211
+ if (packageName && skipPackageSet.has(packageName)) {
212
+ skippedPackages.push(packageName);
213
+ continue;
214
+ }
215
+ includedCandidates.push(candidate);
216
+ }
217
+ return {
218
+ includedCandidates,
219
+ skippedPackages
220
+ };
221
+ }
222
+ async function runOnResolvedTarget(resolvedTarget, write, fs, listener) {
223
+ listener?.onTargetStarted(resolvedTarget);
224
+ const absoluteTargetPath = path.resolve(resolvedTarget.targetPath);
225
+ if (!fs.existsSync(absoluteTargetPath)) {
226
+ const missingTargetResult = {
227
+ target: resolvedTarget,
228
+ targetExists: false,
229
+ runError: `Not found: ${absoluteTargetPath}`,
230
+ result: null
231
+ };
232
+ listener?.onTargetCompleted(resolvedTarget, missingTargetResult);
233
+ return missingTargetResult;
234
+ }
235
+ try {
236
+ const targetRunResult = {
237
+ target: resolvedTarget,
238
+ targetExists: true,
239
+ runError: null,
240
+ result: runTagOnTarget(absoluteTargetPath, { write }, fs)
241
+ };
242
+ listener?.onTargetCompleted(resolvedTarget, targetRunResult);
243
+ return targetRunResult;
244
+ } catch (caughtRunError) {
245
+ const failedTargetRunResult = {
246
+ target: resolvedTarget,
247
+ targetExists: true,
248
+ runError: messageFromCaughtUnknown(caughtRunError),
249
+ result: null
250
+ };
251
+ listener?.onTargetCompleted(resolvedTarget, failedTargetRunResult);
252
+ return failedTargetRunResult;
253
+ }
254
+ }
255
+ /**
256
+ * CLI entry: run tagging and optional `onAfterWrite` using config injected by the command layer.
257
+ * Returns structured execution data; presentation/logging belongs to command layer.
258
+ */
259
+ async function runTagSync(opts) {
260
+ const { fs } = opts;
261
+ const { includedCandidates, skippedPackages } = filterSkippedCandidates(await resolveTagTargetCandidates(opts.rootDir, opts.targetPath, fs), opts.skipPackages);
262
+ const selectedTargets = includedCandidates.map((candidate) => resolveTargetSelection(candidate, opts.rootDir, fs));
263
+ const targetResults = await Promise.all(selectedTargets.map((resolvedTarget) => runOnResolvedTarget(resolvedTarget, opts.write, fs, opts.listener)));
264
+ const allFileResults = targetResults.flatMap((targetResult) => targetResult.result?.fileResults ?? []);
265
+ const filesScanned = targetResults.reduce((sum, targetResult) => sum + (targetResult.result?.filesScanned ?? 0), 0);
266
+ const filesChanged = targetResults.reduce((sum, targetResult) => sum + (targetResult.result?.filesChanged ?? 0), 0);
267
+ const taggedDeclarations = targetResults.reduce((sum, targetResult) => sum + (targetResult.result?.taggedDeclarations ?? 0), 0);
268
+ const modifiedFiles = allFileResults.filter((entry) => entry.changed).map((entry) => entry.filePath);
269
+ const hookError = opts.write && modifiedFiles.length > 0 ? await runTagOnAfterWriteHook(opts.config?.onAfterWrite, modifiedFiles) : null;
270
+ const distinctVersions = [...extractDistinctVersions(targetResults)].sort((left, right) => left.localeCompare(right));
271
+ return {
272
+ mode: opts.write ? "applied" : "dry-run",
273
+ selectedTargets,
274
+ resolvedTargets: selectedTargets,
275
+ skippedPackages,
276
+ targetResults,
277
+ filesScanned,
278
+ filesChanged,
279
+ taggedDeclarations,
280
+ versionSummary: summarizeVersions(targetResults),
281
+ distinctVersions,
282
+ modifiedFiles,
283
+ hookError
284
+ };
285
+ }
286
+ //#endregion
287
+ export { runTagOnTarget as n, runTagSync as r, resolveNearestPackageVersion as t };
@@ -0,0 +1,236 @@
1
+ import { a as VALID_JS_EXTENSIONS, i as PACKAGE_JSON_EXPORT, n as DTS_EXTENSION } from "./constants-Bq5wdyLC.mjs";
2
+ import { t as isDirentList } from "./dirent-list-BSDeRG5i.mjs";
3
+ import { t as normalizePath } from "./path-normalizer-D4ceBO3l.mjs";
4
+ import path from "node:path";
5
+ //#region src/lib/mirror/application/engine.ts
6
+ function resolvePackageScopedConfig(configMap, pkgMeta) {
7
+ if (!configMap) return void 0;
8
+ return configMap[pkgMeta.packageName];
9
+ }
10
+ async function scanDirectoryFiles(fs, dir, baseDir = dir) {
11
+ try {
12
+ const raw = await fs.readdir(dir, {
13
+ recursive: true,
14
+ withFileTypes: true
15
+ });
16
+ if (!isDirentList(raw)) return [];
17
+ return raw.filter((dirent) => dirent.isFile()).map((dirent) => {
18
+ const fullPath = path.join(dirent.parentPath, dirent.name);
19
+ return normalizePath(path.relative(baseDir, fullPath));
20
+ });
21
+ } catch (caughtError) {
22
+ if (caughtError && typeof caughtError === "object" && "code" in caughtError) {
23
+ if (caughtError.code === "ENOENT" || caughtError.code === "EACCES") return [];
24
+ }
25
+ throw caughtError;
26
+ }
27
+ }
28
+ async function isDirectoryCssOnly(fs, distDir, dirPath) {
29
+ try {
30
+ const raw = await fs.readdir(path.join(distDir, dirPath), { withFileTypes: true });
31
+ if (!isDirentList(raw)) return false;
32
+ if (raw.length === 0) return true;
33
+ return raw.every((dirent) => dirent.isFile() && dirent.name.endsWith(".css"));
34
+ } catch {
35
+ return false;
36
+ }
37
+ }
38
+ function groupFilesByModule(files) {
39
+ const modules = /* @__PURE__ */ new Map();
40
+ for (const file of files) {
41
+ let ext;
42
+ let modulePath;
43
+ if (file.endsWith(".d.ts")) {
44
+ ext = DTS_EXTENSION;
45
+ modulePath = file.slice(0, -DTS_EXTENSION.length);
46
+ } else {
47
+ ext = path.extname(file);
48
+ if (!VALID_JS_EXTENSIONS.has(ext)) continue;
49
+ modulePath = file.slice(0, -ext.length);
50
+ }
51
+ if (!path.basename(modulePath)) continue;
52
+ let distModule = modules.get(modulePath);
53
+ if (!distModule) {
54
+ distModule = {
55
+ path: modulePath,
56
+ files: {
57
+ js: null,
58
+ cjs: null,
59
+ dts: null
60
+ }
61
+ };
62
+ modules.set(modulePath, distModule);
63
+ }
64
+ if (ext === ".js") distModule.files.js = file;
65
+ else if (ext === ".cjs") distModule.files.cjs = file;
66
+ else if (ext === ".d.ts") distModule.files.dts = file;
67
+ }
68
+ return modules;
69
+ }
70
+ function toExportPath(distPath) {
71
+ if (distPath === "index") return ".";
72
+ if (distPath.endsWith("/index")) return `./${distPath.slice(0, -6)}`;
73
+ return `./${distPath}`;
74
+ }
75
+ const GROUP_ORDER = {
76
+ components: 100,
77
+ hooks: 200,
78
+ primitives: 300,
79
+ core: 400,
80
+ loaders: 500,
81
+ utils: 600,
82
+ adapters: 700,
83
+ script: 750,
84
+ css: 900
85
+ };
86
+ function getExportGroup(exportPath, pathTransform) {
87
+ if (exportPath === ".") return [
88
+ ".",
89
+ "",
90
+ 0,
91
+ 0
92
+ ];
93
+ const cleanPath = exportPath.startsWith("./") ? exportPath.slice(2) : exportPath;
94
+ if (cleanPath.endsWith("/*")) {
95
+ const dirName = cleanPath.slice(0, -2);
96
+ return [
97
+ dirName,
98
+ "",
99
+ dirName === "css" ? 900 : 100,
100
+ 0
101
+ ];
102
+ }
103
+ const parts = cleanPath.split("/");
104
+ if (parts.length === 1) {
105
+ const name = parts[0];
106
+ if (name in GROUP_ORDER) return [
107
+ name,
108
+ "",
109
+ GROUP_ORDER[name] ?? 0,
110
+ 0
111
+ ];
112
+ if (pathTransform) return [
113
+ "components",
114
+ name,
115
+ 100,
116
+ 1
117
+ ];
118
+ return [
119
+ "",
120
+ name,
121
+ 800,
122
+ 1
123
+ ];
124
+ }
125
+ const group = parts[0] ?? "";
126
+ return [
127
+ group,
128
+ parts.slice(1).join("/"),
129
+ GROUP_ORDER[group] ?? 700,
130
+ 1
131
+ ];
132
+ }
133
+ function createPathTransform(config, pkgMeta) {
134
+ const pathConfig = resolvePackageScopedConfig(config?.pathTransformations, pkgMeta);
135
+ if (!pathConfig) return null;
136
+ const { removePrefix } = pathConfig;
137
+ if (!removePrefix) return null;
138
+ return (exportPath) => {
139
+ if (!exportPath.startsWith(removePrefix)) return exportPath;
140
+ const result = exportPath.slice(removePrefix.length);
141
+ if (result && result !== "." && !result.startsWith("./")) return `./${result}`;
142
+ return result;
143
+ };
144
+ }
145
+ function getSortTuple(exportPath, pathTransform) {
146
+ const [group, subpath, order, isIndex] = getExportGroup(exportPath, pathTransform);
147
+ return [
148
+ order,
149
+ group,
150
+ isIndex,
151
+ subpath
152
+ ];
153
+ }
154
+ function compareTuples(left, right) {
155
+ if (left[0] !== right[0]) return left[0] - right[0];
156
+ if (left[1] !== right[1]) return left[1] < right[1] ? -1 : 1;
157
+ if (left[2] !== right[2]) return left[2] - right[2];
158
+ if (left[3] !== right[3]) return left[3] < right[3] ? -1 : 1;
159
+ return 0;
160
+ }
161
+ async function generateCssExports(fs, distDir, cssConfig) {
162
+ if (cssConfig === false) return {};
163
+ if (cssConfig === true) cssConfig = { enabled: true };
164
+ if (!cssConfig || cssConfig.enabled === false) return {};
165
+ const cssFiles = (await scanDirectoryFiles(fs, distDir)).filter((relativeDistPath) => relativeDistPath.endsWith(".css"));
166
+ if (!cssFiles.length) return {};
167
+ const cssExports = { ...cssConfig.customExports };
168
+ const cssByDir = /* @__PURE__ */ new Map();
169
+ const rootCss = [];
170
+ for (const file of cssFiles) {
171
+ const dirName = normalizePath(path.dirname(file));
172
+ if (dirName === ".") rootCss.push(file);
173
+ else {
174
+ const arr = cssByDir.get(dirName) || [];
175
+ arr.push(file);
176
+ cssByDir.set(dirName, arr);
177
+ }
178
+ }
179
+ for (const file of rootCss) {
180
+ const exportPath = `./${file}`;
181
+ if (!(exportPath in cssExports)) cssExports[exportPath] = `./dist/${file}`;
182
+ }
183
+ for (const [dirName, dirFiles] of cssByDir.entries()) if (await isDirectoryCssOnly(fs, distDir, dirName) && !cssConfig.forceExportFiles) {
184
+ const wildcardExport = `./${dirName}/*`;
185
+ if (!(wildcardExport in cssExports)) cssExports[wildcardExport] = `./dist/${dirName}/*`;
186
+ } else for (const file of dirFiles) {
187
+ const exportPath = `./${file}`;
188
+ if (!(exportPath in cssExports)) cssExports[exportPath] = `./dist/${file}`;
189
+ }
190
+ return cssExports;
191
+ }
192
+ /**
193
+ * Compute `package.json#exports` from a built `dist/` tree. No logging; no writes.
194
+ */
195
+ async function generateExports(fs, distDir, pathTransform, cssConfig, customExports) {
196
+ const files = await scanDirectoryFiles(fs, distDir);
197
+ if (!files.length) return {
198
+ exports: { [PACKAGE_JSON_EXPORT]: PACKAGE_JSON_EXPORT },
199
+ jsCount: 0,
200
+ cssCount: 0
201
+ };
202
+ const modules = groupFilesByModule(files);
203
+ const validModules = Array.from(modules.values()).filter((mod) => mod.files.js && mod.files.dts);
204
+ if (!validModules.length) return {
205
+ exports: { [PACKAGE_JSON_EXPORT]: PACKAGE_JSON_EXPORT },
206
+ jsCount: 0,
207
+ cssCount: 0
208
+ };
209
+ const exportsObj = {};
210
+ for (const distModuleEntry of validModules) {
211
+ let exportPath = toExportPath(distModuleEntry.path);
212
+ if (pathTransform) exportPath = pathTransform(exportPath);
213
+ const distPath = `./dist/${distModuleEntry.path}`;
214
+ const entry = { types: `${distPath}.d.ts` };
215
+ if (distModuleEntry.files.js) entry.import = `${distPath}.js`;
216
+ if (distModuleEntry.files.cjs) entry.require = `${distPath}.cjs`;
217
+ exportsObj[exportPath] = entry;
218
+ }
219
+ let sortedKeys = Object.keys(exportsObj).sort((pathA, pathB) => compareTuples(getSortTuple(pathA, pathTransform), getSortTuple(pathB, pathTransform)));
220
+ const sortedExports = {};
221
+ for (const exportKey of sortedKeys) sortedExports[exportKey] = exportsObj[exportKey];
222
+ const cssExports = await generateCssExports(fs, distDir, cssConfig ?? { enabled: true });
223
+ Object.assign(sortedExports, cssExports);
224
+ for (const [specifier, mappedPath] of Object.entries(customExports || {})) if (specifier !== "./package.json") sortedExports[specifier] = mappedPath;
225
+ sortedKeys = Object.keys(sortedExports).filter((exportKey) => exportKey !== PACKAGE_JSON_EXPORT).sort((pathA, pathB) => compareTuples(getSortTuple(pathA, pathTransform), getSortTuple(pathB, pathTransform)));
226
+ const finalExports = {};
227
+ for (const exportKey of sortedKeys) finalExports[exportKey] = sortedExports[exportKey];
228
+ finalExports[PACKAGE_JSON_EXPORT] = PACKAGE_JSON_EXPORT;
229
+ return {
230
+ exports: finalExports,
231
+ jsCount: Object.keys(exportsObj).length,
232
+ cssCount: Object.keys(cssExports).length
233
+ };
234
+ }
235
+ //#endregion
236
+ export { generateExports as n, createPathTransform as t };
@@ -0,0 +1,15 @@
1
+ //#region src/lib/mirror/domain/errors.ts
2
+ const MirrorErrorCode = {
3
+ FATAL: "FATAL",
4
+ PACKAGE_WRITE: "PACKAGE_WRITE"
5
+ };
6
+ var MirrorError = class extends Error {
7
+ code;
8
+ constructor(code, message, options) {
9
+ super(message, options);
10
+ this.name = "MirrorError";
11
+ this.code = code;
12
+ }
13
+ };
14
+ //#endregion
15
+ export { MirrorErrorCode as n, MirrorError as t };
@@ -0,0 +1,19 @@
1
+ //#region src/lib/arrange/domain/errors.ts
2
+ /**
3
+ * Structured errors for the arrange CLI library (throw from lib; handle exit in commands).
4
+ */
5
+ const ArrangeErrorCode = {
6
+ TARGET_NOT_FOUND: "TARGET_NOT_FOUND",
7
+ INVALID_INPUT: "INVALID_INPUT",
8
+ INTERNAL: "INTERNAL"
9
+ };
10
+ var ArrangeError = class extends Error {
11
+ code;
12
+ constructor(code, message, options) {
13
+ super(message, options);
14
+ this.name = "ArrangeError";
15
+ this.code = code;
16
+ }
17
+ };
18
+ //#endregion
19
+ export { ArrangeErrorCode as n, ArrangeError as t };
@@ -0,0 +1,52 @@
1
+ import { i as indentOfLineContaining } from "./ast-helpers-MDRYuIAk.mjs";
2
+ //#region src/lib/arrange/presentation/formatters.ts
3
+ function escapeTsStringLiteralContent(group) {
4
+ return group.replaceAll("\\", "\\\\").replaceAll("\"", "\\\"");
5
+ }
6
+ /**
7
+ * Multiline fragment for use *inside* an existing `cn(...)` — replaces one
8
+ * string argument with several, without producing `cn(cn(...))`.
9
+ */
10
+ function formatCnArguments(groups, options) {
11
+ const indent = options?.indent ?? " ";
12
+ const commaAfterLast = options?.commaAfterLastGroup ?? options?.trailingClassName ?? false;
13
+ const lines = [];
14
+ for (let i = 0; i < groups.length; i++) {
15
+ const group = groups[i];
16
+ const comma = i < groups.length - 1 || commaAfterLast ? "," : "";
17
+ lines.push(`${indent}"${escapeTsStringLiteralContent(group)}"${comma}`);
18
+ }
19
+ if (options?.trailingClassName) lines.push(`${indent}className,`);
20
+ return lines.join("\n");
21
+ }
22
+ function formatCnCall(groups, options) {
23
+ const lines = ["cn("];
24
+ const commaOnEachStringLine = groups.length > 1 || Boolean(options?.trailingClassName);
25
+ for (let i = 0; i < groups.length; i++) {
26
+ const group = groups[i];
27
+ const comma = commaOnEachStringLine ? "," : "";
28
+ lines.push(` "${escapeTsStringLiteralContent(group)}"${comma}`);
29
+ }
30
+ if (options?.trailingClassName) lines.push(" className,");
31
+ lines.push(")");
32
+ return lines.join("\n");
33
+ }
34
+ function formatArray(groups) {
35
+ const lines = ["["];
36
+ for (let i = 0; i < groups.length; i++) {
37
+ const group = groups[i];
38
+ const comma = i < groups.length - 1 || groups.length > 1 ? "," : "";
39
+ lines.push(` "${escapeTsStringLiteralContent(group)}"${comma}`);
40
+ }
41
+ lines.push("]");
42
+ return lines.join("\n");
43
+ }
44
+ function formatJsxCnAttributeValue(groups, source, valueNodeStart) {
45
+ const baseIndent = indentOfLineContaining(source, valueNodeStart);
46
+ return `{cn(\n${formatCnArguments(groups, {
47
+ indent: `${baseIndent} `,
48
+ commaAfterLastGroup: groups.length > 1
49
+ })}\n${baseIndent})}`;
50
+ }
51
+ //#endregion
52
+ export { formatJsxCnAttributeValue as a, formatCnCall as i, formatArray as n, formatCnArguments as r, escapeTsStringLiteralContent as t };