@zitadel/cli 0.1.0-alpha.10 → 0.1.0-alpha.12

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.
Files changed (34) hide show
  1. package/README.md +53 -35
  2. package/SKILLS.md +6 -2
  3. package/dist/commands/apply.mjs +9 -3
  4. package/dist/commands/apply.mjs.map +1 -1
  5. package/dist/commands/doctor.mjs +12 -5
  6. package/dist/commands/doctor.mjs.map +1 -1
  7. package/dist/commands/eject.mjs +3 -3
  8. package/dist/commands/logs.mjs +2 -2
  9. package/dist/commands/plan.mjs +9 -3
  10. package/dist/commands/plan.mjs.map +1 -1
  11. package/dist/commands/reset.mjs +2 -2
  12. package/dist/commands/setup.mjs +20 -3
  13. package/dist/commands/setup.mjs.map +1 -1
  14. package/dist/commands/start.mjs +4 -3
  15. package/dist/commands/start.mjs.map +1 -1
  16. package/dist/commands/status.mjs +3 -3
  17. package/dist/commands/stop.mjs +2 -2
  18. package/dist/{docker-CnGQK3ZK.mjs → docker-Djz6BLp9.mjs} +2 -2
  19. package/dist/{docker-CnGQK3ZK.mjs.map → docker-Djz6BLp9.mjs.map} +1 -1
  20. package/dist/{docker-guidance-ypN3IM3o.mjs → docker-guidance-D-33g1uV.mjs} +2 -2
  21. package/dist/{docker-guidance-ypN3IM3o.mjs.map → docker-guidance-D-33g1uV.mjs.map} +1 -1
  22. package/dist/{oclif-B7lBzh3R.mjs → oclif-BoUVygsZ.mjs} +708 -5
  23. package/dist/oclif-BoUVygsZ.mjs.map +1 -0
  24. package/dist/{orca-BoTFU8SI.mjs → orca-DU8myWGm.mjs} +743 -103
  25. package/dist/orca-DU8myWGm.mjs.map +1 -0
  26. package/dist/{project-Cd0L3PtM.mjs → project-B1qVQMKS.mjs} +2 -2
  27. package/dist/{project-Cd0L3PtM.mjs.map → project-B1qVQMKS.mjs.map} +1 -1
  28. package/dist/{sync-BojoQm2P.mjs → sync-CzruNz8K.mjs} +11 -5
  29. package/dist/sync-CzruNz8K.mjs.map +1 -0
  30. package/oclif.manifest.json +64 -1
  31. package/package.json +5 -4
  32. package/dist/oclif-B7lBzh3R.mjs.map +0 -1
  33. package/dist/orca-BoTFU8SI.mjs.map +0 -1
  34. package/dist/sync-BojoQm2P.mjs.map +0 -1
@@ -1,4 +1,4 @@
1
- import { C as isObject, E as ZitadelError, T as stableStringify, n as DEFAULT_SERVER, w as parseJsonObject, x as MANAGED_MARKER, y as npmDistTagForCliVersion } from "./oclif-B7lBzh3R.mjs";
1
+ import { C as isObject, E as ZitadelError, T as stableStringify, n as DEFAULT_SERVER, w as parseJsonObject, x as MANAGED_MARKER, y as npmDistTagForCliVersion } from "./oclif-BoUVygsZ.mjs";
2
2
  import { basename, dirname, join } from "node:path";
3
3
  import { chmod, mkdir, readFile, readdir, rename, rm, stat, writeFile } from "node:fs/promises";
4
4
  import { builders, generateCode, parseModule } from "magicast";
@@ -186,6 +186,28 @@ async function dirExists(path) {
186
186
  return stat(path).then((s) => s.isDirectory(), () => false);
187
187
  }
188
188
  //#endregion
189
+ //#region src/lib/orca/detectors/qwik.ts
190
+ /**
191
+ * Detects a Vite + Qwik single-page app: depends on `@builder.io/qwik` and
192
+ * `vite` but NOT `@builder.io/qwik-city` (Qwik City is its own meta-framework
193
+ * and ships Qwik). The source dir is `src`, the dev port comes from the
194
+ * project, and the issuer is derived from it.
195
+ */
196
+ var QwikDetector = class {
197
+ framework = "qwik";
198
+ async detect(cwd) {
199
+ const pkg = await readPackageJson(cwd).catch(() => void 0);
200
+ if (!pkg || hasDependency(pkg, "@builder.io/qwik-city") || !hasDependency(pkg, "@builder.io/qwik") || !hasDependency(pkg, "vite")) return null;
201
+ const devPort = await detectDevPort(cwd, pkg);
202
+ return {
203
+ id: "qwik",
204
+ appDir: "src",
205
+ devPort,
206
+ url: issuerFromPort(devPort)
207
+ };
208
+ }
209
+ };
210
+ //#endregion
189
211
  //#region src/lib/orca/detectors/react.ts
190
212
  /**
191
213
  * Detects a Vite + React single-page app and extracts its facts: the source
@@ -211,6 +233,50 @@ var ReactDetector = class {
211
233
  }
212
234
  };
213
235
  //#endregion
236
+ //#region src/lib/orca/detectors/solid.ts
237
+ /**
238
+ * Detects a Vite + Solid single-page app: depends on `solid-js` and `vite` but
239
+ * NOT `@solidjs/start` (SolidStart is its own meta-framework and ships Solid).
240
+ * The source dir is `src`, the dev port comes from the project, and the issuer
241
+ * is derived from it.
242
+ */
243
+ var SolidDetector = class {
244
+ framework = "solid";
245
+ async detect(cwd) {
246
+ const pkg = await readPackageJson(cwd).catch(() => void 0);
247
+ if (!pkg || hasDependency(pkg, "@solidjs/start") || !hasDependency(pkg, "solid-js") || !hasDependency(pkg, "vite")) return null;
248
+ const devPort = await detectDevPort(cwd, pkg);
249
+ return {
250
+ id: "solid",
251
+ appDir: "src",
252
+ devPort,
253
+ url: issuerFromPort(devPort)
254
+ };
255
+ }
256
+ };
257
+ //#endregion
258
+ //#region src/lib/orca/detectors/svelte.ts
259
+ /**
260
+ * Detects a Vite + Svelte single-page app: depends on `svelte` and `vite` but
261
+ * NOT `@sveltejs/kit` (SvelteKit is its own meta-framework and ships Svelte).
262
+ * The source dir is `src`, the dev port comes from the project, and the issuer
263
+ * is derived from it.
264
+ */
265
+ var SvelteDetector = class {
266
+ framework = "svelte";
267
+ async detect(cwd) {
268
+ const pkg = await readPackageJson(cwd).catch(() => void 0);
269
+ if (!pkg || hasDependency(pkg, "@sveltejs/kit") || !hasDependency(pkg, "svelte") || !hasDependency(pkg, "vite")) return null;
270
+ const devPort = await detectDevPort(cwd, pkg);
271
+ return {
272
+ id: "svelte",
273
+ appDir: "src",
274
+ devPort,
275
+ url: issuerFromPort(devPort)
276
+ };
277
+ }
278
+ };
279
+ //#endregion
214
280
  //#region src/lib/orca/detectors/vue.ts
215
281
  /**
216
282
  * Detects a Vite + Vue single-page app: depends on `vue` and `vite` but NOT
@@ -245,6 +311,9 @@ const detectors = [
245
311
  new NuxtDetector(),
246
312
  new ReactDetector(),
247
313
  new VueDetector(),
314
+ new SolidDetector(),
315
+ new SvelteDetector(),
316
+ new QwikDetector(),
248
317
  new AngularDetector()
249
318
  ];
250
319
  //#endregion
@@ -613,6 +682,7 @@ var AbstractRulePatcher = class {
613
682
  path: ".env.example",
614
683
  entries: {
615
684
  ZITADEL_PROJECT_ID: "",
685
+ ZITADEL_PROJECT_SECRET: "",
616
686
  ZITADEL_ENVIRONMENT: "",
617
687
  ZITADEL_ISSUER: "",
618
688
  ZITADEL_URL: ""
@@ -623,6 +693,7 @@ var AbstractRulePatcher = class {
623
693
  path: ".env.local",
624
694
  entries: {
625
695
  ZITADEL_PROJECT_ID: ctx.project.id,
696
+ ZITADEL_PROJECT_SECRET: ctx.project.projectSecret,
626
697
  ZITADEL_ENVIRONMENT: "development",
627
698
  ZITADEL_ISSUER: ctx.issuer,
628
699
  ZITADEL_URL: ctx.server
@@ -855,8 +926,8 @@ const PROXY_PATH = "/__nextgen";
855
926
  * The managed root component `src/app/app.ts`: a standalone component that
856
927
  * renders the `@zitadel/sdk-angular` widgets based on the current path. The
857
928
  * project id (public, not secret) is inlined; the dev proxy in `proxy.conf.cjs`
858
- * attaches the `sk_<project_id>` bearer (derived from that public id)
859
- * server-side, and no secret reaches the browser.
929
+ * attaches the project service-key secret as the bearer server-side (read from
930
+ * `.env.local`), and no secret reaches the browser.
860
931
  */
861
932
  function appComponentTemplate(projectId) {
862
933
  return `${MANAGED_MARKER}
@@ -888,40 +959,81 @@ export class App {
888
959
  */
889
960
  function appTemplateHtml() {
890
961
  return `<!-- ${MANAGED_MARKER} -->
891
- @if (path.startsWith('/profile')) {
892
- <zitadel-auth-logout [project]="project" [postSignOutUrl]="'/login'"></zitadel-auth-logout>
962
+ @if (path === '/') {
963
+ <main style="position:fixed;inset:0;padding:48px;box-sizing:border-box;display:flex;align-items:center;justify-content:center;background:#0f0f11;color-scheme:dark;color:#f4f4f6;font-family:system-ui,-apple-system,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;line-height:1.5;letter-spacing:normal;text-align:center">
964
+ <section style="width:100%;max-width:560px">
965
+ <p style="margin:0 0 12px;color:#9ca3af;font-size:14px">Zitadel auth</p>
966
+ <h1 style="margin:0 0 24px;font-size:32px;line-height:1.15;font-weight:600;color:#f4f4f6">Sign in, create an account, or open your profile.</h1>
967
+ <div style="display:flex;flex-wrap:wrap;gap:12px;justify-content:center">
968
+ <a href="/login" style="padding:10px 16px;border-radius:8px;background:#f4f4f6;color:#0f0f11;text-decoration:none;font-weight:600;font-size:14px">Sign in</a>
969
+ <a href="/register" style="padding:10px 16px;border-radius:8px;border:1px solid #3f3f46;color:#f4f4f6;text-decoration:none;font-weight:600;font-size:14px">Create account</a>
970
+ <a href="/profile" style="padding:10px 16px;border-radius:8px;border:1px solid #3f3f46;color:#f4f4f6;text-decoration:none;font-weight:600;font-size:14px">Profile</a>
971
+ </div>
972
+ </section>
973
+ </main>
974
+ } @else if (path.startsWith('/profile')) {
975
+ <div style="position:fixed;inset:0;overflow:auto;background:#0f0f11;color-scheme:dark">
976
+ <zitadel-auth-logout [project]="project" [postSignOutUrl]="'/login'"></zitadel-auth-logout>
977
+ </div>
893
978
  } @else if (path.startsWith('/register')) {
894
- <zitadel-auth-login
895
- [project]="project"
896
- purpose="register"
897
- [postSignInUrl]="'/profile'"
898
- ></zitadel-auth-login>
979
+ <div style="position:fixed;inset:0;overflow:auto;background:#0f0f11;color-scheme:dark">
980
+ <zitadel-auth-login
981
+ [project]="project"
982
+ purpose="register"
983
+ [postSignInUrl]="'/profile'"
984
+ ></zitadel-auth-login>
985
+ </div>
899
986
  } @else {
900
- <zitadel-auth-login
901
- [project]="project"
902
- purpose="login"
903
- [postSignInUrl]="'/profile'"
904
- ></zitadel-auth-login>
987
+ <div style="position:fixed;inset:0;overflow:auto;background:#0f0f11;color-scheme:dark">
988
+ <zitadel-auth-login
989
+ [project]="project"
990
+ purpose="login"
991
+ [postSignInUrl]="'/profile'"
992
+ ></zitadel-auth-login>
993
+ </div>
905
994
  }
906
995
  `;
907
996
  }
908
997
  /**
909
998
  * The managed `proxy.conf.cjs` for `ng serve`: forwards `/__nextgen/*` to the
910
- * backend (from `zitadel.json`), strips the prefix, and attaches the project's
911
- * `sk_<project_id>` bearer to every proxied request. The prefix strip and the
912
- * bearer are each provided in both the http-proxy-middleware form
913
- * (`pathRewrite`/`onProxyReq`) and the Vite form (`rewrite`/`configure`), so
914
- * both fire whichever proxy layer Angular's dev server uses.
999
+ * backend and attaches the project's service-key secret as the bearer on every
1000
+ * proxied request. Both the backend URL (`ZITADEL_URL`) and the secret
1001
+ * (`ZITADEL_PROJECT_SECRET`) are read from `.env.local`, which `zitadel setup`
1002
+ * writes and `.gitignore` excludes Angular's CLI does not auto-load env files
1003
+ * into the dev-server process, so this file does it itself with a small inline
1004
+ * parser. The prefix strip and the bearer are each provided in both the
1005
+ * http-proxy-middleware form (`pathRewrite`/`onProxyReq`) and the Vite form
1006
+ * (`rewrite`/`configure`), so both fire whichever proxy layer Angular's
1007
+ * dev server uses.
915
1008
  */
916
1009
  function proxyConfTemplate() {
917
1010
  return `${MANAGED_MARKER}
918
- const { readFileSync } = require("node:fs");
1011
+ const { readFileSync, existsSync } = require("node:fs");
919
1012
 
920
- const config = JSON.parse(readFileSync("zitadel.json", "utf8"));
921
- if (!config.project || !config.server) {
922
- throw new Error("zitadel.json is missing \\"project\\" or \\"server\\"; re-run zitadel setup.");
1013
+ function loadEnvLocal() {
1014
+ if (!existsSync(".env.local")) return {};
1015
+ const out = {};
1016
+ for (const line of readFileSync(".env.local", "utf8").split(/\\r?\\n/)) {
1017
+ const m = line.match(/^\\s*(?:export\\s+)?([A-Z_][A-Z0-9_]*)\\s*=\\s*(.*)$/);
1018
+ if (m) {
1019
+ const raw = m[2].trim();
1020
+ const quoted = raw.match(/^(['"])(.*)\\1\\s*(?:#.*)?$/);
1021
+ out[m[1]] = quoted ? quoted[2] : raw.replace(/\\s+#.*$/, "").trim();
1022
+ }
1023
+ }
1024
+ return out;
923
1025
  }
924
- const bearer = \`Bearer sk_\${config.project}\`;
1026
+
1027
+ const env = loadEnvLocal();
1028
+ const server = process.env.ZITADEL_URL ?? env.ZITADEL_URL;
1029
+ const secret = process.env.ZITADEL_PROJECT_SECRET ?? env.ZITADEL_PROJECT_SECRET;
1030
+ if (!server) {
1031
+ throw new Error("ZITADEL_URL is not set; add it to .env.local (zitadel setup writes it).");
1032
+ }
1033
+ if (!secret) {
1034
+ throw new Error("ZITADEL_PROJECT_SECRET is not set; add it to .env.local (zitadel setup writes it).");
1035
+ }
1036
+ const bearer = \`Bearer \${secret}\`;
925
1037
 
926
1038
  function setBearer(proxyReq) {
927
1039
  proxyReq.setHeader("authorization", bearer);
@@ -933,7 +1045,7 @@ function stripPrefix(path) {
933
1045
 
934
1046
  module.exports = {
935
1047
  "${PROXY_PATH}": {
936
- target: config.server,
1048
+ target: server,
937
1049
  changeOrigin: false,
938
1050
  pathRewrite: stripPrefix,
939
1051
  rewrite: stripPrefix,
@@ -945,7 +1057,7 @@ module.exports = {
945
1057
  }
946
1058
  //#endregion
947
1059
  //#region src/lib/orca/patchers/rule/angular/index.ts
948
- const SDK_DEPENDENCY$3 = "@zitadel/sdk-angular";
1060
+ const SDK_DEPENDENCY$6 = "@zitadel/sdk-angular";
949
1061
  /**
950
1062
  * Adds a `dev: "ng serve"` script only when the project does not already define
951
1063
  * one. `ng new` ships only a `start` script, but the CLI tells every framework
@@ -968,8 +1080,9 @@ function ensureDevScript(source) {
968
1080
  * Rule-based patcher for an Angular app. Inherits the shared `.zitadel/` base
969
1081
  * files from {@link AbstractRulePatcher} and contributes the managed root
970
1082
  * component (`app.ts`/`app.html`) that renders the `@zitadel/sdk-angular`
971
- * widgets, a `proxy.conf.cjs` dev proxy (attaching the `sk_<project_id>` bearer
972
- * to every proxied request) wired into `angular.json`, and the SDK dep.
1083
+ * widgets, a `proxy.conf.cjs` dev proxy (attaching the project secret from
1084
+ * `ZITADEL_PROJECT_SECRET` to every proxied request) wired into `angular.json`,
1085
+ * and the SDK dep.
973
1086
  *
974
1087
  * Unlike React/Vue (whose dev proxy lives in `vite.config.ts`), Angular owns its
975
1088
  * Vite config, so the proxy is a separate `proxy.conf.cjs` referenced from the
@@ -1016,7 +1129,7 @@ var AngularPatcher = class extends AbstractRulePatcher {
1016
1129
  },
1017
1130
  {
1018
1131
  kind: "add-dep",
1019
- name: SDK_DEPENDENCY$3,
1132
+ name: SDK_DEPENDENCY$6,
1020
1133
  version: npmDistTagForCliVersion(ctx.cliVersion)
1021
1134
  }
1022
1135
  ];
@@ -1029,7 +1142,7 @@ var AngularPatcher = class extends AbstractRulePatcher {
1029
1142
  ];
1030
1143
  }
1031
1144
  routeDeps(_view) {
1032
- return [SDK_DEPENDENCY$3];
1145
+ return [SDK_DEPENDENCY$6];
1033
1146
  }
1034
1147
  routeConfigEdits(_view) {
1035
1148
  return [
@@ -1171,7 +1284,7 @@ const ${elementName} = dynamic(
1171
1284
 
1172
1285
  export default function ${componentName}() {
1173
1286
  return (
1174
- <main style={{ minHeight: "100vh", position: "relative", background: "#0f0f11" }}>
1287
+ <main style={{ minHeight: "100vh", position: "relative", colorScheme: "dark", background: "#0f0f11" }}>
1175
1288
  <nav aria-label="Authentication" style={{ position: "absolute", top: "24px", right: "24px", zIndex: 1, display: "flex", gap: "12px" }}>
1176
1289
  <Link href="${mode === "login" ? "/register" : "/login"}" style={{ color: "#f4f4f6", fontWeight: 700, textDecoration: "none" }}>
1177
1290
  ${mode === "login" ? "Create account" : "Sign in"}
@@ -1247,28 +1360,30 @@ export default function ProfilePage() {
1247
1360
  }, []);
1248
1361
 
1249
1362
  return (
1250
- <main style={{ padding: "48px", maxWidth: "680px", margin: "0 auto" }}>
1251
- <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: "24px" }}>
1252
- <h1 style={{ fontSize: "24px", fontWeight: 700, margin: 0 }}>Signed in</h1>
1253
- <ZitadelLogout />
1363
+ <main style={{ minHeight: "100vh", colorScheme: "dark", background: "#0f0f11", color: "#f4f4f6", padding: "48px", fontFamily: "system-ui, -apple-system, 'Segoe UI', Helvetica, Arial, sans-serif" }}>
1364
+ <div style={{ maxWidth: "680px", margin: "0 auto" }}>
1365
+ <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: "24px" }}>
1366
+ <h1 style={{ fontSize: "24px", fontWeight: 700, margin: 0, color: "#f4f4f6" }}>Signed in</h1>
1367
+ <ZitadelLogout />
1368
+ </div>
1369
+ <p style={{ color: "#33a779", fontWeight: 600 }}>Signed in profile loaded.</p>
1370
+ {session ? (
1371
+ <dl style={{ display: "grid", gap: "12px", marginTop: "24px" }}>
1372
+ <div>
1373
+ <dt style={{ color: "#bfbfcf", fontSize: "14px" }}>Session state</dt>
1374
+ <dd style={{ margin: 0, fontWeight: 600, color: "#f4f4f6" }}>{session.state ?? "active"}</dd>
1375
+ </div>
1376
+ <div>
1377
+ <dt style={{ color: "#bfbfcf", fontSize: "14px" }}>User id</dt>
1378
+ <dd style={{ margin: 0, fontFamily: "monospace", color: "#f4f4f6" }}>{session.user_id ?? "available"}</dd>
1379
+ </div>
1380
+ </dl>
1381
+ ) : (
1382
+ <p style={{ color: sessionError ? "#ea4f70" : "#bfbfcf" }}>
1383
+ {sessionError || "Checking session..."}
1384
+ </p>
1385
+ )}
1254
1386
  </div>
1255
- <p style={{ color: "#166534", fontWeight: 600 }}>Signed in profile loaded.</p>
1256
- {session ? (
1257
- <dl style={{ display: "grid", gap: "12px", marginTop: "24px" }}>
1258
- <div>
1259
- <dt style={{ color: "#6b7280", fontSize: "14px" }}>Session state</dt>
1260
- <dd style={{ margin: 0, fontWeight: 600 }}>{session.state ?? "active"}</dd>
1261
- </div>
1262
- <div>
1263
- <dt style={{ color: "#6b7280", fontSize: "14px" }}>User id</dt>
1264
- <dd style={{ margin: 0, fontFamily: "monospace" }}>{session.user_id ?? "available"}</dd>
1265
- </div>
1266
- </dl>
1267
- ) : (
1268
- <p style={{ color: sessionError ? "#b91c1c" : "#6b7280" }}>
1269
- {sessionError || "Checking session..."}
1270
- </p>
1271
- )}
1272
1387
  </main>
1273
1388
  );
1274
1389
  }
@@ -1474,18 +1589,18 @@ import Link from "next/link";
1474
1589
 
1475
1590
  export default function Home() {
1476
1591
  return (
1477
- <main style={{ minHeight: "100vh", padding: "48px", display: "flex", alignItems: "center", justifyContent: "center" }}>
1592
+ <main style={{ position: "fixed", inset: 0, padding: "48px", boxSizing: "border-box", display: "flex", alignItems: "center", justifyContent: "center", background: "#0f0f11", colorScheme: "dark", color: "#f4f4f6", fontFamily: "system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif", lineHeight: 1.5, letterSpacing: "normal", textAlign: "center" }}>
1478
1593
  <section style={{ width: "100%", maxWidth: "560px" }}>
1479
- <p style={{ margin: "0 0 12px", color: "#4b5563", fontSize: "14px" }}>Zitadel auth</p>
1480
- <h1 style={{ margin: "0 0 24px", fontSize: "32px", lineHeight: 1.15 }}>Sign in, create an account, or open your profile.</h1>
1594
+ <p style={{ margin: "0 0 12px", color: "#9ca3af", fontSize: "14px" }}>Zitadel auth</p>
1595
+ <h1 style={{ margin: "0 0 24px", fontSize: "32px", lineHeight: 1.15, fontWeight: 600, color: "#f4f4f6" }}>Sign in, create an account, or open your profile.</h1>
1481
1596
  <div style={{ display: "flex", flexWrap: "wrap", gap: "12px" }}>
1482
- <Link href="/login" style={{ padding: "10px 16px", borderRadius: "8px", background: "#111827", color: "#ffffff", textDecoration: "none", fontWeight: 600 }}>
1597
+ <Link href="/login" style={{ padding: "10px 16px", borderRadius: "8px", background: "#f4f4f6", color: "#0f0f11", textDecoration: "none", fontWeight: 600, fontSize: "14px" }}>
1483
1598
  Sign in
1484
1599
  </Link>
1485
- <Link href="/register" style={{ padding: "10px 16px", borderRadius: "8px", border: "1px solid #d1d5db", color: "#111827", textDecoration: "none", fontWeight: 600 }}>
1600
+ <Link href="/register" style={{ padding: "10px 16px", borderRadius: "8px", border: "1px solid #3f3f46", color: "#f4f4f6", textDecoration: "none", fontWeight: 600, fontSize: "14px" }}>
1486
1601
  Create account
1487
1602
  </Link>
1488
- <Link href="/profile" style={{ padding: "10px 16px", borderRadius: "8px", border: "1px solid #d1d5db", color: "#111827", textDecoration: "none", fontWeight: 600 }}>
1603
+ <Link href="/profile" style={{ padding: "10px 16px", borderRadius: "8px", border: "1px solid #3f3f46", color: "#f4f4f6", textDecoration: "none", fontWeight: 600, fontSize: "14px" }}>
1489
1604
  Profile
1490
1605
  </Link>
1491
1606
  </div>
@@ -1606,7 +1721,7 @@ function nuxtConfigEdit(opts) {
1606
1721
  }
1607
1722
  //#endregion
1608
1723
  //#region src/lib/orca/patchers/rule/nuxt/templates.ts
1609
- const MAIN_STYLE = "min-height: 100vh; background: #0f0f11";
1724
+ const MAIN_STYLE = "min-height: 100vh; background: #0f0f11; color: #f4f4f6; color-scheme: dark";
1610
1725
  /** `app.vue` — renders the page router. Marker in an HTML comment. */
1611
1726
  function appVueTemplate() {
1612
1727
  return `<!-- ${MANAGED_MARKER} -->
@@ -1615,13 +1730,36 @@ function appVueTemplate() {
1615
1730
  </template>
1616
1731
 
1617
1732
  <style>
1733
+ :root {
1734
+ color-scheme: dark;
1735
+ }
1618
1736
  body {
1619
1737
  margin: 0;
1738
+ background: #0f0f11;
1739
+ color: #f4f4f6;
1620
1740
  font-family: sans-serif;
1621
1741
  }
1622
1742
  </style>
1623
1743
  `;
1624
1744
  }
1745
+ /** `pages/index.vue` — the landing chooser linking to login/register/profile. */
1746
+ function indexPageTemplate() {
1747
+ return `<!-- ${MANAGED_MARKER} -->
1748
+ <template>
1749
+ <main style="position:fixed;inset:0;padding:48px;box-sizing:border-box;display:flex;align-items:center;justify-content:center;background:#0f0f11;color-scheme:dark;color:#f4f4f6;font-family:system-ui,-apple-system,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;line-height:1.5;letter-spacing:normal;text-align:center">
1750
+ <section style="width:100%;max-width:560px">
1751
+ <p style="margin:0 0 12px;color:#9ca3af;font-size:14px">Zitadel auth</p>
1752
+ <h1 style="margin:0 0 24px;font-size:32px;line-height:1.15;font-weight:600;color:#f4f4f6">Sign in, create an account, or open your profile.</h1>
1753
+ <div style="display:flex;flex-wrap:wrap;gap:12px;justify-content:center">
1754
+ <NuxtLink to="/login" style="padding:10px 16px;border-radius:8px;background:#f4f4f6;color:#0f0f11;text-decoration:none;font-weight:600;font-size:14px">Sign in</NuxtLink>
1755
+ <NuxtLink to="/register" style="padding:10px 16px;border-radius:8px;border:1px solid #3f3f46;color:#f4f4f6;text-decoration:none;font-weight:600;font-size:14px">Create account</NuxtLink>
1756
+ <NuxtLink to="/profile" style="padding:10px 16px;border-radius:8px;border:1px solid #3f3f46;color:#f4f4f6;text-decoration:none;font-weight:600;font-size:14px">Profile</NuxtLink>
1757
+ </div>
1758
+ </section>
1759
+ </main>
1760
+ </template>
1761
+ `;
1762
+ }
1625
1763
  /** A login/register page rendering `<zitadel-login>` inside `<ClientOnly>`. */
1626
1764
  function authPage(purpose) {
1627
1765
  return `<script setup lang="ts">
@@ -1659,7 +1797,7 @@ const project = useZitadelProject();
1659
1797
  <\/script>
1660
1798
 
1661
1799
  <template>
1662
- <main style="padding: 24px">
1800
+ <main style="${MAIN_STYLE}; padding: 24px">
1663
1801
  <h1>Signed in (Nuxt)</h1>
1664
1802
  <ClientOnly>
1665
1803
  <zitadel-logout :project="project" post-sign-out-url="/login" />
@@ -1710,7 +1848,7 @@ export default defineNuxtPlugin(() => {
1710
1848
  }
1711
1849
  //#endregion
1712
1850
  //#region src/lib/orca/patchers/rule/nuxt/index.ts
1713
- const SDK_DEPENDENCY$2 = "@zitadel/sdk-nuxt";
1851
+ const SDK_DEPENDENCY$5 = "@zitadel/sdk-nuxt";
1714
1852
  const NUXT_CONFIG_PATHS = configCandidates("nuxt.config");
1715
1853
  /**
1716
1854
  * Rule-based patcher for a Nuxt app. Like Next.js, Nuxt proxies the backend and
@@ -1731,6 +1869,11 @@ var NuxtPatcher = class extends AbstractRulePatcher {
1731
1869
  path: src("app.vue"),
1732
1870
  contents: appVueTemplate()
1733
1871
  },
1872
+ {
1873
+ kind: "write",
1874
+ path: src("pages/index.vue"),
1875
+ contents: indexPageTemplate()
1876
+ },
1734
1877
  {
1735
1878
  kind: "write",
1736
1879
  path: src("pages/login.vue"),
@@ -1776,7 +1919,7 @@ var NuxtPatcher = class extends AbstractRulePatcher {
1776
1919
  },
1777
1920
  {
1778
1921
  kind: "add-dep",
1779
- name: SDK_DEPENDENCY$2,
1922
+ name: SDK_DEPENDENCY$5,
1780
1923
  version: npmDistTagForCliVersion(ctx.cliVersion)
1781
1924
  }
1782
1925
  ];
@@ -1785,6 +1928,7 @@ var NuxtPatcher = class extends AbstractRulePatcher {
1785
1928
  const src = (rel) => join(view.framework.appDir, rel);
1786
1929
  return [
1787
1930
  src("app.vue"),
1931
+ src("pages/index.vue"),
1788
1932
  src("pages/login.vue"),
1789
1933
  src("pages/register.vue"),
1790
1934
  src("pages/profile.vue"),
@@ -1793,7 +1937,7 @@ var NuxtPatcher = class extends AbstractRulePatcher {
1793
1937
  ];
1794
1938
  }
1795
1939
  routeDeps(_view) {
1796
- return [SDK_DEPENDENCY$2];
1940
+ return [SDK_DEPENDENCY$5];
1797
1941
  }
1798
1942
  routeConfigEdits(_view) {
1799
1943
  return ["nuxt.config.*"];
@@ -1801,7 +1945,7 @@ var NuxtPatcher = class extends AbstractRulePatcher {
1801
1945
  summary(_ctx) {
1802
1946
  return {
1803
1947
  title: "Nuxt integration",
1804
- detail: "Wrote login/register/profile pages + plugins and registered @zitadel/sdk-nuxt in nuxt.config.*."
1948
+ detail: "Wrote landing/login/register/profile pages + plugins and registered @zitadel/sdk-nuxt in nuxt.config.*."
1805
1949
  };
1806
1950
  }
1807
1951
  };
@@ -1809,9 +1953,13 @@ var NuxtPatcher = class extends AbstractRulePatcher {
1809
1953
  //#region src/lib/orca/patchers/rule/vite-support.ts
1810
1954
  /**
1811
1955
  * Shared Vite dev-server proxy merged into the project's Vite config for the SPA
1812
- * frameworks (React, Vue). It forwards same-origin `/__nextgen/*` calls to the
1813
- * backend, strips the prefix, and attaches the project's `sk_<project_id>`
1814
- * bearer (read from `ZITADEL_PROJECT_ID` in the env) to every proxied request.
1956
+ * frameworks (React, Vue, Solid, Svelte, Qwik). It forwards same-origin
1957
+ * `/__nextgen/*` calls to the
1958
+ * backend, strips the prefix, and attaches the project's service-key secret
1959
+ * (read from `ZITADEL_PROJECT_SECRET` in `.env.local`) as the bearer on every
1960
+ * proxied request. The secret stays server-side: Vite only exposes vars with the
1961
+ * configured `envPrefix` (default `VITE_`) to client bundles, so this server-only
1962
+ * key never leaks into the browser.
1815
1963
  */
1816
1964
  function proxyEntryCode(server) {
1817
1965
  return `{
@@ -1819,11 +1967,11 @@ function proxyEntryCode(server) {
1819
1967
  changeOrigin: false,
1820
1968
  rewrite: (path) => path.replace(/^\\${PROXY_PATH}/, "").replace(/^(?!\\/)/, "/"),
1821
1969
  configure: (proxy) => {
1822
- const projectId = loadEnv("development", process.cwd(), "ZITADEL_").ZITADEL_PROJECT_ID;
1823
- if (!projectId) {
1824
- throw new Error("ZITADEL_PROJECT_ID is not set; add it to .env.local (zitadel setup writes it).");
1970
+ const secret = loadEnv("development", process.cwd(), "ZITADEL_").ZITADEL_PROJECT_SECRET;
1971
+ if (!secret) {
1972
+ throw new Error("ZITADEL_PROJECT_SECRET is not set; add it to .env.local (zitadel setup writes it).");
1825
1973
  }
1826
- const bearer = \`Bearer sk_\${projectId}\`;
1974
+ const bearer = \`Bearer \${secret}\`;
1827
1975
  proxy.on("proxyReq", (proxyReq) => {
1828
1976
  proxyReq.setHeader("authorization", bearer);
1829
1977
  });
@@ -1891,17 +2039,143 @@ function buildViteProxyOp(devPort, server) {
1891
2039
  };
1892
2040
  }
1893
2041
  //#endregion
2042
+ //#region src/lib/orca/patchers/rule/qwik/templates.ts
2043
+ /**
2044
+ * The managed `src/app.tsx`: a minimal path-based router that renders the
2045
+ * `@zitadel/sdk-qwik` widgets — a landing chooser at `/`, login at `/login`,
2046
+ * register at `/register`, and the logout widget at `/profile`. Exports a named `App`
2047
+ * (`component$`) to match the create-vite Qwik entry (`main.tsx` imports
2048
+ * `{ App }`). The project id comes from `VITE_ZITADEL_PROJECT_ID`. No secret
2049
+ * reaches the browser: the dev proxy in `vite.config.*` attaches the project
2050
+ * service-key secret (from `ZITADEL_PROJECT_SECRET`) server-side.
2051
+ */
2052
+ function appTemplate$4() {
2053
+ return `${MANAGED_MARKER}
2054
+ import { component$ } from "@builder.io/qwik";
2055
+ import { ZitadelLogin, ZitadelLogout, configureZitadel } from "@zitadel/sdk-qwik";
2056
+
2057
+ const project = configureZitadel({
2058
+ projectId: import.meta.env.VITE_ZITADEL_PROJECT_ID,
2059
+ proxyPath: "${PROXY_PATH}",
2060
+ });
2061
+
2062
+ export const App = component$(() => {
2063
+ const path = window.location.pathname;
2064
+
2065
+ if (path === "/") {
2066
+ return (
2067
+ <main style={{ position: "fixed", inset: "0", padding: "48px", boxSizing: "border-box", display: "flex", alignItems: "center", justifyContent: "center", background: "#0f0f11", colorScheme: "dark", color: "#f4f4f6", fontFamily: "system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif", lineHeight: "1.5", letterSpacing: "normal", textAlign: "center" }}>
2068
+ <section style={{ width: "100%", maxWidth: "560px" }}>
2069
+ <p style={{ margin: "0 0 12px", color: "#9ca3af", fontSize: "14px" }}>Zitadel auth</p>
2070
+ <h1 style={{ margin: "0 0 24px", fontSize: "32px", lineHeight: "1.15", fontWeight: "600", color: "#f4f4f6" }}>Sign in, create an account, or open your profile.</h1>
2071
+ <div style={{ display: "flex", flexWrap: "wrap", gap: "12px", justifyContent: "center" }}>
2072
+ <a href="/login" style={{ padding: "10px 16px", borderRadius: "8px", background: "#f4f4f6", color: "#0f0f11", textDecoration: "none", fontWeight: "600", fontSize: "14px" }}>Sign in</a>
2073
+ <a href="/register" style={{ padding: "10px 16px", borderRadius: "8px", border: "1px solid #3f3f46", color: "#f4f4f6", textDecoration: "none", fontWeight: "600", fontSize: "14px" }}>Create account</a>
2074
+ <a href="/profile" style={{ padding: "10px 16px", borderRadius: "8px", border: "1px solid #3f3f46", color: "#f4f4f6", textDecoration: "none", fontWeight: "600", fontSize: "14px" }}>Profile</a>
2075
+ </div>
2076
+ </section>
2077
+ </main>
2078
+ );
2079
+ }
2080
+ if (path.startsWith("/profile")) {
2081
+ return (
2082
+ <div style={{ position: "fixed", inset: "0", overflow: "auto", background: "#0f0f11", colorScheme: "dark" }}>
2083
+ <ZitadelLogout project={project} postSignOutUrl="/login" />
2084
+ </div>
2085
+ );
2086
+ }
2087
+ if (path.startsWith("/register")) {
2088
+ return (
2089
+ <div style={{ position: "fixed", inset: "0", overflow: "auto", background: "#0f0f11", colorScheme: "dark" }}>
2090
+ <ZitadelLogin project={project} purpose="register" postSignInUrl="/profile" />
2091
+ </div>
2092
+ );
2093
+ }
2094
+ return (
2095
+ <div style={{ position: "fixed", inset: "0", overflow: "auto", background: "#0f0f11", colorScheme: "dark" }}>
2096
+ <ZitadelLogin project={project} purpose="login" postSignInUrl="/profile" />
2097
+ </div>
2098
+ );
2099
+ });
2100
+ `;
2101
+ }
2102
+ //#endregion
2103
+ //#region src/lib/orca/patchers/rule/qwik/index.ts
2104
+ const SDK_DEPENDENCY$4 = "@zitadel/sdk-qwik";
2105
+ /**
2106
+ * Rule-based patcher for a Vite + Qwik single-page app. Inherits the shared
2107
+ * `.zitadel/` base files from {@link AbstractRulePatcher} and contributes the
2108
+ * managed `src/app.tsx` auth entry, a non-destructive `vite.config.*` merge
2109
+ * that adds the `/__nextgen` dev proxy (attaching the project secret from
2110
+ * `ZITADEL_PROJECT_SECRET` to every proxied request), the `VITE_`-prefixed
2111
+ * project id, and the SDK dep.
2112
+ *
2113
+ * The create-vite Qwik template uses a lowercase `src/app.tsx` exporting a named
2114
+ * `App` (mounted by `main.tsx`), so this patcher writes that exact entry. Unlike
2115
+ * Next.js — whose middleware runs the proxy server-side — a SPA has no server,
2116
+ * so the dev proxy stands in for `@zitadel/edge-proxy` locally. Production
2117
+ * deployments still need that proxy.
2118
+ */
2119
+ var QwikPatcher = class extends AbstractRulePatcher {
2120
+ canPatch(framework) {
2121
+ return framework === "qwik";
2122
+ }
2123
+ viteProxyOp(devPort, server) {
2124
+ return buildViteProxyOp(devPort, server);
2125
+ }
2126
+ routeOps(ctx) {
2127
+ return [
2128
+ {
2129
+ kind: "write",
2130
+ path: "src/app.tsx",
2131
+ contents: appTemplate$4()
2132
+ },
2133
+ this.viteProxyOp(ctx.framework.devPort, ctx.server),
2134
+ {
2135
+ kind: "merge-env",
2136
+ path: ".env.example",
2137
+ entries: { VITE_ZITADEL_PROJECT_ID: "" }
2138
+ },
2139
+ {
2140
+ kind: "merge-env",
2141
+ path: ".env.local",
2142
+ entries: { VITE_ZITADEL_PROJECT_ID: ctx.project.id }
2143
+ },
2144
+ {
2145
+ kind: "add-dep",
2146
+ name: SDK_DEPENDENCY$4,
2147
+ version: npmDistTagForCliVersion(ctx.cliVersion)
2148
+ }
2149
+ ];
2150
+ }
2151
+ routeFiles(_view) {
2152
+ return ["src/app.tsx"];
2153
+ }
2154
+ routeDeps(_view) {
2155
+ return [SDK_DEPENDENCY$4];
2156
+ }
2157
+ routeConfigEdits(_view) {
2158
+ return ["vite.config.*"];
2159
+ }
2160
+ summary(_ctx) {
2161
+ return {
2162
+ title: "Qwik (Vite) integration",
2163
+ detail: "Wrote src/app.tsx auth entry and merged the /__nextgen dev proxy into vite.config.*."
2164
+ };
2165
+ }
2166
+ };
2167
+ //#endregion
1894
2168
  //#region src/lib/orca/patchers/rule/react/templates.ts
1895
2169
  /**
1896
2170
  * The managed `src/App.tsx`: a minimal path-based router that renders the
1897
- * `@zitadel/sdk-react` widgets — login at `/login` (and `/`), register at
1898
- * `/register`, and the logout widget at `/profile`. The project id comes from
2171
+ * `@zitadel/sdk-react` widgets — a landing chooser at `/`, login at `/login`,
2172
+ * register at `/register`, and the logout widget at `/profile`. The project id comes from
1899
2173
  * `VITE_ZITADEL_PROJECT_ID` (Vite only exposes `VITE_`-prefixed env to the
1900
2174
  * client). No secret reaches the browser: the dev proxy in `vite.config.*`
1901
- * attaches the `sk_<project_id>` bearer (derived from the public project id)
2175
+ * attaches the project service-key secret (from `ZITADEL_PROJECT_SECRET`)
1902
2176
  * server-side.
1903
2177
  */
1904
- function appTemplate$1() {
2178
+ function appTemplate$3() {
1905
2179
  return `${MANAGED_MARKER}
1906
2180
  import { ZitadelLogin, ZitadelLogout, configureZitadel } from "@zitadel/sdk-react";
1907
2181
 
@@ -1913,25 +2187,52 @@ const project = configureZitadel({
1913
2187
  export default function App() {
1914
2188
  const path = window.location.pathname;
1915
2189
 
2190
+ if (path === "/") {
2191
+ return (
2192
+ <main style={{ position: "fixed", inset: 0, padding: "48px", boxSizing: "border-box", display: "flex", alignItems: "center", justifyContent: "center", background: "#0f0f11", colorScheme: "dark", color: "#f4f4f6", fontFamily: "system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif", lineHeight: 1.5, letterSpacing: "normal", textAlign: "center" }}>
2193
+ <section style={{ width: "100%", maxWidth: "560px" }}>
2194
+ <p style={{ margin: "0 0 12px", color: "#9ca3af", fontSize: "14px" }}>Zitadel auth</p>
2195
+ <h1 style={{ margin: "0 0 24px", fontSize: "32px", lineHeight: 1.15, fontWeight: 600, color: "#f4f4f6" }}>Sign in, create an account, or open your profile.</h1>
2196
+ <div style={{ display: "flex", flexWrap: "wrap", gap: "12px", justifyContent: "center" }}>
2197
+ <a href="/login" style={{ padding: "10px 16px", borderRadius: "8px", background: "#f4f4f6", color: "#0f0f11", textDecoration: "none", fontWeight: 600, fontSize: "14px" }}>Sign in</a>
2198
+ <a href="/register" style={{ padding: "10px 16px", borderRadius: "8px", border: "1px solid #3f3f46", color: "#f4f4f6", textDecoration: "none", fontWeight: 600, fontSize: "14px" }}>Create account</a>
2199
+ <a href="/profile" style={{ padding: "10px 16px", borderRadius: "8px", border: "1px solid #3f3f46", color: "#f4f4f6", textDecoration: "none", fontWeight: 600, fontSize: "14px" }}>Profile</a>
2200
+ </div>
2201
+ </section>
2202
+ </main>
2203
+ );
2204
+ }
1916
2205
  if (path.startsWith("/profile")) {
1917
- return <ZitadelLogout project={project} postSignOutUrl="/login" />;
2206
+ return (
2207
+ <div style={{ position: "fixed", inset: 0, overflow: "auto", background: "#0f0f11", colorScheme: "dark" }}>
2208
+ <ZitadelLogout project={project} postSignOutUrl="/login" />
2209
+ </div>
2210
+ );
1918
2211
  }
1919
2212
  if (path.startsWith("/register")) {
1920
- return <ZitadelLogin project={project} purpose="register" postSignInUrl="/profile" />;
2213
+ return (
2214
+ <div style={{ position: "fixed", inset: 0, overflow: "auto", background: "#0f0f11", colorScheme: "dark" }}>
2215
+ <ZitadelLogin project={project} purpose="register" postSignInUrl="/profile" />
2216
+ </div>
2217
+ );
1921
2218
  }
1922
- return <ZitadelLogin project={project} purpose="login" postSignInUrl="/profile" />;
2219
+ return (
2220
+ <div style={{ position: "fixed", inset: 0, overflow: "auto", background: "#0f0f11", colorScheme: "dark" }}>
2221
+ <ZitadelLogin project={project} purpose="login" postSignInUrl="/profile" />
2222
+ </div>
2223
+ );
1923
2224
  }
1924
2225
  `;
1925
2226
  }
1926
2227
  //#endregion
1927
2228
  //#region src/lib/orca/patchers/rule/react/index.ts
1928
- const SDK_DEPENDENCY$1 = "@zitadel/sdk-react";
2229
+ const SDK_DEPENDENCY$3 = "@zitadel/sdk-react";
1929
2230
  /**
1930
2231
  * Rule-based patcher for a Vite + React single-page app. Inherits the shared
1931
2232
  * `.zitadel/` base files from {@link AbstractRulePatcher} and contributes the
1932
2233
  * managed `src/App.tsx` auth entry, a non-destructive `vite.config.*` merge
1933
- * that adds the `/__nextgen` dev proxy (attaching the `sk_<project_id>` bearer
1934
- * from `ZITADEL_PROJECT_ID` to every proxied request), the `VITE_`-prefixed
2234
+ * that adds the `/__nextgen` dev proxy (attaching the project secret from
2235
+ * `ZITADEL_PROJECT_SECRET` to every proxied request), the `VITE_`-prefixed
1935
2236
  * project id, and the SDK dep.
1936
2237
  *
1937
2238
  * Unlike Next.js — whose middleware runs the proxy and token exchange
@@ -1950,7 +2251,7 @@ var ReactPatcher = class extends AbstractRulePatcher {
1950
2251
  {
1951
2252
  kind: "write",
1952
2253
  path: "src/App.tsx",
1953
- contents: appTemplate$1()
2254
+ contents: appTemplate$3()
1954
2255
  },
1955
2256
  this.viteProxyOp(ctx.framework.devPort, ctx.server),
1956
2257
  {
@@ -1965,7 +2266,7 @@ var ReactPatcher = class extends AbstractRulePatcher {
1965
2266
  },
1966
2267
  {
1967
2268
  kind: "add-dep",
1968
- name: SDK_DEPENDENCY$1,
2269
+ name: SDK_DEPENDENCY$3,
1969
2270
  version: npmDistTagForCliVersion(ctx.cliVersion)
1970
2271
  }
1971
2272
  ];
@@ -1974,7 +2275,7 @@ var ReactPatcher = class extends AbstractRulePatcher {
1974
2275
  return ["src/App.tsx"];
1975
2276
  }
1976
2277
  routeDeps(_view) {
1977
- return [SDK_DEPENDENCY$1];
2278
+ return [SDK_DEPENDENCY$3];
1978
2279
  }
1979
2280
  routeConfigEdits(_view) {
1980
2281
  return ["vite.config.*"];
@@ -1987,15 +2288,252 @@ var ReactPatcher = class extends AbstractRulePatcher {
1987
2288
  }
1988
2289
  };
1989
2290
  //#endregion
2291
+ //#region src/lib/orca/patchers/rule/solid/templates.ts
2292
+ /**
2293
+ * The managed `src/App.tsx`: a minimal path-based router that renders the
2294
+ * `@zitadel/sdk-solid` widgets — a landing chooser at `/`, login at `/login`,
2295
+ * register at `/register`, and the logout widget at `/profile`. The project id comes from
2296
+ * `VITE_ZITADEL_PROJECT_ID` (Vite only exposes `VITE_`-prefixed env to the
2297
+ * client). No secret reaches the browser: the dev proxy in `vite.config.*`
2298
+ * attaches the project service-key secret (from `ZITADEL_PROJECT_SECRET`)
2299
+ * server-side.
2300
+ */
2301
+ function appTemplate$2() {
2302
+ return `${MANAGED_MARKER}
2303
+ import { ZitadelLogin, ZitadelLogout, configureZitadel } from "@zitadel/sdk-solid";
2304
+
2305
+ const project = configureZitadel({
2306
+ projectId: import.meta.env.VITE_ZITADEL_PROJECT_ID,
2307
+ proxyPath: "${PROXY_PATH}",
2308
+ });
2309
+
2310
+ export default function App() {
2311
+ const path = window.location.pathname;
2312
+
2313
+ if (path === "/") {
2314
+ return (
2315
+ <main style="position:fixed;inset:0;padding:48px;box-sizing:border-box;display:flex;align-items:center;justify-content:center;background:#0f0f11;color-scheme:dark;color:#f4f4f6;font-family:system-ui,-apple-system,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;line-height:1.5;letter-spacing:normal;text-align:center">
2316
+ <section style="width:100%;max-width:560px">
2317
+ <p style="margin:0 0 12px;color:#9ca3af;font-size:14px">Zitadel auth</p>
2318
+ <h1 style="margin:0 0 24px;font-size:32px;line-height:1.15;font-weight:600;color:#f4f4f6">Sign in, create an account, or open your profile.</h1>
2319
+ <div style="display:flex;flex-wrap:wrap;gap:12px;justify-content:center">
2320
+ <a href="/login" style="padding:10px 16px;border-radius:8px;background:#f4f4f6;color:#0f0f11;text-decoration:none;font-weight:600;font-size:14px">Sign in</a>
2321
+ <a href="/register" style="padding:10px 16px;border-radius:8px;border:1px solid #3f3f46;color:#f4f4f6;text-decoration:none;font-weight:600;font-size:14px">Create account</a>
2322
+ <a href="/profile" style="padding:10px 16px;border-radius:8px;border:1px solid #3f3f46;color:#f4f4f6;text-decoration:none;font-weight:600;font-size:14px">Profile</a>
2323
+ </div>
2324
+ </section>
2325
+ </main>
2326
+ );
2327
+ }
2328
+ if (path.startsWith("/profile")) {
2329
+ return (
2330
+ <div style="position:fixed;inset:0;overflow:auto;background:#0f0f11;color-scheme:dark">
2331
+ <ZitadelLogout project={project} postSignOutUrl="/login" />
2332
+ </div>
2333
+ );
2334
+ }
2335
+ if (path.startsWith("/register")) {
2336
+ return (
2337
+ <div style="position:fixed;inset:0;overflow:auto;background:#0f0f11;color-scheme:dark">
2338
+ <ZitadelLogin project={project} purpose="register" postSignInUrl="/profile" />
2339
+ </div>
2340
+ );
2341
+ }
2342
+ return (
2343
+ <div style="position:fixed;inset:0;overflow:auto;background:#0f0f11;color-scheme:dark">
2344
+ <ZitadelLogin project={project} purpose="login" postSignInUrl="/profile" />
2345
+ </div>
2346
+ );
2347
+ }
2348
+ `;
2349
+ }
2350
+ //#endregion
2351
+ //#region src/lib/orca/patchers/rule/solid/index.ts
2352
+ const SDK_DEPENDENCY$2 = "@zitadel/sdk-solid";
2353
+ /**
2354
+ * Rule-based patcher for a Vite + Solid single-page app. Inherits the shared
2355
+ * `.zitadel/` base files from {@link AbstractRulePatcher} and contributes the
2356
+ * managed `src/App.tsx` auth entry, a non-destructive `vite.config.*` merge
2357
+ * that adds the `/__nextgen` dev proxy (attaching the project secret from
2358
+ * `ZITADEL_PROJECT_SECRET` to every proxied request), the `VITE_`-prefixed
2359
+ * project id, and the SDK dep.
2360
+ *
2361
+ * Unlike Next.js — whose middleware runs the proxy and token exchange
2362
+ * server-side — a SPA has no server, so the dev proxy stands in for
2363
+ * `@zitadel/edge-proxy` locally. Production deployments still need that proxy.
2364
+ */
2365
+ var SolidPatcher = class extends AbstractRulePatcher {
2366
+ canPatch(framework) {
2367
+ return framework === "solid";
2368
+ }
2369
+ viteProxyOp(devPort, server) {
2370
+ return buildViteProxyOp(devPort, server);
2371
+ }
2372
+ routeOps(ctx) {
2373
+ return [
2374
+ {
2375
+ kind: "write",
2376
+ path: "src/App.tsx",
2377
+ contents: appTemplate$2()
2378
+ },
2379
+ this.viteProxyOp(ctx.framework.devPort, ctx.server),
2380
+ {
2381
+ kind: "merge-env",
2382
+ path: ".env.example",
2383
+ entries: { VITE_ZITADEL_PROJECT_ID: "" }
2384
+ },
2385
+ {
2386
+ kind: "merge-env",
2387
+ path: ".env.local",
2388
+ entries: { VITE_ZITADEL_PROJECT_ID: ctx.project.id }
2389
+ },
2390
+ {
2391
+ kind: "add-dep",
2392
+ name: SDK_DEPENDENCY$2,
2393
+ version: npmDistTagForCliVersion(ctx.cliVersion)
2394
+ }
2395
+ ];
2396
+ }
2397
+ routeFiles(_view) {
2398
+ return ["src/App.tsx"];
2399
+ }
2400
+ routeDeps(_view) {
2401
+ return [SDK_DEPENDENCY$2];
2402
+ }
2403
+ routeConfigEdits(_view) {
2404
+ return ["vite.config.*"];
2405
+ }
2406
+ summary(_ctx) {
2407
+ return {
2408
+ title: "Solid (Vite) integration",
2409
+ detail: "Wrote src/App.tsx auth entry and merged the /__nextgen dev proxy into vite.config.*."
2410
+ };
2411
+ }
2412
+ };
2413
+ //#endregion
2414
+ //#region src/lib/orca/patchers/rule/svelte/templates.ts
2415
+ /**
2416
+ * The managed `src/App.svelte`: a minimal path-based router that renders the
2417
+ * `@zitadel/sdk-svelte` widgets — a landing chooser at `/`, login at `/login`,
2418
+ * register at `/register`, and the logout widget at `/profile`. The managed marker lives in
2419
+ * the `<script lang="ts">` block (a JS comment) so eject/doctor stay
2420
+ * marker-aware. The project id comes from `VITE_ZITADEL_PROJECT_ID`. No secret
2421
+ * reaches the browser: the dev proxy in `vite.config.*` attaches the project
2422
+ * service-key secret (from `ZITADEL_PROJECT_SECRET`) server-side.
2423
+ */
2424
+ function appTemplate$1() {
2425
+ return `<script lang="ts">
2426
+ ${MANAGED_MARKER}
2427
+ import { ZitadelLogin, ZitadelLogout, configureZitadel } from "@zitadel/sdk-svelte";
2428
+
2429
+ const project = configureZitadel({
2430
+ projectId: import.meta.env.VITE_ZITADEL_PROJECT_ID,
2431
+ proxyPath: "${PROXY_PATH}",
2432
+ });
2433
+
2434
+ const path = window.location.pathname;
2435
+ <\/script>
2436
+
2437
+ {#if path === "/"}
2438
+ <main style="position:fixed;inset:0;padding:48px;box-sizing:border-box;display:flex;align-items:center;justify-content:center;background:#0f0f11;color-scheme:dark;color:#f4f4f6;font-family:system-ui,-apple-system,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;line-height:1.5;letter-spacing:normal;text-align:center">
2439
+ <section style="width:100%;max-width:560px">
2440
+ <p style="margin:0 0 12px;color:#9ca3af;font-size:14px">Zitadel auth</p>
2441
+ <h1 style="margin:0 0 24px;font-size:32px;line-height:1.15;font-weight:600;color:#f4f4f6">Sign in, create an account, or open your profile.</h1>
2442
+ <div style="display:flex;flex-wrap:wrap;gap:12px;justify-content:center">
2443
+ <a href="/login" style="padding:10px 16px;border-radius:8px;background:#f4f4f6;color:#0f0f11;text-decoration:none;font-weight:600;font-size:14px">Sign in</a>
2444
+ <a href="/register" style="padding:10px 16px;border-radius:8px;border:1px solid #3f3f46;color:#f4f4f6;text-decoration:none;font-weight:600;font-size:14px">Create account</a>
2445
+ <a href="/profile" style="padding:10px 16px;border-radius:8px;border:1px solid #3f3f46;color:#f4f4f6;text-decoration:none;font-weight:600;font-size:14px">Profile</a>
2446
+ </div>
2447
+ </section>
2448
+ </main>
2449
+ {:else if path.startsWith("/profile")}
2450
+ <div style="position:fixed;inset:0;overflow:auto;background:#0f0f11;color-scheme:dark">
2451
+ <ZitadelLogout {project} postSignOutUrl="/login" />
2452
+ </div>
2453
+ {:else if path.startsWith("/register")}
2454
+ <div style="position:fixed;inset:0;overflow:auto;background:#0f0f11;color-scheme:dark">
2455
+ <ZitadelLogin {project} purpose="register" postSignInUrl="/profile" />
2456
+ </div>
2457
+ {:else}
2458
+ <div style="position:fixed;inset:0;overflow:auto;background:#0f0f11;color-scheme:dark">
2459
+ <ZitadelLogin {project} purpose="login" postSignInUrl="/profile" />
2460
+ </div>
2461
+ {/if}
2462
+ `;
2463
+ }
2464
+ //#endregion
2465
+ //#region src/lib/orca/patchers/rule/svelte/index.ts
2466
+ const SDK_DEPENDENCY$1 = "@zitadel/sdk-svelte";
2467
+ /**
2468
+ * Rule-based patcher for a Vite + Svelte single-page app. Inherits the shared
2469
+ * `.zitadel/` base files from {@link AbstractRulePatcher} and contributes the
2470
+ * managed `src/App.svelte` auth entry, a non-destructive `vite.config.*` merge
2471
+ * that adds the `/__nextgen` dev proxy (attaching the project secret from
2472
+ * `ZITADEL_PROJECT_SECRET` to every proxied request), the `VITE_`-prefixed
2473
+ * project id, and the SDK dep.
2474
+ *
2475
+ * Unlike Next.js — whose middleware runs the proxy and token exchange
2476
+ * server-side — a SPA has no server, so the dev proxy stands in for
2477
+ * `@zitadel/edge-proxy` locally. Production deployments still need that proxy.
2478
+ */
2479
+ var SveltePatcher = class extends AbstractRulePatcher {
2480
+ canPatch(framework) {
2481
+ return framework === "svelte";
2482
+ }
2483
+ viteProxyOp(devPort, server) {
2484
+ return buildViteProxyOp(devPort, server);
2485
+ }
2486
+ routeOps(ctx) {
2487
+ return [
2488
+ {
2489
+ kind: "write",
2490
+ path: "src/App.svelte",
2491
+ contents: appTemplate$1()
2492
+ },
2493
+ this.viteProxyOp(ctx.framework.devPort, ctx.server),
2494
+ {
2495
+ kind: "merge-env",
2496
+ path: ".env.example",
2497
+ entries: { VITE_ZITADEL_PROJECT_ID: "" }
2498
+ },
2499
+ {
2500
+ kind: "merge-env",
2501
+ path: ".env.local",
2502
+ entries: { VITE_ZITADEL_PROJECT_ID: ctx.project.id }
2503
+ },
2504
+ {
2505
+ kind: "add-dep",
2506
+ name: SDK_DEPENDENCY$1,
2507
+ version: npmDistTagForCliVersion(ctx.cliVersion)
2508
+ }
2509
+ ];
2510
+ }
2511
+ routeFiles(_view) {
2512
+ return ["src/App.svelte"];
2513
+ }
2514
+ routeDeps(_view) {
2515
+ return [SDK_DEPENDENCY$1];
2516
+ }
2517
+ routeConfigEdits(_view) {
2518
+ return ["vite.config.*"];
2519
+ }
2520
+ summary(_ctx) {
2521
+ return {
2522
+ title: "Svelte (Vite) integration",
2523
+ detail: "Wrote src/App.svelte auth entry and merged the /__nextgen dev proxy into vite.config.*."
2524
+ };
2525
+ }
2526
+ };
2527
+ //#endregion
1990
2528
  //#region src/lib/orca/patchers/rule/vue/templates.ts
1991
2529
  /**
1992
2530
  * The managed `src/App.vue`: a minimal path-based router that renders the
1993
- * `@zitadel/sdk-vue` widgets — login at `/login` (and `/`), register at
1994
- * `/register`, and the logout widget at `/profile`. The managed marker lives in
2531
+ * `@zitadel/sdk-vue` widgets — a landing chooser at `/`, login at `/login`,
2532
+ * register at `/register`, and the logout widget at `/profile`. The managed marker lives in
1995
2533
  * the `<script setup>` block (a JS comment) so eject/doctor stay marker-aware.
1996
2534
  * The project id comes from `VITE_ZITADEL_PROJECT_ID`. No secret reaches the
1997
- * browser: the dev proxy in `vite.config.*` attaches the `sk_<project_id>`
1998
- * bearer (derived from the public project id) server-side.
2535
+ * browser: the dev proxy in `vite.config.*` attaches the project service-key
2536
+ * secret (from `ZITADEL_PROJECT_SECRET`) server-side.
1999
2537
  */
2000
2538
  function appTemplate() {
2001
2539
  return `<script setup lang="ts">
@@ -2011,18 +2549,35 @@ const path = window.location.pathname;
2011
2549
  <\/script>
2012
2550
 
2013
2551
  <template>
2014
- <ZitadelLogout
2015
- v-if="path.startsWith('/profile')"
2016
- :project="project"
2017
- postSignOutUrl="/login"
2018
- />
2019
- <ZitadelLogin
2552
+ <main
2553
+ v-if="path === '/'"
2554
+ style="position:fixed;inset:0;padding:48px;box-sizing:border-box;display:flex;align-items:center;justify-content:center;background:#0f0f11;color-scheme:dark;color:#f4f4f6;font-family:system-ui,-apple-system,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;line-height:1.5;letter-spacing:normal;text-align:center"
2555
+ >
2556
+ <section style="width:100%;max-width:560px">
2557
+ <p style="margin:0 0 12px;color:#9ca3af;font-size:14px">Zitadel auth</p>
2558
+ <h1 style="margin:0 0 24px;font-size:32px;line-height:1.15;font-weight:600;color:#f4f4f6">Sign in, create an account, or open your profile.</h1>
2559
+ <div style="display:flex;flex-wrap:wrap;gap:12px;justify-content:center">
2560
+ <a href="/login" style="padding:10px 16px;border-radius:8px;background:#f4f4f6;color:#0f0f11;text-decoration:none;font-weight:600;font-size:14px">Sign in</a>
2561
+ <a href="/register" style="padding:10px 16px;border-radius:8px;border:1px solid #3f3f46;color:#f4f4f6;text-decoration:none;font-weight:600;font-size:14px">Create account</a>
2562
+ <a href="/profile" style="padding:10px 16px;border-radius:8px;border:1px solid #3f3f46;color:#f4f4f6;text-decoration:none;font-weight:600;font-size:14px">Profile</a>
2563
+ </div>
2564
+ </section>
2565
+ </main>
2566
+ <div
2567
+ v-else-if="path.startsWith('/profile')"
2568
+ style="position:fixed;inset:0;overflow:auto;background:#0f0f11;color-scheme:dark"
2569
+ >
2570
+ <ZitadelLogout :project="project" postSignOutUrl="/login" />
2571
+ </div>
2572
+ <div
2020
2573
  v-else-if="path.startsWith('/register')"
2021
- :project="project"
2022
- purpose="register"
2023
- postSignInUrl="/profile"
2024
- />
2025
- <ZitadelLogin v-else :project="project" purpose="login" postSignInUrl="/profile" />
2574
+ style="position:fixed;inset:0;overflow:auto;background:#0f0f11;color-scheme:dark"
2575
+ >
2576
+ <ZitadelLogin :project="project" purpose="register" postSignInUrl="/profile" />
2577
+ </div>
2578
+ <div v-else style="position:fixed;inset:0;overflow:auto;background:#0f0f11;color-scheme:dark">
2579
+ <ZitadelLogin :project="project" purpose="login" postSignInUrl="/profile" />
2580
+ </div>
2026
2581
  </template>
2027
2582
  `;
2028
2583
  }
@@ -2033,8 +2588,8 @@ const SDK_DEPENDENCY = "@zitadel/sdk-vue";
2033
2588
  * Rule-based patcher for a Vite + Vue single-page app. Inherits the shared
2034
2589
  * `.zitadel/` base files from {@link AbstractRulePatcher} and contributes the
2035
2590
  * managed `src/App.vue` auth entry, a non-destructive `vite.config.*` merge
2036
- * that adds the `/__nextgen` dev proxy (attaching the `sk_<project_id>` bearer
2037
- * from `ZITADEL_PROJECT_ID` to every proxied request), the `VITE_`-prefixed
2591
+ * that adds the `/__nextgen` dev proxy (attaching the project secret from
2592
+ * `ZITADEL_PROJECT_SECRET` to every proxied request), the `VITE_`-prefixed
2038
2593
  * project id, and the SDK dep.
2039
2594
  */
2040
2595
  var VuePatcher = class extends AbstractRulePatcher {
@@ -2101,6 +2656,9 @@ const patchers = [
2101
2656
  new NuxtPatcher(),
2102
2657
  new ReactPatcher(),
2103
2658
  new VuePatcher(),
2659
+ new SolidPatcher(),
2660
+ new SveltePatcher(),
2661
+ new QwikPatcher(),
2104
2662
  new AngularPatcher()
2105
2663
  ];
2106
2664
  //#endregion
@@ -2262,6 +2820,36 @@ var NuxtScaffolder = class extends AbstractCLIScaffolder {
2262
2820
  }
2263
2821
  };
2264
2822
  //#endregion
2823
+ //#region src/lib/orca/scaffolders/qwik.ts
2824
+ /**
2825
+ * Scaffolds a new Vite + Qwik (TypeScript) single-page app with `create-vite`,
2826
+ * then removes the starter `app.tsx`/`app.css` demo so the patcher can write the
2827
+ * managed `src/app.tsx` without colliding with boilerplate. The create-vite Qwik
2828
+ * template uses a lowercase `app.tsx` (named `App` export, mounted by `main.tsx`)
2829
+ * — the patched file keeps that same entry.
2830
+ */
2831
+ var QwikScaffolder = class extends AbstractCLIScaffolder {
2832
+ displayName = "Qwik (Vite)";
2833
+ supportedFrameworks = ["qwik"];
2834
+ async scaffold(cwd, _framework) {
2835
+ this.runCommand("npm", [
2836
+ "create",
2837
+ "vite@latest",
2838
+ ".",
2839
+ "--",
2840
+ "--template",
2841
+ "qwik-ts"
2842
+ ], cwd);
2843
+ await rm(join(cwd, "src/app.tsx"), { force: true });
2844
+ await rm(join(cwd, "src/app.css"), { force: true });
2845
+ this.runCommand("npm", [
2846
+ "pkg",
2847
+ "set",
2848
+ "devDependencies.vite=^7.3.5"
2849
+ ], cwd);
2850
+ }
2851
+ };
2852
+ //#endregion
2265
2853
  //#region src/lib/orca/scaffolders/react.ts
2266
2854
  /**
2267
2855
  * Scaffolds a new Vite + React (TypeScript) single-page app with `create-vite`,
@@ -2286,6 +2874,55 @@ var ReactScaffolder = class extends AbstractCLIScaffolder {
2286
2874
  }
2287
2875
  };
2288
2876
  //#endregion
2877
+ //#region src/lib/orca/scaffolders/solid.ts
2878
+ /**
2879
+ * Scaffolds a new Vite + Solid (TypeScript) single-page app with `create-vite`,
2880
+ * then removes the starter `App.tsx`/`App.css` demo so the patcher can write the
2881
+ * managed `src/App.tsx` without colliding with boilerplate. `index.css` and
2882
+ * `index.tsx` are left in place — the patched `App.tsx` keeps the same entry.
2883
+ */
2884
+ var SolidScaffolder = class extends AbstractCLIScaffolder {
2885
+ displayName = "Solid (Vite)";
2886
+ supportedFrameworks = ["solid"];
2887
+ async scaffold(cwd, _framework) {
2888
+ this.runCommand("npm", [
2889
+ "create",
2890
+ "vite@latest",
2891
+ ".",
2892
+ "--",
2893
+ "--template",
2894
+ "solid-ts"
2895
+ ], cwd);
2896
+ await rm(join(cwd, "src/App.tsx"), { force: true });
2897
+ await rm(join(cwd, "src/App.css"), { force: true });
2898
+ }
2899
+ };
2900
+ //#endregion
2901
+ //#region src/lib/orca/scaffolders/svelte.ts
2902
+ /**
2903
+ * Scaffolds a new Vite + Svelte (TypeScript) single-page app with `create-vite`,
2904
+ * then removes the starter `App.svelte`/`lib/Counter.svelte` demo so the patcher
2905
+ * can write the managed `src/App.svelte` without colliding with boilerplate.
2906
+ * `app.css` and `main.ts` are left in place — the patched `App.svelte` keeps the
2907
+ * same entry.
2908
+ */
2909
+ var SvelteScaffolder = class extends AbstractCLIScaffolder {
2910
+ displayName = "Svelte (Vite)";
2911
+ supportedFrameworks = ["svelte"];
2912
+ async scaffold(cwd, _framework) {
2913
+ this.runCommand("npm", [
2914
+ "create",
2915
+ "vite@latest",
2916
+ ".",
2917
+ "--",
2918
+ "--template",
2919
+ "svelte-ts"
2920
+ ], cwd);
2921
+ await rm(join(cwd, "src/App.svelte"), { force: true });
2922
+ await rm(join(cwd, "src/lib/Counter.svelte"), { force: true });
2923
+ }
2924
+ };
2925
+ //#endregion
2289
2926
  //#region src/lib/orca/scaffolders/vue.ts
2290
2927
  /**
2291
2928
  * Scaffolds a new Vite + Vue (TypeScript) single-page app with `create-vite`,
@@ -2320,6 +2957,9 @@ const scaffolders = [
2320
2957
  new NuxtScaffolder(),
2321
2958
  new ReactScaffolder(),
2322
2959
  new VueScaffolder(),
2960
+ new SolidScaffolder(),
2961
+ new SvelteScaffolder(),
2962
+ new QwikScaffolder(),
2323
2963
  new AngularScaffolder()
2324
2964
  ];
2325
2965
  //#endregion
@@ -2578,4 +3218,4 @@ function isErrno(error, code) {
2578
3218
  //#endregion
2579
3219
  export { issuerFromPort as i, inspectScaffoldTarget as n, RENDERER_IDS as r, createOrca as t };
2580
3220
 
2581
- //# sourceMappingURL=orca-BoTFU8SI.mjs.map
3221
+ //# sourceMappingURL=orca-DU8myWGm.mjs.map