@codefast/cli 1.0.0-canary.6 → 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,109 +0,0 @@
1
- import { messageFrom } from "../core/errors.mjs";
2
- import { createMirrorDistFilesystem } from "./dist-filesystem-impl.mjs";
3
- import { DIST_DIR, PACKAGE_JSON } from "./domain/constants.mjs";
4
- import { createPathTransform, generateExports } from "./domain/exports.mjs";
5
- import { resolvePackageDisplayName } from "./domain/package-display-name.mjs";
6
- import { writePackageJsonExportsAtomic } from "./write-exports.mjs";
7
- import { buildSourcePathResolver, supplementExportsInPackageJson } from "./supplement-exports.mjs";
8
- import path from "node:path";
9
- //#region src/mirror/sync-workspace-package.ts
10
- /**
11
- * @since 0.3.16-canary.0
12
- */
13
- async function syncExportsForWorkspacePackage(fs, rootDir, packagePathStr, config, write = true) {
14
- const pathJoin = path.join;
15
- const pathResolve = path.resolve;
16
- const pathBasename = path.basename;
17
- const packageDir = pathResolve(rootDir, packagePathStr);
18
- const distDir = pathJoin(packageDir, DIST_DIR);
19
- const packageJsonPath = pathJoin(packageDir, PACKAGE_JSON);
20
- const folderBasename = pathBasename(packageDir);
21
- const distFilesystem = createMirrorDistFilesystem(fs);
22
- const pkgStats = {
23
- name: folderBasename,
24
- path: packageDir,
25
- jsModules: 0,
26
- cssExports: 0,
27
- extraExports: 0,
28
- totalExports: 0,
29
- hasTransform: false,
30
- cssConfigStatus: "",
31
- skipped: false,
32
- skipReason: "",
33
- error: null,
34
- prunedExportKeys: []
35
- };
36
- if (!fs.existsSync(packageJsonPath)) {
37
- pkgStats.skipped = true;
38
- pkgStats.skipReason = "package.json not found";
39
- return pkgStats;
40
- }
41
- let packageJsonParseError;
42
- let parsedPackageJson;
43
- try {
44
- const packageContent = await fs.readFile(packageJsonPath, "utf8");
45
- const rawPackageJson = JSON.parse(packageContent);
46
- if (rawPackageJson === null || typeof rawPackageJson !== "object" || Array.isArray(rawPackageJson)) throw new SyntaxError("package.json root must be a JSON object");
47
- parsedPackageJson = rawPackageJson;
48
- pkgStats.name = resolvePackageDisplayName(parsedPackageJson, folderBasename);
49
- } catch (caughtError) {
50
- pkgStats.name = folderBasename;
51
- packageJsonParseError = caughtError;
52
- }
53
- const pkgConfig = config[pkgStats.name];
54
- if (pkgConfig === false) {
55
- pkgStats.skipped = true;
56
- pkgStats.skipReason = "configured to skip";
57
- return pkgStats;
58
- }
59
- if (packageJsonParseError !== void 0) {
60
- if (!fs.existsSync(distDir)) {
61
- pkgStats.skipped = true;
62
- pkgStats.skipReason = "dist/ not found";
63
- return pkgStats;
64
- }
65
- pkgStats.error = messageFrom(packageJsonParseError);
66
- return pkgStats;
67
- }
68
- if (!fs.existsSync(distDir)) {
69
- pkgStats.skipped = true;
70
- pkgStats.skipReason = "dist/ not found";
71
- return pkgStats;
72
- }
73
- try {
74
- const resolveSourcePath = buildSourcePathResolver(fs, packageDir);
75
- const exportOptions = {
76
- source: pkgConfig?.source ?? true,
77
- types: pkgConfig?.types ?? true,
78
- import: pkgConfig?.import ?? true,
79
- resolveSourcePath
80
- };
81
- if (pkgConfig?.preserve) {
82
- const { supplementedSpecifiers } = await supplementExportsInPackageJson(fs, packageJsonPath, packageDir, exportOptions, write);
83
- pkgStats.totalExports = supplementedSpecifiers.length;
84
- } else {
85
- const pathTransform = createPathTransform(pkgConfig?.strip);
86
- pkgStats.hasTransform = !!pathTransform;
87
- const cssConfig = pkgConfig?.css;
88
- if (cssConfig === false) pkgStats.cssConfigStatus = "disabled";
89
- else if (cssConfig !== void 0) pkgStats.cssConfigStatus = "configured";
90
- const extraExports = pkgConfig?.exports ?? {};
91
- const generatedExports = await generateExports(distFilesystem, distDir, pathTransform, cssConfig, extraExports, exportOptions);
92
- const { prunedKeys } = await writePackageJsonExportsAtomic(fs, packageJsonPath, {
93
- generatedExports: generatedExports.exports,
94
- managedExportSpecifiers: Object.keys(generatedExports.exports),
95
- originalPathBySpecifier: generatedExports.originalPathBySpecifier
96
- }, write);
97
- pkgStats.jsModules = generatedExports.jsCount;
98
- pkgStats.cssExports = generatedExports.cssCount;
99
- pkgStats.extraExports = Object.keys(extraExports).length;
100
- pkgStats.totalExports = Object.keys(generatedExports.exports).length;
101
- pkgStats.prunedExportKeys = prunedKeys;
102
- }
103
- } catch (caughtError) {
104
- pkgStats.error = messageFrom(caughtError);
105
- }
106
- return pkgStats;
107
- }
108
- //#endregion
109
- export { syncExportsForWorkspacePackage };
@@ -1,88 +0,0 @@
1
- import { AppError, messageFrom } from "../core/errors.mjs";
2
- import { err, ok } from "../core/result.mjs";
3
- import { listWorkspacePackageDirectories } from "../core/workspace/resolver.mjs";
4
- import { normalizePath } from "./domain/path-normalizer.mjs";
5
- import { resolvePackageFilterUnderRoot } from "./package-path.mjs";
6
- import { syncExportsForWorkspacePackage } from "./sync-workspace-package.mjs";
7
- import path from "node:path";
8
- //#region src/mirror/sync.ts
9
- /**
10
- * @since 0.3.16-canary.0
11
- */
12
- async function runMirrorSync(fs, input) {
13
- const config = input.config ?? {};
14
- const { listener } = input;
15
- const write = input.write ?? true;
16
- listener?.onBanner();
17
- const startTime = performance.now();
18
- try {
19
- let targetPackages = [];
20
- if (input.packageFilter) {
21
- const filterOutcome = resolvePackageFilterUnderRoot(fs, input.rootDir, input.packageFilter);
22
- if (!filterOutcome.ok) return filterOutcome;
23
- targetPackages = [filterOutcome.value];
24
- listener?.onProcessingMode({ kind: "single" });
25
- } else {
26
- const layoutOutcome = await listWorkspacePackageDirectories(input.rootDir, fs, false);
27
- const { relPaths, multiSource } = mirrorTargetsFromWorkspaceLayout(input.rootDir, layoutOutcome);
28
- targetPackages = relPaths;
29
- listener?.onProcessingMode({
30
- kind: "multi",
31
- source: multiSource
32
- });
33
- }
34
- const stats = {
35
- packagesFound: targetPackages.length,
36
- packagesProcessed: 0,
37
- packagesSkipped: 0,
38
- packagesErrored: 0,
39
- totalExports: 0,
40
- totalJsModules: 0,
41
- totalCssExports: 0,
42
- packageDetails: []
43
- };
44
- if (targetPackages.length === 0) {
45
- listener?.onNoPackages();
46
- listener?.onComplete(stats, (performance.now() - startTime) / 1e3);
47
- return ok(stats);
48
- }
49
- let ordinal = 1;
50
- for (const pkgPath of targetPackages) {
51
- const pkgStats = await syncExportsForWorkspacePackage(fs, input.rootDir, pkgPath, config, write);
52
- stats.packageDetails.push(pkgStats);
53
- listener?.onPackageComplete(pkgStats, ordinal, targetPackages.length);
54
- ordinal++;
55
- accumulateStats(stats, pkgStats);
56
- }
57
- const elapsed = (performance.now() - startTime) / 1e3;
58
- listener?.onComplete(stats, elapsed);
59
- return ok(stats);
60
- } catch (caughtError) {
61
- return err(new AppError("INFRA_FAILURE", messageFrom(caughtError), caughtError));
62
- }
63
- }
64
- function accumulateStats(stats, pkgStats) {
65
- if (pkgStats.skipped) stats.packagesSkipped++;
66
- else if (pkgStats.error !== null) stats.packagesErrored++;
67
- else {
68
- stats.packagesProcessed++;
69
- stats.totalExports += pkgStats.totalExports;
70
- stats.totalJsModules += pkgStats.jsModules;
71
- stats.totalCssExports += pkgStats.cssExports;
72
- }
73
- }
74
- function mirrorTargetsFromWorkspaceLayout(rootDir, layoutOutcome) {
75
- if (layoutOutcome.layoutSource === "declared-empty") return {
76
- relPaths: [],
77
- multiSource: "declared-empty"
78
- };
79
- const multiSource = layoutOutcome.layoutSource;
80
- const relPaths = layoutOutcome.packageDirectoryPathsAbsolute.map((absolutePath) => normalizePath(path.relative(rootDir, absolutePath))).filter((relativePath) => relativePath.length > 0);
81
- relPaths.sort((left, right) => left.localeCompare(right));
82
- return {
83
- relPaths,
84
- multiSource
85
- };
86
- }
87
- //#endregion
88
- export { runMirrorSync };
@@ -1,94 +0,0 @@
1
- import { messageFrom } from "../core/errors.mjs";
2
- import { PACKAGE_JSON_EXPORT } from "./domain/constants.mjs";
3
- import { MirrorError, MirrorErrorCode } from "./domain/errors.mjs";
4
- //#region src/mirror/write-exports.ts
5
- /**
6
- * Writes `exports` into `package.json` via a temp file + rename (atomic on same volume).
7
- * Preserves a trailing newline after JSON.
8
- *
9
- * @since 0.3.16-canary.0
10
- */
11
- async function writePackageJsonExportsAtomic(fs, packageJsonPath, mergeInput, write = true) {
12
- function containsDistTarget(value) {
13
- if (typeof value === "string") return value.startsWith("./dist/");
14
- if (Array.isArray(value)) return value.some((entryValue) => containsDistTarget(entryValue));
15
- if (value && typeof value === "object") return Object.values(value).some((entryValue) => containsDistTarget(entryValue));
16
- return false;
17
- }
18
- /**
19
- * Keep `./package.json` at the very end for aesthetics by default.
20
- * If a catch-all `./*` exists, move `./package.json` before wildcards so it remains reachable.
21
- */
22
- function exportSpecifierRank(exportSpecifier, hasCatchAllWildcard) {
23
- if (exportSpecifier === ".") return 0;
24
- if (exportSpecifier === "./package.json") return hasCatchAllWildcard ? 2 : 4;
25
- if (exportSpecifier.includes("*")) return 3;
26
- return 1;
27
- }
28
- function compareExportSpecifiers(leftSpecifier, rightSpecifier, pathBySpecifier, hasCatchAllWildcard) {
29
- const leftRank = exportSpecifierRank(leftSpecifier, hasCatchAllWildcard);
30
- const rightRank = exportSpecifierRank(rightSpecifier, hasCatchAllWildcard);
31
- if (leftRank !== rightRank) return leftRank - rightRank;
32
- const leftOriginalPath = pathBySpecifier[leftSpecifier] ?? leftSpecifier;
33
- const rightOriginalPath = pathBySpecifier[rightSpecifier] ?? rightSpecifier;
34
- const originalPathComparison = leftOriginalPath.localeCompare(rightOriginalPath);
35
- if (originalPathComparison !== 0) return originalPathComparison;
36
- return leftSpecifier.localeCompare(rightSpecifier);
37
- }
38
- const raw = await fs.readFile(packageJsonPath, "utf8");
39
- const packageJson = JSON.parse(raw);
40
- const existingExports = packageJson.exports;
41
- const existingExportMap = existingExports && typeof existingExports === "object" && !Array.isArray(existingExports) ? existingExports : {};
42
- const managedSpecifiers = new Set(mergeInput.managedExportSpecifiers);
43
- const originalPathBySpecifier = { ...mergeInput.originalPathBySpecifier };
44
- const mergedExportMap = {};
45
- const prunedKeys = [];
46
- for (const [exportSpecifier, exportValue] of Object.entries(existingExportMap)) {
47
- if (exportSpecifier === "./package.json") {
48
- mergedExportMap[exportSpecifier] = exportValue;
49
- if (!(exportSpecifier in originalPathBySpecifier)) originalPathBySpecifier[exportSpecifier] = exportSpecifier;
50
- continue;
51
- }
52
- if (!managedSpecifiers.has(exportSpecifier)) if (containsDistTarget(exportValue)) prunedKeys.push(exportSpecifier);
53
- else {
54
- mergedExportMap[exportSpecifier] = exportValue;
55
- if (!(exportSpecifier in originalPathBySpecifier)) originalPathBySpecifier[exportSpecifier] = exportSpecifier;
56
- }
57
- }
58
- for (const [exportSpecifier, exportValue] of Object.entries(mergeInput.generatedExports)) mergedExportMap[exportSpecifier] = exportValue;
59
- if (!("./package.json" in mergedExportMap)) mergedExportMap[PACKAGE_JSON_EXPORT] = PACKAGE_JSON_EXPORT;
60
- originalPathBySpecifier[PACKAGE_JSON_EXPORT] = PACKAGE_JSON_EXPORT;
61
- const rootExport = mergedExportMap["."];
62
- if (rootExport && typeof rootExport === "object" && !Array.isArray(rootExport)) {
63
- const rootEntry = rootExport;
64
- const requirePath = typeof rootEntry.require === "string" ? rootEntry.require : void 0;
65
- const importPath = typeof rootEntry.import === "string" ? rootEntry.import : void 0;
66
- const typesPath = typeof rootEntry.types === "string" ? rootEntry.types : void 0;
67
- if (requirePath || importPath) packageJson.main = requirePath ?? importPath;
68
- if (importPath && importPath.endsWith(".mjs")) packageJson.module = importPath;
69
- if (typesPath) packageJson.types = typesPath;
70
- }
71
- const filesField = packageJson.files;
72
- if (Array.isArray(filesField)) {
73
- const normalizedFiles = filesField.filter((entry) => typeof entry === "string");
74
- if (!normalizedFiles.includes("dist")) normalizedFiles.push("dist");
75
- packageJson.files = normalizedFiles;
76
- } else packageJson.files = ["dist"];
77
- const sortedExportMap = {};
78
- const hasCatchAllWildcard = "./*" in mergedExportMap;
79
- for (const exportSpecifier of Object.keys(mergedExportMap).toSorted((leftSpecifier, rightSpecifier) => compareExportSpecifiers(leftSpecifier, rightSpecifier, originalPathBySpecifier, hasCatchAllWildcard))) sortedExportMap[exportSpecifier] = mergedExportMap[exportSpecifier];
80
- if (!write) return { prunedKeys };
81
- packageJson.exports = sortedExportMap;
82
- const serialized = JSON.stringify(packageJson, null, 2) + "\n";
83
- const tmpPath = `${packageJsonPath}.tmp`;
84
- await fs.writeFile(tmpPath, serialized, "utf8");
85
- try {
86
- await fs.rename(tmpPath, packageJsonPath);
87
- } catch (caughtRenameError) {
88
- await fs.unlink(tmpPath).catch(() => {});
89
- throw new MirrorError(MirrorErrorCode.PACKAGE_WRITE, `Failed to atomically update ${packageJsonPath}: ${messageFrom(caughtRenameError)}`, caughtRenameError instanceof Error ? { cause: caughtRenameError } : void 0);
90
- }
91
- return { prunedKeys };
92
- }
93
- //#endregion
94
- export { writePackageJsonExportsAtomic };
@@ -1,11 +0,0 @@
1
- import "../core/exit-codes.mjs";
2
- //#region src/tag/cli-result.ts
3
- /**
4
- * @since 0.3.16-canary.0
5
- */
6
- function exitCodeForTagSyncResult(result) {
7
- if (result.selectedTargets.length === 0) return 1;
8
- return result.targetResults.some((targetResult) => targetResult.runError !== null) || result.hookError !== null ? 1 : 0;
9
- }
10
- //#endregion
11
- export { exitCodeForTagSyncResult };
@@ -1,15 +0,0 @@
1
- import { z } from "zod";
2
- //#region src/tag/cli-schema.ts
3
- /**
4
- * @since 0.3.16-canary.0
5
- */
6
- const tagSyncRunRequestSchema = z.object({
7
- rootDir: z.string().min(1),
8
- write: z.boolean(),
9
- json: z.boolean().optional(),
10
- targetPath: z.string().optional(),
11
- skipPackages: z.array(z.string()).optional(),
12
- config: z.unknown().optional()
13
- });
14
- //#endregion
15
- export { tagSyncRunRequestSchema };
@@ -1,56 +0,0 @@
1
- import { logger } from "../core/logger.mjs";
2
- import { readOptionalPositionalArg } from "../core/cli/positional.mjs";
3
- import { consumeCliAppError } from "../core/cli/result-handle.mjs";
4
- import { nodeFilesystem } from "../core/filesystem/node.mjs";
5
- import { parseWithSchema } from "../core/schema-parse.mjs";
6
- import { exitCodeForTagSyncResult } from "./cli-result.mjs";
7
- import { tagSyncRunRequestSchema } from "./cli-schema.mjs";
8
- import { TagSyncProgressPresenter, presentTagSyncResult } from "./output.mjs";
9
- import { prepareTagSync } from "./prepare.mjs";
10
- import { runTagSync } from "./sync.mjs";
11
- import process from "node:process";
12
- import { Command } from "commander";
13
- //#region src/tag/command.ts
14
- /**
15
- * @since 0.3.16-canary.0
16
- */
17
- function createTagCommand() {
18
- return new Command("tag").description("Add @since <version> JSDoc tags to exported declarations").argument("[target]", "Directory or file to tag (default: auto-discover workspace packages)").option("--dry-run", "Show summary without writing files", false).option("--json", "Print one JSON summary on stdout (suppresses human progress)", false).action(async (target, opts) => {
19
- const prelude = await prepareTagSync(nodeFilesystem, {
20
- currentWorkingDirectory: process.cwd(),
21
- rawTarget: readOptionalPositionalArg(target)
22
- });
23
- if (!consumeCliAppError(prelude)) return;
24
- const { rootDir, config, resolvedTargetPath } = prelude.value;
25
- const tagConfig = config.tag ?? {};
26
- const parsed = parseWithSchema(tagSyncRunRequestSchema, {
27
- rootDir,
28
- write: !opts.dryRun,
29
- json: opts.json,
30
- targetPath: resolvedTargetPath,
31
- skipPackages: tagConfig.skipPackages,
32
- config: tagConfig
33
- });
34
- if (!consumeCliAppError(parsed)) return;
35
- const progressPresenter = new TagSyncProgressPresenter();
36
- const tagOutcome = await runTagSync(nodeFilesystem, {
37
- ...parsed.value,
38
- listener: parsed.value.json ? void 0 : progressPresenter
39
- });
40
- if (!consumeCliAppError(tagOutcome)) return;
41
- if (parsed.value.json) {
42
- logger.out(formatTagSyncJsonOutput(tagOutcome.value, rootDir));
43
- process.exitCode = exitCodeForTagSyncResult(tagOutcome.value);
44
- } else process.exitCode = presentTagSyncResult(tagOutcome.value, rootDir);
45
- });
46
- }
47
- function formatTagSyncJsonOutput(result, rootDir) {
48
- return JSON.stringify({
49
- schemaVersion: 1,
50
- ok: result.hookError === null,
51
- cwd: rootDir,
52
- result
53
- });
54
- }
55
- //#endregion
56
- export { createTagCommand };
@@ -1 +0,0 @@
1
- export {};
@@ -1,87 +0,0 @@
1
- import { logger } from "../core/logger.mjs";
2
- import "../core/exit-codes.mjs";
3
- import { exitCodeForTagSyncResult } from "./cli-result.mjs";
4
- //#region src/tag/output.ts
5
- /**
6
- * @since 0.3.16-canary.0
7
- */
8
- var TagSyncProgressPresenter = class TagSyncProgressPresenter {
9
- onTargetStarted(target) {
10
- logger.out(TagSyncProgressPresenter.formatProgress({
11
- type: "target-started",
12
- target
13
- }));
14
- }
15
- onTargetCompleted(target, result) {
16
- logger.out(TagSyncProgressPresenter.formatProgress({
17
- type: "target-completed",
18
- target,
19
- result
20
- }));
21
- }
22
- static formatProgress(event) {
23
- const targetDisplayName = (target) => target.packageName ?? target.rootRelativeTargetPath;
24
- if (event.type === "target-started") return `[tag] Processing ${targetDisplayName(event.target)}...`;
25
- const changedFiles = event.result.result?.filesChanged ?? 0;
26
- return `[tag] Done ${targetDisplayName(event.target)} (${changedFiles} changes)`;
27
- }
28
- };
29
- const colorReset = "\x1B[0m";
30
- const colors = {
31
- red: "\x1B[31m",
32
- green: "\x1B[32m",
33
- yellow: "\x1B[33m"
34
- };
35
- /**
36
- * @since 0.3.16-canary.0
37
- */
38
- function presentTagSyncResult(result, rootDir) {
39
- logger.out(formatTargetTable(result.selectedTargets, rootDir));
40
- if (result.selectedTargets.length === 0) {
41
- logger.err("No packages found in workspace. Check your pnpm-workspace.yaml or provide an explicit target path.");
42
- return 1;
43
- }
44
- const warningsAndErrorsSection = formatWarningsAndErrors(result);
45
- if (warningsAndErrorsSection) logger.err(warningsAndErrorsSection);
46
- logger.out(formatSummary(result));
47
- return exitCodeForTagSyncResult(result);
48
- }
49
- function withColorizedLine(line, colorCode) {
50
- return `${colorCode}${line}${colorReset}`;
51
- }
52
- function warningsAndErrorsFromResult(result) {
53
- const entries = [];
54
- for (const targetResult of result.targetResults) if (targetResult.runError) entries.push(targetResult.runError);
55
- if (result.hookError) entries.push(result.hookError);
56
- return entries;
57
- }
58
- function formatTargetTable(targets, rootDir) {
59
- const packageColumnWidth = Math.max(7, ...targets.map((target) => (target.packageName ?? "-").length));
60
- const pathColumnWidth = Math.max(4, ...targets.map((target) => target.rootRelativeTargetPath.length));
61
- const lines = [];
62
- lines.push(`[tag] Root: ${rootDir}`);
63
- lines.push(`[tag] Resolved targets: ${targets.length}`);
64
- lines.push("[tag] Targets:");
65
- lines.push(` ${"package".padEnd(packageColumnWidth)} ${"path".padEnd(pathColumnWidth)} source`);
66
- lines.push(` ${"-".repeat(packageColumnWidth)} ${"-".repeat(pathColumnWidth)} ${"-".repeat(6)}`);
67
- for (const target of targets) lines.push(` ${(target.packageName ?? "-").padEnd(packageColumnWidth)} ${target.rootRelativeTargetPath.padEnd(pathColumnWidth)} ${target.source}`);
68
- return lines.join("\n");
69
- }
70
- function formatWarningsAndErrors(result) {
71
- const entries = warningsAndErrorsFromResult(result);
72
- if (entries.length === 0) return null;
73
- const lines = [withColorizedLine("⚠️ Warnings & Errors", colors.yellow)];
74
- for (const entry of entries) lines.push(withColorizedLine(`- ${entry}`, colors.red));
75
- return lines.join("\n");
76
- }
77
- function formatSummary(result) {
78
- const isDryRun = result.mode === "dry-run";
79
- const summaryPrefix = isDryRun ? "[tag:dry-run]" : "[tag]";
80
- const versionSuffix = result.versionSummary === "mixed" && result.distinctVersions.length > 0 ? ` [${result.distinctVersions.join(", ")}]` : "";
81
- const summaryColor = result.targetResults.some((targetResult) => targetResult.runError !== null) || result.hookError !== null ? colors.red : isDryRun ? colors.yellow : colors.green;
82
- const lines = [withColorizedLine(`${summaryPrefix} version=${result.versionSummary}${versionSuffix} files=${result.filesChanged}/${result.filesScanned} declarations=${result.taggedDeclarations}`, summaryColor)];
83
- if (result.skippedPackages.length > 0) lines.push(`[tag] Skipped: ${result.skippedPackages.length} package(s)`);
84
- return lines.join("\n");
85
- }
86
- //#endregion
87
- export { TagSyncProgressPresenter, presentTagSyncResult };
@@ -1,29 +0,0 @@
1
- import { ok } from "../core/result.mjs";
2
- import { loadCodefastConfig } from "../core/config.mjs";
3
- import { findRepoRoot } from "../core/workspace/resolver.mjs";
4
- import { resolveProvidedTagTargetPath } from "./resolve-target-path.mjs";
5
- //#region src/tag/prepare.ts
6
- /**
7
- * @since 0.3.16-canary.0
8
- */
9
- async function prepareTagSync(fs, args) {
10
- let rootDir;
11
- try {
12
- rootDir = findRepoRoot(args.currentWorkingDirectory, fs);
13
- } catch {
14
- rootDir = args.currentWorkingDirectory;
15
- }
16
- const loadedOutcome = await loadCodefastConfig(rootDir, fs);
17
- if (!loadedOutcome.ok) return loadedOutcome;
18
- const resolvedTargetPath = resolveProvidedTagTargetPath(fs, {
19
- currentWorkingDirectory: args.currentWorkingDirectory,
20
- rawTarget: args.rawTarget
21
- });
22
- return ok({
23
- rootDir,
24
- config: loadedOutcome.value.config,
25
- resolvedTargetPath
26
- });
27
- }
28
- //#endregion
29
- export { prepareTagSync };
@@ -1,12 +0,0 @@
1
- import path from "node:path";
2
- //#region src/tag/resolve-target-path.ts
3
- /**
4
- * @since 0.3.16-canary.0
5
- */
6
- function resolveProvidedTagTargetPath(fs, args) {
7
- if (args.rawTarget === void 0) return;
8
- const candidate = path.isAbsolute(args.rawTarget) ? path.resolve(args.rawTarget) : path.resolve(args.currentWorkingDirectory, args.rawTarget);
9
- return fs.canonicalPathSync(candidate);
10
- }
11
- //#endregion
12
- export { resolveProvidedTagTargetPath };
@@ -1,131 +0,0 @@
1
- import { applyEditsDescending, indentOfLineContaining } from "../core/source-text-edit.mjs";
2
- import ts from "typescript";
3
- //#region src/tag/since-writer.ts
4
- /**
5
- * @since 0.3.16-canary.0
6
- */
7
- var TagSinceWriter = class {
8
- fs;
9
- sinceDocumentationTag = "@since";
10
- constructor(fs) {
11
- this.fs = fs;
12
- }
13
- applySinceTagsToFile(filePath, version, write) {
14
- const sourceText = this.fs.readFileSync(filePath, "utf8");
15
- const sf = ts.createSourceFile(filePath, sourceText, ts.ScriptTarget.Latest, true, filePath.endsWith(".tsx") ? ts.ScriptKind.TSX : ts.ScriptKind.TS);
16
- const edits = [];
17
- for (const declaration of this.collectExportedDeclarations(sf)) {
18
- const edit = this.makeDeclarationSinceLine(declaration, sf, sourceText, version);
19
- if (edit) edits.push(edit);
20
- }
21
- if (edits.length > 0 && write) {
22
- const updated = applyEditsDescending(sourceText, edits);
23
- this.fs.writeFileSync(filePath, updated, "utf8");
24
- }
25
- return {
26
- filePath,
27
- taggedDeclarations: edits.length,
28
- changed: edits.length > 0
29
- };
30
- }
31
- hasExportModifier(node) {
32
- return (ts.canHaveModifiers(node) ? ts.getModifiers(node) : void 0)?.some((modifier) => modifier.kind === ts.SyntaxKind.ExportKeyword) ?? false;
33
- }
34
- isTaggableDeclaration(node) {
35
- return ts.isFunctionDeclaration(node) || ts.isClassDeclaration(node) || ts.isInterfaceDeclaration(node) || ts.isTypeAliasDeclaration(node) || ts.isEnumDeclaration(node) || ts.isVariableStatement(node);
36
- }
37
- addDeclarationName(registry, name, declaration) {
38
- if (!registry.has(name)) {
39
- registry.set(name, /* @__PURE__ */ new Set([declaration]));
40
- return;
41
- }
42
- const bucket = registry.get(name);
43
- if (bucket === void 0) throw new Error(`declaration registry missing set for ${name}`);
44
- bucket.add(declaration);
45
- }
46
- collectLocalNamedDeclarations(sf) {
47
- const declarations = /* @__PURE__ */ new Map();
48
- for (const statement of sf.statements) {
49
- if (ts.isFunctionDeclaration(statement) && statement.name) {
50
- this.addDeclarationName(declarations, statement.name.text, statement);
51
- continue;
52
- }
53
- if (ts.isClassDeclaration(statement) && statement.name) {
54
- this.addDeclarationName(declarations, statement.name.text, statement);
55
- continue;
56
- }
57
- if (ts.isInterfaceDeclaration(statement)) {
58
- this.addDeclarationName(declarations, statement.name.text, statement);
59
- continue;
60
- }
61
- if (ts.isTypeAliasDeclaration(statement)) {
62
- this.addDeclarationName(declarations, statement.name.text, statement);
63
- continue;
64
- }
65
- if (ts.isEnumDeclaration(statement)) {
66
- this.addDeclarationName(declarations, statement.name.text, statement);
67
- continue;
68
- }
69
- if (!ts.isVariableStatement(statement)) continue;
70
- for (const declaration of statement.declarationList.declarations) if (ts.isIdentifier(declaration.name)) this.addDeclarationName(declarations, declaration.name.text, statement);
71
- }
72
- return declarations;
73
- }
74
- collectExportedDeclarations(sf) {
75
- const exported = /* @__PURE__ */ new Set();
76
- const localNamed = this.collectLocalNamedDeclarations(sf);
77
- for (const statement of sf.statements) {
78
- if (this.isTaggableDeclaration(statement) && this.hasExportModifier(statement)) {
79
- exported.add(statement);
80
- continue;
81
- }
82
- if (ts.isExportDeclaration(statement) && !statement.moduleSpecifier && statement.exportClause && ts.isNamedExports(statement.exportClause)) {
83
- for (const element of statement.exportClause.elements) {
84
- const localName = element.propertyName?.text ?? element.name.text;
85
- const declarations = localNamed.get(localName);
86
- if (!declarations) continue;
87
- for (const declaration of declarations) exported.add(declaration);
88
- }
89
- continue;
90
- }
91
- if (!ts.isExportAssignment(statement) || !ts.isIdentifier(statement.expression)) continue;
92
- const declarations = localNamed.get(statement.expression.text);
93
- if (!declarations) continue;
94
- for (const declaration of declarations) exported.add(declaration);
95
- }
96
- return exported;
97
- }
98
- makeJSDocSinceLine(existingComment, sourceText, version) {
99
- const commentText = sourceText.slice(existingComment.pos, existingComment.end);
100
- const baseIndent = indentOfLineContaining(sourceText, existingComment.pos);
101
- const normalizedBodyLines = commentText.replace(/^\/\*\*\s?/, "").replace(/\s*\*\/$/, "").split("\n").map((line) => line.replace(/^\s*\*\s?/, "").replace(/\s+$/, "")).filter((line, lineIndex, lines) => {
102
- if (line.length > 0) return true;
103
- const hasNonEmptyBefore = lines.slice(0, lineIndex).some((value) => value.length > 0);
104
- const hasNonEmptyAfter = lines.slice(lineIndex + 1).some((value) => value.length > 0);
105
- return hasNonEmptyBefore && hasNonEmptyAfter;
106
- });
107
- const replacement = `/**\n${normalizedBodyLines.length > 0 ? `${normalizedBodyLines.map((line) => line.length > 0 ? `${baseIndent} * ${line}` : `${baseIndent} *`).join("\n")}\n${baseIndent} *\n` : ""}${baseIndent} * ${this.sinceDocumentationTag} ${version}\n${baseIndent} */`;
108
- return {
109
- start: existingComment.pos,
110
- end: existingComment.end,
111
- replacement
112
- };
113
- }
114
- makeSinceOnlyJSDocBlock(declarationIndent, version) {
115
- return `/**\n${declarationIndent} * ${this.sinceDocumentationTag} ${version}\n${declarationIndent} */`;
116
- }
117
- makeDeclarationSinceLine(declaration, sf, sourceText, version) {
118
- if (ts.getJSDocTags(declaration).some((tag) => tag.tagName.text === "since")) return;
119
- const lastJsDoc = ts.getJSDocCommentsAndTags(declaration).filter(ts.isJSDoc).at(-1);
120
- if (lastJsDoc) return this.makeJSDocSinceLine(lastJsDoc, sourceText, version);
121
- const start = declaration.getStart(sf);
122
- const indent = indentOfLineContaining(sourceText, start);
123
- return {
124
- start,
125
- end: start,
126
- replacement: `${indent}${this.makeSinceOnlyJSDocBlock(indent, version)}\n${indent}`
127
- };
128
- }
129
- };
130
- //#endregion
131
- export { TagSinceWriter };