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

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.ts 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,44 @@ 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
+ cache?: {
138
+ purge: (options: {
139
+ purgeEverything?: boolean;
140
+ tags?: string[];
141
+ }) => Promise<unknown>;
142
+ };
143
+ passThroughOnException?: () => void;
144
+ waitUntil?: (promise: Promise<unknown>) => void;
145
+ }
146
+ /**
147
+ * No-op `ExecutionContext` used when the host runtime didn't supply one (a
148
+ * non-Cloudflare preview, or a unit test), so the worker's `fetch` always
149
+ * receives a valid third argument.
150
+ */
151
+ declare const NOOP_EXECUTION_CONTEXT: ExecutionContextLike;
113
152
  /** A timestamp as better-auth stores it: epoch-ms, an ISO string, or absent. */
114
153
  type AuthTimestamp = null | number | string;
115
154
  /**
@@ -164,6 +203,43 @@ interface AuthCapabilities {
164
203
  passkey: boolean;
165
204
  twoFactor: boolean;
166
205
  }
206
+ /** One user-settable extra field for the create-user form, derived from the merged `user` table. */
207
+ interface AuthUserFieldSpec {
208
+ name: string;
209
+ plugin?: string;
210
+ required: boolean;
211
+ type: "boolean" | "date" | "number" | "string";
212
+ unique: boolean;
213
+ }
214
+ /**
215
+ * Rich, read-only description of the deployment's auth configuration — enabled
216
+ * plugins, sign-in methods, user-settable fields, organization sub-features, and
217
+ * session / rate-limit policy — for the studio's config panel and dynamic
218
+ * create-user form. Never carries a secret.
219
+ */
220
+ interface AuthConfigInfo {
221
+ capabilities: AuthCapabilities;
222
+ emailAndPassword: boolean;
223
+ organization: {
224
+ enabled: boolean;
225
+ roles: boolean;
226
+ teams: boolean;
227
+ };
228
+ plugins: string[];
229
+ rateLimit: {
230
+ enabled: boolean;
231
+ max?: number;
232
+ window?: number;
233
+ };
234
+ session: {
235
+ cookieCache?: boolean;
236
+ expiresIn?: number;
237
+ freshAge?: number;
238
+ updateAge?: number;
239
+ };
240
+ socialProviders: string[];
241
+ userFields: AuthUserFieldSpec[];
242
+ }
167
243
  /** Filtering / paging options forwarded to {@link AuthAdmin.listUsers} from the users endpoint's query string. */
168
244
  interface ListAuthUsersOptions {
169
245
  filterField?: string;
@@ -188,6 +264,15 @@ interface ListAuthUsersOptions {
188
264
  * implementation is a trusted server-side operator, not an end-user API.
189
265
  */
190
266
  interface AuthAdmin {
267
+ addMember?: (input: {
268
+ organizationId: string;
269
+ role?: string;
270
+ userId: string;
271
+ }) => Promise<Record<string, unknown>>;
272
+ addTeamMember?: (input: {
273
+ teamId: string;
274
+ userId: string;
275
+ }) => Promise<Record<string, unknown>>;
191
276
  banUser?: (input: {
192
277
  expiresInSeconds?: number;
193
278
  reason?: string;
@@ -197,6 +282,23 @@ interface AuthAdmin {
197
282
  invitationId: string;
198
283
  }) => Promise<void>;
199
284
  capabilities?: () => Promise<AuthCapabilities>;
285
+ config?: () => Promise<AuthConfigInfo>;
286
+ createOrganization?: (input: {
287
+ logo?: string;
288
+ metadata?: Record<string, unknown>;
289
+ name: string;
290
+ ownerId?: string;
291
+ slug?: string;
292
+ }) => Promise<Record<string, unknown>>;
293
+ createOrgRole?: (input: {
294
+ organizationId: string;
295
+ permission: Record<string, string[]>;
296
+ role: string;
297
+ }) => Promise<Record<string, unknown>>;
298
+ createTeam?: (input: {
299
+ name: string;
300
+ organizationId: string;
301
+ }) => Promise<Record<string, unknown>>;
200
302
  createUser?: (input: {
201
303
  data?: Record<string, unknown>;
202
304
  email: string;
@@ -204,6 +306,12 @@ interface AuthAdmin {
204
306
  password?: string;
205
307
  role?: string | string[];
206
308
  }) => Promise<AuthUser>;
309
+ deleteOrganization?: (input: {
310
+ organizationId: string;
311
+ }) => Promise<void>;
312
+ deleteOrgRole?: (input: {
313
+ roleId: string;
314
+ }) => Promise<void>;
207
315
  deletePasskey?: (input: {
208
316
  passkeyId: string;
209
317
  }) => Promise<void>;
@@ -213,6 +321,12 @@ interface AuthAdmin {
213
321
  impersonateUser?: (input: {
214
322
  userId: string;
215
323
  }) => Promise<AuthImpersonation>;
324
+ inviteMember?: (input: {
325
+ email: string;
326
+ inviterId?: string;
327
+ organizationId: string;
328
+ role?: string;
329
+ }) => Promise<Record<string, unknown>>;
216
330
  listAccounts?: (input: {
217
331
  userId: string;
218
332
  }) => Promise<Record<string, unknown>[]>;
@@ -230,6 +344,11 @@ interface AuthAdmin {
230
344
  limit?: number;
231
345
  offset?: number;
232
346
  }) => Promise<AuthPage<Record<string, unknown>>>;
347
+ listOrgRoles?: (options: {
348
+ limit?: number;
349
+ offset?: number;
350
+ organizationId: string;
351
+ }) => Promise<AuthPage<Record<string, unknown>>>;
233
352
  listPasskeys?: (input: {
234
353
  userId: string;
235
354
  }) => Promise<Record<string, unknown>[]>;
@@ -238,10 +357,26 @@ interface AuthAdmin {
238
357
  offset?: number;
239
358
  userId?: string;
240
359
  }) => Promise<AuthPage<AuthSession>>;
360
+ listTeamMembers?: (options: {
361
+ limit?: number;
362
+ offset?: number;
363
+ teamId: string;
364
+ }) => Promise<AuthPage<Record<string, unknown>>>;
365
+ listTeams?: (options: {
366
+ limit?: number;
367
+ offset?: number;
368
+ organizationId: string;
369
+ }) => Promise<AuthPage<Record<string, unknown>>>;
241
370
  listUsers: (options: ListAuthUsersOptions) => Promise<AuthPage<AuthUser>>;
242
371
  removeMember?: (input: {
243
372
  memberId: string;
244
373
  }) => Promise<void>;
374
+ removeTeam?: (input: {
375
+ teamId: string;
376
+ }) => Promise<void>;
377
+ removeTeamMember?: (input: {
378
+ teamMemberId: string;
379
+ }) => Promise<void>;
245
380
  removeUser?: (input: {
246
381
  userId: string;
247
382
  }) => Promise<void>;
@@ -266,6 +401,25 @@ interface AuthAdmin {
266
401
  accountId: string;
267
402
  userId: string;
268
403
  }) => Promise<void>;
404
+ updateMemberRole?: (input: {
405
+ memberId: string;
406
+ role: string | string[];
407
+ }) => Promise<Record<string, unknown>>;
408
+ updateOrganization?: (input: {
409
+ logo?: string;
410
+ metadata?: Record<string, unknown>;
411
+ name?: string;
412
+ organizationId: string;
413
+ slug?: string;
414
+ }) => Promise<Record<string, unknown>>;
415
+ updateOrgRole?: (input: {
416
+ permission: Record<string, string[]>;
417
+ roleId: string;
418
+ }) => Promise<Record<string, unknown>>;
419
+ updateTeam?: (input: {
420
+ name: string;
421
+ teamId: string;
422
+ }) => Promise<Record<string, unknown>>;
269
423
  updateUser?: (input: {
270
424
  data: Record<string, unknown>;
271
425
  userId: string;
@@ -305,6 +459,182 @@ interface FunctionArgumentDescriptor {
305
459
  * kind only — enough for a signature view without a deep recursive walk.
306
460
  */
307
461
  /**
462
+ * Identity resolved from the inbound request by `WorkerOptions.resolveIdentity`.
463
+ *
464
+ * The `userId` field is special — it becomes `ctx.auth.userId` inside the
465
+ * Durable Object. Any other keys (`email`, `name`, custom roles, etc.) are
466
+ * forwarded verbatim as `ctx.auth.getIdentity()`'s return value.
467
+ *
468
+ * Return `null` to signal that the request is anonymous; the runtime will
469
+ * skip both `x-lunora-userid` and `x-lunora-identity` headers, and
470
+ * `ctx.auth.userId` will be `undefined` on the shard side.
471
+ */
472
+ interface ResolvedIdentity {
473
+ /** Arbitrary additional claims. Must be JSON-serialisable. */
474
+ [key: string]: unknown;
475
+ /**
476
+ * JWT-standard expiry in epoch SECONDS. When present (and `expiresAtMs` is
477
+ * absent), the runtime forwards it as the socket's credential expiry — the
478
+ * DO drops the socket once it lapses. Used only on the WebSocket path.
479
+ */
480
+ exp?: number;
481
+ /**
482
+ * Credential expiry in epoch MILLISECONDS. Preferred over `exp` when
483
+ * both are present. Forwarded as the socket's expiry on the WebSocket path
484
+ * so the DO drops the socket once it lapses; omit for non-expiring sessions.
485
+ */
486
+ expiresAtMs?: number;
487
+ /** Stable user identifier (e.g. `"user_2k3..."` or `"u_42"`). */
488
+ userId: string;
489
+ }
490
+ /**
491
+ * A verifier that turns an inbound request into a {@link ResolvedIdentity} (or
492
+ * `null` for anonymous). Structurally identical to `WorkerOptions.resolveIdentity`,
493
+ * so `.auth()`'s better-auth session resolver, a signed-preview-link verifier, a
494
+ * per-tenant bearer check, an upstream-JWT reader, … are all just `IdentityResolver`s
495
+ * — the identity layer is generic over every scheme, not coupled to any one.
496
+ */
497
+ type IdentityResolver = (request: Request, env: unknown) => Promise<ResolvedIdentity | null> | ResolvedIdentity | null;
498
+ /** Error policy for {@link composeIdentityResolvers} when a participant resolver throws. */
499
+ type ComposeIdentityResolversErrorMode = "fail-closed" | "skip";
500
+ /** Options for {@link composeIdentityResolvers}. */
501
+ interface ComposeIdentityResolversOptions {
502
+ /**
503
+ * What to do when a resolver throws. `"fail-closed"` (default, safe)
504
+ * re-throws so a broken verifier fails the request rather than silently
505
+ * falling through to a weaker one; `"skip"` swallows the error and tries the
506
+ * next resolver (use only when a resolver's failure genuinely means "not my
507
+ * scheme").
508
+ */
509
+ readonly onError?: ComposeIdentityResolversErrorMode;
510
+ }
511
+ /**
512
+ * Compose several {@link IdentityResolver}s into one, first-match-wins: each is
513
+ * tried in order and the first that returns a non-null identity short-circuits.
514
+ * Generic over every scheme — the better-auth session resolver (obtained via the
515
+ * builder's `derived.resolveIdentity` escape hatch) is just one entry in the list,
516
+ * so composition never means losing it.
517
+ *
518
+ * A resolver that throws is handled per {@link ComposeIdentityResolversOptions.onError}
519
+ * (default `"fail-closed"`: the error propagates).
520
+ */
521
+ declare const composeIdentityResolvers: (resolvers: ReadonlyArray<IdentityResolver>, options?: ComposeIdentityResolversOptions) => IdentityResolver;
522
+ /**
523
+ * A thin, generic helper over {@link composeIdentityResolvers} for the per-route case:
524
+ * pick a resolver by `new URL(request.url).pathname`. Keys are matched by longest
525
+ * path prefix; `"*"` is the fallback. Still fully generic — a route→resolver map,
526
+ * with no portal / preview / tenant concepts baked in (those live in the app's
527
+ * own resolvers).
528
+ * @example
529
+ * routeIdentityResolvers({ "/admin": adminResolver, "/partner": partnerResolver, "*": sessionResolver })
530
+ */
531
+ declare const routeIdentityResolvers: (routes: Record<string, IdentityResolver>) => IdentityResolver;
532
+ /** The result of validating a candidate identity against an {@link IdentityContractLike}. */
533
+ type IdentityValidation = {
534
+ ok: true;
535
+ } | {
536
+ error: string;
537
+ ok: false;
538
+ };
539
+ /**
540
+ * Structural view of `@lunora/server`'s `IdentityContract` (from `defineIdentity`).
541
+ * Kept structural so `@lunora/runtime` stays free of an `@lunora/server` dependency.
542
+ * Keep the `onInvalid` union and `validate`/`IdentityValidation` shapes in sync with
543
+ * `@lunora/server`'s `IdentityContract` — they are projected by hand, not imported.
544
+ * The generated worker entry passes the app's `defineIdentity(...)` result here;
545
+ * the worker validates every resolver's returned claims against it at the trust
546
+ * boundary before they become `ctx.auth`.
547
+ */
548
+ interface IdentityContractLike {
549
+ /** Reject policy applied when validation fails: downgrade to anonymous, or reject the request (401). */
550
+ readonly onInvalid: "anonymous" | "reject";
551
+ /** Validate resolver-returned claims against the declared contract. */
552
+ validate: (identity: Record<string, unknown>) => IdentityValidation;
553
+ }
554
+ /**
555
+ * The trust-boundary identity gate. Given the worker's `resolveIdentity` and an
556
+ * optional `defineIdentity(...)` contract, return a resolver that validates every
557
+ * resolved identity against the declared claims BEFORE it becomes `ctx.auth`.
558
+ *
559
+ * Claims arrive from untrusted tokens; a forged / malformed set is either
560
+ * downgraded to anonymous (`onInvalid: "anonymous"`, the safe default — the bad
561
+ * identity never reaches a policy as valid) or rejected with a `401`
562
+ * (`onInvalid: "reject"`), rather than flowing in as an unchecked cast. A valid
563
+ * identity is returned unchanged, so undeclared claims are forwarded verbatim.
564
+ *
565
+ * When no contract is configured (or there is no `resolveIdentity`), the original
566
+ * resolver is returned untouched — zero overhead and byte-identical behaviour.
567
+ * Only the public data paths (RPC / WebSocket / HTTP-action / server-query) use
568
+ * the wrapped resolver; the admin path keeps the raw one (admin is gated by the
569
+ * bearer / Access, not the app's identity contract).
570
+ */
571
+ /** One KV namespace as the studio's KV browser surfaces it. */
572
+ interface KvNamespaceSummary {
573
+ /** The wrangler/env binding name, e.g. `"MY_KV"`. */
574
+ binding: string;
575
+ }
576
+ /** One key entry as the KV admin browser surfaces it. */
577
+ interface KvKeyEntry {
578
+ /** Absolute expiration (Unix seconds), when set. */
579
+ expiration?: number;
580
+ /** Per-key metadata set at write time, or absent when none. */
581
+ metadata?: unknown;
582
+ /** The key name. */
583
+ name: string;
584
+ }
585
+ /** A paginated page of KV keys as the admin browser returns it. */
586
+ interface KvKeyListResult {
587
+ /** Opaque cursor for the next page; absent when the listing is complete. */
588
+ cursor?: string;
589
+ /** The keys on this page. */
590
+ keys: KvKeyEntry[];
591
+ /** True when this is the final page. */
592
+ listComplete: boolean;
593
+ }
594
+ /** A KV value together with its stored metadata. */
595
+ interface KvValueResult {
596
+ /** Per-key metadata, or `null` when none. */
597
+ metadata: unknown;
598
+ /** The stored value as a string, or `null` when the key is absent. */
599
+ value: null | string;
600
+ }
601
+ /**
602
+ * The introspector the worker wires for the studio's KV browser. Build it from
603
+ * the env's bound KV namespaces. Omit it and the `/_lunora/admin/kv/*`
604
+ * endpoints respond `KV_NOT_CONFIGURED`.
605
+ */
606
+ interface KvIntrospector {
607
+ /** Delete a key from a namespace. No-op when the key is absent. */
608
+ deleteKey: (options: {
609
+ key: string;
610
+ namespace: string;
611
+ }) => Promise<void>;
612
+ /** Read a value (as text) and its metadata from a namespace key. */
613
+ getValue: (options: {
614
+ key: string;
615
+ namespace: string;
616
+ }) => Promise<KvValueResult>;
617
+ /** List keys in a namespace, optionally filtered by prefix and paginated. */
618
+ listKeys: (options: {
619
+ cursor?: string;
620
+ limit?: number;
621
+ namespace: string;
622
+ prefix?: string;
623
+ }) => Promise<KvKeyListResult>;
624
+ /** List the registered KV namespaces (binding names). */
625
+ listNamespaces: () => Promise<KvNamespaceSummary[]>;
626
+ /** Write a value (as text) with optional absolute expiration / relative TTL and metadata. */
627
+ putValue: (options: {
628
+ expiration?: number;
629
+ expirationTtl?: number;
630
+ key: string;
631
+ metadata?: unknown;
632
+ namespace: string;
633
+ value: string;
634
+ }) => Promise<void>;
635
+ }
636
+ /** The worker internals the KV routes reach through injection rather than closure. */
637
+ /**
308
638
  * Observability hooks for the Lunora runtime.
309
639
  *
310
640
  * A user-supplied {@link ObservabilitySink} receives one event per dispatched
@@ -420,6 +750,14 @@ declare const emitRpcEvent: (sink: ObservabilitySink | undefined, event: Observa
420
750
  */
421
751
  declare const emitLogEvent: (sink: ObservabilitySink | undefined, event: LogEvent, context?: ObservabilitySinkContext) => void;
422
752
  /**
753
+ * Cloudflare Durable Object jurisdictions restrict where a DO runs and persists
754
+ * data, for data-residency / compliance regimes (GDPR, FedRAMP, US data
755
+ * residency). The set is open — Cloudflare adds values over time — so this is a
756
+ * widening union rather than a closed enum.
757
+ * @see https://developers.cloudflare.com/durable-objects/reference/data-location/
758
+ */
759
+ type DurableObjectJurisdiction = "eu" | "fedramp" | "us";
760
+ /**
423
761
  * Structural projection of the bits of `DurableObjectNamespace` the runtime
424
762
  * needs. Real workers-types defines a much wider surface; this lets us pass
425
763
  * unit-test doubles without coupling to `@cloudflare/workers-types`.
@@ -437,10 +775,29 @@ interface ShardNamespaceLike {
437
775
  fetch: (request: Request) => Promise<Response>;
438
776
  };
439
777
  idFromName: (name: string) => unknown;
778
+ /**
779
+ * Derive a jurisdiction-restricted subnamespace. Every ID and stub created
780
+ * from the returned namespace is pinned to `jurisdiction`. Optional because
781
+ * older workers-types releases (and unit-test doubles) may not expose it;
782
+ * {@link applyJurisdiction} fails closed when a jurisdiction is requested
783
+ * but this method is absent.
784
+ */
785
+ jurisdiction?: (jurisdiction: DurableObjectJurisdiction) => ShardNamespaceLike;
440
786
  }
441
787
  interface ResolvedShard {
442
788
  fetch: (request: Request) => Promise<Response>;
443
789
  }
790
+ /**
791
+ * Return a jurisdiction-restricted view of `namespace`, or `namespace`
792
+ * unchanged when no jurisdiction is configured.
793
+ *
794
+ * Fail-closed: if a jurisdiction is requested but the binding does not expose
795
+ * `.jurisdiction()` (an older workers-types, or a misconfigured test double),
796
+ * this throws rather than silently routing to the un-pinned global namespace —
797
+ * silently dropping a residency constraint would let data land outside the
798
+ * compliance boundary the caller asked for.
799
+ */
800
+ declare const applyJurisdiction: (namespace: ShardNamespaceLike, jurisdiction?: DurableObjectJurisdiction) => ShardNamespaceLike;
444
801
  /** Look up a shard stub by name, preferring `getByName` when present. */
445
802
  declare const resolveShard: (namespace: ShardNamespaceLike, shardKey: string) => ResolvedShard;
446
803
  /**
@@ -959,31 +1316,17 @@ interface ShardTrafficFanOutResult {
959
1316
  shards: ReadonlyArray<ShardTrafficEntry>;
960
1317
  }
961
1318
  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
1319
  /** Per-header overrides for {@link SecurityHeadersOptions}. `false` omits the header. */
981
1320
  interface SecurityHeadersOptions {
982
1321
  /**
983
1322
  * `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.
1323
+ * `default-src 'none'` policy to **non-HTML** responses, and a conservative
1324
+ * hardening policy to **HTML** responses (`base-uri 'none'; frame-ancestors
1325
+ * 'self'; object-src 'none'`) this does NOT set `default-src`/`script-src`,
1326
+ * so it never blocks an SSR page's own scripts/styles/images/fetches, it only
1327
+ * locks down the `base` element, framing (mirroring the `SAMEORIGIN`
1328
+ * X-Frame-Options default), and legacy plugins. Pass a string to apply that
1329
+ * exact policy to every response (HTML included); `false` to never send one.
987
1330
  */
988
1331
  csp?: string | false;
989
1332
  /** `X-Frame-Options` (clickjacking). Defaults to `SAMEORIGIN`. `false` omits it. */
@@ -1032,7 +1375,7 @@ interface SecurityOptions {
1032
1375
  interface ResolvedHeaders {
1033
1376
  coop: string | undefined;
1034
1377
  csp: {
1035
- htmlToo: boolean;
1378
+ htmlValue: string | undefined;
1036
1379
  value: string;
1037
1380
  } | undefined;
1038
1381
  enabled: boolean;
@@ -1095,6 +1438,24 @@ declare const resolveSecurity: (security: SecurityOptions | undefined, env?: Rec
1095
1438
  * @returns a `403` Response when the origin is untrusted, or `undefined` when the request is allowed.
1096
1439
  */
1097
1440
  declare const enforceOrigin: (request: Request, resolved: ResolvedSecurity) => Response | undefined;
1441
+ /**
1442
+ * CSRF defense for the WebSocket upgrade (Cross-Site WebSocket Hijacking).
1443
+ *
1444
+ * A WS handshake is an HTTP `GET`, so {@link enforceOrigin}'s safe-method
1445
+ * exemption never fires for it — yet the browser auto-attaches the session
1446
+ * cookie to the handshake and WebSocket connections are NOT governed by
1447
+ * CORS/SOP. Without an explicit `Origin` check any page can open
1448
+ * `wss://app/_lunora/ws`, authenticate as the logged-in victim, and read the
1449
+ * victim's live queries + issue mutations as them. This guard closes that hole.
1450
+ *
1451
+ * Scoped to cookie-bearing upgrades — the only vector CSWSH can ride (a browser
1452
+ * attaches cookies but never a bearer token). Bearer/token/server-to-server
1453
+ * upgrades (no `Cookie`) are exempt. A browser ALWAYS sends `Origin` on a WS
1454
+ * handshake, so a missing/untrusted `Origin` on a cookie-bearing upgrade fails
1455
+ * closed (mirrors {@link enforceOrigin}).
1456
+ * @returns a `403` Response when the upgrade origin is untrusted, or `undefined` when it is allowed.
1457
+ */
1458
+
1098
1459
  /**
1099
1460
  * Answer a CORS preflight (`OPTIONS` carrying `Access-Control-Request-Method`)
1100
1461
  * for an allowlisted origin with a `204`. Returns `undefined` for non-preflight
@@ -1130,10 +1491,6 @@ interface RpcEnvelope {
1130
1491
  functionPath: string;
1131
1492
  shardKey?: string;
1132
1493
  }
1133
- interface ExecutionContextLike {
1134
- passThroughOnException: () => void;
1135
- waitUntil: (promise: Promise<unknown>) => void;
1136
- }
1137
1494
  type Route = (request: Request, env: unknown, context: ExecutionContextLike) => Promise<Response> | Response;
1138
1495
  /**
1139
1496
  * Context handed to HTTP-action handlers. Built per request by the worker; its
@@ -1149,6 +1506,12 @@ interface HttpActionContext {
1149
1506
  getIdentity: () => Promise<Record<string, unknown> | null>;
1150
1507
  userId: null | string;
1151
1508
  };
1509
+ cache?: {
1510
+ purge: (options: {
1511
+ purgeEverything?: boolean;
1512
+ tags?: string[];
1513
+ }) => Promise<unknown>;
1514
+ };
1152
1515
  fetch: typeof globalThis.fetch;
1153
1516
  runAction: <R>(reference: unknown, args?: Record<string, unknown>) => Promise<R>;
1154
1517
  runMutation: <R>(reference: unknown, args?: Record<string, unknown>) => Promise<R>;
@@ -1168,35 +1531,6 @@ interface HttpRouterLike {
1168
1531
  fetch(request: Request, env?: unknown, context?: ExecutionContextLike): Promise<Response> | Response;
1169
1532
  }
1170
1533
  /**
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
1534
  * Per-table sharding metadata the admin import endpoint needs to route rows.
1201
1535
  * Structural so this package stays free of `@lunora/server`. The codegen-
1202
1536
  * generated worker entry passes a thin projection of the user's schema.
@@ -1472,6 +1806,12 @@ interface ScheduledControllerLike {
1472
1806
  */
1473
1807
  type CronHandler = (controller: ScheduledControllerLike, env: unknown, context: ExecutionContextLike) => Promise<void> | void;
1474
1808
  /**
1809
+ * A Cloudflare Queues push-consumer handler — the worker's `queue()` entry
1810
+ * forwards each delivered `MessageBatch` (typed `unknown` here to keep the
1811
+ * runtime decoupled from `@lunora/queue`'s structural batch type).
1812
+ */
1813
+ type QueueConsumerHandler = (batch: unknown, env: unknown, context: ExecutionContextLike) => Promise<void>;
1814
+ /**
1475
1815
  * A single code-defined cron job, shaped like an entry of the generated
1476
1816
  * `LUNORA_CRONS` map. `functionPath` is the `"namespace:fn"` to run, `args` its
1477
1817
  * bound arguments, and `name` the human label from the `cronJobs()` builder.
@@ -1553,6 +1893,22 @@ interface BackupManifest {
1553
1893
  tables?: string;
1554
1894
  }
1555
1895
  interface WorkerOptions {
1896
+ /**
1897
+ * An additional, async authorization gate for the `/_lunora/admin/*` plane
1898
+ * (the Studio's HTTP + WS endpoints), OR-ed with the static {@link WorkerOptions.adminToken}
1899
+ * bearer. When it resolves `true` for a request, that request is treated as
1900
+ * admin-authorized even without the bearer; when it resolves `false` (or is
1901
+ * unset) the bearer remains the only path. Evaluated once per admin request
1902
+ * and never on the RPC/WebSocket data hot path.
1903
+ *
1904
+ * The intended producer is `@lunora/cloudflare-access`'s `accessAdminGate(...)`,
1905
+ * which verifies the request's `Cf-Access-Jwt-Assertion` JWT and applies an
1906
+ * `isAdmin(claims)` predicate — so the Studio can sit behind Cloudflare Access
1907
+ * instead of (or alongside) a shared admin token. It takes only the request
1908
+ * (verification needs static team-domain/aud config + the remote JWKS, no env
1909
+ * binding), so it composes without threading async through every admin route.
1910
+ */
1911
+ adminGate?: (request: Request) => boolean | Promise<boolean>;
1556
1912
  /**
1557
1913
  * Admin bearer token expected by the export/import endpoints. When unset,
1558
1914
  * the endpoints respond with `ADMIN_FORBIDDEN` — the same posture the
@@ -1560,17 +1916,25 @@ interface WorkerOptions {
1560
1916
  */
1561
1917
  adminToken?: string;
1562
1918
  /**
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.
1919
+ * Opt into an authorization-open posture for sharded and fan-out access.
1920
+ *
1921
+ * By default (this flag unset/`false`) the runtime FAILS CLOSED per
1922
+ * operation: naming a non-default shard (a potential cross-tenant hop) is
1923
+ * rejected with a `403` (`FORBIDDEN_SHARD`) unless
1924
+ * {@link WorkerOptions.authorizeShard} is configured, and a fan-out
1925
+ * envelope is rejected (`FORBIDDEN_FANOUT`) unless
1926
+ * {@link WorkerOptions.authorizeFanOut} is. Set this to `true` to allow
1927
+ * such requests from any caller (including unauthenticated ones)
1928
+ * appropriate only when every table is protected by per-row RLS. The
1929
+ * runtime then emits a single `console.warn` so the open posture stays
1930
+ * visible in logs. The flag is consulted per operation: it has no effect
1931
+ * on an operation whose own `authorize*` callback is configured (that
1932
+ * callback gates directly), but configuring only one of the two callbacks
1933
+ * does NOT cover the other operation.
1934
+ *
1935
+ * NOTE: this is a behaviour change from earlier alphas, where the same
1936
+ * situation was warn-once-then-allow. Apps that relied on client-chosen
1937
+ * shard keys without an `authorize*` callback must set this flag explicitly.
1574
1938
  */
1575
1939
  allowUnauthenticatedShardAccess?: boolean;
1576
1940
  /**
@@ -1737,11 +2101,51 @@ interface WorkerOptions {
1737
2101
  */
1738
2102
  httpRouter?: HttpRouterLike;
1739
2103
  /**
2104
+ * The declared identity claim contract (`defineIdentity(...)` from
2105
+ * `@lunora/server`), passed by the generated worker entry. When present, the
2106
+ * worker validates every `resolveIdentity` result against it at the trust
2107
+ * boundary (on the public data paths — RPC / WebSocket / HTTP-action /
2108
+ * server-query, never the admin path) *before* the claims become `ctx.auth`.
2109
+ * A resolver output that violates the contract is downgraded to anonymous or
2110
+ * rejected with a `401`, per the contract's `onInvalid`. Omitted → no
2111
+ * validation, and the identity stays the historical untyped claim bag.
2112
+ */
2113
+ identity?: IdentityContractLike;
2114
+ /**
1740
2115
  * Insert `.global()` rows for the admin import endpoint. When omitted,
1741
2116
  * rows targeting global tables are reported as hard errors.
1742
2117
  */
1743
2118
  importGlobals?: GlobalImportFunction;
1744
2119
  /**
2120
+ * Restrict every Durable Object this worker reaches — shard DOs, the
2121
+ * scheduler DO, the fan-out coordinator, subscriptions — to a Cloudflare
2122
+ * data-residency jurisdiction (`"eu"`, `"us"`, `"fedramp"`). The runtime
2123
+ * derives a jurisdiction-pinned subnamespace from {@link WorkerOptions.shardDO}
2124
+ * and {@link WorkerOptions.schedulerDO} once, so all routing inherits it.
2125
+ *
2126
+ * Fail-closed: if the bound namespace does not expose `.jurisdiction()`
2127
+ * (an older `@cloudflare/workers-types`), the worker throws rather than
2128
+ * silently routing to the un-pinned global namespace. Omit it for the
2129
+ * default, un-pinned behaviour.
2130
+ *
2131
+ * ⚠️ Set once, before the first deploy — changing it strands data. A DO name
2132
+ * maps to a *different* ID per jurisdiction, so toggling this on an existing
2133
+ * deployment makes every shard/scheduler call resolve to a new, empty DO; the
2134
+ * prior data stays in the old jurisdiction and is unreachable (no in-place
2135
+ * migration). Usually set via the schema's `.jurisdiction(...)`, which codegen
2136
+ * threads here.
2137
+ * @see https://developers.cloudflare.com/durable-objects/reference/data-location/
2138
+ */
2139
+ jurisdiction?: DurableObjectJurisdiction;
2140
+ /**
2141
+ * Introspector for Workers KV namespaces, backing the studio's KV browser
2142
+ * via `GET /_lunora/admin/kv/namespaces`, `GET /_lunora/admin/kv/keys`,
2143
+ * `GET|PUT|DELETE /_lunora/admin/kv/value`. Build it from the env's bound
2144
+ * KV namespaces with `createKvIntrospector` from `@lunora/bindings/kv`.
2145
+ * Omit it and those endpoints respond `KV_NOT_CONFIGURED`.
2146
+ */
2147
+ kvIntrospector?: KvIntrospector;
2148
+ /**
1745
2149
  * Optional telemetry sink. When supplied, the worker emits one
1746
2150
  * `onRpc` event per dispatched RPC (single-shard forward or fan-out)
1747
2151
  * with duration / ok / error / shardKey or fanOut metadata. Sink
@@ -1796,6 +2200,14 @@ interface WorkerOptions {
1796
2200
  */
1797
2201
  queryCoordinator?: QueryCoordinator;
1798
2202
  /**
2203
+ * Cloudflare Queues push-consumer handler — the worker's `queue(batch, …)`
2204
+ * entry forwards every delivered `MessageBatch` here. Built by codegen from
2205
+ * `lunora/queues.ts` (via `@lunora/queue`'s `dispatchQueueBatch`, which routes
2206
+ * by `batch.queue` to the matching `defineQueue` handler), so the runtime
2207
+ * stays decoupled from the queue package. Omitted when no push queues exist.
2208
+ */
2209
+ queue?: QueueConsumerHandler;
2210
+ /**
1799
2211
  * Resolve the calling identity from the inbound RPC request. Called once
1800
2212
  * per RPC (and per fan-out) before the request is forwarded to the
1801
2213
  * shard. The returned `userId` becomes `ctx.auth.userId` on the shard
@@ -1918,6 +2330,12 @@ interface RpcContext {
1918
2330
  */
1919
2331
  interface LunoraWorker {
1920
2332
  fetch: (request: Request, env: unknown, context: ExecutionContextLike) => Promise<Response>;
2333
+ /**
2334
+ * Cloudflare Queues consumer entry — present only when the app declares push
2335
+ * queues. Forwards each delivered `MessageBatch` to the configured
2336
+ * {@link WorkerOptions.queue} handler; a no-op when none is set.
2337
+ */
2338
+ queue?: (batch: unknown, env: unknown, context: ExecutionContextLike) => Promise<void>;
1921
2339
  scheduled: (controller: ScheduledControllerLike, env: unknown, context: ExecutionContextLike) => Promise<void>;
1922
2340
  /**
1923
2341
  * In-process query/mutation dispatch for SSR loaders co-located in this
@@ -2019,6 +2437,55 @@ type FrameworkWorkerOptionsInput = ((env: unknown) => FrameworkWorkerOptions) |
2019
2437
  * @param optionsInput Lunora options minus `httpRouter`, or an `(env) => options` factory.
2020
2438
  */
2021
2439
  declare const withFrameworkWorker: (host: FrameworkHostHandler, optionsInput: FrameworkWorkerOptionsInput) => LunoraWorker;
2440
+ /**
2441
+ * Options for {@link createLunoraHandler}. Either an `(env) => options` factory
2442
+ * (full control — for bindings that only exist at request time), or a partial
2443
+ * {@link FrameworkWorkerOptions} object whose `shardDO` defaults to the
2444
+ * conventional `env.SHARD` binding. Pass nothing for the common case.
2445
+ */
2446
+ type LunoraHandlerOptions = ((env: unknown) => FrameworkWorkerOptions) | Partial<FrameworkWorkerOptions>;
2447
+ /**
2448
+ * Resolve per-request Lunora worker options. A factory is called with the
2449
+ * request `env`; a partial object has its `shardDO` defaulted to `env.SHARD` so
2450
+ * the common case needs no configuration. Throws a clear error when no shard
2451
+ * namespace can be found — a wiring mistake, not a runtime condition to swallow.
2452
+ */
2453
+ declare const resolveLunoraOptions: (options: LunoraHandlerOptions, env: unknown) => FrameworkWorkerOptions;
2454
+ /**
2455
+ * Build a framework-neutral request handler for Lunora's realtime plane
2456
+ * (`/_lunora/rpc`, `/_lunora/ws`, `/_lunora/admin/*`). This is the **one shared
2457
+ * seam** every web-standard framework integration mounts — Hono, Nitro/h3,
2458
+ * Elysia, or any WinterCG host running on Cloudflare Workers — so each is a
2459
+ * 1–2 line bridge (`(request, env, ctx) => Response`) rather than a bespoke
2460
+ * adapter package.
2461
+ *
2462
+ * Mount it under `/_lunora/*` (or whatever path you reserve) inside your app's
2463
+ * router; everything else stays your framework's. The host supplies, per
2464
+ * request: a Web `Request`, the Cloudflare `env` (carrying the `SHARD` Durable
2465
+ * Object namespace), and — when available — the `ExecutionContext`. The
2466
+ * `101 Switching Protocols` WebSocket-upgrade `Response` (with its `webSocket`)
2467
+ * is returned verbatim, so the framework streams the socket through unchanged.
2468
+ *
2469
+ * ```ts
2470
+ * // Hono
2471
+ * const lunora = createLunoraHandler();
2472
+ * app.use("/_lunora/*", (c) => lunora(c.req.raw, c.env, c.executionCtx));
2473
+ *
2474
+ * // Nitro / h3
2475
+ * const lunora = createLunoraHandler();
2476
+ * export default defineEventHandler((event) => {
2477
+ * const { ctx, env } = event.context.cloudflare;
2478
+ * return lunora(toWebRequest(event), env, ctx);
2479
+ * });
2480
+ * ```
2481
+ *
2482
+ * `shardDO` defaults to `env.SHARD`; pass `options` (or an `(env) => options`
2483
+ * factory) to add `auth`, `crons`, a `security` posture, or a custom namespace.
2484
+ * A new worker is composed per request because the options (and the `SHARD`
2485
+ * binding they default from) are only known once `env` arrives.
2486
+ * @param options Partial worker options (default `shardDO: env.SHARD`), or an `(env) => options` factory.
2487
+ */
2488
+ declare const createLunoraHandler: (options?: LunoraHandlerOptions) => ((request: Request, env: unknown, context?: ExecutionContextLike) => Promise<Response>);
2022
2489
  /** Re-exported helper so callers can roundtrip envelopes in tests. */
2023
2490
  declare const defineRpcEnvelope: (envelope: RpcEnvelope) => RpcEnvelope;
2024
2491
  /**
@@ -2082,6 +2549,12 @@ interface DynamicShardRegistryOptions {
2082
2549
  * only if you run multiple isolated registries in one environment.
2083
2550
  */
2084
2551
  instanceName?: string;
2552
+ /**
2553
+ * Pin the registry DO to a Cloudflare data-residency jurisdiction. Pass the
2554
+ * same value as the worker's `jurisdiction` so the registry co-locates with
2555
+ * the shards it tracks. Omit for the un-pinned global namespace.
2556
+ */
2557
+ jurisdiction?: DurableObjectJurisdiction;
2085
2558
  /** DO namespace binding (`env.SHARD_REGISTRY`). */
2086
2559
  namespace: ShardNamespaceLike;
2087
2560
  }
@@ -2104,18 +2577,30 @@ interface DynamicShardRegistry extends ShardRegistry {
2104
2577
  }
2105
2578
  declare const createDynamicShardRegistry: (options: DynamicShardRegistryOptions) => DynamicShardRegistry;
2106
2579
  interface LunoraErrorBody {
2107
- error: {
2108
- code: string;
2109
- message: string;
2110
- };
2580
+ error: ErrorBody;
2111
2581
  }
2112
2582
  /**
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`.
2583
+ * Convert any thrown value into a JSON error response.
2584
+ *
2585
+ * Delegates the envelope + redaction to `@lunora/errors`' {@link toErrorBody} —
2586
+ * a non-internal `LunoraError` (from `@lunora/server`, this runtime, or the
2587
+ * `@lunora/do` data layer) is echoed with its `code`/`message`/`hint`/`docsUrl`;
2588
+ * an internal-coded error keeps its status but its message is redacted; anything
2589
+ * else becomes a generic `INTERNAL` 500. All of these share the unified shape
2590
+ * recognized by `isLunoraError`.
2115
2591
  */
2116
- declare class LunoraError extends Error {
2117
- readonly code: string;
2118
- readonly status: number;
2592
+ declare const toErrorResponse: (error: unknown) => Response;
2593
+ /**
2594
+ * Transport-level error for the worker entry. A thin ergonomic wrapper over the
2595
+ * shared `@lunora/errors` `LunoraError` that keeps the runtime's historical
2596
+ * `(message, { code, status })` signature — the runtime mints these with
2597
+ * dispatch-specific codes (`METHOD_NOT_ALLOWED`, `*_NOT_CONFIGURED`, …) and an
2598
+ * explicit status, so they don't need a central catalog entry. Because it is a
2599
+ * real `LunoraError`, it carries the unified wire shape and is recognized by
2600
+ * `isLunoraError` everywhere. Anything thrown that isn't a `LunoraError`
2601
+ * is mapped to a generic 500 with code `INTERNAL`.
2602
+ */
2603
+ declare class LunoraError extends LunoraError$1 {
2119
2604
  constructor(message: string, options?: {
2120
2605
  cause?: unknown;
2121
2606
  code?: string;
@@ -2123,10 +2608,6 @@ declare class LunoraError extends Error {
2123
2608
  });
2124
2609
  toResponse(): Response;
2125
2610
  }
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
2611
  /** Shared shape for sinks that can be limited to error events only. */
2131
2612
  interface OnlyErrorsOption {
2132
2613
  /** When true, only events with `ok === false` are forwarded. */
@@ -2256,4 +2737,4 @@ declare const analyticsEngineSink: (options: AnalyticsEngineSinkOptions) => Obse
2256
2737
  */
2257
2738
  declare const combineSinks: (...sinks: ObservabilitySink[]) => ObservabilitySink;
2258
2739
  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 };
2740
+ 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 };