@zitadel/cli 0.1.0-alpha.0 → 0.1.0-alpha.2
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 +158 -24
- package/SKILLS.md +40 -8
- package/dist/commands/apply.mjs +4 -3
- package/dist/commands/apply.mjs.map +1 -1
- package/dist/commands/doctor.mjs +150 -16
- package/dist/commands/doctor.mjs.map +1 -1
- package/dist/commands/eject.mjs +4 -3
- package/dist/commands/eject.mjs.map +1 -1
- package/dist/commands/logs.mjs +50 -0
- package/dist/commands/logs.mjs.map +1 -0
- package/dist/commands/plan.mjs +4 -3
- package/dist/commands/plan.mjs.map +1 -1
- package/dist/commands/reset.mjs +62 -0
- package/dist/commands/reset.mjs.map +1 -0
- package/dist/commands/setup.mjs +189 -23
- package/dist/commands/setup.mjs.map +1 -1
- package/dist/commands/start.mjs +128 -0
- package/dist/commands/start.mjs.map +1 -0
- package/dist/commands/status.mjs +74 -27
- package/dist/commands/status.mjs.map +1 -1
- package/dist/commands/stop.mjs +43 -0
- package/dist/commands/stop.mjs.map +1 -0
- package/dist/docker-DrOBycgG.mjs +210 -0
- package/dist/docker-DrOBycgG.mjs.map +1 -0
- package/dist/{project-C3pSfbao.mjs → oclif-CqkWBQ7i.mjs} +300 -119
- package/dist/oclif-CqkWBQ7i.mjs.map +1 -0
- package/dist/{orca-COsUnVoz.mjs → orca-S1tVnngd.mjs} +41 -12
- package/dist/{orca-COsUnVoz.mjs.map → orca-S1tVnngd.mjs.map} +1 -1
- package/dist/project-B6YfSaZw.mjs +87 -0
- package/dist/project-B6YfSaZw.mjs.map +1 -0
- package/dist/{sync-Cuyh-X1J.mjs → sync-DN4oNLVH.mjs} +4 -4
- package/dist/{sync-Cuyh-X1J.mjs.map → sync-DN4oNLVH.mjs.map} +1 -1
- package/oclif.manifest.json +357 -3
- package/package.json +3 -3
- package/dist/project-C3pSfbao.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
Scaffolds Zitadel auth (login, register, profile, middleware) into a Next.js app.
|
|
4
4
|
|
|
5
5
|
```sh
|
|
6
|
-
npx @zitadel/cli@
|
|
6
|
+
npx @zitadel/cli@alpha start
|
|
7
|
+
npx @zitadel/cli@alpha setup --framework next --server local
|
|
7
8
|
```
|
|
8
9
|
|
|
9
10
|
> **Beta.** This is the **next-generation Zitadel**, a ground-up rewrite of the platform. It is distinct from the established Zitadel at [github.com/zitadel/zitadel](https://github.com/zitadel/zitadel). APIs and CLI flags will change.
|
|
@@ -11,21 +12,41 @@ npx @zitadel/cli@latest setup --framework next --server <your-zitadel-server>
|
|
|
11
12
|
## Requirements
|
|
12
13
|
|
|
13
14
|
- Node 20+
|
|
15
|
+
- Docker for the managed local Zitadel runtime
|
|
14
16
|
- A Next.js project created with `create-next-app`
|
|
15
|
-
- A running next-generation Zitadel server to point at:
|
|
16
|
-
- **Zitadel Cloud** — coming soon
|
|
17
|
-
- **Self-hosted** — grab a binary from [github.com/zitadel/nextgen/releases](https://github.com/zitadel/nextgen/releases) and run it locally
|
|
18
17
|
|
|
19
18
|
## Quickstart
|
|
20
19
|
|
|
21
20
|
```sh
|
|
22
21
|
npx create-next-app@latest my-app
|
|
23
22
|
cd my-app
|
|
24
|
-
npx @zitadel/cli@
|
|
23
|
+
npx @zitadel/cli@alpha doctor
|
|
24
|
+
npx @zitadel/cli@alpha start
|
|
25
|
+
npx @zitadel/cli@alpha setup --framework next --server local
|
|
25
26
|
npm run dev
|
|
26
27
|
```
|
|
27
28
|
|
|
28
|
-
`
|
|
29
|
+
`start` runs a Docker-backed local Zitadel server and stores runtime data
|
|
30
|
+
under `.zitadel/local/`. Alpha CLI versions use the matching
|
|
31
|
+
`ghcr.io/zitadel/nextgen:<cli-version>` image by default; local/dev builds fall
|
|
32
|
+
back to `ghcr.io/zitadel/nextgen:latest`. Override with `--image` or
|
|
33
|
+
`ZITADEL_LOCAL_IMAGE` for advanced debugging.
|
|
34
|
+
`setup --server local` creates a project on that local server, scaffolds
|
|
35
|
+
`app/login`, `app/register`, and `middleware.ts`, writes `.env.local` and
|
|
36
|
+
`.zitadel/`, and installs dependencies with the detected package manager. Pass
|
|
37
|
+
`--skip-install` to install them yourself. The project's default user schema
|
|
38
|
+
and login flow are provisioned server-side at creation time, so the CLI does
|
|
39
|
+
not scaffold or upload them. Open `http://localhost:3000/login` to see the
|
|
40
|
+
login page.
|
|
41
|
+
|
|
42
|
+
For a reproducible tester report, use the exact alpha train from the GitHub
|
|
43
|
+
Release:
|
|
44
|
+
|
|
45
|
+
```sh
|
|
46
|
+
npx @zitadel/cli@0.1.0-alpha.N doctor
|
|
47
|
+
npx @zitadel/cli@0.1.0-alpha.N start
|
|
48
|
+
npx @zitadel/cli@0.1.0-alpha.N setup --framework next --server local
|
|
49
|
+
```
|
|
29
50
|
|
|
30
51
|
The default project flow supports password registration/login, passkey
|
|
31
52
|
registration/login, and optional passkey setup after password registration.
|
|
@@ -34,9 +55,10 @@ passkey can sign in with either credential.
|
|
|
34
55
|
|
|
35
56
|
## Other commands
|
|
36
57
|
|
|
37
|
-
- `zitadel doctor` — verify the
|
|
38
|
-
- `zitadel status` — summarise the local project
|
|
58
|
+
- `zitadel doctor` — verify the local Docker runtime and generated project files
|
|
59
|
+
- `zitadel status` — summarise the local Docker runtime and project
|
|
39
60
|
- `zitadel eject` — remove what setup wrote (alias: `zitadel uninstall`)
|
|
61
|
+
- `zitadel start|stop|logs|reset` — manage the local Docker runtime
|
|
40
62
|
|
|
41
63
|
## Reference
|
|
42
64
|
|
|
@@ -44,17 +66,22 @@ passkey can sign in with either credential.
|
|
|
44
66
|
<summary>Full command reference</summary>
|
|
45
67
|
|
|
46
68
|
<!-- commands -->
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
69
|
+
|
|
70
|
+
- [`zitadel autocomplete [SHELL]`](#zitadel-autocomplete-shell)
|
|
71
|
+
- [`zitadel commands`](#zitadel-commands)
|
|
72
|
+
- [`zitadel doctor`](#zitadel-doctor)
|
|
73
|
+
- [`zitadel eject`](#zitadel-eject)
|
|
74
|
+
- [`zitadel help [COMMAND]`](#zitadel-help-command)
|
|
75
|
+
- [`zitadel logs`](#zitadel-logs)
|
|
76
|
+
- [`zitadel reset`](#zitadel-reset)
|
|
77
|
+
- [`zitadel search`](#zitadel-search)
|
|
78
|
+
- [`zitadel setup`](#zitadel-setup)
|
|
79
|
+
- [`zitadel start`](#zitadel-start)
|
|
80
|
+
- [`zitadel status`](#zitadel-status)
|
|
81
|
+
- [`zitadel stop`](#zitadel-stop)
|
|
82
|
+
- [`zitadel uninstall`](#zitadel-uninstall)
|
|
83
|
+
- [`zitadel version`](#zitadel-version)
|
|
84
|
+
- [`zitadel which`](#zitadel-which)
|
|
58
85
|
|
|
59
86
|
## `zitadel autocomplete [SHELL]`
|
|
60
87
|
|
|
@@ -118,11 +145,12 @@ _See code: [@oclif/plugin-commands](https://github.com/oclif/plugin-commands/blo
|
|
|
118
145
|
|
|
119
146
|
## `zitadel doctor`
|
|
120
147
|
|
|
121
|
-
Verify
|
|
148
|
+
Verify local runtime and project state.
|
|
122
149
|
|
|
123
150
|
```
|
|
124
151
|
USAGE
|
|
125
152
|
$ zitadel doctor [--json] [-c <value>] [-s <value>] [-n] [-f] [--dry-run] [--verbose] [--debug] [--fix]
|
|
153
|
+
[--image <value>] [--port <value>]
|
|
126
154
|
|
|
127
155
|
FLAGS
|
|
128
156
|
-c, --cwd=<value> Project directory to operate on.
|
|
@@ -132,13 +160,15 @@ FLAGS
|
|
|
132
160
|
--debug Debug logging.
|
|
133
161
|
--dry-run Preview without mutating files or the platform.
|
|
134
162
|
--fix Re-apply missing managed files.
|
|
163
|
+
--image=<value> Container image to check.
|
|
164
|
+
--port=<value> [default: 8080] Local HTTP port.
|
|
135
165
|
--verbose Verbose logging.
|
|
136
166
|
|
|
137
167
|
GLOBAL FLAGS
|
|
138
168
|
--json Format output as json.
|
|
139
169
|
|
|
140
170
|
DESCRIPTION
|
|
141
|
-
Verify
|
|
171
|
+
Verify local runtime and project state.
|
|
142
172
|
```
|
|
143
173
|
|
|
144
174
|
## `zitadel eject`
|
|
@@ -188,6 +218,57 @@ DESCRIPTION
|
|
|
188
218
|
|
|
189
219
|
_See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/6.2.49/src/commands/help.ts)_
|
|
190
220
|
|
|
221
|
+
## `zitadel logs`
|
|
222
|
+
|
|
223
|
+
Show local Zitadel server logs.
|
|
224
|
+
|
|
225
|
+
```
|
|
226
|
+
USAGE
|
|
227
|
+
$ zitadel logs [--json] [-c <value>] [-s <value>] [-n] [-f] [--dry-run] [--verbose] [--debug] [--follow]
|
|
228
|
+
[--tail <value>]
|
|
229
|
+
|
|
230
|
+
FLAGS
|
|
231
|
+
-c, --cwd=<value> Project directory to operate on.
|
|
232
|
+
-f, --force Overwrite protected files on conflict.
|
|
233
|
+
-n, --non-interactive Disable prompts. Required when scripting or running as an agent.
|
|
234
|
+
-s, --server=<value> Override the resolved server URL.
|
|
235
|
+
--debug Debug logging.
|
|
236
|
+
--dry-run Preview without mutating files or the platform.
|
|
237
|
+
--follow Follow logs.
|
|
238
|
+
--tail=<value> [default: 200] Number of lines to show.
|
|
239
|
+
--verbose Verbose logging.
|
|
240
|
+
|
|
241
|
+
GLOBAL FLAGS
|
|
242
|
+
--json Format output as json.
|
|
243
|
+
|
|
244
|
+
DESCRIPTION
|
|
245
|
+
Show local Zitadel server logs.
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
## `zitadel reset`
|
|
249
|
+
|
|
250
|
+
Delete the local Zitadel server runtime and data.
|
|
251
|
+
|
|
252
|
+
```
|
|
253
|
+
USAGE
|
|
254
|
+
$ zitadel reset [--json] [-c <value>] [-s <value>] [-n] [-f] [--dry-run] [--verbose] [--debug]
|
|
255
|
+
|
|
256
|
+
FLAGS
|
|
257
|
+
-c, --cwd=<value> Project directory to operate on.
|
|
258
|
+
-f, --force Overwrite protected files on conflict.
|
|
259
|
+
-n, --non-interactive Disable prompts. Required when scripting or running as an agent.
|
|
260
|
+
-s, --server=<value> Override the resolved server URL.
|
|
261
|
+
--debug Debug logging.
|
|
262
|
+
--dry-run Preview without mutating files or the platform.
|
|
263
|
+
--verbose Verbose logging.
|
|
264
|
+
|
|
265
|
+
GLOBAL FLAGS
|
|
266
|
+
--json Format output as json.
|
|
267
|
+
|
|
268
|
+
DESCRIPTION
|
|
269
|
+
Delete the local Zitadel server runtime and data.
|
|
270
|
+
```
|
|
271
|
+
|
|
191
272
|
## `zitadel search`
|
|
192
273
|
|
|
193
274
|
Search for a command.
|
|
@@ -211,7 +292,7 @@ Create a Zitadel project and scaffold local auth.
|
|
|
211
292
|
```
|
|
212
293
|
USAGE
|
|
213
294
|
$ zitadel setup [--json] [-c <value>] [-s <value>] [-n] [-f] [--dry-run] [--verbose] [--debug]
|
|
214
|
-
[--framework next] [--renderer react|web-component]
|
|
295
|
+
[--framework next] [--renderer react|web-component] [--skip-install]
|
|
215
296
|
|
|
216
297
|
FLAGS
|
|
217
298
|
-c, --cwd=<value> Project directory to operate on.
|
|
@@ -224,6 +305,7 @@ FLAGS
|
|
|
224
305
|
<options: next>
|
|
225
306
|
--renderer=<option> Renderer (default: react).
|
|
226
307
|
<options: react|web-component>
|
|
308
|
+
--skip-install Do not install dependencies after setup updates package.json.
|
|
227
309
|
--verbose Verbose logging.
|
|
228
310
|
|
|
229
311
|
GLOBAL FLAGS
|
|
@@ -236,9 +318,36 @@ EXAMPLES
|
|
|
236
318
|
$ zitadel setup --framework next
|
|
237
319
|
```
|
|
238
320
|
|
|
321
|
+
## `zitadel start`
|
|
322
|
+
|
|
323
|
+
Start a local Zitadel server.
|
|
324
|
+
|
|
325
|
+
```
|
|
326
|
+
USAGE
|
|
327
|
+
$ zitadel start [--json] [-c <value>] [-s <value>] [-n] [-f] [--dry-run] [--verbose] [--debug] [--image
|
|
328
|
+
<value>] [--port <value>]
|
|
329
|
+
|
|
330
|
+
FLAGS
|
|
331
|
+
-c, --cwd=<value> Project directory to operate on.
|
|
332
|
+
-f, --force Overwrite protected files on conflict.
|
|
333
|
+
-n, --non-interactive Disable prompts. Required when scripting or running as an agent.
|
|
334
|
+
-s, --server=<value> Override the resolved server URL.
|
|
335
|
+
--debug Debug logging.
|
|
336
|
+
--dry-run Preview without mutating files or the platform.
|
|
337
|
+
--image=<value> Container image to run.
|
|
338
|
+
--port=<value> [default: 8080] Local HTTP port.
|
|
339
|
+
--verbose Verbose logging.
|
|
340
|
+
|
|
341
|
+
GLOBAL FLAGS
|
|
342
|
+
--json Format output as json.
|
|
343
|
+
|
|
344
|
+
DESCRIPTION
|
|
345
|
+
Start a local Zitadel server.
|
|
346
|
+
```
|
|
347
|
+
|
|
239
348
|
## `zitadel status`
|
|
240
349
|
|
|
241
|
-
Summarize the local project state.
|
|
350
|
+
Summarize the local Zitadel server and project state.
|
|
242
351
|
|
|
243
352
|
```
|
|
244
353
|
USAGE
|
|
@@ -257,7 +366,31 @@ GLOBAL FLAGS
|
|
|
257
366
|
--json Format output as json.
|
|
258
367
|
|
|
259
368
|
DESCRIPTION
|
|
260
|
-
Summarize the local project state.
|
|
369
|
+
Summarize the local Zitadel server and project state.
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
## `zitadel stop`
|
|
373
|
+
|
|
374
|
+
Stop the local Zitadel server.
|
|
375
|
+
|
|
376
|
+
```
|
|
377
|
+
USAGE
|
|
378
|
+
$ zitadel stop [--json] [-c <value>] [-s <value>] [-n] [-f] [--dry-run] [--verbose] [--debug]
|
|
379
|
+
|
|
380
|
+
FLAGS
|
|
381
|
+
-c, --cwd=<value> Project directory to operate on.
|
|
382
|
+
-f, --force Overwrite protected files on conflict.
|
|
383
|
+
-n, --non-interactive Disable prompts. Required when scripting or running as an agent.
|
|
384
|
+
-s, --server=<value> Override the resolved server URL.
|
|
385
|
+
--debug Debug logging.
|
|
386
|
+
--dry-run Preview without mutating files or the platform.
|
|
387
|
+
--verbose Verbose logging.
|
|
388
|
+
|
|
389
|
+
GLOBAL FLAGS
|
|
390
|
+
--json Format output as json.
|
|
391
|
+
|
|
392
|
+
DESCRIPTION
|
|
393
|
+
Stop the local Zitadel server.
|
|
261
394
|
```
|
|
262
395
|
|
|
263
396
|
## `zitadel uninstall`
|
|
@@ -340,6 +473,7 @@ EXAMPLES
|
|
|
340
473
|
```
|
|
341
474
|
|
|
342
475
|
_See code: [@oclif/plugin-which](https://github.com/oclif/plugin-which/blob/3.2.55/src/commands/which.ts)_
|
|
476
|
+
|
|
343
477
|
<!-- commandsstop -->
|
|
344
478
|
|
|
345
479
|
</details>
|
package/SKILLS.md
CHANGED
|
@@ -24,7 +24,7 @@ parse the result rather than scraping human output.
|
|
|
24
24
|
metadata) or run `zitadel <command> --help` for the full per-command flag list.
|
|
25
25
|
|
|
26
26
|
```sh
|
|
27
|
-
npx @zitadel/cli@
|
|
27
|
+
npx @zitadel/cli@alpha <command> --non-interactive --json
|
|
28
28
|
```
|
|
29
29
|
|
|
30
30
|
## Reading the envelope
|
|
@@ -38,6 +38,8 @@ Each invocation prints one JSON object:
|
|
|
38
38
|
- On failure: `code` (e.g. `E_VALIDATION`, `E_NETWORK`, `E_CONFLICT`) and
|
|
39
39
|
`message`.
|
|
40
40
|
- `next_commands`: the suggested follow-ups. Prefer these over free-text hints.
|
|
41
|
+
- `E_LOCAL_SERVER_NOT_RUNNING`: start the local Docker runtime with
|
|
42
|
+
`npx @zitadel/cli@alpha start`, then retry with `--server local`.
|
|
41
43
|
|
|
42
44
|
Exit codes mirror the error class (3 = validation, 4 = network, 5 = conflict,
|
|
43
45
|
1 = auth, 2 = not-implemented). An unknown command is handled by the CLI's help
|
|
@@ -51,21 +53,51 @@ layer, not the envelope.
|
|
|
51
53
|
scaffolds nor uploads them. Flags: `--framework`, `--renderer`.
|
|
52
54
|
- `plan` — validate config and preview the sync diff without mutating anything.
|
|
53
55
|
- `apply` — validate and upload repo config to the platform.
|
|
54
|
-
- `doctor` — verify generated files and local state
|
|
55
|
-
|
|
56
|
-
|
|
56
|
+
- `doctor` — verify generated app files and local state once `zitadel.json`
|
|
57
|
+
exists. Local Docker runtime prerequisites are advisory warnings unless an
|
|
58
|
+
existing managed runtime is unhealthy; `--fix` re-applies missing managed
|
|
59
|
+
files.
|
|
60
|
+
- `status` — summarize the local Docker runtime and project state.
|
|
57
61
|
- `eject` (alias `uninstall`) — remove managed files and local Zitadel state;
|
|
58
62
|
requires `--force` when non-interactive.
|
|
63
|
+
- `start` — start the managed local Zitadel container and persist runtime
|
|
64
|
+
metadata under `.zitadel/local/runtime.json`.
|
|
65
|
+
- `stop` — stop/remove the managed container while preserving
|
|
66
|
+
`.zitadel/local/nextgen-data`.
|
|
67
|
+
- `logs` — print managed container logs; `--follow` streams in human mode.
|
|
68
|
+
- `reset` — stop/remove the managed container and delete local runtime data;
|
|
69
|
+
requires `--force` when non-interactive.
|
|
70
|
+
|
|
71
|
+
Alpha releases are lockstep trains. `npx @zitadel/cli@alpha start` runs the
|
|
72
|
+
latest tested alpha server image, and
|
|
73
|
+
`npx @zitadel/cli@0.1.0-alpha.N start` runs
|
|
74
|
+
`ghcr.io/zitadel/nextgen:0.1.0-alpha.N`. `zitadel start --image <ref>` remains
|
|
75
|
+
the explicit image override for debugging.
|
|
59
76
|
|
|
60
77
|
## Golden path
|
|
61
78
|
|
|
62
79
|
```sh
|
|
63
|
-
npx @zitadel/cli@
|
|
64
|
-
npx @zitadel/cli@
|
|
65
|
-
npx @zitadel/cli@
|
|
66
|
-
npx @zitadel/cli@
|
|
80
|
+
npx @zitadel/cli@alpha doctor --non-interactive --json
|
|
81
|
+
npx @zitadel/cli@alpha start --non-interactive --json
|
|
82
|
+
npx @zitadel/cli@alpha setup --framework next --server local --non-interactive --json
|
|
83
|
+
npx @zitadel/cli@alpha doctor --non-interactive --json
|
|
84
|
+
npx @zitadel/cli@alpha plan --non-interactive --json
|
|
85
|
+
npx @zitadel/cli@alpha apply --non-interactive --json
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Exact alpha train invocation:
|
|
89
|
+
|
|
90
|
+
```sh
|
|
91
|
+
npx @zitadel/cli@0.1.0-alpha.N doctor --non-interactive --json
|
|
92
|
+
npx @zitadel/cli@0.1.0-alpha.N start --non-interactive --json
|
|
93
|
+
npx @zitadel/cli@0.1.0-alpha.N setup --framework next --server local --non-interactive --json
|
|
67
94
|
```
|
|
68
95
|
|
|
69
96
|
Repo config is authoritative: edit `zitadel.json` or files under `.zitadel/`,
|
|
70
97
|
then re-run `plan` and `apply`. Managed files carry a marker comment; `eject`
|
|
71
98
|
removes only files that still carry it, preserving anything the user replaced.
|
|
99
|
+
For app-local development, `--server local` resolves through
|
|
100
|
+
`.zitadel/local/runtime.json` and requires a healthy `npx @zitadel/cli@alpha start`
|
|
101
|
+
runtime. `setup` installs dependencies with the detected package manager by
|
|
102
|
+
default; pass `--skip-install` when the agent or host workflow will install
|
|
103
|
+
dependencies separately.
|
package/dist/commands/apply.mjs
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { t as BaseCommand } from "../oclif-CqkWBQ7i.mjs";
|
|
2
|
+
import { o as readZitadelSecret } from "../project-B6YfSaZw.mjs";
|
|
3
|
+
import { a as makeSyncers, i as runSyncLoop, n as summarizePlan, o as environmentSchema, r as buildSyncPlan, t as renderPlan } from "../sync-DN4oNLVH.mjs";
|
|
3
4
|
import { Flags } from "@oclif/core";
|
|
4
|
-
import { consola as consola$1 } from "consola";
|
|
5
5
|
import { createZitadelClient } from "@zitadel/api/client";
|
|
6
|
+
import { consola as consola$1 } from "consola";
|
|
6
7
|
//#region src/commands/apply.ts
|
|
7
8
|
/**
|
|
8
9
|
* `zitadel apply` — validate and upload repo config to the platform.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apply.mjs","names":[],"sources":["../../src/commands/apply.ts"],"sourcesContent":["import { Flags } from \"@oclif/core\";\nimport { consola } from \"consola\";\n\nimport { createZitadelClient } from \"@zitadel/api/client\";\n\nimport { BaseCommand, type JsonEnvelope } from \"../lib/oclif\";\nimport { environmentSchema } from \"../lib/environment\";\nimport { buildSyncPlan, makeSyncers, renderPlan, runSyncLoop, summarizePlan } from \"../lib/sync\";\nimport { readZitadelSecret } from \"../lib/project\";\n\n/**\n * `zitadel apply` — validate and upload repo config to the platform.\n *\n * Runs the sync loop to convergence, or (with `--dry-run`) previews the diff\n * without mutating. All validation — structural shape and `${VAR}` / `*_env`\n * reference presence — happens inside the sync engine ({@link buildSyncPlan}),\n * so an invalid or under-configured file fails with `E_VALIDATION` before any\n * platform call.\n */\nexport default class Apply extends BaseCommand {\n static override description = \"Validate and upload repo config to the platform.\";\n // Temporarily hidden while we collapse the dev workflow around `setup`'s\n // auto-apply. The logic stays wired up so re-exposing this command is a\n // one-line flip when we settle on the surface area.\n static override hidden = true;\n static override flags = {\n environment: Flags.string({\n char: \"e\",\n description: \"Target environment (default: development).\",\n options: [...environmentSchema.options],\n }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { flags } = await this.parse(Apply);\n await this.toMeta(flags);\n const { cwd, source, env, dryRun, isTTY } = this.meta;\n\n const secret = await readZitadelSecret(cwd);\n consola.info(`Project ${secret.project_id}`);\n consola.info(`Server ${source}`);\n const client = createZitadelClient({\n baseUrl: source,\n token: secret.project_secret,\n });\n const syncers = makeSyncers({ client, projectId: secret.project_id, env });\n\n if (!dryRun) {\n consola.start(\"Syncing schemas and flows to Zitadel\");\n await runSyncLoop(cwd, syncers);\n consola.success(\"Sync complete\");\n return this.emit({ status: \"ok\", data: { synced: true } });\n }\n\n consola.start(\"Building plan (dry run)\");\n const plan = await buildSyncPlan(cwd, syncers, true);\n const summary = summarizePlan(plan);\n consola.success(\n `Plan: ${summary.creates} create${summary.creates === 1 ? \"\" : \"s\"}, ` +\n `${summary.updates} update${summary.updates === 1 ? \"\" : \"s\"}, ` +\n `${summary.deletes} delete${summary.deletes === 1 ? \"\" : \"s\"}`,\n );\n return this.emit({\n status: \"ok\",\n data: summary,\n pretty: renderPlan(plan, isTTY),\n });\n }\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"apply.mjs","names":[],"sources":["../../src/commands/apply.ts"],"sourcesContent":["import { Flags } from \"@oclif/core\";\nimport { consola } from \"consola\";\n\nimport { createZitadelClient } from \"@zitadel/api/client\";\n\nimport { BaseCommand, type JsonEnvelope } from \"../lib/oclif\";\nimport { environmentSchema } from \"../lib/environment\";\nimport { buildSyncPlan, makeSyncers, renderPlan, runSyncLoop, summarizePlan } from \"../lib/sync\";\nimport { readZitadelSecret } from \"../lib/project\";\n\n/**\n * `zitadel apply` — validate and upload repo config to the platform.\n *\n * Runs the sync loop to convergence, or (with `--dry-run`) previews the diff\n * without mutating. All validation — structural shape and `${VAR}` / `*_env`\n * reference presence — happens inside the sync engine ({@link buildSyncPlan}),\n * so an invalid or under-configured file fails with `E_VALIDATION` before any\n * platform call.\n */\nexport default class Apply extends BaseCommand {\n static override description = \"Validate and upload repo config to the platform.\";\n // Temporarily hidden while we collapse the dev workflow around `setup`'s\n // auto-apply. The logic stays wired up so re-exposing this command is a\n // one-line flip when we settle on the surface area.\n static override hidden = true;\n static override flags = {\n environment: Flags.string({\n char: \"e\",\n description: \"Target environment (default: development).\",\n options: [...environmentSchema.options],\n }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { flags } = await this.parse(Apply);\n await this.toMeta(flags);\n const { cwd, source, env, dryRun, isTTY } = this.meta;\n\n const secret = await readZitadelSecret(cwd);\n consola.info(`Project ${secret.project_id}`);\n consola.info(`Server ${source}`);\n const client = createZitadelClient({\n baseUrl: source,\n token: secret.project_secret,\n });\n const syncers = makeSyncers({ client, projectId: secret.project_id, env });\n\n if (!dryRun) {\n consola.start(\"Syncing schemas and flows to Zitadel\");\n await runSyncLoop(cwd, syncers);\n consola.success(\"Sync complete\");\n return this.emit({ status: \"ok\", data: { synced: true } });\n }\n\n consola.start(\"Building plan (dry run)\");\n const plan = await buildSyncPlan(cwd, syncers, true);\n const summary = summarizePlan(plan);\n consola.success(\n `Plan: ${summary.creates} create${summary.creates === 1 ? \"\" : \"s\"}, ` +\n `${summary.updates} update${summary.updates === 1 ? \"\" : \"s\"}, ` +\n `${summary.deletes} delete${summary.deletes === 1 ? \"\" : \"s\"}`,\n );\n return this.emit({\n status: \"ok\",\n data: summary,\n pretty: renderPlan(plan, isTTY),\n });\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAmBA,IAAqB,QAArB,MAAqB,cAAc,YAAY;CAC7C,OAAgB,cAAc;CAI9B,OAAgB,SAAS;CACzB,OAAgB,QAAQ,EACtB,aAAa,MAAM,OAAO;EACxB,MAAM;EACN,aAAa;EACb,SAAS,CAAC,GAAG,kBAAkB,QAAQ;EACxC,CAAC,EACH;CAED,MAAM,MAA6B;EACjC,MAAM,EAAE,UAAU,MAAM,KAAK,MAAM,MAAM;AACzC,QAAM,KAAK,OAAO,MAAM;EACxB,MAAM,EAAE,KAAK,QAAQ,KAAK,QAAQ,UAAU,KAAK;EAEjD,MAAM,SAAS,MAAM,kBAAkB,IAAI;AAC3C,YAAQ,KAAK,aAAa,OAAO,aAAa;AAC9C,YAAQ,KAAK,aAAa,SAAS;EAKnC,MAAM,UAAU,YAAY;GAAE,QAJf,oBAAoB;IACjC,SAAS;IACT,OAAO,OAAO;IACf,CACmC;GAAE,WAAW,OAAO;GAAY;GAAK,CAAC;AAE1E,MAAI,CAAC,QAAQ;AACX,aAAQ,MAAM,uCAAuC;AACrD,SAAM,YAAY,KAAK,QAAQ;AAC/B,aAAQ,QAAQ,gBAAgB;AAChC,UAAO,KAAK,KAAK;IAAE,QAAQ;IAAM,MAAM,EAAE,QAAQ,MAAM;IAAE,CAAC;;AAG5D,YAAQ,MAAM,0BAA0B;EACxC,MAAM,OAAO,MAAM,cAAc,KAAK,SAAS,KAAK;EACpD,MAAM,UAAU,cAAc,KAAK;AACnC,YAAQ,QACN,SAAS,QAAQ,QAAQ,SAAS,QAAQ,YAAY,IAAI,KAAK,IAAI,IAC9D,QAAQ,QAAQ,SAAS,QAAQ,YAAY,IAAI,KAAK,IAAI,IAC1D,QAAQ,QAAQ,SAAS,QAAQ,YAAY,IAAI,KAAK,MAC5D;AACD,SAAO,KAAK,KAAK;GACf,QAAQ;GACR,MAAM;GACN,QAAQ,WAAW,MAAM,MAAM;GAChC,CAAC"}
|
package/dist/commands/doctor.mjs
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import { a as
|
|
2
|
-
import { r as issuerFromPort, t as createOrca } from "../orca-
|
|
1
|
+
import { C as isObject, E as ZitadelError, a as DEFAULT_LOCAL_SERVER_PORT, c as checkLocalServerHealth, f as isPortAvailable, g as readRuntimeMetadata, h as localServerUrl, l as defaultLocalServerImageForCliVersion, m as localRuntimePaths, s as assertWritableDirectory, t as BaseCommand, x as publicCliCommand } from "../oclif-CqkWBQ7i.mjs";
|
|
2
|
+
import { r as issuerFromPort, t as createOrca } from "../orca-S1tVnngd.mjs";
|
|
3
|
+
import { a as readZitadelConfig, i as readRendererId, o as readZitadelSecret, r as readDevelopmentIssuer, t as hasZitadelConfig } from "../project-B6YfSaZw.mjs";
|
|
4
|
+
import { o as imageAvailable, r as dockerAvailable } from "../docker-DrOBycgG.mjs";
|
|
3
5
|
import { Flags } from "@oclif/core";
|
|
4
6
|
import consola from "consola";
|
|
5
|
-
import { chmod, readFile, stat, writeFile } from "node:fs/promises";
|
|
6
7
|
import { join } from "node:path";
|
|
8
|
+
import { chmod, readFile, stat, writeFile } from "node:fs/promises";
|
|
7
9
|
import "@zitadel/api/generated/endpoints/zitadelNextGen.zod";
|
|
8
10
|
//#region src/commands/doctor/checks/types.ts
|
|
9
11
|
/**
|
|
@@ -148,7 +150,7 @@ var FrameworkCheck = class extends AbstractSanityCheck {
|
|
|
148
150
|
* SDK package via `patcher.repair`. The user schema and flow definition are
|
|
149
151
|
* server-owned and no longer scaffolded locally, so nothing here reads them.
|
|
150
152
|
*/
|
|
151
|
-
async function loadPatchContext(cwd, orca) {
|
|
153
|
+
async function loadPatchContext(cwd, orca, cliVersion) {
|
|
152
154
|
const config = await readZitadelConfig(cwd);
|
|
153
155
|
const secret = await readZitadelSecret(cwd);
|
|
154
156
|
const framework = await orca.detect(cwd);
|
|
@@ -157,6 +159,7 @@ async function loadPatchContext(cwd, orca) {
|
|
|
157
159
|
rendererId: readRendererId(config),
|
|
158
160
|
issuer: await resolveIssuer(cwd, config, framework),
|
|
159
161
|
server: typeof config.server === "string" ? config.server : "",
|
|
162
|
+
cliVersion,
|
|
160
163
|
project: {
|
|
161
164
|
id: secret.project_id,
|
|
162
165
|
projectSecret: secret.project_secret,
|
|
@@ -206,7 +209,7 @@ var DependencyCheck = class extends AbstractSanityCheck {
|
|
|
206
209
|
* so going through `repair` is the only sanctioned path.
|
|
207
210
|
*/
|
|
208
211
|
async fix(ctx) {
|
|
209
|
-
const patchCtx = await loadPatchContext(ctx.cwd, ctx.orca);
|
|
212
|
+
const patchCtx = await loadPatchContext(ctx.cwd, ctx.orca, ctx.cliVersion);
|
|
210
213
|
await ctx.orca.patcherFor(patchCtx.framework.id).repair(patchCtx, {
|
|
211
214
|
cwd: ctx.cwd,
|
|
212
215
|
dryRun: ctx.dryRun,
|
|
@@ -243,6 +246,13 @@ const SANITY_CHECKS = [
|
|
|
243
246
|
];
|
|
244
247
|
//#endregion
|
|
245
248
|
//#region src/commands/doctor/index.ts
|
|
249
|
+
const LOCAL_RUNTIME_CHECK_NAMES = new Set([
|
|
250
|
+
"docker-cli",
|
|
251
|
+
"image",
|
|
252
|
+
"state-dir",
|
|
253
|
+
"port",
|
|
254
|
+
"runtime"
|
|
255
|
+
]);
|
|
246
256
|
/**
|
|
247
257
|
* `zitadel doctor` — verify generated files and local state.
|
|
248
258
|
*
|
|
@@ -257,18 +267,33 @@ const SANITY_CHECKS = [
|
|
|
257
267
|
* whatever remains broken.
|
|
258
268
|
*/
|
|
259
269
|
var Doctor = class Doctor extends BaseCommand {
|
|
260
|
-
static description = "Verify
|
|
261
|
-
static flags = {
|
|
270
|
+
static description = "Verify local runtime and project state.";
|
|
271
|
+
static flags = {
|
|
272
|
+
fix: Flags.boolean({ description: "Re-apply missing managed files." }),
|
|
273
|
+
image: Flags.string({ description: "Container image to check." }),
|
|
274
|
+
port: Flags.integer({
|
|
275
|
+
description: "Local HTTP port.",
|
|
276
|
+
default: DEFAULT_LOCAL_SERVER_PORT
|
|
277
|
+
})
|
|
278
|
+
};
|
|
262
279
|
async run() {
|
|
263
280
|
const { flags } = await this.parse(Doctor);
|
|
264
|
-
|
|
281
|
+
const port = flags.port ?? 8080;
|
|
282
|
+
await this.toMeta(flags, {
|
|
283
|
+
resolveServer: false,
|
|
284
|
+
source: localServerUrl(port)
|
|
285
|
+
});
|
|
265
286
|
const { cwd, dryRun } = this.meta;
|
|
287
|
+
const image = flags.image ?? this.meta.env.ZITADEL_LOCAL_IMAGE ?? defaultLocalServerImageForCliVersion(this.meta.cliVersion);
|
|
288
|
+
const runtimeChecks = await runLocalRuntimeChecks(cwd, image, port);
|
|
289
|
+
const hasConfig = await hasZitadelConfig(cwd);
|
|
266
290
|
const ctx = {
|
|
267
291
|
cwd,
|
|
268
292
|
orca: createOrca(),
|
|
293
|
+
cliVersion: this.meta.cliVersion,
|
|
269
294
|
dryRun
|
|
270
295
|
};
|
|
271
|
-
if (flags.fix) {
|
|
296
|
+
if (hasConfig && flags.fix) {
|
|
272
297
|
const before = await Promise.all(SANITY_CHECKS.map((check) => check.run(ctx)));
|
|
273
298
|
for (const [index, check] of SANITY_CHECKS.entries()) {
|
|
274
299
|
if (before[index]?.status !== "fail") continue;
|
|
@@ -279,23 +304,132 @@ var Doctor = class Doctor extends BaseCommand {
|
|
|
279
304
|
}
|
|
280
305
|
}
|
|
281
306
|
}
|
|
282
|
-
const
|
|
307
|
+
const projectChecks = hasConfig ? await Promise.all(SANITY_CHECKS.map((check) => check.run(ctx))) : [];
|
|
308
|
+
const checks = [...runtimeChecks, ...projectChecks];
|
|
283
309
|
const failed = checks.filter((check) => check.status === "fail");
|
|
310
|
+
const warnings = checks.filter((check) => check.status === "warn");
|
|
284
311
|
const data = {
|
|
285
|
-
title: failed.length
|
|
312
|
+
title: failed.length > 0 ? "Zitadel doctor found issues." : warnings.length > 0 ? "Zitadel doctor passed with warnings." : "Zitadel doctor passed.",
|
|
286
313
|
ok: failed.length === 0,
|
|
314
|
+
image,
|
|
315
|
+
port,
|
|
316
|
+
project: { lifecycle: hasConfig ? "configured" : "not-configured" },
|
|
287
317
|
checks
|
|
288
318
|
};
|
|
289
|
-
if (failed.length > 0)
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
319
|
+
if (failed.length > 0) {
|
|
320
|
+
const advice = failureAdvice(failed, image, port, this.meta.cliVersion);
|
|
321
|
+
throw new ZitadelError("E_VALIDATION", "Zitadel doctor found issues", {
|
|
322
|
+
hint: advice.hint,
|
|
323
|
+
nextCommands: advice.nextCommands,
|
|
324
|
+
details: data
|
|
325
|
+
});
|
|
326
|
+
}
|
|
293
327
|
return this.emit({
|
|
294
328
|
status: "ok",
|
|
295
|
-
data
|
|
329
|
+
data,
|
|
330
|
+
warnings: warnings.map((warning) => `${warning.name}: ${warning.message}`)
|
|
296
331
|
});
|
|
297
332
|
}
|
|
298
333
|
};
|
|
334
|
+
function failureAdvice(failed, image, port, cliVersion) {
|
|
335
|
+
const failedNames = new Set(failed.map((check) => check.name));
|
|
336
|
+
if (failedNames.has("docker-cli")) return {
|
|
337
|
+
hint: "Docker is required for `zitadel start`, but the Docker daemon is not reachable. Install or start Docker, then rerun `zitadel doctor`.",
|
|
338
|
+
nextCommands: ["docker version", publicCliCommand("doctor", cliVersion)]
|
|
339
|
+
};
|
|
340
|
+
if (failedNames.has("image")) return {
|
|
341
|
+
hint: "The local Zitadel image is not available. Check Docker registry access, build it locally, or pass --image / ZITADEL_LOCAL_IMAGE.",
|
|
342
|
+
nextCommands: [`docker pull ${image}`, publicCliCommand("doctor", cliVersion)]
|
|
343
|
+
};
|
|
344
|
+
if (failedNames.has("state-dir")) return {
|
|
345
|
+
hint: "The local Zitadel state directory is not writable. Fix directory permissions, then rerun `zitadel doctor`.",
|
|
346
|
+
nextCommands: [publicCliCommand("doctor", cliVersion)]
|
|
347
|
+
};
|
|
348
|
+
if (failedNames.has("port")) {
|
|
349
|
+
const fallbackPort = port === 8080 ? port + 1 : DEFAULT_LOCAL_SERVER_PORT;
|
|
350
|
+
return {
|
|
351
|
+
hint: `Port ${String(port)} is already in use. Stop the process using it, or choose another port for local Zitadel.`,
|
|
352
|
+
nextCommands: [publicCliCommand(`doctor --port ${String(fallbackPort)}`, cliVersion)]
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
if (failedNames.has("runtime")) return {
|
|
356
|
+
hint: "Existing local runtime metadata was found, but the local Zitadel server is not healthy. Start it again or reset stale local data.",
|
|
357
|
+
nextCommands: [publicCliCommand("start", cliVersion), publicCliCommand("reset --force", cliVersion)]
|
|
358
|
+
};
|
|
359
|
+
if (failed.some((check) => !LOCAL_RUNTIME_CHECK_NAMES.has(check.name))) return {
|
|
360
|
+
hint: `Run \`${publicCliCommand("doctor --fix", cliVersion)}\` to re-apply missing managed files.`,
|
|
361
|
+
nextCommands: [publicCliCommand("doctor --fix", cliVersion)]
|
|
362
|
+
};
|
|
363
|
+
return {
|
|
364
|
+
hint: "Fix the reported checks, then rerun `zitadel doctor`.",
|
|
365
|
+
nextCommands: [publicCliCommand("doctor", cliVersion)]
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
async function runLocalRuntimeChecks(cwd, image, port) {
|
|
369
|
+
const runtime = await readRuntimeMetadata(cwd);
|
|
370
|
+
const docker = await check("docker-cli", "Docker is reachable", async () => {
|
|
371
|
+
let result;
|
|
372
|
+
try {
|
|
373
|
+
result = await dockerAvailable();
|
|
374
|
+
} catch (error) {
|
|
375
|
+
throw new Error(dockerUnavailableMessage(error), { cause: error });
|
|
376
|
+
}
|
|
377
|
+
if (result.status !== 0) throw new Error(dockerUnavailableMessage(result.stderr || "docker version failed"));
|
|
378
|
+
return `Docker engine ${result.stdout.trim() || "available"}`;
|
|
379
|
+
}, "warn");
|
|
380
|
+
return [
|
|
381
|
+
docker,
|
|
382
|
+
docker.status === "pass" ? await check("image", `Image ${image} is available`, async () => {
|
|
383
|
+
try {
|
|
384
|
+
return await imageAvailable(image) === "local" ? `Image ${image} is available locally` : `Image ${image} is available from the registry`;
|
|
385
|
+
} catch (error) {
|
|
386
|
+
throw new Error(imageUnavailableMessage(image, error), { cause: error });
|
|
387
|
+
}
|
|
388
|
+
}, "warn") : {
|
|
389
|
+
name: "image",
|
|
390
|
+
status: "warn",
|
|
391
|
+
message: "Skipped image check because Docker is not reachable."
|
|
392
|
+
},
|
|
393
|
+
await check("state-dir", "Local state directory is writable", async () => {
|
|
394
|
+
const paths = localRuntimePaths(cwd);
|
|
395
|
+
await assertWritableDirectory(paths.dataDir);
|
|
396
|
+
return `${paths.dataDir} is writable`;
|
|
397
|
+
}, "warn"),
|
|
398
|
+
await check("port", `Port ${String(port)} is available`, async () => {
|
|
399
|
+
if (runtime && await checkLocalServerHealth(runtime.server_url)) return `${runtime.server_url} is already healthy`;
|
|
400
|
+
if (!await isPortAvailable(port)) throw new Error(`Port ${String(port)} is already in use`);
|
|
401
|
+
return `Port ${String(port)} is available`;
|
|
402
|
+
}, "warn"),
|
|
403
|
+
await check("runtime", "Existing local runtime is healthy", async () => {
|
|
404
|
+
if (!runtime) return "No existing runtime metadata";
|
|
405
|
+
if (!await checkLocalServerHealth(runtime.server_url)) throw new Error(`${runtime.server_url} did not respond to /healthz`);
|
|
406
|
+
return `${runtime.server_url} is healthy`;
|
|
407
|
+
})
|
|
408
|
+
];
|
|
409
|
+
}
|
|
410
|
+
async function check(name, fallback, run, failureStatus = "fail") {
|
|
411
|
+
try {
|
|
412
|
+
return {
|
|
413
|
+
name,
|
|
414
|
+
status: "pass",
|
|
415
|
+
message: await run()
|
|
416
|
+
};
|
|
417
|
+
} catch (error) {
|
|
418
|
+
return {
|
|
419
|
+
name,
|
|
420
|
+
status: failureStatus,
|
|
421
|
+
message: error instanceof Error ? error.message : fallback
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
function dockerUnavailableMessage(error) {
|
|
426
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
427
|
+
return `Docker is not reachable${detail.trim() ? ` (${detail.trim()})` : ""}; \`zitadel start\` needs Docker, but cloud setup can continue.`;
|
|
428
|
+
}
|
|
429
|
+
function imageUnavailableMessage(image, error) {
|
|
430
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
431
|
+
return `Image ${image} is not available to Docker${detail.trim() ? ` (${detail.trim()})` : ""}; \`zitadel start\` may need a pull or a different image.`;
|
|
432
|
+
}
|
|
299
433
|
//#endregion
|
|
300
434
|
export { Doctor as default };
|
|
301
435
|
|