@lunora/runtime 1.0.0-alpha.2 → 1.0.0-alpha.20

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/dist/index.d.mts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { RankDirection, RankPageRow, DatabaseWriterLike } from '@lunora/do';
2
2
  export type { RankDirection as RankPageDirection, RankPageRowKey as RankPageKey, RankPageRow, ShardRankPageResult } from '@lunora/do';
3
3
  import { WorkflowsRestClient } from '@lunora/workflow';
4
+ import { LunoraError as LunoraError$1, ErrorBody } from '@lunora/errors';
4
5
  /**
5
6
  * Turn-key incremental-sync source helpers for warehouse connectors
6
7
  * (Fivetran custom functions, Airbyte incremental sources).
@@ -110,6 +111,38 @@ declare const toFivetranResponse: (page: ConnectorSyncPage, primaryKey?: Record<
110
111
  * @param emittedAt epoch-ms stamped on each `RECORD` (default `Date.now()`).
111
112
  */
112
113
  declare const toAirbyteMessages: (page: ConnectorSyncPage, emittedAt?: number) => AirbyteMessage[];
114
+ /**
115
+ * The subset of the Cloudflare `ExecutionContext` the Lunora worker entry and
116
+ * the framework mount seams rely on — `waitUntil` for fire-and-forget work that
117
+ * must outlive the response, and `passThroughOnException` for the top-level
118
+ * error posture.
119
+ *
120
+ * It is deliberately **not** a package. `@lunora/runtime` is the leaf server
121
+ * runtime and `@lunora/nuxt` is a framework integration that intentionally does
122
+ * not depend on `@lunora/runtime`'s worker types, yet both need this exact
123
+ * shape: the runtime to build/forward the worker `fetch`, Nuxt to forward an
124
+ * inbound request to the user's composed worker. Each imports this file by
125
+ * relative path and the bundler (packem/rollup) inlines it: no runtime
126
+ * dependency edge is created, the helper is duplicated only in emitted output,
127
+ * never in source. One source of truth, zero deps. See AGENTS.md → "Top-level
128
+ * `shared/` — bundler-inlined source".
129
+ *
130
+ * Both methods are **optional**: a real Cloudflare `ExecutionContext` always
131
+ * supplies them, but a host that mounts Lunora as a sub-handler (Nitro/H3, a
132
+ * non-Cloudflare preview, a unit test) may hand over a partial context or none
133
+ * at all. Callers therefore invoke them defensively (`ctx.waitUntil?.(…)`) or
134
+ * fall back to {@link NOOP_EXECUTION_CONTEXT}.
135
+ */
136
+ interface ExecutionContextLike {
137
+ passThroughOnException?: () => void;
138
+ waitUntil?: (promise: Promise<unknown>) => void;
139
+ }
140
+ /**
141
+ * No-op `ExecutionContext` used when the host runtime didn't supply one (a
142
+ * non-Cloudflare preview, or a unit test), so the worker's `fetch` always
143
+ * receives a valid third argument.
144
+ */
145
+ declare const NOOP_EXECUTION_CONTEXT: ExecutionContextLike;
113
146
  /** A timestamp as better-auth stores it: epoch-ms, an ISO string, or absent. */
114
147
  type AuthTimestamp = null | number | string;
115
148
  /**
@@ -164,6 +197,43 @@ interface AuthCapabilities {
164
197
  passkey: boolean;
165
198
  twoFactor: boolean;
166
199
  }
200
+ /** One user-settable extra field for the create-user form, derived from the merged `user` table. */
201
+ interface AuthUserFieldSpec {
202
+ name: string;
203
+ plugin?: string;
204
+ required: boolean;
205
+ type: "boolean" | "date" | "number" | "string";
206
+ unique: boolean;
207
+ }
208
+ /**
209
+ * Rich, read-only description of the deployment's auth configuration — enabled
210
+ * plugins, sign-in methods, user-settable fields, organization sub-features, and
211
+ * session / rate-limit policy — for the studio's config panel and dynamic
212
+ * create-user form. Never carries a secret.
213
+ */
214
+ interface AuthConfigInfo {
215
+ capabilities: AuthCapabilities;
216
+ emailAndPassword: boolean;
217
+ organization: {
218
+ enabled: boolean;
219
+ roles: boolean;
220
+ teams: boolean;
221
+ };
222
+ plugins: string[];
223
+ rateLimit: {
224
+ enabled: boolean;
225
+ max?: number;
226
+ window?: number;
227
+ };
228
+ session: {
229
+ cookieCache?: boolean;
230
+ expiresIn?: number;
231
+ freshAge?: number;
232
+ updateAge?: number;
233
+ };
234
+ socialProviders: string[];
235
+ userFields: AuthUserFieldSpec[];
236
+ }
167
237
  /** Filtering / paging options forwarded to {@link AuthAdmin.listUsers} from the users endpoint's query string. */
168
238
  interface ListAuthUsersOptions {
169
239
  filterField?: string;
@@ -188,6 +258,15 @@ interface ListAuthUsersOptions {
188
258
  * implementation is a trusted server-side operator, not an end-user API.
189
259
  */
190
260
  interface AuthAdmin {
261
+ addMember?: (input: {
262
+ organizationId: string;
263
+ role?: string;
264
+ userId: string;
265
+ }) => Promise<Record<string, unknown>>;
266
+ addTeamMember?: (input: {
267
+ teamId: string;
268
+ userId: string;
269
+ }) => Promise<Record<string, unknown>>;
191
270
  banUser?: (input: {
192
271
  expiresInSeconds?: number;
193
272
  reason?: string;
@@ -197,6 +276,23 @@ interface AuthAdmin {
197
276
  invitationId: string;
198
277
  }) => Promise<void>;
199
278
  capabilities?: () => Promise<AuthCapabilities>;
279
+ config?: () => Promise<AuthConfigInfo>;
280
+ createOrganization?: (input: {
281
+ logo?: string;
282
+ metadata?: Record<string, unknown>;
283
+ name: string;
284
+ ownerId?: string;
285
+ slug?: string;
286
+ }) => Promise<Record<string, unknown>>;
287
+ createOrgRole?: (input: {
288
+ organizationId: string;
289
+ permission: Record<string, string[]>;
290
+ role: string;
291
+ }) => Promise<Record<string, unknown>>;
292
+ createTeam?: (input: {
293
+ name: string;
294
+ organizationId: string;
295
+ }) => Promise<Record<string, unknown>>;
200
296
  createUser?: (input: {
201
297
  data?: Record<string, unknown>;
202
298
  email: string;
@@ -204,6 +300,12 @@ interface AuthAdmin {
204
300
  password?: string;
205
301
  role?: string | string[];
206
302
  }) => Promise<AuthUser>;
303
+ deleteOrganization?: (input: {
304
+ organizationId: string;
305
+ }) => Promise<void>;
306
+ deleteOrgRole?: (input: {
307
+ roleId: string;
308
+ }) => Promise<void>;
207
309
  deletePasskey?: (input: {
208
310
  passkeyId: string;
209
311
  }) => Promise<void>;
@@ -213,6 +315,12 @@ interface AuthAdmin {
213
315
  impersonateUser?: (input: {
214
316
  userId: string;
215
317
  }) => Promise<AuthImpersonation>;
318
+ inviteMember?: (input: {
319
+ email: string;
320
+ inviterId?: string;
321
+ organizationId: string;
322
+ role?: string;
323
+ }) => Promise<Record<string, unknown>>;
216
324
  listAccounts?: (input: {
217
325
  userId: string;
218
326
  }) => Promise<Record<string, unknown>[]>;
@@ -230,6 +338,11 @@ interface AuthAdmin {
230
338
  limit?: number;
231
339
  offset?: number;
232
340
  }) => Promise<AuthPage<Record<string, unknown>>>;
341
+ listOrgRoles?: (options: {
342
+ limit?: number;
343
+ offset?: number;
344
+ organizationId: string;
345
+ }) => Promise<AuthPage<Record<string, unknown>>>;
233
346
  listPasskeys?: (input: {
234
347
  userId: string;
235
348
  }) => Promise<Record<string, unknown>[]>;
@@ -238,10 +351,26 @@ interface AuthAdmin {
238
351
  offset?: number;
239
352
  userId?: string;
240
353
  }) => Promise<AuthPage<AuthSession>>;
354
+ listTeamMembers?: (options: {
355
+ limit?: number;
356
+ offset?: number;
357
+ teamId: string;
358
+ }) => Promise<AuthPage<Record<string, unknown>>>;
359
+ listTeams?: (options: {
360
+ limit?: number;
361
+ offset?: number;
362
+ organizationId: string;
363
+ }) => Promise<AuthPage<Record<string, unknown>>>;
241
364
  listUsers: (options: ListAuthUsersOptions) => Promise<AuthPage<AuthUser>>;
242
365
  removeMember?: (input: {
243
366
  memberId: string;
244
367
  }) => Promise<void>;
368
+ removeTeam?: (input: {
369
+ teamId: string;
370
+ }) => Promise<void>;
371
+ removeTeamMember?: (input: {
372
+ teamMemberId: string;
373
+ }) => Promise<void>;
245
374
  removeUser?: (input: {
246
375
  userId: string;
247
376
  }) => Promise<void>;
@@ -266,6 +395,25 @@ interface AuthAdmin {
266
395
  accountId: string;
267
396
  userId: string;
268
397
  }) => Promise<void>;
398
+ updateMemberRole?: (input: {
399
+ memberId: string;
400
+ role: string | string[];
401
+ }) => Promise<Record<string, unknown>>;
402
+ updateOrganization?: (input: {
403
+ logo?: string;
404
+ metadata?: Record<string, unknown>;
405
+ name?: string;
406
+ organizationId: string;
407
+ slug?: string;
408
+ }) => Promise<Record<string, unknown>>;
409
+ updateOrgRole?: (input: {
410
+ permission: Record<string, string[]>;
411
+ roleId: string;
412
+ }) => Promise<Record<string, unknown>>;
413
+ updateTeam?: (input: {
414
+ name: string;
415
+ teamId: string;
416
+ }) => Promise<Record<string, unknown>>;
269
417
  updateUser?: (input: {
270
418
  data: Record<string, unknown>;
271
419
  userId: string;
@@ -305,6 +453,182 @@ interface FunctionArgumentDescriptor {
305
453
  * kind only — enough for a signature view without a deep recursive walk.
306
454
  */
307
455
  /**
456
+ * Identity resolved from the inbound request by `WorkerOptions.resolveIdentity`.
457
+ *
458
+ * The `userId` field is special — it becomes `ctx.auth.userId` inside the
459
+ * Durable Object. Any other keys (`email`, `name`, custom roles, etc.) are
460
+ * forwarded verbatim as `ctx.auth.getIdentity()`'s return value.
461
+ *
462
+ * Return `null` to signal that the request is anonymous; the runtime will
463
+ * skip both `x-lunora-userid` and `x-lunora-identity` headers, and
464
+ * `ctx.auth.userId` will be `undefined` on the shard side.
465
+ */
466
+ interface ResolvedIdentity {
467
+ /** Arbitrary additional claims. Must be JSON-serialisable. */
468
+ [key: string]: unknown;
469
+ /**
470
+ * JWT-standard expiry in epoch SECONDS. When present (and `expiresAtMs` is
471
+ * absent), the runtime forwards it as the socket's credential expiry — the
472
+ * DO drops the socket once it lapses. Used only on the WebSocket path.
473
+ */
474
+ exp?: number;
475
+ /**
476
+ * Credential expiry in epoch MILLISECONDS. Preferred over `exp` when
477
+ * both are present. Forwarded as the socket's expiry on the WebSocket path
478
+ * so the DO drops the socket once it lapses; omit for non-expiring sessions.
479
+ */
480
+ expiresAtMs?: number;
481
+ /** Stable user identifier (e.g. `"user_2k3..."` or `"u_42"`). */
482
+ userId: string;
483
+ }
484
+ /**
485
+ * A verifier that turns an inbound request into a {@link ResolvedIdentity} (or
486
+ * `null` for anonymous). Structurally identical to `WorkerOptions.resolveIdentity`,
487
+ * so `.auth()`'s better-auth session resolver, a signed-preview-link verifier, a
488
+ * per-tenant bearer check, an upstream-JWT reader, … are all just `IdentityResolver`s
489
+ * — the identity layer is generic over every scheme, not coupled to any one.
490
+ */
491
+ type IdentityResolver = (request: Request, env: unknown) => Promise<ResolvedIdentity | null> | ResolvedIdentity | null;
492
+ /** Error policy for {@link composeIdentityResolvers} when a participant resolver throws. */
493
+ type ComposeIdentityResolversErrorMode = "fail-closed" | "skip";
494
+ /** Options for {@link composeIdentityResolvers}. */
495
+ interface ComposeIdentityResolversOptions {
496
+ /**
497
+ * What to do when a resolver throws. `"fail-closed"` (default, safe)
498
+ * re-throws so a broken verifier fails the request rather than silently
499
+ * falling through to a weaker one; `"skip"` swallows the error and tries the
500
+ * next resolver (use only when a resolver's failure genuinely means "not my
501
+ * scheme").
502
+ */
503
+ readonly onError?: ComposeIdentityResolversErrorMode;
504
+ }
505
+ /**
506
+ * Compose several {@link IdentityResolver}s into one, first-match-wins: each is
507
+ * tried in order and the first that returns a non-null identity short-circuits.
508
+ * Generic over every scheme — the better-auth session resolver (obtained via the
509
+ * builder's `derived.resolveIdentity` escape hatch) is just one entry in the list,
510
+ * so composition never means losing it.
511
+ *
512
+ * A resolver that throws is handled per {@link ComposeIdentityResolversOptions.onError}
513
+ * (default `"fail-closed"`: the error propagates).
514
+ */
515
+ declare const composeIdentityResolvers: (resolvers: ReadonlyArray<IdentityResolver>, options?: ComposeIdentityResolversOptions) => IdentityResolver;
516
+ /**
517
+ * A thin, generic helper over {@link composeIdentityResolvers} for the per-route case:
518
+ * pick a resolver by `new URL(request.url).pathname`. Keys are matched by longest
519
+ * path prefix; `"*"` is the fallback. Still fully generic — a route→resolver map,
520
+ * with no portal / preview / tenant concepts baked in (those live in the app's
521
+ * own resolvers).
522
+ * @example
523
+ * routeIdentityResolvers({ "/admin": adminResolver, "/partner": partnerResolver, "*": sessionResolver })
524
+ */
525
+ declare const routeIdentityResolvers: (routes: Record<string, IdentityResolver>) => IdentityResolver;
526
+ /** The result of validating a candidate identity against an {@link IdentityContractLike}. */
527
+ type IdentityValidation = {
528
+ ok: true;
529
+ } | {
530
+ error: string;
531
+ ok: false;
532
+ };
533
+ /**
534
+ * Structural view of `@lunora/server`'s `IdentityContract` (from `defineIdentity`).
535
+ * Kept structural so `@lunora/runtime` stays free of an `@lunora/server` dependency.
536
+ * Keep the `onInvalid` union and `validate`/`IdentityValidation` shapes in sync with
537
+ * `@lunora/server`'s `IdentityContract` — they are projected by hand, not imported.
538
+ * The generated worker entry passes the app's `defineIdentity(...)` result here;
539
+ * the worker validates every resolver's returned claims against it at the trust
540
+ * boundary before they become `ctx.auth`.
541
+ */
542
+ interface IdentityContractLike {
543
+ /** Reject policy applied when validation fails: downgrade to anonymous, or reject the request (401). */
544
+ readonly onInvalid: "anonymous" | "reject";
545
+ /** Validate resolver-returned claims against the declared contract. */
546
+ validate: (identity: Record<string, unknown>) => IdentityValidation;
547
+ }
548
+ /**
549
+ * The trust-boundary identity gate. Given the worker's `resolveIdentity` and an
550
+ * optional `defineIdentity(...)` contract, return a resolver that validates every
551
+ * resolved identity against the declared claims BEFORE it becomes `ctx.auth`.
552
+ *
553
+ * Claims arrive from untrusted tokens; a forged / malformed set is either
554
+ * downgraded to anonymous (`onInvalid: "anonymous"`, the safe default — the bad
555
+ * identity never reaches a policy as valid) or rejected with a `401`
556
+ * (`onInvalid: "reject"`), rather than flowing in as an unchecked cast. A valid
557
+ * identity is returned unchanged, so undeclared claims are forwarded verbatim.
558
+ *
559
+ * When no contract is configured (or there is no `resolveIdentity`), the original
560
+ * resolver is returned untouched — zero overhead and byte-identical behaviour.
561
+ * Only the public data paths (RPC / WebSocket / HTTP-action / server-query) use
562
+ * the wrapped resolver; the admin path keeps the raw one (admin is gated by the
563
+ * bearer / Access, not the app's identity contract).
564
+ */
565
+ /** One KV namespace as the studio's KV browser surfaces it. */
566
+ interface KvNamespaceSummary {
567
+ /** The wrangler/env binding name, e.g. `"MY_KV"`. */
568
+ binding: string;
569
+ }
570
+ /** One key entry as the KV admin browser surfaces it. */
571
+ interface KvKeyEntry {
572
+ /** Absolute expiration (Unix seconds), when set. */
573
+ expiration?: number;
574
+ /** Per-key metadata set at write time, or absent when none. */
575
+ metadata?: unknown;
576
+ /** The key name. */
577
+ name: string;
578
+ }
579
+ /** A paginated page of KV keys as the admin browser returns it. */
580
+ interface KvKeyListResult {
581
+ /** Opaque cursor for the next page; absent when the listing is complete. */
582
+ cursor?: string;
583
+ /** The keys on this page. */
584
+ keys: KvKeyEntry[];
585
+ /** True when this is the final page. */
586
+ listComplete: boolean;
587
+ }
588
+ /** A KV value together with its stored metadata. */
589
+ interface KvValueResult {
590
+ /** Per-key metadata, or `null` when none. */
591
+ metadata: unknown;
592
+ /** The stored value as a string, or `null` when the key is absent. */
593
+ value: null | string;
594
+ }
595
+ /**
596
+ * The introspector the worker wires for the studio's KV browser. Build it from
597
+ * the env's bound KV namespaces. Omit it and the `/_lunora/admin/kv/*`
598
+ * endpoints respond `KV_NOT_CONFIGURED`.
599
+ */
600
+ interface KvIntrospector {
601
+ /** Delete a key from a namespace. No-op when the key is absent. */
602
+ deleteKey: (options: {
603
+ key: string;
604
+ namespace: string;
605
+ }) => Promise<void>;
606
+ /** Read a value (as text) and its metadata from a namespace key. */
607
+ getValue: (options: {
608
+ key: string;
609
+ namespace: string;
610
+ }) => Promise<KvValueResult>;
611
+ /** List keys in a namespace, optionally filtered by prefix and paginated. */
612
+ listKeys: (options: {
613
+ cursor?: string;
614
+ limit?: number;
615
+ namespace: string;
616
+ prefix?: string;
617
+ }) => Promise<KvKeyListResult>;
618
+ /** List the registered KV namespaces (binding names). */
619
+ listNamespaces: () => Promise<KvNamespaceSummary[]>;
620
+ /** Write a value (as text) with optional absolute expiration / relative TTL and metadata. */
621
+ putValue: (options: {
622
+ expiration?: number;
623
+ expirationTtl?: number;
624
+ key: string;
625
+ metadata?: unknown;
626
+ namespace: string;
627
+ value: string;
628
+ }) => Promise<void>;
629
+ }
630
+ /** The worker internals the KV routes reach through injection rather than closure. */
631
+ /**
308
632
  * Observability hooks for the Lunora runtime.
309
633
  *
310
634
  * A user-supplied {@link ObservabilitySink} receives one event per dispatched
@@ -420,6 +744,14 @@ declare const emitRpcEvent: (sink: ObservabilitySink | undefined, event: Observa
420
744
  */
421
745
  declare const emitLogEvent: (sink: ObservabilitySink | undefined, event: LogEvent, context?: ObservabilitySinkContext) => void;
422
746
  /**
747
+ * Cloudflare Durable Object jurisdictions restrict where a DO runs and persists
748
+ * data, for data-residency / compliance regimes (GDPR, FedRAMP, US data
749
+ * residency). The set is open — Cloudflare adds values over time — so this is a
750
+ * widening union rather than a closed enum.
751
+ * @see https://developers.cloudflare.com/durable-objects/reference/data-location/
752
+ */
753
+ type DurableObjectJurisdiction = "eu" | "fedramp" | "us";
754
+ /**
423
755
  * Structural projection of the bits of `DurableObjectNamespace` the runtime
424
756
  * needs. Real workers-types defines a much wider surface; this lets us pass
425
757
  * unit-test doubles without coupling to `@cloudflare/workers-types`.
@@ -437,10 +769,29 @@ interface ShardNamespaceLike {
437
769
  fetch: (request: Request) => Promise<Response>;
438
770
  };
439
771
  idFromName: (name: string) => unknown;
772
+ /**
773
+ * Derive a jurisdiction-restricted subnamespace. Every ID and stub created
774
+ * from the returned namespace is pinned to `jurisdiction`. Optional because
775
+ * older workers-types releases (and unit-test doubles) may not expose it;
776
+ * {@link applyJurisdiction} fails closed when a jurisdiction is requested
777
+ * but this method is absent.
778
+ */
779
+ jurisdiction?: (jurisdiction: DurableObjectJurisdiction) => ShardNamespaceLike;
440
780
  }
441
781
  interface ResolvedShard {
442
782
  fetch: (request: Request) => Promise<Response>;
443
783
  }
784
+ /**
785
+ * Return a jurisdiction-restricted view of `namespace`, or `namespace`
786
+ * unchanged when no jurisdiction is configured.
787
+ *
788
+ * Fail-closed: if a jurisdiction is requested but the binding does not expose
789
+ * `.jurisdiction()` (an older workers-types, or a misconfigured test double),
790
+ * this throws rather than silently routing to the un-pinned global namespace —
791
+ * silently dropping a residency constraint would let data land outside the
792
+ * compliance boundary the caller asked for.
793
+ */
794
+ declare const applyJurisdiction: (namespace: ShardNamespaceLike, jurisdiction?: DurableObjectJurisdiction) => ShardNamespaceLike;
444
795
  /** Look up a shard stub by name, preferring `getByName` when present. */
445
796
  declare const resolveShard: (namespace: ShardNamespaceLike, shardKey: string) => ResolvedShard;
446
797
  /**
@@ -959,31 +1310,17 @@ interface ShardTrafficFanOutResult {
959
1310
  shards: ReadonlyArray<ShardTrafficEntry>;
960
1311
  }
961
1312
  declare const createQueryCoordinator: (options: QueryCoordinatorOptions) => QueryCoordinator;
962
- /**
963
- * Secure-by-default HTTP edge for the Lunora worker.
964
- *
965
- * The worker's top-level `fetch` (see `./create-worker`) is the single choke
966
- * point every response passes through — RPC, auth, admin, `httpRoute` handlers,
967
- * and the SSR fallback alike. This module supplies what is applied there:
968
- * `decorateResponse` adds baseline security headers plus, for allowed
969
- * cross-origin requests, the matching `Access-Control-Allow-*` headers (never
970
- * overwriting a header the inner handler set); `handleCorsPreflight` answers
971
- * `OPTIONS` preflights for allowlisted origins; `enforceOrigin` is a CSRF guard
972
- * that rejects state-changing, cookie-authenticated requests from untrusted
973
- * origins.
974
- *
975
- * Every layer is on by default and individually disable-able through the
976
- * `SecurityOptions` passed to `createWorker`. Resolution (`resolveSecurity`) is
977
- * pure and platform-agnostic — it touches only the global `Request`/`Response`/
978
- * `Headers`/`URL`, so it unit-tests under plain Node without workerd.
979
- */
980
1313
  /** Per-header overrides for {@link SecurityHeadersOptions}. `false` omits the header. */
981
1314
  interface SecurityHeadersOptions {
982
1315
  /**
983
1316
  * `Content-Security-Policy`. Omitted (`undefined`) applies a restrictive
984
- * default to **non-HTML** responses only, so an SSR page is never broken by
985
- * a policy it didn't opt into. Pass a string to apply that policy to every
986
- * response (HTML included); `false` to never send one.
1317
+ * `default-src 'none'` policy to **non-HTML** responses, and a conservative
1318
+ * hardening policy to **HTML** responses (`base-uri 'none'; frame-ancestors
1319
+ * 'self'; object-src 'none'`) this does NOT set `default-src`/`script-src`,
1320
+ * so it never blocks an SSR page's own scripts/styles/images/fetches, it only
1321
+ * locks down the `base` element, framing (mirroring the `SAMEORIGIN`
1322
+ * X-Frame-Options default), and legacy plugins. Pass a string to apply that
1323
+ * exact policy to every response (HTML included); `false` to never send one.
987
1324
  */
988
1325
  csp?: string | false;
989
1326
  /** `X-Frame-Options` (clickjacking). Defaults to `SAMEORIGIN`. `false` omits it. */
@@ -1032,7 +1369,7 @@ interface SecurityOptions {
1032
1369
  interface ResolvedHeaders {
1033
1370
  coop: string | undefined;
1034
1371
  csp: {
1035
- htmlToo: boolean;
1372
+ htmlValue: string | undefined;
1036
1373
  value: string;
1037
1374
  } | undefined;
1038
1375
  enabled: boolean;
@@ -1095,6 +1432,24 @@ declare const resolveSecurity: (security: SecurityOptions | undefined, env?: Rec
1095
1432
  * @returns a `403` Response when the origin is untrusted, or `undefined` when the request is allowed.
1096
1433
  */
1097
1434
  declare const enforceOrigin: (request: Request, resolved: ResolvedSecurity) => Response | undefined;
1435
+ /**
1436
+ * CSRF defense for the WebSocket upgrade (Cross-Site WebSocket Hijacking).
1437
+ *
1438
+ * A WS handshake is an HTTP `GET`, so {@link enforceOrigin}'s safe-method
1439
+ * exemption never fires for it — yet the browser auto-attaches the session
1440
+ * cookie to the handshake and WebSocket connections are NOT governed by
1441
+ * CORS/SOP. Without an explicit `Origin` check any page can open
1442
+ * `wss://app/_lunora/ws`, authenticate as the logged-in victim, and read the
1443
+ * victim's live queries + issue mutations as them. This guard closes that hole.
1444
+ *
1445
+ * Scoped to cookie-bearing upgrades — the only vector CSWSH can ride (a browser
1446
+ * attaches cookies but never a bearer token). Bearer/token/server-to-server
1447
+ * upgrades (no `Cookie`) are exempt. A browser ALWAYS sends `Origin` on a WS
1448
+ * handshake, so a missing/untrusted `Origin` on a cookie-bearing upgrade fails
1449
+ * closed (mirrors {@link enforceOrigin}).
1450
+ * @returns a `403` Response when the upgrade origin is untrusted, or `undefined` when it is allowed.
1451
+ */
1452
+
1098
1453
  /**
1099
1454
  * Answer a CORS preflight (`OPTIONS` carrying `Access-Control-Request-Method`)
1100
1455
  * for an allowlisted origin with a `204`. Returns `undefined` for non-preflight
@@ -1130,10 +1485,6 @@ interface RpcEnvelope {
1130
1485
  functionPath: string;
1131
1486
  shardKey?: string;
1132
1487
  }
1133
- interface ExecutionContextLike {
1134
- passThroughOnException: () => void;
1135
- waitUntil: (promise: Promise<unknown>) => void;
1136
- }
1137
1488
  type Route = (request: Request, env: unknown, context: ExecutionContextLike) => Promise<Response> | Response;
1138
1489
  /**
1139
1490
  * Context handed to HTTP-action handlers. Built per request by the worker; its
@@ -1168,35 +1519,6 @@ interface HttpRouterLike {
1168
1519
  fetch(request: Request, env?: unknown, context?: ExecutionContextLike): Promise<Response> | Response;
1169
1520
  }
1170
1521
  /**
1171
- * Identity resolved from the inbound request by {@link WorkerOptions.resolveIdentity}.
1172
- *
1173
- * The `userId` field is special — it becomes `ctx.auth.userId` inside the
1174
- * Durable Object. Any other keys (`email`, `name`, custom roles, etc.) are
1175
- * forwarded verbatim as `ctx.auth.getIdentity()`'s return value.
1176
- *
1177
- * Return `null` to signal that the request is anonymous; the runtime will
1178
- * skip both `x-lunora-userid` and `x-lunora-identity` headers, and
1179
- * `ctx.auth.userId` will be `undefined` on the shard side.
1180
- */
1181
- interface ResolvedIdentity {
1182
- /** Arbitrary additional claims. Must be JSON-serialisable. */
1183
- [key: string]: unknown;
1184
- /**
1185
- * JWT-standard expiry in epoch SECONDS. When present (and `expiresAtMs` is
1186
- * absent), the runtime forwards it as the socket's credential expiry — the
1187
- * DO drops the socket once it lapses. Used only on the WebSocket path.
1188
- */
1189
- exp?: number;
1190
- /**
1191
- * Credential expiry in epoch MILLISECONDS. Preferred over `exp` when
1192
- * both are present. Forwarded as the socket's expiry on the WebSocket path
1193
- * so the DO drops the socket once it lapses; omit for non-expiring sessions.
1194
- */
1195
- expiresAtMs?: number;
1196
- /** Stable user identifier (e.g. `"user_2k3..."` or `"u_42"`). */
1197
- userId: string;
1198
- }
1199
- /**
1200
1522
  * Per-table sharding metadata the admin import endpoint needs to route rows.
1201
1523
  * Structural so this package stays free of `@lunora/server`. The codegen-
1202
1524
  * generated worker entry passes a thin projection of the user's schema.
@@ -1472,6 +1794,12 @@ interface ScheduledControllerLike {
1472
1794
  */
1473
1795
  type CronHandler = (controller: ScheduledControllerLike, env: unknown, context: ExecutionContextLike) => Promise<void> | void;
1474
1796
  /**
1797
+ * A Cloudflare Queues push-consumer handler — the worker's `queue()` entry
1798
+ * forwards each delivered `MessageBatch` (typed `unknown` here to keep the
1799
+ * runtime decoupled from `@lunora/queue`'s structural batch type).
1800
+ */
1801
+ type QueueConsumerHandler = (batch: unknown, env: unknown, context: ExecutionContextLike) => Promise<void>;
1802
+ /**
1475
1803
  * A single code-defined cron job, shaped like an entry of the generated
1476
1804
  * `LUNORA_CRONS` map. `functionPath` is the `"namespace:fn"` to run, `args` its
1477
1805
  * bound arguments, and `name` the human label from the `cronJobs()` builder.
@@ -1553,6 +1881,22 @@ interface BackupManifest {
1553
1881
  tables?: string;
1554
1882
  }
1555
1883
  interface WorkerOptions {
1884
+ /**
1885
+ * An additional, async authorization gate for the `/_lunora/admin/*` plane
1886
+ * (the Studio's HTTP + WS endpoints), OR-ed with the static {@link WorkerOptions.adminToken}
1887
+ * bearer. When it resolves `true` for a request, that request is treated as
1888
+ * admin-authorized even without the bearer; when it resolves `false` (or is
1889
+ * unset) the bearer remains the only path. Evaluated once per admin request
1890
+ * and never on the RPC/WebSocket data hot path.
1891
+ *
1892
+ * The intended producer is `@lunora/cloudflare-access`'s `accessAdminGate(...)`,
1893
+ * which verifies the request's `Cf-Access-Jwt-Assertion` JWT and applies an
1894
+ * `isAdmin(claims)` predicate — so the Studio can sit behind Cloudflare Access
1895
+ * instead of (or alongside) a shared admin token. It takes only the request
1896
+ * (verification needs static team-domain/aud config + the remote JWKS, no env
1897
+ * binding), so it composes without threading async through every admin route.
1898
+ */
1899
+ adminGate?: (request: Request) => boolean | Promise<boolean>;
1556
1900
  /**
1557
1901
  * Admin bearer token expected by the export/import endpoints. When unset,
1558
1902
  * the endpoints respond with `ADMIN_FORBIDDEN` — the same posture the
@@ -1560,17 +1904,25 @@ interface WorkerOptions {
1560
1904
  */
1561
1905
  adminToken?: string;
1562
1906
  /**
1563
- * Acknowledge explicitly that sharded and fan-out access may be
1564
- * exercised by any caller (including unauthenticated ones) because no
1565
- * authorization callback is configured. When neither {@link WorkerOptions.authorizeShard}
1566
- * nor {@link WorkerOptions.authorizeFanOut} is set, naming a non-default shard or sending
1567
- * a fan-out envelope is authorization-open: this is the historical posture,
1568
- * preserved for backward compatibility. The runtime emits a single loud
1569
- * `console.warn` the first time such a request is seen so the gap is
1570
- * visible in logs. Set this to `true` to assert the posture is intentional
1571
- * and silence that warning. It does NOT change behaviour it is purely an
1572
- * acknowledgement flag and has no effect once an `authorize*` callback is
1573
- * configured.
1907
+ * Opt into an authorization-open posture for sharded and fan-out access.
1908
+ *
1909
+ * By default (this flag unset/`false`) the runtime FAILS CLOSED per
1910
+ * operation: naming a non-default shard (a potential cross-tenant hop) is
1911
+ * rejected with a `403` (`FORBIDDEN_SHARD`) unless
1912
+ * {@link WorkerOptions.authorizeShard} is configured, and a fan-out
1913
+ * envelope is rejected (`FORBIDDEN_FANOUT`) unless
1914
+ * {@link WorkerOptions.authorizeFanOut} is. Set this to `true` to allow
1915
+ * such requests from any caller (including unauthenticated ones)
1916
+ * appropriate only when every table is protected by per-row RLS. The
1917
+ * runtime then emits a single `console.warn` so the open posture stays
1918
+ * visible in logs. The flag is consulted per operation: it has no effect
1919
+ * on an operation whose own `authorize*` callback is configured (that
1920
+ * callback gates directly), but configuring only one of the two callbacks
1921
+ * does NOT cover the other operation.
1922
+ *
1923
+ * NOTE: this is a behaviour change from earlier alphas, where the same
1924
+ * situation was warn-once-then-allow. Apps that relied on client-chosen
1925
+ * shard keys without an `authorize*` callback must set this flag explicitly.
1574
1926
  */
1575
1927
  allowUnauthenticatedShardAccess?: boolean;
1576
1928
  /**
@@ -1737,11 +2089,51 @@ interface WorkerOptions {
1737
2089
  */
1738
2090
  httpRouter?: HttpRouterLike;
1739
2091
  /**
2092
+ * The declared identity claim contract (`defineIdentity(...)` from
2093
+ * `@lunora/server`), passed by the generated worker entry. When present, the
2094
+ * worker validates every `resolveIdentity` result against it at the trust
2095
+ * boundary (on the public data paths — RPC / WebSocket / HTTP-action /
2096
+ * server-query, never the admin path) *before* the claims become `ctx.auth`.
2097
+ * A resolver output that violates the contract is downgraded to anonymous or
2098
+ * rejected with a `401`, per the contract's `onInvalid`. Omitted → no
2099
+ * validation, and the identity stays the historical untyped claim bag.
2100
+ */
2101
+ identity?: IdentityContractLike;
2102
+ /**
1740
2103
  * Insert `.global()` rows for the admin import endpoint. When omitted,
1741
2104
  * rows targeting global tables are reported as hard errors.
1742
2105
  */
1743
2106
  importGlobals?: GlobalImportFunction;
1744
2107
  /**
2108
+ * Restrict every Durable Object this worker reaches — shard DOs, the
2109
+ * scheduler DO, the fan-out coordinator, subscriptions — to a Cloudflare
2110
+ * data-residency jurisdiction (`"eu"`, `"us"`, `"fedramp"`). The runtime
2111
+ * derives a jurisdiction-pinned subnamespace from {@link WorkerOptions.shardDO}
2112
+ * and {@link WorkerOptions.schedulerDO} once, so all routing inherits it.
2113
+ *
2114
+ * Fail-closed: if the bound namespace does not expose `.jurisdiction()`
2115
+ * (an older `@cloudflare/workers-types`), the worker throws rather than
2116
+ * silently routing to the un-pinned global namespace. Omit it for the
2117
+ * default, un-pinned behaviour.
2118
+ *
2119
+ * ⚠️ Set once, before the first deploy — changing it strands data. A DO name
2120
+ * maps to a *different* ID per jurisdiction, so toggling this on an existing
2121
+ * deployment makes every shard/scheduler call resolve to a new, empty DO; the
2122
+ * prior data stays in the old jurisdiction and is unreachable (no in-place
2123
+ * migration). Usually set via the schema's `.jurisdiction(...)`, which codegen
2124
+ * threads here.
2125
+ * @see https://developers.cloudflare.com/durable-objects/reference/data-location/
2126
+ */
2127
+ jurisdiction?: DurableObjectJurisdiction;
2128
+ /**
2129
+ * Introspector for Workers KV namespaces, backing the studio's KV browser
2130
+ * via `GET /_lunora/admin/kv/namespaces`, `GET /_lunora/admin/kv/keys`,
2131
+ * `GET|PUT|DELETE /_lunora/admin/kv/value`. Build it from the env's bound
2132
+ * KV namespaces with `createKvIntrospector` from `@lunora/bindings/kv`.
2133
+ * Omit it and those endpoints respond `KV_NOT_CONFIGURED`.
2134
+ */
2135
+ kvIntrospector?: KvIntrospector;
2136
+ /**
1745
2137
  * Optional telemetry sink. When supplied, the worker emits one
1746
2138
  * `onRpc` event per dispatched RPC (single-shard forward or fan-out)
1747
2139
  * with duration / ok / error / shardKey or fanOut metadata. Sink
@@ -1796,6 +2188,14 @@ interface WorkerOptions {
1796
2188
  */
1797
2189
  queryCoordinator?: QueryCoordinator;
1798
2190
  /**
2191
+ * Cloudflare Queues push-consumer handler — the worker's `queue(batch, …)`
2192
+ * entry forwards every delivered `MessageBatch` here. Built by codegen from
2193
+ * `lunora/queues.ts` (via `@lunora/queue`'s `dispatchQueueBatch`, which routes
2194
+ * by `batch.queue` to the matching `defineQueue` handler), so the runtime
2195
+ * stays decoupled from the queue package. Omitted when no push queues exist.
2196
+ */
2197
+ queue?: QueueConsumerHandler;
2198
+ /**
1799
2199
  * Resolve the calling identity from the inbound RPC request. Called once
1800
2200
  * per RPC (and per fan-out) before the request is forwarded to the
1801
2201
  * shard. The returned `userId` becomes `ctx.auth.userId` on the shard
@@ -1918,6 +2318,12 @@ interface RpcContext {
1918
2318
  */
1919
2319
  interface LunoraWorker {
1920
2320
  fetch: (request: Request, env: unknown, context: ExecutionContextLike) => Promise<Response>;
2321
+ /**
2322
+ * Cloudflare Queues consumer entry — present only when the app declares push
2323
+ * queues. Forwards each delivered `MessageBatch` to the configured
2324
+ * {@link WorkerOptions.queue} handler; a no-op when none is set.
2325
+ */
2326
+ queue?: (batch: unknown, env: unknown, context: ExecutionContextLike) => Promise<void>;
1921
2327
  scheduled: (controller: ScheduledControllerLike, env: unknown, context: ExecutionContextLike) => Promise<void>;
1922
2328
  /**
1923
2329
  * In-process query/mutation dispatch for SSR loaders co-located in this
@@ -2019,6 +2425,55 @@ type FrameworkWorkerOptionsInput = ((env: unknown) => FrameworkWorkerOptions) |
2019
2425
  * @param optionsInput Lunora options minus `httpRouter`, or an `(env) => options` factory.
2020
2426
  */
2021
2427
  declare const withFrameworkWorker: (host: FrameworkHostHandler, optionsInput: FrameworkWorkerOptionsInput) => LunoraWorker;
2428
+ /**
2429
+ * Options for {@link createLunoraHandler}. Either an `(env) => options` factory
2430
+ * (full control — for bindings that only exist at request time), or a partial
2431
+ * {@link FrameworkWorkerOptions} object whose `shardDO` defaults to the
2432
+ * conventional `env.SHARD` binding. Pass nothing for the common case.
2433
+ */
2434
+ type LunoraHandlerOptions = ((env: unknown) => FrameworkWorkerOptions) | Partial<FrameworkWorkerOptions>;
2435
+ /**
2436
+ * Resolve per-request Lunora worker options. A factory is called with the
2437
+ * request `env`; a partial object has its `shardDO` defaulted to `env.SHARD` so
2438
+ * the common case needs no configuration. Throws a clear error when no shard
2439
+ * namespace can be found — a wiring mistake, not a runtime condition to swallow.
2440
+ */
2441
+ declare const resolveLunoraOptions: (options: LunoraHandlerOptions, env: unknown) => FrameworkWorkerOptions;
2442
+ /**
2443
+ * Build a framework-neutral request handler for Lunora's realtime plane
2444
+ * (`/_lunora/rpc`, `/_lunora/ws`, `/_lunora/admin/*`). This is the **one shared
2445
+ * seam** every web-standard framework integration mounts — Hono, Nitro/h3,
2446
+ * Elysia, or any WinterCG host running on Cloudflare Workers — so each is a
2447
+ * 1–2 line bridge (`(request, env, ctx) => Response`) rather than a bespoke
2448
+ * adapter package.
2449
+ *
2450
+ * Mount it under `/_lunora/*` (or whatever path you reserve) inside your app's
2451
+ * router; everything else stays your framework's. The host supplies, per
2452
+ * request: a Web `Request`, the Cloudflare `env` (carrying the `SHARD` Durable
2453
+ * Object namespace), and — when available — the `ExecutionContext`. The
2454
+ * `101 Switching Protocols` WebSocket-upgrade `Response` (with its `webSocket`)
2455
+ * is returned verbatim, so the framework streams the socket through unchanged.
2456
+ *
2457
+ * ```ts
2458
+ * // Hono
2459
+ * const lunora = createLunoraHandler();
2460
+ * app.use("/_lunora/*", (c) => lunora(c.req.raw, c.env, c.executionCtx));
2461
+ *
2462
+ * // Nitro / h3
2463
+ * const lunora = createLunoraHandler();
2464
+ * export default defineEventHandler((event) => {
2465
+ * const { ctx, env } = event.context.cloudflare;
2466
+ * return lunora(toWebRequest(event), env, ctx);
2467
+ * });
2468
+ * ```
2469
+ *
2470
+ * `shardDO` defaults to `env.SHARD`; pass `options` (or an `(env) => options`
2471
+ * factory) to add `auth`, `crons`, a `security` posture, or a custom namespace.
2472
+ * A new worker is composed per request because the options (and the `SHARD`
2473
+ * binding they default from) are only known once `env` arrives.
2474
+ * @param options Partial worker options (default `shardDO: env.SHARD`), or an `(env) => options` factory.
2475
+ */
2476
+ declare const createLunoraHandler: (options?: LunoraHandlerOptions) => ((request: Request, env: unknown, context?: ExecutionContextLike) => Promise<Response>);
2022
2477
  /** Re-exported helper so callers can roundtrip envelopes in tests. */
2023
2478
  declare const defineRpcEnvelope: (envelope: RpcEnvelope) => RpcEnvelope;
2024
2479
  /**
@@ -2082,6 +2537,12 @@ interface DynamicShardRegistryOptions {
2082
2537
  * only if you run multiple isolated registries in one environment.
2083
2538
  */
2084
2539
  instanceName?: string;
2540
+ /**
2541
+ * Pin the registry DO to a Cloudflare data-residency jurisdiction. Pass the
2542
+ * same value as the worker's `jurisdiction` so the registry co-locates with
2543
+ * the shards it tracks. Omit for the un-pinned global namespace.
2544
+ */
2545
+ jurisdiction?: DurableObjectJurisdiction;
2085
2546
  /** DO namespace binding (`env.SHARD_REGISTRY`). */
2086
2547
  namespace: ShardNamespaceLike;
2087
2548
  }
@@ -2104,18 +2565,30 @@ interface DynamicShardRegistry extends ShardRegistry {
2104
2565
  }
2105
2566
  declare const createDynamicShardRegistry: (options: DynamicShardRegistryOptions) => DynamicShardRegistry;
2106
2567
  interface LunoraErrorBody {
2107
- error: {
2108
- code: string;
2109
- message: string;
2110
- };
2568
+ error: ErrorBody;
2111
2569
  }
2112
2570
  /**
2113
- * Error type recognised by the runtime's error middleware. Anything thrown
2114
- * that isn't a `LunoraError` is mapped to a generic 500 with code `INTERNAL`.
2571
+ * Convert any thrown value into a JSON error response.
2572
+ *
2573
+ * Delegates the envelope + redaction to `@lunora/errors`' {@link toErrorBody} —
2574
+ * a non-internal `LunoraError` (from `@lunora/server`, this runtime, or the
2575
+ * `@lunora/do` data layer) is echoed with its `code`/`message`/`hint`/`docsUrl`;
2576
+ * an internal-coded error keeps its status but its message is redacted; anything
2577
+ * else becomes a generic `INTERNAL` 500. All of these share the unified shape
2578
+ * recognized by `isLunoraError`.
2115
2579
  */
2116
- declare class LunoraError extends Error {
2117
- readonly code: string;
2118
- readonly status: number;
2580
+ declare const toErrorResponse: (error: unknown) => Response;
2581
+ /**
2582
+ * Transport-level error for the worker entry. A thin ergonomic wrapper over the
2583
+ * shared `@lunora/errors` `LunoraError` that keeps the runtime's historical
2584
+ * `(message, { code, status })` signature — the runtime mints these with
2585
+ * dispatch-specific codes (`METHOD_NOT_ALLOWED`, `*_NOT_CONFIGURED`, …) and an
2586
+ * explicit status, so they don't need a central catalog entry. Because it is a
2587
+ * real `LunoraError`, it carries the unified wire shape and is recognized by
2588
+ * `isLunoraError` everywhere. Anything thrown that isn't a `LunoraError`
2589
+ * is mapped to a generic 500 with code `INTERNAL`.
2590
+ */
2591
+ declare class LunoraError extends LunoraError$1 {
2119
2592
  constructor(message: string, options?: {
2120
2593
  cause?: unknown;
2121
2594
  code?: string;
@@ -2123,10 +2596,6 @@ declare class LunoraError extends Error {
2123
2596
  });
2124
2597
  toResponse(): Response;
2125
2598
  }
2126
- /** Shape recognised by the runtime's structural error checks. */
2127
-
2128
- /** Convert any thrown value into a JSON error response. */
2129
- declare const toErrorResponse: (error: unknown) => Response;
2130
2599
  /** Shared shape for sinks that can be limited to error events only. */
2131
2600
  interface OnlyErrorsOption {
2132
2601
  /** When true, only events with `ok === false` are forwarded. */
@@ -2256,4 +2725,4 @@ declare const analyticsEngineSink: (options: AnalyticsEngineSinkOptions) => Obse
2256
2725
  */
2257
2726
  declare const combineSinks: (...sinks: ObservabilitySink[]) => ObservabilitySink;
2258
2727
  declare const VERSION: string;
2259
- export { type AdminTableResolver, type AirbyteMessage, type AnalyticsEngineDataPointLike, type AnalyticsEngineDatasetLike, type AnalyticsEngineSinkOptions, type AuthAdmin, type AuthCapabilities, type AuthImpersonation, type AuthIntrospector, type AuthPage, type AuthSession, type AuthUser, type BackupManifest, type BackupStore, type ConnectorChange, type ConnectorSyncPage, type CorsOptions, type CronHandler, type CronJobDispatch, type CronJobInfo, type CrossShardCounter, type CrossShardReader, type CrossShardRelationCapabilities, type CrossShardRelationOptions, type CsrfOptions, DEFAULT_REGISTRY_CACHE_TTL_MS, type DynamicShardRegistry, type DynamicShardRegistryOptions, type ExecutionContextLike, type ExportFanOutRequest, type ExportFanOutResult, type FanOutRequest, type FanOutResult, type FanOutSpec, type FivetranResponse, type FrameworkHostHandler, type FrameworkWorkerOptions, type FrameworkWorkerOptionsInput, type FunctionDescriptor, type FunctionRegistryEntry, type FunctionRegistryLike, type GlobalExportFunction as GlobalExportFn, type GlobalImportFunction as GlobalImportFn, type GlobalIntrospector, type GlobalTableInfo as GlobalTableInfoMeta, type GlobalTablePage as GlobalTablePageMeta, type HttpActionContext, type HttpActionLike, type HttpRouterLike, type ImportFanOutRequest, type ImportFanOutResult, type ListAuthUsersOptions, type LogEvent, type LogLevel, LunoraError, type LunoraErrorBody, type LunoraWorker, type MergeStrategy, type MigrationFanOutRequest, type MigrationFanOutResult, type ObservabilityEvent, type ObservabilitySink, type ObservabilitySinkContext, type QueryCoordinator, type QueryCoordinatorOptions, type RankFanOutRequest, type RankFanOutResult, type RankPageFanOutRequest, type RankPageFanOutResult, type ResolvedSecurity, type ResolvedShard, type Route, type RpcContext, type RpcEnvelope, SHARD_REGISTRY_DO_NAME, type ScheduledControllerLike, type SecurityHeadersOptions, type SecurityOptions, type SentrySinkOptions, type ShardError, type ShardExportOutcome, type ShardImportOutcome, type ShardMigrationOutcome, type ShardNamespaceLike, type ShardRankOutcome, type ShardRankPageOutcome, type ShardRegistry, type ShardTrafficEntry, type ShardTrafficFanOutRequest, type ShardTrafficFanOutResult, type ShardingInfo, type StorageListFunction as StorageListFn, type StorageObject, VERSION, type VectorIndexSummary, type VectorIntrospector, type VectorQueryMatch, type WebhookSinkOptions, type WorkerOptions, analyticsEngineSink, combineSinks, composeWorker, consoleSink, createCrossShardRelationCapabilities, createDynamicShardRegistry, createQueryCoordinator, createStaticShardRegistry, createWorker, decorateResponse, defineRpcEnvelope, emitLogEvent, emitRpcEvent, enforceOrigin, handleCorsPreflight, mergeStrategyForAggregate, resolveSecurity, resolveShard, sentrySink, toAirbyteMessages, toErrorResponse, toFivetranResponse, webhookSink, withFrameworkWorker };
2728
+ export { type AdminTableResolver, type AirbyteMessage, type AnalyticsEngineDataPointLike, type AnalyticsEngineDatasetLike, type AnalyticsEngineSinkOptions, type AuthAdmin, type AuthCapabilities, type AuthConfigInfo, type AuthImpersonation, type AuthIntrospector, type AuthPage, type AuthSession, type AuthUser, type AuthUserFieldSpec, type BackupManifest, type BackupStore, type ComposeIdentityResolversErrorMode, type ComposeIdentityResolversOptions, type ConnectorChange, type ConnectorSyncPage, type CorsOptions, type CronHandler, type CronJobDispatch, type CronJobInfo, type CrossShardCounter, type CrossShardReader, type CrossShardRelationCapabilities, type CrossShardRelationOptions, type CsrfOptions, DEFAULT_REGISTRY_CACHE_TTL_MS, type DurableObjectJurisdiction, type DynamicShardRegistry, type DynamicShardRegistryOptions, type ExecutionContextLike, type ExportFanOutRequest, type ExportFanOutResult, type FanOutRequest, type FanOutResult, type FanOutSpec, type FivetranResponse, type FrameworkHostHandler, type FrameworkWorkerOptions, type FrameworkWorkerOptionsInput, type FunctionDescriptor, type FunctionRegistryEntry, type FunctionRegistryLike, type GlobalExportFunction as GlobalExportFn, type GlobalImportFunction as GlobalImportFn, type GlobalIntrospector, type GlobalTableInfo as GlobalTableInfoMeta, type GlobalTablePage as GlobalTablePageMeta, type HttpActionContext, type HttpActionLike, type HttpRouterLike, type IdentityContractLike, type IdentityResolver, type IdentityValidation, type ImportFanOutRequest, type ImportFanOutResult, type KvIntrospector, type KvKeyEntry, type KvKeyListResult, type KvNamespaceSummary, type KvValueResult, type ListAuthUsersOptions, type LogEvent, type LogLevel, LunoraError, type LunoraErrorBody, type LunoraHandlerOptions, type LunoraWorker, type MergeStrategy, type MigrationFanOutRequest, type MigrationFanOutResult, NOOP_EXECUTION_CONTEXT, type ObservabilityEvent, type ObservabilitySink, type ObservabilitySinkContext, type QueryCoordinator, type QueryCoordinatorOptions, type RankFanOutRequest, type RankFanOutResult, type RankPageFanOutRequest, type RankPageFanOutResult, type ResolvedSecurity, type ResolvedShard, type Route, type RpcContext, type RpcEnvelope, SHARD_REGISTRY_DO_NAME, type ScheduledControllerLike, type SecurityHeadersOptions, type SecurityOptions, type SentrySinkOptions, type ShardError, type ShardExportOutcome, type ShardImportOutcome, type ShardMigrationOutcome, type ShardNamespaceLike, type ShardRankOutcome, type ShardRankPageOutcome, type ShardRegistry, type ShardTrafficEntry, type ShardTrafficFanOutRequest, type ShardTrafficFanOutResult, type ShardingInfo, type StorageListFunction as StorageListFn, type StorageObject, VERSION, type VectorIndexSummary, type VectorIntrospector, type VectorQueryMatch, type WebhookSinkOptions, type WorkerOptions, analyticsEngineSink, applyJurisdiction, combineSinks, composeIdentityResolvers, composeWorker, consoleSink, createCrossShardRelationCapabilities, createDynamicShardRegistry, createLunoraHandler, createQueryCoordinator, createStaticShardRegistry, createWorker, decorateResponse, defineRpcEnvelope, emitLogEvent, emitRpcEvent, enforceOrigin, handleCorsPreflight, mergeStrategyForAggregate, resolveLunoraOptions, resolveSecurity, resolveShard, routeIdentityResolvers, sentrySink, toAirbyteMessages, toErrorResponse, toFivetranResponse, webhookSink, withFrameworkWorker };