@zerotal/arch 1.7.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/CHANGELOG.md +31 -0
- package/LICENSE +21 -0
- package/README.md +67 -0
- package/api-surface.md +283 -0
- package/docs/about.md +676 -0
- package/docs/admin/actions.md +183 -0
- package/docs/admin/auth.md +89 -0
- package/docs/admin/dashboard.md +155 -0
- package/docs/admin/extending-ui.md +229 -0
- package/docs/admin/extending.md +205 -0
- package/docs/admin/forms.md +155 -0
- package/docs/admin/index.md +144 -0
- package/docs/admin/operations.md +224 -0
- package/docs/admin/references.md +174 -0
- package/docs/admin/resources.md +132 -0
- package/docs/admin/structure.md +158 -0
- package/docs/admin/tables.md +185 -0
- package/docs/admin/testing.md +138 -0
- package/docs/ai.md +373 -0
- package/docs/application.md +435 -0
- package/docs/arch.md +263 -0
- package/docs/assets.md +755 -0
- package/docs/audit.md +367 -0
- package/docs/authentication.md +1000 -0
- package/docs/authorization.md +529 -0
- package/docs/broadcasting/channels.md +170 -0
- package/docs/broadcasting/client.md +108 -0
- package/docs/broadcasting/events.md +190 -0
- package/docs/broadcasting/index.md +163 -0
- package/docs/broadcasting/references.md +84 -0
- package/docs/broadcasting/testing.md +132 -0
- package/docs/cache.md +387 -0
- package/docs/carbon.md +830 -0
- package/docs/changelog.md +465 -0
- package/docs/client/auth.md +113 -0
- package/docs/client/errors.md +139 -0
- package/docs/client/files.md +118 -0
- package/docs/client/index.md +128 -0
- package/docs/client/references.md +58 -0
- package/docs/client/requests.md +131 -0
- package/docs/client/resilience.md +141 -0
- package/docs/client/testing.md +146 -0
- package/docs/commands.md +450 -0
- package/docs/components.md +2427 -0
- package/docs/config-system.md +258 -0
- package/docs/container.md +596 -0
- package/docs/context.md +579 -0
- package/docs/contributing.md +164 -0
- package/docs/controllers.md +354 -0
- package/docs/conventions.md +466 -0
- package/docs/cookies.md +101 -0
- package/docs/csrf.md +206 -0
- package/docs/database.md +476 -0
- package/docs/deployment.md +434 -0
- package/docs/devtools.md +1013 -0
- package/docs/email-verification.md +320 -0
- package/docs/encryption.md +380 -0
- package/docs/errors.md +317 -0
- package/docs/events.md +420 -0
- package/docs/flow/components.md +846 -0
- package/docs/flow/decorators.md +458 -0
- package/docs/flow/events.md +420 -0
- package/docs/flow/forms.md +551 -0
- package/docs/flow/index.md +568 -0
- package/docs/flow/layouts.md +793 -0
- package/docs/flow/lifecycle.md +336 -0
- package/docs/flow/pagination.md +402 -0
- package/docs/flow/performance.md +262 -0
- package/docs/flow/references.md +317 -0
- package/docs/flow/routing.md +550 -0
- package/docs/flow/testing.md +447 -0
- package/docs/getting-started.md +286 -0
- package/docs/health.md +269 -0
- package/docs/helpers.md +423 -0
- package/docs/i18n.md +414 -0
- package/docs/index.md +65 -0
- package/docs/inertia/build.md +95 -0
- package/docs/inertia/devtools.md +197 -0
- package/docs/inertia/index.md +267 -0
- package/docs/inertia/middleware.md +81 -0
- package/docs/inertia/props.md +507 -0
- package/docs/inertia/references.md +144 -0
- package/docs/inertia/rendering.md +189 -0
- package/docs/inertia/ssr.md +102 -0
- package/docs/inspirations.md +257 -0
- package/docs/lifecycle.md +331 -0
- package/docs/lock.md +454 -0
- package/docs/logger.md +517 -0
- package/docs/media.md +582 -0
- package/docs/middleware.md +509 -0
- package/docs/migrations.md +529 -0
- package/docs/monitor.md +377 -0
- package/docs/notifications.md +848 -0
- package/docs/orm/casts.md +365 -0
- package/docs/orm/factories.md +231 -0
- package/docs/orm/index.md +663 -0
- package/docs/orm/lifecycle.md +421 -0
- package/docs/orm/queries.md +692 -0
- package/docs/orm/relationships.md +440 -0
- package/docs/orm/serialization.md +251 -0
- package/docs/package-development.md +536 -0
- package/docs/pagination.md +340 -0
- package/docs/password-reset.md +335 -0
- package/docs/providers.md +447 -0
- package/docs/query-builder.md +465 -0
- package/docs/queue.md +549 -0
- package/docs/rate-limiting.md +253 -0
- package/docs/responses.md +336 -0
- package/docs/roles-and-2fa.md +418 -0
- package/docs/routing.md +1008 -0
- package/docs/scaffolding.md +335 -0
- package/docs/scheduler.md +533 -0
- package/docs/seeding.md +229 -0
- package/docs/session.md +451 -0
- package/docs/social.md +524 -0
- package/docs/storage.md +622 -0
- package/docs/structure.md +230 -0
- package/docs/support-policy.md +114 -0
- package/docs/telemetry.md +505 -0
- package/docs/tenancy.md +608 -0
- package/docs/testing/browser.md +153 -0
- package/docs/testing/console.md +130 -0
- package/docs/testing/database.md +238 -0
- package/docs/testing/flow-browser.md +216 -0
- package/docs/testing/http.md +441 -0
- package/docs/testing/index.md +240 -0
- package/docs/testing/mocking.md +410 -0
- package/docs/upgrade.md +192 -0
- package/docs/validator.md +549 -0
- package/docs/view.md +453 -0
- package/package.json +60 -0
- package/src/bin/mcp.ts +73 -0
- package/src/config.ts +63 -0
- package/src/errors.ts +27 -0
- package/src/index.ts +56 -0
- package/src/install/ArchInstallCommand.ts +189 -0
- package/src/install/detect.ts +98 -0
- package/src/install/guidelines.ts +290 -0
- package/src/install/markers.ts +77 -0
- package/src/install/mcpConfig.ts +81 -0
- package/src/mcp/index.ts +27 -0
- package/src/mcp/jsonrpc.ts +133 -0
- package/src/mcp/server.ts +307 -0
- package/src/mcp/stdio.ts +111 -0
- package/src/mcp/types.ts +146 -0
- package/src/probe/ArchProbeCommand.ts +48 -0
- package/src/probe/sentinel.ts +13 -0
- package/src/probe/topics.ts +291 -0
- package/src/provider/ArchProvider.ts +101 -0
- package/src/tools/_probe.ts +164 -0
- package/src/tools/apiSurface.ts +241 -0
- package/src/tools/appInfo.ts +88 -0
- package/src/tools/baselines.ts +210 -0
- package/src/tools/context.ts +37 -0
- package/src/tools/doctor.ts +93 -0
- package/src/tools/index.ts +50 -0
- package/src/tools/logs.ts +265 -0
- package/src/tools/routes.ts +133 -0
- package/src/tools/schema.ts +119 -0
- package/src/tools/searchDocs.ts +345 -0
package/docs/commands.md
ADDED
|
@@ -0,0 +1,450 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Commands
|
|
3
|
+
description: Build and run CLI commands with bun zt, from generators to your own class- or closure-based commands.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Commands
|
|
7
|
+
|
|
8
|
+
Zerotal ships a class-based CLI for running framework tasks and your own
|
|
9
|
+
scripts. Every command is invoked with `bun zt <name>`, and you can add new
|
|
10
|
+
ones as classes or one-line closures.
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
# in your project root
|
|
14
|
+
bun zt list # list all commands with descriptions
|
|
15
|
+
bun zt help <command> # detailed usage for one command
|
|
16
|
+
bun zt make:controller PostController
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
The command system is built into `@zerotal/core` — there is no package to
|
|
20
|
+
install and no provider to register. The CLI bootstraps your application, then
|
|
21
|
+
dispatches the matched command.
|
|
22
|
+
|
|
23
|
+
## Listing & help
|
|
24
|
+
|
|
25
|
+
`bun zt list` prints every registered command, its description, and any
|
|
26
|
+
aliases. `bun zt help <command>` prints the usage line, description,
|
|
27
|
+
arguments, and options for a single command.
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
# in your project root
|
|
31
|
+
bun zt list
|
|
32
|
+
bun zt help migrate
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Class-based commands
|
|
36
|
+
|
|
37
|
+
Extend `Command`, declare static metadata, and implement `run()`. Inside `run()`
|
|
38
|
+
you read parsed positional arguments from `this.args` and flags from
|
|
39
|
+
`this.flags`:
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
// app/commands/SendDigestCommand.ts
|
|
43
|
+
import { Command } from "zerotal";
|
|
44
|
+
|
|
45
|
+
export class SendDigestCommand extends Command {
|
|
46
|
+
static commandName = "digest:send";
|
|
47
|
+
static description = "Send the weekly digest email";
|
|
48
|
+
static args = [{ name: "segment", required: false, default: "all" }];
|
|
49
|
+
static flags = [{ name: "dry", type: "boolean" as const, default: false }];
|
|
50
|
+
|
|
51
|
+
async run(): Promise<void> {
|
|
52
|
+
const segment = this.args["segment"];
|
|
53
|
+
if (this.flags["dry"]) {
|
|
54
|
+
this.warn("Dry run — nothing sent");
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
this.info(`Sending digest to ${segment}…`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
A `FlagDef`'s `type` is `"string" | "boolean" | "number"`; the `as const`
|
|
63
|
+
keeps the literal type so the field stays type-checked.
|
|
64
|
+
|
|
65
|
+
> **Tip** — Run `bun zt make:command SendDigest` to scaffold a ready-to-edit
|
|
66
|
+
> command class at `app/commands/SendDigestCommand.ts`.
|
|
67
|
+
|
|
68
|
+
## Closure commands
|
|
69
|
+
|
|
70
|
+
For one-liners, register a plain definition with a signature string. The
|
|
71
|
+
signature's first token is the name; `{arg}` is required, `{arg?}` optional,
|
|
72
|
+
`{arg=default}` has a default, `{--flag}` is a boolean flag, and `{--flag=}` /
|
|
73
|
+
`{--flag=default}` is a string flag.
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
// in a service provider or bootstrap script
|
|
77
|
+
const runner = app.container.tryMake("commands");
|
|
78
|
+
|
|
79
|
+
runner.command({
|
|
80
|
+
signature: "greet {name} {--loud}",
|
|
81
|
+
description: "Say hello",
|
|
82
|
+
handle: ({ name, loud }, cmd) => {
|
|
83
|
+
cmd.info(loud ? `HELLO ${name}!` : `Hello, ${name}`);
|
|
84
|
+
},
|
|
85
|
+
});
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
The `handle` callback receives a single object merging the parsed arguments and
|
|
89
|
+
flags, plus the `Command` instance so you can use its output helpers.
|
|
90
|
+
|
|
91
|
+
> **Note** — `registerCommand()` is an alias for `command()`; both build a
|
|
92
|
+
> synthetic `Command` subclass from the definition and register it.
|
|
93
|
+
|
|
94
|
+
### Which should I use?
|
|
95
|
+
|
|
96
|
+
| You have… | Use |
|
|
97
|
+
| ------------------------------------------------------ | -------------------- |
|
|
98
|
+
| A quick task with little logic, defined inline | Closure |
|
|
99
|
+
| Logic worth testing, multiple methods, or its own file | Class |
|
|
100
|
+
| A folder of commands to register together | Class + `discover()` |
|
|
101
|
+
|
|
102
|
+
## Auto-discovery
|
|
103
|
+
|
|
104
|
+
`app/commands/` is discovered automatically: any command class dropped there —
|
|
105
|
+
including everything `make:command` generates — is registered when the CLI boots,
|
|
106
|
+
with no imports or provider wiring. An app command registers after the built-ins,
|
|
107
|
+
so it wins a name collision. The directory is configurable via
|
|
108
|
+
`conventions.paths.commands` in `config/app.ts`, and discovery honours the
|
|
109
|
+
`conventions.enabled` master switch.
|
|
110
|
+
|
|
111
|
+
To register a folder from somewhere else, call `discover()` yourself:
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
// in a service provider or bootstrap script
|
|
115
|
+
await runner.discover("./vendor/acme/commands");
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Every non-test `.ts`/`.js` file under the directory is imported, and any exported
|
|
119
|
+
`Command` subclass with a non-empty `commandName` is registered. `discover()`
|
|
120
|
+
returns the list of registered names.
|
|
121
|
+
|
|
122
|
+
## Styled output & prompts
|
|
123
|
+
|
|
124
|
+
The `Command` base class provides coloured output helpers and interactive
|
|
125
|
+
prompts. The prompts read from stdin and only work on a real TTY:
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
// inside a command's run()
|
|
129
|
+
this.info("Success"); // green
|
|
130
|
+
this.warn("Heads up"); // yellow
|
|
131
|
+
this.error("Failed"); // red (written to stderr)
|
|
132
|
+
this.line("Plain"); // cyan
|
|
133
|
+
this.dim("subtle"); // dim
|
|
134
|
+
this.section("Title"); // bold heading
|
|
135
|
+
this.table([["Key", "Value"]]); // aligned two-column rows
|
|
136
|
+
this.newLine();
|
|
137
|
+
|
|
138
|
+
const name = await this.ask("Your name?", "guest");
|
|
139
|
+
const ok = await this.confirm("Proceed?", true);
|
|
140
|
+
const env = await this.choice("Environment:", ["local", "staging", "production"]);
|
|
141
|
+
const token = await this.secret("API token:"); // input hidden on a Unix TTY
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
> **Warning** — `secret()` only hides input on a Unix TTY with raw mode; on
|
|
145
|
+
> Windows and in non-interactive contexts it falls back to a visible prompt.
|
|
146
|
+
|
|
147
|
+
## Built-in Commands
|
|
148
|
+
|
|
149
|
+
### Server & Development
|
|
150
|
+
|
|
151
|
+
| Command | Description |
|
|
152
|
+
| ----------------------------- | --------------------------------------------------------------- |
|
|
153
|
+
| `bun zt dev` | Dev mode: the server plus every registered process (alias: `d`) |
|
|
154
|
+
| `bun zt dev --only=server` | Run only the named processes, comma-separated |
|
|
155
|
+
| `bun zt dev --without=queue` | Run everything except the named processes |
|
|
156
|
+
| `bun zt dev --list` | Print what would run, and which provider registered it |
|
|
157
|
+
| `bun zt dev --stream` | Interleave prefixed output instead of drawing tabs |
|
|
158
|
+
| `bun zt dev --force-build` | Rebuild assets even when the build cache says they're current |
|
|
159
|
+
| `bun zt serve` | Start the HTTP server on port 3000 |
|
|
160
|
+
| `bun zt serve --port 8080` | Start on a custom port |
|
|
161
|
+
| `bun zt serve --force` | If the port is busy, stop whatever holds it |
|
|
162
|
+
| `bun zt serve --auto-port` | If the port is busy, start on the next free port |
|
|
163
|
+
| `bun zt reload` | Hot-reload routes in the running server (sends SIGUSR2) |
|
|
164
|
+
| `bun zt status` | Show live metrics from the running server |
|
|
165
|
+
| `bun zt repl` | Start an interactive REPL with the bootstrapped app in scope |
|
|
166
|
+
| `bun zt worker` | Start the background job worker process |
|
|
167
|
+
| `bun zt worker --queue email` | Process a specific queue |
|
|
168
|
+
| `bun zt worker --once` | Process one job then exit |
|
|
169
|
+
| `bun zt test` | Run the test suite in the `test` environment |
|
|
170
|
+
| `bun zt compile` | Compile the app to a self-contained binary (alias: `build`) |
|
|
171
|
+
| `bun zt css:build` | Build the Tailwind CSS bundle for production |
|
|
172
|
+
|
|
173
|
+
#### When the port is already taken
|
|
174
|
+
|
|
175
|
+
`serve` checks the port before it binds, so a busy one is a question rather than
|
|
176
|
+
a crash. It tells you which process is holding it — usually a server you forgot
|
|
177
|
+
was running — and offers to stop that process and take the port, or to start on
|
|
178
|
+
the next free one instead. Pressing Enter takes the next free port, the answer
|
|
179
|
+
that cannot cost you anything.
|
|
180
|
+
|
|
181
|
+
Nothing prompts when there is no terminal to answer, which covers CI, containers,
|
|
182
|
+
and anything reading `serve`'s output from a pipe. There it fails with the same
|
|
183
|
+
explanation, so use `--force` or `--auto-port` to say up front which way you want
|
|
184
|
+
it decided. Both flags work with a plain `serve` and with `serve --dev`.
|
|
185
|
+
|
|
186
|
+
The dev server is a special case worth knowing about: on every restart it waits a
|
|
187
|
+
few seconds for its own previous process to let go of the socket rather than
|
|
188
|
+
asking you about it. A prompt on each file save would be unbearable, and the port
|
|
189
|
+
is about to free itself anyway.
|
|
190
|
+
|
|
191
|
+
#### Dev mode and the deck
|
|
192
|
+
|
|
193
|
+
`bun zt dev` starts the server, the file watcher, and every process a provider or
|
|
194
|
+
your app registered — a queue worker, a type-checker, a Stripe listener — in one
|
|
195
|
+
terminal, each in its own tab. It is `serve --dev` with those extra tabs and the
|
|
196
|
+
keys to drive them, so anything true of one is true of the other.
|
|
197
|
+
|
|
198
|
+
An app with a queue no longer needs a second terminal:
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
# in your project root
|
|
202
|
+
bun zt dev
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
The deck draws one tab per process, colour-coded, showing whether each is
|
|
206
|
+
running, restarting, or has given up:
|
|
207
|
+
|
|
208
|
+
```text
|
|
209
|
+
1 server ●│ 2 queue ●│ 3 types ◌
|
|
210
|
+
─────────────────────────────────────────────────
|
|
211
|
+
GET / 200 4ms
|
|
212
|
+
GET /posts 200 11ms
|
|
213
|
+
1-9 tab · ←/→ cycle · r restart · c clear · / search · t time · s stream · q quit
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
| Key | Does |
|
|
217
|
+
| ------------- | ---------------------------------------------------------------- |
|
|
218
|
+
| `1`–`9` | Select that tab |
|
|
219
|
+
| `←` `→` `Tab` | Cycle through tabs |
|
|
220
|
+
| `r` | Restart the focused process |
|
|
221
|
+
| `c` | Clear the focused tab's output |
|
|
222
|
+
| `/` | Search within the focused tab (`Enter` keeps it, `Esc` drops it) |
|
|
223
|
+
| `t` | Toggle per-line timestamps |
|
|
224
|
+
| `s` | Switch to stream mode |
|
|
225
|
+
| `PgUp` `PgDn` | Scroll the focused tab |
|
|
226
|
+
| `q` | Quit — stops every process and restores your shell |
|
|
227
|
+
|
|
228
|
+
Scrollback belongs to the deck rather than to your terminal, which is what makes
|
|
229
|
+
per-tab history and search possible. It keeps the last 5,000 lines per process.
|
|
230
|
+
|
|
231
|
+
**A process that dies never takes the server with it.** It restarts on its own —
|
|
232
|
+
three times, backing off between attempts — and if it still will not start, that
|
|
233
|
+
one tab parks with a message telling you how to retry. Everything else keeps
|
|
234
|
+
running. This is the opposite of the asset build, where a failure deliberately
|
|
235
|
+
aborts the reload.
|
|
236
|
+
|
|
237
|
+
#### Stream mode
|
|
238
|
+
|
|
239
|
+
Not everything watching `zt dev` is a person at a terminal. When stdout is not a
|
|
240
|
+
TTY — CI, a pipe, a log file — the deck writes prefixed lines instead, with no
|
|
241
|
+
escape codes at all:
|
|
242
|
+
|
|
243
|
+
```text
|
|
244
|
+
[server] GET / 200 4ms
|
|
245
|
+
[queue ] processing SendWelcomeEmail
|
|
246
|
+
[server] GET /posts 200 11ms
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
That happens automatically; `--stream` forces it, and `s` switches to it
|
|
250
|
+
mid-session. It is the same information, and it is what you want in a file.
|
|
251
|
+
|
|
252
|
+
#### Choosing what runs
|
|
253
|
+
|
|
254
|
+
`--only` and `--without` take comma-separated names, and the server is an
|
|
255
|
+
ordinary name among them:
|
|
256
|
+
|
|
257
|
+
```bash
|
|
258
|
+
# in your project root
|
|
259
|
+
bun zt dev --only=server,queue # just these two
|
|
260
|
+
bun zt dev --without=queue # everything else
|
|
261
|
+
bun zt dev --only=queue # no server at all
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
When you are not sure what a tab is or who asked for it, `--list` answers both
|
|
265
|
+
without starting anything:
|
|
266
|
+
|
|
267
|
+
```bash
|
|
268
|
+
# in your project root
|
|
269
|
+
bun zt dev --list
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
```text
|
|
273
|
+
Dev processes
|
|
274
|
+
server
|
|
275
|
+
command managed by the orchestrator
|
|
276
|
+
registered by @zerotal/core
|
|
277
|
+
queue
|
|
278
|
+
command bun zt queue:work
|
|
279
|
+
registered by QueueProvider
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
Your app has the last word. `app.dev.disable` removes a process by name, and
|
|
283
|
+
registering the same name again replaces it rather than adding a second tab:
|
|
284
|
+
|
|
285
|
+
```ts
|
|
286
|
+
// config/app.ts
|
|
287
|
+
export default AppConfig({
|
|
288
|
+
dev: {
|
|
289
|
+
processes: [
|
|
290
|
+
{ name: "stripe", command: ["stripe", "listen", "--forward-to", "localhost:3000"] },
|
|
291
|
+
],
|
|
292
|
+
disable: ["queue"],
|
|
293
|
+
},
|
|
294
|
+
});
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
Packages register their own — see
|
|
298
|
+
[Registering a dev process](/docs/package-development#registering-a-dev-process).
|
|
299
|
+
|
|
300
|
+
### Inspection
|
|
301
|
+
|
|
302
|
+
| Command | Description |
|
|
303
|
+
| ---------------------- | ------------------------------------------------------ |
|
|
304
|
+
| `bun zt route:list` | List all registered routes with methods and middleware |
|
|
305
|
+
| `bun zt route:types` | Write `types/routes.generated.ts` (`--check` in CI) |
|
|
306
|
+
| `bun zt doctor` | Check the app for silent misconfigurations |
|
|
307
|
+
| `bun zt key:generate` | Generate a new `APP_KEY` and write it to `.env` |
|
|
308
|
+
| `bun zt lint:packages` | Check every workspace package against convention rules |
|
|
309
|
+
|
|
310
|
+
`doctor` runs every static sanity check against the booted app and prints each
|
|
311
|
+
finding with its fix: APP_KEY strength, `database.synchronize` colliding with
|
|
312
|
+
migration files, a `routes/` directory nothing loads, and class directories
|
|
313
|
+
(`app/schedules`, `app/jobs`, `config/storage.ts`) whose consuming provider is
|
|
314
|
+
not registered. These failures otherwise fail by _doing nothing_, which is the
|
|
315
|
+
most expensive kind to find. Packages can contribute checks via
|
|
316
|
+
`app.registerDoctorCheck()`. Exits non-zero when a check fails outright, so it
|
|
317
|
+
can gate a deploy.
|
|
318
|
+
|
|
319
|
+
### Database
|
|
320
|
+
|
|
321
|
+
| Command | Description |
|
|
322
|
+
| ----------------------------- | -------------------------------------------------------------- |
|
|
323
|
+
| `bun zt migrate` | Run all pending migrations |
|
|
324
|
+
| `bun zt migrate --fresh` | Drop all tables, then re-run everything from scratch |
|
|
325
|
+
| `bun zt migrate --seed` | Run migrations, then run the seeders |
|
|
326
|
+
| `bun zt migrate:rollback` | Roll back the most recent migration batch |
|
|
327
|
+
| `bun zt migrate:fresh` | Alias: drop all tables and re-run all migrations |
|
|
328
|
+
| `bun zt migrate:fresh --seed` | Rebuild the schema from scratch, then run the seeders |
|
|
329
|
+
| `bun zt migrate:status` | Show the status (run / pending / batch) of each migration file |
|
|
330
|
+
| `bun zt migrate:generate` | Auto-generate a migration from model schema changes |
|
|
331
|
+
| `bun zt db:seed` | Run all seeders from `database/seeders/` |
|
|
332
|
+
|
|
333
|
+
> **Danger** — `migrate --fresh` and `migrate:fresh` drop every table before
|
|
334
|
+
> re-running migrations. Never run them against a production database.
|
|
335
|
+
|
|
336
|
+
### Generators
|
|
337
|
+
|
|
338
|
+
| Command | Creates |
|
|
339
|
+
| ---------------------------------------------------- | -------------------------------------------------------------------------- |
|
|
340
|
+
| `bun zt make:model Post` | `app/models/Post.ts` |
|
|
341
|
+
| `bun zt make:controller PostController [--resource]` | `app/controllers/PostController.ts` |
|
|
342
|
+
| `bun zt make:middleware RequireAdmin` | `app/middleware/RequireAdminMiddleware.ts` |
|
|
343
|
+
| `bun zt make:command SendDigest` | `app/commands/SendDigestCommand.ts` |
|
|
344
|
+
| `bun zt make:request StorePost` | `app/requests/StorePostRequest.ts` |
|
|
345
|
+
| `bun zt make:notification OrderShipped` | `app/notifications/OrderShippedNotification.ts` |
|
|
346
|
+
| `bun zt make:job ProcessPayment` | `app/jobs/ProcessPaymentJob.ts` |
|
|
347
|
+
| `bun zt make:event UserRegistered` | `app/events/UserRegisteredEvent.ts` |
|
|
348
|
+
| `bun zt make:listener SendWelcome` | `app/listeners/SendWelcomeListener.ts` |
|
|
349
|
+
| `bun zt make:observer UserObserver [--model User]` | `app/observers/UserObserver.ts` |
|
|
350
|
+
| `bun zt make:policy PostPolicy [--model Post]` | `app/policies/PostPolicy.ts` |
|
|
351
|
+
| `bun zt make:resource UserResource` | `app/resources/UserResource.ts` |
|
|
352
|
+
| `bun zt make:migration create_posts_table` | `database/migrations/{timestamp}_create_posts_table.ts` |
|
|
353
|
+
| `bun zt make:factory PostFactory` | `database/factories/PostFactory.ts` |
|
|
354
|
+
| `bun zt make:seeder PostSeeder` | `database/seeders/PostSeeder.ts` |
|
|
355
|
+
| `bun zt make:provider Payment [--no-register]` | `app/providers/PaymentProvider.ts` + registers in `bootstrap/providers.ts` |
|
|
356
|
+
| `bun zt make:package billing` | Full `packages/billing/` package skeleton |
|
|
357
|
+
|
|
358
|
+
### Queue
|
|
359
|
+
|
|
360
|
+
| Command | Description |
|
|
361
|
+
| ---------------------------------------------- | ---------------------------------------------------- |
|
|
362
|
+
| `bun zt queue:work [--queue default] [--once]` | Process jobs. Daemon in production; `--once` for CI. |
|
|
363
|
+
| `bun zt queue:failed` | List all failed jobs |
|
|
364
|
+
| `bun zt queue:retry <id\|all>` | Retry one failed job or all failed jobs |
|
|
365
|
+
| `bun zt queue:flush [--queue name] [--force]` | Delete all failed jobs from the database |
|
|
366
|
+
|
|
367
|
+
### Cache
|
|
368
|
+
|
|
369
|
+
| Command | Description |
|
|
370
|
+
| -------------------- | ------------------------------------------------------- |
|
|
371
|
+
| `bun zt cache:clear` | Clear all cached values from the configured cache store |
|
|
372
|
+
|
|
373
|
+
### Scheduler
|
|
374
|
+
|
|
375
|
+
| Command | Description |
|
|
376
|
+
| ---------------------- | ------------------------------------------------------------ |
|
|
377
|
+
| `bun zt schedule:list` | List all registered scheduled tasks with their next run time |
|
|
378
|
+
|
|
379
|
+
## References
|
|
380
|
+
|
|
381
|
+
The command surface lives in `@zerotal/core`. The base `Command` class is what
|
|
382
|
+
you extend; `CommandRunner` (resolved from the container as `"commands"`) is the
|
|
383
|
+
registry and dispatcher.
|
|
384
|
+
|
|
385
|
+
### Command static metadata
|
|
386
|
+
|
|
387
|
+
| Field | Type | Description |
|
|
388
|
+
| ------------- | ----------- | ----------------------------------------- |
|
|
389
|
+
| `commandName` | `string` | The name invoked on the CLI. |
|
|
390
|
+
| `description` | `string` | Shown in `list` and `help`. |
|
|
391
|
+
| `args` | `ArgDef[]` | Positional arguments the command accepts. |
|
|
392
|
+
| `flags` | `FlagDef[]` | Named flags the command accepts. |
|
|
393
|
+
| `needsApp` | `boolean` | Whether the bootstrapped app is injected. |
|
|
394
|
+
|
|
395
|
+
`ArgDef` is `{ name: string; required?: boolean; default?: string }`. `FlagDef`
|
|
396
|
+
is `{ name: string; short?: string; type: "string" | "boolean" | "number"; description?: string; default?: unknown }`.
|
|
397
|
+
|
|
398
|
+
### Command instance members
|
|
399
|
+
|
|
400
|
+
| Member | Signature | Description |
|
|
401
|
+
| ------- | --------------------------------------------- | ------------------------------------------------ |
|
|
402
|
+
| `run` | `run(): Promise<void>` | The work the command performs (abstract). |
|
|
403
|
+
| `args` | `Record<string, string>` | Parsed positional arguments, set before `run()`. |
|
|
404
|
+
| `flags` | `Record<string, string \| boolean \| number>` | Parsed flags, set before `run()`. |
|
|
405
|
+
| `app` | `unknown` | The application instance, set before `run()`. |
|
|
406
|
+
|
|
407
|
+
### Output helpers
|
|
408
|
+
|
|
409
|
+
| Method | Signature | Description |
|
|
410
|
+
| --------- | ------------------------------------------------ | ---------------------------- |
|
|
411
|
+
| `info` | `info(msg: string): void` | Green success line. |
|
|
412
|
+
| `warn` | `warn(msg: string): void` | Yellow warning line. |
|
|
413
|
+
| `error` | `error(msg: string): void` | Red line, written to stderr. |
|
|
414
|
+
| `line` | `line(msg: string): void` | Cyan line. |
|
|
415
|
+
| `dim` | `dim(msg: string): void` | Dimmed line. |
|
|
416
|
+
| `write` | `write(msg: string): void` | Raw write, no newline. |
|
|
417
|
+
| `newLine` | `newLine(): void` | Blank line. |
|
|
418
|
+
| `section` | `section(title: string): void` | Bold heading. |
|
|
419
|
+
| `table` | `table(rows: [string, string][], indent?): void` | Aligned two-column rows. |
|
|
420
|
+
|
|
421
|
+
### Prompts
|
|
422
|
+
|
|
423
|
+
| Method | Signature | Description |
|
|
424
|
+
| --------- | --------------------------------------------------------------------- | --------------------------------- |
|
|
425
|
+
| `ask` | `ask(question: string, defaultValue?: string): Promise<string>` | Text input with optional default. |
|
|
426
|
+
| `confirm` | `confirm(question: string, defaultValue?: boolean): Promise<boolean>` | Yes/no confirmation. |
|
|
427
|
+
| `choice` | `choice(question: string, options: string[]): Promise<string>` | Pick one from a numbered list. |
|
|
428
|
+
| `secret` | `secret(question: string): Promise<string>` | Hidden input on a Unix TTY. |
|
|
429
|
+
|
|
430
|
+
### CommandRunner
|
|
431
|
+
|
|
432
|
+
| Method | Signature | Description |
|
|
433
|
+
| ----------------- | --------------------------------------------------------------------------------------- | ------------------------------------------------------ |
|
|
434
|
+
| `register` | `register(Cmd: CommandClass, aliases?: string[]): void` | Register a command class under its name and aliases. |
|
|
435
|
+
| `registerAll` | `registerAll(commandClasses: CommandClass[]): void` | Register several classes at once. |
|
|
436
|
+
| `command` | `command(definition: CommandDefinition, aliases?: string[]): CommandClass` | Build and register a closure command. |
|
|
437
|
+
| `registerCommand` | `registerCommand(definition: CommandDefinition, aliases?: string[]): CommandClass` | Alias for `command()`. |
|
|
438
|
+
| `registerLazy` | `registerLazy(name: string, thunk: CommandThunk, aliases?: string[]): void` | Register a command imported lazily on first call. |
|
|
439
|
+
| `discover` | `discover(dir: string): Promise<string[]>` | Import a directory and register found command classes. |
|
|
440
|
+
| `run` | `run(argv: string[]): Promise<void>` | Parse argv, run the command, and `process.exit()`. |
|
|
441
|
+
| `callInProcess` | `callInProcess(argv: string[], parameters?): Promise<{ code: number; output: string }>` | Run in-process, capture output, no exit. |
|
|
442
|
+
|
|
443
|
+
## Next steps
|
|
444
|
+
|
|
445
|
+
- [Scaffolding](/docs/scaffolding) — what the `make:` generators produce.
|
|
446
|
+
- [Scheduler](/docs/scheduler) — register tasks that `schedule:list` reports.
|
|
447
|
+
- [Queue](/docs/queue) — the worker and queue commands in context.
|
|
448
|
+
- [Container](/docs/container) — how commands resolve their dependencies.
|
|
449
|
+
</content>
|
|
450
|
+
</invoke>
|