@zitadel/cli 0.1.0-alpha.14 → 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 +13 -7
- 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 +9 -6
- 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 +154 -40
- 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-nSLnVhKK.mjs → sync-Bu_iLIbb.mjs} +351 -29
- 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-nSLnVhKK.mjs.map +0 -1
package/dist/commands/setup.mjs
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
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 { c as
|
|
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 {
|
|
16
|
+
import { normalizeFlowBody, normalizeSchemaBody } from "@zitadel/config/normalize";
|
|
15
17
|
import pc from "picocolors";
|
|
16
18
|
//#region src/lib/setup-resources.ts
|
|
17
19
|
/**
|
|
@@ -29,23 +31,39 @@ async function materializeSetupResources(opts) {
|
|
|
29
31
|
await mkdir(join(opts.cwd, FLOWS_DIR), { recursive: true });
|
|
30
32
|
await mkdir(join(opts.cwd, SCHEMAS_DIR), { recursive: true });
|
|
31
33
|
const filesWritten = [];
|
|
32
|
-
const
|
|
34
|
+
const preset = opts.preset ?? DEFAULT_SETUP_PRESET;
|
|
35
|
+
const { $id: _templateId, ...schemaBody } = getDefaultHumanUserSchema({ preset });
|
|
33
36
|
if (await writeResourceFile(opts.cwd, DEFAULT_SCHEMA_CONFIG_PATH, schemaBody, opts.force)) filesWritten.push(join(opts.cwd, DEFAULT_SCHEMA_CONFIG_PATH));
|
|
34
37
|
const schemaId = requiredString((await opts.client.createSchema(schemaBody, { project_id: opts.projectId })).id, "created schema id");
|
|
38
|
+
let schemaHash = hashForState({ normalize: normalizeSchemaBody }, schemaBody);
|
|
39
|
+
try {
|
|
40
|
+
const canonical = await opts.client.getSchemaById(encodeURIComponent(schemaId), { project_id: opts.projectId });
|
|
41
|
+
schemaHash = (await writeBackResource(opts.cwd, DEFAULT_SCHEMA_CONFIG_PATH, { normalize: normalizeSchemaBody }, canonical)).hash;
|
|
42
|
+
} catch (err) {
|
|
43
|
+
consola$1.debug(`fetch created schema ${schemaId} during setup failed:`, err);
|
|
44
|
+
}
|
|
35
45
|
await updateState(opts.cwd, DEFAULT_SCHEMA_CONFIG_PATH, {
|
|
36
46
|
id: schemaId,
|
|
37
|
-
hash:
|
|
47
|
+
hash: schemaHash
|
|
48
|
+
});
|
|
49
|
+
const flowBody = getDefaultLoginFlow({
|
|
50
|
+
userSchemaUrl: schemaId,
|
|
51
|
+
preset
|
|
38
52
|
});
|
|
39
|
-
const flowBody = getDefaultLoginFlow({ userSchemaUrl: schemaId });
|
|
40
53
|
if (await writeResourceFile(opts.cwd, DEFAULT_FLOW_CONFIG_PATH, flowBody, opts.force)) filesWritten.push(join(opts.cwd, DEFAULT_FLOW_CONFIG_PATH));
|
|
41
54
|
const flow = await opts.client.createFlowDefinition({
|
|
42
55
|
project_id: opts.projectId,
|
|
43
56
|
schema_uri: DEFAULT_FLOW_SCHEMA_URI,
|
|
44
57
|
flow_definition: flowBody
|
|
45
58
|
});
|
|
59
|
+
let flowHash = hashForState({ normalize: normalizeFlowBody }, flowBody);
|
|
60
|
+
if (flow.flow_definition) flowHash = (await writeBackResource(opts.cwd, DEFAULT_FLOW_CONFIG_PATH, {
|
|
61
|
+
normalize: normalizeFlowBody,
|
|
62
|
+
normalizeWrite: normalizeFlowBody
|
|
63
|
+
}, flow.flow_definition)).hash;
|
|
46
64
|
await updateState(opts.cwd, DEFAULT_FLOW_CONFIG_PATH, {
|
|
47
65
|
id: requiredString(flow.id, "created flow definition id"),
|
|
48
|
-
hash:
|
|
66
|
+
hash: flowHash,
|
|
49
67
|
name: flowBody.name,
|
|
50
68
|
status: flowBody.status
|
|
51
69
|
});
|
|
@@ -81,9 +99,6 @@ async function writeResourceFile(cwd, relPath, body, force) {
|
|
|
81
99
|
throw error;
|
|
82
100
|
}
|
|
83
101
|
}
|
|
84
|
-
function hashWrittenBody(body) {
|
|
85
|
-
return hashResourceContent(JSON.parse(stableStringify(body)));
|
|
86
|
-
}
|
|
87
102
|
function requiredString(value, label) {
|
|
88
103
|
if (typeof value === "string" && value.length > 0) return value;
|
|
89
104
|
throw new ZitadelError("E_VALIDATION", `Missing ${label} in server response.`);
|
|
@@ -187,6 +202,7 @@ async function installDependenciesForSetup(input) {
|
|
|
187
202
|
reason: "no-dependency-changes"
|
|
188
203
|
},
|
|
189
204
|
devCommand: devCommand.display,
|
|
205
|
+
cliVersion: input.cliVersion,
|
|
190
206
|
issuer: input.issuer,
|
|
191
207
|
includeInstallCommand: false
|
|
192
208
|
});
|
|
@@ -198,6 +214,7 @@ async function installDependenciesForSetup(input) {
|
|
|
198
214
|
reason: input.dryRun ? "dry-run" : "skip-install"
|
|
199
215
|
},
|
|
200
216
|
devCommand: devCommand.display,
|
|
217
|
+
cliVersion: input.cliVersion,
|
|
201
218
|
issuer: input.issuer,
|
|
202
219
|
includeInstallCommand: true
|
|
203
220
|
});
|
|
@@ -219,22 +236,30 @@ async function installDependenciesForSetup(input) {
|
|
|
219
236
|
command: installCommand.display
|
|
220
237
|
},
|
|
221
238
|
devCommand: devCommand.display,
|
|
239
|
+
cliVersion: input.cliVersion,
|
|
222
240
|
issuer: input.issuer,
|
|
223
241
|
includeInstallCommand: false
|
|
224
242
|
});
|
|
225
243
|
}
|
|
226
244
|
function outcome(input) {
|
|
227
|
-
const
|
|
228
|
-
const
|
|
245
|
+
const planCommand = publicCliCommand("plan", input.cliVersion);
|
|
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()
|
|
251
|
+
];
|
|
252
|
+
const breadcrumb = `Once login works: ${statusCommand} shows your next steps; customizing is covered in your README's Zitadel section.`;
|
|
229
253
|
return {
|
|
230
254
|
install: input.install,
|
|
231
255
|
devCommand: input.devCommand,
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
256
|
+
boxActions: [...verifyActions, breadcrumb],
|
|
257
|
+
nextActions: [...verifyActions, ...customizeAndPublishActions(input.cliVersion)],
|
|
258
|
+
nextCommands: input.includeInstallCommand ? [
|
|
259
|
+
input.install.command,
|
|
260
|
+
input.devCommand,
|
|
261
|
+
planCommand
|
|
262
|
+
] : [input.devCommand, planCommand]
|
|
238
263
|
};
|
|
239
264
|
}
|
|
240
265
|
function installFailed(error, installCommand, devCommand, cwd) {
|
|
@@ -449,6 +474,36 @@ async function discoverLocalOidc() {
|
|
|
449
474
|
}
|
|
450
475
|
}
|
|
451
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
|
|
452
507
|
//#region src/commands/setup/prompts/pick-framework.ts
|
|
453
508
|
/**
|
|
454
509
|
* "Choose a framework to scaffold" — the only prompt outside the main wizard.
|
|
@@ -487,7 +542,8 @@ var PickFrameworkPrompt = class {
|
|
|
487
542
|
const SETUP_PROMPTS = [
|
|
488
543
|
new FrameworkConfirmPrompt(),
|
|
489
544
|
new ServerPrompt(),
|
|
490
|
-
new DevPortPrompt()
|
|
545
|
+
new DevPortPrompt(),
|
|
546
|
+
new SignInPresetPrompt()
|
|
491
547
|
];
|
|
492
548
|
//#endregion
|
|
493
549
|
//#region src/commands/setup/summary.ts
|
|
@@ -614,14 +670,18 @@ var Setup = class Setup extends BaseCommand {
|
|
|
614
670
|
options: [...RENDERER_IDS]
|
|
615
671
|
}),
|
|
616
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." }),
|
|
617
|
-
"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
|
+
})
|
|
618
678
|
};
|
|
619
679
|
async run() {
|
|
620
680
|
const { flags } = await this.parse(Setup);
|
|
621
681
|
try {
|
|
622
682
|
await this.toMeta(flags);
|
|
623
683
|
} catch (error) {
|
|
624
|
-
throw localSetupHint(error, flags
|
|
684
|
+
throw localSetupHint(error, retryOptionsFromFlags(flags), this.config.version);
|
|
625
685
|
}
|
|
626
686
|
const { cwd, nonInteractive, dryRun, force } = this.meta;
|
|
627
687
|
if (await hasZitadelConfig(cwd)) return this.emit({
|
|
@@ -652,6 +712,7 @@ var Setup = class Setup extends BaseCommand {
|
|
|
652
712
|
scaffolded_skeleton: scaffoldedFramework,
|
|
653
713
|
skip_install: Boolean(flags["skip-install"]),
|
|
654
714
|
dev_port_explicit: flags["dev-port"] !== void 0,
|
|
715
|
+
preset: flags.preset ?? DEFAULT_SETUP_PRESET,
|
|
655
716
|
step: "framework_resolved"
|
|
656
717
|
});
|
|
657
718
|
if (flags["dev-port"] !== void 0) {
|
|
@@ -665,18 +726,21 @@ var Setup = class Setup extends BaseCommand {
|
|
|
665
726
|
}
|
|
666
727
|
let answers = {
|
|
667
728
|
server: this.meta.source,
|
|
668
|
-
devPort: framework.devPort
|
|
729
|
+
devPort: framework.devPort,
|
|
730
|
+
preset: flags.preset ?? DEFAULT_SETUP_PRESET
|
|
669
731
|
};
|
|
670
732
|
if (!nonInteractive && !dryRun) {
|
|
671
733
|
intro("Zitadel setup");
|
|
672
734
|
const promptCtx = {
|
|
673
735
|
framework,
|
|
674
736
|
serverFlag: this.meta.serverFlag,
|
|
675
|
-
devPortFromFlag: flags["dev-port"] !== void 0
|
|
737
|
+
devPortFromFlag: flags["dev-port"] !== void 0,
|
|
738
|
+
presetFromFlag: flags.preset !== void 0
|
|
676
739
|
};
|
|
677
740
|
for (const prompt of SETUP_PROMPTS) answers = await prompt.ask(answers, promptCtx);
|
|
678
741
|
outro("Configuration captured");
|
|
679
742
|
}
|
|
743
|
+
this.recordTelemetry({ preset: answers.preset });
|
|
680
744
|
const issuer = issuerFromPort(answers.devPort);
|
|
681
745
|
framework = {
|
|
682
746
|
...framework,
|
|
@@ -685,7 +749,13 @@ var Setup = class Setup extends BaseCommand {
|
|
|
685
749
|
};
|
|
686
750
|
consola$1.start(`Creating project on ${answers.server}${dryRun ? " (dry run)" : ""}`);
|
|
687
751
|
const unauthClient = createZitadelClient({ baseUrl: answers.server });
|
|
688
|
-
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
|
+
});
|
|
689
759
|
consola$1.success(`Created project ${project.id}`);
|
|
690
760
|
this.recordTelemetry({ step: "project_created" });
|
|
691
761
|
const ctx = {
|
|
@@ -695,7 +765,8 @@ var Setup = class Setup extends BaseCommand {
|
|
|
695
765
|
issuer,
|
|
696
766
|
server: answers.server,
|
|
697
767
|
cliVersion: this.meta.cliVersion,
|
|
698
|
-
scaffoldedFramework
|
|
768
|
+
scaffoldedFramework,
|
|
769
|
+
preset: answers.preset
|
|
699
770
|
};
|
|
700
771
|
consola$1.start(`Patching project files${dryRun ? " (dry run)" : ""}`);
|
|
701
772
|
const result = await orca.patcherFor(framework.id).patch(ctx, {
|
|
@@ -717,7 +788,8 @@ var Setup = class Setup extends BaseCommand {
|
|
|
717
788
|
token: project.projectSecret
|
|
718
789
|
}),
|
|
719
790
|
projectId: project.id,
|
|
720
|
-
force
|
|
791
|
+
force,
|
|
792
|
+
preset: answers.preset
|
|
721
793
|
});
|
|
722
794
|
} catch (error) {
|
|
723
795
|
await rm(join(cwd, "zitadel.json"), { force: true });
|
|
@@ -740,6 +812,7 @@ var Setup = class Setup extends BaseCommand {
|
|
|
740
812
|
files_written_count: allFilesWritten.length
|
|
741
813
|
});
|
|
742
814
|
const installOutcome = await installDependenciesForSetup({
|
|
815
|
+
cliVersion: this.meta.cliVersion,
|
|
743
816
|
cwd,
|
|
744
817
|
depsAdded: result.depsAdded,
|
|
745
818
|
dryRun,
|
|
@@ -768,7 +841,7 @@ var Setup = class Setup extends BaseCommand {
|
|
|
768
841
|
message: [
|
|
769
842
|
renderSummary(sections),
|
|
770
843
|
"",
|
|
771
|
-
installOutcome.
|
|
844
|
+
installOutcome.boxActions.join("\n")
|
|
772
845
|
].join("\n"),
|
|
773
846
|
style: {
|
|
774
847
|
padding: 1,
|
|
@@ -827,17 +900,49 @@ function dryRunProject(issuer) {
|
|
|
827
900
|
createdAt: "2026-04-21T14:03:11.000Z"
|
|
828
901
|
};
|
|
829
902
|
}
|
|
830
|
-
|
|
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) {
|
|
831
933
|
try {
|
|
832
|
-
|
|
934
|
+
const payload = {
|
|
935
|
+
name: projectName,
|
|
833
936
|
previewOrigins: [issuer],
|
|
834
937
|
seedDefaults: false
|
|
835
|
-
}
|
|
938
|
+
};
|
|
939
|
+
return await client.createProject(payload);
|
|
836
940
|
} catch (error) {
|
|
837
941
|
const normalized = toZitadelError(error);
|
|
942
|
+
const retryFlags = setupRetryFlags(retry);
|
|
838
943
|
throw new ZitadelError(normalized.code, normalized.message, {
|
|
839
|
-
hint: `${normalized.hint ? `${normalized.hint} ` : ""}If you meant to use a local Zitadel server, start it first and retry setup with
|
|
840
|
-
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)],
|
|
841
946
|
details: {
|
|
842
947
|
server,
|
|
843
948
|
original: normalized.details
|
|
@@ -845,10 +950,14 @@ async function createProjectWithLocalHint(client, server, cliVersion, issuer, fr
|
|
|
845
950
|
});
|
|
846
951
|
}
|
|
847
952
|
}
|
|
848
|
-
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) {
|
|
849
958
|
const normalized = toZitadelError(error);
|
|
850
959
|
if (normalized.code !== "E_LOCAL_SERVER_NOT_RUNNING") return error;
|
|
851
|
-
const setupCommand =
|
|
960
|
+
const setupCommand = `setup ${setupRetryFlags(retry)}`;
|
|
852
961
|
return new ZitadelError(normalized.code, normalized.message, {
|
|
853
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.`,
|
|
854
963
|
nextCommands: [publicCliCommand("start", cliVersion), publicCliCommand(setupCommand, cliVersion)],
|
|
@@ -887,7 +996,7 @@ function pickWrittenFile(written, suffix) {
|
|
|
887
996
|
* something happened.
|
|
888
997
|
*/
|
|
889
998
|
function describeWrittenFile(relPath, dryRun) {
|
|
890
|
-
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;
|
|
891
1000
|
const verb = dryRun ? "Would write" : "Wrote";
|
|
892
1001
|
const sentence = SENTENCE_BY_PATH[relPath];
|
|
893
1002
|
if (sentence) return `${verb} ${sentence.subject} (${path(relPath)})`;
|
|
@@ -910,7 +1019,12 @@ const SENTENCE_BY_PATH = {
|
|
|
910
1019
|
".zitadel/flows/README.md": { subject: "the flows folder README" },
|
|
911
1020
|
".zitadel/schemas/default-human-user.json": { subject: "the editable default human user schema" },
|
|
912
1021
|
".zitadel/schemas/README.md": { subject: "the schemas folder README" },
|
|
913
|
-
"
|
|
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" },
|
|
914
1028
|
"app/login/page.tsx": { subject: "the login page" },
|
|
915
1029
|
"app/register/page.tsx": { subject: "the registration page" },
|
|
916
1030
|
"app/profile/page.tsx": { subject: "the profile page" },
|
|
@@ -939,7 +1053,7 @@ function buildSummary(opts) {
|
|
|
939
1053
|
secondary: path(fileNameOf(packageJsonHit))
|
|
940
1054
|
});
|
|
941
1055
|
for (const [label, suffix] of [
|
|
942
|
-
["Home
|
|
1056
|
+
["Home redirect", "app/page.tsx"],
|
|
943
1057
|
["Login page", "app/login/page.tsx"],
|
|
944
1058
|
["Register page", "app/register/page.tsx"],
|
|
945
1059
|
["Profile page", "app/profile/page.tsx"],
|