@codefast/cli 0.3.14 → 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 (189) hide show
  1. package/README.md +8 -3
  2. package/dist/arrange/analyze.mjs +24 -0
  3. package/dist/{lib/arrange/presentation/arrange-cli.schema.mjs → arrange/cli-schema.mjs} +10 -1
  4. package/dist/arrange/command.mjs +106 -0
  5. package/dist/{lib/arrange/domain/arrange-analyze.service.mjs → arrange/domain/analyze-service.mjs} +17 -10
  6. package/dist/{lib/arrange/domain/ast/ast-node.model.mjs → arrange/domain/ast/ast-node.mjs} +57 -3
  7. package/dist/{lib/arrange/domain/ast/collectors-cn.collector.mjs → arrange/domain/ast/collectors-cn.mjs} +21 -9
  8. package/dist/{lib/arrange/domain/ast/collectors-jsx.collector.mjs → arrange/domain/ast/collectors-jsx.mjs} +5 -2
  9. package/dist/{lib/arrange/domain/ast/collectors-tv.collector.mjs → arrange/domain/ast/collectors-tv.mjs} +21 -6
  10. package/dist/{lib/arrange/domain/ast/ast-helpers.helper.mjs → arrange/domain/ast/helpers.mjs} +26 -9
  11. package/dist/{lib/arrange/domain/ast/targets.model.mjs → arrange/domain/ast/targets.mjs} +19 -10
  12. package/dist/{lib/arrange/domain/constants.domain.mjs → arrange/domain/constants.mjs} +63 -18
  13. package/dist/{lib/arrange/domain/arrange-grouping.service.mjs → arrange/domain/grouping-service.mjs} +31 -10
  14. package/dist/{lib/arrange/domain/grouping.domain.mjs → arrange/domain/grouping.mjs} +39 -18
  15. package/dist/{lib/arrange/domain/imports.domain.mjs → arrange/domain/imports.mjs} +7 -3
  16. package/dist/{lib/arrange/domain/source-text-formatters.formatter.mjs → arrange/domain/source-text-formatters.mjs} +22 -5
  17. package/dist/{lib/arrange/domain/tailwind-token.value-object.mjs → arrange/domain/tailwind-token.mjs} +12 -3
  18. package/dist/{lib/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 -19
  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/{lib/config/infrastructure/config-schema.adapter.mjs → core/config/schema.mjs} +20 -6
  36. package/dist/core/config/warnings.mjs +12 -0
  37. package/dist/core/config.mjs +19 -0
  38. package/dist/{lib/core/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/{lib/core/domain/result.model.mjs → core/result.mjs} +7 -3
  43. package/dist/{lib/core/application/services/schema-validator.service.mjs → core/schema-parse.mjs} +6 -5
  44. package/dist/{lib/shared/source-code/domain/text-edit.model.mjs → core/source-text-edit.mjs} +15 -14
  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/mirror/cli-result.mjs +21 -0
  49. package/dist/{lib/mirror/presentation/mirror-cli.schema.mjs → mirror/cli-schema.mjs} +4 -4
  50. package/dist/mirror/command.mjs +57 -0
  51. package/dist/mirror/dist-filesystem-impl.mjs +42 -0
  52. package/dist/{lib/mirror/domain/constants.domain.mjs → mirror/domain/constants.mjs} +16 -1
  53. package/dist/{lib/mirror/infrastructure/dirent-list.guard.mjs → mirror/domain/dirent-guard.mjs} +5 -2
  54. package/dist/{lib/mirror/domain/errors.domain.mjs → mirror/domain/errors.mjs} +7 -1
  55. package/dist/{lib/mirror/application/services/generate-mirror-exports.service.mjs → mirror/domain/exports.mjs} +17 -10
  56. package/dist/{lib/mirror/domain/package-display-name.policy.mjs → mirror/domain/package-display-name.mjs} +5 -2
  57. package/dist/{lib/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/{lib/mirror/infrastructure/package-json-exports.repository.mjs → mirror/write-exports.mjs} +35 -31
  65. package/dist/tag/cli-result.mjs +11 -0
  66. package/dist/{lib/tag/presentation/tag-cli.schema.mjs → tag/cli-schema.mjs} +4 -1
  67. package/dist/tag/command.mjs +56 -0
  68. package/dist/{lib/tag/presentation/tag-sync.presenter.mjs → tag/output.mjs} +54 -28
  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 +8 -9
  77. package/dist/lib/arrange/adapters/primary/cli/arrange.command.mjs +0 -324
  78. package/dist/lib/arrange/adapters/primary/cli/arrange.presentation.module.mjs +0 -14
  79. package/dist/lib/arrange/adapters/primary/cli/presentation.tokens.mjs +0 -5
  80. package/dist/lib/arrange/adapters/secondary/domain-source-parser.adapter.mjs +0 -239
  81. package/dist/lib/arrange/adapters/secondary/file-walker.adapter.mjs +0 -241
  82. package/dist/lib/arrange/adapters/secondary/workspace-resolver.adapter.mjs +0 -233
  83. package/dist/lib/arrange/application/requests/suggest-groups.request.mjs +0 -1
  84. package/dist/lib/arrange/application/services/arrange-file-processor.service.mjs +0 -267
  85. package/dist/lib/arrange/application/services/arrange-target-path-resolver.service.mjs +0 -21
  86. package/dist/lib/arrange/application/services/arrange-target-scanner.service.mjs +0 -243
  87. package/dist/lib/arrange/application/use-cases/analyze-directory.use-case.mjs +0 -255
  88. package/dist/lib/arrange/application/use-cases/prepare-arrange-workspace.use-case.mjs +0 -263
  89. package/dist/lib/arrange/application/use-cases/run-arrange-sync.use-case.mjs +0 -274
  90. package/dist/lib/arrange/application/use-cases/suggest-cn-groups.use-case.mjs +0 -237
  91. package/dist/lib/arrange/arrange.module.mjs +0 -31
  92. package/dist/lib/arrange/contracts/analyze-report-presenter.contract.mjs +0 -1
  93. package/dist/lib/arrange/contracts/models.mjs +0 -1
  94. package/dist/lib/arrange/contracts/services.contract.mjs +0 -1
  95. package/dist/lib/arrange/contracts/tokens.mjs +0 -15
  96. package/dist/lib/arrange/domain/tailwind-grouping.service.mjs +0 -231
  97. package/dist/lib/arrange/domain/types.domain.mjs +0 -1
  98. package/dist/lib/arrange/infrastructure/typescript-ast-translator.adapter.mjs +0 -355
  99. package/dist/lib/arrange/presentation/arrange-analyze.presenter.mjs +0 -259
  100. package/dist/lib/arrange/presentation/arrange-sync.presenter.mjs +0 -33
  101. package/dist/lib/arrange/presentation/group-file-preview.presenter.mjs +0 -271
  102. package/dist/lib/bootstrap/composition-root.mjs +0 -33
  103. package/dist/lib/config/application/ports/config-loader.port.mjs +0 -1
  104. package/dist/lib/config/application/ports/config-warning-reporter.port.mjs +0 -1
  105. package/dist/lib/config/application/services/load-config.service.mjs +0 -17
  106. package/dist/lib/config/contracts/tokens.mjs +0 -6
  107. package/dist/lib/config/domain/schema.domain.mjs +0 -1
  108. package/dist/lib/config/infrastructure/config-loader.adapter.mjs +0 -306
  109. package/dist/lib/config/infrastructure/config-warning-reporter.adapter.mjs +0 -234
  110. package/dist/lib/core/application/load-codefast-config.use-case.mjs +0 -245
  111. package/dist/lib/core/application/ports/cli-io.port.mjs +0 -1
  112. package/dist/lib/core/application/ports/path.port.mjs +0 -1
  113. package/dist/lib/core/application/ports/repo-root-resolver.port.mjs +0 -1
  114. package/dist/lib/core/application/ports/runtime.port.mjs +0 -1
  115. package/dist/lib/core/application/services/global-cli-options-parser.service.mjs +0 -9
  116. package/dist/lib/core/contracts/tokens.mjs +0 -10
  117. package/dist/lib/core/core.module.mjs +0 -9
  118. package/dist/lib/core/domain/cli-exit-codes.domain.mjs +0 -11
  119. package/dist/lib/core/domain/errors.domain.mjs +0 -17
  120. package/dist/lib/core/infrastructure/infrastructure.module.mjs +0 -30
  121. package/dist/lib/core/infrastructure/path.adapter.mjs +0 -246
  122. package/dist/lib/core/infrastructure/port-telemetry.decorator.mjs +0 -62
  123. package/dist/lib/core/infrastructure/repo-root-resolver.adapter.mjs +0 -233
  124. package/dist/lib/core/infrastructure/verbose-diagnostics.policy.mjs +0 -9
  125. package/dist/lib/core/presentation/cli-executor.presenter.mjs +0 -42
  126. package/dist/lib/core/presentation/cli-schema.parser.mjs +0 -7
  127. package/dist/lib/core/presentation/format-app-error.presenter.mjs +0 -17
  128. package/dist/lib/core/presentation/presentation.module.mjs +0 -5
  129. package/dist/lib/infrastructure/node-io.adapter.mjs +0 -285
  130. package/dist/lib/infrastructure/workspace/repo-root-resolver.service.mjs +0 -21
  131. package/dist/lib/kernel/contracts/cli-command.contract.mjs +0 -1
  132. package/dist/lib/kernel/contracts/tokens.mjs +0 -5
  133. package/dist/lib/mirror/adapters/primary/cli/mirror.command.mjs +0 -272
  134. package/dist/lib/mirror/adapters/secondary/file-system-service.adapter.mjs +0 -261
  135. package/dist/lib/mirror/adapters/secondary/mirror-sync-reporter.adapter.mjs +0 -243
  136. package/dist/lib/mirror/adapters/secondary/package-repository.adapter.mjs +0 -241
  137. package/dist/lib/mirror/adapters/secondary/sync-workspace-package.adapter.mjs +0 -351
  138. package/dist/lib/mirror/adapters/secondary/workspace-service.adapter.mjs +0 -237
  139. package/dist/lib/mirror/application/mirror-sync-json.format.mjs +0 -12
  140. package/dist/lib/mirror/application/ports/file-system-service.port.mjs +0 -1
  141. package/dist/lib/mirror/application/ports/mirror-sync-reporter.port.mjs +0 -1
  142. package/dist/lib/mirror/application/ports/package-repository.port.mjs +0 -1
  143. package/dist/lib/mirror/application/ports/sync-workspace-package.port.mjs +0 -1
  144. package/dist/lib/mirror/application/ports/workspace-service.port.mjs +0 -1
  145. package/dist/lib/mirror/application/requests/mirror-sync.request.mjs +0 -1
  146. package/dist/lib/mirror/application/services/mirror-package-arg-resolver.service.mjs +0 -20
  147. package/dist/lib/mirror/application/use-cases/prepare-mirror-sync.use-case.mjs +0 -264
  148. package/dist/lib/mirror/application/use-cases/run-mirror-sync.use-case.mjs +0 -302
  149. package/dist/lib/mirror/contracts/models.mjs +0 -1
  150. package/dist/lib/mirror/contracts/tokens.mjs +0 -11
  151. package/dist/lib/mirror/domain/types.domain.mjs +0 -1
  152. package/dist/lib/mirror/infrastructure/mirror-console-reporter.presenter.mjs +0 -99
  153. package/dist/lib/mirror/infrastructure/package-filter-resolver.service.mjs +0 -25
  154. package/dist/lib/mirror/infrastructure/workspace-packages.service.mjs +0 -158
  155. package/dist/lib/mirror/mirror.module.mjs +0 -25
  156. package/dist/lib/shared/source-code/infrastructure/typescript-source-file-walker.service.mjs +0 -33
  157. package/dist/lib/tag/adapters/primary/cli/presentation.tokens.mjs +0 -6
  158. package/dist/lib/tag/adapters/primary/cli/tag.command.mjs +0 -285
  159. package/dist/lib/tag/adapters/primary/cli/tag.presentation.module.mjs +0 -13
  160. package/dist/lib/tag/adapters/secondary/tag-since-writer.adapter.mjs +0 -348
  161. package/dist/lib/tag/adapters/secondary/tag-target-resolver.adapter.mjs +0 -233
  162. package/dist/lib/tag/adapters/secondary/tag-version-resolver.adapter.mjs +0 -249
  163. package/dist/lib/tag/adapters/secondary/typescript-tree-walk.adapter.mjs +0 -233
  164. package/dist/lib/tag/application/ports/tag-since-writer.port.mjs +0 -1
  165. package/dist/lib/tag/application/ports/tag-version-resolver.port.mjs +0 -1
  166. package/dist/lib/tag/application/ports/target-resolver.port.mjs +0 -1
  167. package/dist/lib/tag/application/ports/typescript-tree-walk.port.mjs +0 -1
  168. package/dist/lib/tag/application/requests/tag-sync.request.mjs +0 -1
  169. package/dist/lib/tag/application/services/tag-cli-target-path-resolver.service.mjs +0 -9
  170. package/dist/lib/tag/application/services/tag-target-runner.service.mjs +0 -21
  171. package/dist/lib/tag/application/tag-sync-cli-result.mjs +0 -11
  172. package/dist/lib/tag/application/tag-sync-json.format.mjs +0 -14
  173. package/dist/lib/tag/application/use-cases/prepare-tag-sync.use-case.mjs +0 -264
  174. package/dist/lib/tag/application/use-cases/run-tag-sync.use-case.mjs +0 -381
  175. package/dist/lib/tag/contracts/models.mjs +0 -1
  176. package/dist/lib/tag/contracts/tag-sync-result-presenter.contract.mjs +0 -1
  177. package/dist/lib/tag/contracts/tokens.mjs +0 -10
  178. package/dist/lib/tag/domain/types.domain.mjs +0 -1
  179. package/dist/lib/tag/infrastructure/tag-target-candidates.adapter.mjs +0 -170
  180. package/dist/lib/tag/presentation/colors.presenter.mjs +0 -12
  181. package/dist/lib/tag/presentation/present-tag-sync-result.presenter.mjs +0 -233
  182. package/dist/lib/tag/presentation/tag-sync-progress-listener.presenter.mjs +0 -243
  183. package/dist/lib/tag/tag.module.mjs +0 -23
  184. /package/dist/{lib/arrange/application/ports/domain-source-parser.port.mjs → arrange/domain/types.mjs} +0 -0
  185. /package/dist/{lib/arrange/application/ports/file-walker.port.mjs → core/filesystem/port.mjs} +0 -0
  186. /package/dist/{lib/arrange/application/ports/group-file-preview.port.mjs → mirror/domain/dist-filesystem.mjs} +0 -0
  187. /package/dist/{lib/arrange/application/ports/workspace-resolver.port.mjs → mirror/domain/types.mjs} +0 -0
  188. /package/dist/{lib/arrange/application/requests/analyze-directory.request.mjs → mirror/sync-types.mjs} +0 -0
  189. /package/dist/{lib/arrange/application/requests/arrange-sync.request.mjs → tag/domain/types.mjs} +0 -0
@@ -1,10 +1,12 @@
1
- import { createCliRuntimeContainer, resolveCliCommands } from "./lib/bootstrap/composition-root.mjs";
1
+ import { createArrangeCommand } from "./arrange/command.mjs";
2
+ import { createMirrorCommand } from "./mirror/command.mjs";
3
+ import { createTagCommand } from "./tag/command.mjs";
2
4
  import process from "node:process";
3
5
  import { readFileSync } from "node:fs";
4
6
  import path from "node:path";
5
7
  import { fileURLToPath } from "node:url";
6
8
  import { Command } from "commander";
7
- //#region src/program.ts
9
+ //#region src/cli.ts
8
10
  function readVersion() {
9
11
  try {
10
12
  const dir = path.dirname(fileURLToPath(import.meta.url));
@@ -15,25 +17,18 @@ function readVersion() {
15
17
  return "unknown";
16
18
  }
17
19
  }
18
- function createProgram(commands) {
20
+ /**
21
+ * @since 0.3.16-canary.0
22
+ */
23
+ async function runCli(argv) {
19
24
  const program = new Command();
20
25
  program.name("codefast").description("Codefast monorepo developer CLI").version(readVersion()).option("--no-color", "Disable ANSI color output").configureHelp({ sortSubcommands: true }).showHelpAfterError("(use --help for usage)");
21
- for (const cliCommand of commands) cliCommand.register(program);
22
- return program;
23
- }
24
- async function runCli(argv) {
25
- const runtimeContainer = createCliRuntimeContainer();
26
- try {
27
- if (process.env.NODE_ENV !== "production") {
28
- runtimeContainer.validate();
29
- await runtimeContainer.initializeAsync();
30
- }
31
- await createProgram(resolveCliCommands(runtimeContainer)).parseAsync(argv, { from: "node" });
32
- const code = process.exitCode ?? 0;
33
- return typeof code === "number" ? code : Number(code) || 0;
34
- } finally {
35
- await runtimeContainer.dispose();
36
- }
26
+ program.addCommand(createArrangeCommand());
27
+ program.addCommand(createMirrorCommand());
28
+ program.addCommand(createTagCommand());
29
+ await program.parseAsync(argv, { from: "node" });
30
+ const code = process.exitCode ?? 0;
31
+ return typeof code === "number" ? code : Number(code) || 0;
37
32
  }
38
33
  //#endregion
39
34
  export { runCli };
@@ -0,0 +1,15 @@
1
+ //#region src/core/cli/format-error.ts
2
+ /**
3
+ * @since 0.3.16-canary.0
4
+ */
5
+ function formatAppError(error) {
6
+ const { code, message } = error;
7
+ switch (code) {
8
+ case "NOT_FOUND": return `[NOT_FOUND] ${message}`;
9
+ case "VALIDATION_ERROR": return `[VALIDATION_ERROR] ${message}`;
10
+ case "INFRA_FAILURE": return `[INFRA_FAILURE] ${message}`;
11
+ default: return `Unhandled error code: ${String(code)}`;
12
+ }
13
+ }
14
+ //#endregion
15
+ export { formatAppError };
@@ -0,0 +1,10 @@
1
+ import { z } from "zod";
2
+ //#region src/core/cli/global-options.ts
3
+ /**
4
+ * Commander global opts shape validated before mirror prelude (`color` from `--no-color`).
5
+ *
6
+ * @since 0.3.16-canary.0
7
+ */
8
+ const globalCliCommanderOptionsSchema = z.object({ color: z.boolean().optional() });
9
+ //#endregion
10
+ export { globalCliCommanderOptionsSchema };
@@ -0,0 +1,11 @@
1
+ //#region src/core/cli/positional.ts
2
+ /**
3
+ * Coerce a raw Commander positional argument to a string, or undefined when absent.
4
+ *
5
+ * @since 0.3.16-canary.0
6
+ */
7
+ function readOptionalPositionalArg(candidate) {
8
+ return typeof candidate === "string" ? candidate : void 0;
9
+ }
10
+ //#endregion
11
+ export { readOptionalPositionalArg };
@@ -0,0 +1,51 @@
1
+ import { formatAppError } from "./format-error.mjs";
2
+ import "../exit-codes.mjs";
3
+ import { logger } from "../logger.mjs";
4
+ import { isVerboseCliDiagnostics } from "../verbose-diagnostics.mjs";
5
+ import process from "node:process";
6
+ //#region src/core/cli/result-handle.ts
7
+ function exitCodeForAppError(error) {
8
+ switch (error.code) {
9
+ case "NOT_FOUND": return 1;
10
+ case "VALIDATION_ERROR": return 2;
11
+ case "INFRA_FAILURE": return 1;
12
+ default: return error.code;
13
+ }
14
+ }
15
+ /**
16
+ * @since 0.3.16-canary.0
17
+ */
18
+ function handleResult(outcome, onSuccess) {
19
+ if (!outcome.ok) {
20
+ logger.err(formatAppError(outcome.error));
21
+ if (isVerboseCliDiagnostics() && outcome.error.code === "INFRA_FAILURE" && outcome.error.cause instanceof Error && outcome.error.cause.stack !== void 0) logger.err(outcome.error.cause.stack);
22
+ process.exitCode = exitCodeForAppError(outcome.error);
23
+ return false;
24
+ }
25
+ onSuccess(outcome.value);
26
+ return true;
27
+ }
28
+ /**
29
+ * @since 0.3.16-canary.0
30
+ */
31
+ function consumeCliAppError(outcome, options) {
32
+ if (!outcome.ok) {
33
+ logger.err(formatAppError(outcome.error));
34
+ if (isVerboseCliDiagnostics() && outcome.error.code === "INFRA_FAILURE" && outcome.error.cause instanceof Error && outcome.error.cause.stack !== void 0) logger.err(outcome.error.cause.stack);
35
+ process.exitCode = exitCodeForAppError(outcome.error);
36
+ return false;
37
+ }
38
+ if (options?.successMessage !== void 0) logger.out(options.successMessage);
39
+ return true;
40
+ }
41
+ /**
42
+ * @since 0.3.16-canary.0
43
+ */
44
+ async function runCliResultAsync(outcomePromise, onSuccess) {
45
+ const outcome = await outcomePromise;
46
+ if (!consumeCliAppError(outcome)) return;
47
+ const exit = await onSuccess(outcome.value);
48
+ process.exitCode = exit === void 0 ? 0 : exit;
49
+ }
50
+ //#endregion
51
+ export { consumeCliAppError, handleResult, runCliResultAsync };
@@ -0,0 +1,79 @@
1
+ import { codefastConfigRootSchema } from "./schema.mjs";
2
+ import path from "node:path";
3
+ import jiti from "jiti";
4
+ //#region src/core/config/loader.ts
5
+ function formatZodError(error, filePath) {
6
+ const formatted = error.issues.map((issue) => {
7
+ return ` - ${issue.path.length > 0 ? issue.path.join(".") : "<root>"}: ${issue.message}`;
8
+ }).join("\n");
9
+ return `Invalid config schema in ${path.basename(filePath)}:\n${formatted}`;
10
+ }
11
+ function parseLoadedConfig(raw, filePath) {
12
+ const parsed = codefastConfigRootSchema.safeParse(raw);
13
+ if (!parsed.success) throw new Error(formatZodError(parsed.error, filePath));
14
+ return parsed.data;
15
+ }
16
+ const configJsPriority = [
17
+ "codefast.config.mjs",
18
+ "codefast.config.js",
19
+ "codefast.config.cjs"
20
+ ];
21
+ const configJson = "codefast.config.json";
22
+ const cachedLoads = /* @__PURE__ */ new Map();
23
+ function listConfigCandidates(startDir, fs) {
24
+ const candidates = [];
25
+ let current = path.resolve(startDir);
26
+ while (true) {
27
+ for (const name of configJsPriority) {
28
+ const candidate = path.join(current, name);
29
+ if (fs.existsSync(candidate)) candidates.push(candidate);
30
+ }
31
+ const jsonCandidate = path.join(current, configJson);
32
+ if (fs.existsSync(jsonCandidate)) candidates.push(jsonCandidate);
33
+ const parent = path.dirname(current);
34
+ if (parent === current) break;
35
+ current = parent;
36
+ }
37
+ return candidates;
38
+ }
39
+ async function readConfigFromPath(filePath, jitiBaseDir, fs) {
40
+ if (path.extname(filePath) === ".json") {
41
+ const content = await fs.readFile(filePath, "utf8");
42
+ return parseLoadedConfig(JSON.parse(content), filePath);
43
+ }
44
+ const moduleConfig = jiti(jitiBaseDir, {
45
+ interopDefault: true,
46
+ moduleCache: false
47
+ })(filePath);
48
+ return parseLoadedConfig(typeof moduleConfig === "object" && moduleConfig !== null && "default" in moduleConfig ? moduleConfig.default : moduleConfig, filePath);
49
+ }
50
+ async function loadOnce(startDir, fs) {
51
+ const warnings = [];
52
+ const configPaths = listConfigCandidates(startDir, fs);
53
+ if (configPaths.length === 0) return {
54
+ config: {},
55
+ warnings
56
+ };
57
+ const configPath = configPaths[0];
58
+ if (configPath === void 0) return {
59
+ config: {},
60
+ warnings
61
+ };
62
+ return {
63
+ config: await readConfigFromPath(configPath, startDir, fs),
64
+ warnings,
65
+ configPath
66
+ };
67
+ }
68
+ /**
69
+ * @since 0.3.16-canary.0
70
+ */
71
+ function loadConfigPayload(startDir, fs) {
72
+ const cacheKey = path.resolve(startDir);
73
+ if (!cachedLoads.has(cacheKey)) cachedLoads.set(cacheKey, loadOnce(cacheKey, fs));
74
+ const cached = cachedLoads.get(cacheKey);
75
+ if (cached === void 0) throw new Error("config loader cache invariant violated");
76
+ return cached;
77
+ }
78
+ //#endregion
79
+ export { loadConfigPayload };
@@ -1,6 +1,9 @@
1
1
  import { z } from "zod";
2
- //#region src/lib/config/infrastructure/config-schema.adapter.ts
3
- const hookSchema = z.custom((value) => typeof value === "function", { message: "Expected a function" });
2
+ //#region src/core/config/schema.ts
3
+ const afterWriteHookSchema = z.custom((value) => typeof value === "function", { message: "Expected a function" });
4
+ /**
5
+ * @since 0.3.16-canary.0
6
+ */
4
7
  const mirrorConfigSchema = z.object({
5
8
  skipPackages: z.array(z.string()).optional(),
6
9
  pathTransformations: z.record(z.string(), z.object({ removePrefix: z.string().optional() }).strict()).optional(),
@@ -11,15 +14,26 @@ const mirrorConfigSchema = z.object({
11
14
  forceExportFiles: z.boolean().optional()
12
15
  }).strict()])).optional()
13
16
  }).strict();
17
+ /**
18
+ * @since 0.3.16-canary.0
19
+ */
14
20
  const codefastTagConfigSchema = z.object({
15
21
  skipPackages: z.array(z.string()).optional(),
16
- onAfterWrite: hookSchema.optional()
22
+ onAfterWrite: afterWriteHookSchema.optional()
17
23
  }).strict();
18
- const codefastArrangeConfigSchema = z.object({ onAfterWrite: hookSchema.optional() }).strict();
19
- const codefastConfigSchema = z.object({
24
+ /**
25
+ * @since 0.3.16-canary.0
26
+ */
27
+ const codefastArrangeConfigSchema = z.object({ onAfterWrite: afterWriteHookSchema.optional() }).strict();
28
+ /**
29
+ * Root `codefast.config` Zod schema — single source of truth for both validation and TS types.
30
+ *
31
+ * @since 0.3.16-canary.0
32
+ */
33
+ const codefastConfigRootSchema = z.object({
20
34
  mirror: mirrorConfigSchema.optional(),
21
35
  tag: codefastTagConfigSchema.optional(),
22
36
  arrange: codefastArrangeConfigSchema.optional()
23
37
  }).strict();
24
38
  //#endregion
25
- export { codefastConfigSchema };
39
+ export { codefastArrangeConfigSchema, codefastConfigRootSchema, codefastTagConfigSchema, mirrorConfigSchema };
@@ -0,0 +1,12 @@
1
+ import { logger } from "../logger.mjs";
2
+ //#region src/core/config/warnings.ts
3
+ const yellowAnsi = "\x1B[33m";
4
+ const resetAnsi = "\x1B[0m";
5
+ /**
6
+ * @since 0.3.16-canary.0
7
+ */
8
+ function reportSchemaWarnings(warnings) {
9
+ for (const warningMessage of warnings) logger.out(`${yellowAnsi}⚠ ${warningMessage}${resetAnsi}`);
10
+ }
11
+ //#endregion
12
+ export { reportSchemaWarnings };
@@ -0,0 +1,19 @@
1
+ import { AppError, messageFrom } from "./errors.mjs";
2
+ import { err, ok } from "./result.mjs";
3
+ import { loadConfigPayload } from "./config/loader.mjs";
4
+ import { reportSchemaWarnings } from "./config/warnings.mjs";
5
+ //#region src/core/config.ts
6
+ /**
7
+ * @since 0.3.16-canary.0
8
+ */
9
+ async function loadCodefastConfig(rootDir, fs) {
10
+ try {
11
+ const { config, warnings } = await loadConfigPayload(rootDir, fs);
12
+ reportSchemaWarnings(warnings);
13
+ return ok({ config });
14
+ } catch (caughtError) {
15
+ return err(new AppError("INFRA_FAILURE", messageFrom(caughtError), caughtError));
16
+ }
17
+ }
18
+ //#endregion
19
+ export { loadCodefastConfig };
@@ -1,8 +1,24 @@
1
- //#region src/lib/core/domain/caught-unknown-message.value-object.ts
1
+ //#region src/core/errors.ts
2
+ /**
3
+ * @since 0.3.16-canary.0
4
+ */
5
+ var AppError = class {
6
+ name = "AppError";
7
+ code;
8
+ message;
9
+ cause;
10
+ constructor(code, message, cause) {
11
+ this.code = code;
12
+ this.message = message;
13
+ if (cause !== void 0) this.cause = cause;
14
+ }
15
+ };
2
16
  /**
3
17
  * Stable, user-facing text for values caught as `unknown`.
4
- * Avoids `String(unknown)` / `[object Object]` and satisfies strict `no-base-to-string`.
5
- */ function messageFromCaughtUnknown(value) {
18
+ *
19
+ * @since 0.3.16-canary.0
20
+ */
21
+ function messageFrom(value) {
6
22
  if (value instanceof Error) return value.message;
7
23
  if (typeof value === "string") return value;
8
24
  if (typeof value === "number" || typeof value === "bigint" || typeof value === "boolean") return String(value);
@@ -16,4 +32,4 @@
16
32
  return "[unserializable non-Error value]";
17
33
  }
18
34
  //#endregion
19
- export { messageFromCaughtUnknown };
35
+ export { AppError, messageFrom };
@@ -0,0 +1,17 @@
1
+ //#region src/core/exit-codes.ts
2
+ /**
3
+ * Process exit codes for the `codefast` CLI.
4
+ *
5
+ * @since 0.3.16-canary.0
6
+ */
7
+ const CLI_EXIT_SUCCESS = 0;
8
+ /**
9
+ * @since 0.3.16-canary.0
10
+ */
11
+ const CLI_EXIT_GENERAL_ERROR = 1;
12
+ /**
13
+ * @since 0.3.16-canary.0
14
+ */
15
+ const CLI_EXIT_USAGE = 2;
16
+ //#endregion
17
+ export { CLI_EXIT_GENERAL_ERROR, CLI_EXIT_SUCCESS, CLI_EXIT_USAGE };
@@ -0,0 +1,32 @@
1
+ import fsSync from "node:fs";
2
+ import path from "node:path";
3
+ import fsPromises from "node:fs/promises";
4
+ //#region src/core/filesystem/node.ts
5
+ /**
6
+ * @since 0.3.16-canary.0
7
+ */
8
+ const nodeFilesystem = {
9
+ existsSync: fsSync.existsSync,
10
+ statSync: fsSync.statSync,
11
+ readFileSync: fsSync.readFileSync,
12
+ writeFileSync: fsSync.writeFileSync,
13
+ readdirSync: fsSync.readdirSync,
14
+ canonicalPathSync(inputPath) {
15
+ try {
16
+ return fsSync.realpathSync.native(inputPath);
17
+ } catch {
18
+ return path.resolve(inputPath);
19
+ }
20
+ },
21
+ readFile: (filePath, enc) => fsPromises.readFile(filePath, enc),
22
+ writeFile: (filePath, data, enc) => fsPromises.writeFile(filePath, data, enc),
23
+ readdir: async (filePath, opts) => {
24
+ const raw = await fsPromises.readdir(filePath, opts);
25
+ if (!opts?.withFileTypes) return raw;
26
+ return raw;
27
+ },
28
+ rename: (oldPath, newPath) => fsPromises.rename(oldPath, newPath),
29
+ unlink: (filePath) => fsPromises.unlink(filePath)
30
+ };
31
+ //#endregion
32
+ export { nodeFilesystem };
@@ -0,0 +1,15 @@
1
+ import process from "node:process";
2
+ //#region src/core/logger.ts
3
+ /**
4
+ * @since 0.3.16-canary.0
5
+ */
6
+ const logger = {
7
+ out(line) {
8
+ process.stdout.write(`${line}\n`);
9
+ },
10
+ err(line) {
11
+ process.stderr.write(`${line}\n`);
12
+ }
13
+ };
14
+ //#endregion
15
+ export { logger };
@@ -1,12 +1,16 @@
1
- //#region src/lib/core/domain/result.model.ts
1
+ //#region src/core/result.ts
2
2
  /**
3
- * Lightweight functional Result type for use-case boundaries.
4
- */ function ok(value) {
3
+ * @since 0.3.16-canary.0
4
+ */
5
+ function ok(value) {
5
6
  return {
6
7
  ok: true,
7
8
  value
8
9
  };
9
10
  }
11
+ /**
12
+ * @since 0.3.16-canary.0
13
+ */
10
14
  function err(error) {
11
15
  return {
12
16
  ok: false,
@@ -1,14 +1,15 @@
1
- import { AppError } from "../../domain/errors.domain.mjs";
2
- import { err, ok } from "../../domain/result.model.mjs";
3
- //#region src/lib/core/application/services/schema-validator.service.ts
1
+ import { AppError } from "./errors.mjs";
2
+ import { err, ok } from "./result.mjs";
3
+ //#region src/core/schema-parse.ts
4
4
  function formatSchemaIssues(issues) {
5
5
  return issues.map((issue) => {
6
6
  return `${issue.path.length > 0 ? `${issue.path.join(".")}: ` : ""}${issue.message}`;
7
7
  }).join("; ");
8
8
  }
9
9
  /**
10
- * Validates `input` with `schema`, returning {@link AppError} (code `VALIDATION_ERROR`) on failure.
11
- */ function parseWithSchema(schema, input) {
10
+ * @since 0.3.16-canary.0
11
+ */
12
+ function parseWithSchema(schema, input) {
12
13
  const parsed = schema.safeParse(input);
13
14
  if (!parsed.success) return err(new AppError("VALIDATION_ERROR", formatSchemaIssues(parsed.error.issues)));
14
15
  return ok(parsed.data);
@@ -1,14 +1,13 @@
1
- //#region src/lib/shared/source-code/domain/text-edit.model.ts
2
- /**
3
- * Pure string utilities for applying non-overlapping text edits and reading line indentation.
4
- */ function lineStartIndexContaining(source, pos) {
1
+ //#region src/core/source-text-edit.ts
2
+ function lineStartIndexContaining(source, pos) {
5
3
  const searchPos = Math.max(0, Math.min(pos, source.length));
6
4
  const prevLineBreak = Math.max(source.lastIndexOf("\n", searchPos - 1), source.lastIndexOf("\r", searchPos - 1));
7
5
  return prevLineBreak === -1 ? 0 : prevLineBreak + 1;
8
6
  }
9
7
  /**
10
- * Returns only the leading whitespace (tabs / spaces) of the line containing `pos`.
11
- */ function indentOfLineContaining(source, pos) {
8
+ * @since 0.3.16-canary.0
9
+ */
10
+ function indentOfLineContaining(source, pos) {
12
11
  const lineStart = lineStartIndexContaining(source, pos);
13
12
  let lineEnd = source.length;
14
13
  for (let i = lineStart; i < source.length; i++) {
@@ -22,17 +21,16 @@
22
21
  return /^[\t ]*/.exec(line)?.[0] ?? "";
23
22
  }
24
23
  /**
25
- * Source slice `[lineStart, pos)` for the line containing `pos`. Aligns continuation lines with
26
- * a token not at column 0 (e.g. `base: ["foo"` → prefix before the opening `"` of `"foo"`).
27
- */ function textPrefixFromLineStartToPosition(source, pos) {
24
+ * @since 0.3.16-canary.0
25
+ */
26
+ function textPrefixFromLineStartToPosition(source, pos) {
28
27
  const searchPos = Math.max(0, Math.min(pos, source.length));
29
- return source.slice(lineStartIndexContaining(source, pos), searchPos);
28
+ return source.slice(lineStartIndexContaining(source, searchPos), searchPos);
30
29
  }
31
30
  /**
32
- * If `tokenEnd` is followed by optional ASCII whitespace then `,`, returns the index after that
33
- * comma. Otherwise returns `tokenEnd`. Useful when a replacement already ends with `,` and the
34
- * following source comma must be absorbed.
35
- */ function endAfterOptionalCommaFollowingInSource(source, tokenEnd) {
31
+ * @since 0.3.16-canary.0
32
+ */
33
+ function endAfterOptionalCommaFollowingInSource(source, tokenEnd) {
36
34
  let index = tokenEnd;
37
35
  while (index < source.length) {
38
36
  const ch = source[index];
@@ -45,6 +43,9 @@
45
43
  }
46
44
  return tokenEnd;
47
45
  }
46
+ /**
47
+ * @since 0.3.16-canary.0
48
+ */
48
49
  function applyEditsDescending(sourceText, edits) {
49
50
  const sorted = [...edits].sort((editA, editB) => editB.start - editA.start);
50
51
  let out = sourceText;
@@ -0,0 +1,11 @@
1
+ import process from "node:process";
2
+ //#region src/core/verbose-diagnostics.ts
3
+ /**
4
+ * @since 0.3.16-canary.0
5
+ */
6
+ function isVerboseCliDiagnostics() {
7
+ const raw = process.env.CODEFAST_VERBOSE;
8
+ return raw === "1" || raw === "true";
9
+ }
10
+ //#endregion
11
+ export { isVerboseCliDiagnostics };