@zitadel/testing 0.0.0 → 0.1.0-alpha.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +124 -42
- package/dist/{app-env-D3W0GYhA.d.mts → app-env-Btmfcflb.d.mts} +4 -4
- package/dist/{app-env-D3W0GYhA.d.mts.map → app-env-Btmfcflb.d.mts.map} +1 -1
- package/dist/app-runner.cjs +1 -1
- package/dist/app-runner.mjs +1 -1
- package/dist/{handshake-CggSIoxF.cjs → handshake-CRKcgkfN.cjs} +3 -2
- package/dist/{handshake-CggSIoxF.cjs.map → handshake-CRKcgkfN.cjs.map} +1 -1
- package/dist/{handshake-BPtWruO8.mjs → handshake-ClzWvG8z.mjs} +3 -2
- package/dist/{handshake-BPtWruO8.mjs.map → handshake-ClzWvG8z.mjs.map} +1 -1
- package/dist/index.cjs +2 -2
- package/dist/index.d.mts +4 -5
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/playwright.cjs +273 -15
- package/dist/playwright.cjs.map +1 -1
- package/dist/playwright.d.mts +173 -6
- package/dist/playwright.d.mts.map +1 -1
- package/dist/playwright.mjs +265 -16
- package/dist/playwright.mjs.map +1 -1
- package/dist/{src-DkG0V4A6.mjs → src-9dFjTIAw.mjs} +19 -17
- package/dist/src-9dFjTIAw.mjs.map +1 -0
- package/dist/{src-BIL0PdSd.cjs → src-I0KAh1zU.cjs} +447 -429
- package/dist/src-I0KAh1zU.cjs.map +1 -0
- package/dist/supervisor.cjs +2 -2
- package/dist/supervisor.mjs +2 -2
- package/package.json +5 -5
- package/dist/src-BIL0PdSd.cjs.map +0 -1
- package/dist/src-DkG0V4A6.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# @zitadel/testing
|
|
2
2
|
|
|
3
3
|
Test-kit for **seeded ephemeral local Zitadel instances**: boot the real server
|
|
4
|
-
(binary runtime +
|
|
4
|
+
(binary runtime + SQLite by default, no Docker) from test code, create a
|
|
5
5
|
project with the default login flow, and mint password users that can complete
|
|
6
6
|
the real login journey immediately.
|
|
7
7
|
|
|
@@ -54,15 +54,12 @@ export default defineConfig({
|
|
|
54
54
|
|
|
55
55
|
```ts
|
|
56
56
|
// my-login.spec.ts
|
|
57
|
-
import { expect, test } from "@zitadel/testing/playwright";
|
|
57
|
+
import { expect, loginWithPassword, test } from "@zitadel/testing/playwright";
|
|
58
58
|
|
|
59
59
|
test("user signs in with password", async ({ page, seed }) => {
|
|
60
60
|
const user = await seed.user(); // unique email + password, loginable now
|
|
61
61
|
await page.goto("/login");
|
|
62
|
-
await page
|
|
63
|
-
await page.getByRole("button", { name: "Sign in", exact: true }).click();
|
|
64
|
-
await page.getByLabel(/password/i).fill(user.password);
|
|
65
|
-
await page.getByRole("button", { name: "Sign in", exact: true }).click();
|
|
62
|
+
await loginWithPassword(page, user); // drives the identifier → password steps
|
|
66
63
|
await expect(page).toHaveURL(/\/admin/);
|
|
67
64
|
});
|
|
68
65
|
```
|
|
@@ -73,6 +70,24 @@ apps; the console maps the same fields to `VITE_*`/`CONSOLE_*` names instead.
|
|
|
73
70
|
The fixtures find the instance through `ZITADEL_TESTING_HANDSHAKE`, which
|
|
74
71
|
`withZitadel()` points at its handshake file.
|
|
75
72
|
|
|
73
|
+
`app` is optional. Omit it when the instance itself serves the app — the
|
|
74
|
+
Zitadel binary embeds the console and hosted sign-in at `/ui/console/` and
|
|
75
|
+
`/ui/login/`, so a suite testing those surfaces has no second server to boot.
|
|
76
|
+
Only the instance entry is generated, and `appOrigin` must then be the
|
|
77
|
+
instance's own local origin:
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
export default defineConfig({
|
|
81
|
+
testDir: "./e2e",
|
|
82
|
+
use: { baseURL: "http://localhost:8092" },
|
|
83
|
+
...withZitadel({
|
|
84
|
+
configDir: import.meta.dirname,
|
|
85
|
+
port: 8092,
|
|
86
|
+
appOrigin: "http://localhost:8092", // the instance is the app server
|
|
87
|
+
}),
|
|
88
|
+
});
|
|
89
|
+
```
|
|
90
|
+
|
|
76
91
|
### Start tests authenticated
|
|
77
92
|
|
|
78
93
|
Most app tests don't want to re-test login. `authenticatedPage` seeds a user,
|
|
@@ -96,6 +111,65 @@ log in through the UI for those. `seed.identity()` complements registration
|
|
|
96
111
|
specs: an unused email+password that creates nothing, so the flow under test
|
|
97
112
|
must create the user.
|
|
98
113
|
|
|
114
|
+
### Drive the login flow
|
|
115
|
+
|
|
116
|
+
Four ceremony helpers complete whole auth journeys against the
|
|
117
|
+
`<zitadel-login>` widget. They are built on the widget's documented
|
|
118
|
+
automation hooks (`zitadel-action-*`, `zitadel-field-*` / `zitadel-input-*`),
|
|
119
|
+
not on translated button texts, so they survive locale and copy changes:
|
|
120
|
+
|
|
121
|
+
```ts
|
|
122
|
+
import {
|
|
123
|
+
loginWithPassword, // identifier → password (handles combined steps too)
|
|
124
|
+
loginWithPasskey, // identifier-first; or one-tap without an email
|
|
125
|
+
registerWithPassword, // unknown identifier → registration → password path
|
|
126
|
+
registerWithPasskey, // unknown identifier → registration → passkey ceremony
|
|
127
|
+
} from "@zitadel/testing/playwright";
|
|
128
|
+
|
|
129
|
+
await page.goto("/login");
|
|
130
|
+
await registerWithPassword(page, { email, password });
|
|
131
|
+
// assert your app's signed-in surface — the helpers never assert app state
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
They assume the default flow vocabulary (`submit` / `passkey` /
|
|
135
|
+
`passkey_register` actions, `email` and password fields) and branch only on
|
|
136
|
+
what the flow renders: flows that require extra registration fields get them
|
|
137
|
+
via `profile: [{ field, value }]`, filled when present — a boolean value
|
|
138
|
+
drives a checkbox, a string matches a select option or fills a text-like
|
|
139
|
+
input. For custom flows or single steps, `flowAction(page, name)` /
|
|
140
|
+
`flowField(page, name)` return plain locators for the same hooks, with
|
|
141
|
+
`clickFlowAction` / `fillFlowField` as one-line wrappers. Broad fallbacks
|
|
142
|
+
(accessible names via `{ name }` / `{ label }`, the generic `data-action`
|
|
143
|
+
attribute) are scoped to the `<zitadel-login>` host element — so they never
|
|
144
|
+
match same-named controls in your app's own chrome, and they keep working
|
|
145
|
+
for custom templates that render no automation hooks.
|
|
146
|
+
|
|
147
|
+
### Test passkey flows
|
|
148
|
+
|
|
149
|
+
`enableVirtualPasskey(page)` — also available as the on-demand `passkey`
|
|
150
|
+
fixture — attaches a CDP virtual authenticator to the page (a platform
|
|
151
|
+
authenticator with discoverable credentials and automatic user presence), so
|
|
152
|
+
the real registration and login ceremonies complete without an OS dialog:
|
|
153
|
+
|
|
154
|
+
```ts
|
|
155
|
+
test("registers and signs in with a passkey", async ({ page, seed, passkey }) => {
|
|
156
|
+
const who = seed.identity();
|
|
157
|
+
await page.goto("/login");
|
|
158
|
+
await registerWithPasskey(page, { email: who.email });
|
|
159
|
+
await expect.poll(() => passkey.credentialCount()).toBe(1);
|
|
160
|
+
});
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Constraints, all inherent to WebAuthn/CDP: Chromium projects only (the CDP
|
|
164
|
+
WebAuthn domain exists nowhere else); the authenticator is bound to the page,
|
|
165
|
+
so register and sign back in on the same page (sign out by clearing cookies
|
|
166
|
+
instead of opening a fresh context); and serve the app on an origin WebAuthn
|
|
167
|
+
accepts as a relying-party ID — HTTPS on a real domain, or `http://localhost`
|
|
168
|
+
for local tests; raw IP origins like `127.0.0.1` are invalid. The default
|
|
169
|
+
`password-first` flow offers passkey registration at the registration-choice
|
|
170
|
+
step; boot `preset: "passkey-first"` for one-tap discoverable-credential
|
|
171
|
+
login flows.
|
|
172
|
+
|
|
99
173
|
The two in-repo consumers are `apps/demo-next-e2e/playwright.real.config.mts`
|
|
100
174
|
and `apps/console-e2e/playwright.real.config.mts` — run them with
|
|
101
175
|
`moon run demo-next-e2e:e2e-real` / `moon run console-e2e:e2e-real`.
|
|
@@ -122,10 +196,10 @@ import {
|
|
|
122
196
|
const z = await startLocalZitadel({
|
|
123
197
|
port, // default: free port
|
|
124
198
|
dir, // default: temp dir, removed on stop (caller dirs are kept)
|
|
125
|
-
appOrigins, // registered as the project's
|
|
199
|
+
appOrigins, // registered as the project's preview_origins
|
|
126
200
|
useCase, // "minimal" (default) | "consumer" | "business"
|
|
127
201
|
preset, // "password-first" (default)
|
|
128
|
-
serverBinary, // ZITADEL_SERVER_BINARY override (
|
|
202
|
+
serverBinary, // ZITADEL_SERVER_BINARY override (path to a built server binary)
|
|
129
203
|
keep, // keep the temp dir for debugging
|
|
130
204
|
});
|
|
131
205
|
|
|
@@ -136,7 +210,7 @@ await z.seedUser({ email?, password?, attributes? }); // → { id, email, passwo
|
|
|
136
210
|
await z.seedUsers(8, { email?, password?, attributes? }); // per-index templates
|
|
137
211
|
z.identity(); // unused { email, password } — creates nothing
|
|
138
212
|
await z.seedSession({ user? }); // → { user, sessionToken, expiresAt, cookie }
|
|
139
|
-
await z.stop(); // stop server
|
|
213
|
+
await z.stop(); // stop server and remove owned temp dir
|
|
140
214
|
```
|
|
141
215
|
|
|
142
216
|
`connectZitadel(handle)` returns the same surface minus lifecycle — this is
|
|
@@ -144,23 +218,28 @@ what the Playwright fixtures use, and what a future remote-instance mode would
|
|
|
144
218
|
build on.
|
|
145
219
|
|
|
146
220
|
From `@zitadel/testing/playwright`: the `test`/`expect` fixtures (`seed.user()`
|
|
147
|
-
per test, `zitadel` per worker
|
|
148
|
-
`
|
|
149
|
-
|
|
221
|
+
per test, `zitadel` per worker, `passkey` on demand), the flow ceremonies
|
|
222
|
+
(`loginWithPassword`, `loginWithPasskey`, `registerWithPassword`,
|
|
223
|
+
`registerWithPasskey`) with their locator-level escape hatches
|
|
224
|
+
(`flowAction`/`flowField`, `clickFlowAction`/`fillFlowField`), plus
|
|
225
|
+
`withZitadel(options)` returning `{ webServer }` for the config,
|
|
226
|
+
`enableVirtualPasskey(page)` for non-fixture pages, and
|
|
227
|
+
`nextAppEnv`/`applyAppEnvTemplate` for the env-template mechanism described
|
|
228
|
+
above.
|
|
150
229
|
|
|
151
230
|
## How it works
|
|
152
231
|
|
|
153
232
|
- **Lifecycle** shells out to `zitadel start/stop --json` (the CLI owns port
|
|
154
|
-
preflight, the health wait, process-group stop
|
|
155
|
-
|
|
156
|
-
public API.
|
|
233
|
+
preflight, the health wait, and process-group stop). Swapping this for direct
|
|
234
|
+
library calls later will not change the public API.
|
|
157
235
|
- **Bootstrap** is the server-side half of `zitadel setup`, no files:
|
|
158
|
-
`POST /projects` (unauthenticated; returns the `
|
|
236
|
+
`POST /projects` (unauthenticated; returns the `project_secret` used as
|
|
159
237
|
bearer for everything else) → `POST /schemas` (server assigns the schema id)
|
|
160
238
|
→ `POST /flow_definitions` (default login flow pinned to that schema id).
|
|
161
239
|
Templates come from `@zitadel/config/defaults`.
|
|
162
|
-
- **Seeding** is `POST /users` (the body
|
|
163
|
-
|
|
240
|
+
- **Seeding** is `POST /users` (the body names the schema in `schema` and puts
|
|
241
|
+
the schema-defined content under `attributes`) +
|
|
242
|
+
`PUT /users/{id}/password` with `is_change_required: false`.
|
|
164
243
|
|
|
165
244
|
## Parallelism model
|
|
166
245
|
|
|
@@ -169,13 +248,13 @@ project, so per-test `seed.user()` calls are isolation enough for login-flow
|
|
|
169
248
|
tests, and tests run fully parallel against the shared instance
|
|
170
249
|
(demonstrated by `demo-next-e2e:e2e-real`, 2 workers).
|
|
171
250
|
|
|
172
|
-
|
|
251
|
+
Typical timings with the SQLite local default (dated estimates from a July 2026 dev build — orders of magnitude, not a benchmark; remeasure locally before relying on them):
|
|
173
252
|
|
|
174
253
|
| Operation | Time |
|
|
175
254
|
| --- | --- |
|
|
176
|
-
| Cold boot (fresh data dir:
|
|
177
|
-
| Warm restart (existing data dir) |
|
|
178
|
-
| Stop
|
|
255
|
+
| Cold boot (fresh data dir: SQLite migrate + health) | typically under a few seconds |
|
|
256
|
+
| Warm restart (existing data dir) | typically under a second |
|
|
257
|
+
| Stop | typically under a second |
|
|
179
258
|
| Bootstrap (project + schema + flow) | ~100ms |
|
|
180
259
|
| Seed one user (create + password) | ~50ms |
|
|
181
260
|
| Full `e2e-real` suite (boot + Next dev + 2 browser tests) | ~25s |
|
|
@@ -199,10 +278,12 @@ Customer installs get the published server binary through `@zitadel/server`'s
|
|
|
199
278
|
platform packages; the in-repo workspace carries no such binary, so the repo's
|
|
200
279
|
own suites run `moon run server:build` and point the kit at the result via
|
|
201
280
|
`ZITADEL_SERVER_BINARY` (the `withZitadel` option `zitadel.serverBinary` /
|
|
202
|
-
`serverBinaryHint` exists for this).
|
|
281
|
+
`serverBinaryHint` exists for this). Most in-repo moon tasks set
|
|
203
282
|
`NEXTGEN_SERVER_LOGIN_ENABLED=false` / `NEXTGEN_SERVER_CONSOLE_ENABLED=false`
|
|
204
|
-
|
|
205
|
-
|
|
283
|
+
because they drive the app-embedded login, not the server-hosted `/ui/*`; the
|
|
284
|
+
exception is `console-e2e:e2e-embedded`, which keeps both surfaces on and
|
|
285
|
+
omits `app` — the binary-served `/ui/*` pages are its subject. Customer
|
|
286
|
+
installs need none of this.
|
|
206
287
|
|
|
207
288
|
## Known limitations
|
|
208
289
|
|
|
@@ -211,8 +292,8 @@ Customer installs need none of this.
|
|
|
211
292
|
processes (Playwright workers) are unaffected.
|
|
212
293
|
- macOS/Linux only for now. Not because of the port preflight (it degrades
|
|
213
294
|
gracefully where `lsof` is missing) — the untested surface on Windows is the
|
|
214
|
-
process-group stop
|
|
215
|
-
runtime
|
|
295
|
+
process-group stop for the local binary runtime. Revisit when Windows local
|
|
296
|
+
runtime support is a goal.
|
|
216
297
|
|
|
217
298
|
## Roadmap
|
|
218
299
|
|
|
@@ -238,19 +319,20 @@ on top, in intended order:
|
|
|
238
319
|
`bootstrapProject({ baseUrl })` + `connectZitadel(handle)` already compose
|
|
239
320
|
into this today; formalizing it means cleanup semantics and docs.
|
|
240
321
|
5. **Vercel Sandbox runtime.** A publicly reachable ephemeral instance per
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
322
|
+
preview deployment (e.g. `@zitadel/testing/vercel`), returning the same
|
|
323
|
+
`InstanceHandle` so fixtures don't change. Gated on a spike: SQLite (or
|
|
324
|
+
another Sandbox-friendly store) on the Sandbox image, forwarded proto/host
|
|
325
|
+
handling, secure cookies + issuer + handoff verification through
|
|
326
|
+
`sandbox.domain()`, registering the preview URL as an allowed origin
|
|
327
|
+
post-deploy (`PATCH /projects`), and cleanup that survives failed runs.
|
|
247
328
|
6. **Publishing.** Landed: the consumer journey installs the kit the way a
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
into a shared package and swap the lifecycle
|
|
329
|
+
customer would in CI, and the kit ships on the release train (release
|
|
330
|
+
manifest + changeset `fixed` group), versioned in lockstep with
|
|
331
|
+
`@zitadel/cli`. Remaining: the Windows decision for the local binary
|
|
332
|
+
runtime and the stability commitment when the train leaves alpha.
|
|
333
|
+
|
|
334
|
+
Parked until server support exists: passkey *seeding* (pre-registered WebAuthn
|
|
335
|
+
credentials) — UI-driven passkey ceremonies are covered today by
|
|
336
|
+
`enableVirtualPasskey`. Independent refactor: extract
|
|
337
|
+
`apps/cli/src/lib/local-server` into a shared package and swap the lifecycle
|
|
338
|
+
shell-out for imports.
|
|
@@ -16,9 +16,9 @@ interface InstanceHandle {
|
|
|
16
16
|
*/
|
|
17
17
|
appOrigin?: string;
|
|
18
18
|
/**
|
|
19
|
-
* Server-assigned id of the seeded user schema.
|
|
20
|
-
*
|
|
21
|
-
* project credential.
|
|
19
|
+
* Server-assigned id of the seeded user schema. A user names it in `schema`
|
|
20
|
+
* and puts the schema-defined content under `attributes`, so seeding needs
|
|
21
|
+
* it alongside the project credential.
|
|
22
22
|
*/
|
|
23
23
|
schemaId: string;
|
|
24
24
|
previewSecret?: string;
|
|
@@ -119,4 +119,4 @@ declare const nextAppEnv: AppEnvTemplate;
|
|
|
119
119
|
declare function applyAppEnvTemplate(template: AppEnvTemplate, handle: InstanceHandle): Record<string, string>;
|
|
120
120
|
//#endregion
|
|
121
121
|
export { Identity as a, LocalZitadelRuntime as c, SeedUserInput as d, SeedUsersTemplate as f, ConnectedZitadel as i, MintedSession as l, SessionCookie as m, applyAppEnvTemplate as n, InstanceHandle as o, SeededUser as p, nextAppEnv as r, LocalZitadel as s, AppEnvTemplate as t, SeedSessionInput as u };
|
|
122
|
-
//# sourceMappingURL=app-env-
|
|
122
|
+
//# sourceMappingURL=app-env-Btmfcflb.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-env-
|
|
1
|
+
{"version":3,"file":"app-env-Btmfcflb.d.mts","names":[],"sources":["../src/types.ts","../src/app-env.ts"],"mappings":";;;;;AAMA;;UAAiB,cAAA;EACf,OAAA;EACA,SAAA;EACA,aAAA;EAAA;;;;;EAMA,SAAA;EAUe;;;;;EAJf,QAAA;EACA,aAAA;AAAA;AAAA,UAGe,aAAA;EACf,KAAA;EACA,QAAA;EAKyB;EAHzB,UAAA,GAAa,MAAA;AAAA;AAAA,UAGE,UAAA;EACf,EAAA;EACA,KAAA;EACA,QAAA;AAAA;AAIF;AAAA,UAAiB,QAAA;EACf,KAAA;EACA,QAAA;AAAA;AAIF;AAAA,UAAiB,aAAA;EACf,IAAA;EACA,KAAA;EACA,QAAA;EACA,MAAA;EACA,QAAA;EACA,IAAA;AAAA;AAAA,UAGe,aAAA;EACf,IAAA,EAAM,UAAA;EAJF;EAMJ,YAAA;EACA,SAAA;EACA,MAAA,EAAQ,aAAA;AAAA;AAAA,UAGO,gBAAA,SAAyB,aAAA;EAPlC;EASN,IAAA,GAAO,UAAA;EANP;EAQA,kBAAA;EAPQ;;;AAGV;;EAUE,MAAA;AAAA;AAAA,UAGe,iBAAA;EACf,KAAA,IAAS,KAAA;EACT,QAAA,IAAY,KAAA;EACZ,UAAA,IAAc,KAAA,aAAkB,MAAA;AAAA;AAAA,UAGjB,gBAAA;EACf,MAAA,EAAQ,cAAA;EAPO;EASf,GAAA,EAAK,aAAA;;EAEL,MAAA,EAAQ,MAAA;EACR,QAAA,CAAS,KAAA,GAAQ,aAAA,GAAgB,OAAA,CAAQ,UAAA;EAXhC;EAaT,SAAA,CAAU,KAAA,UAAe,QAAA,GAAW,iBAAA,GAAoB,OAAA,CAAQ,UAAA;EAZpD;EAcZ,QAAA,IAAY,QAAA;EAbE;;;;AAGhB;EAgBE,WAAA,CAAY,KAAA,GAAQ,gBAAA,GAAmB,OAAA,CAAQ,aAAA;AAAA;AAAA,UAGhC,mBAAA;EACf,IAAA;EACA,GAAA;EAfiB;EAiBjB,GAAA;EACA,OAAA;AAAA;AAAA,UAGe,YAAA,SAAqB,gBAAA,EAAkB,eAAA;EACtD,OAAA,EAAS,mBAAA;EACT,IAAA,IAAQ,OAAA;AAAA;;;;;AAxGV;;;;KCEY,cAAA,GAAiB,MAAA,eAAqB,cAAA;;;;;;cAOrC,UAAA,EAAY,cAAA;AAAA,iBAMT,mBAAA,CACd,QAAA,EAAU,cAAA,EACV,MAAA,EAAQ,cAAA,GACP,MAAA"}
|
package/dist/app-runner.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const require_handshake = require("./handshake-
|
|
1
|
+
const require_handshake = require("./handshake-CRKcgkfN.cjs");
|
|
2
2
|
const require_orchestration = require("./orchestration-D7QBgQ0l.cjs");
|
|
3
3
|
let node_child_process = require("node:child_process");
|
|
4
4
|
//#region src/app-runner.ts
|
package/dist/app-runner.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as applyAppEnvTemplate, n as waitForHandshake } from "./handshake-
|
|
1
|
+
import { i as applyAppEnvTemplate, n as waitForHandshake } from "./handshake-ClzWvG8z.mjs";
|
|
2
2
|
import { i as parseAppRunnerConfig, o as requireHandshakePath, t as APP_RUNNER_CONFIG_ENV } from "./orchestration-C640_1Lg.mjs";
|
|
3
3
|
import { spawn } from "node:child_process";
|
|
4
4
|
//#region src/app-runner.ts
|
|
@@ -53,13 +53,14 @@ async function waitForHandshake(path, timeoutMs = 6e4) {
|
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
function validateHandle(value, source) {
|
|
56
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) throw new Error(`handshake file ${source} is not an object`);
|
|
56
57
|
const handle = value;
|
|
57
58
|
for (const field of [
|
|
58
59
|
"baseUrl",
|
|
59
60
|
"projectId",
|
|
60
61
|
"projectSecret",
|
|
61
62
|
"schemaId"
|
|
62
|
-
]) if (typeof handle
|
|
63
|
+
]) if (typeof handle[field] !== "string" || handle[field].length === 0) throw new Error(`handshake file ${source} is missing "${field}"`);
|
|
63
64
|
if (!URL.canParse(handle.baseUrl)) throw new Error(`handshake file ${source} has a malformed "baseUrl": ${handle.baseUrl}`);
|
|
64
65
|
return handle;
|
|
65
66
|
}
|
|
@@ -95,4 +96,4 @@ Object.defineProperty(exports, "writeHandshake", {
|
|
|
95
96
|
}
|
|
96
97
|
});
|
|
97
98
|
|
|
98
|
-
//# sourceMappingURL=handshake-
|
|
99
|
+
//# sourceMappingURL=handshake-CRKcgkfN.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handshake-
|
|
1
|
+
{"version":3,"file":"handshake-CRKcgkfN.cjs","names":[],"sources":["../src/app-env.ts","../src/handshake.ts"],"sourcesContent":["import type { InstanceHandle } from \"./types\";\n\n/**\n * Declarative mapping from an app's env var names to InstanceHandle fields.\n * A template (not a function) so it can cross process boundaries: the\n * Playwright config serializes it into the app-runner's environment, where it\n * is applied to the handle read from the handshake file.\n */\nexport type AppEnvTemplate = Record<string, keyof InstanceHandle>;\n\n/**\n * The env shape `@zitadel/sdk-next` apps read. Other frameworks pass their own\n * template — the console maps the same handle fields to `VITE_*`/`CONSOLE_*`\n * names, for example.\n */\nexport const nextAppEnv: AppEnvTemplate = {\n ZITADEL_URL: \"baseUrl\",\n NEXT_PUBLIC_ZITADEL_PROJECT_ID: \"projectId\",\n ZITADEL_PROJECT_SECRET: \"projectSecret\",\n};\n\nexport function applyAppEnvTemplate(\n template: AppEnvTemplate,\n handle: InstanceHandle,\n): Record<string, string> {\n const env: Record<string, string> = {};\n for (const [name, field] of Object.entries(template)) {\n const value = handle[field];\n if (typeof value !== \"string\" || value.length === 0) {\n // Fail instead of silently dropping the var: an app booted without one\n // of its env vars produces a much harder-to-read failure downstream.\n throw new Error(\n `app env template maps \"${name}\" to handle field \"${field}\", which the instance handle does not carry`,\n );\n }\n env[name] = value;\n }\n return env;\n}\n","import { readFileSync } from \"node:fs\";\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\nimport { setTimeout as sleep } from \"node:timers/promises\";\n\nimport type { InstanceHandle } from \"./types\";\n\n/**\n * The handshake file carries an InstanceHandle across process boundaries:\n * written by the script that boots + bootstraps the instance, read by\n * Playwright workers (fixtures) and the app dev-server wrapper.\n */\nexport async function writeHandshake(path: string, handle: InstanceHandle): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, `${JSON.stringify(handle, null, 2)}\\n`, { mode: 0o600 });\n}\n\nexport function readHandshakeSync(path: string): InstanceHandle {\n const contents = readFileSync(path, \"utf8\");\n let value: unknown;\n try {\n value = JSON.parse(contents);\n } catch (error) {\n throw new Error(`handshake file ${path} contains invalid JSON: ${(error as Error).message}`, {\n cause: error,\n });\n }\n return validateHandle(value, path);\n}\n\nexport async function waitForHandshake(path: string, timeoutMs = 60_000): Promise<InstanceHandle> {\n const deadline = Date.now() + timeoutMs;\n for (;;) {\n try {\n return validateHandle(JSON.parse(await readFile(path, \"utf8\")), path);\n } catch (error) {\n if (Date.now() >= deadline) {\n throw new Error(\n `handshake file not readable within ${timeoutMs}ms: ${path} (${(error as Error).message})`,\n { cause: error },\n );\n }\n await sleep(250);\n }\n }\n}\n\nfunction validateHandle(value: unknown, source: string): InstanceHandle {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n throw new Error(`handshake file ${source} is not an object`);\n }\n const handle = value as Partial<InstanceHandle>;\n for (const field of [\"baseUrl\", \"projectId\", \"projectSecret\", \"schemaId\"] as const) {\n if (typeof handle[field] !== \"string\" || handle[field].length === 0) {\n throw new Error(`handshake file ${source} is missing \"${field}\"`);\n }\n }\n if (!URL.canParse(handle.baseUrl as string)) {\n throw new Error(`handshake file ${source} has a malformed \"baseUrl\": ${handle.baseUrl}`);\n }\n return handle as InstanceHandle;\n}\n"],"mappings":";;;;;;;;;;AAeA,MAAa,aAA6B;CACxC,aAAa;CACb,gCAAgC;CAChC,wBAAwB;CACzB;AAED,SAAgB,oBACd,UACA,QACwB;CACxB,MAAM,MAA8B,EAAE;AACtC,MAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,SAAS,EAAE;EACpD,MAAM,QAAQ,OAAO;AACrB,MAAI,OAAO,UAAU,YAAY,MAAM,WAAW,EAGhD,OAAM,IAAI,MACR,0BAA0B,KAAK,qBAAqB,MAAM,6CAC3D;AAEH,MAAI,QAAQ;;AAEd,QAAO;;;;;;;;;ACzBT,eAAsB,eAAe,MAAc,QAAuC;AACxF,QAAA,GAAA,iBAAA,QAAA,GAAA,UAAA,SAAoB,KAAK,EAAE,EAAE,WAAW,MAAM,CAAC;AAC/C,QAAA,GAAA,iBAAA,WAAgB,MAAM,GAAG,KAAK,UAAU,QAAQ,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAO,CAAC;;AAGhF,SAAgB,kBAAkB,MAA8B;CAC9D,MAAM,YAAA,GAAA,QAAA,cAAwB,MAAM,OAAO;CAC3C,IAAI;AACJ,KAAI;AACF,UAAQ,KAAK,MAAM,SAAS;UACrB,OAAO;AACd,QAAM,IAAI,MAAM,kBAAkB,KAAK,0BAA2B,MAAgB,WAAW,EAC3F,OAAO,OACR,CAAC;;AAEJ,QAAO,eAAe,OAAO,KAAK;;AAGpC,eAAsB,iBAAiB,MAAc,YAAY,KAAiC;CAChG,MAAM,WAAW,KAAK,KAAK,GAAG;AAC9B,SACE,KAAI;AACF,SAAO,eAAe,KAAK,MAAM,OAAA,GAAA,iBAAA,UAAe,MAAM,OAAO,CAAC,EAAE,KAAK;UAC9D,OAAO;AACd,MAAI,KAAK,KAAK,IAAI,SAChB,OAAM,IAAI,MACR,sCAAsC,UAAU,MAAM,KAAK,IAAK,MAAgB,QAAQ,IACxF,EAAE,OAAO,OAAO,CACjB;AAEH,SAAA,GAAA,qBAAA,YAAY,IAAI;;;AAKtB,SAAS,eAAe,OAAgB,QAAgC;AACtE,KAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,MAAM,QAAQ,MAAM,CACrE,OAAM,IAAI,MAAM,kBAAkB,OAAO,mBAAmB;CAE9D,MAAM,SAAS;AACf,MAAK,MAAM,SAAS;EAAC;EAAW;EAAa;EAAiB;EAAW,CACvE,KAAI,OAAO,OAAO,WAAW,YAAY,OAAO,OAAO,WAAW,EAChE,OAAM,IAAI,MAAM,kBAAkB,OAAO,eAAe,MAAM,GAAG;AAGrE,KAAI,CAAC,IAAI,SAAS,OAAO,QAAkB,CACzC,OAAM,IAAI,MAAM,kBAAkB,OAAO,8BAA8B,OAAO,UAAU;AAE1F,QAAO"}
|
|
@@ -53,17 +53,18 @@ async function waitForHandshake(path, timeoutMs = 6e4) {
|
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
function validateHandle(value, source) {
|
|
56
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) throw new Error(`handshake file ${source} is not an object`);
|
|
56
57
|
const handle = value;
|
|
57
58
|
for (const field of [
|
|
58
59
|
"baseUrl",
|
|
59
60
|
"projectId",
|
|
60
61
|
"projectSecret",
|
|
61
62
|
"schemaId"
|
|
62
|
-
]) if (typeof handle
|
|
63
|
+
]) if (typeof handle[field] !== "string" || handle[field].length === 0) throw new Error(`handshake file ${source} is missing "${field}"`);
|
|
63
64
|
if (!URL.canParse(handle.baseUrl)) throw new Error(`handshake file ${source} has a malformed "baseUrl": ${handle.baseUrl}`);
|
|
64
65
|
return handle;
|
|
65
66
|
}
|
|
66
67
|
//#endregion
|
|
67
68
|
export { nextAppEnv as a, applyAppEnvTemplate as i, waitForHandshake as n, writeHandshake as r, readHandshakeSync as t };
|
|
68
69
|
|
|
69
|
-
//# sourceMappingURL=handshake-
|
|
70
|
+
//# sourceMappingURL=handshake-ClzWvG8z.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handshake-
|
|
1
|
+
{"version":3,"file":"handshake-ClzWvG8z.mjs","names":["sleep"],"sources":["../src/app-env.ts","../src/handshake.ts"],"sourcesContent":["import type { InstanceHandle } from \"./types\";\n\n/**\n * Declarative mapping from an app's env var names to InstanceHandle fields.\n * A template (not a function) so it can cross process boundaries: the\n * Playwright config serializes it into the app-runner's environment, where it\n * is applied to the handle read from the handshake file.\n */\nexport type AppEnvTemplate = Record<string, keyof InstanceHandle>;\n\n/**\n * The env shape `@zitadel/sdk-next` apps read. Other frameworks pass their own\n * template — the console maps the same handle fields to `VITE_*`/`CONSOLE_*`\n * names, for example.\n */\nexport const nextAppEnv: AppEnvTemplate = {\n ZITADEL_URL: \"baseUrl\",\n NEXT_PUBLIC_ZITADEL_PROJECT_ID: \"projectId\",\n ZITADEL_PROJECT_SECRET: \"projectSecret\",\n};\n\nexport function applyAppEnvTemplate(\n template: AppEnvTemplate,\n handle: InstanceHandle,\n): Record<string, string> {\n const env: Record<string, string> = {};\n for (const [name, field] of Object.entries(template)) {\n const value = handle[field];\n if (typeof value !== \"string\" || value.length === 0) {\n // Fail instead of silently dropping the var: an app booted without one\n // of its env vars produces a much harder-to-read failure downstream.\n throw new Error(\n `app env template maps \"${name}\" to handle field \"${field}\", which the instance handle does not carry`,\n );\n }\n env[name] = value;\n }\n return env;\n}\n","import { readFileSync } from \"node:fs\";\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\nimport { setTimeout as sleep } from \"node:timers/promises\";\n\nimport type { InstanceHandle } from \"./types\";\n\n/**\n * The handshake file carries an InstanceHandle across process boundaries:\n * written by the script that boots + bootstraps the instance, read by\n * Playwright workers (fixtures) and the app dev-server wrapper.\n */\nexport async function writeHandshake(path: string, handle: InstanceHandle): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, `${JSON.stringify(handle, null, 2)}\\n`, { mode: 0o600 });\n}\n\nexport function readHandshakeSync(path: string): InstanceHandle {\n const contents = readFileSync(path, \"utf8\");\n let value: unknown;\n try {\n value = JSON.parse(contents);\n } catch (error) {\n throw new Error(`handshake file ${path} contains invalid JSON: ${(error as Error).message}`, {\n cause: error,\n });\n }\n return validateHandle(value, path);\n}\n\nexport async function waitForHandshake(path: string, timeoutMs = 60_000): Promise<InstanceHandle> {\n const deadline = Date.now() + timeoutMs;\n for (;;) {\n try {\n return validateHandle(JSON.parse(await readFile(path, \"utf8\")), path);\n } catch (error) {\n if (Date.now() >= deadline) {\n throw new Error(\n `handshake file not readable within ${timeoutMs}ms: ${path} (${(error as Error).message})`,\n { cause: error },\n );\n }\n await sleep(250);\n }\n }\n}\n\nfunction validateHandle(value: unknown, source: string): InstanceHandle {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n throw new Error(`handshake file ${source} is not an object`);\n }\n const handle = value as Partial<InstanceHandle>;\n for (const field of [\"baseUrl\", \"projectId\", \"projectSecret\", \"schemaId\"] as const) {\n if (typeof handle[field] !== \"string\" || handle[field].length === 0) {\n throw new Error(`handshake file ${source} is missing \"${field}\"`);\n }\n }\n if (!URL.canParse(handle.baseUrl as string)) {\n throw new Error(`handshake file ${source} has a malformed \"baseUrl\": ${handle.baseUrl}`);\n }\n return handle as InstanceHandle;\n}\n"],"mappings":";;;;;;;;;;AAeA,MAAa,aAA6B;CACxC,aAAa;CACb,gCAAgC;CAChC,wBAAwB;CACzB;AAED,SAAgB,oBACd,UACA,QACwB;CACxB,MAAM,MAA8B,EAAE;AACtC,MAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,SAAS,EAAE;EACpD,MAAM,QAAQ,OAAO;AACrB,MAAI,OAAO,UAAU,YAAY,MAAM,WAAW,EAGhD,OAAM,IAAI,MACR,0BAA0B,KAAK,qBAAqB,MAAM,6CAC3D;AAEH,MAAI,QAAQ;;AAEd,QAAO;;;;;;;;;ACzBT,eAAsB,eAAe,MAAc,QAAuC;AACxF,OAAM,MAAM,QAAQ,KAAK,EAAE,EAAE,WAAW,MAAM,CAAC;AAC/C,OAAM,UAAU,MAAM,GAAG,KAAK,UAAU,QAAQ,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAO,CAAC;;AAGhF,SAAgB,kBAAkB,MAA8B;CAC9D,MAAM,WAAW,aAAa,MAAM,OAAO;CAC3C,IAAI;AACJ,KAAI;AACF,UAAQ,KAAK,MAAM,SAAS;UACrB,OAAO;AACd,QAAM,IAAI,MAAM,kBAAkB,KAAK,0BAA2B,MAAgB,WAAW,EAC3F,OAAO,OACR,CAAC;;AAEJ,QAAO,eAAe,OAAO,KAAK;;AAGpC,eAAsB,iBAAiB,MAAc,YAAY,KAAiC;CAChG,MAAM,WAAW,KAAK,KAAK,GAAG;AAC9B,SACE,KAAI;AACF,SAAO,eAAe,KAAK,MAAM,MAAM,SAAS,MAAM,OAAO,CAAC,EAAE,KAAK;UAC9D,OAAO;AACd,MAAI,KAAK,KAAK,IAAI,SAChB,OAAM,IAAI,MACR,sCAAsC,UAAU,MAAM,KAAK,IAAK,MAAgB,QAAQ,IACxF,EAAE,OAAO,OAAO,CACjB;AAEH,QAAMA,WAAM,IAAI;;;AAKtB,SAAS,eAAe,OAAgB,QAAgC;AACtE,KAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,MAAM,QAAQ,MAAM,CACrE,OAAM,IAAI,MAAM,kBAAkB,OAAO,mBAAmB;CAE9D,MAAM,SAAS;AACf,MAAK,MAAM,SAAS;EAAC;EAAW;EAAa;EAAiB;EAAW,CACvE,KAAI,OAAO,OAAO,WAAW,YAAY,OAAO,OAAO,WAAW,EAChE,OAAM,IAAI,MAAM,kBAAkB,OAAO,eAAe,MAAM,GAAG;AAGrE,KAAI,CAAC,IAAI,SAAS,OAAO,QAAkB,CACzC,OAAM,IAAI,MAAM,kBAAkB,OAAO,8BAA8B,OAAO,UAAU;AAE1F,QAAO"}
|
package/dist/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_src = require("./src-
|
|
3
|
-
const require_handshake = require("./handshake-
|
|
2
|
+
const require_src = require("./src-I0KAh1zU.cjs");
|
|
3
|
+
const require_handshake = require("./handshake-CRKcgkfN.cjs");
|
|
4
4
|
exports.SESSION_COOKIE_NAME = require_src.SESSION_COOKIE_NAME;
|
|
5
5
|
exports.applyAppEnvTemplate = require_handshake.applyAppEnvTemplate;
|
|
6
6
|
exports.bootLocalServer = require_src.bootLocalServer;
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as Identity, c as LocalZitadelRuntime, d as SeedUserInput, f as SeedUsersTemplate, i as ConnectedZitadel, l as MintedSession, m as SessionCookie, n as applyAppEnvTemplate, o as InstanceHandle, p as SeededUser, r as nextAppEnv, s as LocalZitadel, t as AppEnvTemplate, u as SeedSessionInput } from "./app-env-
|
|
1
|
+
import { a as Identity, c as LocalZitadelRuntime, d as SeedUserInput, f as SeedUsersTemplate, i as ConnectedZitadel, l as MintedSession, m as SessionCookie, n as applyAppEnvTemplate, o as InstanceHandle, p as SeededUser, r as nextAppEnv, s as LocalZitadel, t as AppEnvTemplate, u as SeedSessionInput } from "./app-env-Btmfcflb.mjs";
|
|
2
2
|
import { ZitadelClient } from "@zitadel/api/client";
|
|
3
3
|
import { SetupPreset, SetupUseCase } from "@zitadel/config/defaults";
|
|
4
4
|
|
|
@@ -54,9 +54,8 @@ interface BootedServer {
|
|
|
54
54
|
/**
|
|
55
55
|
* Boot an ephemeral local server by shelling out to `zitadel start` and parse
|
|
56
56
|
* its JSON envelope. The CLI owns the subtle parts (port preflight, health
|
|
57
|
-
* wait, process-group stop
|
|
58
|
-
*
|
|
59
|
-
* shape returned here.
|
|
57
|
+
* wait, process-group stop), so this module stays a thin adapter; swapping it
|
|
58
|
+
* for direct library calls later must not change the shape returned here.
|
|
60
59
|
*/
|
|
61
60
|
declare function bootLocalServer(options?: BootServerOptions): Promise<BootedServer>;
|
|
62
61
|
//#endregion
|
|
@@ -83,7 +82,7 @@ type StartLocalZitadelOptions = BootServerOptions & Omit<BootstrapProjectOptions
|
|
|
83
82
|
*/
|
|
84
83
|
declare function connectZitadel(handle: InstanceHandle): ConnectedZitadel;
|
|
85
84
|
/**
|
|
86
|
-
* Boot an ephemeral local instance (binary runtime +
|
|
85
|
+
* Boot an ephemeral local instance (binary runtime + SQLite by default, no
|
|
87
86
|
* Docker) and bootstrap a project + default schema + login flow on it. The
|
|
88
87
|
* result can seed loginable password users immediately.
|
|
89
88
|
*/
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/bootstrap.ts","../src/lifecycle.ts","../src/handshake.ts","../src/session.ts","../src/index.ts"],"mappings":";;;;;UASiB,uBAAA;EACf,OAAA;EACA,WAAA;;AAFF;;;EAOE,UAAA;EACA,MAAA,GAAS,WAAA;EACT,OAAA,GAAU,YAAA;AAAA;AAAA,UAGK,mBAAA;EACf,SAAA;EACA,aAAA;EACA,aAAA;EACA,QAAA;EACA,MAAA;AAAA;;;;;;;iBAWoB,gBAAA,CACpB,OAAA,EAAS,uBAAA,GACR,OAAA,CAAQ,mBAAA;;;UCzBM,iBAAA;;EAEf,IAAA;;ADPF;;;ECYE,GAAA;EDXA;ECaA,YAAA;EDPA;ECSA,IAAA;EDRS;ECUT,MAAA;EACA,SAAA;AAAA;AAAA,UAGe,YAAA;EACf,OAAA;EACA,OAAA,EAAS,mBAAA;EACT,IAAA,IAAQ,OAAA;AAAA
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/bootstrap.ts","../src/lifecycle.ts","../src/handshake.ts","../src/session.ts","../src/index.ts"],"mappings":";;;;;UASiB,uBAAA;EACf,OAAA;EACA,WAAA;;AAFF;;;EAOE,UAAA;EACA,MAAA,GAAS,WAAA;EACT,OAAA,GAAU,YAAA;AAAA;AAAA,UAGK,mBAAA;EACf,SAAA;EACA,aAAA;EACA,aAAA;EACA,QAAA;EACA,MAAA;AAAA;;;;;;;iBAWoB,gBAAA,CACpB,OAAA,EAAS,uBAAA,GACR,OAAA,CAAQ,mBAAA;;;UCzBM,iBAAA;;EAEf,IAAA;;ADPF;;;ECYE,GAAA;EDXA;ECaA,YAAA;EDPA;ECSA,IAAA;EDRS;ECUT,MAAA;EACA,SAAA;AAAA;AAAA,UAGe,YAAA;EACf,OAAA;EACA,OAAA,EAAS,mBAAA;EACT,IAAA,IAAQ,OAAA;AAAA;;;;;;;iBASY,eAAA,CAAgB,OAAA,GAAS,iBAAA,GAAyB,OAAA,CAAQ,YAAA;;;;;;;ADlChF;iBEGsB,cAAA,CAAe,IAAA,UAAc,MAAA,EAAQ,cAAA,GAAiB,OAAA;AAAA,iBAK5D,iBAAA,CAAkB,IAAA,WAAe,cAAA;AAAA,iBAa3B,gBAAA,CAAiB,IAAA,UAAc,SAAA,YAAqB,OAAA,CAAQ,cAAA;;;;cCvBrE,mBAAA;;;KCED,wBAAA,GAA2B,iBAAA,GACrC,IAAA,CAAK,uBAAA;;AJDP;;;;iBIQgB,cAAA,CAAe,MAAA,EAAQ,cAAA,GAAiB,gBAAA;;;;;;iBA6BlC,iBAAA,CACpB,OAAA,GAAS,wBAAA,GACR,OAAA,CAAQ,YAAA"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { a as nextAppEnv, i as applyAppEnvTemplate, n as waitForHandshake, r as writeHandshake, t as readHandshakeSync } from "./handshake-
|
|
2
|
-
import { a as bootstrapProject, i as bootLocalServer, n as startLocalZitadel, r as SESSION_COOKIE_NAME, t as connectZitadel } from "./src-
|
|
1
|
+
import { a as nextAppEnv, i as applyAppEnvTemplate, n as waitForHandshake, r as writeHandshake, t as readHandshakeSync } from "./handshake-ClzWvG8z.mjs";
|
|
2
|
+
import { a as bootstrapProject, i as bootLocalServer, n as startLocalZitadel, r as SESSION_COOKIE_NAME, t as connectZitadel } from "./src-9dFjTIAw.mjs";
|
|
3
3
|
export { SESSION_COOKIE_NAME, applyAppEnvTemplate, bootLocalServer, bootstrapProject, connectZitadel, nextAppEnv, readHandshakeSync, startLocalZitadel, waitForHandshake, writeHandshake };
|