@malyuga/aether-cli 0.1.1

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 (147) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +117 -0
  3. package/dist/cli.d.ts +3 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +119 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/commands/check.d.ts +4 -0
  8. package/dist/commands/check.d.ts.map +1 -0
  9. package/dist/commands/check.js +45 -0
  10. package/dist/commands/check.js.map +1 -0
  11. package/dist/commands/doctor.d.ts +8 -0
  12. package/dist/commands/doctor.d.ts.map +1 -0
  13. package/dist/commands/doctor.js +62 -0
  14. package/dist/commands/doctor.js.map +1 -0
  15. package/dist/commands/generate.d.ts +15 -0
  16. package/dist/commands/generate.d.ts.map +1 -0
  17. package/dist/commands/generate.js +51 -0
  18. package/dist/commands/generate.js.map +1 -0
  19. package/dist/commands/help.d.ts +6 -0
  20. package/dist/commands/help.d.ts.map +1 -0
  21. package/dist/commands/help.js +60 -0
  22. package/dist/commands/help.js.map +1 -0
  23. package/dist/commands/init.d.ts +7 -0
  24. package/dist/commands/init.d.ts.map +1 -0
  25. package/dist/commands/init.js +24 -0
  26. package/dist/commands/init.js.map +1 -0
  27. package/dist/commands/upgrade.d.ts +5 -0
  28. package/dist/commands/upgrade.d.ts.map +1 -0
  29. package/dist/commands/upgrade.js +42 -0
  30. package/dist/commands/upgrade.js.map +1 -0
  31. package/dist/core/ast.d.ts +7 -0
  32. package/dist/core/ast.d.ts.map +1 -0
  33. package/dist/core/ast.js +90 -0
  34. package/dist/core/ast.js.map +1 -0
  35. package/dist/core/constants.d.ts +133 -0
  36. package/dist/core/constants.d.ts.map +1 -0
  37. package/dist/core/constants.js +135 -0
  38. package/dist/core/constants.js.map +1 -0
  39. package/dist/core/diff.d.ts +20 -0
  40. package/dist/core/diff.d.ts.map +1 -0
  41. package/dist/core/diff.js +39 -0
  42. package/dist/core/diff.js.map +1 -0
  43. package/dist/core/errors.d.ts +19 -0
  44. package/dist/core/errors.d.ts.map +1 -0
  45. package/dist/core/errors.js +37 -0
  46. package/dist/core/errors.js.map +1 -0
  47. package/dist/core/naming.d.ts +10 -0
  48. package/dist/core/naming.d.ts.map +1 -0
  49. package/dist/core/naming.js +50 -0
  50. package/dist/core/naming.js.map +1 -0
  51. package/dist/core/paths.d.ts +10 -0
  52. package/dist/core/paths.d.ts.map +1 -0
  53. package/dist/core/paths.js +38 -0
  54. package/dist/core/paths.js.map +1 -0
  55. package/dist/core/plan.d.ts +37 -0
  56. package/dist/core/plan.d.ts.map +1 -0
  57. package/dist/core/plan.js +126 -0
  58. package/dist/core/plan.js.map +1 -0
  59. package/dist/core/project.d.ts +16 -0
  60. package/dist/core/project.d.ts.map +1 -0
  61. package/dist/core/project.js +66 -0
  62. package/dist/core/project.js.map +1 -0
  63. package/dist/core/render.d.ts +4 -0
  64. package/dist/core/render.d.ts.map +1 -0
  65. package/dist/core/render.js +44 -0
  66. package/dist/core/render.js.map +1 -0
  67. package/dist/generators/middleware.d.ts +11 -0
  68. package/dist/generators/middleware.d.ts.map +1 -0
  69. package/dist/generators/middleware.js +41 -0
  70. package/dist/generators/middleware.js.map +1 -0
  71. package/dist/generators/openapi.d.ts +9 -0
  72. package/dist/generators/openapi.d.ts.map +1 -0
  73. package/dist/generators/openapi.js +46 -0
  74. package/dist/generators/openapi.js.map +1 -0
  75. package/dist/generators/project.d.ts +9 -0
  76. package/dist/generators/project.d.ts.map +1 -0
  77. package/dist/generators/project.js +76 -0
  78. package/dist/generators/project.js.map +1 -0
  79. package/dist/generators/resource-context.d.ts +18 -0
  80. package/dist/generators/resource-context.d.ts.map +1 -0
  81. package/dist/generators/resource-context.js +21 -0
  82. package/dist/generators/resource-context.js.map +1 -0
  83. package/dist/generators/resource-file.d.ts +8 -0
  84. package/dist/generators/resource-file.d.ts.map +1 -0
  85. package/dist/generators/resource-file.js +9 -0
  86. package/dist/generators/resource-file.js.map +1 -0
  87. package/dist/generators/resource-tests.d.ts +5 -0
  88. package/dist/generators/resource-tests.d.ts.map +1 -0
  89. package/dist/generators/resource-tests.js +17 -0
  90. package/dist/generators/resource-tests.js.map +1 -0
  91. package/dist/generators/resource.d.ts +21 -0
  92. package/dist/generators/resource.d.ts.map +1 -0
  93. package/dist/generators/resource.js +64 -0
  94. package/dist/generators/resource.js.map +1 -0
  95. package/dist/generators/types.d.ts +7 -0
  96. package/dist/generators/types.d.ts.map +1 -0
  97. package/dist/generators/types.js +2 -0
  98. package/dist/generators/types.js.map +1 -0
  99. package/dist/help/guide.txt +126 -0
  100. package/dist/openapi/extract-resources.d.ts +3 -0
  101. package/dist/openapi/extract-resources.d.ts.map +1 -0
  102. package/dist/openapi/extract-resources.js +130 -0
  103. package/dist/openapi/extract-resources.js.map +1 -0
  104. package/dist/openapi/load-spec.d.ts +3 -0
  105. package/dist/openapi/load-spec.d.ts.map +1 -0
  106. package/dist/openapi/load-spec.js +19 -0
  107. package/dist/openapi/load-spec.js.map +1 -0
  108. package/dist/openapi/types.d.ts +51 -0
  109. package/dist/openapi/types.d.ts.map +1 -0
  110. package/dist/openapi/types.js +2 -0
  111. package/dist/openapi/types.js.map +1 -0
  112. package/dist/templates/init/aether.config.json.eta +5 -0
  113. package/dist/templates/init/astraeus.config.json.eta +5 -0
  114. package/dist/templates/init/chisel.config.json.eta +5 -0
  115. package/dist/templates/init/env.eta +8 -0
  116. package/dist/templates/init/env.example.eta +8 -0
  117. package/dist/templates/init/gitignore.eta +5 -0
  118. package/dist/templates/init/package.json.eta +14 -0
  119. package/dist/templates/init/src-app-composition.ts.eta +6 -0
  120. package/dist/templates/init/src-app-config.ts.eta +105 -0
  121. package/dist/templates/init/src-app-http.ts.eta +74 -0
  122. package/dist/templates/init/src-app-list.ts.eta +35 -0
  123. package/dist/templates/init/src-app-logger.ts.eta +35 -0
  124. package/dist/templates/init/src-app-middleware-bearer-auth.ts.eta +60 -0
  125. package/dist/templates/init/src-app-middleware-body-limit.ts.eta +37 -0
  126. package/dist/templates/init/src-app-middleware-cors.ts.eta +53 -0
  127. package/dist/templates/init/src-app-middleware-error-handler.ts.eta +15 -0
  128. package/dist/templates/init/src-app-middleware-request-logger.ts.eta +8 -0
  129. package/dist/templates/init/src-app-middleware-types.ts.eta +7 -0
  130. package/dist/templates/init/src-app-router.ts.eta +72 -0
  131. package/dist/templates/init/src-app-server.ts.eta +16 -0
  132. package/dist/templates/init/src-app.ts.eta +36 -0
  133. package/dist/templates/init/src-health-health.routes.ts.eta +12 -0
  134. package/dist/templates/init/src-main.ts.eta +37 -0
  135. package/dist/templates/init/tsconfig.json.eta +14 -0
  136. package/dist/templates/middleware/middleware.ts.eta +6 -0
  137. package/dist/templates/resource/controller.ts.eta +135 -0
  138. package/dist/templates/resource/module.test.ts.eta +16 -0
  139. package/dist/templates/resource/module.ts.eta +25 -0
  140. package/dist/templates/resource/repository.fake.ts.eta +33 -0
  141. package/dist/templates/resource/repository.ts.eta +14 -0
  142. package/dist/templates/resource/routes.ts.eta +18 -0
  143. package/dist/templates/resource/service.ts.eta +45 -0
  144. package/dist/templates/resource/types.ts.eta +12 -0
  145. package/dist/templates/resource/validate.ts.eta +64 -0
  146. package/llms.txt +57 -0
  147. package/package.json +67 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 MalyugaSensei
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,117 @@
1
+ # aether-cli
2
+
3
+ Aether scaffolds **plain TypeScript** HTTP backends on Node’s built-in `http` module. It writes source files you own and edit by hand—it is not a runtime framework. After generation, your app runs with **no Aether dependency** and **no npm packages in `dependencies`**.
4
+
5
+ Requires **Node.js 20+**.
6
+
7
+ ## Why Aether?
8
+
9
+ Starting from an empty directory means rebuilding the same server, routing, configuration, and error handling every time. Starting from a framework means adopting its runtime, conventions, and upgrade path.
10
+
11
+ Aether takes the middle ground: it generates a small, working backend and then gets out of the way. The result is ordinary TypeScript with explicit wiring, replaceable parts, and no framework-specific runtime. You can keep the generated structure, change it, or remove any part of it without fighting the tool.
12
+
13
+ ## When to use Aether
14
+
15
+ - You want a **new TypeScript HTTP API** on **`node:http`**, with source files you edit directly
16
+ - You prefer an **explicit composition root** (`composition.ts`) over a runtime framework
17
+ - You need **CRUD scaffolding** by hand or from an **OpenAPI** specification
18
+ - The generated app should ship with **zero runtime npm dependencies**
19
+
20
+ Concise context for coding agents: [llms.txt](./llms.txt).
21
+
22
+ ## Quick start
23
+
24
+ ```bash
25
+ npm i -g @malyuga/aether-cli
26
+
27
+ mkdir my-api && cd my-api
28
+ aether init
29
+ npm install
30
+ aether g resource users --crud
31
+ npm run dev
32
+ ```
33
+
34
+ `GET /health` works immediately. CRUD routes are wired in `src/app/composition.ts`, but the generated **repository is only an interface**—until you pass a real implementation there, CRUD handlers respond with **501 Repository not configured**. That is intentional: persistence is your code, not generated magic.
35
+
36
+ Typical next step: implement `UserRepository` (or use the optional fake from `aether g resource users --crud --tests`) and pass it into `createUserModule({ repository: … })` in `composition.ts`.
37
+
38
+ ## What `init` gives you
39
+
40
+ - **HTTP server** with graceful shutdown (`SIGINT` / `SIGTERM`)
41
+ - **Router** and a single **composition root** (`src/app/composition.ts`) where modules and repositories are wired
42
+ - **Config from environment** (`.env` parsed without `dotenv`); see `.env.example`
43
+ - **Middleware**: CORS, body size limit, request logging, centralized errors, optional **Bearer** auth via `BEARER_TOKEN` in `.env` (disabled when unset; `GET /health` stays public)
44
+ - **`GET /health`** → `{ "status": "ok" }`
45
+ - **List helper** for collection endpoints: `?limit=1..100&offset=0` (default limit 50)
46
+
47
+ Output is **CommonJS**; local imports omit file extensions. Production path: `npm run build` then `npm start` (`node dist/main.js`)—runtime needs only Node, not TypeScript or tsx.
48
+
49
+ ## Commands
50
+
51
+ | Command | Purpose |
52
+ |--------|---------|
53
+ | `aether init` | Scaffold a new project in the current directory |
54
+ | `aether g resource <name>` | Resource module (add `--crud` for full stack) |
55
+ | `aether g middleware <name>` | Middleware stub (`--global` registers in `src/app.ts`) |
56
+ | `aether g openapi <spec>` | Generates CRUD resources from an OpenAPI specification |
57
+ | `aether check` | Verify layout (`composition`, config) |
58
+ | `aether doctor` | Node version, project context, CLI templates |
59
+ | `aether upgrade` | Reports how the project drifts from the current Aether contract; read-only, does not rewrite your code |
60
+ | `aether help` | Full guide with examples |
61
+
62
+ `generate` is aliased as **`g`**.
63
+
64
+ ### Useful flags
65
+
66
+ - **`--dry-run`** — show planned creates/modifies without writing
67
+ - **`--diff`** — with `--dry-run`, print a unified diff
68
+ - **`--json`** — machine-readable output (including errors)
69
+ - **`--force`** — overwrite existing generated files (`init` never overwrites `.env`)
70
+
71
+ Resource-specific: `--crud`, `--singular`, `--tests` (with `--crud`: fake repo + smoke tests under `tests/`). OpenAPI: `--strict`, `--only a,b`.
72
+
73
+ ## Examples
74
+
75
+ Preview scaffold before writing:
76
+
77
+ ```bash
78
+ aether init --dry-run --diff
79
+ ```
80
+
81
+ CRUD and tests in one step:
82
+
83
+ ```bash
84
+ aether g resource orders --crud --tests
85
+ ```
86
+
87
+ Generate from an API contract (re-run updates **types** and **validate** only; use `--force` to rewrite the whole module):
88
+
89
+ ```bash
90
+ aether g openapi ./api.yaml --strict
91
+ ```
92
+
93
+ Enable Bearer auth on all routes except health (already wired by `init`; set the token in `.env`):
94
+
95
+ ```bash
96
+ BEARER_TOKEN=your-secret
97
+ ```
98
+
99
+ CI-style structure check:
100
+
101
+ ```bash
102
+ aether check --json
103
+ ```
104
+
105
+ ## Resource layout (with `--crud`)
106
+
107
+ For `users` you get layers under `src/users/`:
108
+
109
+ `types` → `validate` → `repository` (interface) → `service` → `controller` → `routes` → `module`, plus registration in `composition.ts`.
110
+
111
+ Without OpenAPI, a manual CRUD resource starts with entity **`{ id }`** only—you extend types and validation yourself, or import fields from OpenAPI.
112
+
113
+ For the full command reference and notes, run **`aether help`**.
114
+
115
+ ## License
116
+
117
+ MIT
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,119 @@
1
+ #!/usr/bin/env node
2
+ import { readFileSync } from "node:fs";
3
+ import { dirname, join } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { Command } from "commander";
6
+ import { runInit } from "./commands/init.js";
7
+ import { runGenerate } from "./commands/generate.js";
8
+ import { runDoctor } from "./commands/doctor.js";
9
+ import { runCheck } from "./commands/check.js";
10
+ import { runUpgrade } from "./commands/upgrade.js";
11
+ import { runHelp } from "./commands/help.js";
12
+ import { CLI_NAME, DEFAULT_APP_ENTRY, EXIT_FAIL, GENERATOR, PACKAGE_JSON } from "./core/constants.js";
13
+ import { errorToJson, formatUserError } from "./core/errors.js";
14
+ function readCliVersion() {
15
+ const here = dirname(fileURLToPath(import.meta.url));
16
+ const pkg = JSON.parse(readFileSync(join(here, "..", PACKAGE_JSON), "utf8"));
17
+ return pkg.version;
18
+ }
19
+ const program = new Command();
20
+ program
21
+ .name(CLI_NAME)
22
+ .description("Generate Node.js backend source code")
23
+ .version(readCliVersion())
24
+ .option("--json", "Machine-readable JSON output")
25
+ .option("--diff", "With --dry-run, print unified diff preview")
26
+ .addHelpText("after", `\nFull guide: ${CLI_NAME} help\n`);
27
+ program
28
+ .command("init")
29
+ .description("Initialize a new backend project")
30
+ .option("-f, --force", "Overwrite existing files in target directory")
31
+ .option("--dry-run", "Print planned changes without writing")
32
+ .action(async (options) => {
33
+ const globals = program.opts();
34
+ await runInit(process.cwd(), { ...options, json: globals.json, diff: globals.diff });
35
+ });
36
+ program
37
+ .command("upgrade")
38
+ .description("Report migration steps toward current Aether contract")
39
+ .option("--dry-run", "Report only (default)")
40
+ .action(async (options) => {
41
+ const globals = program.opts();
42
+ process.exitCode = await runUpgrade(process.cwd(), {
43
+ dryRun: options.dryRun ?? true,
44
+ json: globals.json,
45
+ });
46
+ });
47
+ program
48
+ .command("doctor")
49
+ .description("Diagnose environment and project layout")
50
+ .action(async () => {
51
+ const globals = program.opts();
52
+ process.exitCode = await runDoctor(process.cwd(), globals.json);
53
+ });
54
+ program
55
+ .command("check")
56
+ .description("Verify Aether project structure")
57
+ .action(async () => {
58
+ const globals = program.opts();
59
+ process.exitCode = await runCheck(process.cwd(), { json: globals.json });
60
+ });
61
+ program
62
+ .command("help")
63
+ .description("Full command guide with examples")
64
+ .option("--no-color", "Disable ANSI styling")
65
+ .action((options) => {
66
+ const globals = program.opts();
67
+ process.exitCode = runHelp({ json: globals.json, color: !options.noColor });
68
+ });
69
+ const generate = program
70
+ .command("generate")
71
+ .alias("g")
72
+ .description("Generate application code");
73
+ generate
74
+ .command("openapi <spec>")
75
+ .description("Generate CRUD resources from an OpenAPI 3 document")
76
+ .option("--strict", "Fail when any OpenAPI path is skipped")
77
+ .option("--only <names>", "Comma-separated resource names to generate", (v) => v.split(",").map((s) => s.trim()).filter(Boolean))
78
+ .option("-f, --force", "Overwrite existing resource files")
79
+ .option("--dry-run", "Print planned changes without writing")
80
+ .action(async (spec, options) => {
81
+ const globals = program.opts();
82
+ await runGenerate(GENERATOR.openapi, undefined, { specPath: spec, ...options, json: globals.json, diff: globals.diff });
83
+ });
84
+ generate
85
+ .command("middleware <name>")
86
+ .description("Generate middleware")
87
+ .option("--global", `Register in ${DEFAULT_APP_ENTRY} global middleware chain`)
88
+ .option("-f, --force", "Overwrite existing middleware file")
89
+ .option("--dry-run", "Print planned changes without writing")
90
+ .action(async (name, options) => {
91
+ const globals = program.opts();
92
+ await runGenerate(GENERATOR.middleware, name, { ...options, json: globals.json, diff: globals.diff });
93
+ });
94
+ generate
95
+ .command("resource <name>")
96
+ .description("Generate a resource module")
97
+ .option("--crud", "Generate CRUD endpoints")
98
+ .option("--singular <singular>", "Singular entity name (PascalCase or camelCase)")
99
+ .option("--tests", "With --crud: generate tests/ on create; on existing CRUD resource: add tests only")
100
+ .option("-f, --force", "Overwrite existing resource files")
101
+ .option("--dry-run", "Print planned changes without writing")
102
+ .action(async (name, options) => {
103
+ const globals = program.opts();
104
+ await runGenerate(GENERATOR.resource, name, { ...options, json: globals.json, diff: globals.diff });
105
+ });
106
+ try {
107
+ await program.parseAsync(process.argv);
108
+ }
109
+ catch (err) {
110
+ const globals = program.opts();
111
+ if (globals.json) {
112
+ console.error(JSON.stringify({ ok: false, error: errorToJson(err) }, null, 2));
113
+ }
114
+ else {
115
+ console.error(formatUserError(err));
116
+ }
117
+ process.exitCode = EXIT_FAIL;
118
+ }
119
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACtG,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEhE,SAAS,cAAc;IACrB,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACrD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,YAAY,CAAC,EAAE,MAAM,CAAC,CAAwB,CAAC;IACpG,OAAO,GAAG,CAAC,OAAO,CAAC;AACrB,CAAC;AAED,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,QAAQ,CAAC;KACd,WAAW,CAAC,sCAAsC,CAAC;KACnD,OAAO,CAAC,cAAc,EAAE,CAAC;KACzB,MAAM,CAAC,QAAQ,EAAE,8BAA8B,CAAC;KAChD,MAAM,CAAC,QAAQ,EAAE,4CAA4C,CAAC;KAC9D,WAAW,CAAC,OAAO,EAAE,iBAAiB,QAAQ,SAAS,CAAC,CAAC;AAE5D,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,kCAAkC,CAAC;KAC/C,MAAM,CAAC,aAAa,EAAE,8CAA8C,CAAC;KACrE,MAAM,CAAC,WAAW,EAAE,uCAAuC,CAAC;KAC5D,MAAM,CAAC,KAAK,EAAE,OAA8C,EAAE,EAAE;IAC/D,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAsC,CAAC;IACnE,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;AACvF,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,SAAS,CAAC;KAClB,WAAW,CAAC,uDAAuD,CAAC;KACpE,MAAM,CAAC,WAAW,EAAE,uBAAuB,CAAC;KAC5C,MAAM,CAAC,KAAK,EAAE,OAA6B,EAAE,EAAE;IAC9C,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAsB,CAAC;IACnD,OAAO,CAAC,QAAQ,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE;QACjD,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,IAAI;QAC9B,IAAI,EAAE,OAAO,CAAC,IAAI;KACnB,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,yCAAyC,CAAC;KACtD,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAsB,CAAC;IACnD,OAAO,CAAC,QAAQ,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;AAClE,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,iCAAiC,CAAC;KAC9C,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAsB,CAAC;IACnD,OAAO,CAAC,QAAQ,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;AAC3E,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,kCAAkC,CAAC;KAC/C,MAAM,CAAC,YAAY,EAAE,sBAAsB,CAAC;KAC5C,MAAM,CAAC,CAAC,OAA8B,EAAE,EAAE;IACzC,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAsB,CAAC;IACnD,OAAO,CAAC,QAAQ,GAAG,OAAO,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;AAC9E,CAAC,CAAC,CAAC;AAEL,MAAM,QAAQ,GAAG,OAAO;KACrB,OAAO,CAAC,UAAU,CAAC;KACnB,KAAK,CAAC,GAAG,CAAC;KACV,WAAW,CAAC,2BAA2B,CAAC,CAAC;AAE5C,QAAQ;KACL,OAAO,CAAC,gBAAgB,CAAC;KACzB,WAAW,CAAC,oDAAoD,CAAC;KACjE,MAAM,CAAC,UAAU,EAAE,uCAAuC,CAAC;KAC3D,MAAM,CAAC,gBAAgB,EAAE,4CAA4C,EAAE,CAAC,CAAS,EAAE,EAAE,CACpF,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAClD;KACA,MAAM,CAAC,aAAa,EAAE,mCAAmC,CAAC;KAC1D,MAAM,CAAC,WAAW,EAAE,uCAAuC,CAAC;KAC5D,MAAM,CAAC,KAAK,EAAE,IAAY,EAAE,OAAiF,EAAE,EAAE;IAChH,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAsC,CAAC;IACnE,MAAM,WAAW,CAAC,SAAS,CAAC,OAAO,EAAE,SAAS,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;AAC1H,CAAC,CAAC,CAAC;AAEL,QAAQ;KACL,OAAO,CAAC,mBAAmB,CAAC;KAC5B,WAAW,CAAC,qBAAqB,CAAC;KAClC,MAAM,CAAC,UAAU,EAAE,eAAe,iBAAiB,0BAA0B,CAAC;KAC9E,MAAM,CAAC,aAAa,EAAE,oCAAoC,CAAC;KAC3D,MAAM,CAAC,WAAW,EAAE,uCAAuC,CAAC;KAC5D,MAAM,CAAC,KAAK,EAAE,IAAY,EAAE,OAAgE,EAAE,EAAE;IAC/F,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAsC,CAAC;IACnE,MAAM,WAAW,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;AACxG,CAAC,CAAC,CAAC;AAEL,QAAQ;KACL,OAAO,CAAC,iBAAiB,CAAC;KAC1B,WAAW,CAAC,4BAA4B,CAAC;KACzC,MAAM,CAAC,QAAQ,EAAE,yBAAyB,CAAC;KAC3C,MAAM,CAAC,uBAAuB,EAAE,gDAAgD,CAAC;KACjF,MAAM,CACL,SAAS,EACT,mFAAmF,CACpF;KACA,MAAM,CAAC,aAAa,EAAE,mCAAmC,CAAC;KAC1D,MAAM,CAAC,WAAW,EAAE,uCAAuC,CAAC;KAC5D,MAAM,CACL,KAAK,EACH,IAAY,EACZ,OAMC,EACD,EAAE;IACF,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAsC,CAAC;IACnE,MAAM,WAAW,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;AACtG,CAAC,CACF,CAAC;AAEJ,IAAI,CAAC;IACH,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AACzC,CAAC;AAAC,OAAO,GAAG,EAAE,CAAC;IACb,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAsB,CAAC;IACnD,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACjF,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,KAAK,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC;IACtC,CAAC;IACD,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC;AAC/B,CAAC"}
@@ -0,0 +1,4 @@
1
+ export declare function runCheck(cwd: string, options: {
2
+ json?: boolean;
3
+ }): Promise<number>;
4
+ //# sourceMappingURL=check.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/commands/check.ts"],"names":[],"mappings":"AAOA,wBAAsB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAmCxF"}
@@ -0,0 +1,45 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { createProjectContext, loadConfig } from "../core/project.js";
4
+ import { compositionRel } from "../core/paths.js";
5
+ import { pathExists } from "../core/plan.js";
6
+ import { AST_SYMBOL, EXIT_FAIL, EXIT_OK } from "../core/constants.js";
7
+ export async function runCheck(cwd, options) {
8
+ const issues = [];
9
+ try {
10
+ loadConfig(cwd);
11
+ }
12
+ catch (err) {
13
+ issues.push(err instanceof Error ? err.message : String(err));
14
+ }
15
+ try {
16
+ const ctx = createProjectContext(cwd);
17
+ const compPath = compositionRel(ctx);
18
+ if (!pathExists(cwd, compPath)) {
19
+ issues.push(`Missing ${compPath}`);
20
+ }
21
+ else {
22
+ const src = readFileSync(join(cwd, compPath), "utf8");
23
+ if (!src.includes(`function ${AST_SYMBOL.buildAppRoutes}`)) {
24
+ issues.push(`${compPath} must export ${AST_SYMBOL.buildAppRoutes}()`);
25
+ }
26
+ }
27
+ }
28
+ catch (err) {
29
+ issues.push(err instanceof Error ? err.message : String(err));
30
+ }
31
+ const ok = issues.length === 0;
32
+ if (options.json) {
33
+ console.log(JSON.stringify({ ok, issues }, null, 2));
34
+ }
35
+ else if (ok) {
36
+ console.log("ok: project structure checks passed");
37
+ }
38
+ else {
39
+ for (const issue of issues) {
40
+ console.error(issue);
41
+ }
42
+ }
43
+ return ok ? EXIT_OK : EXIT_FAIL;
44
+ }
45
+ //# sourceMappingURL=check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check.js","sourceRoot":"","sources":["../../src/commands/check.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,oBAAoB,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAEtE,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,GAAW,EAAE,OAA2B;IACrE,MAAM,MAAM,GAAa,EAAE,CAAC;IAE5B,IAAI,CAAC;QACH,UAAU,CAAC,GAAG,CAAC,CAAC;IAClB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,IAAI,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IAChE,CAAC;IAED,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAC;QACtC,MAAM,QAAQ,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;QACrC,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,QAAQ,CAAC,EAAE,CAAC;YAC/B,MAAM,CAAC,IAAI,CAAC,WAAW,QAAQ,EAAE,CAAC,CAAC;QACrC,CAAC;aAAM,CAAC;YACN,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,CAAC;YACtD,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,YAAY,UAAU,CAAC,cAAc,EAAE,CAAC,EAAE,CAAC;gBAC3D,MAAM,CAAC,IAAI,CAAC,GAAG,QAAQ,gBAAgB,UAAU,CAAC,cAAc,IAAI,CAAC,CAAC;YACxE,CAAC;QACH,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,IAAI,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IAChE,CAAC;IAED,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC;IAC/B,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACvD,CAAC;SAAM,IAAI,EAAE,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;IACrD,CAAC;SAAM,CAAC;QACN,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IACD,OAAO,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;AAClC,CAAC"}
@@ -0,0 +1,8 @@
1
+ export interface DoctorCheck {
2
+ id: string;
3
+ ok: boolean;
4
+ message: string;
5
+ }
6
+ export declare function runDoctorChecks(cwd: string): DoctorCheck[];
7
+ export declare function runDoctor(cwd: string, json?: boolean): Promise<number>;
8
+ //# sourceMappingURL=doctor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAcA,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,EAAE,CA6C1D;AAED,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAW5E"}
@@ -0,0 +1,62 @@
1
+ import { existsSync } from "node:fs";
2
+ import { dirname, join } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import { createProjectContext } from "../core/project.js";
5
+ import { CONFIG_FILE, DIST_DIR, EXIT_FAIL, EXIT_OK, MIN_NODE_MAJOR, TEMPLATE_INIT_DIR, TEMPLATES_DIRNAME, } from "../core/constants.js";
6
+ export function runDoctorChecks(cwd) {
7
+ const checks = [];
8
+ const nodeMajor = Number(process.versions.node.split(".")[0]);
9
+ checks.push({
10
+ id: "node",
11
+ ok: nodeMajor >= MIN_NODE_MAJOR,
12
+ message: nodeMajor >= MIN_NODE_MAJOR
13
+ ? `Node ${process.version}`
14
+ : `Node ${process.version} is below engines (>=${MIN_NODE_MAJOR})`,
15
+ });
16
+ try {
17
+ createProjectContext(cwd);
18
+ checks.push({ id: "project", ok: true, message: "Aether project context loads" });
19
+ }
20
+ catch (err) {
21
+ checks.push({
22
+ id: "project",
23
+ ok: false,
24
+ message: err instanceof Error ? err.message : String(err),
25
+ });
26
+ }
27
+ const cliRoot = join(dirname(fileURLToPath(import.meta.url)), "../..");
28
+ const templatesDist = join(cliRoot, DIST_DIR, TEMPLATES_DIRNAME, TEMPLATE_INIT_DIR);
29
+ checks.push({
30
+ id: "templates",
31
+ ok: existsSync(templatesDist),
32
+ message: existsSync(templatesDist)
33
+ ? `Packaged templates present (${DIST_DIR}/${TEMPLATES_DIRNAME})`
34
+ : `Run npm run build to copy templates into ${DIST_DIR}/`,
35
+ });
36
+ const configPath = join(cwd, CONFIG_FILE);
37
+ if (existsSync(configPath)) {
38
+ checks.push({ id: "config", ok: true, message: `${CONFIG_FILE} found` });
39
+ }
40
+ else {
41
+ checks.push({
42
+ id: "config",
43
+ ok: true,
44
+ message: `${CONFIG_FILE} missing (defaults apply after init)`,
45
+ });
46
+ }
47
+ return checks;
48
+ }
49
+ export async function runDoctor(cwd, json) {
50
+ const checks = runDoctorChecks(cwd);
51
+ const ok = checks.every((c) => c.ok);
52
+ if (json) {
53
+ console.log(JSON.stringify({ ok, checks }, null, 2));
54
+ }
55
+ else {
56
+ for (const c of checks) {
57
+ console.log(`${c.ok ? "ok" : "fail"} ${c.id}: ${c.message}`);
58
+ }
59
+ }
60
+ return ok ? EXIT_OK : EXIT_FAIL;
61
+ }
62
+ //# sourceMappingURL=doctor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import { type GeneratorName } from "../core/constants.js";
2
+ export declare function runGenerate(kind: Exclude<GeneratorName, "project">, name: string | undefined, options: {
3
+ crud?: boolean;
4
+ singular?: string;
5
+ tests?: boolean;
6
+ specPath?: string;
7
+ strict?: boolean;
8
+ only?: string[];
9
+ force?: boolean;
10
+ global?: boolean;
11
+ dryRun?: boolean;
12
+ json?: boolean;
13
+ diff?: boolean;
14
+ }): Promise<void>;
15
+ //# sourceMappingURL=generate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/commands/generate.ts"],"names":[],"mappings":"AAEA,OAAO,EAAa,KAAK,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAKrE,wBAAsB,WAAW,CAC/B,IAAI,EAAE,OAAO,CAAC,aAAa,EAAE,SAAS,CAAC,EACvC,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,OAAO,EAAE;IACP,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,GACA,OAAO,CAAC,IAAI,CAAC,CAuCf"}
@@ -0,0 +1,51 @@
1
+ import { commitPlan } from "../core/plan.js";
2
+ import { createProjectContext } from "../core/project.js";
3
+ import { GENERATOR } from "../core/constants.js";
4
+ import { middlewareGenerator } from "../generators/middleware.js";
5
+ import { openapiGenerator } from "../generators/openapi.js";
6
+ import { resourceGenerator } from "../generators/resource.js";
7
+ export async function runGenerate(kind, name, options) {
8
+ const ctx = createProjectContext(process.cwd());
9
+ let ops;
10
+ if (kind === GENERATOR.middleware) {
11
+ if (!name)
12
+ throw new Error("Middleware name is required.");
13
+ ops = await middlewareGenerator.plan(ctx, { name, force: options.force, global: options.global });
14
+ }
15
+ else if (kind === GENERATOR.openapi) {
16
+ if (!options.specPath)
17
+ throw new Error("OpenAPI spec path is required.");
18
+ ops = await openapiGenerator.plan(ctx, {
19
+ specPath: options.specPath,
20
+ force: options.force,
21
+ strict: options.strict,
22
+ only: options.only,
23
+ });
24
+ }
25
+ else {
26
+ if (!name)
27
+ throw new Error("Resource name is required.");
28
+ ops = await resourceGenerator.plan(ctx, {
29
+ name,
30
+ crud: options.crud,
31
+ singular: options.singular,
32
+ tests: options.tests,
33
+ force: options.force,
34
+ });
35
+ }
36
+ await commitPlan(ctx.root, ops, {
37
+ dryRun: options.dryRun,
38
+ force: options.force,
39
+ json: options.json,
40
+ showDiff: options.diff,
41
+ });
42
+ if (!options.dryRun && !options.json) {
43
+ if (kind === GENERATOR.openapi) {
44
+ console.log(`Generated from OpenAPI "${options.specPath}"`);
45
+ }
46
+ else {
47
+ console.log(`Generated ${kind} "${name}"`);
48
+ }
49
+ }
50
+ }
51
+ //# sourceMappingURL=generate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate.js","sourceRoot":"","sources":["../../src/commands/generate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAsB,MAAM,sBAAsB,CAAC;AACrE,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAE9D,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,IAAuC,EACvC,IAAwB,EACxB,OAYC;IAED,MAAM,GAAG,GAAG,oBAAoB,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAEhD,IAAI,GAAG,CAAC;IACR,IAAI,IAAI,KAAK,SAAS,CAAC,UAAU,EAAE,CAAC;QAClC,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;QAC3D,GAAG,GAAG,MAAM,mBAAmB,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACpG,CAAC;SAAM,IAAI,IAAI,KAAK,SAAS,CAAC,OAAO,EAAE,CAAC;QACtC,IAAI,CAAC,OAAO,CAAC,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;QACzE,GAAG,GAAG,MAAM,gBAAgB,CAAC,IAAI,CAAC,GAAG,EAAE;YACrC,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,IAAI,EAAE,OAAO,CAAC,IAAI;SACnB,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;QACzD,GAAG,GAAG,MAAM,iBAAiB,CAAC,IAAI,CAAC,GAAG,EAAE;YACtC,IAAI;YACJ,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,KAAK,EAAE,OAAO,CAAC,KAAK;SACrB,CAAC,CAAC;IACL,CAAC;IAED,MAAM,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,EAAE;QAC9B,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,QAAQ,EAAE,OAAO,CAAC,IAAI;KACvB,CAAC,CAAC;IACH,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QACrC,IAAI,IAAI,KAAK,SAAS,CAAC,OAAO,EAAE,CAAC;YAC/B,OAAO,CAAC,GAAG,CAAC,2BAA2B,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QAC9D,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,KAAK,IAAI,GAAG,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,6 @@
1
+ export declare function resolveHelpGuidePath(): string;
2
+ export declare function runHelp(options: {
3
+ json?: boolean;
4
+ color?: boolean;
5
+ }): number;
6
+ //# sourceMappingURL=help.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../../src/commands/help.ts"],"names":[],"mappings":"AAYA,wBAAgB,oBAAoB,IAAI,MAAM,CAW7C;AA8BD,wBAAgB,OAAO,CAAC,OAAO,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,MAAM,CAY5E"}
@@ -0,0 +1,60 @@
1
+ import { readFileSync, existsSync } from "node:fs";
2
+ import { dirname, join } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import { CLI_NAME, EXIT_OK } from "../core/constants.js";
5
+ import { ChiselError, ErrorCode } from "../core/errors.js";
6
+ const ESC = "\x1b";
7
+ const bold = (s) => `${ESC}[1m${s}${ESC}[0m`;
8
+ const dim = (s) => `${ESC}[2m${s}${ESC}[0m`;
9
+ const cyan = (s) => `${ESC}[36m${s}${ESC}[0m`;
10
+ const green = (s) => `${ESC}[32m${s}${ESC}[0m`;
11
+ export function resolveHelpGuidePath() {
12
+ const here = dirname(fileURLToPath(import.meta.url));
13
+ const packaged = join(here, "..", "help", "guide.txt");
14
+ if (existsSync(packaged)) {
15
+ return packaged;
16
+ }
17
+ const dev = join(here, "..", "..", "help", "guide.txt");
18
+ if (existsSync(dev)) {
19
+ return dev;
20
+ }
21
+ throw new ChiselError(ErrorCode.NOT_FOUND, "Help guide missing. Run npm run build.");
22
+ }
23
+ function paintGuide(raw, color) {
24
+ if (!color) {
25
+ return raw;
26
+ }
27
+ return raw
28
+ .split("\n")
29
+ .map((line) => {
30
+ if (line.includes("┌") || line.includes("└") || line.includes("│")) {
31
+ return cyan(line);
32
+ }
33
+ if (/^ [A-Z][A-Z0-9 ]+$/.test(line)) {
34
+ return bold(cyan(line.trimEnd()));
35
+ }
36
+ if (/^ ─/.test(line)) {
37
+ return dim(line);
38
+ }
39
+ if (line.startsWith(` ${CLI_NAME} `)) {
40
+ return ` ${green(CLI_NAME)}${line.slice(` ${CLI_NAME}`.length)}`;
41
+ }
42
+ if (line.startsWith(` ${CLI_NAME} `)) {
43
+ return ` ${green(CLI_NAME)}${line.slice(` ${CLI_NAME}`.length)}`;
44
+ }
45
+ return line;
46
+ })
47
+ .join("\n");
48
+ }
49
+ export function runHelp(options) {
50
+ const path = resolveHelpGuidePath();
51
+ const text = readFileSync(path, "utf8");
52
+ const useColor = options.color !== false && process.stdout.isTTY;
53
+ if (options.json) {
54
+ console.log(JSON.stringify({ ok: true, guide: text.trim() }, null, 2));
55
+ return EXIT_OK;
56
+ }
57
+ console.log(paintGuide(text, useColor).trimEnd());
58
+ return EXIT_OK;
59
+ }
60
+ //# sourceMappingURL=help.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"help.js","sourceRoot":"","sources":["../../src/commands/help.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export declare function runInit(cwd: string, options: {
2
+ force?: boolean;
3
+ dryRun?: boolean;
4
+ json?: boolean;
5
+ diff?: boolean;
6
+ }): Promise<void>;
7
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAIA,wBAAsB,OAAO,CAC3B,GAAG,EAAE,MAAM,EACX,OAAO,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAC7E,OAAO,CAAC,IAAI,CAAC,CAmBf"}
@@ -0,0 +1,24 @@
1
+ import { commitPlan } from "../core/plan.js";
2
+ import { projectGenerator } from "../generators/project.js";
3
+ import { CONFIG_VERSION, DEFAULT_APP_ENTRY, DEFAULT_SRC_DIR } from "../core/constants.js";
4
+ export async function runInit(cwd, options) {
5
+ const ctx = {
6
+ root: cwd,
7
+ config: { version: CONFIG_VERSION, srcDir: DEFAULT_SRC_DIR, appEntry: DEFAULT_APP_ENTRY },
8
+ appEntryPath: "",
9
+ };
10
+ const ops = await projectGenerator.plan(ctx, {
11
+ targetRoot: cwd,
12
+ force: options.force,
13
+ });
14
+ await commitPlan(cwd, ops, {
15
+ dryRun: options.dryRun,
16
+ force: options.force,
17
+ json: options.json,
18
+ showDiff: options.diff,
19
+ });
20
+ if (!options.dryRun && !options.json) {
21
+ console.log("Project initialized. Run npm install && npm run dev");
22
+ }
23
+ }
24
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAE1F,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,GAAW,EACX,OAA8E;IAE9E,MAAM,GAAG,GAAG;QACV,IAAI,EAAE,GAAG;QACT,MAAM,EAAE,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,eAAe,EAAE,QAAQ,EAAE,iBAAiB,EAAE;QACzF,YAAY,EAAE,EAAE;KACjB,CAAC;IACF,MAAM,GAAG,GAAG,MAAM,gBAAgB,CAAC,IAAI,CAAC,GAAG,EAAE;QAC3C,UAAU,EAAE,GAAG;QACf,KAAK,EAAE,OAAO,CAAC,KAAK;KACrB,CAAC,CAAC;IACH,MAAM,UAAU,CAAC,GAAG,EAAE,GAAG,EAAE;QACzB,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,QAAQ,EAAE,OAAO,CAAC,IAAI;KACvB,CAAC,CAAC;IACH,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QACrC,OAAO,CAAC,GAAG,CAAC,qDAAqD,CAAC,CAAC;IACrE,CAAC;AACH,CAAC"}
@@ -0,0 +1,5 @@
1
+ export declare function runUpgrade(cwd: string, options: {
2
+ dryRun?: boolean;
3
+ json?: boolean;
4
+ }): Promise<number>;
5
+ //# sourceMappingURL=upgrade.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upgrade.d.ts","sourceRoot":"","sources":["../../src/commands/upgrade.ts"],"names":[],"mappings":"AAMA,wBAAsB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAoC5G"}