@zitadel/cli 0.1.0-alpha.18 → 0.1.0-alpha.19
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 +81 -33
- package/SKILLS.md +74 -8
- package/dist/{branding-BXj028-W.mjs → branding-cygSBPkV.mjs} +2 -2
- package/dist/{branding-BXj028-W.mjs.map → branding-cygSBPkV.mjs.map} +1 -1
- package/dist/{claim-state-BTGInAaN.mjs → claim-state-DlfD6Res.mjs} +2 -2
- package/dist/{claim-state-BTGInAaN.mjs.map → claim-state-DlfD6Res.mjs.map} +1 -1
- package/dist/commands/apply.mjs +4 -4
- package/dist/commands/branding/eject.mjs +11 -32
- package/dist/commands/branding/eject.mjs.map +1 -1
- package/dist/commands/claim.mjs +3 -3
- package/dist/commands/doctor.mjs +41 -18
- package/dist/commands/doctor.mjs.map +1 -1
- package/dist/commands/eject.mjs +4 -4
- package/dist/commands/eject.mjs.map +1 -1
- package/dist/commands/logs.mjs +2 -2
- package/dist/commands/plan.mjs +4 -4
- package/dist/commands/reset.mjs +2 -2
- package/dist/commands/schemas/list.mjs +6 -6
- package/dist/commands/schemas/list.mjs.map +1 -1
- package/dist/commands/setup.mjs +101 -143
- package/dist/commands/setup.mjs.map +1 -1
- package/dist/commands/start.mjs +3 -3
- package/dist/commands/status.mjs +5 -5
- package/dist/commands/stop.mjs +3 -3
- package/dist/designs-Ckz18Dpo.mjs +38 -0
- package/dist/designs-Ckz18Dpo.mjs.map +1 -0
- package/dist/{docker-Ciz9N6uI.mjs → docker-DcRGTOJa.mjs} +4 -3
- package/dist/docker-DcRGTOJa.mjs.map +1 -0
- package/dist/{environment-CuHKxtIO.mjs → environment-rjRVkJjW.mjs} +1 -1
- package/dist/{environment-CuHKxtIO.mjs.map → environment-rjRVkJjW.mjs.map} +1 -1
- package/dist/{journey-guidance-CtQUfWar.mjs → journey-guidance-BGrOX_gT.mjs} +2 -2
- package/dist/{journey-guidance-CtQUfWar.mjs.map → journey-guidance-BGrOX_gT.mjs.map} +1 -1
- package/dist/{oclif-CL6-M13m.mjs → oclif-CanO3zdt.mjs} +48 -2
- package/dist/oclif-CanO3zdt.mjs.map +1 -0
- package/dist/{orca-BWB4zOdw.mjs → orca-Cu0iW1mv.mjs} +167 -26
- package/dist/orca-Cu0iW1mv.mjs.map +1 -0
- package/dist/package-manager-DFdLcDx1.mjs +194 -0
- package/dist/package-manager-DFdLcDx1.mjs.map +1 -0
- package/dist/{ports-Cu2Y7aXQ.mjs → ports-BM20XIZb.mjs} +2 -2
- package/dist/{ports-Cu2Y7aXQ.mjs.map → ports-BM20XIZb.mjs.map} +1 -1
- package/dist/{processes-Bn2WngOi.mjs → processes-DKHPkU8O.mjs} +1 -1
- package/dist/{processes-Bn2WngOi.mjs.map → processes-DKHPkU8O.mjs.map} +1 -1
- package/dist/{project-yejJSfdJ.mjs → project-CHhot85s.mjs} +2 -2
- package/dist/{project-yejJSfdJ.mjs.map → project-CHhot85s.mjs.map} +1 -1
- package/dist/{sync-Cx2_4rXW.mjs → sync-Bd6vASgg.mjs} +456 -31
- package/dist/sync-Bd6vASgg.mjs.map +1 -0
- package/dist/{user-schema-W1OsXdpc.mjs → user-schema-DTuOsdKE.mjs} +1 -1
- package/dist/{user-schema-W1OsXdpc.mjs.map → user-schema-DTuOsdKE.mjs.map} +1 -1
- package/oclif.manifest.json +2 -2
- package/package.json +6 -5
- package/dist/docker-Ciz9N6uI.mjs.map +0 -1
- package/dist/oclif-CL6-M13m.mjs.map +0 -1
- package/dist/orca-BWB4zOdw.mjs.map +0 -1
- package/dist/scaffold-manifest-CKNFLX9T.mjs +0 -81
- package/dist/scaffold-manifest-CKNFLX9T.mjs.map +0 -1
- package/dist/sync-Cx2_4rXW.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @zitadel/cli
|
|
2
2
|
|
|
3
|
-
Scaffolds Zitadel auth (login, register, profile, middleware) into a Next.js, React, Vue, Angular, or
|
|
3
|
+
Scaffolds Zitadel auth (login, register, profile, middleware/proxy) into a Next.js, Nuxt, React, Vue, Angular, Solid, Svelte, or Qwik app.
|
|
4
4
|
|
|
5
5
|
```sh
|
|
6
6
|
npx @zitadel/cli@alpha start
|
|
@@ -15,9 +15,10 @@ automation when reproducibility matters.
|
|
|
15
15
|
|
|
16
16
|
## Requirements
|
|
17
17
|
|
|
18
|
-
- Node 24
|
|
18
|
+
- Node from the supported range in `package.json#engines` (currently ≥ 24)
|
|
19
19
|
- Docker only when using the optional Docker runtime backend
|
|
20
|
-
-
|
|
20
|
+
- An app in one of the eight supported frameworks, or an empty directory
|
|
21
|
+
where setup can scaffold one
|
|
21
22
|
|
|
22
23
|
## Quickstart
|
|
23
24
|
|
|
@@ -31,14 +32,20 @@ npm run dev
|
|
|
31
32
|
```
|
|
32
33
|
|
|
33
34
|
`start` runs the `@zitadel/server` npm binary by default and stores runtime data
|
|
34
|
-
under `.zitadel/local
|
|
35
|
-
starting a local runtime. Use `--runtime docker`,
|
|
36
|
-
`ZITADEL_LOCAL_IMAGE` for advanced Docker backend debugging.
|
|
35
|
+
under `.zitadel/local/` (SQLite by default). Remote-server setup can use
|
|
36
|
+
`--server <url>` without starting a local runtime. Use `--runtime docker`,
|
|
37
|
+
`--image`, or `ZITADEL_LOCAL_IMAGE` for advanced Docker backend debugging.
|
|
37
38
|
`setup --server local` creates a project on that local server, asks which
|
|
38
|
-
framework to scaffold when the directory is fresh
|
|
39
|
-
the current directory, scaffolds
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
framework to scaffold when the directory is fresh (and which login design to
|
|
40
|
+
use), writes the app into the current directory, and scaffolds the framework's
|
|
41
|
+
idiomatic auth routes plus the proxy layer — for Next.js that means
|
|
42
|
+
`app/login`, `app/register`, `app/profile`, and `proxy.ts` for Next 16+ or
|
|
43
|
+
`middleware.ts` for older versions; other frameworks get their equivalents
|
|
44
|
+
from the same patcher system. In a pre-existing app, setup derives the
|
|
45
|
+
embedding posture from the app instead of assuming a fresh skeleton: the
|
|
46
|
+
scaffolded pages take the `variant="widget"` posture inside your app's own
|
|
47
|
+
shell, recorded in the scaffold manifest and verified by `doctor`. Fresh
|
|
48
|
+
scaffolds also replace the starter home page with a redirect to `/login`.
|
|
42
49
|
Setup writes `.env.local` and `.zitadel/`, and installs
|
|
43
50
|
dependencies with the detected package manager. Pass `--skip-install` to install
|
|
44
51
|
them yourself. The project's default user schema and login flow are provisioned
|
|
@@ -80,13 +87,23 @@ and agent UIs may display stderr package-manager progress together with stdout.
|
|
|
80
87
|
|
|
81
88
|
## Other commands
|
|
82
89
|
|
|
90
|
+
- `zitadel claim` — attach the project to your team (opens the claim page,
|
|
91
|
+
polls for completion; team attachment then shows in `setup`, `status`, and
|
|
92
|
+
`doctor`)
|
|
83
93
|
- `zitadel doctor` — verify the local runtime and generated project files
|
|
94
|
+
(including scaffold drift and dependency-version alignment)
|
|
84
95
|
- `zitadel status` — summarise the local runtime and project
|
|
85
96
|
- `zitadel plan` — validate config and preview sync changes without mutation
|
|
86
97
|
- `zitadel apply` — validate and upload repo config to Zitadel
|
|
98
|
+
- `zitadel branding eject` — scaffold an editable login template from a design
|
|
99
|
+
- `zitadel schemas list` — list the project's user schemas
|
|
87
100
|
- `zitadel eject` — remove what setup wrote (alias: `zitadel uninstall`)
|
|
88
101
|
- `zitadel start|stop|logs|reset` — manage the local runtime
|
|
89
102
|
|
|
103
|
+
The full agent-facing contract (JSON envelope, posture rules, claim flow,
|
|
104
|
+
doctor repair) is [`SKILLS.md`](https://github.com/zitadel/nextgen/blob/main/apps/cli/SKILLS.md),
|
|
105
|
+
which ships in this package.
|
|
106
|
+
|
|
90
107
|
## Reference
|
|
91
108
|
|
|
92
109
|
<details>
|
|
@@ -484,29 +501,60 @@ USAGE
|
|
|
484
501
|
centered|split|split-right|hero|minimal]
|
|
485
502
|
|
|
486
503
|
FLAGS
|
|
487
|
-
-c, --cwd=<value>
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
504
|
+
-c, --cwd=<value>
|
|
505
|
+
Project directory to operate on.
|
|
506
|
+
|
|
507
|
+
-f, --force
|
|
508
|
+
Overwrite protected files on conflict.
|
|
509
|
+
|
|
510
|
+
-n, --non-interactive
|
|
511
|
+
Disable prompts. Required when scripting or running as an agent.
|
|
512
|
+
|
|
513
|
+
-s, --server=<value>
|
|
514
|
+
Override the resolved server URL.
|
|
515
|
+
|
|
516
|
+
--debug
|
|
517
|
+
Debug logging.
|
|
518
|
+
|
|
519
|
+
--design=<option>
|
|
520
|
+
Login design to eject into .zitadel/branding/ and publish as branding revision 1. Skips the wizard's design
|
|
521
|
+
question. When omitted in non-interactive runs, the login uses the built-in template; run the `branding eject`
|
|
522
|
+
command later to customize. Split-family designs (split, split-right, hero) collapse their brand pane by container
|
|
523
|
+
width: narrow containers — including widget-posture embeds at card width — render the compact brand mark instead
|
|
524
|
+
(logo_url, else hero_url, from .zitadel/branding/branding.json; hero falls back to editable text).
|
|
525
|
+
<options: centered|split|split-right|hero|minimal>
|
|
526
|
+
|
|
527
|
+
--dev-port=<value>
|
|
528
|
+
Dev-server port; also the issuer origin registered with Zitadel. Defaults to the detected port. Use distinct ports
|
|
529
|
+
to run several scaffolded apps side by side.
|
|
530
|
+
|
|
531
|
+
--dry-run
|
|
532
|
+
Preview without mutating files or the platform.
|
|
533
|
+
|
|
534
|
+
--framework=<option>
|
|
535
|
+
Framework to target.
|
|
536
|
+
<options: next|nuxt|react|vue|solid|svelte|qwik|angular>
|
|
537
|
+
|
|
538
|
+
--preset=<option>
|
|
539
|
+
Sign-in preset for the scaffolded schema and login flow (default: password-first).
|
|
540
|
+
<options: password-first|passkey-first>
|
|
541
|
+
|
|
542
|
+
--renderer=<option>
|
|
543
|
+
Renderer (default: react). Not yet available: web-component.
|
|
544
|
+
<options: react>
|
|
545
|
+
|
|
546
|
+
--skip-install
|
|
547
|
+
Do not install dependencies after setup updates package.json.
|
|
548
|
+
|
|
549
|
+
--[no-]telemetry
|
|
550
|
+
Send anonymous usage analytics. Disable with --no-telemetry.
|
|
551
|
+
|
|
552
|
+
--use-case=<option>
|
|
553
|
+
Use case for the scaffolded schema fields: who signs in to the app (default: minimal).
|
|
554
|
+
<options: minimal|consumer|business>
|
|
555
|
+
|
|
556
|
+
--verbose
|
|
557
|
+
Verbose logging.
|
|
510
558
|
|
|
511
559
|
GLOBAL FLAGS
|
|
512
560
|
--json Format output as json.
|
package/SKILLS.md
CHANGED
|
@@ -99,7 +99,14 @@ the CLI's help layer, not the envelope.
|
|
|
99
99
|
templates by it; the planned `web-component` renderer is not yet available
|
|
100
100
|
and is rejected if passed), `--dev-port` (dev-server port, also the issuer
|
|
101
101
|
origin registered with Zitadel — use distinct ports to run several scaffolded
|
|
102
|
-
apps side by side
|
|
102
|
+
apps side by side. The app must actually serve this port or the flow API
|
|
103
|
+
rejects its origin on the first submit, so setup makes the port explicit in
|
|
104
|
+
the app's own dev-server config: `server.port` + `strictPort` for Vite
|
|
105
|
+
frameworks, `serve.options.port` for Angular, and — because `next dev` and
|
|
106
|
+
`nuxt dev` take a port only from the command line — `--port` in the
|
|
107
|
+
`package.json` `dev` script for Next and Nuxt. On a pre-existing app that
|
|
108
|
+
means setup edits the `dev` script when it does not already name that port;
|
|
109
|
+
a script already on it is left untouched), `--preset password-first|passkey-first` (the sign-in
|
|
103
110
|
experience the scaffold starts from: `password-first` is the default —
|
|
104
111
|
email + password with passkey optional during registration; `passkey-first`
|
|
105
112
|
enters login on a one-tap passkey step with an email + password fallback;
|
|
@@ -114,8 +121,51 @@ the CLI's help layer, not the envelope.
|
|
|
114
121
|
the interactive wizard asks this as its final question with the built-in
|
|
115
122
|
template preselected — omit the flag in non-interactive runs to keep the
|
|
116
123
|
built-in template and no branding files), `--skip-install`.
|
|
124
|
+
On Next and Nuxt, the scaffolded auth/profile pages derive their embedding
|
|
125
|
+
posture from the app: a fresh scaffold (setup created the skeleton) pins
|
|
126
|
+
`variant="page"` full-page chrome, while a pre-existing app embeds
|
|
127
|
+
`variant="widget"` cards with `theme="auto"` in a layout-neutral wrapper.
|
|
128
|
+
`theme="auto"` follows the OS `prefers-color-scheme`, not the host app's
|
|
129
|
+
own theme — edit the generated page to set `theme="light"` or
|
|
130
|
+
`theme="dark"` when the app pins its scheme. Other frameworks always
|
|
131
|
+
scaffold the page posture. The chosen posture is recorded in the scaffold
|
|
132
|
+
manifest, `doctor --fix` restores managed pages in the recorded posture,
|
|
133
|
+
and editing the generated page is the supported way to change presentation
|
|
134
|
+
— there is no config knob.
|
|
135
|
+
Widget-posture embedding levers: host-page CSS sets `--zl-*` design-token
|
|
136
|
+
custom properties on the element to bridge the app's look through the
|
|
137
|
+
widget's shadow DOM (fonts `--zl-font-family-heading`/`-sans`, radii
|
|
138
|
+
`--zl-radius-*`, primary CTA `--zl-primary`/`--zl-primary-foreground`,
|
|
139
|
+
link color `--zl-color-text-link`); the `suppress-header` attribute
|
|
140
|
+
(wrapper prop `suppressHeader`) visually hides the widget's own heading
|
|
141
|
+
block when the page already carries one, keeping it in the accessibility
|
|
142
|
+
tree. Split-family designs collapse their brand pane by container width —
|
|
143
|
+
at card width they show the compact brand mark (`logo_url`, else
|
|
144
|
+
`hero_url`, from `.zitadel/branding/branding.json`; `hero` falls back to
|
|
145
|
+
editable text), and setup warns when a widget-posture app picks `split`
|
|
146
|
+
or `split-right`.
|
|
117
147
|
- `plan` — validate config and preview the sync diff without mutating anything.
|
|
118
148
|
- `apply` — validate and upload repo config to the platform.
|
|
149
|
+
- `plan` and `apply --dry-run` also emit `data.warnings`: non-blocking
|
|
150
|
+
findings as `{path, rule, message}`, the same text the human plan prints as
|
|
151
|
+
`# warning:` lines and `apply` prints through stderr. They never fail a run.
|
|
152
|
+
Two families exist today: flow-definition rules (`warn/…`, mirrored from the
|
|
153
|
+
server's validator) and branding asset reachability. `warn/asset-unreachable`
|
|
154
|
+
and `warn/asset-content-type` come from a bounded HEAD probe of
|
|
155
|
+
`logo_url` / `hero_url` — a URL that is well-formed but dead passes every
|
|
156
|
+
gate and then renders as a 0×0 image with nothing in the console, so the
|
|
157
|
+
probe is the only place it can be caught. It is advisory by design: the
|
|
158
|
+
machine planning is not necessarily the machine that renders the login page.
|
|
159
|
+
The probe only contacts public HTTPS destinations and re-checks every
|
|
160
|
+
redirect; loopback/private/internal targets stay inconclusive instead of
|
|
161
|
+
turning repo config into a network request from the planning host.
|
|
162
|
+
Set `ZITADEL_SKIP_ASSET_PROBE` to turn it off (offline, air-gapped CI, or a
|
|
163
|
+
CDN that only resolves from production) and `ZITADEL_ASSET_PROBE_TIMEOUT_MS`
|
|
164
|
+
to retune the per-URL budget (default 2500).
|
|
165
|
+
- In the human-readable plan, a multi-line field (branding's inlined
|
|
166
|
+
`liquid_template`) renders as `(<n> lines, sha256:…)` when it is created or
|
|
167
|
+
unchanged, and as a changed-line diff when it moved — not as one escaped
|
|
168
|
+
line. Read the file itself for full content.
|
|
119
169
|
- `schemas list` — inspect the revision history of a user-schema, filtered by
|
|
120
170
|
`--object-type` (e.g. `human-user`). Non-interactive/`--json` prints one row
|
|
121
171
|
per revision (newest first); interactive adds a picker that fetches and
|
|
@@ -129,7 +179,11 @@ the CLI's help layer, not the envelope.
|
|
|
129
179
|
managed config wirings (Vite/Nuxt proxy merges, Angular's `angular.json`
|
|
130
180
|
proxy and auth routes) through the patchers' idempotent transforms — a
|
|
131
181
|
detached or missing wiring config fails, an unverifiable one warns, and
|
|
132
|
-
`--fix` re-applies it.
|
|
182
|
+
`--fix` re-applies it. The Next/Nuxt `dev` script is verified the same way,
|
|
183
|
+
against the port recorded as the development issuer rather than the port the
|
|
184
|
+
script names today: a script moved off that port reports as an unapplied
|
|
185
|
+
config edit (a warning — a `dev` script is not the only way to choose a
|
|
186
|
+
port), and `--fix` restores the registered one. Boundary migrations converge: a pristine leftover
|
|
133
187
|
`middleware.ts` from a Next 15→16 upgrade is swapped for `proxy.ts`, while
|
|
134
188
|
an edited one is reported as a conflict instead of creating both (Next
|
|
135
189
|
rejects the pair). The default local
|
|
@@ -138,7 +192,14 @@ the CLI's help layer, not the envelope.
|
|
|
138
192
|
files and never replaces an existing scaffolded app file; additive repairs
|
|
139
193
|
(missing `.gitignore` entries, `.env.example` keys) still append to their
|
|
140
194
|
targets, and the SDK dependency is re-added only when absent — an existing
|
|
141
|
-
version pin is never rewritten.
|
|
195
|
+
version pin is never rewritten. The `dependency-version` check warns when
|
|
196
|
+
an exactly-pinned `@zitadel/*` dependency does not match the CLI's own
|
|
197
|
+
version (the packages release as one train, and a floating
|
|
198
|
+
`npx @zitadel/cli@alpha` can run ahead of the app's pins); ranges,
|
|
199
|
+
dist-tags, and `file:`/`workspace:` specifiers express a deliberate choice
|
|
200
|
+
and are not compared. The repair — an exact-pin install command for the
|
|
201
|
+
project's detected package manager — is emitted in `data.next_commands`
|
|
202
|
+
and quoted in the warning message.
|
|
142
203
|
- `claim` — attach the project to a team so it becomes permanent. Mints a
|
|
143
204
|
short-lived link, opens it in a browser, and blocks until the developer
|
|
144
205
|
finishes signing in there, then records `claimed_at` and `team_id` in
|
|
@@ -168,8 +229,13 @@ the CLI's help layer, not the envelope.
|
|
|
168
229
|
- `eject` (alias `uninstall`) — remove managed files and local Zitadel state;
|
|
169
230
|
requires `--force` when non-interactive.
|
|
170
231
|
- `start` — start the managed local Zitadel server and persist runtime metadata
|
|
171
|
-
under `.zitadel/local/runtime.json`.
|
|
172
|
-
the
|
|
232
|
+
under `.zitadel/local/runtime.json`. The binary runtime defaults to SQLite
|
|
233
|
+
under `.zitadel/local/nextgen-data/`. Runtime metadata reports the published
|
|
234
|
+
server package version; the repository contributor wrapper reports the
|
|
235
|
+
`dev+<short-commit>` source build it launched. That label names the revision
|
|
236
|
+
the binary was built from, which after a Moon cache hit can be an earlier
|
|
237
|
+
commit whose server sources are byte-identical. Use `--runtime docker` or
|
|
238
|
+
`--image` for the Docker backend.
|
|
173
239
|
- `stop` — stop the managed runtime while preserving
|
|
174
240
|
`.zitadel/local/nextgen-data`. Use `stop --all` to sweep all discovered
|
|
175
241
|
host-wide CLI-managed local runtime processes, including healthy runtimes
|
|
@@ -263,9 +329,9 @@ validator (`E_VALIDATION` lists rule ids such as `no-script-tag` and
|
|
|
263
329
|
must be absolute `https://`. Keep exactly one descriptor in
|
|
264
330
|
`.zitadel/branding/` — extra `*.json` files there fail the scan.
|
|
265
331
|
Server-provisioned defaults remain a fallback for non-CLI project
|
|
266
|
-
creation, but CLI-created projects are authored from local files first. Flow create, read, list,
|
|
267
|
-
update are available, while the server enforces lifecycle rules
|
|
268
|
-
draft-only edits. Managed files carry a marker comment; `eject` removes only
|
|
332
|
+
creation, but CLI-created projects are authored from local files first. Flow create, read, list,
|
|
333
|
+
update, and delete are available, while the server enforces lifecycle rules
|
|
334
|
+
such as draft-only edits. Managed files carry a marker comment; `eject` removes only
|
|
269
335
|
files that still carry it, preserving anything the user replaced. For app-local
|
|
270
336
|
development, `--server local` resolves through `.zitadel/local/runtime.json` and
|
|
271
337
|
requires a healthy
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { E as ZitadelError } from "./oclif-
|
|
1
|
+
import { E as ZitadelError } from "./oclif-CanO3zdt.mjs";
|
|
2
2
|
import { isAbsolute, join, relative, resolve } from "node:path";
|
|
3
3
|
import { readFileSync } from "node:fs";
|
|
4
4
|
//#region src/lib/branding/index.ts
|
|
@@ -76,4 +76,4 @@ function toLocalBrandingBody(canonicalWire, localData) {
|
|
|
76
76
|
//#endregion
|
|
77
77
|
export { toLocalBrandingBody as a, toBrandingWireBody as i, readDescriptorTemplate as n, resolveTemplatePath as r, BRANDING_DIR as t };
|
|
78
78
|
|
|
79
|
-
//# sourceMappingURL=branding-
|
|
79
|
+
//# sourceMappingURL=branding-cygSBPkV.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"branding-
|
|
1
|
+
{"version":3,"file":"branding-cygSBPkV.mjs","names":[],"sources":["../src/lib/branding/index.ts"],"sourcesContent":["import { readFileSync } from \"node:fs\";\nimport { isAbsolute, join, relative, resolve } from \"node:path\";\n\nimport { ZitadelError } from \"../errors\";\n\n/**\n * Relative directory (from the project root) where local branding files live:\n * the `branding.json` descriptor plus the sibling `.liquid` template it\n * references. Owned here so commands, syncers, and tests share one source of\n * truth; only `*.json` files are sync-discovered, the template rides along\n * via `liquid_template_file`.\n */\nexport const BRANDING_DIR = \".zitadel/branding\";\n\ntype BrandingDescriptor = {\n liquid_template?: string;\n liquid_template_file?: string;\n [key: string]: unknown;\n};\n\n/**\n * Resolves a descriptor's `liquid_template_file` reference to an absolute\n * path. References are relative to the descriptor's directory (all\n * descriptors live flat in {@link BRANDING_DIR}) and must stay inside the\n * project — a reference escaping `cwd` is an error because apply would later\n * write server state back to that path.\n */\nexport function resolveTemplatePath(cwd: string, ref: string): string {\n const absolute = isAbsolute(ref) ? ref : resolve(join(cwd, BRANDING_DIR), ref);\n const rel = relative(cwd, absolute);\n if (rel.startsWith(\"..\") || isAbsolute(rel)) {\n throw new ZitadelError(\n \"E_VALIDATION\",\n `liquid_template_file ${JSON.stringify(ref)} points outside the project`,\n { hint: `Keep the template next to its descriptor in ${BRANDING_DIR}/.` },\n );\n }\n return absolute;\n}\n\n/**\n * Returns the template string a descriptor carries — the inline\n * `liquid_template`, or the content of `liquid_template_file`. Returns\n * undefined when the descriptor has neither (a legal descriptor that only\n * sets layout/asset URLs).\n */\nexport function readDescriptorTemplate(cwd: string, data: object): string | undefined {\n const descriptor = data as BrandingDescriptor;\n if (typeof descriptor.liquid_template === \"string\") {\n return descriptor.liquid_template;\n }\n if (typeof descriptor.liquid_template_file !== \"string\") {\n return undefined;\n }\n const path = resolveTemplatePath(cwd, descriptor.liquid_template_file);\n try {\n return readFileSync(path, \"utf8\");\n } catch (error) {\n throw new ZitadelError(\n \"E_VALIDATION\",\n `liquid_template_file ${JSON.stringify(descriptor.liquid_template_file)} cannot be read`,\n {\n hint: \"Create the template file or fix the reference; the `branding eject` command scaffolds a starting point.\",\n details: { cause: error instanceof Error ? error.message : String(error) },\n },\n );\n }\n}\n\n/**\n * Converts a local descriptor to the wire body of `POST /branding`: strips\n * the editor `$schema` affordance and replaces `liquid_template_file` with\n * the inlined template content. Non-throwing on a missing template file (the\n * field is simply left out) — `validate` reports that case with a hint\n * before any planning happens.\n */\nexport function toBrandingWireBody(cwd: string, data: object): object {\n const { $schema, liquid_template_file, ...rest } = data as BrandingDescriptor & {\n $schema?: string;\n };\n void $schema;\n const out: Record<string, unknown> = { ...rest };\n if (typeof liquid_template_file === \"string\" && out.liquid_template === undefined) {\n try {\n out.liquid_template = readFileSync(resolveTemplatePath(cwd, liquid_template_file), \"utf8\");\n } catch {\n // Reported by validate(); keep normalize/hashing total.\n }\n }\n return out;\n}\n\n/**\n * Converts the server's canonical wire body back to the local descriptor\n * form: when the local descriptor references a template file, the template\n * string moves back out of the JSON into that reference. The caller writes\n * the template content to the referenced file separately.\n */\nexport function toLocalBrandingBody(canonicalWire: object, localData: object): object {\n const local = localData as BrandingDescriptor;\n if (typeof local.liquid_template_file !== \"string\") {\n return canonicalWire;\n }\n const { liquid_template, ...rest } = canonicalWire as BrandingDescriptor;\n void liquid_template;\n return { ...rest, liquid_template_file: local.liquid_template_file };\n}\n"],"mappings":";;;;;;;;;;;AAYA,MAAa,eAAe;;;;;;;;AAe5B,SAAgB,oBAAoB,KAAa,KAAqB;CACpE,MAAM,WAAW,WAAW,IAAI,GAAG,MAAM,QAAQ,KAAK,KAAK,aAAa,EAAE,IAAI;CAC9E,MAAM,MAAM,SAAS,KAAK,SAAS;AACnC,KAAI,IAAI,WAAW,KAAK,IAAI,WAAW,IAAI,CACzC,OAAM,IAAI,aACR,gBACA,wBAAwB,KAAK,UAAU,IAAI,CAAC,8BAC5C,EAAE,MAAM,+CAA+C,aAAa,KAAK,CAC1E;AAEH,QAAO;;;;;;;;AAST,SAAgB,uBAAuB,KAAa,MAAkC;CACpF,MAAM,aAAa;AACnB,KAAI,OAAO,WAAW,oBAAoB,SACxC,QAAO,WAAW;AAEpB,KAAI,OAAO,WAAW,yBAAyB,SAC7C;CAEF,MAAM,OAAO,oBAAoB,KAAK,WAAW,qBAAqB;AACtE,KAAI;AACF,SAAO,aAAa,MAAM,OAAO;UAC1B,OAAO;AACd,QAAM,IAAI,aACR,gBACA,wBAAwB,KAAK,UAAU,WAAW,qBAAqB,CAAC,kBACxE;GACE,MAAM;GACN,SAAS,EAAE,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,EAAE;GAC3E,CACF;;;;;;;;;;AAWL,SAAgB,mBAAmB,KAAa,MAAsB;CACpE,MAAM,EAAE,SAAS,sBAAsB,GAAG,SAAS;CAInD,MAAM,MAA+B,EAAE,GAAG,MAAM;AAChD,KAAI,OAAO,yBAAyB,YAAY,IAAI,oBAAoB,KAAA,EACtE,KAAI;AACF,MAAI,kBAAkB,aAAa,oBAAoB,KAAK,qBAAqB,EAAE,OAAO;SACpF;AAIV,QAAO;;;;;;;;AAST,SAAgB,oBAAoB,eAAuB,WAA2B;CACpF,MAAM,QAAQ;AACd,KAAI,OAAO,MAAM,yBAAyB,SACxC,QAAO;CAET,MAAM,EAAE,iBAAiB,GAAG,SAAS;AAErC,QAAO;EAAE,GAAG;EAAM,sBAAsB,MAAM;EAAsB"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { M as serverKind, j as publicCliCommand } from "./oclif-CanO3zdt.mjs";
|
|
2
2
|
//#region src/lib/claim-state.ts
|
|
3
3
|
/**
|
|
4
4
|
* Whether the local record says a team owns this project.
|
|
@@ -63,4 +63,4 @@ function claimCommand(cliVersion) {
|
|
|
63
63
|
//#endregion
|
|
64
64
|
export { isAttached as i, claimCommand as n, claimState as r, claimAction as t };
|
|
65
65
|
|
|
66
|
-
//# sourceMappingURL=claim-state-
|
|
66
|
+
//# sourceMappingURL=claim-state-DlfD6Res.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claim-state-
|
|
1
|
+
{"version":3,"file":"claim-state-DlfD6Res.mjs","names":[],"sources":["../src/lib/claim-state.ts"],"sourcesContent":["import { serverKind } from \"./oclif/server-kind\";\nimport type { ZitadelSecret } from \"./project\";\nimport { publicCliCommand } from \"./public-cli\";\n\n/**\n * Whether this project is attached to a team, as the CLI can tell locally.\n *\n * `not-applicable` is its own variant rather than a boolean flag on the caller\n * because \"there is nothing to attach here\" and \"nothing is attached yet\" want\n * opposite output: the first prints nothing at all, the second nudges.\n */\nexport type ClaimState =\n | { kind: \"attached\"; team_id: string; claimed_at: string }\n | { kind: \"detached\" }\n | { kind: \"not-applicable\" };\n\n/**\n * Whether the local record says a team owns this project.\n *\n * Both fields or neither: a half-written record is not an attachment, and\n * treating it as one would hand callers a `team_id` with no idea when it\n * landed. Shared with `zitadel claim`, which asks the same question before it\n * decides to skip, so the two cannot drift as the record grows fields.\n *\n * Deliberately separate from {@link claimState}: the command must answer this\n * on any server, while the nudges only ask it on the cloud.\n */\nexport function isAttached(\n secret: Pick<ZitadelSecret, \"claimed_at\" | \"team_id\">,\n): secret is { claimed_at: string; team_id: string } {\n return Boolean(secret.claimed_at && secret.team_id);\n}\n\n/**\n * Decides the attachment state from local state alone.\n *\n * **Why no network call.** The contract exposes no ambient claim-state read:\n * `getClaimStatus` answers for one live challenge and rejects a secret that did\n * not mint it, and claim attributes were deliberately kept off\n * `GET /projects/{id}` because they belong to the grant, not the project. So\n * `.zitadel/secret` is the only source, which is also why `status` and `doctor`\n * stay fast and work offline. `zitadel claim` reaches the same conclusion the\n * same way before it decides to skip.\n *\n * **Why cloud only.** Claiming attaches a project to a team on the platform.\n * A local or self-hosted server has no such platform, and `--server local` is\n * the documented dev loop, so an ungated nudge would advertise an impossible\n * action for the entire life of a local project.\n *\n * The local record can be stale in one direction: a project claimed from\n * another machine, or a `.zitadel/secret` restored from a backup, reads as\n * `detached` here. That is tolerable because everything downstream is\n * advisory, and `zitadel claim` itself turns the resulting `409` into a clean\n * skip rather than an error.\n */\nexport function claimState(input: {\n secret: Pick<ZitadelSecret, \"claimed_at\" | \"team_id\">;\n server: string;\n}): ClaimState {\n if (serverKind.value(input.server) !== \"cloud\") {\n return { kind: \"not-applicable\" };\n }\n if (isAttached(input.secret)) {\n return {\n kind: \"attached\",\n team_id: input.secret.team_id,\n claimed_at: input.secret.claimed_at,\n };\n }\n return { kind: \"detached\" };\n}\n\n/**\n * The nudge for `next_actions`, quoting the command the way `journey-guidance`\n * does.\n *\n * Deliberately says nothing about deletion: unattached projects are framed as\n * temporary, but the epic's 14-day lifetime is not enforced anywhere yet, so\n * promising it would be a lie the product cannot keep.\n */\nexport function claimAction(cliVersion: string): string {\n return (\n \"This project is temporary until you attach it to a team: run \" +\n `${publicCliCommand(\"claim\", cliVersion)} to make it permanent. ` +\n \"Nothing about the project changes, so users, passkeys, and the issuer keep working.\"\n );\n}\n\n/** The command for `next_commands`. */\nexport function claimCommand(cliVersion: string): string {\n return publicCliCommand(\"claim\", cliVersion);\n}\n"],"mappings":";;;;;;;;;;;;;AA2BA,SAAgB,WACd,QACmD;AACnD,QAAO,QAAQ,OAAO,cAAc,OAAO,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;AAyBrD,SAAgB,WAAW,OAGZ;AACb,KAAI,WAAW,MAAM,MAAM,OAAO,KAAK,QACrC,QAAO,EAAE,MAAM,kBAAkB;AAEnC,KAAI,WAAW,MAAM,OAAO,CAC1B,QAAO;EACL,MAAM;EACN,SAAS,MAAM,OAAO;EACtB,YAAY,MAAM,OAAO;EAC1B;AAEH,QAAO,EAAE,MAAM,YAAY;;;;;;;;;;AAW7B,SAAgB,YAAY,YAA4B;AACtD,QACE,gEACG,iBAAiB,SAAS,WAAW,CAAC;;;AAM7C,SAAgB,aAAa,YAA4B;AACvD,QAAO,iBAAiB,SAAS,WAAW"}
|
package/dist/commands/apply.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { l as readZitadelSecret } from "../project-
|
|
3
|
-
import { a as buildSyncPlan, i as summarizePlan, l as makeSyncers, n as enumeratePlanResources, r as renderPlan, s as runSyncLoop, t as collectPlanWarnings } from "../sync-
|
|
4
|
-
import { t as environmentSchema } from "../environment-
|
|
1
|
+
import { j as publicCliCommand, t as BaseCommand } from "../oclif-CanO3zdt.mjs";
|
|
2
|
+
import { l as readZitadelSecret } from "../project-CHhot85s.mjs";
|
|
3
|
+
import { a as buildSyncPlan, i as summarizePlan, l as makeSyncers, n as enumeratePlanResources, r as renderPlan, s as runSyncLoop, t as collectPlanWarnings } from "../sync-Bd6vASgg.mjs";
|
|
4
|
+
import { t as environmentSchema } from "../environment-rjRVkJjW.mjs";
|
|
5
5
|
import { Flags } from "@oclif/core";
|
|
6
6
|
import { createZitadelClient } from "@zitadel/api/client";
|
|
7
7
|
import { consola as consola$1 } from "consola";
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as
|
|
3
|
-
import { t as
|
|
1
|
+
import { t as BRANDING_DESIGN_INFO } from "../../designs-Ckz18Dpo.mjs";
|
|
2
|
+
import { E as ZitadelError, O as normalizePublicCliJson, T as stableStringify, j as publicCliCommand, k as normalizePublicCliProse, t as BaseCommand } from "../../oclif-CanO3zdt.mjs";
|
|
3
|
+
import { t as hasZitadelConfig } from "../../project-CHhot85s.mjs";
|
|
4
|
+
import { t as BRANDING_DIR } from "../../branding-cygSBPkV.mjs";
|
|
4
5
|
import { mkdir, writeFile } from "node:fs/promises";
|
|
5
6
|
import { dirname, join } from "node:path";
|
|
6
7
|
import { cancel, isCancel, select } from "@clack/prompts";
|
|
@@ -57,9 +58,9 @@ var BrandingEject = class BrandingEject extends BaseCommand {
|
|
|
57
58
|
...branding
|
|
58
59
|
})}\n`, force);
|
|
59
60
|
await write(DEFAULT_BRANDING_TEMPLATE_PATH, template, force);
|
|
60
|
-
await write(join(BRANDING_DIR, "README.md"), brandingReadmeContent(), false).catch(swallowConflict);
|
|
61
|
+
await write(join(BRANDING_DIR, "README.md"), normalizePublicCliProse(brandingReadmeContent(), this.meta.cliVersion), false).catch(swallowConflict);
|
|
61
62
|
const brandingMeta = metaSchemaFiles().find((f) => f.name === "branding.json");
|
|
62
|
-
if (brandingMeta) await write(join(META_SCHEMA_DIR, brandingMeta.name), `${stableStringify(brandingMeta.body)}\n`, false).catch(swallowConflict);
|
|
63
|
+
if (brandingMeta) await write(join(META_SCHEMA_DIR, brandingMeta.name), `${stableStringify(normalizePublicCliJson(brandingMeta.body, this.meta.cliVersion))}\n`, false).catch(swallowConflict);
|
|
63
64
|
for (const file of filesWritten) consola$1.info(`Wrote ${file}`);
|
|
64
65
|
consola$1.success(`Ejected the ${design} design into ${BRANDING_DIR}/`);
|
|
65
66
|
return this.emit({
|
|
@@ -77,33 +78,11 @@ var BrandingEject = class BrandingEject extends BaseCommand {
|
|
|
77
78
|
const choice = await select({
|
|
78
79
|
message: "Which design do you want to start from?",
|
|
79
80
|
initialValue: DEFAULT_BRANDING_DESIGN,
|
|
80
|
-
options:
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
},
|
|
86
|
-
{
|
|
87
|
-
value: "split",
|
|
88
|
-
label: "Split",
|
|
89
|
-
hint: "brand panel left, form right"
|
|
90
|
-
},
|
|
91
|
-
{
|
|
92
|
-
value: "split-right",
|
|
93
|
-
label: "Split (reversed)",
|
|
94
|
-
hint: "form left, brand panel right"
|
|
95
|
-
},
|
|
96
|
-
{
|
|
97
|
-
value: "hero",
|
|
98
|
-
label: "Hero",
|
|
99
|
-
hint: "landing-style brand pane left, form right"
|
|
100
|
-
},
|
|
101
|
-
{
|
|
102
|
-
value: "minimal",
|
|
103
|
-
label: "Minimal",
|
|
104
|
-
hint: "no card chrome, fields straight on the page"
|
|
105
|
-
}
|
|
106
|
-
]
|
|
81
|
+
options: BRANDING_DESIGNS.map((design) => ({
|
|
82
|
+
value: design,
|
|
83
|
+
label: BRANDING_DESIGN_INFO[design].label,
|
|
84
|
+
hint: BRANDING_DESIGN_INFO[design].hint
|
|
85
|
+
}))
|
|
107
86
|
});
|
|
108
87
|
if (isCancel(choice)) {
|
|
109
88
|
cancel("Eject cancelled.");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"eject.mjs","names":[],"sources":["../../../src/commands/branding/eject.ts"],"sourcesContent":["import { mkdir, writeFile } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\n\nimport { cancel, isCancel, select } from \"@clack/prompts\";\nimport { Flags } from \"@oclif/core\";\nimport { consola } from \"consola\";\n\nimport {\n BRANDING_DESIGNS,\n DEFAULT_BRANDING_CONFIG_PATH,\n DEFAULT_BRANDING_DESIGN,\n DEFAULT_BRANDING_TEMPLATE_PATH,\n brandingReadmeContent,\n getDefaultBrandingConfig,\n} from \"@zitadel/config/defaults\";\nimport { BRANDING_FILE_SCHEMA_REF, META_SCHEMA_DIR, metaSchemaFiles } from \"@zitadel/config/meta-schemas\";\n\nimport { BRANDING_DIR } from \"../../lib/branding\";\nimport { ZitadelError } from \"../../lib/errors\";\nimport { stableStringify } from \"../../lib/json\";\nimport { BaseCommand, type JsonEnvelope } from \"../../lib/oclif\";\nimport { hasZitadelConfig } from \"../../lib/project\";\nimport {
|
|
1
|
+
{"version":3,"file":"eject.mjs","names":[],"sources":["../../../src/commands/branding/eject.ts"],"sourcesContent":["import { mkdir, writeFile } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\n\nimport { cancel, isCancel, select } from \"@clack/prompts\";\nimport { Flags } from \"@oclif/core\";\nimport { consola } from \"consola\";\n\nimport {\n BRANDING_DESIGNS,\n DEFAULT_BRANDING_CONFIG_PATH,\n DEFAULT_BRANDING_DESIGN,\n DEFAULT_BRANDING_TEMPLATE_PATH,\n brandingReadmeContent,\n getDefaultBrandingConfig,\n} from \"@zitadel/config/defaults\";\nimport { BRANDING_FILE_SCHEMA_REF, META_SCHEMA_DIR, metaSchemaFiles } from \"@zitadel/config/meta-schemas\";\n\nimport { BRANDING_DIR } from \"../../lib/branding\";\nimport { BRANDING_DESIGN_INFO } from \"../../lib/branding/designs\";\nimport { ZitadelError } from \"../../lib/errors\";\nimport { stableStringify } from \"../../lib/json\";\nimport { BaseCommand, type JsonEnvelope } from \"../../lib/oclif\";\nimport { hasZitadelConfig } from \"../../lib/project\";\nimport {\n normalizePublicCliJson,\n normalizePublicCliProse,\n publicCliCommand,\n} from \"../../lib/public-cli\";\n\n/**\n * The `branding eject` command — take ownership of the login template.\n *\n * Scaffolds `.zitadel/branding/` from a shipped design: the `branding.json`\n * descriptor, the `login.liquid` template it references, a README, and the\n * branding dialect meta-schema (for projects set up before it existed).\n * Purely local — nothing is uploaded; the first `zitadel apply` publishes\n * revision 1. Ejecting the template is the last rung of the branding\n * override ladder (docs/design/branding/override-ladder.md); unrelated to\n * `zitadel eject`, which removes the Zitadel integration.\n */\nexport default class BrandingEject extends BaseCommand {\n static override description =\n \"Take ownership of the login template: scaffold .zitadel/branding/ from a shipped design.\";\n static override flags = {\n design: Flags.string({\n description: `Design to start from (default: ${DEFAULT_BRANDING_DESIGN}).`,\n options: [...BRANDING_DESIGNS],\n }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { flags } = await this.parse(BrandingEject);\n await this.toMeta(flags);\n const { cwd, force, nonInteractive } = this.meta;\n\n if (!(await hasZitadelConfig(cwd))) {\n throw new ZitadelError(\"E_VALIDATION\", \"This directory is not a Zitadel project\", {\n hint: \"Run setup first; branding files live under .zitadel/.\",\n nextCommands: [publicCliCommand(\"setup\", this.meta.cliVersion)],\n });\n }\n\n const design = flags.design ?? (await this.promptDesign(nonInteractive));\n this.recordTelemetry({ design, force });\n const { branding, template } = getDefaultBrandingConfig(design);\n\n const filesWritten: string[] = [];\n const write = async (relPath: string, content: string, overwrite: boolean): Promise<void> => {\n const dest = join(cwd, relPath);\n await mkdir(dirname(dest), { recursive: true });\n try {\n await writeFile(dest, content, overwrite ? undefined : { flag: \"wx\" });\n filesWritten.push(relPath);\n } catch (error) {\n if (isErrno(error, \"EEXIST\")) {\n throw new ZitadelError(\"E_CONFLICT\", `${relPath} already exists`, {\n hint: \"Rerun with --force to replace it, or edit the existing file directly.\",\n });\n }\n throw error;\n }\n };\n\n await write(\n DEFAULT_BRANDING_CONFIG_PATH,\n `${stableStringify({ $schema: BRANDING_FILE_SCHEMA_REF, ...branding })}\\n`,\n force,\n );\n await write(DEFAULT_BRANDING_TEMPLATE_PATH, template, force);\n\n // Never overwrite a hand-edited README; setups from before the branding\n // dialect also miss the meta-schema, so materialize it when absent.\n await write(\n join(BRANDING_DIR, \"README.md\"),\n normalizePublicCliProse(brandingReadmeContent(), this.meta.cliVersion),\n false,\n ).catch(swallowConflict);\n const brandingMeta = metaSchemaFiles().find((f) => f.name === \"branding.json\");\n if (brandingMeta) {\n await write(\n join(META_SCHEMA_DIR, brandingMeta.name),\n `${stableStringify(normalizePublicCliJson(brandingMeta.body, this.meta.cliVersion))}\\n`,\n false,\n ).catch(swallowConflict);\n }\n\n for (const file of filesWritten) {\n consola.info(`Wrote ${file}`);\n }\n consola.success(`Ejected the ${design} design into ${BRANDING_DIR}/`);\n\n return this.emit({\n status: \"ok\",\n data: {\n design,\n files_written: filesWritten,\n next_actions: [\n `Edit ${DEFAULT_BRANDING_TEMPLATE_PATH} — the login UI is yours now.`,\n \"Plan validates the template and shows the pending revision; apply publishes it.\",\n ],\n next_commands: [\n publicCliCommand(\"plan\", this.meta.cliVersion),\n publicCliCommand(\"apply\", this.meta.cliVersion),\n ],\n },\n });\n }\n\n private async promptDesign(nonInteractive: boolean): Promise<string> {\n if (nonInteractive) {\n return DEFAULT_BRANDING_DESIGN;\n }\n const choice = await select({\n message: \"Which design do you want to start from?\",\n initialValue: DEFAULT_BRANDING_DESIGN as string,\n options: BRANDING_DESIGNS.map((design) => ({\n value: design as string,\n label: BRANDING_DESIGN_INFO[design].label,\n hint: BRANDING_DESIGN_INFO[design].hint,\n })),\n });\n if (isCancel(choice)) {\n cancel(\"Eject cancelled.\");\n throw new ZitadelError(\"E_VALIDATION\", \"Eject cancelled by user\");\n }\n return choice;\n }\n}\n\nfunction swallowConflict(error: unknown): void {\n if (error instanceof ZitadelError && error.code === \"E_CONFLICT\") {\n return;\n }\n throw error;\n}\n\nfunction isErrno(error: unknown, code: string): boolean {\n return (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n (error as NodeJS.ErrnoException).code === code\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAwCA,IAAqB,gBAArB,MAAqB,sBAAsB,YAAY;CACrD,OAAgB,cACd;CACF,OAAgB,QAAQ,EACtB,QAAQ,MAAM,OAAO;EACnB,aAAa,kCAAkC,wBAAwB;EACvE,SAAS,CAAC,GAAG,iBAAiB;EAC/B,CAAC,EACH;CAED,MAAM,MAA6B;EACjC,MAAM,EAAE,UAAU,MAAM,KAAK,MAAM,cAAc;AACjD,QAAM,KAAK,OAAO,MAAM;EACxB,MAAM,EAAE,KAAK,OAAO,mBAAmB,KAAK;AAE5C,MAAI,CAAE,MAAM,iBAAiB,IAAI,CAC/B,OAAM,IAAI,aAAa,gBAAgB,2CAA2C;GAChF,MAAM;GACN,cAAc,CAAC,iBAAiB,SAAS,KAAK,KAAK,WAAW,CAAC;GAChE,CAAC;EAGJ,MAAM,SAAS,MAAM,UAAW,MAAM,KAAK,aAAa,eAAe;AACvE,OAAK,gBAAgB;GAAE;GAAQ;GAAO,CAAC;EACvC,MAAM,EAAE,UAAU,aAAa,yBAAyB,OAAO;EAE/D,MAAM,eAAyB,EAAE;EACjC,MAAM,QAAQ,OAAO,SAAiB,SAAiB,cAAsC;GAC3F,MAAM,OAAO,KAAK,KAAK,QAAQ;AAC/B,SAAM,MAAM,QAAQ,KAAK,EAAE,EAAE,WAAW,MAAM,CAAC;AAC/C,OAAI;AACF,UAAM,UAAU,MAAM,SAAS,YAAY,KAAA,IAAY,EAAE,MAAM,MAAM,CAAC;AACtE,iBAAa,KAAK,QAAQ;YACnB,OAAO;AACd,QAAI,QAAQ,OAAO,SAAS,CAC1B,OAAM,IAAI,aAAa,cAAc,GAAG,QAAQ,kBAAkB,EAChE,MAAM,yEACP,CAAC;AAEJ,UAAM;;;AAIV,QAAM,MACJ,8BACA,GAAG,gBAAgB;GAAE,SAAS;GAA0B,GAAG;GAAU,CAAC,CAAC,KACvE,MACD;AACD,QAAM,MAAM,gCAAgC,UAAU,MAAM;AAI5D,QAAM,MACJ,KAAK,cAAc,YAAY,EAC/B,wBAAwB,uBAAuB,EAAE,KAAK,KAAK,WAAW,EACtE,MACD,CAAC,MAAM,gBAAgB;EACxB,MAAM,eAAe,iBAAiB,CAAC,MAAM,MAAM,EAAE,SAAS,gBAAgB;AAC9E,MAAI,aACF,OAAM,MACJ,KAAK,iBAAiB,aAAa,KAAK,EACxC,GAAG,gBAAgB,uBAAuB,aAAa,MAAM,KAAK,KAAK,WAAW,CAAC,CAAC,KACpF,MACD,CAAC,MAAM,gBAAgB;AAG1B,OAAK,MAAM,QAAQ,aACjB,WAAQ,KAAK,SAAS,OAAO;AAE/B,YAAQ,QAAQ,eAAe,OAAO,eAAe,aAAa,GAAG;AAErE,SAAO,KAAK,KAAK;GACf,QAAQ;GACR,MAAM;IACJ;IACA,eAAe;IACf,cAAc,CACZ,QAAQ,+BAA+B,gCACvC,kFACD;IACD,eAAe,CACb,iBAAiB,QAAQ,KAAK,KAAK,WAAW,EAC9C,iBAAiB,SAAS,KAAK,KAAK,WAAW,CAChD;IACF;GACF,CAAC;;CAGJ,MAAc,aAAa,gBAA0C;AACnE,MAAI,eACF,QAAO;EAET,MAAM,SAAS,MAAM,OAAO;GAC1B,SAAS;GACT,cAAc;GACd,SAAS,iBAAiB,KAAK,YAAY;IACzC,OAAO;IACP,OAAO,qBAAqB,QAAQ;IACpC,MAAM,qBAAqB,QAAQ;IACpC,EAAE;GACJ,CAAC;AACF,MAAI,SAAS,OAAO,EAAE;AACpB,UAAO,mBAAmB;AAC1B,SAAM,IAAI,aAAa,gBAAgB,0BAA0B;;AAEnE,SAAO;;;AAIX,SAAS,gBAAgB,OAAsB;AAC7C,KAAI,iBAAiB,gBAAgB,MAAM,SAAS,aAClD;AAEF,OAAM;;AAGR,SAAS,QAAQ,OAAgB,MAAuB;AACtD,QACE,OAAO,UAAU,YACjB,UAAU,QACV,UAAU,SACT,MAAgC,SAAS"}
|
package/dist/commands/claim.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { E as ZitadelError, S as isObject, t as BaseCommand } from "../oclif-
|
|
2
|
-
import { i as isAttached } from "../claim-state-
|
|
3
|
-
import { l as readZitadelSecret, u as writeZitadelSecret } from "../project-
|
|
1
|
+
import { E as ZitadelError, S as isObject, t as BaseCommand } from "../oclif-CanO3zdt.mjs";
|
|
2
|
+
import { i as isAttached } from "../claim-state-DlfD6Res.mjs";
|
|
3
|
+
import { l as readZitadelSecret, u as writeZitadelSecret } from "../project-CHhot85s.mjs";
|
|
4
4
|
import { access, readFile } from "node:fs/promises";
|
|
5
5
|
import { delimiter, join } from "node:path";
|
|
6
6
|
import { Flags } from "@oclif/core";
|
package/dist/commands/doctor.mjs
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { E as ZitadelError, S as isObject, a as DEFAULT_LOCAL_SERVER_PORT, c as checkLocalServerHealth, h as readRuntimeMetadata,
|
|
2
|
-
import { n as claimCommand, r as claimState, t as claimAction } from "../claim-state-
|
|
3
|
-
import { s as issuerFromPort, t as createOrca } from "../orca-
|
|
4
|
-
import { a as readProjectServer, c as readZitadelConfig, i as readPreset, l as readZitadelSecret, o as readRendererId, r as readDevelopmentIssuer, s as readUseCase, t as hasZitadelConfig } from "../project-
|
|
5
|
-
import { i as updateScaffold, t as SCHEMAS_DIR } from "../user-schema-
|
|
6
|
-
import { n as
|
|
7
|
-
import { d as assertServerPackageAvailable, o as imageAvailable, r as dockerAvailable } from "../docker-
|
|
8
|
-
import { n as dockerRuntimeGuidance, r as dockerUnavailableMessage, t as listenersForPort } from "../ports-
|
|
9
|
-
import { t as discoverManagedRuntimeProcesses } from "../processes-
|
|
1
|
+
import { E as ZitadelError, S as isObject, a as DEFAULT_LOCAL_SERVER_PORT, c as checkLocalServerHealth, h as readRuntimeMetadata, j as publicCliCommand, l as defaultLocalServerImageForCliVersion, m as localServerUrl, s as assertLocalStateWritable, t as BaseCommand } from "../oclif-CanO3zdt.mjs";
|
|
2
|
+
import { n as claimCommand, r as claimState, t as claimAction } from "../claim-state-DlfD6Res.mjs";
|
|
3
|
+
import { s as issuerFromPort, t as createOrca } from "../orca-Cu0iW1mv.mjs";
|
|
4
|
+
import { a as readProjectServer, c as readZitadelConfig, i as readPreset, l as readZitadelSecret, o as readRendererId, r as readDevelopmentIssuer, s as readUseCase, t as hasZitadelConfig } from "../project-CHhot85s.mjs";
|
|
5
|
+
import { i as updateScaffold, t as SCHEMAS_DIR } from "../user-schema-DTuOsdKE.mjs";
|
|
6
|
+
import { c as writeScaffoldManifest, n as detectPackageManager, o as hashScaffoldFile, s as readScaffoldManifest, t as addExactCommandFor } from "../package-manager-DFdLcDx1.mjs";
|
|
7
|
+
import { d as assertServerPackageAvailable, o as imageAvailable, r as dockerAvailable } from "../docker-DcRGTOJa.mjs";
|
|
8
|
+
import { n as dockerRuntimeGuidance, r as dockerUnavailableMessage, t as listenersForPort } from "../ports-BM20XIZb.mjs";
|
|
9
|
+
import { t as discoverManagedRuntimeProcesses } from "../processes-DKHPkU8O.mjs";
|
|
10
10
|
import { chmod, readFile, readdir, rm, stat, writeFile } from "node:fs/promises";
|
|
11
11
|
import { join } from "node:path";
|
|
12
12
|
import { Flags } from "@oclif/core";
|
|
@@ -280,16 +280,19 @@ var DependencyVersionCheck = class {
|
|
|
280
280
|
}).filter(([name]) => name.startsWith("@zitadel/")).filter(([, version]) => semver.valid(version.trim()) !== null);
|
|
281
281
|
const mismatched = exact.filter(([, version]) => !semver.eq(version.trim(), ctx.cliVersion));
|
|
282
282
|
if (mismatched.length > 0) {
|
|
283
|
-
const remedy = mismatched.map(([name]) => `${name}@${ctx.cliVersion}`).
|
|
283
|
+
const remedy = addExactCommandFor(await detectPackageManager(ctx.cwd), mismatched.map(([name]) => `${name}@${ctx.cliVersion}`)).display;
|
|
284
284
|
return {
|
|
285
285
|
...base,
|
|
286
286
|
status: "warn",
|
|
287
|
-
message: `${mismatched.map(([name, version]) => `${name}@${version}`).join(", ")} does not match this CLI's version (${ctx.cliVersion}); scaffolded files and guidance target the CLI's train — update with
|
|
288
|
-
details: {
|
|
289
|
-
name,
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
287
|
+
message: `${mismatched.map(([name, version]) => `${name}@${version}`).join(", ")} does not match this CLI's version (${ctx.cliVersion}); scaffolded files and guidance target the CLI's train — update with \`${remedy}\``,
|
|
288
|
+
details: {
|
|
289
|
+
mismatched: mismatched.map(([name, version]) => ({
|
|
290
|
+
name,
|
|
291
|
+
declared: version,
|
|
292
|
+
expected: ctx.cliVersion
|
|
293
|
+
})),
|
|
294
|
+
remedy_command: remedy
|
|
295
|
+
}
|
|
293
296
|
};
|
|
294
297
|
}
|
|
295
298
|
return {
|
|
@@ -300,8 +303,10 @@ var DependencyVersionCheck = class {
|
|
|
300
303
|
}
|
|
301
304
|
/**
|
|
302
305
|
* No auto-fix: repair's dependency op is deliberately additive-only (it
|
|
303
|
-
* never rewrites a version the user declared), so the
|
|
304
|
-
*
|
|
306
|
+
* never rewrites a version the user declared), so the repair ships as the
|
|
307
|
+
* package-manager-aware install command in `details.remedy_command` — the
|
|
308
|
+
* doctor command surfaces it in the envelope's `next_commands` — with the
|
|
309
|
+
* same command quoted in the warn message for human readers.
|
|
305
310
|
*/
|
|
306
311
|
async fix(_ctx) {}
|
|
307
312
|
};
|
|
@@ -935,6 +940,11 @@ function advisoryForWarnings(warnings, cliVersion) {
|
|
|
935
940
|
nextActions.push("Review other host-wide CLI-managed local Zitadel runtimes before starting a new one.");
|
|
936
941
|
nextCommands.push(publicCliCommand("stop --all", cliVersion));
|
|
937
942
|
}
|
|
943
|
+
const dependencyRemedy = remedyCommandOf(warnings.find((check) => check.name === "dependency-version"));
|
|
944
|
+
if (dependencyRemedy !== void 0) {
|
|
945
|
+
nextActions.push("Align the exactly-pinned @zitadel/* dependencies with the CLI version; scaffolded files and guidance target the CLI's train.");
|
|
946
|
+
nextCommands.push(dependencyRemedy);
|
|
947
|
+
}
|
|
938
948
|
if (nextActions.length === 0 && nextCommands.length === 0) return;
|
|
939
949
|
return {
|
|
940
950
|
nextActions: unique(nextActions),
|
|
@@ -1050,6 +1060,19 @@ async function checkRuntime(runtime, runtimeBackend) {
|
|
|
1050
1060
|
function formatListeners(listeners) {
|
|
1051
1061
|
return listeners.map((listener) => [listener.command ?? "unknown", listener.pid ? `pid ${String(listener.pid)}` : void 0].filter(Boolean).join(" ")).join(", ");
|
|
1052
1062
|
}
|
|
1063
|
+
/**
|
|
1064
|
+
* A warning may carry its own repair as `details.remedy_command` (today: the
|
|
1065
|
+
* dependency-version check's package-manager-aware exact-pin install).
|
|
1066
|
+
* Surfacing that string keeps the structured advisory identical to the
|
|
1067
|
+
* command quoted in the warning's prose.
|
|
1068
|
+
*/
|
|
1069
|
+
function remedyCommandOf(check) {
|
|
1070
|
+
if (check?.status !== "warn") return;
|
|
1071
|
+
const details = check.details;
|
|
1072
|
+
if (typeof details !== "object" || details === null) return;
|
|
1073
|
+
const remedy = details.remedy_command;
|
|
1074
|
+
return typeof remedy === "string" && remedy.length > 0 ? remedy : void 0;
|
|
1075
|
+
}
|
|
1053
1076
|
function hasManagedRuntimeProcesses(check) {
|
|
1054
1077
|
if (!check || check.status !== "warn") return false;
|
|
1055
1078
|
const details = check.details;
|