@zitadel/cli 0.1.0-alpha.15 → 0.1.0-alpha.16
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 +2 -2
- package/SKILLS.md +15 -6
- package/dist/commands/apply.mjs +8 -5
- package/dist/commands/apply.mjs.map +1 -1
- package/dist/commands/doctor.mjs +7 -7
- package/dist/commands/eject.mjs +17 -5
- package/dist/commands/eject.mjs.map +1 -1
- package/dist/commands/logs.mjs +2 -2
- package/dist/commands/plan.mjs +8 -5
- package/dist/commands/plan.mjs.map +1 -1
- package/dist/commands/reset.mjs +2 -2
- package/dist/commands/schemas/list.mjs +3 -3
- package/dist/commands/setup.mjs +128 -34
- package/dist/commands/setup.mjs.map +1 -1
- package/dist/commands/start.mjs +4 -4
- package/dist/commands/status.mjs +40 -9
- package/dist/commands/status.mjs.map +1 -1
- package/dist/commands/stop.mjs +3 -3
- package/dist/{docker-D7BSD5C9.mjs → docker-BbX0yOpg.mjs} +2 -2
- package/dist/{docker-D7BSD5C9.mjs.map → docker-BbX0yOpg.mjs.map} +1 -1
- package/dist/{docker-guidance-mcTT3_0E.mjs → docker-guidance-3UZESTfb.mjs} +2 -2
- package/dist/{docker-guidance-mcTT3_0E.mjs.map → docker-guidance-3UZESTfb.mjs.map} +1 -1
- package/dist/{environment-BQF7LeCz.mjs → environment-ABj1IWZt.mjs} +1 -1
- package/dist/{environment-BQF7LeCz.mjs.map → environment-ABj1IWZt.mjs.map} +1 -1
- package/dist/journey-guidance-E_3_UwGt.mjs +29 -0
- package/dist/journey-guidance-E_3_UwGt.mjs.map +1 -0
- package/dist/{oclif-Bm-FkF6z.mjs → oclif-SjHLB_XK.mjs} +17 -35
- package/dist/oclif-SjHLB_XK.mjs.map +1 -0
- package/dist/{orca-CpXj_XsA.mjs → orca-_TmrJQMw.mjs} +209 -163
- package/dist/orca-_TmrJQMw.mjs.map +1 -0
- package/dist/{ports-CxBKS1ga.mjs → ports-XujDtA47.mjs} +1 -1
- package/dist/{ports-CxBKS1ga.mjs.map → ports-XujDtA47.mjs.map} +1 -1
- package/dist/{processes-BVqYsxT8.mjs → processes-p2PPbKGG.mjs} +1 -1
- package/dist/{processes-BVqYsxT8.mjs.map → processes-p2PPbKGG.mjs.map} +1 -1
- package/dist/{project-Dk7V0xka.mjs → project-DXc7q4wN.mjs} +2 -2
- package/dist/{project-Dk7V0xka.mjs.map → project-DXc7q4wN.mjs.map} +1 -1
- package/dist/{sync-CYuHVQT5.mjs → sync-Bu_iLIbb.mjs} +148 -30
- package/dist/sync-Bu_iLIbb.mjs.map +1 -0
- package/oclif.manifest.json +12 -1
- package/package.json +5 -5
- package/dist/oclif-Bm-FkF6z.mjs.map +0 -1
- package/dist/orca-CpXj_XsA.mjs.map +0 -1
- package/dist/sync-CYuHVQT5.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -38,8 +38,8 @@ starting a local runtime. Use `--runtime docker`, `--image`, or
|
|
|
38
38
|
framework to scaffold when the directory is fresh, writes the Next.js app into
|
|
39
39
|
the current directory, scaffolds `app/login`, `app/register`, `app/profile`, and
|
|
40
40
|
`proxy.ts` for Next 16+ or `middleware.ts` for older Next versions. Fresh
|
|
41
|
-
scaffolds also replace the starter `app/page.tsx` with
|
|
42
|
-
|
|
41
|
+
scaffolds also replace the starter `app/page.tsx` with a redirect to `/login`.
|
|
42
|
+
Setup writes `.env.local` and `.zitadel/`, and installs
|
|
43
43
|
dependencies with the detected package manager. Pass `--skip-install` to install
|
|
44
44
|
them yourself. The project's default user schema and login flow are provisioned
|
|
45
45
|
from versioned local defaults; setup writes editable copies into
|
package/SKILLS.md
CHANGED
|
@@ -43,11 +43,16 @@ Each invocation prints one JSON object:
|
|
|
43
43
|
- `cli_version`, `command`, `source`: always present.
|
|
44
44
|
- On success: `data` with the command-specific payload.
|
|
45
45
|
- On a no-op: `reason` (e.g. `no-framework-detected`, `orphaned-config`).
|
|
46
|
-
- On failure: `code` (e.g. `E_VALIDATION`, `E_NETWORK`, `
|
|
47
|
-
`message`.
|
|
46
|
+
- On failure: `code` (e.g. `E_VALIDATION`, `E_NETWORK`, `E_NOT_FOUND`,
|
|
47
|
+
`E_CONFLICT`) and `message`.
|
|
48
48
|
- `next_commands`: the suggested follow-ups. Prefer these over free-text hints.
|
|
49
49
|
- `E_LOCAL_SERVER_NOT_RUNNING`: start the local runtime with
|
|
50
50
|
`npx @zitadel/cli@alpha start`, then retry with `--server local`.
|
|
51
|
+
- `E_NOT_FOUND`: an HTTP 404 from the target server. With the platform's
|
|
52
|
+
error envelope it names a missing resource (e.g. an unknown schema id);
|
|
53
|
+
without one the endpoint itself is missing — the `--server` value likely
|
|
54
|
+
points at something that is not a Zitadel platform API. Follow
|
|
55
|
+
`next_commands` (usually `start` + retry with `--server local`).
|
|
51
56
|
- `E_PORT_IN_USE`: the requested local runtime port already has a listener.
|
|
52
57
|
Stop that process, run `npx @zitadel/cli@alpha stop --all` for host-wide
|
|
53
58
|
CLI-managed local runtimes, or choose another `start --port`.
|
|
@@ -57,9 +62,9 @@ UIs display both streams together, but the machine contract is one parseable
|
|
|
57
62
|
JSON object on stdout; installer, audit, and package-manager progress belongs
|
|
58
63
|
on stderr.
|
|
59
64
|
|
|
60
|
-
Exit codes mirror the error class (3 = validation, 4 = network
|
|
61
|
-
1 = auth, 2 = not-implemented). An unknown command is handled by
|
|
62
|
-
layer, not the envelope.
|
|
65
|
+
Exit codes mirror the error class (3 = validation, 4 = network or not-found,
|
|
66
|
+
5 = conflict, 1 = auth, 2 = not-implemented). An unknown command is handled by
|
|
67
|
+
the CLI's help layer, not the envelope.
|
|
63
68
|
|
|
64
69
|
## Commands
|
|
65
70
|
|
|
@@ -76,7 +81,11 @@ layer, not the envelope.
|
|
|
76
81
|
framework and recorded in `zitadel.json` branding, but only Next varies its
|
|
77
82
|
generated templates by it), `--dev-port` (dev-server port, also the issuer
|
|
78
83
|
origin registered with Zitadel — use distinct ports to run several scaffolded
|
|
79
|
-
apps side by side), `--
|
|
84
|
+
apps side by side), `--preset password-first|passkey-first` (the sign-in
|
|
85
|
+
experience the scaffold starts from: `password-first` is the default —
|
|
86
|
+
email + password with passkey optional during registration; `passkey-first`
|
|
87
|
+
enters login on a one-tap passkey step with an email + password fallback;
|
|
88
|
+
recorded in `zitadel.json`), `--skip-install`.
|
|
80
89
|
- `plan` — validate config and preview the sync diff without mutating anything.
|
|
81
90
|
- `apply` — validate and upload repo config to the platform.
|
|
82
91
|
- `schemas list` — inspect the revision history of a user-schema, filtered by
|
package/dist/commands/apply.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { t as BaseCommand } from "../oclif-
|
|
2
|
-
import { o as readZitadelSecret } from "../project-
|
|
3
|
-
import {
|
|
4
|
-
import { t as environmentSchema } from "../environment-
|
|
1
|
+
import { t as BaseCommand } from "../oclif-SjHLB_XK.mjs";
|
|
2
|
+
import { o as readZitadelSecret } from "../project-DXc7q4wN.mjs";
|
|
3
|
+
import { i as buildSyncPlan, l as makeSyncers, n as renderPlan, o as runSyncLoop, r as summarizePlan, t as collectPlanWarnings } from "../sync-Bu_iLIbb.mjs";
|
|
4
|
+
import { t as environmentSchema } from "../environment-ABj1IWZt.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";
|
|
@@ -62,7 +62,10 @@ var Apply = class Apply extends BaseCommand {
|
|
|
62
62
|
consola$1.success(`Plan: ${summary.creates} create${summary.creates === 1 ? "" : "s"}, ${summary.updates} update${summary.updates === 1 ? "" : "s"}, ${summary.revisions} new revision${summary.revisions === 1 ? "" : "s"}, ${summary.deletes} delete${summary.deletes === 1 ? "" : "s"}`);
|
|
63
63
|
return this.emit({
|
|
64
64
|
status: "ok",
|
|
65
|
-
data:
|
|
65
|
+
data: {
|
|
66
|
+
...summary,
|
|
67
|
+
warnings: collectPlanWarnings(plan)
|
|
68
|
+
},
|
|
66
69
|
pretty: renderPlan(plan, isTTY)
|
|
67
70
|
});
|
|
68
71
|
}
|
|
@@ -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 {
|
|
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 {\n buildSyncPlan,\n collectPlanWarnings,\n makeSyncers,\n renderPlan,\n runSyncLoop,\n summarizePlan,\n} 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 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({\n client,\n projectId: secret.project_id,\n env,\n });\n\n if (!dryRun) {\n consola.start(\"Syncing schemas and flows to Zitadel\");\n const { filesUpdated } = await runSyncLoop(cwd, syncers);\n consola.success(\"Sync complete\");\n return this.emit({ status: \"ok\", data: { synced: true, files_updated: filesUpdated } });\n }\n\n consola.start(\"Building plan (dry run)\");\n const plan = await buildSyncPlan(cwd, syncers, true);\n const summary = summarizePlan(plan);\n this.recordTelemetry({\n creates: summary.creates,\n updates: summary.updates,\n revisions: summary.revisions,\n deletes: summary.deletes,\n total: summary.total,\n });\n consola.success(\n `Plan: ${summary.creates} create${summary.creates === 1 ? \"\" : \"s\"}, ` +\n `${summary.updates} update${summary.updates === 1 ? \"\" : \"s\"}, ` +\n `${summary.revisions} new revision${summary.revisions === 1 ? \"\" : \"s\"}, ` +\n `${summary.deletes} delete${summary.deletes === 1 ? \"\" : \"s\"}`,\n );\n return this.emit({\n status: \"ok\",\n data: { ...summary, warnings: collectPlanWarnings(plan) },\n pretty: renderPlan(plan, isTTY),\n });\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AA0BA,IAAqB,QAArB,MAAqB,cAAc,YAAY;CAC7C,OAAgB,cAAc;CAC9B,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;GAC1B,QALa,oBAAoB;IACjC,SAAS;IACT,OAAO,OAAO;IACf,CAEO;GACN,WAAW,OAAO;GAClB;GACD,CAAC;AAEF,MAAI,CAAC,QAAQ;AACX,aAAQ,MAAM,uCAAuC;GACrD,MAAM,EAAE,iBAAiB,MAAM,YAAY,KAAK,QAAQ;AACxD,aAAQ,QAAQ,gBAAgB;AAChC,UAAO,KAAK,KAAK;IAAE,QAAQ;IAAM,MAAM;KAAE,QAAQ;KAAM,eAAe;KAAc;IAAE,CAAC;;AAGzF,YAAQ,MAAM,0BAA0B;EACxC,MAAM,OAAO,MAAM,cAAc,KAAK,SAAS,KAAK;EACpD,MAAM,UAAU,cAAc,KAAK;AACnC,OAAK,gBAAgB;GACnB,SAAS,QAAQ;GACjB,SAAS,QAAQ;GACjB,WAAW,QAAQ;GACnB,SAAS,QAAQ;GACjB,OAAO,QAAQ;GAChB,CAAC;AACF,YAAQ,QACN,SAAS,QAAQ,QAAQ,SAAS,QAAQ,YAAY,IAAI,KAAK,IAAI,IAC9D,QAAQ,QAAQ,SAAS,QAAQ,YAAY,IAAI,KAAK,IAAI,IAC1D,QAAQ,UAAU,eAAe,QAAQ,cAAc,IAAI,KAAK,IAAI,IACpE,QAAQ,QAAQ,SAAS,QAAQ,YAAY,IAAI,KAAK,MAC5D;AACD,SAAO,KAAK,KAAK;GACf,QAAQ;GACR,MAAM;IAAE,GAAG;IAAS,UAAU,oBAAoB,KAAK;IAAE;GACzD,QAAQ,WAAW,MAAM,MAAM;GAChC,CAAC"}
|
package/dist/commands/doctor.mjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { C as isObject, E as ZitadelError, a as DEFAULT_LOCAL_SERVER_PORT, b as publicCliCommand, c as checkLocalServerHealth, l as defaultLocalServerImageForCliVersion, m as readRuntimeMetadata, p as localServerUrl, s as assertLocalStateWritable, t as BaseCommand } from "../oclif-
|
|
2
|
-
import {
|
|
3
|
-
import { a as readZitadelConfig, i as readRendererId, o as readZitadelSecret, r as readDevelopmentIssuer, t as hasZitadelConfig } from "../project-
|
|
1
|
+
import { C as isObject, E as ZitadelError, a as DEFAULT_LOCAL_SERVER_PORT, b as publicCliCommand, c as checkLocalServerHealth, l as defaultLocalServerImageForCliVersion, m as readRuntimeMetadata, p as localServerUrl, s as assertLocalStateWritable, t as BaseCommand } from "../oclif-SjHLB_XK.mjs";
|
|
2
|
+
import { o as issuerFromPort, t as createOrca } from "../orca-_TmrJQMw.mjs";
|
|
3
|
+
import { a as readZitadelConfig, i as readRendererId, o as readZitadelSecret, r as readDevelopmentIssuer, t as hasZitadelConfig } from "../project-DXc7q4wN.mjs";
|
|
4
4
|
import { t as SCHEMAS_DIR } from "../user-schema-DDz5-lX5.mjs";
|
|
5
|
-
import { n as listenersForPort } from "../ports-
|
|
6
|
-
import { d as assertServerPackageAvailable, o as imageAvailable, r as dockerAvailable } from "../docker-
|
|
7
|
-
import { n as dockerUnavailableMessage, t as dockerRuntimeGuidance } from "../docker-guidance-
|
|
8
|
-
import { t as discoverManagedRuntimeProcesses } from "../processes-
|
|
5
|
+
import { n as listenersForPort } from "../ports-XujDtA47.mjs";
|
|
6
|
+
import { d as assertServerPackageAvailable, o as imageAvailable, r as dockerAvailable } from "../docker-BbX0yOpg.mjs";
|
|
7
|
+
import { n as dockerUnavailableMessage, t as dockerRuntimeGuidance } from "../docker-guidance-3UZESTfb.mjs";
|
|
8
|
+
import { t as discoverManagedRuntimeProcesses } from "../processes-p2PPbKGG.mjs";
|
|
9
9
|
import { chmod, readFile, readdir, stat, writeFile } from "node:fs/promises";
|
|
10
10
|
import { join } from "node:path";
|
|
11
11
|
import { Flags } from "@oclif/core";
|
package/dist/commands/eject.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { E as ZitadelError, t as BaseCommand } from "../oclif-
|
|
2
|
-
import { t as createOrca } from "../orca-
|
|
3
|
-
import { a as readZitadelConfig, i as readRendererId } from "../project-
|
|
4
|
-
import { readFile, rename, rm, stat } from "node:fs/promises";
|
|
1
|
+
import { E as ZitadelError, t as BaseCommand } from "../oclif-SjHLB_XK.mjs";
|
|
2
|
+
import { a as removeGuidanceSection, i as AGENTS_HEADER, t as createOrca } from "../orca-_TmrJQMw.mjs";
|
|
3
|
+
import { a as readZitadelConfig, i as readRendererId } from "../project-DXc7q4wN.mjs";
|
|
4
|
+
import { readFile, rename, rm, stat, writeFile } from "node:fs/promises";
|
|
5
5
|
import { join } from "node:path";
|
|
6
6
|
//#region src/commands/eject.ts
|
|
7
7
|
/**
|
|
@@ -17,7 +17,8 @@ async function resolveEjectActions(cwd) {
|
|
|
17
17
|
directories: [".zitadel"],
|
|
18
18
|
envBackups: [".env.local"],
|
|
19
19
|
dependencies: [],
|
|
20
|
-
configEdits: []
|
|
20
|
+
configEdits: [],
|
|
21
|
+
guidanceFiles: ["AGENTS.md", "README.md"]
|
|
21
22
|
};
|
|
22
23
|
const orca = createOrca();
|
|
23
24
|
const framework = await orca.tryDetect(cwd);
|
|
@@ -115,6 +116,17 @@ var Eject = class Eject extends BaseCommand {
|
|
|
115
116
|
});
|
|
116
117
|
removed.push(rel);
|
|
117
118
|
}
|
|
119
|
+
for (const rel of actions.guidanceFiles) {
|
|
120
|
+
const abs = join(cwd, rel);
|
|
121
|
+
if (!await pathExists(abs)) continue;
|
|
122
|
+
const contents = await readFile(abs, "utf8").catch(() => "");
|
|
123
|
+
const stripped = removeGuidanceSection(contents);
|
|
124
|
+
if (stripped === contents) continue;
|
|
125
|
+
const husk = stripped.trim() === "" || stripped.trim() === AGENTS_HEADER.trim();
|
|
126
|
+
if (!dryRun) if (husk) await rm(abs, { force: true });
|
|
127
|
+
else await writeFile(abs, stripped);
|
|
128
|
+
removed.push(husk ? rel : `${rel} (managed section)`);
|
|
129
|
+
}
|
|
118
130
|
const manualSteps = actions.configEdits.map((rel) => {
|
|
119
131
|
if (rel === "package.json" || rel.endsWith("/package.json")) return `Remove the "dev" script setup added to ${rel}`;
|
|
120
132
|
if (rel === "angular.json" || rel.endsWith("/angular.json")) return `Remove the Zitadel proxyConfig (and dev-server port) from the serve target in ${rel}`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"eject.mjs","names":[],"sources":["../../src/commands/eject.ts"],"sourcesContent":["import { readFile, rename, rm, stat } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { BaseCommand, type JsonEnvelope } from \"../lib/oclif\";\nimport { ZitadelError } from \"../lib/errors\";\nimport { createOrca } from \"../lib/orca\";\nimport type { EjectActions } from \"../lib/orca/patchers/types\";\nimport { MANAGED_MARKER } from \"../lib/paths\";\nimport { readRendererId, readZitadelConfig } from \"../lib/project\";\n\n/**\n * Asks the framework patcher which artifacts it owns. Falls back to the\n * framework-agnostic set (`zitadel.json`, `.zitadel/`, `.env.local`) when the\n * framework or its patcher cannot be resolved, so an orphaned/partial project\n * can still be cleaned up.\n */\nasync function resolveEjectActions(cwd: string): Promise<EjectActions> {\n const fallback: EjectActions = {\n markedFiles: [],\n rootConfigFiles: [\"zitadel.json\"],\n directories: [\".zitadel\"],\n envBackups: [\".env.local\"],\n dependencies: [],\n configEdits: [],\n };\n const orca = createOrca();\n const framework = await orca.tryDetect(cwd);\n if (!framework) {\n return fallback;\n }\n try {\n const config = await readZitadelConfig(cwd).catch(() => ({}) as Record<string, unknown>);\n return orca.patcherFor(framework.id).artifacts({\n framework,\n rendererId: readRendererId(config),\n });\n } catch {\n return fallback;\n }\n}\n\n/**\n * Builds the `next_commands` envelope field — manual follow-ups `eject` can't\n * safely run itself: deleting the `.env.local.ejected-*` backups it created\n * (only when some were made), and uninstalling the SDK packages the patcher\n * added (the CLI never modifies the user's `package.json` + lockfile +\n * `node_modules` directly; it just suggests the command).\n */\nfunction assembleNextCommands(\n backedUp: ReadonlyArray<unknown>,\n dependencies: ReadonlyArray<string>,\n): ReadonlyArray<string> {\n const commands: string[] = [];\n if (backedUp.length > 0) {\n commands.push(\"rm -f .env.local.ejected-*\");\n }\n for (const dep of dependencies) {\n commands.push(`npm uninstall ${dep}`);\n }\n return commands;\n}\n\nasync function pathExists(path: string): Promise<boolean> {\n try {\n await stat(path);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * `zitadel eject` — remove managed files and local Zitadel state.\n *\n * Removes Zitadel-managed files from the project, leaving the remote project\n * untouched. The set of files comes from the framework patcher's\n * {@link import(\"../lib/orca/patchers/types\").Patcher.artifacts}, so the patcher\n * is the single source of truth for what its integration owns.\n *\n * Marked code files are removed only when they still carry the managed marker\n * (user-replaced files are preserved); `zitadel.json` is removed; `.env.local`\n * is renamed to a timestamped backup; and `.zitadel/` is removed wholesale.\n * `--dry-run` reports without touching the filesystem; non-interactive runs\n * require `--force`.\n */\nexport default class Eject extends BaseCommand {\n static override description = \"Remove managed files and local Zitadel state.\";\n static override aliases = [\"uninstall\"];\n\n async run(): Promise<JsonEnvelope> {\n const { flags } = await this.parse(Eject);\n await this.toMeta(flags);\n const { cwd, force, nonInteractive, dryRun } = this.meta;\n\n if (!force && nonInteractive) {\n throw new ZitadelError(\"E_VALIDATION\", \"Eject requires --force in non-interactive mode\", {\n hint: \"Re-run with --force to confirm deletion of managed files.\",\n });\n }\n\n const actions = await resolveEjectActions(cwd);\n const removed: string[] = [];\n const preserved: string[] = [];\n const backedUp: string[] = [];\n\n for (const rel of actions.markedFiles) {\n const abs = join(cwd, rel);\n if (!(await pathExists(abs))) {\n continue;\n }\n const contents = await readFile(abs, \"utf8\").catch(() => \"\");\n if (!contents.includes(MANAGED_MARKER)) {\n preserved.push(rel);\n continue;\n }\n if (!dryRun) {\n await rm(abs, { force: true });\n }\n removed.push(rel);\n }\n\n for (const rel of actions.rootConfigFiles) {\n const abs = join(cwd, rel);\n if (!(await pathExists(abs))) {\n continue;\n }\n if (!dryRun) {\n await rm(abs, { force: true });\n }\n removed.push(rel);\n }\n\n for (const rel of actions.envBackups) {\n const abs = join(cwd, rel);\n if (!(await pathExists(abs))) {\n continue;\n }\n if (dryRun) {\n backedUp.push(`${rel} -> ${rel}.ejected-<timestamp>`);\n continue;\n }\n const stamp = new Date().toISOString().replace(/[:.]/g, \"-\");\n const backup = `${abs}.ejected-${stamp}`;\n await rename(abs, backup);\n backedUp.push(`${rel} -> ${backup.slice(cwd.length + 1)}`);\n }\n\n for (const rel of actions.directories) {\n const abs = join(cwd, rel);\n if (!(await pathExists(abs))) {\n continue;\n }\n if (!dryRun) {\n await rm(abs, { recursive: true, force: true });\n }\n removed.push(rel);\n }\n\n // In-place config merges (vite.config.ts / angular.json / nuxt.config.ts)\n // can't be auto-reverted, so surface them as manual cleanup steps. The\n // Angular patcher also edits package.json (a `dev` script, not a config\n // block), so word that one accurately.\n const manualSteps = actions.configEdits.map((rel) => {\n if (rel === \"package.json\" || rel.endsWith(\"/package.json\")) {\n return `Remove the \"dev\" script setup added to ${rel}`;\n }\n if (rel === \"angular.json\" || rel.endsWith(\"/angular.json\")) {\n return `Remove the Zitadel proxyConfig (and dev-server port) from the serve target in ${rel}`;\n }\n return `Remove the Zitadel configuration block from ${rel}`;\n });\n\n if (removed.length === 0 && backedUp.length === 0 && manualSteps.length === 0) {\n return this.emit({ status: \"skipped\", reason: \"nothing-to-eject\", data: { cwd } });\n }\n\n const nextCommands = assembleNextCommands(backedUp, actions.dependencies);\n\n return this.emit({\n status: \"ok\",\n data: {\n title: \"Zitadel ejected. Remote project is untouched.\",\n files_removed: removed,\n files_preserved: preserved,\n backed_up: backedUp,\n next_commands: nextCommands,\n manual_steps: manualSteps,\n },\n });\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"eject.mjs","names":[],"sources":["../../src/commands/eject.ts"],"sourcesContent":["import { readFile, rename, rm, stat, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { BaseCommand, type JsonEnvelope } from \"../lib/oclif\";\nimport { ZitadelError } from \"../lib/errors\";\nimport { createOrca } from \"../lib/orca\";\nimport { AGENTS_HEADER, removeGuidanceSection } from \"../lib/orca/patchers/rule/guidance\";\nimport type { EjectActions } from \"../lib/orca/patchers/types\";\nimport { MANAGED_MARKER } from \"../lib/paths\";\nimport { readRendererId, readZitadelConfig } from \"../lib/project\";\n\n/**\n * Asks the framework patcher which artifacts it owns. Falls back to the\n * framework-agnostic set (`zitadel.json`, `.zitadel/`, `.env.local`) when the\n * framework or its patcher cannot be resolved, so an orphaned/partial project\n * can still be cleaned up.\n */\nasync function resolveEjectActions(cwd: string): Promise<EjectActions> {\n const fallback: EjectActions = {\n markedFiles: [],\n rootConfigFiles: [\"zitadel.json\"],\n directories: [\".zitadel\"],\n envBackups: [\".env.local\"],\n dependencies: [],\n configEdits: [],\n guidanceFiles: [\"AGENTS.md\", \"README.md\"],\n };\n const orca = createOrca();\n const framework = await orca.tryDetect(cwd);\n if (!framework) {\n return fallback;\n }\n try {\n const config = await readZitadelConfig(cwd).catch(() => ({}) as Record<string, unknown>);\n return orca.patcherFor(framework.id).artifacts({\n framework,\n rendererId: readRendererId(config),\n });\n } catch {\n return fallback;\n }\n}\n\n/**\n * Builds the `next_commands` envelope field — manual follow-ups `eject` can't\n * safely run itself: deleting the `.env.local.ejected-*` backups it created\n * (only when some were made), and uninstalling the SDK packages the patcher\n * added (the CLI never modifies the user's `package.json` + lockfile +\n * `node_modules` directly; it just suggests the command).\n */\nfunction assembleNextCommands(\n backedUp: ReadonlyArray<unknown>,\n dependencies: ReadonlyArray<string>,\n): ReadonlyArray<string> {\n const commands: string[] = [];\n if (backedUp.length > 0) {\n commands.push(\"rm -f .env.local.ejected-*\");\n }\n for (const dep of dependencies) {\n commands.push(`npm uninstall ${dep}`);\n }\n return commands;\n}\n\nasync function pathExists(path: string): Promise<boolean> {\n try {\n await stat(path);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * `zitadel eject` — remove managed files and local Zitadel state.\n *\n * Removes Zitadel-managed files from the project, leaving the remote project\n * untouched. The set of files comes from the framework patcher's\n * {@link import(\"../lib/orca/patchers/types\").Patcher.artifacts}, so the patcher\n * is the single source of truth for what its integration owns.\n *\n * Marked code files are removed only when they still carry the managed marker\n * (user-replaced files are preserved); `zitadel.json` is removed; `.env.local`\n * is renamed to a timestamped backup; and `.zitadel/` is removed wholesale.\n * `--dry-run` reports without touching the filesystem; non-interactive runs\n * require `--force`.\n */\nexport default class Eject extends BaseCommand {\n static override description = \"Remove managed files and local Zitadel state.\";\n static override aliases = [\"uninstall\"];\n\n async run(): Promise<JsonEnvelope> {\n const { flags } = await this.parse(Eject);\n await this.toMeta(flags);\n const { cwd, force, nonInteractive, dryRun } = this.meta;\n\n if (!force && nonInteractive) {\n throw new ZitadelError(\"E_VALIDATION\", \"Eject requires --force in non-interactive mode\", {\n hint: \"Re-run with --force to confirm deletion of managed files.\",\n });\n }\n\n const actions = await resolveEjectActions(cwd);\n const removed: string[] = [];\n const preserved: string[] = [];\n const backedUp: string[] = [];\n\n for (const rel of actions.markedFiles) {\n const abs = join(cwd, rel);\n if (!(await pathExists(abs))) {\n continue;\n }\n const contents = await readFile(abs, \"utf8\").catch(() => \"\");\n if (!contents.includes(MANAGED_MARKER)) {\n preserved.push(rel);\n continue;\n }\n if (!dryRun) {\n await rm(abs, { force: true });\n }\n removed.push(rel);\n }\n\n for (const rel of actions.rootConfigFiles) {\n const abs = join(cwd, rel);\n if (!(await pathExists(abs))) {\n continue;\n }\n if (!dryRun) {\n await rm(abs, { force: true });\n }\n removed.push(rel);\n }\n\n for (const rel of actions.envBackups) {\n const abs = join(cwd, rel);\n if (!(await pathExists(abs))) {\n continue;\n }\n if (dryRun) {\n backedUp.push(`${rel} -> ${rel}.ejected-<timestamp>`);\n continue;\n }\n const stamp = new Date().toISOString().replace(/[:.]/g, \"-\");\n const backup = `${abs}.ejected-${stamp}`;\n await rename(abs, backup);\n backedUp.push(`${rel} -> ${backup.slice(cwd.length + 1)}`);\n }\n\n for (const rel of actions.directories) {\n const abs = join(cwd, rel);\n if (!(await pathExists(abs))) {\n continue;\n }\n if (!dryRun) {\n await rm(abs, { recursive: true, force: true });\n }\n removed.push(rel);\n }\n\n // Guidance sections live inside user-owned docs (README.md / AGENTS.md):\n // strip only the marker-fenced section so the stale golden path doesn't\n // outlive the files it points at. The whole file goes only when nothing\n // but the scaffold-created header (or whitespace) would remain — i.e. we\n // created it and nobody added anything since.\n for (const rel of actions.guidanceFiles) {\n const abs = join(cwd, rel);\n if (!(await pathExists(abs))) {\n continue;\n }\n const contents = await readFile(abs, \"utf8\").catch(() => \"\");\n const stripped = removeGuidanceSection(contents);\n if (stripped === contents) {\n continue;\n }\n const husk = stripped.trim() === \"\" || stripped.trim() === AGENTS_HEADER.trim();\n if (!dryRun) {\n if (husk) {\n await rm(abs, { force: true });\n } else {\n await writeFile(abs, stripped);\n }\n }\n removed.push(husk ? rel : `${rel} (managed section)`);\n }\n\n // In-place config merges (vite.config.ts / angular.json / nuxt.config.ts)\n // can't be auto-reverted, so surface them as manual cleanup steps. The\n // Angular patcher also edits package.json (a `dev` script, not a config\n // block), so word that one accurately.\n const manualSteps = actions.configEdits.map((rel) => {\n if (rel === \"package.json\" || rel.endsWith(\"/package.json\")) {\n return `Remove the \"dev\" script setup added to ${rel}`;\n }\n if (rel === \"angular.json\" || rel.endsWith(\"/angular.json\")) {\n return `Remove the Zitadel proxyConfig (and dev-server port) from the serve target in ${rel}`;\n }\n return `Remove the Zitadel configuration block from ${rel}`;\n });\n\n if (removed.length === 0 && backedUp.length === 0 && manualSteps.length === 0) {\n return this.emit({ status: \"skipped\", reason: \"nothing-to-eject\", data: { cwd } });\n }\n\n const nextCommands = assembleNextCommands(backedUp, actions.dependencies);\n\n return this.emit({\n status: \"ok\",\n data: {\n title: \"Zitadel ejected. Remote project is untouched.\",\n files_removed: removed,\n files_preserved: preserved,\n backed_up: backedUp,\n next_commands: nextCommands,\n manual_steps: manualSteps,\n },\n });\n }\n}\n"],"mappings":";;;;;;;;;;;;AAiBA,eAAe,oBAAoB,KAAoC;CACrE,MAAM,WAAyB;EAC7B,aAAa,EAAE;EACf,iBAAiB,CAAC,eAAe;EACjC,aAAa,CAAC,WAAW;EACzB,YAAY,CAAC,aAAa;EAC1B,cAAc,EAAE;EAChB,aAAa,EAAE;EACf,eAAe,CAAC,aAAa,YAAY;EAC1C;CACD,MAAM,OAAO,YAAY;CACzB,MAAM,YAAY,MAAM,KAAK,UAAU,IAAI;AAC3C,KAAI,CAAC,UACH,QAAO;AAET,KAAI;EACF,MAAM,SAAS,MAAM,kBAAkB,IAAI,CAAC,aAAa,EAAE,EAA6B;AACxF,SAAO,KAAK,WAAW,UAAU,GAAG,CAAC,UAAU;GAC7C;GACA,YAAY,eAAe,OAAO;GACnC,CAAC;SACI;AACN,SAAO;;;;;;;;;;AAWX,SAAS,qBACP,UACA,cACuB;CACvB,MAAM,WAAqB,EAAE;AAC7B,KAAI,SAAS,SAAS,EACpB,UAAS,KAAK,6BAA6B;AAE7C,MAAK,MAAM,OAAO,aAChB,UAAS,KAAK,iBAAiB,MAAM;AAEvC,QAAO;;AAGT,eAAe,WAAW,MAAgC;AACxD,KAAI;AACF,QAAM,KAAK,KAAK;AAChB,SAAO;SACD;AACN,SAAO;;;;;;;;;;;;;;;;;AAkBX,IAAqB,QAArB,MAAqB,cAAc,YAAY;CAC7C,OAAgB,cAAc;CAC9B,OAAgB,UAAU,CAAC,YAAY;CAEvC,MAAM,MAA6B;EACjC,MAAM,EAAE,UAAU,MAAM,KAAK,MAAM,MAAM;AACzC,QAAM,KAAK,OAAO,MAAM;EACxB,MAAM,EAAE,KAAK,OAAO,gBAAgB,WAAW,KAAK;AAEpD,MAAI,CAAC,SAAS,eACZ,OAAM,IAAI,aAAa,gBAAgB,kDAAkD,EACvF,MAAM,6DACP,CAAC;EAGJ,MAAM,UAAU,MAAM,oBAAoB,IAAI;EAC9C,MAAM,UAAoB,EAAE;EAC5B,MAAM,YAAsB,EAAE;EAC9B,MAAM,WAAqB,EAAE;AAE7B,OAAK,MAAM,OAAO,QAAQ,aAAa;GACrC,MAAM,MAAM,KAAK,KAAK,IAAI;AAC1B,OAAI,CAAE,MAAM,WAAW,IAAI,CACzB;AAGF,OAAI,EAAC,MADkB,SAAS,KAAK,OAAO,CAAC,YAAY,GAAG,EAC9C,SAAA,kCAAwB,EAAE;AACtC,cAAU,KAAK,IAAI;AACnB;;AAEF,OAAI,CAAC,OACH,OAAM,GAAG,KAAK,EAAE,OAAO,MAAM,CAAC;AAEhC,WAAQ,KAAK,IAAI;;AAGnB,OAAK,MAAM,OAAO,QAAQ,iBAAiB;GACzC,MAAM,MAAM,KAAK,KAAK,IAAI;AAC1B,OAAI,CAAE,MAAM,WAAW,IAAI,CACzB;AAEF,OAAI,CAAC,OACH,OAAM,GAAG,KAAK,EAAE,OAAO,MAAM,CAAC;AAEhC,WAAQ,KAAK,IAAI;;AAGnB,OAAK,MAAM,OAAO,QAAQ,YAAY;GACpC,MAAM,MAAM,KAAK,KAAK,IAAI;AAC1B,OAAI,CAAE,MAAM,WAAW,IAAI,CACzB;AAEF,OAAI,QAAQ;AACV,aAAS,KAAK,GAAG,IAAI,MAAM,IAAI,sBAAsB;AACrD;;GAGF,MAAM,SAAS,GAAG,IAAI,4BADR,IAAI,MAAM,EAAC,aAAa,CAAC,QAAQ,SAAS,IAClB;AACtC,SAAM,OAAO,KAAK,OAAO;AACzB,YAAS,KAAK,GAAG,IAAI,MAAM,OAAO,MAAM,IAAI,SAAS,EAAE,GAAG;;AAG5D,OAAK,MAAM,OAAO,QAAQ,aAAa;GACrC,MAAM,MAAM,KAAK,KAAK,IAAI;AAC1B,OAAI,CAAE,MAAM,WAAW,IAAI,CACzB;AAEF,OAAI,CAAC,OACH,OAAM,GAAG,KAAK;IAAE,WAAW;IAAM,OAAO;IAAM,CAAC;AAEjD,WAAQ,KAAK,IAAI;;AAQnB,OAAK,MAAM,OAAO,QAAQ,eAAe;GACvC,MAAM,MAAM,KAAK,KAAK,IAAI;AAC1B,OAAI,CAAE,MAAM,WAAW,IAAI,CACzB;GAEF,MAAM,WAAW,MAAM,SAAS,KAAK,OAAO,CAAC,YAAY,GAAG;GAC5D,MAAM,WAAW,sBAAsB,SAAS;AAChD,OAAI,aAAa,SACf;GAEF,MAAM,OAAO,SAAS,MAAM,KAAK,MAAM,SAAS,MAAM,KAAK,cAAc,MAAM;AAC/E,OAAI,CAAC,OACH,KAAI,KACF,OAAM,GAAG,KAAK,EAAE,OAAO,MAAM,CAAC;OAE9B,OAAM,UAAU,KAAK,SAAS;AAGlC,WAAQ,KAAK,OAAO,MAAM,GAAG,IAAI,oBAAoB;;EAOvD,MAAM,cAAc,QAAQ,YAAY,KAAK,QAAQ;AACnD,OAAI,QAAQ,kBAAkB,IAAI,SAAS,gBAAgB,CACzD,QAAO,0CAA0C;AAEnD,OAAI,QAAQ,kBAAkB,IAAI,SAAS,gBAAgB,CACzD,QAAO,iFAAiF;AAE1F,UAAO,+CAA+C;IACtD;AAEF,MAAI,QAAQ,WAAW,KAAK,SAAS,WAAW,KAAK,YAAY,WAAW,EAC1E,QAAO,KAAK,KAAK;GAAE,QAAQ;GAAW,QAAQ;GAAoB,MAAM,EAAE,KAAK;GAAE,CAAC;EAGpF,MAAM,eAAe,qBAAqB,UAAU,QAAQ,aAAa;AAEzE,SAAO,KAAK,KAAK;GACf,QAAQ;GACR,MAAM;IACJ,OAAO;IACP,eAAe;IACf,iBAAiB;IACjB,WAAW;IACX,eAAe;IACf,cAAc;IACf;GACF,CAAC"}
|
package/dist/commands/logs.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { E as ZitadelError, S as resolveCwd, b as publicCliCommand, m as readRuntimeMetadata, t as BaseCommand } from "../oclif-
|
|
2
|
-
import { a as followContainerLogs, f as binaryLogs, p as followBinaryLogs, t as containerLogs } from "../docker-
|
|
1
|
+
import { E as ZitadelError, S as resolveCwd, b as publicCliCommand, m as readRuntimeMetadata, t as BaseCommand } from "../oclif-SjHLB_XK.mjs";
|
|
2
|
+
import { a as followContainerLogs, f as binaryLogs, p as followBinaryLogs, t as containerLogs } from "../docker-BbX0yOpg.mjs";
|
|
3
3
|
import { Flags } from "@oclif/core";
|
|
4
4
|
//#region src/commands/logs.ts
|
|
5
5
|
var Logs = class Logs extends BaseCommand {
|
package/dist/commands/plan.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { t as BaseCommand } from "../oclif-
|
|
2
|
-
import { o as readZitadelSecret } from "../project-
|
|
3
|
-
import {
|
|
4
|
-
import { t as environmentSchema } from "../environment-
|
|
1
|
+
import { t as BaseCommand } from "../oclif-SjHLB_XK.mjs";
|
|
2
|
+
import { o as readZitadelSecret } from "../project-DXc7q4wN.mjs";
|
|
3
|
+
import { i as buildSyncPlan, l as makeSyncers, n as renderPlan, r as summarizePlan, t as collectPlanWarnings } from "../sync-Bu_iLIbb.mjs";
|
|
4
|
+
import { t as environmentSchema } from "../environment-ABj1IWZt.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";
|
|
@@ -49,7 +49,10 @@ var Plan = class Plan extends BaseCommand {
|
|
|
49
49
|
consola$1.success(`Plan: ${summary.creates} create${summary.creates === 1 ? "" : "s"}, ${summary.updates} update${summary.updates === 1 ? "" : "s"}, ${summary.revisions} new revision${summary.revisions === 1 ? "" : "s"}, ${summary.deletes} delete${summary.deletes === 1 ? "" : "s"}, ${plan.length - summary.total} unchanged`);
|
|
50
50
|
return this.emit({
|
|
51
51
|
status: "ok",
|
|
52
|
-
data:
|
|
52
|
+
data: {
|
|
53
|
+
...summary,
|
|
54
|
+
warnings: collectPlanWarnings(plan)
|
|
55
|
+
},
|
|
53
56
|
pretty: renderPlan(plan, isTTY)
|
|
54
57
|
});
|
|
55
58
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plan.mjs","names":[],"sources":["../../src/commands/plan.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 {
|
|
1
|
+
{"version":3,"file":"plan.mjs","names":[],"sources":["../../src/commands/plan.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 {\n buildSyncPlan,\n collectPlanWarnings,\n makeSyncers,\n renderPlan,\n summarizePlan,\n} from \"../lib/sync\";\nimport { readZitadelSecret } from \"../lib/project\";\n\n/**\n * `zitadel plan` — validate config and preview the sync diff without mutating.\n *\n * The read-only counterpart of `apply`: it builds and renders the diff instead\n * of running the sync loop. All validation (structural shape and env-ref\n * presence) happens in the sync engine, so an invalid file fails the same way\n * `apply` would.\n */\nexport default class Plan extends BaseCommand {\n static override description = \"Validate config without mutation and preview the sync diff.\";\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(Plan);\n await this.toMeta(flags);\n const { cwd, source, env, 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({\n client,\n projectId: secret.project_id,\n env,\n });\n\n consola.start(\"Building plan\");\n const plan = await buildSyncPlan(cwd, syncers, true);\n const summary = summarizePlan(plan);\n this.recordTelemetry({\n creates: summary.creates,\n updates: summary.updates,\n revisions: summary.revisions,\n deletes: summary.deletes,\n total: summary.total,\n });\n consola.success(\n `Plan: ${summary.creates} create${summary.creates === 1 ? \"\" : \"s\"}, ` +\n `${summary.updates} update${summary.updates === 1 ? \"\" : \"s\"}, ` +\n `${summary.revisions} new revision${summary.revisions === 1 ? \"\" : \"s\"}, ` +\n `${summary.deletes} delete${summary.deletes === 1 ? \"\" : \"s\"}, ` +\n `${plan.length - summary.total} unchanged`,\n );\n return this.emit({\n status: \"ok\",\n data: { ...summary, warnings: collectPlanWarnings(plan) },\n pretty: renderPlan(plan, isTTY),\n });\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAwBA,IAAqB,OAArB,MAAqB,aAAa,YAAY;CAC5C,OAAgB,cAAc;CAC9B,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,KAAK;AACxC,QAAM,KAAK,OAAO,MAAM;EACxB,MAAM,EAAE,KAAK,QAAQ,KAAK,UAAU,KAAK;EAEzC,MAAM,SAAS,MAAM,kBAAkB,IAAI;AAC3C,YAAQ,KAAK,aAAa,OAAO,aAAa;AAC9C,YAAQ,KAAK,aAAa,SAAS;EAKnC,MAAM,UAAU,YAAY;GAC1B,QALa,oBAAoB;IACjC,SAAS;IACT,OAAO,OAAO;IACf,CAEO;GACN,WAAW,OAAO;GAClB;GACD,CAAC;AAEF,YAAQ,MAAM,gBAAgB;EAC9B,MAAM,OAAO,MAAM,cAAc,KAAK,SAAS,KAAK;EACpD,MAAM,UAAU,cAAc,KAAK;AACnC,OAAK,gBAAgB;GACnB,SAAS,QAAQ;GACjB,SAAS,QAAQ;GACjB,WAAW,QAAQ;GACnB,SAAS,QAAQ;GACjB,OAAO,QAAQ;GAChB,CAAC;AACF,YAAQ,QACN,SAAS,QAAQ,QAAQ,SAAS,QAAQ,YAAY,IAAI,KAAK,IAAI,IAC9D,QAAQ,QAAQ,SAAS,QAAQ,YAAY,IAAI,KAAK,IAAI,IAC1D,QAAQ,UAAU,eAAe,QAAQ,cAAc,IAAI,KAAK,IAAI,IACpE,QAAQ,QAAQ,SAAS,QAAQ,YAAY,IAAI,KAAK,IAAI,IAC1D,KAAK,SAAS,QAAQ,MAAM,YAClC;AACD,SAAO,KAAK,KAAK;GACf,QAAQ;GACR,MAAM;IAAE,GAAG;IAAS,UAAU,oBAAoB,KAAK;IAAE;GACzD,QAAQ,WAAW,MAAM,MAAM;GAChC,CAAC"}
|
package/dist/commands/reset.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { E as ZitadelError, S as resolveCwd, b as publicCliCommand, f as localContainerName, g as removeRuntimeMetadata, h as removeLocalData, m as readRuntimeMetadata, t as BaseCommand } from "../oclif-
|
|
2
|
-
import { g as stopBinaryRuntime, u as stopAndRemoveContainer } from "../docker-
|
|
1
|
+
import { E as ZitadelError, S as resolveCwd, b as publicCliCommand, f as localContainerName, g as removeRuntimeMetadata, h as removeLocalData, m as readRuntimeMetadata, t as BaseCommand } from "../oclif-SjHLB_XK.mjs";
|
|
2
|
+
import { g as stopBinaryRuntime, u as stopAndRemoveContainer } from "../docker-BbX0yOpg.mjs";
|
|
3
3
|
import { cancel, confirm, isCancel } from "@clack/prompts";
|
|
4
4
|
//#region src/commands/reset.ts
|
|
5
5
|
var Reset = class Reset extends BaseCommand {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { t as BaseCommand } from "../../oclif-
|
|
2
|
-
import { o as readZitadelSecret } from "../../project-
|
|
3
|
-
import { t as environmentSchema } from "../../environment-
|
|
1
|
+
import { t as BaseCommand } from "../../oclif-SjHLB_XK.mjs";
|
|
2
|
+
import { o as readZitadelSecret } from "../../project-DXc7q4wN.mjs";
|
|
3
|
+
import { t as environmentSchema } from "../../environment-ABj1IWZt.mjs";
|
|
4
4
|
import { cancel, isCancel, select, spinner } from "@clack/prompts";
|
|
5
5
|
import { Flags } from "@oclif/core";
|
|
6
6
|
import { createZitadelClient } from "@zitadel/api/client";
|
package/dist/commands/setup.mjs
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
import { D as toZitadelError, E as ZitadelError, T as stableStringify, b as publicCliCommand, n as DEFAULT_SERVER, t as BaseCommand } from "../oclif-
|
|
2
|
-
import {
|
|
3
|
-
import { n as hasZitadelSecret, t as hasZitadelConfig } from "../project-
|
|
4
|
-
import {
|
|
1
|
+
import { D as toZitadelError, E as ZitadelError, T as stableStringify, b as publicCliCommand, n as DEFAULT_SERVER, t as BaseCommand } from "../oclif-SjHLB_XK.mjs";
|
|
2
|
+
import { n as inspectScaffoldTarget, o as issuerFromPort, r as RENDERER_IDS, t as createOrca } from "../orca-_TmrJQMw.mjs";
|
|
3
|
+
import { n as hasZitadelSecret, t as hasZitadelConfig } from "../project-DXc7q4wN.mjs";
|
|
4
|
+
import { a as hashForState, c as updateState, s as writeBackResource, u as FLOWS_DIR } from "../sync-Bu_iLIbb.mjs";
|
|
5
5
|
import { t as SCHEMAS_DIR } from "../user-schema-DDz5-lX5.mjs";
|
|
6
|
-
import { t as
|
|
6
|
+
import { n as verifyLoginAction, t as customizeAndPublishActions } from "../journey-guidance-E_3_UwGt.mjs";
|
|
7
|
+
import { t as listListeningPorts } from "../ports-XujDtA47.mjs";
|
|
7
8
|
import { mkdir, readFile, rm, stat, writeFile } from "node:fs/promises";
|
|
8
9
|
import { basename, dirname, join } from "node:path";
|
|
9
10
|
import { cancel, confirm, intro, isCancel, outro, select, spinner, text } from "@clack/prompts";
|
|
10
11
|
import { Flags } from "@oclif/core";
|
|
11
12
|
import { createZitadelClient } from "@zitadel/api/client";
|
|
13
|
+
import { DEFAULT_FLOW_CONFIG_PATH, DEFAULT_FLOW_SCHEMA_URI, DEFAULT_SCHEMA_CONFIG_PATH, DEFAULT_SETUP_PRESET, SETUP_PRESETS, flowsReadmeContent, getDefaultHumanUserSchema, getDefaultLoginFlow, schemasReadmeContent } from "@zitadel/config/defaults";
|
|
12
14
|
import { consola as consola$1 } from "consola";
|
|
13
15
|
import { spawn } from "node:child_process";
|
|
14
|
-
import { DEFAULT_FLOW_CONFIG_PATH, DEFAULT_FLOW_SCHEMA_URI, DEFAULT_SCHEMA_CONFIG_PATH, flowsReadmeContent, getDefaultHumanUserSchema, getDefaultLoginFlow, schemasReadmeContent } from "@zitadel/config/defaults";
|
|
15
16
|
import { normalizeFlowBody, normalizeSchemaBody } from "@zitadel/config/normalize";
|
|
16
17
|
import pc from "picocolors";
|
|
17
18
|
//#region src/lib/setup-resources.ts
|
|
@@ -30,7 +31,8 @@ async function materializeSetupResources(opts) {
|
|
|
30
31
|
await mkdir(join(opts.cwd, FLOWS_DIR), { recursive: true });
|
|
31
32
|
await mkdir(join(opts.cwd, SCHEMAS_DIR), { recursive: true });
|
|
32
33
|
const filesWritten = [];
|
|
33
|
-
const
|
|
34
|
+
const preset = opts.preset ?? DEFAULT_SETUP_PRESET;
|
|
35
|
+
const { $id: _templateId, ...schemaBody } = getDefaultHumanUserSchema({ preset });
|
|
34
36
|
if (await writeResourceFile(opts.cwd, DEFAULT_SCHEMA_CONFIG_PATH, schemaBody, opts.force)) filesWritten.push(join(opts.cwd, DEFAULT_SCHEMA_CONFIG_PATH));
|
|
35
37
|
const schemaId = requiredString((await opts.client.createSchema(schemaBody, { project_id: opts.projectId })).id, "created schema id");
|
|
36
38
|
let schemaHash = hashForState({ normalize: normalizeSchemaBody }, schemaBody);
|
|
@@ -44,7 +46,10 @@ async function materializeSetupResources(opts) {
|
|
|
44
46
|
id: schemaId,
|
|
45
47
|
hash: schemaHash
|
|
46
48
|
});
|
|
47
|
-
const flowBody = getDefaultLoginFlow({
|
|
49
|
+
const flowBody = getDefaultLoginFlow({
|
|
50
|
+
userSchemaUrl: schemaId,
|
|
51
|
+
preset
|
|
52
|
+
});
|
|
48
53
|
if (await writeResourceFile(opts.cwd, DEFAULT_FLOW_CONFIG_PATH, flowBody, opts.force)) filesWritten.push(join(opts.cwd, DEFAULT_FLOW_CONFIG_PATH));
|
|
49
54
|
const flow = await opts.client.createFlowDefinition({
|
|
50
55
|
project_id: opts.projectId,
|
|
@@ -238,17 +243,18 @@ async function installDependenciesForSetup(input) {
|
|
|
238
243
|
}
|
|
239
244
|
function outcome(input) {
|
|
240
245
|
const planCommand = publicCliCommand("plan", input.cliVersion);
|
|
241
|
-
const
|
|
242
|
-
const
|
|
243
|
-
`
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
`Preview and publish config changes: ${planCommand} then ${applyCommand}`
|
|
246
|
+
const statusCommand = publicCliCommand("status", input.cliVersion);
|
|
247
|
+
const verifyActions = [
|
|
248
|
+
...input.includeInstallCommand ? [`Install dependencies: ${input.install.command}`] : [],
|
|
249
|
+
`Start your project: ${input.devCommand} (then open ${input.issuer}/login)`,
|
|
250
|
+
verifyLoginAction()
|
|
247
251
|
];
|
|
252
|
+
const breadcrumb = `Once login works: ${statusCommand} shows your next steps; customizing is covered in your README's Zitadel section.`;
|
|
248
253
|
return {
|
|
249
254
|
install: input.install,
|
|
250
255
|
devCommand: input.devCommand,
|
|
251
|
-
|
|
256
|
+
boxActions: [...verifyActions, breadcrumb],
|
|
257
|
+
nextActions: [...verifyActions, ...customizeAndPublishActions(input.cliVersion)],
|
|
252
258
|
nextCommands: input.includeInstallCommand ? [
|
|
253
259
|
input.install.command,
|
|
254
260
|
input.devCommand,
|
|
@@ -468,6 +474,36 @@ async function discoverLocalOidc() {
|
|
|
468
474
|
}
|
|
469
475
|
}
|
|
470
476
|
//#endregion
|
|
477
|
+
//#region src/commands/setup/prompts/sign-in-preset.ts
|
|
478
|
+
/**
|
|
479
|
+
* "How should users sign in?" — picks the schema+flow preset the scaffold
|
|
480
|
+
* starts from (#448: app-type/preset selection before any `.zitadel/` file
|
|
481
|
+
* is written). `--preset` is authoritative; non-interactive runs keep the
|
|
482
|
+
* password-first default seeded by the command.
|
|
483
|
+
*/
|
|
484
|
+
var SignInPresetPrompt = class {
|
|
485
|
+
async ask(answers, ctx) {
|
|
486
|
+
if (ctx.presetFromFlag) return answers;
|
|
487
|
+
const labels = {
|
|
488
|
+
"password-first": "Password first — email + password, passkey optional during registration",
|
|
489
|
+
"passkey-first": "Passkey first — one-tap passkey up front, email + password fallback"
|
|
490
|
+
};
|
|
491
|
+
const value = await select({
|
|
492
|
+
message: "How should users sign in?",
|
|
493
|
+
initialValue: answers.preset,
|
|
494
|
+
options: SETUP_PRESETS.map((preset) => ({
|
|
495
|
+
value: preset,
|
|
496
|
+
label: labels[preset]
|
|
497
|
+
}))
|
|
498
|
+
});
|
|
499
|
+
bail(value);
|
|
500
|
+
return {
|
|
501
|
+
...answers,
|
|
502
|
+
preset: value
|
|
503
|
+
};
|
|
504
|
+
}
|
|
505
|
+
};
|
|
506
|
+
//#endregion
|
|
471
507
|
//#region src/commands/setup/prompts/pick-framework.ts
|
|
472
508
|
/**
|
|
473
509
|
* "Choose a framework to scaffold" — the only prompt outside the main wizard.
|
|
@@ -506,7 +542,8 @@ var PickFrameworkPrompt = class {
|
|
|
506
542
|
const SETUP_PROMPTS = [
|
|
507
543
|
new FrameworkConfirmPrompt(),
|
|
508
544
|
new ServerPrompt(),
|
|
509
|
-
new DevPortPrompt()
|
|
545
|
+
new DevPortPrompt(),
|
|
546
|
+
new SignInPresetPrompt()
|
|
510
547
|
];
|
|
511
548
|
//#endregion
|
|
512
549
|
//#region src/commands/setup/summary.ts
|
|
@@ -633,14 +670,18 @@ var Setup = class Setup extends BaseCommand {
|
|
|
633
670
|
options: [...RENDERER_IDS]
|
|
634
671
|
}),
|
|
635
672
|
"dev-port": Flags.integer({ description: "Dev-server port; also the issuer origin registered with Zitadel. Defaults to the detected port. Use distinct ports to run several scaffolded apps side by side." }),
|
|
636
|
-
"skip-install": Flags.boolean({ description: "Do not install dependencies after setup updates package.json." })
|
|
673
|
+
"skip-install": Flags.boolean({ description: "Do not install dependencies after setup updates package.json." }),
|
|
674
|
+
preset: Flags.string({
|
|
675
|
+
description: "Sign-in preset for the scaffolded schema and login flow (default: password-first).",
|
|
676
|
+
options: [...SETUP_PRESETS]
|
|
677
|
+
})
|
|
637
678
|
};
|
|
638
679
|
async run() {
|
|
639
680
|
const { flags } = await this.parse(Setup);
|
|
640
681
|
try {
|
|
641
682
|
await this.toMeta(flags);
|
|
642
683
|
} catch (error) {
|
|
643
|
-
throw localSetupHint(error, flags
|
|
684
|
+
throw localSetupHint(error, retryOptionsFromFlags(flags), this.config.version);
|
|
644
685
|
}
|
|
645
686
|
const { cwd, nonInteractive, dryRun, force } = this.meta;
|
|
646
687
|
if (await hasZitadelConfig(cwd)) return this.emit({
|
|
@@ -671,6 +712,7 @@ var Setup = class Setup extends BaseCommand {
|
|
|
671
712
|
scaffolded_skeleton: scaffoldedFramework,
|
|
672
713
|
skip_install: Boolean(flags["skip-install"]),
|
|
673
714
|
dev_port_explicit: flags["dev-port"] !== void 0,
|
|
715
|
+
preset: flags.preset ?? DEFAULT_SETUP_PRESET,
|
|
674
716
|
step: "framework_resolved"
|
|
675
717
|
});
|
|
676
718
|
if (flags["dev-port"] !== void 0) {
|
|
@@ -684,18 +726,21 @@ var Setup = class Setup extends BaseCommand {
|
|
|
684
726
|
}
|
|
685
727
|
let answers = {
|
|
686
728
|
server: this.meta.source,
|
|
687
|
-
devPort: framework.devPort
|
|
729
|
+
devPort: framework.devPort,
|
|
730
|
+
preset: flags.preset ?? DEFAULT_SETUP_PRESET
|
|
688
731
|
};
|
|
689
732
|
if (!nonInteractive && !dryRun) {
|
|
690
733
|
intro("Zitadel setup");
|
|
691
734
|
const promptCtx = {
|
|
692
735
|
framework,
|
|
693
736
|
serverFlag: this.meta.serverFlag,
|
|
694
|
-
devPortFromFlag: flags["dev-port"] !== void 0
|
|
737
|
+
devPortFromFlag: flags["dev-port"] !== void 0,
|
|
738
|
+
presetFromFlag: flags.preset !== void 0
|
|
695
739
|
};
|
|
696
740
|
for (const prompt of SETUP_PROMPTS) answers = await prompt.ask(answers, promptCtx);
|
|
697
741
|
outro("Configuration captured");
|
|
698
742
|
}
|
|
743
|
+
this.recordTelemetry({ preset: answers.preset });
|
|
699
744
|
const issuer = issuerFromPort(answers.devPort);
|
|
700
745
|
framework = {
|
|
701
746
|
...framework,
|
|
@@ -704,7 +749,13 @@ var Setup = class Setup extends BaseCommand {
|
|
|
704
749
|
};
|
|
705
750
|
consola$1.start(`Creating project on ${answers.server}${dryRun ? " (dry run)" : ""}`);
|
|
706
751
|
const unauthClient = createZitadelClient({ baseUrl: answers.server });
|
|
707
|
-
const
|
|
752
|
+
const projectName = defaultProjectName(cwd, framework.id);
|
|
753
|
+
const project = dryRun ? dryRunProject(issuer) : await createProjectWithLocalHint(unauthClient, answers.server, this.meta.cliVersion, projectName, issuer, {
|
|
754
|
+
...retryOptionsFromFlags(flags),
|
|
755
|
+
framework: framework.id,
|
|
756
|
+
preset: answers.preset,
|
|
757
|
+
devPort: answers.devPort
|
|
758
|
+
});
|
|
708
759
|
consola$1.success(`Created project ${project.id}`);
|
|
709
760
|
this.recordTelemetry({ step: "project_created" });
|
|
710
761
|
const ctx = {
|
|
@@ -714,7 +765,8 @@ var Setup = class Setup extends BaseCommand {
|
|
|
714
765
|
issuer,
|
|
715
766
|
server: answers.server,
|
|
716
767
|
cliVersion: this.meta.cliVersion,
|
|
717
|
-
scaffoldedFramework
|
|
768
|
+
scaffoldedFramework,
|
|
769
|
+
preset: answers.preset
|
|
718
770
|
};
|
|
719
771
|
consola$1.start(`Patching project files${dryRun ? " (dry run)" : ""}`);
|
|
720
772
|
const result = await orca.patcherFor(framework.id).patch(ctx, {
|
|
@@ -736,7 +788,8 @@ var Setup = class Setup extends BaseCommand {
|
|
|
736
788
|
token: project.projectSecret
|
|
737
789
|
}),
|
|
738
790
|
projectId: project.id,
|
|
739
|
-
force
|
|
791
|
+
force,
|
|
792
|
+
preset: answers.preset
|
|
740
793
|
});
|
|
741
794
|
} catch (error) {
|
|
742
795
|
await rm(join(cwd, "zitadel.json"), { force: true });
|
|
@@ -788,7 +841,7 @@ var Setup = class Setup extends BaseCommand {
|
|
|
788
841
|
message: [
|
|
789
842
|
renderSummary(sections),
|
|
790
843
|
"",
|
|
791
|
-
installOutcome.
|
|
844
|
+
installOutcome.boxActions.join("\n")
|
|
792
845
|
].join("\n"),
|
|
793
846
|
style: {
|
|
794
847
|
padding: 1,
|
|
@@ -847,17 +900,49 @@ function dryRunProject(issuer) {
|
|
|
847
900
|
createdAt: "2026-04-21T14:03:11.000Z"
|
|
848
901
|
};
|
|
849
902
|
}
|
|
850
|
-
|
|
903
|
+
/**
|
|
904
|
+
* Reconstructs the flag list of the current invocation for retry guidance,
|
|
905
|
+
* ending in `--server local`. Flags whose resolved value equals the default
|
|
906
|
+
* are omitted — the retry reproduces the same outcome without them.
|
|
907
|
+
*/
|
|
908
|
+
function setupRetryFlags(opts) {
|
|
909
|
+
const parts = [];
|
|
910
|
+
if (opts.framework) parts.push(`--framework ${opts.framework}`);
|
|
911
|
+
if (opts.preset && opts.preset !== DEFAULT_SETUP_PRESET) parts.push(`--preset ${opts.preset}`);
|
|
912
|
+
if (opts.renderer && opts.renderer !== "react") parts.push(`--renderer ${opts.renderer}`);
|
|
913
|
+
if (opts.devPort !== void 0) parts.push(`--dev-port ${opts.devPort}`);
|
|
914
|
+
if (opts.nonInteractive) parts.push("--non-interactive");
|
|
915
|
+
parts.push("--server local");
|
|
916
|
+
return parts.join(" ");
|
|
917
|
+
}
|
|
918
|
+
/**
|
|
919
|
+
* Retry options straight from parsed flags, for failures before the wizard
|
|
920
|
+
* resolves answers. `--non-interactive` is echoed only when explicitly passed
|
|
921
|
+
* — TTY/JSON-inferred non-interactivity re-infers itself on the retry.
|
|
922
|
+
*/
|
|
923
|
+
function retryOptionsFromFlags(flags) {
|
|
924
|
+
return {
|
|
925
|
+
framework: flags.framework,
|
|
926
|
+
preset: flags.preset,
|
|
927
|
+
renderer: flags.renderer,
|
|
928
|
+
devPort: flags["dev-port"],
|
|
929
|
+
nonInteractive: Boolean(flags["non-interactive"])
|
|
930
|
+
};
|
|
931
|
+
}
|
|
932
|
+
async function createProjectWithLocalHint(client, server, cliVersion, projectName, issuer, retry) {
|
|
851
933
|
try {
|
|
852
|
-
|
|
934
|
+
const payload = {
|
|
935
|
+
name: projectName,
|
|
853
936
|
previewOrigins: [issuer],
|
|
854
937
|
seedDefaults: false
|
|
855
|
-
}
|
|
938
|
+
};
|
|
939
|
+
return await client.createProject(payload);
|
|
856
940
|
} catch (error) {
|
|
857
941
|
const normalized = toZitadelError(error);
|
|
942
|
+
const retryFlags = setupRetryFlags(retry);
|
|
858
943
|
throw new ZitadelError(normalized.code, normalized.message, {
|
|
859
|
-
hint: `${normalized.hint ? `${normalized.hint} ` : ""}If you meant to use a local Zitadel server, start it first and retry setup with
|
|
860
|
-
nextCommands: [publicCliCommand("start", cliVersion), publicCliCommand(`setup
|
|
944
|
+
hint: `${normalized.hint ? `${normalized.hint} ` : ""}If you meant to use a local Zitadel server, start it first and retry setup with ${retryFlags}.`,
|
|
945
|
+
nextCommands: [publicCliCommand("start", cliVersion), publicCliCommand(`setup ${retryFlags}`, cliVersion)],
|
|
861
946
|
details: {
|
|
862
947
|
server,
|
|
863
948
|
original: normalized.details
|
|
@@ -865,10 +950,14 @@ async function createProjectWithLocalHint(client, server, cliVersion, issuer, fr
|
|
|
865
950
|
});
|
|
866
951
|
}
|
|
867
952
|
}
|
|
868
|
-
function
|
|
953
|
+
function defaultProjectName(cwd, framework) {
|
|
954
|
+
const fromDirectory = basename(cwd).trim();
|
|
955
|
+
return fromDirectory.length > 0 ? fromDirectory : `zitadel-${framework}-app`;
|
|
956
|
+
}
|
|
957
|
+
function localSetupHint(error, retry, cliVersion) {
|
|
869
958
|
const normalized = toZitadelError(error);
|
|
870
959
|
if (normalized.code !== "E_LOCAL_SERVER_NOT_RUNNING") return error;
|
|
871
|
-
const setupCommand =
|
|
960
|
+
const setupCommand = `setup ${setupRetryFlags(retry)}`;
|
|
872
961
|
return new ZitadelError(normalized.code, normalized.message, {
|
|
873
962
|
hint: `${normalized.hint ? `${normalized.hint} ` : ""}Start local Zitadel first, then rerun setup. After setup succeeds, follow its next_commands to start the app and verify registration, logout, and login in the browser.`,
|
|
874
963
|
nextCommands: [publicCliCommand("start", cliVersion), publicCliCommand(setupCommand, cliVersion)],
|
|
@@ -907,7 +996,7 @@ function pickWrittenFile(written, suffix) {
|
|
|
907
996
|
* something happened.
|
|
908
997
|
*/
|
|
909
998
|
function describeWrittenFile(relPath, dryRun) {
|
|
910
|
-
if (relPath === ".zitadel" || relPath === ".zitadel/flows" || relPath === ".zitadel/schemas") return null;
|
|
999
|
+
if (relPath === ".zitadel" || relPath === ".zitadel/flows" || relPath === ".zitadel/schemas" || relPath === ".zitadel/meta") return null;
|
|
911
1000
|
const verb = dryRun ? "Would write" : "Wrote";
|
|
912
1001
|
const sentence = SENTENCE_BY_PATH[relPath];
|
|
913
1002
|
if (sentence) return `${verb} ${sentence.subject} (${path(relPath)})`;
|
|
@@ -930,7 +1019,12 @@ const SENTENCE_BY_PATH = {
|
|
|
930
1019
|
".zitadel/flows/README.md": { subject: "the flows folder README" },
|
|
931
1020
|
".zitadel/schemas/default-human-user.json": { subject: "the editable default human user schema" },
|
|
932
1021
|
".zitadel/schemas/README.md": { subject: "the schemas folder README" },
|
|
933
|
-
"
|
|
1022
|
+
".zitadel/meta/flow-definition.json": { subject: "the flow dialect spec (editor $schema)" },
|
|
1023
|
+
".zitadel/meta/user-schema.json": { subject: "the user-schema dialect spec" },
|
|
1024
|
+
".zitadel/meta/user-property.json": { subject: "the user-property dialect spec" },
|
|
1025
|
+
"AGENTS.md": { subject: "the agent guidance (golden journey + config dialect)" },
|
|
1026
|
+
"README.md": { subject: "the README's Zitadel section" },
|
|
1027
|
+
"app/page.tsx": { subject: "the home page redirect" },
|
|
934
1028
|
"app/login/page.tsx": { subject: "the login page" },
|
|
935
1029
|
"app/register/page.tsx": { subject: "the registration page" },
|
|
936
1030
|
"app/profile/page.tsx": { subject: "the profile page" },
|
|
@@ -959,7 +1053,7 @@ function buildSummary(opts) {
|
|
|
959
1053
|
secondary: path(fileNameOf(packageJsonHit))
|
|
960
1054
|
});
|
|
961
1055
|
for (const [label, suffix] of [
|
|
962
|
-
["Home
|
|
1056
|
+
["Home redirect", "app/page.tsx"],
|
|
963
1057
|
["Login page", "app/login/page.tsx"],
|
|
964
1058
|
["Register page", "app/register/page.tsx"],
|
|
965
1059
|
["Profile page", "app/profile/page.tsx"],
|