@codefast/cli 0.3.15 → 0.3.16-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 (209) hide show
  1. package/README.md +1 -1
  2. package/dist/arrange/analyze.mjs +24 -0
  3. package/dist/{domains/arrange/presentation/presenters/arrange-cli.schema.mjs → arrange/cli-schema.mjs} +10 -1
  4. package/dist/arrange/command.mjs +106 -0
  5. package/dist/{domains/arrange/domain/arrange-analyze.domain-service.mjs → arrange/domain/analyze-service.mjs} +17 -10
  6. package/dist/{domains/arrange/domain/ast/ast-node.model.mjs → arrange/domain/ast/ast-node.mjs} +57 -3
  7. package/dist/{domains/arrange/domain/ast/collectors-cn.collector.mjs → arrange/domain/ast/collectors-cn.mjs} +21 -9
  8. package/dist/{domains/arrange/domain/ast/collectors-jsx.collector.mjs → arrange/domain/ast/collectors-jsx.mjs} +5 -2
  9. package/dist/{domains/arrange/domain/ast/collectors-tv.collector.mjs → arrange/domain/ast/collectors-tv.mjs} +21 -6
  10. package/dist/{domains/arrange/domain/ast/ast-helpers.helper.mjs → arrange/domain/ast/helpers.mjs} +26 -9
  11. package/dist/{domains/arrange/domain/ast/targets.model.mjs → arrange/domain/ast/targets.mjs} +19 -10
  12. package/dist/{domains/arrange/domain/constants.domain.mjs → arrange/domain/constants.mjs} +63 -18
  13. package/dist/{domains/arrange/domain/arrange-grouping.domain-service.mjs → arrange/domain/grouping-service.mjs} +31 -10
  14. package/dist/{domains/arrange/domain/grouping.domain.mjs → arrange/domain/grouping.mjs} +39 -18
  15. package/dist/{domains/arrange/domain/imports.domain.mjs → arrange/domain/imports.mjs} +7 -3
  16. package/dist/{domains/arrange/domain/source-text-formatters.formatter.mjs → arrange/domain/source-text-formatters.mjs} +22 -5
  17. package/dist/{domains/arrange/domain/tailwind-token.value-object.mjs → arrange/domain/tailwind-token.mjs} +12 -3
  18. package/dist/{domains/arrange/domain/tailwind-token-classifier.domain-service.mjs → arrange/domain/token-classifier.mjs} +40 -15
  19. package/dist/arrange/output.mjs +79 -0
  20. package/dist/arrange/process-file.mjs +42 -0
  21. package/dist/arrange/resolve-target.mjs +24 -0
  22. package/dist/arrange/scan-target.mjs +20 -0
  23. package/dist/arrange/source-parse.mjs +18 -0
  24. package/dist/arrange/suggest.mjs +15 -0
  25. package/dist/arrange/sync.mjs +51 -0
  26. package/dist/arrange/typescript-ast-translator.mjs +354 -0
  27. package/dist/arrange/workspace.mjs +31 -0
  28. package/dist/bin.mjs +1 -1
  29. package/dist/{program.mjs → cli.mjs} +14 -20
  30. package/dist/core/cli/format-error.mjs +15 -0
  31. package/dist/core/cli/global-options.mjs +10 -0
  32. package/dist/core/cli/positional.mjs +11 -0
  33. package/dist/core/cli/result-handle.mjs +51 -0
  34. package/dist/core/config/loader.mjs +79 -0
  35. package/dist/{domains/config/domain/codefast-config.schema.mjs → core/config/schema.mjs} +16 -2
  36. package/dist/core/config/warnings.mjs +12 -0
  37. package/dist/core/config.mjs +19 -0
  38. package/dist/{shell/domain/caught-unknown-message.value-object.mjs → core/errors.mjs} +20 -4
  39. package/dist/core/exit-codes.mjs +17 -0
  40. package/dist/core/filesystem/node.mjs +32 -0
  41. package/dist/core/logger.mjs +15 -0
  42. package/dist/{shell/domain/result.model.mjs → core/result.mjs} +7 -3
  43. package/dist/core/schema-parse.mjs +18 -0
  44. package/dist/{shell/domain/source-text-edit.support.mjs → core/source-text-edit.mjs} +14 -13
  45. package/dist/core/verbose-diagnostics.mjs +11 -0
  46. package/dist/core/workspace/resolver.mjs +177 -0
  47. package/dist/core/workspace/typescript-walk.mjs +36 -0
  48. package/dist/{domains/mirror/application/mirror-sync-cli-result.mjs → mirror/cli-result.mjs} +8 -2
  49. package/dist/{domains/mirror/presentation/presenters/mirror-cli.schema.mjs → mirror/cli-schema.mjs} +4 -1
  50. package/dist/mirror/command.mjs +57 -0
  51. package/dist/mirror/dist-filesystem-impl.mjs +42 -0
  52. package/dist/{domains/mirror/domain/constants.domain.mjs → mirror/domain/constants.mjs} +16 -1
  53. package/dist/{domains/mirror/infrastructure/guards/dirent-list.guard.mjs → mirror/domain/dirent-guard.mjs} +5 -2
  54. package/dist/{domains/mirror/domain/errors.domain.mjs → mirror/domain/errors.mjs} +7 -1
  55. package/dist/{domains/mirror/domain/generate-mirror-exports.domain-service.mjs → mirror/domain/exports.mjs} +17 -10
  56. package/dist/{domains/mirror/domain/package-display-name.policy.mjs → mirror/domain/package-display-name.mjs} +5 -2
  57. package/dist/{domains/mirror/domain/path-normalizer.value-object.mjs → mirror/domain/path-normalizer.mjs} +4 -1
  58. package/dist/mirror/output.mjs +45 -0
  59. package/dist/mirror/package-path.mjs +32 -0
  60. package/dist/mirror/prepare.mjs +33 -0
  61. package/dist/mirror/sync-reporter.mjs +104 -0
  62. package/dist/mirror/sync-workspace-package.mjs +103 -0
  63. package/dist/mirror/sync.mjs +87 -0
  64. package/dist/{domains/mirror/infrastructure/package-json-exports.repository.mjs → mirror/write-exports.mjs} +11 -7
  65. package/dist/tag/cli-result.mjs +11 -0
  66. package/dist/{domains/tag/presentation/presenters/tag-cli.schema.mjs → tag/cli-schema.mjs} +4 -1
  67. package/dist/tag/command.mjs +56 -0
  68. package/dist/tag/output.mjs +87 -0
  69. package/dist/tag/prepare.mjs +29 -0
  70. package/dist/tag/resolve-target-path.mjs +12 -0
  71. package/dist/tag/since-writer.mjs +130 -0
  72. package/dist/tag/sync.mjs +141 -0
  73. package/dist/tag/target-candidates.mjs +68 -0
  74. package/dist/tag/target-runner.mjs +26 -0
  75. package/dist/tag/version-resolver.mjs +25 -0
  76. package/package.json +4 -7
  77. package/dist/bootstrap/cli-application.module.mjs +0 -18
  78. package/dist/bootstrap/composition-root.mjs +0 -14
  79. package/dist/bootstrap/register-cli-command-trees.mjs +0 -7
  80. package/dist/domains/arrange/application/ports/outbound/arrange-target-scanner.port.mjs +0 -1
  81. package/dist/domains/arrange/application/ports/outbound/domain-source-parser.port.mjs +0 -1
  82. package/dist/domains/arrange/application/ports/outbound/file-walker.port.mjs +0 -1
  83. package/dist/domains/arrange/application/ports/presenting/present-analyze-report.presenter.mjs +0 -1
  84. package/dist/domains/arrange/application/ports/presenting/present-arrange-sync-result.presenter.mjs +0 -1
  85. package/dist/domains/arrange/application/ports/presenting/present-group-file-preview.presenter.mjs +0 -1
  86. package/dist/domains/arrange/application/requests/analyze-directory.request.mjs +0 -1
  87. package/dist/domains/arrange/application/requests/arrange-sync.request.mjs +0 -1
  88. package/dist/domains/arrange/application/requests/suggest-groups.request.mjs +0 -1
  89. package/dist/domains/arrange/application/use-cases/analyze-directory.use-case.mjs +0 -255
  90. package/dist/domains/arrange/application/use-cases/prepare-arrange-workspace.use-case.mjs +0 -264
  91. package/dist/domains/arrange/application/use-cases/run-arrange-sync.use-case.mjs +0 -274
  92. package/dist/domains/arrange/application/use-cases/suggest-cn-groups.use-case.mjs +0 -237
  93. package/dist/domains/arrange/arrange.module.mjs +0 -38
  94. package/dist/domains/arrange/composition/tokens.mjs +0 -17
  95. package/dist/domains/arrange/contracts/models.mjs +0 -1
  96. package/dist/domains/arrange/domain/tailwind-grouping.domain-service.mjs +0 -231
  97. package/dist/domains/arrange/domain/types.domain.mjs +0 -1
  98. package/dist/domains/arrange/infrastructure/adapters/arrange-file-processor.adapter.mjs +0 -267
  99. package/dist/domains/arrange/infrastructure/adapters/arrange-target-path-resolver.adapter.mjs +0 -247
  100. package/dist/domains/arrange/infrastructure/adapters/arrange-target-scanner.adapter.mjs +0 -243
  101. package/dist/domains/arrange/infrastructure/adapters/domain-source-parser.adapter.mjs +0 -241
  102. package/dist/domains/arrange/infrastructure/adapters/file-walker.adapter.mjs +0 -240
  103. package/dist/domains/arrange/infrastructure/typescript-ast-translator.mjs +0 -580
  104. package/dist/domains/arrange/presentation/cli/arrange.command.mjs +0 -465
  105. package/dist/domains/arrange/presentation/presenters/arrange-analyze.presenter.mjs +0 -252
  106. package/dist/domains/arrange/presentation/presenters/arrange-sync.presenter.mjs +0 -236
  107. package/dist/domains/arrange/presentation/presenters/group-file-preview.presenter.mjs +0 -271
  108. package/dist/domains/config/application/ports/outbound/codefast-config-schema.port.mjs +0 -1
  109. package/dist/domains/config/application/ports/outbound/config-loader.port.mjs +0 -1
  110. package/dist/domains/config/application/ports/outbound/config-warning-reporter.port.mjs +0 -1
  111. package/dist/domains/config/composition/tokens.mjs +0 -7
  112. package/dist/domains/config/domain/schema.domain.mjs +0 -1
  113. package/dist/domains/config/infrastructure/adapters/config-loader.adapter.mjs +0 -305
  114. package/dist/domains/config/infrastructure/adapters/config-warning-reporter.adapter.mjs +0 -234
  115. package/dist/domains/config/infrastructure/adapters/zod-codefast-config-schema.adapter.mjs +0 -236
  116. package/dist/domains/mirror/application/ports/inbound/prepare-mirror-sync.port.mjs +0 -1
  117. package/dist/domains/mirror/application/ports/inbound/run-mirror-sync.port.mjs +0 -1
  118. package/dist/domains/mirror/application/ports/outbound/file-system-service.port.mjs +0 -1
  119. package/dist/domains/mirror/application/ports/outbound/mirror-package-path.port.mjs +0 -1
  120. package/dist/domains/mirror/application/ports/outbound/mirror-sync-reporter.port.mjs +0 -1
  121. package/dist/domains/mirror/application/ports/outbound/package-repository.port.mjs +0 -1
  122. package/dist/domains/mirror/application/ports/outbound/sync-workspace-package.port.mjs +0 -1
  123. package/dist/domains/mirror/application/ports/presenting/present-mirror-sync-progress.presenter.mjs +0 -1
  124. package/dist/domains/mirror/application/requests/mirror-sync-execution-input.mjs +0 -1
  125. package/dist/domains/mirror/application/requests/mirror-sync.request.mjs +0 -1
  126. package/dist/domains/mirror/application/use-cases/prepare-mirror-sync.use-case.mjs +0 -263
  127. package/dist/domains/mirror/application/use-cases/run-mirror-sync.use-case.mjs +0 -317
  128. package/dist/domains/mirror/composition/tokens.mjs +0 -12
  129. package/dist/domains/mirror/contracts/models.mjs +0 -1
  130. package/dist/domains/mirror/domain/types.domain.mjs +0 -1
  131. package/dist/domains/mirror/infrastructure/adapters/file-system-service.adapter.mjs +0 -261
  132. package/dist/domains/mirror/infrastructure/adapters/mirror-package-path-resolver.adapter.mjs +0 -252
  133. package/dist/domains/mirror/infrastructure/adapters/mirror-sync-reporter.adapter.mjs +0 -322
  134. package/dist/domains/mirror/infrastructure/adapters/package-repository.adapter.mjs +0 -241
  135. package/dist/domains/mirror/infrastructure/adapters/sync-workspace-package.adapter.mjs +0 -328
  136. package/dist/domains/mirror/mirror.module.mjs +0 -26
  137. package/dist/domains/mirror/presentation/cli/mirror.command.mjs +0 -328
  138. package/dist/domains/mirror/presentation/presenters/present-mirror-sync-progress.presenter.mjs +0 -265
  139. package/dist/domains/tag/application/ports/inbound/prepare-tag-sync.port.mjs +0 -1
  140. package/dist/domains/tag/application/ports/inbound/run-tag-sync.port.mjs +0 -1
  141. package/dist/domains/tag/application/ports/outbound/tag-eligible-workspace-paths.port.mjs +0 -1
  142. package/dist/domains/tag/application/ports/outbound/tag-since-writer.port.mjs +0 -1
  143. package/dist/domains/tag/application/ports/outbound/tag-target-path-resolver.port.mjs +0 -1
  144. package/dist/domains/tag/application/ports/outbound/tag-target-runner.port.mjs +0 -1
  145. package/dist/domains/tag/application/ports/outbound/tag-version-resolver.port.mjs +0 -1
  146. package/dist/domains/tag/application/ports/presenting/present-tag-sync-progress.presenter.mjs +0 -1
  147. package/dist/domains/tag/application/ports/presenting/present-tag-sync-result.presenter.mjs +0 -1
  148. package/dist/domains/tag/application/requests/tag-sync-execution-input.mjs +0 -1
  149. package/dist/domains/tag/application/requests/tag-sync.request.mjs +0 -1
  150. package/dist/domains/tag/application/tag-sync-cli-result.mjs +0 -11
  151. package/dist/domains/tag/application/use-cases/prepare-tag-sync.use-case.mjs +0 -260
  152. package/dist/domains/tag/application/use-cases/run-tag-sync.use-case.mjs +0 -375
  153. package/dist/domains/tag/composition/tokens.mjs +0 -13
  154. package/dist/domains/tag/contracts/models.mjs +0 -1
  155. package/dist/domains/tag/domain/types.domain.mjs +0 -1
  156. package/dist/domains/tag/infrastructure/adapters/tag-since-writer.adapter.mjs +0 -348
  157. package/dist/domains/tag/infrastructure/adapters/tag-target-path-resolver.adapter.mjs +0 -235
  158. package/dist/domains/tag/infrastructure/adapters/tag-target-resolver.adapter.mjs +0 -302
  159. package/dist/domains/tag/infrastructure/adapters/tag-target-runner.adapter.mjs +0 -259
  160. package/dist/domains/tag/infrastructure/adapters/tag-version-resolver.adapter.mjs +0 -249
  161. package/dist/domains/tag/presentation/cli/tag.command.mjs +0 -325
  162. package/dist/domains/tag/presentation/presenters/present-tag-sync-progress.presenter.mjs +0 -248
  163. package/dist/domains/tag/presentation/presenters/present-tag-sync-result.presenter.mjs +0 -290
  164. package/dist/domains/tag/tag.module.mjs +0 -28
  165. package/dist/shell/application/cli-runtime.tokens.mjs +0 -18
  166. package/dist/shell/application/coordination/cli-executor.coordination.mjs +0 -1
  167. package/dist/shell/application/coordination/cli-schema-parsing.coordination.mjs +0 -1
  168. package/dist/shell/application/global-cli-options.model.mjs +0 -5
  169. package/dist/shell/application/ports/inbound/load-codefast-config.port.mjs +0 -1
  170. package/dist/shell/application/ports/outbound/cli-fs.port.mjs +0 -1
  171. package/dist/shell/application/ports/outbound/cli-logger.port.mjs +0 -1
  172. package/dist/shell/application/ports/outbound/cli-path.port.mjs +0 -1
  173. package/dist/shell/application/ports/outbound/cli-runtime.port.mjs +0 -1
  174. package/dist/shell/application/ports/outbound/cli-telemetry.port.mjs +0 -1
  175. package/dist/shell/application/ports/outbound/cli-verbose-diagnostics.port.mjs +0 -1
  176. package/dist/shell/application/ports/outbound/format-app-error.port.mjs +0 -1
  177. package/dist/shell/application/ports/outbound/global-cli-options-parse.port.mjs +0 -1
  178. package/dist/shell/application/ports/outbound/repo-root-resolver.port.mjs +0 -1
  179. package/dist/shell/application/ports/outbound/typescript-source-file-walker.port.mjs +0 -1
  180. package/dist/shell/application/ports/outbound/workspace-package-layout.port.mjs +0 -1
  181. package/dist/shell/application/ports/primary/command.port.mjs +0 -1
  182. package/dist/shell/application/services/cli-executor.service.mjs +0 -267
  183. package/dist/shell/application/services/schema-validator.service.mjs +0 -236
  184. package/dist/shell/application/use-cases/load-codefast-config.use-case.mjs +0 -243
  185. package/dist/shell/composition/tokens.mjs +0 -5
  186. package/dist/shell/contracts/cli-command-slots.mjs +0 -11
  187. package/dist/shell/domain/cli-exit-codes.domain.mjs +0 -11
  188. package/dist/shell/domain/cli-positional-arg.value-object.mjs +0 -6
  189. package/dist/shell/domain/errors.domain.mjs +0 -17
  190. package/dist/shell/infrastructure/adapters/cli-verbose-diagnostics.adapter.mjs +0 -228
  191. package/dist/shell/infrastructure/adapters/format-app-error.adapter.mjs +0 -236
  192. package/dist/shell/infrastructure/adapters/global-cli-options-parser.adapter.mjs +0 -233
  193. package/dist/shell/infrastructure/adapters/repo-root-resolver.adapter.mjs +0 -244
  194. package/dist/shell/infrastructure/adapters/typescript-source-file-walker.adapter.mjs +0 -259
  195. package/dist/shell/infrastructure/commander/commander-cli-host.adapter.mjs +0 -69
  196. package/dist/shell/infrastructure/node/node-cli-fs.adapter.mjs +0 -249
  197. package/dist/shell/infrastructure/node/node-cli-logger.adapter.mjs +0 -231
  198. package/dist/shell/infrastructure/node/node-cli-path.adapter.mjs +0 -246
  199. package/dist/shell/infrastructure/node/node-cli-runtime.adapter.mjs +0 -234
  200. package/dist/shell/infrastructure/telemetry/cli-telemetry.adapter.mjs +0 -280
  201. package/dist/shell/infrastructure/workspace/node-pnpm-workspace-package-layout.adapter.mjs +0 -385
  202. package/dist/shell/shell.module.mjs +0 -43
  203. package/dist/shell/wiring/optional-cli-port-telemetry-activation.mjs +0 -13
  204. /package/dist/{domains/arrange/application/ports/inbound/analyze-directory.port.mjs → arrange/domain/types.mjs} +0 -0
  205. /package/dist/{domains/arrange/application/ports/inbound/prepare-arrange-workspace.port.mjs → core/filesystem/port.mjs} +0 -0
  206. /package/dist/{domains/arrange/application/ports/inbound/run-arrange-sync.port.mjs → mirror/domain/dist-filesystem.mjs} +0 -0
  207. /package/dist/{domains/arrange/application/ports/inbound/suggest-cn-groups.port.mjs → mirror/domain/types.mjs} +0 -0
  208. /package/dist/{domains/arrange/application/ports/outbound/arrange-file-processor.port.mjs → mirror/sync-types.mjs} +0 -0
  209. /package/dist/{domains/arrange/application/ports/outbound/arrange-target-path-resolver.port.mjs → tag/domain/types.mjs} +0 -0
@@ -0,0 +1,36 @@
1
+ import path from "node:path";
2
+ //#region src/core/workspace/typescript-walk.ts
3
+ const defaultSkipDirectoryNames = new Set([
4
+ "node_modules",
5
+ "dist",
6
+ ".git",
7
+ ".turbo",
8
+ ".next",
9
+ ".cache",
10
+ "out",
11
+ "build",
12
+ "coverage",
13
+ ".vercel",
14
+ ".output"
15
+ ]);
16
+ /**
17
+ * @since 0.3.16-canary.0
18
+ */
19
+ function walkTsxFiles(rootDirectoryPath, fs) {
20
+ const result = [];
21
+ visitTsxPaths(result, rootDirectoryPath, fs);
22
+ return result;
23
+ }
24
+ function visitTsxPaths(result, entryPath, fs) {
25
+ if (fs.statSync(entryPath).isDirectory()) {
26
+ for (const childName of fs.readdirSync(entryPath)) {
27
+ if (defaultSkipDirectoryNames.has(childName)) continue;
28
+ visitTsxPaths(result, path.join(entryPath, childName), fs);
29
+ }
30
+ return;
31
+ }
32
+ if (entryPath.endsWith(".d.ts")) return;
33
+ if (entryPath.endsWith(".tsx") || entryPath.endsWith(".ts")) result.push(entryPath);
34
+ }
35
+ //#endregion
36
+ export { walkTsxFiles };
@@ -1,8 +1,14 @@
1
- import "../../../shell/domain/cli-exit-codes.domain.mjs";
2
- //#region src/domains/mirror/application/mirror-sync-cli-result.ts
1
+ import "../core/exit-codes.mjs";
2
+ //#region src/mirror/cli-result.ts
3
+ /**
4
+ * @since 0.3.16-canary.0
5
+ */
3
6
  function exitCodeForMirrorSyncResult(stats) {
4
7
  return stats.packagesErrored > 0 ? 1 : 0;
5
8
  }
9
+ /**
10
+ * @since 0.3.16-canary.0
11
+ */
6
12
  function formatMirrorSyncJsonOutput(stats, elapsedSeconds) {
7
13
  return JSON.stringify({
8
14
  schemaVersion: 1,
@@ -1,5 +1,8 @@
1
1
  import { z } from "zod";
2
- //#region src/domains/mirror/presentation/presenters/mirror-cli.schema.ts
2
+ //#region src/mirror/cli-schema.ts
3
+ /**
4
+ * @since 0.3.16-canary.0
5
+ */
3
6
  const mirrorSyncRunRequestSchema = z.object({
4
7
  rootDir: z.string().min(1),
5
8
  packageFilter: z.string().optional(),
@@ -0,0 +1,57 @@
1
+ import { parseWithSchema } from "../core/schema-parse.mjs";
2
+ import { logger } from "../core/logger.mjs";
3
+ import { consumeCliAppError } from "../core/cli/result-handle.mjs";
4
+ import { nodeFilesystem } from "../core/filesystem/node.mjs";
5
+ import { readOptionalPositionalArg } from "../core/cli/positional.mjs";
6
+ import { globalCliCommanderOptionsSchema } from "../core/cli/global-options.mjs";
7
+ import { prepareMirrorSync } from "./prepare.mjs";
8
+ import { runMirrorSync } from "./sync.mjs";
9
+ import { mirrorSyncRunRequestSchema } from "./cli-schema.mjs";
10
+ import { exitCodeForMirrorSyncResult, formatMirrorSyncJsonOutput } from "./cli-result.mjs";
11
+ import { MirrorSyncProgressPresenter } from "./output.mjs";
12
+ import process from "node:process";
13
+ import { Command } from "commander";
14
+ //#region src/mirror/command.ts
15
+ /**
16
+ * @since 0.3.16-canary.0
17
+ */
18
+ function createMirrorCommand() {
19
+ const cmd = new Command("mirror").description("Keep package manifests aligned with what you ship");
20
+ cmd.command("sync").description("Write package.json exports from dist/ for workspace packages").argument("[package]", "Optional package path relative to repo root (e.g. packages/ui)").option("-v, --verbose", "Print extra diagnostics", false).option("--json", "Print one JSON summary on stdout (suppresses human progress)", false).action(async (packageArg, opts, command) => {
21
+ const globalOptionsOutcome = parseWithSchema(globalCliCommanderOptionsSchema, command.optsWithGlobals?.() ?? command.opts());
22
+ if (!consumeCliAppError(globalOptionsOutcome)) return;
23
+ const prelude = await prepareMirrorSync(nodeFilesystem, {
24
+ currentWorkingDirectory: process.cwd(),
25
+ packageArg: readOptionalPositionalArg(packageArg),
26
+ globals: globalOptionsOutcome.value
27
+ });
28
+ if (!consumeCliAppError(prelude)) return;
29
+ const { rootDir, config, packageFilter } = prelude.value;
30
+ const parsed = parseWithSchema(mirrorSyncRunRequestSchema, {
31
+ rootDir,
32
+ config: config.mirror ?? {},
33
+ packageFilter
34
+ });
35
+ if (!consumeCliAppError(parsed)) return;
36
+ const json = !!opts.json;
37
+ const noColor = globalOptionsOutcome.value.color === false;
38
+ const verbose = !!opts.verbose;
39
+ const progressPresenter = new MirrorSyncProgressPresenter();
40
+ const listener = json ? void 0 : progressPresenter;
41
+ if (!json) progressPresenter.configure({
42
+ noColor,
43
+ verbose
44
+ });
45
+ const startTime = performance.now();
46
+ const outcome = await runMirrorSync(nodeFilesystem, {
47
+ ...parsed.value,
48
+ listener
49
+ });
50
+ if (!consumeCliAppError(outcome)) return;
51
+ if (json) logger.out(formatMirrorSyncJsonOutput(outcome.value, (performance.now() - startTime) / 1e3));
52
+ process.exitCode = exitCodeForMirrorSyncResult(outcome.value);
53
+ });
54
+ return cmd;
55
+ }
56
+ //#endregion
57
+ export { createMirrorCommand };
@@ -0,0 +1,42 @@
1
+ import { normalizePath } from "./domain/path-normalizer.mjs";
2
+ import { isDirentList } from "./domain/dirent-guard.mjs";
3
+ import path from "node:path";
4
+ //#region src/mirror/dist-filesystem-impl.ts
5
+ /**
6
+ * @since 0.3.16-canary.0
7
+ */
8
+ function createMirrorDistFilesystem(fs) {
9
+ return {
10
+ async listRelativeFilesRecursively(dirPath) {
11
+ try {
12
+ const raw = await fs.readdir(dirPath, {
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(dirPath, fullPath));
20
+ });
21
+ } catch (caughtError) {
22
+ if (isKnownReadDirError(caughtError)) return [];
23
+ throw caughtError;
24
+ }
25
+ },
26
+ async isDirectoryCssOnly(distDir, dirPath) {
27
+ try {
28
+ const raw = await fs.readdir(path.join(distDir, dirPath), { withFileTypes: true });
29
+ if (!isDirentList(raw)) return false;
30
+ if (raw.length === 0) return true;
31
+ return raw.every((dirent) => dirent.isFile() && dirent.name.endsWith(".css"));
32
+ } catch {
33
+ return false;
34
+ }
35
+ }
36
+ };
37
+ }
38
+ function isKnownReadDirError(caughtError) {
39
+ return typeof caughtError === "object" && caughtError !== null && "code" in caughtError && (caughtError.code === "ENOENT" || caughtError.code === "EACCES");
40
+ }
41
+ //#endregion
42
+ export { createMirrorDistFilesystem };
@@ -1,16 +1,31 @@
1
- //#region src/domains/mirror/domain/constants.domain.ts
1
+ //#region src/mirror/domain/constants.ts
2
+ /**
3
+ * @since 0.3.16-canary.0
4
+ */
2
5
  const DIST_DIR = "dist";
6
+ /**
7
+ * @since 0.3.16-canary.0
8
+ */
3
9
  const PACKAGE_JSON = "package.json";
10
+ /**
11
+ * @since 0.3.16-canary.0
12
+ */
4
13
  const VALID_JS_EXTENSIONS = new Set([
5
14
  ".js",
6
15
  ".mjs",
7
16
  ".cjs"
8
17
  ]);
18
+ /**
19
+ * @since 0.3.16-canary.0
20
+ */
9
21
  const VALID_DTS_EXTENSIONS = new Set([
10
22
  ".d.ts",
11
23
  ".d.mts",
12
24
  ".d.cts"
13
25
  ]);
26
+ /**
27
+ * @since 0.3.16-canary.0
28
+ */
14
29
  const PACKAGE_JSON_EXPORT = "./package.json";
15
30
  //#endregion
16
31
  export { DIST_DIR, PACKAGE_JSON, PACKAGE_JSON_EXPORT, VALID_DTS_EXTENSIONS, VALID_JS_EXTENSIONS };
@@ -1,10 +1,13 @@
1
- //#region src/domains/mirror/infrastructure/guards/dirent-list.guard.ts
1
+ //#region src/mirror/domain/dirent-guard.ts
2
2
  /**
3
3
  * Narrow `fs.promises.readdir` overload result to `Dirent[]` when `withFileTypes: true`.
4
4
  * Accepts both historical checks (`isFile` / `isDirectory`) in one guard.
5
5
  * Returning `true` for an empty array is intentional: callers treat empty lists
6
6
  * the same regardless of the element type, so `[]` is safely accepted as `Dirent[]`.
7
- */ function isDirentList(x) {
7
+ *
8
+ * @since 0.3.16-canary.0
9
+ */
10
+ function isDirentList(x) {
8
11
  if (x.length === 0) return true;
9
12
  const first = x[0];
10
13
  return typeof first === "object" && first !== null && "isFile" in first && "isDirectory" in first;
@@ -1,8 +1,14 @@
1
- //#region src/domains/mirror/domain/errors.domain.ts
1
+ //#region src/mirror/domain/errors.ts
2
+ /**
3
+ * @since 0.3.16-canary.0
4
+ */
2
5
  const MirrorErrorCode = {
3
6
  FATAL: "FATAL",
4
7
  PACKAGE_WRITE: "PACKAGE_WRITE"
5
8
  };
9
+ /**
10
+ * @since 0.3.16-canary.0
11
+ */
6
12
  var MirrorError = class extends Error {
7
13
  code;
8
14
  constructor(code, message, options) {
@@ -1,10 +1,11 @@
1
- import { PACKAGE_JSON_EXPORT, VALID_DTS_EXTENSIONS, VALID_JS_EXTENSIONS } from "./constants.domain.mjs";
2
- //#region src/domains/mirror/domain/generate-mirror-exports.domain-service.ts
1
+ import { PACKAGE_JSON_EXPORT, VALID_DTS_EXTENSIONS, VALID_JS_EXTENSIONS } from "./constants.mjs";
2
+ import * as nodePath from "node:path";
3
+ //#region src/mirror/domain/exports.ts
3
4
  function resolvePackageScopedConfig(configMap, pkgMeta) {
4
5
  if (!configMap) return;
5
6
  return configMap[pkgMeta.packageName];
6
7
  }
7
- function groupFilesByModule(files, pathService) {
8
+ function groupFilesByModule(files) {
8
9
  const modules = /* @__PURE__ */ new Map();
9
10
  for (const file of files) {
10
11
  let ext;
@@ -14,11 +15,11 @@ function groupFilesByModule(files, pathService) {
14
15
  ext = dtsExt;
15
16
  modulePath = file.slice(0, -dtsExt.length);
16
17
  } else {
17
- ext = pathService.extname(file);
18
+ ext = nodePath.extname(file);
18
19
  if (!VALID_JS_EXTENSIONS.has(ext)) continue;
19
20
  modulePath = file.slice(0, -ext.length);
20
21
  }
21
- if (!pathService.basename(modulePath)) continue;
22
+ if (!nodePath.basename(modulePath)) continue;
22
23
  let distModule = modules.get(modulePath);
23
24
  if (!distModule) {
24
25
  distModule = {
@@ -103,6 +104,9 @@ function getExportGroup(exportPath, pathTransform) {
103
104
  1
104
105
  ];
105
106
  }
107
+ /**
108
+ * @since 0.3.16-canary.0
109
+ */
106
110
  function createPathTransform(config, pkgMeta) {
107
111
  const pathConfig = resolvePackageScopedConfig(config?.pathTransformations, pkgMeta);
108
112
  if (!pathConfig) return null;
@@ -131,7 +135,7 @@ function compareTuples(left, right) {
131
135
  if (left[3] !== right[3]) return left[3] < right[3] ? -1 : 1;
132
136
  return 0;
133
137
  }
134
- async function generateCssExports(pathService, fileSystemService, distDir, cssConfig) {
138
+ async function generateCssExports(fileSystemService, distDir, cssConfig) {
135
139
  if (cssConfig === false) return {};
136
140
  if (cssConfig === true) cssConfig = { enabled: true };
137
141
  if (!cssConfig || cssConfig.enabled === false) return {};
@@ -141,7 +145,7 @@ async function generateCssExports(pathService, fileSystemService, distDir, cssCo
141
145
  const cssByDir = /* @__PURE__ */ new Map();
142
146
  const rootCss = [];
143
147
  for (const file of cssFiles) {
144
- const dirName = pathService.dirname(file).split(pathService.separator).join("/");
148
+ const dirName = nodePath.dirname(file).split(nodePath.sep).join("/");
145
149
  if (dirName === ".") rootCss.push(file);
146
150
  else {
147
151
  const arr = cssByDir.get(dirName) || [];
@@ -164,7 +168,10 @@ async function generateCssExports(pathService, fileSystemService, distDir, cssCo
164
168
  }
165
169
  /**
166
170
  * Compute `package.json#exports` from a built `dist/` tree. No logging; no writes.
167
- */ async function generateExports(pathService, fileSystemService, distDir, pathTransform, cssConfig, customExports) {
171
+ *
172
+ * @since 0.3.16-canary.0
173
+ */
174
+ async function generateExports(fileSystemService, distDir, pathTransform, cssConfig, customExports) {
168
175
  const files = await fileSystemService.listRelativeFilesRecursively(distDir);
169
176
  if (!files.length) return {
170
177
  exports: { [PACKAGE_JSON_EXPORT]: PACKAGE_JSON_EXPORT },
@@ -172,7 +179,7 @@ async function generateCssExports(pathService, fileSystemService, distDir, cssCo
172
179
  jsCount: 0,
173
180
  cssCount: 0
174
181
  };
175
- const modules = groupFilesByModule(files, pathService);
182
+ const modules = groupFilesByModule(files);
176
183
  const validModules = Array.from(modules.values()).filter((moduleEntry) => (moduleEntry.files.js || moduleEntry.files.mjs) && moduleEntry.files.dts);
177
184
  if (!validModules.length) return {
178
185
  exports: { [PACKAGE_JSON_EXPORT]: PACKAGE_JSON_EXPORT },
@@ -198,7 +205,7 @@ async function generateCssExports(pathService, fileSystemService, distDir, cssCo
198
205
  let sortedKeys = Object.keys(exportsObj).sort((pathA, pathB) => compareTuples(getSortTuple(pathA, pathTransform), getSortTuple(pathB, pathTransform)));
199
206
  const sortedExports = {};
200
207
  for (const exportKey of sortedKeys) sortedExports[exportKey] = exportsObj[exportKey];
201
- const cssExports = await generateCssExports(pathService, fileSystemService, distDir, cssConfig ?? { enabled: true });
208
+ const cssExports = await generateCssExports(fileSystemService, distDir, cssConfig ?? { enabled: true });
202
209
  Object.assign(sortedExports, cssExports);
203
210
  for (const [specifier, mappedPath] of Object.entries(customExports || {})) if (specifier !== "./package.json") sortedExports[specifier] = mappedPath;
204
211
  for (const cssSpecifier of Object.keys(cssExports)) if (!(cssSpecifier in originalPathBySpecifier)) originalPathBySpecifier[cssSpecifier] = cssSpecifier;
@@ -1,7 +1,10 @@
1
- //#region src/domains/mirror/domain/package-display-name.policy.ts
1
+ //#region src/mirror/domain/package-display-name.ts
2
2
  /**
3
3
  * Domain rule: prefer `package.json#name` when it is present, otherwise use folder basename.
4
- */ function resolvePackageDisplayName(packageJson, folderBasename) {
4
+ *
5
+ * @since 0.3.16-canary.0
6
+ */
7
+ function resolvePackageDisplayName(packageJson, folderBasename) {
5
8
  const declaredName = packageJson.name;
6
9
  return typeof declaredName === "string" && declaredName.length > 0 ? declaredName : folderBasename;
7
10
  }
@@ -1,5 +1,8 @@
1
1
  import path from "node:path";
2
- //#region src/domains/mirror/domain/path-normalizer.value-object.ts
2
+ //#region src/mirror/domain/path-normalizer.ts
3
+ /**
4
+ * @since 0.3.16-canary.0
5
+ */
3
6
  function normalizePath(pathString) {
4
7
  return pathString.split(path.sep).join("/").replace(/\\/g, "/");
5
8
  }
@@ -0,0 +1,45 @@
1
+ import { logger } from "../core/logger.mjs";
2
+ import { MirrorSyncReporter } from "./sync-reporter.mjs";
3
+ //#region src/mirror/output.ts
4
+ const cliLogger = logger;
5
+ /**
6
+ * @since 0.3.16-canary.0
7
+ */
8
+ var MirrorSyncProgressPresenter = class {
9
+ reporter = new MirrorSyncReporter();
10
+ verbose = false;
11
+ configure(options) {
12
+ this.verbose = options.verbose;
13
+ this.reporter.configureMirrorColors(options.noColor);
14
+ }
15
+ onBanner() {
16
+ this.reporter.mirrorBanner(cliLogger);
17
+ }
18
+ onProcessingMode(mode) {
19
+ this.reporter.mirrorProcessingMode(cliLogger, mode);
20
+ }
21
+ onNoPackages() {
22
+ this.reporter.mirrorNoPackages(cliLogger);
23
+ }
24
+ onPackageComplete(pkgStats, ordinal, total) {
25
+ if (pkgStats.skipped) {
26
+ this.reporter.logSkippedWorkspacePackage(cliLogger, ordinal, total, pkgStats.name, pkgStats.skipReason);
27
+ return;
28
+ }
29
+ if (pkgStats.error !== null) {
30
+ this.reporter.logPackageError(cliLogger, ordinal, total, pkgStats.name, pkgStats.error, this.verbose);
31
+ return;
32
+ }
33
+ for (const exportSpecifier of pkgStats.prunedExportKeys) this.reporter.logPrunedStaleExport(cliLogger, exportSpecifier);
34
+ this.reporter.logPackageSuccess(cliLogger, ordinal, total, pkgStats, {
35
+ jsCount: pkgStats.jsModules,
36
+ cssCount: pkgStats.cssExports
37
+ }, this.verbose);
38
+ }
39
+ onComplete(stats, elapsedSeconds) {
40
+ this.reporter.mirrorSummarySeparator(cliLogger);
41
+ this.reporter.mirrorSummary(cliLogger, stats, elapsedSeconds);
42
+ }
43
+ };
44
+ //#endregion
45
+ export { MirrorSyncProgressPresenter };
@@ -0,0 +1,32 @@
1
+ import { AppError } from "../core/errors.mjs";
2
+ import { err, ok } from "../core/result.mjs";
3
+ import { normalizePath } from "./domain/path-normalizer.mjs";
4
+ import path from "node:path";
5
+ //#region src/mirror/package-path.ts
6
+ /**
7
+ * @since 0.3.16-canary.0
8
+ */
9
+ function resolveMirrorPackageFromCliArg(fs, args) {
10
+ const { rootDir, packageArg, currentWorkingDirectory } = args;
11
+ if (!packageArg) return ok(void 0);
12
+ const rootReal = fs.canonicalPathSync(path.resolve(rootDir));
13
+ const cwdReal = fs.canonicalPathSync(currentWorkingDirectory);
14
+ const resolved = path.isAbsolute(packageArg) ? path.resolve(packageArg) : path.resolve(cwdReal, packageArg);
15
+ const targetReal = fs.canonicalPathSync(resolved);
16
+ const normalized = normalizePath(path.relative(rootReal, targetReal));
17
+ if (normalized.startsWith("..") || path.isAbsolute(normalized) || normalized === "" || normalized === ".") return err(new AppError("VALIDATION_ERROR", `Package path must be a subdirectory under monorepo root: ${rootDir}`));
18
+ return ok(normalized);
19
+ }
20
+ /**
21
+ * @since 0.3.16-canary.0
22
+ */
23
+ function resolvePackageFilterUnderRoot(fs, rootDir, packageFilter) {
24
+ const rootResolved = path.resolve(rootDir);
25
+ const rootReal = fs.canonicalPathSync(rootResolved);
26
+ const resolved = path.isAbsolute(packageFilter) ? fs.canonicalPathSync(path.resolve(packageFilter)) : fs.canonicalPathSync(path.join(rootReal, packageFilter));
27
+ const normalized = normalizePath(path.relative(rootReal, resolved));
28
+ if (normalized.startsWith("..") || path.isAbsolute(normalized) || normalized === "" || normalized === ".") return err(new AppError("VALIDATION_ERROR", `Package path must be a subdirectory under monorepo root: ${rootDir}`));
29
+ return ok(normalized);
30
+ }
31
+ //#endregion
32
+ export { resolveMirrorPackageFromCliArg, resolvePackageFilterUnderRoot };
@@ -0,0 +1,33 @@
1
+ import { AppError, messageFrom } from "../core/errors.mjs";
2
+ import { err, ok } from "../core/result.mjs";
3
+ import { loadCodefastConfig } from "../core/config.mjs";
4
+ import { findRepoRoot } from "../core/workspace/resolver.mjs";
5
+ import { resolveMirrorPackageFromCliArg } from "./package-path.mjs";
6
+ //#region src/mirror/prepare.ts
7
+ /**
8
+ * @since 0.3.16-canary.0
9
+ */
10
+ async function prepareMirrorSync(fs, args) {
11
+ let rootDir;
12
+ try {
13
+ rootDir = findRepoRoot(args.currentWorkingDirectory, fs);
14
+ } catch (caughtError) {
15
+ return err(new AppError("INFRA_FAILURE", messageFrom(caughtError), caughtError));
16
+ }
17
+ const filterOutcome = resolveMirrorPackageFromCliArg(fs, {
18
+ rootDir,
19
+ packageArg: args.packageArg,
20
+ currentWorkingDirectory: args.currentWorkingDirectory
21
+ });
22
+ if (!filterOutcome.ok) return filterOutcome;
23
+ const loadedOutcome = await loadCodefastConfig(rootDir, fs);
24
+ if (!loadedOutcome.ok) return loadedOutcome;
25
+ return ok({
26
+ globals: args.globals,
27
+ rootDir,
28
+ config: loadedOutcome.value.config,
29
+ packageFilter: filterOutcome.value
30
+ });
31
+ }
32
+ //#endregion
33
+ export { prepareMirrorSync };
@@ -0,0 +1,104 @@
1
+ import { messageFrom } from "../core/errors.mjs";
2
+ import process from "node:process";
3
+ //#region src/mirror/sync-reporter.ts
4
+ const ANSI = {
5
+ reset: "\x1B[0m",
6
+ bold: "\x1B[1m",
7
+ dim: "\x1B[2m",
8
+ green: "\x1B[32m",
9
+ yellow: "\x1B[33m",
10
+ cyan: "\x1B[36m",
11
+ gray: "\x1B[90m",
12
+ magenta: "\x1B[35m",
13
+ brightGreen: "\x1B[92m",
14
+ brightCyan: "\x1B[96m"
15
+ };
16
+ /**
17
+ * Console implementation: ANSI styling and layout for mirror sync.
18
+ *
19
+ * @since 0.3.16-canary.0
20
+ */
21
+ var MirrorSyncReporter = class {
22
+ colorsAreEnabled = true;
23
+ configureMirrorColors(noColor) {
24
+ this.colorsAreEnabled = !!process.stdout.isTTY && !noColor;
25
+ }
26
+ mirrorBanner(logger) {
27
+ logger.out(`\n${this.paint("📦 Mirror — package exports", ANSI.bold + ANSI.cyan)}`);
28
+ logger.out(`${this.paint("═".repeat(60), ANSI.dim)}\n`);
29
+ }
30
+ mirrorProcessingMode(logger, mode) {
31
+ if (mode.kind === "single") {
32
+ logger.out(`${this.paint("Processing single package...", ANSI.dim)}\n`);
33
+ return;
34
+ }
35
+ if (mode.source === "default-patterns") {
36
+ logger.out(`${this.paint("Discovering workspace packages using default patterns (packages/*)…", ANSI.dim)}\n`);
37
+ return;
38
+ }
39
+ if (mode.source === "pnpm-workspace-yaml") {
40
+ logger.out(`${this.paint("Discovering workspace packages from pnpm-workspace.yaml…", ANSI.dim)}\n`);
41
+ return;
42
+ }
43
+ logger.out(`${this.paint("pnpm-workspace.yaml declares an empty workspace package list.", ANSI.dim)}\n`);
44
+ }
45
+ mirrorNoPackages(logger) {
46
+ logger.out(this.paint("⚠ No packages found", ANSI.yellow));
47
+ }
48
+ logSkippedWorkspacePackage(logger, index, total, displayName, reason) {
49
+ const progress = this.paint(`[${index}/${total}]`, ANSI.dim);
50
+ logger.out(`${progress} ${this.paint("○", ANSI.gray)} ${this.paint(displayName, ANSI.dim)}`);
51
+ logger.out(` ${this.paint("└─", ANSI.dim)} ${this.paint(`Skipped: ${reason}`, ANSI.gray)}`);
52
+ logger.out("");
53
+ }
54
+ logPackageSuccess(logger, index, total, pkgStats, generatedDistAssetCounts, verbose) {
55
+ const progress = this.paint(`[${index}/${total}]`, ANSI.dim);
56
+ logger.out(`${progress} ${this.paint("✓", ANSI.brightGreen)} ${this.paint(pkgStats.name, ANSI.bold)}`);
57
+ if (verbose) {
58
+ logger.out(` ${this.paint("├─", ANSI.dim)} Path: ${pkgStats.path}`);
59
+ if (pkgStats.hasTransform) logger.out(` ${this.paint("├─", ANSI.dim)} ${this.paint("Custom path transformation", ANSI.cyan)}`);
60
+ if (pkgStats.cssConfigStatus) {
61
+ const status = pkgStats.cssConfigStatus === "disabled" ? "CSS disabled" : "CSS configured";
62
+ logger.out(` ${this.paint("├─", ANSI.dim)} ${this.paint(status, ANSI.cyan)}`);
63
+ }
64
+ }
65
+ const breakdown = [];
66
+ if (generatedDistAssetCounts.jsCount > 0) breakdown.push(this.paint(`${generatedDistAssetCounts.jsCount} modules`, ANSI.green));
67
+ if (generatedDistAssetCounts.cssCount > 0) breakdown.push(this.paint(`${generatedDistAssetCounts.cssCount} CSS`, ANSI.magenta));
68
+ if (pkgStats.customExports > 0) breakdown.push(this.paint(`${pkgStats.customExports} custom`, ANSI.yellow));
69
+ const totalExportsText = this.paint(`${pkgStats.totalExports} exports`, ANSI.brightCyan);
70
+ if (breakdown.length === 0) logger.out(` ${this.paint("└─", ANSI.dim)} ${totalExportsText}`);
71
+ else logger.out(` ${this.paint("└─", ANSI.dim)} ${breakdown.join(" + ")} = ${totalExportsText}`);
72
+ logger.out("");
73
+ }
74
+ logPrunedStaleExport(logger, exportSpecifier) {
75
+ logger.out(` ${this.paint("└─", ANSI.dim)} ${this.paint(`Pruned stale export: ${exportSpecifier}`, ANSI.gray)}`);
76
+ }
77
+ logPackageError(logger, index, total, displayName, errorValue, verbose) {
78
+ logger.out(`${this.paint(`[${index}/${total}]`, ANSI.dim)} ${this.paint("✗", ANSI.yellow)} ${this.paint(displayName, ANSI.bold)}`);
79
+ logger.out(` ${this.paint("└─", ANSI.dim)} ${this.paint(`Error: ${messageFrom(errorValue)}`, ANSI.yellow)}\n`);
80
+ if (verbose) logger.err(errorValue instanceof Error && errorValue.stack ? errorValue.stack : messageFrom(errorValue));
81
+ }
82
+ mirrorSummarySeparator(logger) {
83
+ logger.out(this.paint("═".repeat(60), ANSI.dim));
84
+ }
85
+ mirrorSummary(logger, stats, elapsedSeconds) {
86
+ logger.out(`${this.paint("📊 Summary", ANSI.bold)} ${this.paint(`(completed in ${elapsedSeconds.toFixed(2)}s)`, ANSI.dim)}\n`);
87
+ logger.out(` ${this.paint("Packages:", ANSI.bold)}`);
88
+ logger.out(` ${this.paint("├─", ANSI.dim)} Processed: ${this.paint(String(stats.packagesProcessed), ANSI.green)}`);
89
+ if (stats.packagesSkipped > 0) logger.out(` ${this.paint("├─", ANSI.dim)} Skipped: ${this.paint(String(stats.packagesSkipped), ANSI.gray)}`);
90
+ if (stats.packagesErrored > 0) logger.out(` ${this.paint("├─", ANSI.dim)} Errors: ${this.paint(String(stats.packagesErrored), ANSI.yellow)}`);
91
+ logger.out(` ${this.paint("└─", ANSI.dim)} Total found: ${stats.packagesFound}\n`);
92
+ logger.out(` ${this.paint("Exports:", ANSI.bold)}`);
93
+ logger.out(` ${this.paint("├─", ANSI.dim)} JS Modules: ${this.paint(String(stats.totalJsModules), ANSI.cyan)}`);
94
+ logger.out(` ${this.paint("├─", ANSI.dim)} CSS Files: ${this.paint(String(stats.totalCssExports), ANSI.magenta)}`);
95
+ logger.out(` ${this.paint("└─", ANSI.dim)} Total: ${this.paint(String(stats.totalExports), ANSI.brightCyan)}\n`);
96
+ logger.out(`${this.paint("═".repeat(60), ANSI.dim)}\n`);
97
+ }
98
+ paint(text, openSequence) {
99
+ if (!this.colorsAreEnabled) return text;
100
+ return `${openSequence}${text}${ANSI.reset}`;
101
+ }
102
+ };
103
+ //#endregion
104
+ export { MirrorSyncReporter };
@@ -0,0 +1,103 @@
1
+ import { messageFrom } from "../core/errors.mjs";
2
+ import { DIST_DIR, PACKAGE_JSON } from "./domain/constants.mjs";
3
+ import { createPathTransform, generateExports } from "./domain/exports.mjs";
4
+ import { resolvePackageDisplayName } from "./domain/package-display-name.mjs";
5
+ import { writePackageJsonExportsAtomic } from "./write-exports.mjs";
6
+ import { createMirrorDistFilesystem } from "./dist-filesystem-impl.mjs";
7
+ import path from "node:path";
8
+ //#region src/mirror/sync-workspace-package.ts
9
+ /**
10
+ * @since 0.3.16-canary.0
11
+ */
12
+ async function syncExportsForWorkspacePackage(fs, rootDir, packagePathStr, config) {
13
+ const pathJoin = path.join;
14
+ const pathResolve = path.resolve;
15
+ const pathBasename = path.basename;
16
+ const packageDir = pathResolve(rootDir, packagePathStr);
17
+ const distDir = pathJoin(packageDir, DIST_DIR);
18
+ const packageJsonPath = pathJoin(packageDir, PACKAGE_JSON);
19
+ const folderBasename = pathBasename(packageDir);
20
+ const distFilesystem = createMirrorDistFilesystem(fs);
21
+ const pkgStats = {
22
+ name: folderBasename,
23
+ path: packageDir,
24
+ jsModules: 0,
25
+ cssExports: 0,
26
+ customExports: 0,
27
+ totalExports: 0,
28
+ hasTransform: false,
29
+ cssConfigStatus: "",
30
+ skipped: false,
31
+ skipReason: "",
32
+ error: null,
33
+ prunedExportKeys: []
34
+ };
35
+ if (!fs.existsSync(packageJsonPath)) {
36
+ pkgStats.skipped = true;
37
+ pkgStats.skipReason = "package.json not found";
38
+ return pkgStats;
39
+ }
40
+ let packageJsonParseError;
41
+ let parsedPackageJson;
42
+ try {
43
+ const packageContent = await fs.readFile(packageJsonPath, "utf8");
44
+ const rawPackageJson = JSON.parse(packageContent);
45
+ if (rawPackageJson === null || typeof rawPackageJson !== "object" || Array.isArray(rawPackageJson)) throw new SyntaxError("package.json root must be a JSON object");
46
+ parsedPackageJson = rawPackageJson;
47
+ pkgStats.name = resolvePackageDisplayName(parsedPackageJson, folderBasename);
48
+ } catch (caughtError) {
49
+ pkgStats.name = folderBasename;
50
+ packageJsonParseError = caughtError;
51
+ }
52
+ const packageMeta = { packageName: pkgStats.name };
53
+ if (isPackageSkipped(config.skipPackages, packageMeta)) {
54
+ pkgStats.skipped = true;
55
+ pkgStats.skipReason = "configured to skip";
56
+ return pkgStats;
57
+ }
58
+ if (packageJsonParseError !== void 0) {
59
+ if (!fs.existsSync(distDir)) {
60
+ pkgStats.skipped = true;
61
+ pkgStats.skipReason = "dist/ not found";
62
+ return pkgStats;
63
+ }
64
+ pkgStats.error = messageFrom(packageJsonParseError);
65
+ return pkgStats;
66
+ }
67
+ if (!fs.existsSync(distDir)) {
68
+ pkgStats.skipped = true;
69
+ pkgStats.skipReason = "dist/ not found";
70
+ return pkgStats;
71
+ }
72
+ try {
73
+ const pathTransform = createPathTransform(config, packageMeta);
74
+ pkgStats.hasTransform = !!pathTransform;
75
+ const cssConfig = resolvePackageScopedConfig(config.cssExports, packageMeta);
76
+ if (cssConfig === false) pkgStats.cssConfigStatus = "disabled";
77
+ else if (cssConfig !== void 0) pkgStats.cssConfigStatus = "configured";
78
+ const customExports = resolvePackageScopedConfig(config.customExports, packageMeta) || {};
79
+ const generatedExports = await generateExports(distFilesystem, distDir, pathTransform, cssConfig, customExports);
80
+ const { prunedKeys } = await writePackageJsonExportsAtomic(fs, packageJsonPath, {
81
+ generatedExports: generatedExports.exports,
82
+ managedExportSpecifiers: Object.keys(generatedExports.exports),
83
+ originalPathBySpecifier: generatedExports.originalPathBySpecifier
84
+ });
85
+ pkgStats.jsModules = generatedExports.jsCount;
86
+ pkgStats.cssExports = generatedExports.cssCount;
87
+ pkgStats.customExports = Object.keys(customExports).length;
88
+ pkgStats.totalExports = Object.keys(generatedExports.exports).length;
89
+ pkgStats.prunedExportKeys = prunedKeys;
90
+ } catch (caughtError) {
91
+ pkgStats.error = messageFrom(caughtError);
92
+ }
93
+ return pkgStats;
94
+ }
95
+ function resolvePackageScopedConfig(configMap, packageMeta) {
96
+ if (!configMap) return;
97
+ return configMap[packageMeta.packageName];
98
+ }
99
+ function isPackageSkipped(skipPackagesList, packageMeta) {
100
+ return !!skipPackagesList?.includes(packageMeta.packageName);
101
+ }
102
+ //#endregion
103
+ export { syncExportsForWorkspacePackage };