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

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.
@@ -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:#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">
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">
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">
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");
1012
+
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;
1025
+ }
919
1026
 
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.");
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).");
923
1035
  }
924
- const bearer = \`Bearer sk_\${config.project}\`;
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 [
@@ -1474,18 +1587,18 @@ import Link from "next/link";
1474
1587
 
1475
1588
  export default function Home() {
1476
1589
  return (
1477
- <main style={{ minHeight: "100vh", padding: "48px", display: "flex", alignItems: "center", justifyContent: "center" }}>
1590
+ <main style={{ position: "fixed", inset: 0, padding: "48px", boxSizing: "border-box", display: "flex", alignItems: "center", justifyContent: "center", background: "#0f0f11", color: "#f4f4f6", fontFamily: "system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif", lineHeight: 1.5, letterSpacing: "normal", textAlign: "center" }}>
1478
1591
  <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>
1592
+ <p style={{ margin: "0 0 12px", color: "#9ca3af", fontSize: "14px" }}>Zitadel auth</p>
1593
+ <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
1594
  <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 }}>
1595
+ <Link href="/login" style={{ padding: "10px 16px", borderRadius: "8px", background: "#f4f4f6", color: "#0f0f11", textDecoration: "none", fontWeight: 600, fontSize: "14px" }}>
1483
1596
  Sign in
1484
1597
  </Link>
1485
- <Link href="/register" style={{ padding: "10px 16px", borderRadius: "8px", border: "1px solid #d1d5db", color: "#111827", textDecoration: "none", fontWeight: 600 }}>
1598
+ <Link href="/register" style={{ padding: "10px 16px", borderRadius: "8px", border: "1px solid #3f3f46", color: "#f4f4f6", textDecoration: "none", fontWeight: 600, fontSize: "14px" }}>
1486
1599
  Create account
1487
1600
  </Link>
1488
- <Link href="/profile" style={{ padding: "10px 16px", borderRadius: "8px", border: "1px solid #d1d5db", color: "#111827", textDecoration: "none", fontWeight: 600 }}>
1601
+ <Link href="/profile" style={{ padding: "10px 16px", borderRadius: "8px", border: "1px solid #3f3f46", color: "#f4f4f6", textDecoration: "none", fontWeight: 600, fontSize: "14px" }}>
1489
1602
  Profile
1490
1603
  </Link>
1491
1604
  </div>
@@ -1622,6 +1735,24 @@ body {
1622
1735
  </style>
1623
1736
  `;
1624
1737
  }
1738
+ /** `pages/index.vue` — the landing chooser linking to login/register/profile. */
1739
+ function indexPageTemplate() {
1740
+ return `<!-- ${MANAGED_MARKER} -->
1741
+ <template>
1742
+ <main style="position:fixed;inset:0;padding:48px;box-sizing:border-box;display:flex;align-items:center;justify-content:center;background:#0f0f11;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">
1743
+ <section style="width:100%;max-width:560px">
1744
+ <p style="margin:0 0 12px;color:#9ca3af;font-size:14px">Zitadel auth</p>
1745
+ <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>
1746
+ <div style="display:flex;flex-wrap:wrap;gap:12px;justify-content:center">
1747
+ <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>
1748
+ <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>
1749
+ <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>
1750
+ </div>
1751
+ </section>
1752
+ </main>
1753
+ </template>
1754
+ `;
1755
+ }
1625
1756
  /** A login/register page rendering `<zitadel-login>` inside `<ClientOnly>`. */
1626
1757
  function authPage(purpose) {
1627
1758
  return `<script setup lang="ts">
@@ -1710,7 +1841,7 @@ export default defineNuxtPlugin(() => {
1710
1841
  }
1711
1842
  //#endregion
1712
1843
  //#region src/lib/orca/patchers/rule/nuxt/index.ts
1713
- const SDK_DEPENDENCY$2 = "@zitadel/sdk-nuxt";
1844
+ const SDK_DEPENDENCY$5 = "@zitadel/sdk-nuxt";
1714
1845
  const NUXT_CONFIG_PATHS = configCandidates("nuxt.config");
1715
1846
  /**
1716
1847
  * Rule-based patcher for a Nuxt app. Like Next.js, Nuxt proxies the backend and
@@ -1731,6 +1862,11 @@ var NuxtPatcher = class extends AbstractRulePatcher {
1731
1862
  path: src("app.vue"),
1732
1863
  contents: appVueTemplate()
1733
1864
  },
1865
+ {
1866
+ kind: "write",
1867
+ path: src("pages/index.vue"),
1868
+ contents: indexPageTemplate()
1869
+ },
1734
1870
  {
1735
1871
  kind: "write",
1736
1872
  path: src("pages/login.vue"),
@@ -1776,7 +1912,7 @@ var NuxtPatcher = class extends AbstractRulePatcher {
1776
1912
  },
1777
1913
  {
1778
1914
  kind: "add-dep",
1779
- name: SDK_DEPENDENCY$2,
1915
+ name: SDK_DEPENDENCY$5,
1780
1916
  version: npmDistTagForCliVersion(ctx.cliVersion)
1781
1917
  }
1782
1918
  ];
@@ -1785,6 +1921,7 @@ var NuxtPatcher = class extends AbstractRulePatcher {
1785
1921
  const src = (rel) => join(view.framework.appDir, rel);
1786
1922
  return [
1787
1923
  src("app.vue"),
1924
+ src("pages/index.vue"),
1788
1925
  src("pages/login.vue"),
1789
1926
  src("pages/register.vue"),
1790
1927
  src("pages/profile.vue"),
@@ -1793,7 +1930,7 @@ var NuxtPatcher = class extends AbstractRulePatcher {
1793
1930
  ];
1794
1931
  }
1795
1932
  routeDeps(_view) {
1796
- return [SDK_DEPENDENCY$2];
1933
+ return [SDK_DEPENDENCY$5];
1797
1934
  }
1798
1935
  routeConfigEdits(_view) {
1799
1936
  return ["nuxt.config.*"];
@@ -1801,7 +1938,7 @@ var NuxtPatcher = class extends AbstractRulePatcher {
1801
1938
  summary(_ctx) {
1802
1939
  return {
1803
1940
  title: "Nuxt integration",
1804
- detail: "Wrote login/register/profile pages + plugins and registered @zitadel/sdk-nuxt in nuxt.config.*."
1941
+ detail: "Wrote landing/login/register/profile pages + plugins and registered @zitadel/sdk-nuxt in nuxt.config.*."
1805
1942
  };
1806
1943
  }
1807
1944
  };
@@ -1809,9 +1946,13 @@ var NuxtPatcher = class extends AbstractRulePatcher {
1809
1946
  //#region src/lib/orca/patchers/rule/vite-support.ts
1810
1947
  /**
1811
1948
  * 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.
1949
+ * frameworks (React, Vue, Solid, Svelte, Qwik). It forwards same-origin
1950
+ * `/__nextgen/*` calls to the
1951
+ * backend, strips the prefix, and attaches the project's service-key secret
1952
+ * (read from `ZITADEL_PROJECT_SECRET` in `.env.local`) as the bearer on every
1953
+ * proxied request. The secret stays server-side: Vite only exposes vars with the
1954
+ * configured `envPrefix` (default `VITE_`) to client bundles, so this server-only
1955
+ * key never leaks into the browser.
1815
1956
  */
1816
1957
  function proxyEntryCode(server) {
1817
1958
  return `{
@@ -1819,11 +1960,11 @@ function proxyEntryCode(server) {
1819
1960
  changeOrigin: false,
1820
1961
  rewrite: (path) => path.replace(/^\\${PROXY_PATH}/, "").replace(/^(?!\\/)/, "/"),
1821
1962
  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).");
1963
+ const secret = loadEnv("development", process.cwd(), "ZITADEL_").ZITADEL_PROJECT_SECRET;
1964
+ if (!secret) {
1965
+ throw new Error("ZITADEL_PROJECT_SECRET is not set; add it to .env.local (zitadel setup writes it).");
1825
1966
  }
1826
- const bearer = \`Bearer sk_\${projectId}\`;
1967
+ const bearer = \`Bearer \${secret}\`;
1827
1968
  proxy.on("proxyReq", (proxyReq) => {
1828
1969
  proxyReq.setHeader("authorization", bearer);
1829
1970
  });
@@ -1891,17 +2032,143 @@ function buildViteProxyOp(devPort, server) {
1891
2032
  };
1892
2033
  }
1893
2034
  //#endregion
2035
+ //#region src/lib/orca/patchers/rule/qwik/templates.ts
2036
+ /**
2037
+ * The managed `src/app.tsx`: a minimal path-based router that renders the
2038
+ * `@zitadel/sdk-qwik` widgets — a landing chooser at `/`, login at `/login`,
2039
+ * register at `/register`, and the logout widget at `/profile`. Exports a named `App`
2040
+ * (`component$`) to match the create-vite Qwik entry (`main.tsx` imports
2041
+ * `{ App }`). The project id comes from `VITE_ZITADEL_PROJECT_ID`. No secret
2042
+ * reaches the browser: the dev proxy in `vite.config.*` attaches the project
2043
+ * service-key secret (from `ZITADEL_PROJECT_SECRET`) server-side.
2044
+ */
2045
+ function appTemplate$4() {
2046
+ return `${MANAGED_MARKER}
2047
+ import { component$ } from "@builder.io/qwik";
2048
+ import { ZitadelLogin, ZitadelLogout, configureZitadel } from "@zitadel/sdk-qwik";
2049
+
2050
+ const project = configureZitadel({
2051
+ projectId: import.meta.env.VITE_ZITADEL_PROJECT_ID,
2052
+ proxyPath: "${PROXY_PATH}",
2053
+ });
2054
+
2055
+ export const App = component$(() => {
2056
+ const path = window.location.pathname;
2057
+
2058
+ if (path === "/") {
2059
+ return (
2060
+ <main style={{ position: "fixed", inset: "0", padding: "48px", boxSizing: "border-box", display: "flex", alignItems: "center", justifyContent: "center", background: "#0f0f11", color: "#f4f4f6", fontFamily: "system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif", lineHeight: "1.5", letterSpacing: "normal", textAlign: "center" }}>
2061
+ <section style={{ width: "100%", maxWidth: "560px" }}>
2062
+ <p style={{ margin: "0 0 12px", color: "#9ca3af", fontSize: "14px" }}>Zitadel auth</p>
2063
+ <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>
2064
+ <div style={{ display: "flex", flexWrap: "wrap", gap: "12px", justifyContent: "center" }}>
2065
+ <a href="/login" style={{ padding: "10px 16px", borderRadius: "8px", background: "#f4f4f6", color: "#0f0f11", textDecoration: "none", fontWeight: "600", fontSize: "14px" }}>Sign in</a>
2066
+ <a href="/register" style={{ padding: "10px 16px", borderRadius: "8px", border: "1px solid #3f3f46", color: "#f4f4f6", textDecoration: "none", fontWeight: "600", fontSize: "14px" }}>Create account</a>
2067
+ <a href="/profile" style={{ padding: "10px 16px", borderRadius: "8px", border: "1px solid #3f3f46", color: "#f4f4f6", textDecoration: "none", fontWeight: "600", fontSize: "14px" }}>Profile</a>
2068
+ </div>
2069
+ </section>
2070
+ </main>
2071
+ );
2072
+ }
2073
+ if (path.startsWith("/profile")) {
2074
+ return (
2075
+ <div style={{ position: "fixed", inset: "0", overflow: "auto", background: "#0f0f11" }}>
2076
+ <ZitadelLogout project={project} postSignOutUrl="/login" />
2077
+ </div>
2078
+ );
2079
+ }
2080
+ if (path.startsWith("/register")) {
2081
+ return (
2082
+ <div style={{ position: "fixed", inset: "0", overflow: "auto", background: "#0f0f11" }}>
2083
+ <ZitadelLogin project={project} purpose="register" postSignInUrl="/profile" />
2084
+ </div>
2085
+ );
2086
+ }
2087
+ return (
2088
+ <div style={{ position: "fixed", inset: "0", overflow: "auto", background: "#0f0f11" }}>
2089
+ <ZitadelLogin project={project} purpose="login" postSignInUrl="/profile" />
2090
+ </div>
2091
+ );
2092
+ });
2093
+ `;
2094
+ }
2095
+ //#endregion
2096
+ //#region src/lib/orca/patchers/rule/qwik/index.ts
2097
+ const SDK_DEPENDENCY$4 = "@zitadel/sdk-qwik";
2098
+ /**
2099
+ * Rule-based patcher for a Vite + Qwik single-page app. Inherits the shared
2100
+ * `.zitadel/` base files from {@link AbstractRulePatcher} and contributes the
2101
+ * managed `src/app.tsx` auth entry, a non-destructive `vite.config.*` merge
2102
+ * that adds the `/__nextgen` dev proxy (attaching the project secret from
2103
+ * `ZITADEL_PROJECT_SECRET` to every proxied request), the `VITE_`-prefixed
2104
+ * project id, and the SDK dep.
2105
+ *
2106
+ * The create-vite Qwik template uses a lowercase `src/app.tsx` exporting a named
2107
+ * `App` (mounted by `main.tsx`), so this patcher writes that exact entry. Unlike
2108
+ * Next.js — whose middleware runs the proxy server-side — a SPA has no server,
2109
+ * so the dev proxy stands in for `@zitadel/edge-proxy` locally. Production
2110
+ * deployments still need that proxy.
2111
+ */
2112
+ var QwikPatcher = class extends AbstractRulePatcher {
2113
+ canPatch(framework) {
2114
+ return framework === "qwik";
2115
+ }
2116
+ viteProxyOp(devPort, server) {
2117
+ return buildViteProxyOp(devPort, server);
2118
+ }
2119
+ routeOps(ctx) {
2120
+ return [
2121
+ {
2122
+ kind: "write",
2123
+ path: "src/app.tsx",
2124
+ contents: appTemplate$4()
2125
+ },
2126
+ this.viteProxyOp(ctx.framework.devPort, ctx.server),
2127
+ {
2128
+ kind: "merge-env",
2129
+ path: ".env.example",
2130
+ entries: { VITE_ZITADEL_PROJECT_ID: "" }
2131
+ },
2132
+ {
2133
+ kind: "merge-env",
2134
+ path: ".env.local",
2135
+ entries: { VITE_ZITADEL_PROJECT_ID: ctx.project.id }
2136
+ },
2137
+ {
2138
+ kind: "add-dep",
2139
+ name: SDK_DEPENDENCY$4,
2140
+ version: npmDistTagForCliVersion(ctx.cliVersion)
2141
+ }
2142
+ ];
2143
+ }
2144
+ routeFiles(_view) {
2145
+ return ["src/app.tsx"];
2146
+ }
2147
+ routeDeps(_view) {
2148
+ return [SDK_DEPENDENCY$4];
2149
+ }
2150
+ routeConfigEdits(_view) {
2151
+ return ["vite.config.*"];
2152
+ }
2153
+ summary(_ctx) {
2154
+ return {
2155
+ title: "Qwik (Vite) integration",
2156
+ detail: "Wrote src/app.tsx auth entry and merged the /__nextgen dev proxy into vite.config.*."
2157
+ };
2158
+ }
2159
+ };
2160
+ //#endregion
1894
2161
  //#region src/lib/orca/patchers/rule/react/templates.ts
1895
2162
  /**
1896
2163
  * 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
2164
+ * `@zitadel/sdk-react` widgets — a landing chooser at `/`, login at `/login`,
2165
+ * register at `/register`, and the logout widget at `/profile`. The project id comes from
1899
2166
  * `VITE_ZITADEL_PROJECT_ID` (Vite only exposes `VITE_`-prefixed env to the
1900
2167
  * 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)
2168
+ * attaches the project service-key secret (from `ZITADEL_PROJECT_SECRET`)
1902
2169
  * server-side.
1903
2170
  */
1904
- function appTemplate$1() {
2171
+ function appTemplate$3() {
1905
2172
  return `${MANAGED_MARKER}
1906
2173
  import { ZitadelLogin, ZitadelLogout, configureZitadel } from "@zitadel/sdk-react";
1907
2174
 
@@ -1913,25 +2180,52 @@ const project = configureZitadel({
1913
2180
  export default function App() {
1914
2181
  const path = window.location.pathname;
1915
2182
 
2183
+ if (path === "/") {
2184
+ return (
2185
+ <main style={{ position: "fixed", inset: 0, padding: "48px", boxSizing: "border-box", display: "flex", alignItems: "center", justifyContent: "center", background: "#0f0f11", color: "#f4f4f6", fontFamily: "system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif", lineHeight: 1.5, letterSpacing: "normal", textAlign: "center" }}>
2186
+ <section style={{ width: "100%", maxWidth: "560px" }}>
2187
+ <p style={{ margin: "0 0 12px", color: "#9ca3af", fontSize: "14px" }}>Zitadel auth</p>
2188
+ <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>
2189
+ <div style={{ display: "flex", flexWrap: "wrap", gap: "12px", justifyContent: "center" }}>
2190
+ <a href="/login" style={{ padding: "10px 16px", borderRadius: "8px", background: "#f4f4f6", color: "#0f0f11", textDecoration: "none", fontWeight: 600, fontSize: "14px" }}>Sign in</a>
2191
+ <a href="/register" style={{ padding: "10px 16px", borderRadius: "8px", border: "1px solid #3f3f46", color: "#f4f4f6", textDecoration: "none", fontWeight: 600, fontSize: "14px" }}>Create account</a>
2192
+ <a href="/profile" style={{ padding: "10px 16px", borderRadius: "8px", border: "1px solid #3f3f46", color: "#f4f4f6", textDecoration: "none", fontWeight: 600, fontSize: "14px" }}>Profile</a>
2193
+ </div>
2194
+ </section>
2195
+ </main>
2196
+ );
2197
+ }
1916
2198
  if (path.startsWith("/profile")) {
1917
- return <ZitadelLogout project={project} postSignOutUrl="/login" />;
2199
+ return (
2200
+ <div style={{ position: "fixed", inset: 0, overflow: "auto", background: "#0f0f11" }}>
2201
+ <ZitadelLogout project={project} postSignOutUrl="/login" />
2202
+ </div>
2203
+ );
1918
2204
  }
1919
2205
  if (path.startsWith("/register")) {
1920
- return <ZitadelLogin project={project} purpose="register" postSignInUrl="/profile" />;
2206
+ return (
2207
+ <div style={{ position: "fixed", inset: 0, overflow: "auto", background: "#0f0f11" }}>
2208
+ <ZitadelLogin project={project} purpose="register" postSignInUrl="/profile" />
2209
+ </div>
2210
+ );
1921
2211
  }
1922
- return <ZitadelLogin project={project} purpose="login" postSignInUrl="/profile" />;
2212
+ return (
2213
+ <div style={{ position: "fixed", inset: 0, overflow: "auto", background: "#0f0f11" }}>
2214
+ <ZitadelLogin project={project} purpose="login" postSignInUrl="/profile" />
2215
+ </div>
2216
+ );
1923
2217
  }
1924
2218
  `;
1925
2219
  }
1926
2220
  //#endregion
1927
2221
  //#region src/lib/orca/patchers/rule/react/index.ts
1928
- const SDK_DEPENDENCY$1 = "@zitadel/sdk-react";
2222
+ const SDK_DEPENDENCY$3 = "@zitadel/sdk-react";
1929
2223
  /**
1930
2224
  * Rule-based patcher for a Vite + React single-page app. Inherits the shared
1931
2225
  * `.zitadel/` base files from {@link AbstractRulePatcher} and contributes the
1932
2226
  * 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
2227
+ * that adds the `/__nextgen` dev proxy (attaching the project secret from
2228
+ * `ZITADEL_PROJECT_SECRET` to every proxied request), the `VITE_`-prefixed
1935
2229
  * project id, and the SDK dep.
1936
2230
  *
1937
2231
  * Unlike Next.js — whose middleware runs the proxy and token exchange
@@ -1950,7 +2244,7 @@ var ReactPatcher = class extends AbstractRulePatcher {
1950
2244
  {
1951
2245
  kind: "write",
1952
2246
  path: "src/App.tsx",
1953
- contents: appTemplate$1()
2247
+ contents: appTemplate$3()
1954
2248
  },
1955
2249
  this.viteProxyOp(ctx.framework.devPort, ctx.server),
1956
2250
  {
@@ -1965,7 +2259,7 @@ var ReactPatcher = class extends AbstractRulePatcher {
1965
2259
  },
1966
2260
  {
1967
2261
  kind: "add-dep",
1968
- name: SDK_DEPENDENCY$1,
2262
+ name: SDK_DEPENDENCY$3,
1969
2263
  version: npmDistTagForCliVersion(ctx.cliVersion)
1970
2264
  }
1971
2265
  ];
@@ -1974,7 +2268,7 @@ var ReactPatcher = class extends AbstractRulePatcher {
1974
2268
  return ["src/App.tsx"];
1975
2269
  }
1976
2270
  routeDeps(_view) {
1977
- return [SDK_DEPENDENCY$1];
2271
+ return [SDK_DEPENDENCY$3];
1978
2272
  }
1979
2273
  routeConfigEdits(_view) {
1980
2274
  return ["vite.config.*"];
@@ -1987,15 +2281,252 @@ var ReactPatcher = class extends AbstractRulePatcher {
1987
2281
  }
1988
2282
  };
1989
2283
  //#endregion
2284
+ //#region src/lib/orca/patchers/rule/solid/templates.ts
2285
+ /**
2286
+ * The managed `src/App.tsx`: a minimal path-based router that renders the
2287
+ * `@zitadel/sdk-solid` widgets — a landing chooser at `/`, login at `/login`,
2288
+ * register at `/register`, and the logout widget at `/profile`. The project id comes from
2289
+ * `VITE_ZITADEL_PROJECT_ID` (Vite only exposes `VITE_`-prefixed env to the
2290
+ * client). No secret reaches the browser: the dev proxy in `vite.config.*`
2291
+ * attaches the project service-key secret (from `ZITADEL_PROJECT_SECRET`)
2292
+ * server-side.
2293
+ */
2294
+ function appTemplate$2() {
2295
+ return `${MANAGED_MARKER}
2296
+ import { ZitadelLogin, ZitadelLogout, configureZitadel } from "@zitadel/sdk-solid";
2297
+
2298
+ const project = configureZitadel({
2299
+ projectId: import.meta.env.VITE_ZITADEL_PROJECT_ID,
2300
+ proxyPath: "${PROXY_PATH}",
2301
+ });
2302
+
2303
+ export default function App() {
2304
+ const path = window.location.pathname;
2305
+
2306
+ if (path === "/") {
2307
+ return (
2308
+ <main style="position:fixed;inset:0;padding:48px;box-sizing:border-box;display:flex;align-items:center;justify-content:center;background:#0f0f11;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">
2309
+ <section style="width:100%;max-width:560px">
2310
+ <p style="margin:0 0 12px;color:#9ca3af;font-size:14px">Zitadel auth</p>
2311
+ <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>
2312
+ <div style="display:flex;flex-wrap:wrap;gap:12px;justify-content:center">
2313
+ <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>
2314
+ <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>
2315
+ <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>
2316
+ </div>
2317
+ </section>
2318
+ </main>
2319
+ );
2320
+ }
2321
+ if (path.startsWith("/profile")) {
2322
+ return (
2323
+ <div style="position:fixed;inset:0;overflow:auto;background:#0f0f11">
2324
+ <ZitadelLogout project={project} postSignOutUrl="/login" />
2325
+ </div>
2326
+ );
2327
+ }
2328
+ if (path.startsWith("/register")) {
2329
+ return (
2330
+ <div style="position:fixed;inset:0;overflow:auto;background:#0f0f11">
2331
+ <ZitadelLogin project={project} purpose="register" postSignInUrl="/profile" />
2332
+ </div>
2333
+ );
2334
+ }
2335
+ return (
2336
+ <div style="position:fixed;inset:0;overflow:auto;background:#0f0f11">
2337
+ <ZitadelLogin project={project} purpose="login" postSignInUrl="/profile" />
2338
+ </div>
2339
+ );
2340
+ }
2341
+ `;
2342
+ }
2343
+ //#endregion
2344
+ //#region src/lib/orca/patchers/rule/solid/index.ts
2345
+ const SDK_DEPENDENCY$2 = "@zitadel/sdk-solid";
2346
+ /**
2347
+ * Rule-based patcher for a Vite + Solid single-page app. Inherits the shared
2348
+ * `.zitadel/` base files from {@link AbstractRulePatcher} and contributes the
2349
+ * managed `src/App.tsx` auth entry, a non-destructive `vite.config.*` merge
2350
+ * that adds the `/__nextgen` dev proxy (attaching the project secret from
2351
+ * `ZITADEL_PROJECT_SECRET` to every proxied request), the `VITE_`-prefixed
2352
+ * project id, and the SDK dep.
2353
+ *
2354
+ * Unlike Next.js — whose middleware runs the proxy and token exchange
2355
+ * server-side — a SPA has no server, so the dev proxy stands in for
2356
+ * `@zitadel/edge-proxy` locally. Production deployments still need that proxy.
2357
+ */
2358
+ var SolidPatcher = class extends AbstractRulePatcher {
2359
+ canPatch(framework) {
2360
+ return framework === "solid";
2361
+ }
2362
+ viteProxyOp(devPort, server) {
2363
+ return buildViteProxyOp(devPort, server);
2364
+ }
2365
+ routeOps(ctx) {
2366
+ return [
2367
+ {
2368
+ kind: "write",
2369
+ path: "src/App.tsx",
2370
+ contents: appTemplate$2()
2371
+ },
2372
+ this.viteProxyOp(ctx.framework.devPort, ctx.server),
2373
+ {
2374
+ kind: "merge-env",
2375
+ path: ".env.example",
2376
+ entries: { VITE_ZITADEL_PROJECT_ID: "" }
2377
+ },
2378
+ {
2379
+ kind: "merge-env",
2380
+ path: ".env.local",
2381
+ entries: { VITE_ZITADEL_PROJECT_ID: ctx.project.id }
2382
+ },
2383
+ {
2384
+ kind: "add-dep",
2385
+ name: SDK_DEPENDENCY$2,
2386
+ version: npmDistTagForCliVersion(ctx.cliVersion)
2387
+ }
2388
+ ];
2389
+ }
2390
+ routeFiles(_view) {
2391
+ return ["src/App.tsx"];
2392
+ }
2393
+ routeDeps(_view) {
2394
+ return [SDK_DEPENDENCY$2];
2395
+ }
2396
+ routeConfigEdits(_view) {
2397
+ return ["vite.config.*"];
2398
+ }
2399
+ summary(_ctx) {
2400
+ return {
2401
+ title: "Solid (Vite) integration",
2402
+ detail: "Wrote src/App.tsx auth entry and merged the /__nextgen dev proxy into vite.config.*."
2403
+ };
2404
+ }
2405
+ };
2406
+ //#endregion
2407
+ //#region src/lib/orca/patchers/rule/svelte/templates.ts
2408
+ /**
2409
+ * The managed `src/App.svelte`: a minimal path-based router that renders the
2410
+ * `@zitadel/sdk-svelte` widgets — a landing chooser at `/`, login at `/login`,
2411
+ * register at `/register`, and the logout widget at `/profile`. The managed marker lives in
2412
+ * the `<script lang="ts">` block (a JS comment) so eject/doctor stay
2413
+ * marker-aware. The project id comes from `VITE_ZITADEL_PROJECT_ID`. No secret
2414
+ * reaches the browser: the dev proxy in `vite.config.*` attaches the project
2415
+ * service-key secret (from `ZITADEL_PROJECT_SECRET`) server-side.
2416
+ */
2417
+ function appTemplate$1() {
2418
+ return `<script lang="ts">
2419
+ ${MANAGED_MARKER}
2420
+ import { ZitadelLogin, ZitadelLogout, configureZitadel } from "@zitadel/sdk-svelte";
2421
+
2422
+ const project = configureZitadel({
2423
+ projectId: import.meta.env.VITE_ZITADEL_PROJECT_ID,
2424
+ proxyPath: "${PROXY_PATH}",
2425
+ });
2426
+
2427
+ const path = window.location.pathname;
2428
+ <\/script>
2429
+
2430
+ {#if path === "/"}
2431
+ <main style="position:fixed;inset:0;padding:48px;box-sizing:border-box;display:flex;align-items:center;justify-content:center;background:#0f0f11;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">
2432
+ <section style="width:100%;max-width:560px">
2433
+ <p style="margin:0 0 12px;color:#9ca3af;font-size:14px">Zitadel auth</p>
2434
+ <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>
2435
+ <div style="display:flex;flex-wrap:wrap;gap:12px;justify-content:center">
2436
+ <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>
2437
+ <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>
2438
+ <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>
2439
+ </div>
2440
+ </section>
2441
+ </main>
2442
+ {:else if path.startsWith("/profile")}
2443
+ <div style="position:fixed;inset:0;overflow:auto;background:#0f0f11">
2444
+ <ZitadelLogout {project} postSignOutUrl="/login" />
2445
+ </div>
2446
+ {:else if path.startsWith("/register")}
2447
+ <div style="position:fixed;inset:0;overflow:auto;background:#0f0f11">
2448
+ <ZitadelLogin {project} purpose="register" postSignInUrl="/profile" />
2449
+ </div>
2450
+ {:else}
2451
+ <div style="position:fixed;inset:0;overflow:auto;background:#0f0f11">
2452
+ <ZitadelLogin {project} purpose="login" postSignInUrl="/profile" />
2453
+ </div>
2454
+ {/if}
2455
+ `;
2456
+ }
2457
+ //#endregion
2458
+ //#region src/lib/orca/patchers/rule/svelte/index.ts
2459
+ const SDK_DEPENDENCY$1 = "@zitadel/sdk-svelte";
2460
+ /**
2461
+ * Rule-based patcher for a Vite + Svelte single-page app. Inherits the shared
2462
+ * `.zitadel/` base files from {@link AbstractRulePatcher} and contributes the
2463
+ * managed `src/App.svelte` auth entry, a non-destructive `vite.config.*` merge
2464
+ * that adds the `/__nextgen` dev proxy (attaching the project secret from
2465
+ * `ZITADEL_PROJECT_SECRET` to every proxied request), the `VITE_`-prefixed
2466
+ * project id, and the SDK dep.
2467
+ *
2468
+ * Unlike Next.js — whose middleware runs the proxy and token exchange
2469
+ * server-side — a SPA has no server, so the dev proxy stands in for
2470
+ * `@zitadel/edge-proxy` locally. Production deployments still need that proxy.
2471
+ */
2472
+ var SveltePatcher = class extends AbstractRulePatcher {
2473
+ canPatch(framework) {
2474
+ return framework === "svelte";
2475
+ }
2476
+ viteProxyOp(devPort, server) {
2477
+ return buildViteProxyOp(devPort, server);
2478
+ }
2479
+ routeOps(ctx) {
2480
+ return [
2481
+ {
2482
+ kind: "write",
2483
+ path: "src/App.svelte",
2484
+ contents: appTemplate$1()
2485
+ },
2486
+ this.viteProxyOp(ctx.framework.devPort, ctx.server),
2487
+ {
2488
+ kind: "merge-env",
2489
+ path: ".env.example",
2490
+ entries: { VITE_ZITADEL_PROJECT_ID: "" }
2491
+ },
2492
+ {
2493
+ kind: "merge-env",
2494
+ path: ".env.local",
2495
+ entries: { VITE_ZITADEL_PROJECT_ID: ctx.project.id }
2496
+ },
2497
+ {
2498
+ kind: "add-dep",
2499
+ name: SDK_DEPENDENCY$1,
2500
+ version: npmDistTagForCliVersion(ctx.cliVersion)
2501
+ }
2502
+ ];
2503
+ }
2504
+ routeFiles(_view) {
2505
+ return ["src/App.svelte"];
2506
+ }
2507
+ routeDeps(_view) {
2508
+ return [SDK_DEPENDENCY$1];
2509
+ }
2510
+ routeConfigEdits(_view) {
2511
+ return ["vite.config.*"];
2512
+ }
2513
+ summary(_ctx) {
2514
+ return {
2515
+ title: "Svelte (Vite) integration",
2516
+ detail: "Wrote src/App.svelte auth entry and merged the /__nextgen dev proxy into vite.config.*."
2517
+ };
2518
+ }
2519
+ };
2520
+ //#endregion
1990
2521
  //#region src/lib/orca/patchers/rule/vue/templates.ts
1991
2522
  /**
1992
2523
  * 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
2524
+ * `@zitadel/sdk-vue` widgets — a landing chooser at `/`, login at `/login`,
2525
+ * register at `/register`, and the logout widget at `/profile`. The managed marker lives in
1995
2526
  * the `<script setup>` block (a JS comment) so eject/doctor stay marker-aware.
1996
2527
  * 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.
2528
+ * browser: the dev proxy in `vite.config.*` attaches the project service-key
2529
+ * secret (from `ZITADEL_PROJECT_SECRET`) server-side.
1999
2530
  */
2000
2531
  function appTemplate() {
2001
2532
  return `<script setup lang="ts">
@@ -2011,18 +2542,35 @@ const path = window.location.pathname;
2011
2542
  <\/script>
2012
2543
 
2013
2544
  <template>
2014
- <ZitadelLogout
2015
- v-if="path.startsWith('/profile')"
2016
- :project="project"
2017
- postSignOutUrl="/login"
2018
- />
2019
- <ZitadelLogin
2545
+ <main
2546
+ v-if="path === '/'"
2547
+ style="position:fixed;inset:0;padding:48px;box-sizing:border-box;display:flex;align-items:center;justify-content:center;background:#0f0f11;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"
2548
+ >
2549
+ <section style="width:100%;max-width:560px">
2550
+ <p style="margin:0 0 12px;color:#9ca3af;font-size:14px">Zitadel auth</p>
2551
+ <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>
2552
+ <div style="display:flex;flex-wrap:wrap;gap:12px;justify-content:center">
2553
+ <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>
2554
+ <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>
2555
+ <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>
2556
+ </div>
2557
+ </section>
2558
+ </main>
2559
+ <div
2560
+ v-else-if="path.startsWith('/profile')"
2561
+ style="position:fixed;inset:0;overflow:auto;background:#0f0f11"
2562
+ >
2563
+ <ZitadelLogout :project="project" postSignOutUrl="/login" />
2564
+ </div>
2565
+ <div
2020
2566
  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" />
2567
+ style="position:fixed;inset:0;overflow:auto;background:#0f0f11"
2568
+ >
2569
+ <ZitadelLogin :project="project" purpose="register" postSignInUrl="/profile" />
2570
+ </div>
2571
+ <div v-else style="position:fixed;inset:0;overflow:auto;background:#0f0f11">
2572
+ <ZitadelLogin :project="project" purpose="login" postSignInUrl="/profile" />
2573
+ </div>
2026
2574
  </template>
2027
2575
  `;
2028
2576
  }
@@ -2033,8 +2581,8 @@ const SDK_DEPENDENCY = "@zitadel/sdk-vue";
2033
2581
  * Rule-based patcher for a Vite + Vue single-page app. Inherits the shared
2034
2582
  * `.zitadel/` base files from {@link AbstractRulePatcher} and contributes the
2035
2583
  * 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
2584
+ * that adds the `/__nextgen` dev proxy (attaching the project secret from
2585
+ * `ZITADEL_PROJECT_SECRET` to every proxied request), the `VITE_`-prefixed
2038
2586
  * project id, and the SDK dep.
2039
2587
  */
2040
2588
  var VuePatcher = class extends AbstractRulePatcher {
@@ -2101,6 +2649,9 @@ const patchers = [
2101
2649
  new NuxtPatcher(),
2102
2650
  new ReactPatcher(),
2103
2651
  new VuePatcher(),
2652
+ new SolidPatcher(),
2653
+ new SveltePatcher(),
2654
+ new QwikPatcher(),
2104
2655
  new AngularPatcher()
2105
2656
  ];
2106
2657
  //#endregion
@@ -2262,6 +2813,36 @@ var NuxtScaffolder = class extends AbstractCLIScaffolder {
2262
2813
  }
2263
2814
  };
2264
2815
  //#endregion
2816
+ //#region src/lib/orca/scaffolders/qwik.ts
2817
+ /**
2818
+ * Scaffolds a new Vite + Qwik (TypeScript) single-page app with `create-vite`,
2819
+ * then removes the starter `app.tsx`/`app.css` demo so the patcher can write the
2820
+ * managed `src/app.tsx` without colliding with boilerplate. The create-vite Qwik
2821
+ * template uses a lowercase `app.tsx` (named `App` export, mounted by `main.tsx`)
2822
+ * — the patched file keeps that same entry.
2823
+ */
2824
+ var QwikScaffolder = class extends AbstractCLIScaffolder {
2825
+ displayName = "Qwik (Vite)";
2826
+ supportedFrameworks = ["qwik"];
2827
+ async scaffold(cwd, _framework) {
2828
+ this.runCommand("npm", [
2829
+ "create",
2830
+ "vite@latest",
2831
+ ".",
2832
+ "--",
2833
+ "--template",
2834
+ "qwik-ts"
2835
+ ], cwd);
2836
+ await rm(join(cwd, "src/app.tsx"), { force: true });
2837
+ await rm(join(cwd, "src/app.css"), { force: true });
2838
+ this.runCommand("npm", [
2839
+ "pkg",
2840
+ "set",
2841
+ "devDependencies.vite=^7.3.5"
2842
+ ], cwd);
2843
+ }
2844
+ };
2845
+ //#endregion
2265
2846
  //#region src/lib/orca/scaffolders/react.ts
2266
2847
  /**
2267
2848
  * Scaffolds a new Vite + React (TypeScript) single-page app with `create-vite`,
@@ -2286,6 +2867,55 @@ var ReactScaffolder = class extends AbstractCLIScaffolder {
2286
2867
  }
2287
2868
  };
2288
2869
  //#endregion
2870
+ //#region src/lib/orca/scaffolders/solid.ts
2871
+ /**
2872
+ * Scaffolds a new Vite + Solid (TypeScript) single-page app with `create-vite`,
2873
+ * then removes the starter `App.tsx`/`App.css` demo so the patcher can write the
2874
+ * managed `src/App.tsx` without colliding with boilerplate. `index.css` and
2875
+ * `index.tsx` are left in place — the patched `App.tsx` keeps the same entry.
2876
+ */
2877
+ var SolidScaffolder = class extends AbstractCLIScaffolder {
2878
+ displayName = "Solid (Vite)";
2879
+ supportedFrameworks = ["solid"];
2880
+ async scaffold(cwd, _framework) {
2881
+ this.runCommand("npm", [
2882
+ "create",
2883
+ "vite@latest",
2884
+ ".",
2885
+ "--",
2886
+ "--template",
2887
+ "solid-ts"
2888
+ ], cwd);
2889
+ await rm(join(cwd, "src/App.tsx"), { force: true });
2890
+ await rm(join(cwd, "src/App.css"), { force: true });
2891
+ }
2892
+ };
2893
+ //#endregion
2894
+ //#region src/lib/orca/scaffolders/svelte.ts
2895
+ /**
2896
+ * Scaffolds a new Vite + Svelte (TypeScript) single-page app with `create-vite`,
2897
+ * then removes the starter `App.svelte`/`lib/Counter.svelte` demo so the patcher
2898
+ * can write the managed `src/App.svelte` without colliding with boilerplate.
2899
+ * `app.css` and `main.ts` are left in place — the patched `App.svelte` keeps the
2900
+ * same entry.
2901
+ */
2902
+ var SvelteScaffolder = class extends AbstractCLIScaffolder {
2903
+ displayName = "Svelte (Vite)";
2904
+ supportedFrameworks = ["svelte"];
2905
+ async scaffold(cwd, _framework) {
2906
+ this.runCommand("npm", [
2907
+ "create",
2908
+ "vite@latest",
2909
+ ".",
2910
+ "--",
2911
+ "--template",
2912
+ "svelte-ts"
2913
+ ], cwd);
2914
+ await rm(join(cwd, "src/App.svelte"), { force: true });
2915
+ await rm(join(cwd, "src/lib/Counter.svelte"), { force: true });
2916
+ }
2917
+ };
2918
+ //#endregion
2289
2919
  //#region src/lib/orca/scaffolders/vue.ts
2290
2920
  /**
2291
2921
  * Scaffolds a new Vite + Vue (TypeScript) single-page app with `create-vite`,
@@ -2320,6 +2950,9 @@ const scaffolders = [
2320
2950
  new NuxtScaffolder(),
2321
2951
  new ReactScaffolder(),
2322
2952
  new VueScaffolder(),
2953
+ new SolidScaffolder(),
2954
+ new SvelteScaffolder(),
2955
+ new QwikScaffolder(),
2323
2956
  new AngularScaffolder()
2324
2957
  ];
2325
2958
  //#endregion
@@ -2578,4 +3211,4 @@ function isErrno(error, code) {
2578
3211
  //#endregion
2579
3212
  export { issuerFromPort as i, inspectScaffoldTarget as n, RENDERER_IDS as r, createOrca as t };
2580
3213
 
2581
- //# sourceMappingURL=orca-BoTFU8SI.mjs.map
3214
+ //# sourceMappingURL=orca-mzcHxDvu.mjs.map