@velajs/cli 1.22.0 → 1.23.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.
- package/README.md +29 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +86 -4
- package/dist/index.js.map +1 -1
- package/package.json +6 -5
- package/templates/worker/.swcrc +10 -0
- package/templates/worker/README.md +38 -0
- package/templates/worker/gitignore +8 -0
- package/templates/worker/package.json +28 -0
- package/templates/worker/pnpm-workspace.yaml +4 -0
- package/templates/worker/src/app.controller.ts +12 -0
- package/templates/worker/src/app.module.ts +9 -0
- package/templates/worker/src/app.service.ts +8 -0
- package/templates/worker/src/worker.ts +7 -0
- package/templates/worker/tsconfig.json +18 -0
- package/templates/worker/wrangler.jsonc +12 -0
package/README.md
CHANGED
|
@@ -14,6 +14,7 @@ pnpm add -D @velajs/cli
|
|
|
14
14
|
|
|
15
15
|
| Command | What it does |
|
|
16
16
|
| --- | --- |
|
|
17
|
+
| `vela new my-api` | Create a minimal Workers project with a module, controller, injected service, and a working local development setup. |
|
|
17
18
|
| `vela db seed` | Build the app and run all `@Seeder()` classes in order. |
|
|
18
19
|
| `vela route list` | HTTP route table: framework-composed controller routes (`Controller#handler`, full paths incl. prefix/version) plus `(mounted)` extras (CRUD/contributed, doc UIs). |
|
|
19
20
|
| `vela module graph` | Module graph: imports tree with `global`/`lazy` flags and provider counts (`--json` for the raw graph). |
|
|
@@ -24,6 +25,34 @@ pnpm add -D @velajs/cli
|
|
|
24
25
|
|
|
25
26
|
All introspection commands take `--config <path>`; the four listing/dump commands also take `--json`.
|
|
26
27
|
|
|
28
|
+
### Create a project
|
|
29
|
+
|
|
30
|
+
Requires Node.js 24+ and pnpm 11.11.0:
|
|
31
|
+
|
|
32
|
+
```sh
|
|
33
|
+
pnpm dlx @velajs/cli@latest new my-api
|
|
34
|
+
cd my-api
|
|
35
|
+
pnpm install
|
|
36
|
+
pnpm typecheck
|
|
37
|
+
pnpm build
|
|
38
|
+
pnpm dev
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Request `http://localhost:8787` to receive `{"message":"Hello from Vela!"}`.
|
|
42
|
+
The greeting comes from a constructor-injected service. SWC emits decorator
|
|
43
|
+
metadata, and Wrangler rebuilds source changes during local development.
|
|
44
|
+
The generated application uses published npm dependencies and requires no
|
|
45
|
+
Cloudflare login, authentication integration, D1, Studio, or live queries.
|
|
46
|
+
|
|
47
|
+
With an installed CLI, use `vela new my-api`. Names start with a lowercase letter
|
|
48
|
+
and contain lowercase letters, digits, or single hyphens (at most 63 characters).
|
|
49
|
+
Paths and reserved device names are rejected. Existing empty directories are
|
|
50
|
+
accepted; nonempty directories, files, and symbolic links are rejected without
|
|
51
|
+
overwriting them. Creation does not install dependencies or initialize Git.
|
|
52
|
+
|
|
53
|
+
See the [project creation guide](https://github.com/velajs/vela/blob/main/docs/getting-started.md).
|
|
54
|
+
Module, controller, service, and resource generators are not included yet.
|
|
55
|
+
|
|
27
56
|
### MCP server
|
|
28
57
|
|
|
29
58
|
`vela mcp serve` builds the app from `vela.config` and speaks the [Model Context
|
package/dist/index.d.ts
CHANGED
|
@@ -13,6 +13,14 @@ export declare class SeedCommand extends Command {
|
|
|
13
13
|
execute(): Promise<number>;
|
|
14
14
|
}
|
|
15
15
|
//#endregion
|
|
16
|
+
//#region src/commands/new.command.d.ts
|
|
17
|
+
export declare class NewCommand extends Command {
|
|
18
|
+
static paths: string[][];
|
|
19
|
+
static usage: import("clipanion").Usage;
|
|
20
|
+
name: string;
|
|
21
|
+
execute(): Promise<number>;
|
|
22
|
+
}
|
|
23
|
+
//#endregion
|
|
16
24
|
//#region src/commands/introspect.commands.d.ts
|
|
17
25
|
/** Shared shell: load config → createApp → run → best-effort dispose. */
|
|
18
26
|
declare abstract class AppCommand extends Command {
|
package/dist/index.js
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { defineVelaConfig, loadConfig } from "./config.js";
|
|
3
3
|
import { t as generateClientContract } from "./client-contract-C7P2btFE.js";
|
|
4
|
-
import { Builtins, Cli, Command, Option } from "clipanion";
|
|
5
|
-
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
4
|
+
import { Builtins, Cli, Command, Option, UsageError } from "clipanion";
|
|
5
|
+
import { lstat, mkdir, open, readFile, readdir, rmdir, unlink, writeFile } from "node:fs/promises";
|
|
6
6
|
import { createOpenApiDocument, describeToken, getEntrypointKinds } from "@velajs/vela";
|
|
7
7
|
import { dirname, join } from "node:path";
|
|
8
8
|
import { fileURLToPath } from "node:url";
|
|
9
9
|
import { z } from "zod";
|
|
10
10
|
import { runSeeders } from "@velajs/vela/seeder";
|
|
11
|
+
//#region package.json
|
|
12
|
+
var version = "1.23.0";
|
|
13
|
+
//#endregion
|
|
11
14
|
//#region src/format.ts
|
|
12
15
|
/**
|
|
13
16
|
* Render seeder results to a logger and return a process exit code
|
|
@@ -626,14 +629,93 @@ var ClientGenerateCommand = class extends Command {
|
|
|
626
629
|
}
|
|
627
630
|
};
|
|
628
631
|
//#endregion
|
|
632
|
+
//#region src/new-project.ts
|
|
633
|
+
const template = new URL("../templates/worker/", import.meta.url);
|
|
634
|
+
const files = [
|
|
635
|
+
"package.json",
|
|
636
|
+
"pnpm-workspace.yaml",
|
|
637
|
+
"tsconfig.json",
|
|
638
|
+
".swcrc",
|
|
639
|
+
"wrangler.jsonc",
|
|
640
|
+
"gitignore",
|
|
641
|
+
"README.md",
|
|
642
|
+
"src/worker.ts",
|
|
643
|
+
"src/app.module.ts",
|
|
644
|
+
"src/app.controller.ts",
|
|
645
|
+
"src/app.service.ts"
|
|
646
|
+
];
|
|
647
|
+
function hasCode(error, code) {
|
|
648
|
+
return error instanceof Error && "code" in error && error.code === code;
|
|
649
|
+
}
|
|
650
|
+
async function createProject(name, cwd) {
|
|
651
|
+
if (name.length > 63 || name !== name.trim() || !/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/.test(name) || /^(con|prn|aux|nul|com[1-9]|lpt[1-9])$/.test(name)) throw new UsageError("Use a project name of at most 63 lowercase letters, digits, and single hyphens, starting with a letter. Paths and reserved device names are not supported.");
|
|
652
|
+
const contents = await Promise.all(files.map(async (file) => ({
|
|
653
|
+
file: file === "gitignore" ? ".gitignore" : file,
|
|
654
|
+
content: (await readFile(new URL(file, template), "utf8")).replaceAll("__PROJECT_NAME__", name)
|
|
655
|
+
})));
|
|
656
|
+
const destination = join(cwd, name);
|
|
657
|
+
const directories = [];
|
|
658
|
+
const written = [];
|
|
659
|
+
try {
|
|
660
|
+
try {
|
|
661
|
+
await mkdir(destination);
|
|
662
|
+
directories.push(destination);
|
|
663
|
+
} catch (error) {
|
|
664
|
+
if (!hasCode(error, "EEXIST")) throw error;
|
|
665
|
+
const stat = await lstat(destination);
|
|
666
|
+
if (stat.isSymbolicLink() || !stat.isDirectory()) throw new UsageError(`Destination is not a regular directory: ${destination}`);
|
|
667
|
+
if ((await readdir(destination)).length) throw new UsageError(`Destination is not empty: ${destination}. Choose a new project name.`);
|
|
668
|
+
}
|
|
669
|
+
const source = join(destination, "src");
|
|
670
|
+
await mkdir(source);
|
|
671
|
+
directories.push(source);
|
|
672
|
+
for (const { file, content } of contents) {
|
|
673
|
+
const path = join(destination, file);
|
|
674
|
+
const handle = await open(path, "wx");
|
|
675
|
+
written.push(path);
|
|
676
|
+
try {
|
|
677
|
+
await writeFile(handle, content, "utf8");
|
|
678
|
+
} finally {
|
|
679
|
+
await handle.close();
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
} catch (error) {
|
|
683
|
+
for (const path of written.toReversed()) await unlink(path).catch(() => {});
|
|
684
|
+
for (const path of directories.toReversed()) await rmdir(path).catch(() => {});
|
|
685
|
+
throw error;
|
|
686
|
+
}
|
|
687
|
+
return destination;
|
|
688
|
+
}
|
|
689
|
+
//#endregion
|
|
690
|
+
//#region src/commands/new.command.ts
|
|
691
|
+
var NewCommand = class extends Command {
|
|
692
|
+
static paths = [["new"]];
|
|
693
|
+
static usage = Command.Usage({
|
|
694
|
+
category: "Project",
|
|
695
|
+
description: "Create a minimal Vela application for Cloudflare Workers.",
|
|
696
|
+
details: "Creates a directory in the current working directory. An existing directory must be empty. Dependencies are installed separately with pnpm install.",
|
|
697
|
+
examples: [["Create an API", "vela new my-api"]]
|
|
698
|
+
});
|
|
699
|
+
name = Option.String({
|
|
700
|
+
name: "name",
|
|
701
|
+
required: true
|
|
702
|
+
});
|
|
703
|
+
async execute() {
|
|
704
|
+
await createProject(this.name, process.cwd());
|
|
705
|
+
this.context.stdout.write(`Created ${this.name}.\n\nNext steps:\n cd ${this.name}\n pnpm install\n pnpm typecheck\n pnpm build\n pnpm dev\n\nThen visit http://localhost:8787 or run: curl http://localhost:8787\n`);
|
|
706
|
+
return 0;
|
|
707
|
+
}
|
|
708
|
+
};
|
|
709
|
+
//#endregion
|
|
629
710
|
//#region src/index.ts
|
|
630
711
|
const cli = new Cli({
|
|
631
712
|
binaryName: "vela",
|
|
632
713
|
binaryLabel: "Vela CLI",
|
|
633
|
-
binaryVersion:
|
|
714
|
+
binaryVersion: version
|
|
634
715
|
});
|
|
635
716
|
cli.register(Builtins.HelpCommand);
|
|
636
717
|
cli.register(Builtins.VersionCommand);
|
|
718
|
+
cli.register(NewCommand);
|
|
637
719
|
cli.register(SeedCommand);
|
|
638
720
|
cli.register(RouteListCommand);
|
|
639
721
|
cli.register(ModuleGraphCommand);
|
|
@@ -644,6 +726,6 @@ cli.register(StudioCommand);
|
|
|
644
726
|
cli.register(ClientGenerateCommand);
|
|
645
727
|
cli.runExit(process.argv.slice(2));
|
|
646
728
|
//#endregion
|
|
647
|
-
export { ClientGenerateCommand, EntrypointListCommand, McpServeCommand, ModuleGraphCommand, OpenApiDumpCommand, RouteListCommand, SeedCommand, StudioCommand, collectEntrypoints, collectModules, collectRoutes, defineVelaConfig, formatSeedResults, generateClientContract, loadConfig, renderModuleTree, renderTable };
|
|
729
|
+
export { ClientGenerateCommand, EntrypointListCommand, McpServeCommand, ModuleGraphCommand, NewCommand, OpenApiDumpCommand, RouteListCommand, SeedCommand, StudioCommand, collectEntrypoints, collectModules, collectRoutes, defineVelaConfig, formatSeedResults, generateClientContract, loadConfig, renderModuleTree, renderTable };
|
|
648
730
|
|
|
649
731
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["describeToken"],"sources":["../src/format.ts","../src/introspect.ts","../src/commands/introspect.commands.ts","../src/commands/mcp.command.ts","../src/commands/seed.command.ts","../src/commands/studio.command.ts","../src/commands/client.command.ts","../src/index.ts"],"sourcesContent":["import type { SeederResult } from '@velajs/vela/seeder';\n\n/**\n * Render seeder results to a logger and return a process exit code\n * (0 = all ran, 1 = at least one failed). Pure — no I/O beyond the logger.\n */\nexport function formatSeedResults(\n results: SeederResult[],\n log: (message: string) => void = (m) => console.log(m),\n): number {\n if (results.length === 0) {\n log('No seeders found.');\n return 0;\n }\n\n let failed = 0;\n for (const result of results) {\n if (result.ok) {\n log(` ✓ ${result.name}`);\n } else {\n failed++;\n log(` ✗ ${result.name}${result.error ? `: ${errorMessage(result.error)}` : ''}`);\n }\n }\n\n const total = results.length;\n log(`\\n${total - failed}/${total} seeders ran successfully.`);\n return failed > 0 ? 1 : 0;\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\n/** Aligned plain-text table. Pure; returns lines. */\nexport function renderTable(headers: string[], rows: string[][]): string[] {\n const widths = headers.map((h, i) => Math.max(h.length, ...rows.map((r) => (r[i] ?? '').length)));\n const line = (cells: string[]): string =>\n cells\n .map((c, i) => (c ?? '').padEnd(widths[i]!))\n .join(' ')\n .trimEnd();\n return [line(headers), line(widths.map((w) => '-'.repeat(w))), ...rows.map(line)];\n}\n","import type { VelaApplication } from '@velajs/vela';\nimport { describeToken, getEntrypointKinds } from '@velajs/vela';\nimport type { ModuleDescription, RouteDescription } from '@velajs/vela';\n\n/** One row of `vela route list`. */\nexport interface RouteRow {\n method: string;\n path: string;\n /** `Controller#handler`, or `(mounted)` for routes vela did not compose\n * itself (RouteContributor/CRUD, OpenAPI UI mounts, manual Hono routes). */\n handler: string;\n source: 'controller' | 'mounted';\n}\n\n/**\n * The app's route table: `describeRoutes()` rows (framework-composed truth)\n * plus everything else present on the Hono router, deduped and labeled\n * `(mounted)`. Returns null when the app never built HTTP routes.\n */\nexport function collectRoutes(app: VelaApplication): RouteRow[] | null {\n let described: RouteDescription[];\n try {\n described = app.describeRoutes();\n } catch {\n return null; // no HTTP routes built (slim/non-HTTP app)\n }\n\n const rows: RouteRow[] = described.map((r) => ({\n method: r.method,\n path: r.path,\n handler: `${r.controller}#${r.handler}`,\n source: 'controller',\n }));\n\n const covered = new Set(described.map((r) => `${r.method} ${r.path}`));\n for (const r of described) {\n // @Head handlers are served by Hono under GET — claim that row too so it\n // doesn't reappear as a mounted duplicate.\n if (r.method === 'HEAD') covered.add(`GET ${r.path}`);\n }\n\n const seenMounted = new Set<string>();\n for (const honoRoute of app.getHonoApp().routes) {\n // 'ALL' entries are middleware mounts (framework-internal disposal/context\n // wrappers, global + scoped middleware) — not endpoints.\n if (honoRoute.method === 'ALL') continue;\n const key = `${honoRoute.method} ${honoRoute.path}`;\n if (covered.has(key) || seenMounted.has(key)) continue;\n seenMounted.add(key);\n rows.push({\n method: honoRoute.method,\n path: honoRoute.path,\n handler: '(mounted)',\n source: 'mounted',\n });\n }\n\n return rows.sort((a, b) => a.path.localeCompare(b.path) || a.method.localeCompare(b.method));\n}\n\n/** `vela module graph` tree lines (or raw descriptions for --json). */\nexport function collectModules(app: VelaApplication): ModuleDescription[] {\n return app.getContainer().getModuleDescriptions();\n}\n\nexport function renderModuleTree(modules: ModuleDescription[]): string[] {\n const byId = new Map(modules.map((m) => [m.moduleId, m]));\n const imported = new Set(modules.flatMap((m) => m.imports));\n const roots = modules.filter((m) => !imported.has(m.moduleId));\n\n const lines: string[] = [];\n const render = (id: string, depth: number, trail: Set<string>): void => {\n const mod = byId.get(id);\n const flags = mod\n ? [mod.isGlobal ? 'global' : null, mod.lazy ? 'lazy' : null].filter(Boolean)\n : [];\n const suffix = flags.length > 0 ? ` (${flags.join(', ')})` : '';\n const providers = mod\n ? ` — ${mod.providers.length} provider${mod.providers.length === 1 ? '' : 's'}`\n : '';\n lines.push(`${' '.repeat(depth)}${id}${suffix}${providers}`);\n if (!mod || trail.has(id)) return;\n const nextTrail = new Set(trail).add(id);\n for (const child of mod.imports) render(child, depth + 1, nextTrail);\n };\n\n for (const root of roots) render(root.moduleId, 0, new Set());\n return lines;\n}\n\n/** One row of `vela entrypoint list`. */\nexport interface EntrypointRow {\n kind: string;\n target: string;\n meta: string;\n}\n\nfunction safeMeta(meta: unknown): string {\n try {\n return (\n JSON.stringify(meta, (_key, value: unknown) =>\n typeof value === 'function'\n ? '[function]'\n : typeof value === 'object' &&\n value !== null &&\n value.constructor !== Object &&\n !Array.isArray(value)\n ? `[${(value as object).constructor.name}]`\n : value,\n ) ?? 'undefined'\n );\n } catch {\n return '[unserializable]';\n }\n}\n\n/**\n * Every DECLARED entrypoint kind (from the global kind store — includes kinds\n * with zero entries) joined with the app's entries. Metadata-only entries of\n * lazy modules list fine; nothing materializes.\n */\nexport function collectEntrypoints(app: VelaApplication): EntrypointRow[] {\n const rows: EntrypointRow[] = [];\n const declared = getEntrypointKinds().map((k: { kind: string }) => k.kind);\n const populated = app.entrypoints.kinds();\n const kinds = [...new Set([...declared, ...populated])];\n\n for (const kind of kinds) {\n const entries = app.entrypoints.ofKind(kind);\n if (entries.length === 0) {\n rows.push({ kind, target: '(no entrypoints)', meta: '' });\n continue;\n }\n for (const ep of entries) {\n const method = ep.methodName !== undefined ? `#${String(ep.methodName)}` : '';\n rows.push({ kind, target: `${describeToken(ep.token)}${method}`, meta: safeMeta(ep.meta) });\n }\n }\n return rows;\n}\n","import { writeFile } from 'node:fs/promises';\nimport { createOpenApiDocument } from '@velajs/vela';\nimport type { VelaApplication } from '@velajs/vela';\nimport { Command, Option } from 'clipanion';\nimport { loadConfig } from '../config.js';\nimport { renderTable } from '../format.js';\nimport {\n collectEntrypoints,\n collectModules,\n collectRoutes,\n renderModuleTree,\n} from '../introspect.js';\n\n/** Shared shell: load config → createApp → run → best-effort dispose. */\nabstract class AppCommand extends Command {\n config = Option.String('--config', { description: 'Path to the vela config file.' });\n json = Option.Boolean('--json', false, { description: 'Emit machine-readable JSON.' });\n\n protected abstract run(app: VelaApplication): Promise<number>;\n\n async execute(): Promise<number> {\n const velaConfig = await loadConfig(process.cwd(), this.config);\n const app = await velaConfig.createApp();\n try {\n return await this.run(app);\n } finally {\n const dispose = (app as { dispose?: () => Promise<void> }).dispose;\n if (typeof dispose === 'function') {\n try {\n await dispose.call(app);\n } catch (error) {\n this.context.stderr.write(`Warning: teardown failed: ${String(error)}\\n`);\n }\n }\n }\n }\n\n protected print(text: string): void {\n this.context.stdout.write(`${text}\\n`);\n }\n}\n\n/** `vela route list` — the app's HTTP route table. */\nexport class RouteListCommand extends AppCommand {\n static override paths = [['route', 'list']];\n static override usage = Command.Usage({\n category: 'Introspection',\n description: 'List the HTTP routes of the Vela app.',\n details:\n 'Framework-composed controller routes (method, full path, controller#handler) plus ' +\n 'everything else mounted on the router (CRUD/contributed routes, doc UIs) labeled (mounted).',\n examples: [\n ['List routes', 'vela route list'],\n ['As JSON', 'vela route list --json'],\n ],\n });\n\n protected async run(app: VelaApplication): Promise<number> {\n const rows = collectRoutes(app);\n if (rows === null) {\n this.print('This app builds no HTTP routes — nothing to list.');\n return 0;\n }\n if (this.json) {\n this.print(JSON.stringify(rows, null, 2));\n return 0;\n }\n for (const line of renderTable(\n ['METHOD', 'PATH', 'HANDLER'],\n rows.map((r) => [r.method, r.path, r.handler]),\n )) {\n this.print(line);\n }\n return 0;\n }\n}\n\n/** `vela module graph` — the loaded module graph. */\nexport class ModuleGraphCommand extends AppCommand {\n static override paths = [['module', 'graph']];\n static override usage = Command.Usage({\n category: 'Introspection',\n description: 'Print the module graph of the Vela app.',\n details:\n 'Module instances with their imports (indented tree), global/lazy flags, and provider ' +\n 'counts. --json emits the raw descriptions (providers, exports, imports per module).',\n examples: [\n ['Print the graph', 'vela module graph'],\n ['As JSON', 'vela module graph --json'],\n ],\n });\n\n protected async run(app: VelaApplication): Promise<number> {\n const modules = collectModules(app);\n if (this.json) {\n this.print(JSON.stringify(modules, null, 2));\n return 0;\n }\n for (const line of renderModuleTree(modules)) this.print(line);\n return 0;\n }\n}\n\n/** `vela entrypoint list` — declared entrypoint kinds and their entries. */\nexport class EntrypointListCommand extends AppCommand {\n static override paths = [['entrypoint', 'list']];\n static override usage = Command.Usage({\n category: 'Introspection',\n description: 'List entrypoint kinds and entries (websocket, queue, cron, …).',\n details:\n 'Every declared kind — including kinds with zero entries — with the contributing ' +\n 'class (and method for method-level kinds) and its metadata.',\n examples: [['List entrypoints', 'vela entrypoint list']],\n });\n\n protected async run(app: VelaApplication): Promise<number> {\n const rows = collectEntrypoints(app);\n if (this.json) {\n this.print(JSON.stringify(rows, null, 2));\n return 0;\n }\n for (const line of renderTable(\n ['KIND', 'TARGET', 'META'],\n rows.map((r) => [r.kind, r.target, r.meta]),\n )) {\n this.print(line);\n }\n return 0;\n }\n}\n\n/** `vela openapi dump` — emit the OpenAPI document. */\nexport class OpenApiDumpCommand extends Command {\n static override paths = [['openapi', 'dump']];\n static override usage = Command.Usage({\n category: 'Introspection',\n description: 'Emit the OpenAPI document for the Vela app.',\n details:\n 'Requires `rootModule` in vela.config (createOpenApiDocument works from the module ' +\n \"class). The app's global prefix is applied automatically; --global-prefix overrides.\",\n examples: [\n ['Print to stdout', 'vela openapi dump'],\n ['Write to a file', 'vela openapi dump --out openapi.json'],\n ],\n });\n\n config = Option.String('--config', { description: 'Path to the vela config file.' });\n out = Option.String('--out', {\n description: 'Write the document to this file instead of stdout.',\n });\n title = Option.String('--title', { description: 'info.title override.' });\n apiVersion = Option.String('--api-version', { description: 'info.version override.' });\n globalPrefix = Option.String('--global-prefix', {\n description: \"Path prefix override (defaults to the app's global prefix).\",\n });\n\n async execute(): Promise<number> {\n const velaConfig = await loadConfig(process.cwd(), this.config);\n if (!velaConfig.rootModule) {\n this.context.stderr.write(\n 'openapi dump needs the root module. Add it to your vela.config:\\n\\n' +\n ' export default defineVelaConfig({\\n' +\n ' rootModule: AppModule,\\n' +\n ' async createApp() { ... },\\n' +\n ' });\\n',\n );\n return 1;\n }\n\n const app = await velaConfig.createApp();\n try {\n const info: Record<string, string> = {};\n if (this.title) info.title = this.title;\n if (this.apiVersion) info.version = this.apiVersion;\n\n const document = createOpenApiDocument(velaConfig.rootModule, {\n globalPrefix: this.globalPrefix ?? app.getGlobalPrefix(),\n ...(Object.keys(info).length > 0 ? { info } : {}),\n });\n\n const text = JSON.stringify(document, null, 2);\n if (this.out) {\n await writeFile(this.out, `${text}\\n`, 'utf8');\n this.context.stdout.write(`Wrote ${this.out}\\n`);\n } else {\n this.context.stdout.write(`${text}\\n`);\n }\n return 0;\n } finally {\n const dispose = (app as { dispose?: () => Promise<void> }).dispose;\n if (typeof dispose === 'function') {\n try {\n await dispose.call(app);\n } catch (error) {\n this.context.stderr.write(`Warning: teardown failed: ${String(error)}\\n`);\n }\n }\n }\n }\n}\n","import { readFile } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { createOpenApiDocument } from '@velajs/vela';\nimport type { Type, VelaApplication } from '@velajs/vela';\nimport { Command, Option } from 'clipanion';\nimport { z } from 'zod';\nimport { loadConfig } from '../config.js';\nimport {\n collectEntrypoints,\n collectModules,\n collectRoutes,\n renderModuleTree,\n} from '../introspect.js';\n\nconst OPENAPI_URI = 'vela://openapi';\n\n/** A single JSON text block — the shape every tool/resource result uses. */\nfunction jsonText(data: unknown): { content: { type: 'text'; text: string }[] } {\n return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };\n}\n\n/** An MCP tool error result (JSON-RPC stays 2.0; the failure is in-band). */\nfunction toolError(message: string): { isError: true; content: { type: 'text'; text: string }[] } {\n return { isError: true, content: [{ type: 'text', text: message }] };\n}\n\n/** Name + version for the MCP server handshake, read from the CLI's own package.json. */\nasync function readCliIdentity(): Promise<{ name: string; version: string }> {\n const here = dirname(fileURLToPath(import.meta.url));\n // tsdown bundles this module into dist/index.js; source-mode tests load it\n // from src/commands/mcp.command.ts. Support both locations without relying\n // on a fixed output depth.\n for (const pkgPath of [\n join(here, '..', 'package.json'),\n join(here, '..', '..', 'package.json'),\n ]) {\n try {\n const pkg = JSON.parse(await readFile(pkgPath, 'utf8')) as {\n name?: string;\n version?: string;\n };\n return { name: pkg.name ?? '@velajs/cli', version: pkg.version ?? '0.0.0' };\n } catch (error) {\n if ((error as { code?: string }).code !== 'ENOENT') throw error;\n }\n }\n return { name: '@velajs/cli', version: '0.0.0' };\n}\n\n/**\n * String-label lookup for a DI token across the module graph. Reads only the\n * serializable descriptions (`collectModules`) — never resolves the token or\n * constructs anything. Reports which modules provide/export it and their scope\n * flags, plus whether the string names a module itself.\n */\nfunction describeToken(app: VelaApplication, token: string): unknown {\n const modules = collectModules(app);\n const providedBy = modules\n .filter((m) => m.providers.includes(token))\n .map((m) => ({\n moduleId: m.moduleId,\n isGlobal: m.isGlobal,\n lazy: m.lazy,\n exported: m.exports.includes(token),\n }));\n const matchesModule = modules.find((m) => m.moduleId === token);\n return {\n token,\n found: providedBy.length > 0 || matchesModule !== undefined,\n providedBy,\n module: matchesModule\n ? {\n moduleId: matchesModule.moduleId,\n isGlobal: matchesModule.isGlobal,\n lazy: matchesModule.lazy,\n }\n : null,\n };\n}\n\n/**\n * `vela mcp serve` — an MCP stdio server exposing the same READ-ONLY\n * introspection as the `route`/`module`/`entrypoint`/`openapi` commands, so an\n * AI agent can query a Vela app's shape over the Model Context Protocol.\n *\n * Deliberately does NOT extend `AppCommand`: that base disposes the app in its\n * `finally` the moment `run()` returns, but an MCP server must stay alive until\n * the transport closes. stdout is reserved for JSON-RPC framing; every human\n * message goes to stderr.\n */\nexport class McpServeCommand extends Command {\n static override paths = [['mcp', 'serve']];\n static override usage = Command.Usage({\n category: 'Introspection',\n description: 'Serve Vela introspection as MCP tools over stdio (for AI agents).',\n details:\n 'Builds the app from vela.config and runs a Model Context Protocol stdio server. Exposes ' +\n 'read-only tools (route_list, module_graph, entrypoint_list, openapi_dump, token_describe) ' +\n 'and — when the config declares a rootModule — a `vela://openapi` resource. stdout carries ' +\n 'only JSON-RPC; all logging goes to stderr. The server runs until the client disconnects.',\n examples: [\n ['Serve over stdio', 'vela mcp serve'],\n ['Use a specific config', 'vela mcp serve --config ./config/vela.config.js'],\n ],\n });\n\n config = Option.String('--config', { description: 'Path to the vela config file.' });\n\n async execute(): Promise<number> {\n const { McpServer } = await import('@modelcontextprotocol/sdk/server/mcp.js');\n const { StdioServerTransport } = await import('@modelcontextprotocol/sdk/server/stdio.js');\n\n const log = (message: string): void => {\n this.context.stderr.write(`${message}\\n`);\n };\n\n const velaConfig = await loadConfig(process.cwd(), this.config);\n const app = await velaConfig.createApp();\n const rootModule: Type | undefined = velaConfig.rootModule;\n\n try {\n const identity = await readCliIdentity();\n const server = new McpServer(identity);\n\n server.registerTool(\n 'route_list',\n {\n description:\n \"The app's HTTP route table: framework-composed controller routes (method, full \" +\n 'path, Controller#handler) plus everything else mounted on the router, labeled ' +\n '(mounted). Empty when the app builds no HTTP routes.',\n inputSchema: {},\n },\n () => jsonText(collectRoutes(app) ?? []),\n );\n\n server.registerTool(\n 'module_graph',\n {\n description:\n 'The loaded module graph as serializable descriptions (providers, exports, imports, ' +\n 'global/lazy flags). Pass tree=true to also get the rendered import tree lines.',\n inputSchema: { tree: z.boolean().optional() },\n },\n ({ tree }) => {\n const modules = collectModules(app);\n return jsonText(tree ? { modules, tree: renderModuleTree(modules) } : modules);\n },\n );\n\n server.registerTool(\n 'entrypoint_list',\n {\n description:\n 'Every declared entrypoint kind (websocket, queue, cron, …) with its entries and ' +\n 'metadata — including kinds with zero entries. Lazy modules stay unmaterialized.',\n inputSchema: {},\n },\n () => jsonText(collectEntrypoints(app)),\n );\n\n server.registerTool(\n 'openapi_dump',\n {\n description:\n 'The OpenAPI 3.1 document for the app. Requires a rootModule in vela.config. ' +\n 'globalPrefix/title/apiVersion override the defaults (the app global prefix and ' +\n 'the module-derived info).',\n inputSchema: {\n globalPrefix: z.string().optional(),\n title: z.string().optional(),\n apiVersion: z.string().optional(),\n },\n },\n ({ globalPrefix, title, apiVersion }) => {\n if (!rootModule) {\n return toolError(\n 'openapi_dump needs the root module. Add `rootModule: AppModule` to your vela.config.',\n );\n }\n const info: Record<string, string> = {};\n if (title) info.title = title;\n if (apiVersion) info.version = apiVersion;\n const document = createOpenApiDocument(rootModule, {\n globalPrefix: globalPrefix ?? app.getGlobalPrefix(),\n ...(Object.keys(info).length > 0 ? { info } : {}),\n });\n return jsonText(document);\n },\n );\n\n server.registerTool(\n 'token_describe',\n {\n description:\n 'Look a DI token STRING LABEL up across the module graph: which modules provide/export ' +\n 'it and their scope flags, plus whether the string names a module. Read-only string ' +\n 'match — does not resolve or construct the token.',\n inputSchema: { token: z.string() },\n },\n ({ token }) => jsonText(describeToken(app, token)),\n );\n\n if (rootModule) {\n server.registerResource(\n 'openapi',\n OPENAPI_URI,\n { description: 'The OpenAPI 3.1 document for the app.', mimeType: 'application/json' },\n () => ({\n contents: [\n {\n uri: OPENAPI_URI,\n mimeType: 'application/json',\n text: JSON.stringify(\n createOpenApiDocument(rootModule, { globalPrefix: app.getGlobalPrefix() }),\n null,\n 2,\n ),\n },\n ],\n }),\n );\n }\n\n const transport = new StdioServerTransport();\n const closed = new Promise<void>((resolvePromise) => {\n transport.onclose = resolvePromise;\n });\n await server.connect(transport);\n log(\n `vela mcp serve — ready (5 tools${rootModule ? ' + vela://openapi resource' : ''}). ` +\n 'Awaiting client on stdio; stdout is JSON-RPC only.',\n );\n\n // Keep the process alive until the client disconnects; only then dispose.\n await closed;\n return 0;\n } finally {\n const dispose = (app as { dispose?: () => Promise<void> }).dispose;\n if (typeof dispose === 'function') {\n try {\n await dispose.call(app);\n } catch (error) {\n this.context.stderr.write(`Warning: teardown failed: ${String(error)}\\n`);\n }\n }\n }\n }\n}\n","import { runSeeders } from '@velajs/vela/seeder';\nimport { Command, Option } from 'clipanion';\nimport { loadConfig } from '../config.js';\nimport { formatSeedResults } from '../format.js';\n\n/** `vela db seed` — build the app from vela.config and run its seeders. */\nexport class SeedCommand extends Command {\n static override paths = [['db', 'seed']];\n static override usage = Command.Usage({\n category: 'Database',\n description: 'Run database seeders for the Vela app.',\n details:\n 'Loads vela.config.{js,mjs,ts}, builds the app, and runs all @Seeder() classes in order.',\n examples: [\n ['Run all seeders', 'vela db seed'],\n ['Use a specific config', 'vela db seed --config ./config/vela.config.js'],\n ],\n });\n\n config = Option.String('--config', { description: 'Path to the vela config file.' });\n continueOnError = Option.Boolean('--continue-on-error', false, {\n description: 'Run all seeders even if one fails.',\n });\n\n async execute(): Promise<number> {\n const { createApp } = await loadConfig(process.cwd(), this.config);\n const app = await createApp();\n this.context.stdout.write('Running seeders…\\n');\n\n const results = await runSeeders(app, { stopOnError: !this.continueOnError });\n const code = formatSeedResults(results, (message) => this.context.stdout.write(`${message}\\n`));\n\n // Best-effort teardown (VelaApplication.dispose exists on recent versions).\n // Must not clobber the computed exit code if a shutdown hook throws.\n const dispose = (app as { dispose?: () => Promise<void> }).dispose;\n if (typeof dispose === 'function') {\n try {\n await dispose.call(app);\n } catch (error) {\n this.context.stderr.write(`Warning: teardown failed after seeding: ${String(error)}\\n`);\n }\n }\n\n return code;\n }\n}\n","import { Command, Option } from 'clipanion';\n\n/**\n * The optional peer that does the real work. It is Node-only and heavy, so it is\n * NOT a hard dependency of the CLI — it is lazily imported here and, when it\n * isn't installed, the command prints an install hint (mirroring how\n * `mcp.command` lazily loads its optional peer).\n */\nconst HOST_PACKAGE = '@velajs/studio-host';\n\n/** The slice of `@velajs/studio-host`'s surface this command uses. */\ninterface StudioHostModule {\n startStudioServer(options: {\n workerOrigin: string;\n adminToken?: string;\n port?: number;\n adminPath?: string;\n cwd?: string;\n }): Promise<{ readonly url: string; readonly port: number; close(): Promise<void> }>;\n}\n\n/** True for a failed dynamic `import()` of a missing module (ESM or CJS code). */\nfunction isModuleNotFound(error: unknown, specifier: string): boolean {\n const code = (error as { code?: string }).code;\n if (code === 'ERR_MODULE_NOT_FOUND' || code === 'MODULE_NOT_FOUND') {\n return true;\n }\n // Some resolvers surface only a message; match the specifier defensively.\n const message = error instanceof Error ? error.message : '';\n return message.includes(specifier);\n}\n\n/**\n * `vela studio` — start the loopback dev host that serves Vela Studio and proxies\n * the admin API to a running app.\n *\n * App-origin resolution (v1): the target app is taken from `--url <origin>`,\n * which is REQUIRED. The host proxies `{--path}/*` to that origin, injecting the\n * admin token as `Authorization: Bearer` server-side (the browser never holds\n * it). Booting the app in-process from `vela.config` (via `loadConfig`) is a\n * planned follow-up; requiring `--url` keeps v1 simple and adapter-agnostic.\n */\nexport class StudioCommand extends Command {\n static override paths = [['studio']];\n static override usage = Command.Usage({\n category: 'Studio',\n description: 'Serve Vela Studio locally and proxy the admin API to a running app.',\n details:\n 'Starts a loopback dev host (from the optional @velajs/studio-host peer) that serves the ' +\n 'prebuilt Studio SPA and proxies {--path}/* to the app at --url, injecting the admin token ' +\n 'as a Bearer server-side so the browser never receives it. The token comes from --token or ' +\n 'the VELA_STUDIO_TOKEN environment variable. Runs until interrupted (Ctrl+C).',\n examples: [\n ['Serve against a local worker', 'vela studio --url http://127.0.0.1:8787'],\n [\n 'With an explicit token + port',\n 'vela studio --url http://127.0.0.1:8787 --token $TOKEN --port 4000',\n ],\n ],\n });\n\n url = Option.String('--url', {\n description: 'Origin of the running app to proxy the admin API to (required).',\n });\n token = Option.String('--token', {\n description: 'Admin bearer token (falls back to VELA_STUDIO_TOKEN). Never sent to the browser.',\n });\n port = Option.String('--port', {\n description: 'Loopback port to bind (default: an ephemeral port).',\n });\n adminPath = Option.String('--path', {\n description: 'Server admin-mount prefix to proxy (default: /_vela/admin).',\n });\n\n async execute(): Promise<number> {\n const workerOrigin = this.url;\n if (workerOrigin === undefined || workerOrigin === '') {\n this.context.stderr.write(\n 'vela studio: --url <origin> is required — the running app to proxy the admin API to.\\n' +\n ' Example: vela studio --url http://127.0.0.1:8787\\n',\n );\n return 1;\n }\n if (!URL.canParse(workerOrigin)) {\n this.context.stderr.write(`vela studio: --url is not a valid origin: ${workerOrigin}\\n`);\n return 1;\n }\n\n let port: number | undefined;\n if (this.port !== undefined) {\n port = Number.parseInt(this.port, 10);\n if (Number.isNaN(port) || port < 0 || port > 65_535) {\n this.context.stderr.write(\n `vela studio: --port must be a number 0-65535, got: ${this.port}\\n`,\n );\n return 1;\n }\n }\n\n const adminToken = this.token ?? process.env.VELA_STUDIO_TOKEN;\n\n let host: StudioHostModule;\n try {\n host = (await import(HOST_PACKAGE)) as StudioHostModule;\n } catch (error) {\n if (isModuleNotFound(error, HOST_PACKAGE)) {\n this.context.stderr.write(\n `vela studio needs the optional \"${HOST_PACKAGE}\" package, which isn't installed.\\n` +\n ` Install it: pnpm add -D ${HOST_PACKAGE}\\n` +\n ` (it also needs the prebuilt UI: pnpm add -D @velajs/studio-ui)\\n`,\n );\n return 1;\n }\n throw error;\n }\n\n const server = await host.startStudioServer({\n workerOrigin,\n adminToken,\n port,\n adminPath: this.adminPath,\n cwd: process.cwd(),\n });\n\n this.context.stdout.write(\n `\\n Vela Studio ${server.url}\\n` +\n ` Proxying ${workerOrigin}${this.adminPath ?? '/_vela/admin'}/*\\n` +\n ` Admin token ${adminToken !== undefined ? 'set (injected server-side)' : 'none (app requires none)'}\\n\\n` +\n ' Press Ctrl+C to stop.\\n',\n );\n\n // Run until interrupted. The listener is removed on trigger so a second\n // Ctrl+C during shutdown falls through to Node's default (force-exit).\n await new Promise<void>((resolvePromise) => {\n const onSignal = (): void => {\n process.off('SIGINT', onSignal);\n process.off('SIGTERM', onSignal);\n resolvePromise();\n };\n process.on('SIGINT', onSignal);\n process.on('SIGTERM', onSignal);\n });\n\n await server.close();\n this.context.stdout.write('\\nVela Studio stopped.\\n');\n return 0;\n }\n}\n","import { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { dirname } from 'node:path';\nimport { createOpenApiDocument } from '@velajs/vela';\nimport type { OpenApiDocument } from '@velajs/vela';\nimport { Command, Option } from 'clipanion';\nimport { generateClientContract } from '../client-contract.js';\nimport { loadConfig } from '../config.js';\n\nexport class ClientGenerateCommand extends Command {\n static override paths = [['client', 'generate']];\n static override usage = Command.Usage({\n category: 'Client',\n description: \"Generate a typed HTTP contract for Hono's hc client.\",\n details:\n 'Uses rootModule and createApp from vela.config, or an OpenAPI JSON file with --input. Missing schemas emit unknown and a warning; --strict makes those warnings an error.',\n examples: [\n ['Generate from an app', 'vela client generate --out src/api.generated.ts'],\n [\n 'Generate from a document',\n 'vela client generate --input openapi.json --out src/api.generated.ts',\n ],\n ['Check a committed contract', 'vela client generate --out src/api.generated.ts --check'],\n ],\n });\n\n config = Option.String('--config', { description: 'Path to the vela config file.' });\n input = Option.String('--input', {\n description: 'Read an OpenAPI JSON file without bootstrapping the app.',\n });\n out = Option.String('--out', { description: 'Output TypeScript file (stdout when omitted).' });\n check = Option.Boolean('--check', false, {\n description: 'Fail if --out differs from the generated contract; do not write.',\n });\n strict = Option.Boolean('--strict', false, { description: 'Fail on missing or lossy schemas.' });\n\n async execute(): Promise<number> {\n if (this.input && this.config) throw new Error('Use either --input or --config, not both.');\n if (this.check && !this.out) throw new Error('--check requires --out.');\n const document = this.input ? await this.readDocument(this.input) : await this.fromApp();\n const { source, warnings } = generateClientContract(document);\n for (const warning of warnings) this.context.stderr.write(`Warning: ${warning}\\n`);\n if (this.strict && warnings.length) return 1;\n if (this.check) {\n let existing: string | undefined;\n try {\n existing = await readFile(this.out!, 'utf8');\n } catch (error) {\n if (!(error instanceof Error) || !('code' in error) || error.code !== 'ENOENT') throw error;\n }\n if (existing !== source) {\n this.context.stderr.write(\n `Client contract is missing or stale: ${this.out}. Run vela client generate without --check.\\n`,\n );\n return 1;\n }\n } else if (this.out) {\n await mkdir(dirname(this.out), { recursive: true });\n await writeFile(this.out, source, 'utf8');\n this.context.stdout.write(`Wrote ${this.out}\\n`);\n } else {\n this.context.stdout.write(source);\n }\n return 0;\n }\n\n private async readDocument(file: string): Promise<unknown> {\n const value: unknown = JSON.parse(await readFile(file, 'utf8'));\n // generateClientContract validates the complete consumed projection for\n // both file inputs and documents produced by the running application.\n return value;\n }\n\n private async fromApp(): Promise<OpenApiDocument> {\n const config = await loadConfig(process.cwd(), this.config);\n if (!config.rootModule)\n throw new Error(\n 'client generate needs rootModule in vela.config, or pass --input openapi.json.',\n );\n const app = await config.createApp();\n try {\n const document = createOpenApiDocument(config.rootModule, {\n globalPrefix: app.getGlobalPrefix(),\n });\n // Detect older Vela exporters which omit versioned controller routes.\n // Never silently ship a contract which points at a different endpoint.\n for (const route of app.describeRoutes()) {\n const path = route.path.replace(/:([A-Za-z_][A-Za-z0-9_]*)/g, '{$1}');\n const item = document.paths[path];\n if (!item || !Object.hasOwn(item, route.method.toLowerCase())) {\n throw new Error(\n `OpenAPI is missing ${route.method} ${route.path}. Update Vela or pass a complete document with --input.`,\n );\n }\n }\n return document;\n } finally {\n try {\n await app.dispose();\n } catch (error) {\n this.context.stderr.write(`Warning: teardown failed: ${String(error)}\\n`);\n }\n }\n }\n}\n","#!/usr/bin/env node\nimport { Builtins, Cli } from 'clipanion';\nimport {\n EntrypointListCommand,\n ModuleGraphCommand,\n OpenApiDumpCommand,\n RouteListCommand,\n} from './commands/introspect.commands.js';\nimport { McpServeCommand } from './commands/mcp.command.js';\nimport { SeedCommand } from './commands/seed.command.js';\nimport { StudioCommand } from './commands/studio.command.js';\nimport { ClientGenerateCommand } from './commands/client.command.js';\n\nconst cli = new Cli({\n binaryName: 'vela',\n binaryLabel: 'Vela CLI',\n binaryVersion: '0.2.0',\n});\n\ncli.register(Builtins.HelpCommand);\ncli.register(Builtins.VersionCommand);\ncli.register(SeedCommand);\ncli.register(RouteListCommand);\ncli.register(ModuleGraphCommand);\ncli.register(EntrypointListCommand);\ncli.register(OpenApiDumpCommand);\ncli.register(McpServeCommand);\ncli.register(StudioCommand);\ncli.register(ClientGenerateCommand);\n\nvoid cli.runExit(process.argv.slice(2));\n\nexport { SeedCommand } from './commands/seed.command.js';\nexport {\n EntrypointListCommand,\n ModuleGraphCommand,\n OpenApiDumpCommand,\n RouteListCommand,\n} from './commands/introspect.commands.js';\nexport { McpServeCommand } from './commands/mcp.command.js';\nexport { StudioCommand } from './commands/studio.command.js';\nexport { ClientGenerateCommand } from './commands/client.command.js';\nexport { generateClientContract } from './client-contract.js';\nexport type { GeneratedClientContract } from './client-contract.js';\nexport {\n collectRoutes,\n collectModules,\n collectEntrypoints,\n renderModuleTree,\n} from './introspect.js';\nexport type { RouteRow, EntrypointRow } from './introspect.js';\nexport { renderTable } from './format.js';\nexport { loadConfig, defineVelaConfig } from './config.js';\nexport type { VelaConfig } from './config.js';\nexport { formatSeedResults } from './format.js';\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["describeToken","manifest.version"],"sources":["../package.json","../src/format.ts","../src/introspect.ts","../src/commands/introspect.commands.ts","../src/commands/mcp.command.ts","../src/commands/seed.command.ts","../src/commands/studio.command.ts","../src/commands/client.command.ts","../src/new-project.ts","../src/commands/new.command.ts","../src/index.ts"],"sourcesContent":["","import type { SeederResult } from '@velajs/vela/seeder';\n\n/**\n * Render seeder results to a logger and return a process exit code\n * (0 = all ran, 1 = at least one failed). Pure — no I/O beyond the logger.\n */\nexport function formatSeedResults(\n results: SeederResult[],\n log: (message: string) => void = (m) => console.log(m),\n): number {\n if (results.length === 0) {\n log('No seeders found.');\n return 0;\n }\n\n let failed = 0;\n for (const result of results) {\n if (result.ok) {\n log(` ✓ ${result.name}`);\n } else {\n failed++;\n log(` ✗ ${result.name}${result.error ? `: ${errorMessage(result.error)}` : ''}`);\n }\n }\n\n const total = results.length;\n log(`\\n${total - failed}/${total} seeders ran successfully.`);\n return failed > 0 ? 1 : 0;\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\n/** Aligned plain-text table. Pure; returns lines. */\nexport function renderTable(headers: string[], rows: string[][]): string[] {\n const widths = headers.map((h, i) => Math.max(h.length, ...rows.map((r) => (r[i] ?? '').length)));\n const line = (cells: string[]): string =>\n cells\n .map((c, i) => (c ?? '').padEnd(widths[i]!))\n .join(' ')\n .trimEnd();\n return [line(headers), line(widths.map((w) => '-'.repeat(w))), ...rows.map(line)];\n}\n","import type { VelaApplication } from '@velajs/vela';\nimport { describeToken, getEntrypointKinds } from '@velajs/vela';\nimport type { ModuleDescription, RouteDescription } from '@velajs/vela';\n\n/** One row of `vela route list`. */\nexport interface RouteRow {\n method: string;\n path: string;\n /** `Controller#handler`, or `(mounted)` for routes vela did not compose\n * itself (RouteContributor/CRUD, OpenAPI UI mounts, manual Hono routes). */\n handler: string;\n source: 'controller' | 'mounted';\n}\n\n/**\n * The app's route table: `describeRoutes()` rows (framework-composed truth)\n * plus everything else present on the Hono router, deduped and labeled\n * `(mounted)`. Returns null when the app never built HTTP routes.\n */\nexport function collectRoutes(app: VelaApplication): RouteRow[] | null {\n let described: RouteDescription[];\n try {\n described = app.describeRoutes();\n } catch {\n return null; // no HTTP routes built (slim/non-HTTP app)\n }\n\n const rows: RouteRow[] = described.map((r) => ({\n method: r.method,\n path: r.path,\n handler: `${r.controller}#${r.handler}`,\n source: 'controller',\n }));\n\n const covered = new Set(described.map((r) => `${r.method} ${r.path}`));\n for (const r of described) {\n // @Head handlers are served by Hono under GET — claim that row too so it\n // doesn't reappear as a mounted duplicate.\n if (r.method === 'HEAD') covered.add(`GET ${r.path}`);\n }\n\n const seenMounted = new Set<string>();\n for (const honoRoute of app.getHonoApp().routes) {\n // 'ALL' entries are middleware mounts (framework-internal disposal/context\n // wrappers, global + scoped middleware) — not endpoints.\n if (honoRoute.method === 'ALL') continue;\n const key = `${honoRoute.method} ${honoRoute.path}`;\n if (covered.has(key) || seenMounted.has(key)) continue;\n seenMounted.add(key);\n rows.push({\n method: honoRoute.method,\n path: honoRoute.path,\n handler: '(mounted)',\n source: 'mounted',\n });\n }\n\n return rows.sort((a, b) => a.path.localeCompare(b.path) || a.method.localeCompare(b.method));\n}\n\n/** `vela module graph` tree lines (or raw descriptions for --json). */\nexport function collectModules(app: VelaApplication): ModuleDescription[] {\n return app.getContainer().getModuleDescriptions();\n}\n\nexport function renderModuleTree(modules: ModuleDescription[]): string[] {\n const byId = new Map(modules.map((m) => [m.moduleId, m]));\n const imported = new Set(modules.flatMap((m) => m.imports));\n const roots = modules.filter((m) => !imported.has(m.moduleId));\n\n const lines: string[] = [];\n const render = (id: string, depth: number, trail: Set<string>): void => {\n const mod = byId.get(id);\n const flags = mod\n ? [mod.isGlobal ? 'global' : null, mod.lazy ? 'lazy' : null].filter(Boolean)\n : [];\n const suffix = flags.length > 0 ? ` (${flags.join(', ')})` : '';\n const providers = mod\n ? ` — ${mod.providers.length} provider${mod.providers.length === 1 ? '' : 's'}`\n : '';\n lines.push(`${' '.repeat(depth)}${id}${suffix}${providers}`);\n if (!mod || trail.has(id)) return;\n const nextTrail = new Set(trail).add(id);\n for (const child of mod.imports) render(child, depth + 1, nextTrail);\n };\n\n for (const root of roots) render(root.moduleId, 0, new Set());\n return lines;\n}\n\n/** One row of `vela entrypoint list`. */\nexport interface EntrypointRow {\n kind: string;\n target: string;\n meta: string;\n}\n\nfunction safeMeta(meta: unknown): string {\n try {\n return (\n JSON.stringify(meta, (_key, value: unknown) =>\n typeof value === 'function'\n ? '[function]'\n : typeof value === 'object' &&\n value !== null &&\n value.constructor !== Object &&\n !Array.isArray(value)\n ? `[${(value as object).constructor.name}]`\n : value,\n ) ?? 'undefined'\n );\n } catch {\n return '[unserializable]';\n }\n}\n\n/**\n * Every DECLARED entrypoint kind (from the global kind store — includes kinds\n * with zero entries) joined with the app's entries. Metadata-only entries of\n * lazy modules list fine; nothing materializes.\n */\nexport function collectEntrypoints(app: VelaApplication): EntrypointRow[] {\n const rows: EntrypointRow[] = [];\n const declared = getEntrypointKinds().map((k: { kind: string }) => k.kind);\n const populated = app.entrypoints.kinds();\n const kinds = [...new Set([...declared, ...populated])];\n\n for (const kind of kinds) {\n const entries = app.entrypoints.ofKind(kind);\n if (entries.length === 0) {\n rows.push({ kind, target: '(no entrypoints)', meta: '' });\n continue;\n }\n for (const ep of entries) {\n const method = ep.methodName !== undefined ? `#${String(ep.methodName)}` : '';\n rows.push({ kind, target: `${describeToken(ep.token)}${method}`, meta: safeMeta(ep.meta) });\n }\n }\n return rows;\n}\n","import { writeFile } from 'node:fs/promises';\nimport { createOpenApiDocument } from '@velajs/vela';\nimport type { VelaApplication } from '@velajs/vela';\nimport { Command, Option } from 'clipanion';\nimport { loadConfig } from '../config.js';\nimport { renderTable } from '../format.js';\nimport {\n collectEntrypoints,\n collectModules,\n collectRoutes,\n renderModuleTree,\n} from '../introspect.js';\n\n/** Shared shell: load config → createApp → run → best-effort dispose. */\nabstract class AppCommand extends Command {\n config = Option.String('--config', { description: 'Path to the vela config file.' });\n json = Option.Boolean('--json', false, { description: 'Emit machine-readable JSON.' });\n\n protected abstract run(app: VelaApplication): Promise<number>;\n\n async execute(): Promise<number> {\n const velaConfig = await loadConfig(process.cwd(), this.config);\n const app = await velaConfig.createApp();\n try {\n return await this.run(app);\n } finally {\n const dispose = (app as { dispose?: () => Promise<void> }).dispose;\n if (typeof dispose === 'function') {\n try {\n await dispose.call(app);\n } catch (error) {\n this.context.stderr.write(`Warning: teardown failed: ${String(error)}\\n`);\n }\n }\n }\n }\n\n protected print(text: string): void {\n this.context.stdout.write(`${text}\\n`);\n }\n}\n\n/** `vela route list` — the app's HTTP route table. */\nexport class RouteListCommand extends AppCommand {\n static override paths = [['route', 'list']];\n static override usage = Command.Usage({\n category: 'Introspection',\n description: 'List the HTTP routes of the Vela app.',\n details:\n 'Framework-composed controller routes (method, full path, controller#handler) plus ' +\n 'everything else mounted on the router (CRUD/contributed routes, doc UIs) labeled (mounted).',\n examples: [\n ['List routes', 'vela route list'],\n ['As JSON', 'vela route list --json'],\n ],\n });\n\n protected async run(app: VelaApplication): Promise<number> {\n const rows = collectRoutes(app);\n if (rows === null) {\n this.print('This app builds no HTTP routes — nothing to list.');\n return 0;\n }\n if (this.json) {\n this.print(JSON.stringify(rows, null, 2));\n return 0;\n }\n for (const line of renderTable(\n ['METHOD', 'PATH', 'HANDLER'],\n rows.map((r) => [r.method, r.path, r.handler]),\n )) {\n this.print(line);\n }\n return 0;\n }\n}\n\n/** `vela module graph` — the loaded module graph. */\nexport class ModuleGraphCommand extends AppCommand {\n static override paths = [['module', 'graph']];\n static override usage = Command.Usage({\n category: 'Introspection',\n description: 'Print the module graph of the Vela app.',\n details:\n 'Module instances with their imports (indented tree), global/lazy flags, and provider ' +\n 'counts. --json emits the raw descriptions (providers, exports, imports per module).',\n examples: [\n ['Print the graph', 'vela module graph'],\n ['As JSON', 'vela module graph --json'],\n ],\n });\n\n protected async run(app: VelaApplication): Promise<number> {\n const modules = collectModules(app);\n if (this.json) {\n this.print(JSON.stringify(modules, null, 2));\n return 0;\n }\n for (const line of renderModuleTree(modules)) this.print(line);\n return 0;\n }\n}\n\n/** `vela entrypoint list` — declared entrypoint kinds and their entries. */\nexport class EntrypointListCommand extends AppCommand {\n static override paths = [['entrypoint', 'list']];\n static override usage = Command.Usage({\n category: 'Introspection',\n description: 'List entrypoint kinds and entries (websocket, queue, cron, …).',\n details:\n 'Every declared kind — including kinds with zero entries — with the contributing ' +\n 'class (and method for method-level kinds) and its metadata.',\n examples: [['List entrypoints', 'vela entrypoint list']],\n });\n\n protected async run(app: VelaApplication): Promise<number> {\n const rows = collectEntrypoints(app);\n if (this.json) {\n this.print(JSON.stringify(rows, null, 2));\n return 0;\n }\n for (const line of renderTable(\n ['KIND', 'TARGET', 'META'],\n rows.map((r) => [r.kind, r.target, r.meta]),\n )) {\n this.print(line);\n }\n return 0;\n }\n}\n\n/** `vela openapi dump` — emit the OpenAPI document. */\nexport class OpenApiDumpCommand extends Command {\n static override paths = [['openapi', 'dump']];\n static override usage = Command.Usage({\n category: 'Introspection',\n description: 'Emit the OpenAPI document for the Vela app.',\n details:\n 'Requires `rootModule` in vela.config (createOpenApiDocument works from the module ' +\n \"class). The app's global prefix is applied automatically; --global-prefix overrides.\",\n examples: [\n ['Print to stdout', 'vela openapi dump'],\n ['Write to a file', 'vela openapi dump --out openapi.json'],\n ],\n });\n\n config = Option.String('--config', { description: 'Path to the vela config file.' });\n out = Option.String('--out', {\n description: 'Write the document to this file instead of stdout.',\n });\n title = Option.String('--title', { description: 'info.title override.' });\n apiVersion = Option.String('--api-version', { description: 'info.version override.' });\n globalPrefix = Option.String('--global-prefix', {\n description: \"Path prefix override (defaults to the app's global prefix).\",\n });\n\n async execute(): Promise<number> {\n const velaConfig = await loadConfig(process.cwd(), this.config);\n if (!velaConfig.rootModule) {\n this.context.stderr.write(\n 'openapi dump needs the root module. Add it to your vela.config:\\n\\n' +\n ' export default defineVelaConfig({\\n' +\n ' rootModule: AppModule,\\n' +\n ' async createApp() { ... },\\n' +\n ' });\\n',\n );\n return 1;\n }\n\n const app = await velaConfig.createApp();\n try {\n const info: Record<string, string> = {};\n if (this.title) info.title = this.title;\n if (this.apiVersion) info.version = this.apiVersion;\n\n const document = createOpenApiDocument(velaConfig.rootModule, {\n globalPrefix: this.globalPrefix ?? app.getGlobalPrefix(),\n ...(Object.keys(info).length > 0 ? { info } : {}),\n });\n\n const text = JSON.stringify(document, null, 2);\n if (this.out) {\n await writeFile(this.out, `${text}\\n`, 'utf8');\n this.context.stdout.write(`Wrote ${this.out}\\n`);\n } else {\n this.context.stdout.write(`${text}\\n`);\n }\n return 0;\n } finally {\n const dispose = (app as { dispose?: () => Promise<void> }).dispose;\n if (typeof dispose === 'function') {\n try {\n await dispose.call(app);\n } catch (error) {\n this.context.stderr.write(`Warning: teardown failed: ${String(error)}\\n`);\n }\n }\n }\n }\n}\n","import { readFile } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { createOpenApiDocument } from '@velajs/vela';\nimport type { Type, VelaApplication } from '@velajs/vela';\nimport { Command, Option } from 'clipanion';\nimport { z } from 'zod';\nimport { loadConfig } from '../config.js';\nimport {\n collectEntrypoints,\n collectModules,\n collectRoutes,\n renderModuleTree,\n} from '../introspect.js';\n\nconst OPENAPI_URI = 'vela://openapi';\n\n/** A single JSON text block — the shape every tool/resource result uses. */\nfunction jsonText(data: unknown): { content: { type: 'text'; text: string }[] } {\n return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };\n}\n\n/** An MCP tool error result (JSON-RPC stays 2.0; the failure is in-band). */\nfunction toolError(message: string): { isError: true; content: { type: 'text'; text: string }[] } {\n return { isError: true, content: [{ type: 'text', text: message }] };\n}\n\n/** Name + version for the MCP server handshake, read from the CLI's own package.json. */\nasync function readCliIdentity(): Promise<{ name: string; version: string }> {\n const here = dirname(fileURLToPath(import.meta.url));\n // tsdown bundles this module into dist/index.js; source-mode tests load it\n // from src/commands/mcp.command.ts. Support both locations without relying\n // on a fixed output depth.\n for (const pkgPath of [\n join(here, '..', 'package.json'),\n join(here, '..', '..', 'package.json'),\n ]) {\n try {\n const pkg = JSON.parse(await readFile(pkgPath, 'utf8')) as {\n name?: string;\n version?: string;\n };\n return { name: pkg.name ?? '@velajs/cli', version: pkg.version ?? '0.0.0' };\n } catch (error) {\n if ((error as { code?: string }).code !== 'ENOENT') throw error;\n }\n }\n return { name: '@velajs/cli', version: '0.0.0' };\n}\n\n/**\n * String-label lookup for a DI token across the module graph. Reads only the\n * serializable descriptions (`collectModules`) — never resolves the token or\n * constructs anything. Reports which modules provide/export it and their scope\n * flags, plus whether the string names a module itself.\n */\nfunction describeToken(app: VelaApplication, token: string): unknown {\n const modules = collectModules(app);\n const providedBy = modules\n .filter((m) => m.providers.includes(token))\n .map((m) => ({\n moduleId: m.moduleId,\n isGlobal: m.isGlobal,\n lazy: m.lazy,\n exported: m.exports.includes(token),\n }));\n const matchesModule = modules.find((m) => m.moduleId === token);\n return {\n token,\n found: providedBy.length > 0 || matchesModule !== undefined,\n providedBy,\n module: matchesModule\n ? {\n moduleId: matchesModule.moduleId,\n isGlobal: matchesModule.isGlobal,\n lazy: matchesModule.lazy,\n }\n : null,\n };\n}\n\n/**\n * `vela mcp serve` — an MCP stdio server exposing the same READ-ONLY\n * introspection as the `route`/`module`/`entrypoint`/`openapi` commands, so an\n * AI agent can query a Vela app's shape over the Model Context Protocol.\n *\n * Deliberately does NOT extend `AppCommand`: that base disposes the app in its\n * `finally` the moment `run()` returns, but an MCP server must stay alive until\n * the transport closes. stdout is reserved for JSON-RPC framing; every human\n * message goes to stderr.\n */\nexport class McpServeCommand extends Command {\n static override paths = [['mcp', 'serve']];\n static override usage = Command.Usage({\n category: 'Introspection',\n description: 'Serve Vela introspection as MCP tools over stdio (for AI agents).',\n details:\n 'Builds the app from vela.config and runs a Model Context Protocol stdio server. Exposes ' +\n 'read-only tools (route_list, module_graph, entrypoint_list, openapi_dump, token_describe) ' +\n 'and — when the config declares a rootModule — a `vela://openapi` resource. stdout carries ' +\n 'only JSON-RPC; all logging goes to stderr. The server runs until the client disconnects.',\n examples: [\n ['Serve over stdio', 'vela mcp serve'],\n ['Use a specific config', 'vela mcp serve --config ./config/vela.config.js'],\n ],\n });\n\n config = Option.String('--config', { description: 'Path to the vela config file.' });\n\n async execute(): Promise<number> {\n const { McpServer } = await import('@modelcontextprotocol/sdk/server/mcp.js');\n const { StdioServerTransport } = await import('@modelcontextprotocol/sdk/server/stdio.js');\n\n const log = (message: string): void => {\n this.context.stderr.write(`${message}\\n`);\n };\n\n const velaConfig = await loadConfig(process.cwd(), this.config);\n const app = await velaConfig.createApp();\n const rootModule: Type | undefined = velaConfig.rootModule;\n\n try {\n const identity = await readCliIdentity();\n const server = new McpServer(identity);\n\n server.registerTool(\n 'route_list',\n {\n description:\n \"The app's HTTP route table: framework-composed controller routes (method, full \" +\n 'path, Controller#handler) plus everything else mounted on the router, labeled ' +\n '(mounted). Empty when the app builds no HTTP routes.',\n inputSchema: {},\n },\n () => jsonText(collectRoutes(app) ?? []),\n );\n\n server.registerTool(\n 'module_graph',\n {\n description:\n 'The loaded module graph as serializable descriptions (providers, exports, imports, ' +\n 'global/lazy flags). Pass tree=true to also get the rendered import tree lines.',\n inputSchema: { tree: z.boolean().optional() },\n },\n ({ tree }) => {\n const modules = collectModules(app);\n return jsonText(tree ? { modules, tree: renderModuleTree(modules) } : modules);\n },\n );\n\n server.registerTool(\n 'entrypoint_list',\n {\n description:\n 'Every declared entrypoint kind (websocket, queue, cron, …) with its entries and ' +\n 'metadata — including kinds with zero entries. Lazy modules stay unmaterialized.',\n inputSchema: {},\n },\n () => jsonText(collectEntrypoints(app)),\n );\n\n server.registerTool(\n 'openapi_dump',\n {\n description:\n 'The OpenAPI 3.1 document for the app. Requires a rootModule in vela.config. ' +\n 'globalPrefix/title/apiVersion override the defaults (the app global prefix and ' +\n 'the module-derived info).',\n inputSchema: {\n globalPrefix: z.string().optional(),\n title: z.string().optional(),\n apiVersion: z.string().optional(),\n },\n },\n ({ globalPrefix, title, apiVersion }) => {\n if (!rootModule) {\n return toolError(\n 'openapi_dump needs the root module. Add `rootModule: AppModule` to your vela.config.',\n );\n }\n const info: Record<string, string> = {};\n if (title) info.title = title;\n if (apiVersion) info.version = apiVersion;\n const document = createOpenApiDocument(rootModule, {\n globalPrefix: globalPrefix ?? app.getGlobalPrefix(),\n ...(Object.keys(info).length > 0 ? { info } : {}),\n });\n return jsonText(document);\n },\n );\n\n server.registerTool(\n 'token_describe',\n {\n description:\n 'Look a DI token STRING LABEL up across the module graph: which modules provide/export ' +\n 'it and their scope flags, plus whether the string names a module. Read-only string ' +\n 'match — does not resolve or construct the token.',\n inputSchema: { token: z.string() },\n },\n ({ token }) => jsonText(describeToken(app, token)),\n );\n\n if (rootModule) {\n server.registerResource(\n 'openapi',\n OPENAPI_URI,\n { description: 'The OpenAPI 3.1 document for the app.', mimeType: 'application/json' },\n () => ({\n contents: [\n {\n uri: OPENAPI_URI,\n mimeType: 'application/json',\n text: JSON.stringify(\n createOpenApiDocument(rootModule, { globalPrefix: app.getGlobalPrefix() }),\n null,\n 2,\n ),\n },\n ],\n }),\n );\n }\n\n const transport = new StdioServerTransport();\n const closed = new Promise<void>((resolvePromise) => {\n transport.onclose = resolvePromise;\n });\n await server.connect(transport);\n log(\n `vela mcp serve — ready (5 tools${rootModule ? ' + vela://openapi resource' : ''}). ` +\n 'Awaiting client on stdio; stdout is JSON-RPC only.',\n );\n\n // Keep the process alive until the client disconnects; only then dispose.\n await closed;\n return 0;\n } finally {\n const dispose = (app as { dispose?: () => Promise<void> }).dispose;\n if (typeof dispose === 'function') {\n try {\n await dispose.call(app);\n } catch (error) {\n this.context.stderr.write(`Warning: teardown failed: ${String(error)}\\n`);\n }\n }\n }\n }\n}\n","import { runSeeders } from '@velajs/vela/seeder';\nimport { Command, Option } from 'clipanion';\nimport { loadConfig } from '../config.js';\nimport { formatSeedResults } from '../format.js';\n\n/** `vela db seed` — build the app from vela.config and run its seeders. */\nexport class SeedCommand extends Command {\n static override paths = [['db', 'seed']];\n static override usage = Command.Usage({\n category: 'Database',\n description: 'Run database seeders for the Vela app.',\n details:\n 'Loads vela.config.{js,mjs,ts}, builds the app, and runs all @Seeder() classes in order.',\n examples: [\n ['Run all seeders', 'vela db seed'],\n ['Use a specific config', 'vela db seed --config ./config/vela.config.js'],\n ],\n });\n\n config = Option.String('--config', { description: 'Path to the vela config file.' });\n continueOnError = Option.Boolean('--continue-on-error', false, {\n description: 'Run all seeders even if one fails.',\n });\n\n async execute(): Promise<number> {\n const { createApp } = await loadConfig(process.cwd(), this.config);\n const app = await createApp();\n this.context.stdout.write('Running seeders…\\n');\n\n const results = await runSeeders(app, { stopOnError: !this.continueOnError });\n const code = formatSeedResults(results, (message) => this.context.stdout.write(`${message}\\n`));\n\n // Best-effort teardown (VelaApplication.dispose exists on recent versions).\n // Must not clobber the computed exit code if a shutdown hook throws.\n const dispose = (app as { dispose?: () => Promise<void> }).dispose;\n if (typeof dispose === 'function') {\n try {\n await dispose.call(app);\n } catch (error) {\n this.context.stderr.write(`Warning: teardown failed after seeding: ${String(error)}\\n`);\n }\n }\n\n return code;\n }\n}\n","import { Command, Option } from 'clipanion';\n\n/**\n * The optional peer that does the real work. It is Node-only and heavy, so it is\n * NOT a hard dependency of the CLI — it is lazily imported here and, when it\n * isn't installed, the command prints an install hint (mirroring how\n * `mcp.command` lazily loads its optional peer).\n */\nconst HOST_PACKAGE = '@velajs/studio-host';\n\n/** The slice of `@velajs/studio-host`'s surface this command uses. */\ninterface StudioHostModule {\n startStudioServer(options: {\n workerOrigin: string;\n adminToken?: string;\n port?: number;\n adminPath?: string;\n cwd?: string;\n }): Promise<{ readonly url: string; readonly port: number; close(): Promise<void> }>;\n}\n\n/** True for a failed dynamic `import()` of a missing module (ESM or CJS code). */\nfunction isModuleNotFound(error: unknown, specifier: string): boolean {\n const code = (error as { code?: string }).code;\n if (code === 'ERR_MODULE_NOT_FOUND' || code === 'MODULE_NOT_FOUND') {\n return true;\n }\n // Some resolvers surface only a message; match the specifier defensively.\n const message = error instanceof Error ? error.message : '';\n return message.includes(specifier);\n}\n\n/**\n * `vela studio` — start the loopback dev host that serves Vela Studio and proxies\n * the admin API to a running app.\n *\n * App-origin resolution (v1): the target app is taken from `--url <origin>`,\n * which is REQUIRED. The host proxies `{--path}/*` to that origin, injecting the\n * admin token as `Authorization: Bearer` server-side (the browser never holds\n * it). Booting the app in-process from `vela.config` (via `loadConfig`) is a\n * planned follow-up; requiring `--url` keeps v1 simple and adapter-agnostic.\n */\nexport class StudioCommand extends Command {\n static override paths = [['studio']];\n static override usage = Command.Usage({\n category: 'Studio',\n description: 'Serve Vela Studio locally and proxy the admin API to a running app.',\n details:\n 'Starts a loopback dev host (from the optional @velajs/studio-host peer) that serves the ' +\n 'prebuilt Studio SPA and proxies {--path}/* to the app at --url, injecting the admin token ' +\n 'as a Bearer server-side so the browser never receives it. The token comes from --token or ' +\n 'the VELA_STUDIO_TOKEN environment variable. Runs until interrupted (Ctrl+C).',\n examples: [\n ['Serve against a local worker', 'vela studio --url http://127.0.0.1:8787'],\n [\n 'With an explicit token + port',\n 'vela studio --url http://127.0.0.1:8787 --token $TOKEN --port 4000',\n ],\n ],\n });\n\n url = Option.String('--url', {\n description: 'Origin of the running app to proxy the admin API to (required).',\n });\n token = Option.String('--token', {\n description: 'Admin bearer token (falls back to VELA_STUDIO_TOKEN). Never sent to the browser.',\n });\n port = Option.String('--port', {\n description: 'Loopback port to bind (default: an ephemeral port).',\n });\n adminPath = Option.String('--path', {\n description: 'Server admin-mount prefix to proxy (default: /_vela/admin).',\n });\n\n async execute(): Promise<number> {\n const workerOrigin = this.url;\n if (workerOrigin === undefined || workerOrigin === '') {\n this.context.stderr.write(\n 'vela studio: --url <origin> is required — the running app to proxy the admin API to.\\n' +\n ' Example: vela studio --url http://127.0.0.1:8787\\n',\n );\n return 1;\n }\n if (!URL.canParse(workerOrigin)) {\n this.context.stderr.write(`vela studio: --url is not a valid origin: ${workerOrigin}\\n`);\n return 1;\n }\n\n let port: number | undefined;\n if (this.port !== undefined) {\n port = Number.parseInt(this.port, 10);\n if (Number.isNaN(port) || port < 0 || port > 65_535) {\n this.context.stderr.write(\n `vela studio: --port must be a number 0-65535, got: ${this.port}\\n`,\n );\n return 1;\n }\n }\n\n const adminToken = this.token ?? process.env.VELA_STUDIO_TOKEN;\n\n let host: StudioHostModule;\n try {\n host = (await import(HOST_PACKAGE)) as StudioHostModule;\n } catch (error) {\n if (isModuleNotFound(error, HOST_PACKAGE)) {\n this.context.stderr.write(\n `vela studio needs the optional \"${HOST_PACKAGE}\" package, which isn't installed.\\n` +\n ` Install it: pnpm add -D ${HOST_PACKAGE}\\n` +\n ` (it also needs the prebuilt UI: pnpm add -D @velajs/studio-ui)\\n`,\n );\n return 1;\n }\n throw error;\n }\n\n const server = await host.startStudioServer({\n workerOrigin,\n adminToken,\n port,\n adminPath: this.adminPath,\n cwd: process.cwd(),\n });\n\n this.context.stdout.write(\n `\\n Vela Studio ${server.url}\\n` +\n ` Proxying ${workerOrigin}${this.adminPath ?? '/_vela/admin'}/*\\n` +\n ` Admin token ${adminToken !== undefined ? 'set (injected server-side)' : 'none (app requires none)'}\\n\\n` +\n ' Press Ctrl+C to stop.\\n',\n );\n\n // Run until interrupted. The listener is removed on trigger so a second\n // Ctrl+C during shutdown falls through to Node's default (force-exit).\n await new Promise<void>((resolvePromise) => {\n const onSignal = (): void => {\n process.off('SIGINT', onSignal);\n process.off('SIGTERM', onSignal);\n resolvePromise();\n };\n process.on('SIGINT', onSignal);\n process.on('SIGTERM', onSignal);\n });\n\n await server.close();\n this.context.stdout.write('\\nVela Studio stopped.\\n');\n return 0;\n }\n}\n","import { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { dirname } from 'node:path';\nimport { createOpenApiDocument } from '@velajs/vela';\nimport type { OpenApiDocument } from '@velajs/vela';\nimport { Command, Option } from 'clipanion';\nimport { generateClientContract } from '../client-contract.js';\nimport { loadConfig } from '../config.js';\n\nexport class ClientGenerateCommand extends Command {\n static override paths = [['client', 'generate']];\n static override usage = Command.Usage({\n category: 'Client',\n description: \"Generate a typed HTTP contract for Hono's hc client.\",\n details:\n 'Uses rootModule and createApp from vela.config, or an OpenAPI JSON file with --input. Missing schemas emit unknown and a warning; --strict makes those warnings an error.',\n examples: [\n ['Generate from an app', 'vela client generate --out src/api.generated.ts'],\n [\n 'Generate from a document',\n 'vela client generate --input openapi.json --out src/api.generated.ts',\n ],\n ['Check a committed contract', 'vela client generate --out src/api.generated.ts --check'],\n ],\n });\n\n config = Option.String('--config', { description: 'Path to the vela config file.' });\n input = Option.String('--input', {\n description: 'Read an OpenAPI JSON file without bootstrapping the app.',\n });\n out = Option.String('--out', { description: 'Output TypeScript file (stdout when omitted).' });\n check = Option.Boolean('--check', false, {\n description: 'Fail if --out differs from the generated contract; do not write.',\n });\n strict = Option.Boolean('--strict', false, { description: 'Fail on missing or lossy schemas.' });\n\n async execute(): Promise<number> {\n if (this.input && this.config) throw new Error('Use either --input or --config, not both.');\n if (this.check && !this.out) throw new Error('--check requires --out.');\n const document = this.input ? await this.readDocument(this.input) : await this.fromApp();\n const { source, warnings } = generateClientContract(document);\n for (const warning of warnings) this.context.stderr.write(`Warning: ${warning}\\n`);\n if (this.strict && warnings.length) return 1;\n if (this.check) {\n let existing: string | undefined;\n try {\n existing = await readFile(this.out!, 'utf8');\n } catch (error) {\n if (!(error instanceof Error) || !('code' in error) || error.code !== 'ENOENT') throw error;\n }\n if (existing !== source) {\n this.context.stderr.write(\n `Client contract is missing or stale: ${this.out}. Run vela client generate without --check.\\n`,\n );\n return 1;\n }\n } else if (this.out) {\n await mkdir(dirname(this.out), { recursive: true });\n await writeFile(this.out, source, 'utf8');\n this.context.stdout.write(`Wrote ${this.out}\\n`);\n } else {\n this.context.stdout.write(source);\n }\n return 0;\n }\n\n private async readDocument(file: string): Promise<unknown> {\n const value: unknown = JSON.parse(await readFile(file, 'utf8'));\n // generateClientContract validates the complete consumed projection for\n // both file inputs and documents produced by the running application.\n return value;\n }\n\n private async fromApp(): Promise<OpenApiDocument> {\n const config = await loadConfig(process.cwd(), this.config);\n if (!config.rootModule)\n throw new Error(\n 'client generate needs rootModule in vela.config, or pass --input openapi.json.',\n );\n const app = await config.createApp();\n try {\n const document = createOpenApiDocument(config.rootModule, {\n globalPrefix: app.getGlobalPrefix(),\n });\n // Detect older Vela exporters which omit versioned controller routes.\n // Never silently ship a contract which points at a different endpoint.\n for (const route of app.describeRoutes()) {\n const path = route.path.replace(/:([A-Za-z_][A-Za-z0-9_]*)/g, '{$1}');\n const item = document.paths[path];\n if (!item || !Object.hasOwn(item, route.method.toLowerCase())) {\n throw new Error(\n `OpenAPI is missing ${route.method} ${route.path}. Update Vela or pass a complete document with --input.`,\n );\n }\n }\n return document;\n } finally {\n try {\n await app.dispose();\n } catch (error) {\n this.context.stderr.write(`Warning: teardown failed: ${String(error)}\\n`);\n }\n }\n }\n}\n","import { lstat, mkdir, open, readFile, readdir, rmdir, unlink, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { UsageError } from 'clipanion';\n\nconst template = new URL('../templates/worker/', import.meta.url);\nconst files = [\n 'package.json',\n 'pnpm-workspace.yaml',\n 'tsconfig.json',\n '.swcrc',\n 'wrangler.jsonc',\n 'gitignore',\n 'README.md',\n 'src/worker.ts',\n 'src/app.module.ts',\n 'src/app.controller.ts',\n 'src/app.service.ts',\n] as const;\n\nfunction hasCode(error: unknown, code: string): boolean {\n return error instanceof Error && 'code' in error && error.code === code;\n}\n\nexport async function createProject(name: string, cwd: string): Promise<string> {\n if (\n name.length > 63 ||\n name !== name.trim() ||\n !/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/.test(name) ||\n /^(con|prn|aux|nul|com[1-9]|lpt[1-9])$/.test(name)\n ) {\n throw new UsageError(\n 'Use a project name of at most 63 lowercase letters, digits, and single hyphens, starting with a letter. Paths and reserved device names are not supported.',\n );\n }\n\n // Read the entire packaged template before touching the destination.\n const contents = await Promise.all(\n files.map(async (file) => ({\n file: file === 'gitignore' ? '.gitignore' : file,\n content: (await readFile(new URL(file, template), 'utf8')).replaceAll(\n '__PROJECT_NAME__',\n name,\n ),\n })),\n );\n const destination = join(cwd, name);\n const directories: string[] = [];\n const written: string[] = [];\n try {\n try {\n await mkdir(destination);\n directories.push(destination);\n } catch (error) {\n if (!hasCode(error, 'EEXIST')) throw error;\n const stat = await lstat(destination);\n if (stat.isSymbolicLink() || !stat.isDirectory()) {\n throw new UsageError(`Destination is not a regular directory: ${destination}`);\n }\n if ((await readdir(destination)).length) {\n throw new UsageError(\n `Destination is not empty: ${destination}. Choose a new project name.`,\n );\n }\n }\n const source = join(destination, 'src');\n await mkdir(source);\n directories.push(source);\n for (const { file, content } of contents) {\n const path = join(destination, file);\n // Never overwrite a file, even if it appeared after the initial check.\n const handle = await open(path, 'wx');\n written.push(path);\n try {\n await writeFile(handle, content, 'utf8');\n } finally {\n await handle.close();\n }\n }\n } catch (error) {\n // Only undo our own writes; rmdir leaves directories containing other files intact.\n for (const path of written.toReversed()) await unlink(path).catch(() => {});\n for (const path of directories.toReversed()) await rmdir(path).catch(() => {});\n throw error;\n }\n return destination;\n}\n","import { Command, Option } from 'clipanion';\nimport { createProject } from '../new-project.js';\n\nexport class NewCommand extends Command {\n static override paths = [['new']];\n static override usage = Command.Usage({\n category: 'Project',\n description: 'Create a minimal Vela application for Cloudflare Workers.',\n details:\n 'Creates a directory in the current working directory. An existing directory must be empty. Dependencies are installed separately with pnpm install.',\n examples: [['Create an API', 'vela new my-api']],\n });\n\n name = Option.String({ name: 'name', required: true });\n\n async execute(): Promise<number> {\n await createProject(this.name, process.cwd());\n this.context.stdout.write(\n `Created ${this.name}.\\n\\nNext steps:\\n cd ${this.name}\\n pnpm install\\n pnpm typecheck\\n pnpm build\\n pnpm dev\\n\\nThen visit http://localhost:8787 or run: curl http://localhost:8787\\n`,\n );\n return 0;\n }\n}\n","#!/usr/bin/env node\nimport { Builtins, Cli } from 'clipanion';\nimport manifest from '../package.json' with { type: 'json' };\nimport {\n EntrypointListCommand,\n ModuleGraphCommand,\n OpenApiDumpCommand,\n RouteListCommand,\n} from './commands/introspect.commands.js';\nimport { McpServeCommand } from './commands/mcp.command.js';\nimport { SeedCommand } from './commands/seed.command.js';\nimport { StudioCommand } from './commands/studio.command.js';\nimport { ClientGenerateCommand } from './commands/client.command.js';\nimport { NewCommand } from './commands/new.command.js';\n\nconst cli = new Cli({\n binaryName: 'vela',\n binaryLabel: 'Vela CLI',\n binaryVersion: manifest.version,\n});\n\ncli.register(Builtins.HelpCommand);\ncli.register(Builtins.VersionCommand);\ncli.register(NewCommand);\ncli.register(SeedCommand);\ncli.register(RouteListCommand);\ncli.register(ModuleGraphCommand);\ncli.register(EntrypointListCommand);\ncli.register(OpenApiDumpCommand);\ncli.register(McpServeCommand);\ncli.register(StudioCommand);\ncli.register(ClientGenerateCommand);\n\nvoid cli.runExit(process.argv.slice(2));\n\nexport { SeedCommand } from './commands/seed.command.js';\nexport { NewCommand } from './commands/new.command.js';\nexport {\n EntrypointListCommand,\n ModuleGraphCommand,\n OpenApiDumpCommand,\n RouteListCommand,\n} from './commands/introspect.commands.js';\nexport { McpServeCommand } from './commands/mcp.command.js';\nexport { StudioCommand } from './commands/studio.command.js';\nexport { ClientGenerateCommand } from './commands/client.command.js';\nexport { generateClientContract } from './client-contract.js';\nexport type { GeneratedClientContract } from './client-contract.js';\nexport {\n collectRoutes,\n collectModules,\n collectEntrypoints,\n renderModuleTree,\n} from './introspect.js';\nexport type { RouteRow, EntrypointRow } from './introspect.js';\nexport { renderTable } from './format.js';\nexport { loadConfig, defineVelaConfig } from './config.js';\nexport type { VelaConfig } from './config.js';\nexport { formatSeedResults } from './format.js';\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@velajs/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.23.0",
|
|
4
4
|
"description": "CLI for Vela apps — seeding and project tasks (Node-side; not bundled into the edge Worker)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
},
|
|
21
21
|
"files": [
|
|
22
22
|
"dist",
|
|
23
|
+
"templates",
|
|
23
24
|
"README.md"
|
|
24
25
|
],
|
|
25
26
|
"type": "module",
|
|
@@ -57,14 +58,14 @@
|
|
|
57
58
|
"typescript": "7.0.2",
|
|
58
59
|
"unplugin-swc": "1.5.9",
|
|
59
60
|
"vitest": "4.1.10",
|
|
60
|
-
"@velajs/client": "1.22.
|
|
61
|
-
"@velajs/vela": "1.22.
|
|
61
|
+
"@velajs/client": "1.22.1",
|
|
62
|
+
"@velajs/vela": "1.22.1"
|
|
62
63
|
},
|
|
63
64
|
"peerDependencies": {
|
|
64
|
-
"@velajs/vela": "^1.22.
|
|
65
|
+
"@velajs/vela": "^1.22.1"
|
|
65
66
|
},
|
|
66
67
|
"optionalDependencies": {
|
|
67
|
-
"@velajs/studio-host": "1.22.
|
|
68
|
+
"@velajs/studio-host": "1.22.1"
|
|
68
69
|
},
|
|
69
70
|
"engines": {
|
|
70
71
|
"node": ">=24"
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# __PROJECT_NAME__
|
|
2
|
+
|
|
3
|
+
A small Vela API running on Cloudflare Workers. Requires Node.js 24+ and
|
|
4
|
+
pnpm 11.11.0. Local development needs no Cloudflare login or external services.
|
|
5
|
+
|
|
6
|
+
```sh
|
|
7
|
+
pnpm install
|
|
8
|
+
pnpm typecheck
|
|
9
|
+
pnpm build
|
|
10
|
+
pnpm dev
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
In another terminal:
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
curl http://localhost:8787
|
|
17
|
+
# {"message":"Hello from Vela!"}
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
`src/app.module.ts` registers the controller and service. Vela injects
|
|
21
|
+
`AppService` into `AppController` through its constructor; the service supplies
|
|
22
|
+
the response message. `src/worker.ts` connects the module to Workers and keeps
|
|
23
|
+
application construction scoped to the Workers environment.
|
|
24
|
+
|
|
25
|
+
`pnpm build` compiles TypeScript into `dist/` with SWC, including the legacy
|
|
26
|
+
decorator metadata needed for constructor injection. `pnpm typecheck` checks
|
|
27
|
+
types separately. Wrangler runs the build on startup and rebuilds when `src/`
|
|
28
|
+
or `.swcrc` changes. Edit the service message and refresh to try it.
|
|
29
|
+
|
|
30
|
+
`pnpm dev --port 8788` uses a different local port. Stop with Ctrl-C.
|
|
31
|
+
Commit the generated `pnpm-lock.yaml` to keep dependency resolution repeatable.
|
|
32
|
+
|
|
33
|
+
To deploy later, authenticate with `pnpm exec wrangler login` and run
|
|
34
|
+
`pnpm run deploy`. Deployment uses your Cloudflare account; it is optional for
|
|
35
|
+
local development.
|
|
36
|
+
|
|
37
|
+
See the [Vela guides](https://github.com/velajs/vela/tree/main/docs) for modules,
|
|
38
|
+
controllers, dependency injection, and optional integrations.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "__PROJECT_NAME__",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"typecheck": "tsc --noEmit",
|
|
8
|
+
"build": "swc src -d dist --strip-leading-paths --delete-dir-on-start",
|
|
9
|
+
"dev": "wrangler dev --local",
|
|
10
|
+
"deploy": "wrangler deploy"
|
|
11
|
+
},
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"@velajs/cloudflare": "1.22.1",
|
|
14
|
+
"@velajs/vela": "1.22.1",
|
|
15
|
+
"hono": "4.13.8"
|
|
16
|
+
},
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"@cloudflare/workers-types": "5.20260920.1",
|
|
19
|
+
"@swc/cli": "0.8.0",
|
|
20
|
+
"@swc/core": "1.15.43",
|
|
21
|
+
"typescript": "7.0.2",
|
|
22
|
+
"wrangler": "4.135.0"
|
|
23
|
+
},
|
|
24
|
+
"engines": {
|
|
25
|
+
"node": ">=24"
|
|
26
|
+
},
|
|
27
|
+
"packageManager": "pnpm@11.11.0"
|
|
28
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Controller, Get } from '@velajs/vela';
|
|
2
|
+
import { AppService } from './app.service.js';
|
|
3
|
+
|
|
4
|
+
@Controller('/')
|
|
5
|
+
export class AppController {
|
|
6
|
+
constructor(private readonly appService: AppService) {}
|
|
7
|
+
|
|
8
|
+
@Get()
|
|
9
|
+
getHello() {
|
|
10
|
+
return { message: this.appService.getHello() };
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { createCloudflareWorker } from '@velajs/cloudflare';
|
|
2
|
+
import { InjectionToken } from '@velajs/vela';
|
|
3
|
+
import { AppModule } from './app.module.js';
|
|
4
|
+
|
|
5
|
+
const ENV = new InjectionToken<Record<string, never>>('Worker environment');
|
|
6
|
+
|
|
7
|
+
export default createCloudflareWorker(AppModule, { envToken: ENV });
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2024",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "Bundler",
|
|
6
|
+
"strict": true,
|
|
7
|
+
"noUncheckedIndexedAccess": true,
|
|
8
|
+
"verbatimModuleSyntax": true,
|
|
9
|
+
"isolatedModules": true,
|
|
10
|
+
"experimentalDecorators": true,
|
|
11
|
+
"emitDecoratorMetadata": true,
|
|
12
|
+
"noEmit": true,
|
|
13
|
+
"skipLibCheck": true,
|
|
14
|
+
"lib": ["ES2024"],
|
|
15
|
+
"types": ["@cloudflare/workers-types"]
|
|
16
|
+
},
|
|
17
|
+
"include": ["src/**/*.ts"]
|
|
18
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "node_modules/wrangler/config-schema.json",
|
|
3
|
+
"name": "__PROJECT_NAME__",
|
|
4
|
+
"main": "dist/worker.js",
|
|
5
|
+
"compatibility_date": "2026-09-20",
|
|
6
|
+
"compatibility_flags": ["nodejs_compat"],
|
|
7
|
+
"build": {
|
|
8
|
+
"command": "pnpm build",
|
|
9
|
+
"watch_dir": ["src", ".swcrc"],
|
|
10
|
+
},
|
|
11
|
+
"dev": { "port": 8787 },
|
|
12
|
+
}
|