@lunora/runtime 1.0.0-alpha.62 → 1.0.0-alpha.64

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/dist/index.d.mts +102 -15
  2. package/dist/index.d.ts +102 -15
  3. package/dist/index.mjs +1 -1
  4. package/dist/packem_shared/BACKUP_KEY_PREFIX-BOtSu-_3.mjs +1 -0
  5. package/dist/packem_shared/DEFAULT_LOG_COLUMNS-B8FFcwsX.mjs +1 -0
  6. package/dist/packem_shared/DEFAULT_REGISTRY_CACHE_TTL_MS-D5O7elXI.mjs +1 -0
  7. package/dist/packem_shared/HEALTH_PATH-jZsuCmSs.mjs +1 -0
  8. package/dist/packem_shared/LOG_ARCHIVE_PATH-jgHjdsz2.mjs +1 -0
  9. package/dist/packem_shared/{LunoraError-ByasbDmd.mjs → LunoraError-DksAgIpa.mjs} +1 -1
  10. package/dist/packem_shared/STORAGE_UPLOAD_MAX_BODY_BYTES-BqyO-1l6.mjs +1 -0
  11. package/dist/packem_shared/analyticsEngineSink-D7qu89f2.mjs +1 -0
  12. package/dist/packem_shared/applyJurisdiction-C0ddU7Tg.mjs +1 -0
  13. package/dist/packem_shared/applyRestCache-qYyCDFO2.mjs +1 -0
  14. package/dist/packem_shared/argsFromQuery-NAXezjJF.mjs +1 -0
  15. package/dist/packem_shared/base64-CMlwEPti.mjs +1 -0
  16. package/dist/packem_shared/composeIdentityResolvers-BHZ4jH8o.mjs +1 -0
  17. package/dist/packem_shared/composeWorker-CTKu1qZV.mjs +6 -0
  18. package/dist/packem_shared/createCrossShardRelationCapabilities-DgQYQzd1.mjs +1 -0
  19. package/dist/packem_shared/createKvCursorStore-VOd1DFsf.mjs +3 -0
  20. package/dist/packem_shared/createQueryCoordinator-CnNyazLX.mjs +1 -0
  21. package/dist/packem_shared/createShardClient-Yb6_Mzd6.mjs +1 -0
  22. package/dist/packem_shared/decorateResponse-D3NzOIvB.mjs +1 -0
  23. package/dist/packem_shared/emitLogEvent-qlixolZi.mjs +1 -0
  24. package/dist/packem_shared/evict-oldest-BNXsKx4s.mjs +1 -0
  25. package/dist/packem_shared/identity-header-JF5q3H5w.mjs +1 -0
  26. package/dist/packem_shared/memoizeIdentity-DnOj3QRi.mjs +1 -0
  27. package/dist/packem_shared/method-guard-BG_vJNTl.mjs +1 -0
  28. package/dist/packem_shared/observability-vDK-rMbs.mjs +1 -0
  29. package/dist/packem_shared/otlp-resource-B4Yylr0V.mjs +1 -0
  30. package/dist/packem_shared/pipeline-log-reader-BGrl66P5.mjs +1 -0
  31. package/dist/packem_shared/rest-cache-BnMq2hbO.mjs +1 -0
  32. package/dist/packem_shared/rest-routes-D2b3HXA9.mjs +1 -0
  33. package/dist/packem_shared/toAirbyteMessages-Cy3uaySU.mjs +1 -0
  34. package/package.json +4 -4
  35. package/dist/packem_shared/BACKUP_KEY_PREFIX-DhFUE3VL.mjs +0 -1
  36. package/dist/packem_shared/DEFAULT_LOG_COLUMNS-CzsNuTZj.mjs +0 -1
  37. package/dist/packem_shared/DEFAULT_REGISTRY_CACHE_TTL_MS-DqWtiFAk.mjs +0 -1
  38. package/dist/packem_shared/HEALTH_PATH-BwWsxoqV.mjs +0 -1
  39. package/dist/packem_shared/LOG_ARCHIVE_PATH-CuHKuDCS.mjs +0 -1
  40. package/dist/packem_shared/STORAGE_UPLOAD_MAX_BODY_BYTES-K0uZPIUj.mjs +0 -1
  41. package/dist/packem_shared/analyticsEngineSink-iIRy11I9.mjs +0 -1
  42. package/dist/packem_shared/applyJurisdiction-DX_lQ6fY.mjs +0 -1
  43. package/dist/packem_shared/applyRestCache-DwBDPRf6.mjs +0 -1
  44. package/dist/packem_shared/argsFromQuery-nMGzM5bK.mjs +0 -1
  45. package/dist/packem_shared/base64-DPPVK6s_.mjs +0 -1
  46. package/dist/packem_shared/composeIdentityResolvers-DwE0Jbww.mjs +0 -1
  47. package/dist/packem_shared/composeWorker-rVokGnPq.mjs +0 -6
  48. package/dist/packem_shared/createCrossShardRelationCapabilities-CQfrCIWR.mjs +0 -1
  49. package/dist/packem_shared/createKvCursorStore-C24tEuYk.mjs +0 -3
  50. package/dist/packem_shared/createQueryCoordinator-D8GY_boW.mjs +0 -1
  51. package/dist/packem_shared/createShardClient-DoSOeXwx.mjs +0 -1
  52. package/dist/packem_shared/decorateResponse-BeLVRQuJ.mjs +0 -1
  53. package/dist/packem_shared/emitLogEvent-BxJ6jRKW.mjs +0 -1
  54. package/dist/packem_shared/evict-oldest-C2XU6HBR.mjs +0 -1
  55. package/dist/packem_shared/identity-header-pdXOyDU4.mjs +0 -1
  56. package/dist/packem_shared/memoizeIdentity-CX3xEPYw.mjs +0 -1
  57. package/dist/packem_shared/method-guard-rzvo19pa.mjs +0 -1
  58. package/dist/packem_shared/observability-DWlkDJJw.mjs +0 -1
  59. package/dist/packem_shared/otlp-resource-B-ByO9qo.mjs +0 -1
  60. package/dist/packem_shared/pipeline-log-reader-FF1V32O2.mjs +0 -1
  61. package/dist/packem_shared/rest-cache-5unAzdFN.mjs +0 -1
  62. package/dist/packem_shared/rest-routes-BqldHiaH.mjs +0 -1
  63. package/dist/packem_shared/toAirbyteMessages-DTk8e2f9.mjs +0 -1
package/dist/index.d.mts CHANGED
@@ -208,6 +208,13 @@ declare const toAirbyteMessages: (page: ConnectorSyncPage, emittedAt?: number) =
208
208
  * fall back to {@link NOOP_EXECUTION_CONTEXT}.
209
209
  */
210
210
  interface ExecutionContextLike {
211
+ /**
212
+ * Present only when Cloudflare Access authenticated the request against a
213
+ * policy attached to the **Worker** (rather than to a hostname). `undefined`
214
+ * on every unauthenticated request, so its presence is itself the "Access
215
+ * authorized this caller" signal — see {@link AccessContextLike}.
216
+ */
217
+ access?: AccessContextLike;
211
218
  cache?: {
212
219
  purge: (options: {
213
220
  purgeEverything?: boolean;
@@ -217,6 +224,48 @@ interface ExecutionContextLike {
217
224
  passThroughOnException?: () => void;
218
225
  waitUntil?: (promise: Promise<unknown>) => void;
219
226
  }
227
+ /**
228
+ * The identity Cloudflare Access attaches to a Worker-protected request.
229
+ *
230
+ * Shape follows the Access application-token payload: `sub` is the stable per-user
231
+ * id, `email` the verified address, `common_name` the service-token name (machine
232
+ * callers, whose `sub` is empty), and `exp` the credential expiry in epoch
233
+ * **seconds**. Group membership is whatever the Access policy emits — a list of
234
+ * names, or of `{ id, name }` objects — hence `unknown`; normalize before use.
235
+ *
236
+ * Cloudflare may add further fields, so the index signature keeps them rather
237
+ * than dropping them: this is a view of a payload we do not own.
238
+ */
239
+ interface AccessIdentityLike {
240
+ [claim: string]: unknown;
241
+ /** Service-token name. Present for non-interactive (machine) callers instead of `email`. */
242
+ common_name?: string;
243
+ /** Verified user email. Present for interactive (SSO) callers. */
244
+ email?: string;
245
+ /** Credential expiry, epoch **seconds**. */
246
+ exp?: number;
247
+ /** IdP group membership — names or `{ id, name }` objects, depending on the policy. */
248
+ groups?: unknown;
249
+ /** Display name from the identity provider, when it emits one. */
250
+ name?: string;
251
+ /** Stable per-user id, and what consumers key a user on. Empty for service tokens. */
252
+ sub?: string;
253
+ /** Cloudflare's per-user UUID. Carried through, but deliberately not used as an id — only this path emits it, so keying on it would not match the JWT path. */
254
+ user_uuid?: string;
255
+ }
256
+ /**
257
+ * The `ctx.access` facade Cloudflare exposes on a Worker protected by Access.
258
+ *
259
+ * Reading the identity from here is preferable to verifying the
260
+ * `Cf-Access-Jwt-Assertion` header: the platform has already authenticated the
261
+ * caller, so there is no JWKS fetch, no audience check to get wrong, and nothing
262
+ * a request can forge — the field simply does not exist unless Access authorized
263
+ * the call. The header path remains the fallback for hostname-scoped Access
264
+ * applications, which do not populate this.
265
+ */
266
+ interface AccessContextLike {
267
+ getIdentity: () => AccessIdentityLike | null | undefined | Promise<AccessIdentityLike | null | undefined>;
268
+ }
220
269
  /**
221
270
  * No-op `ExecutionContext` used when the host runtime didn't supply one (a
222
271
  * non-Cloudflare preview, or a unit test), so the worker's `fetch` always
@@ -1597,8 +1646,13 @@ interface ResolvedIdentity {
1597
1646
  * so `.auth()`'s better-auth session resolver, a signed-preview-link verifier, a
1598
1647
  * per-tenant bearer check, an upstream-JWT reader, … are all just `IdentityResolver`s
1599
1648
  * — the identity layer is generic over every scheme, not coupled to any one.
1649
+ *
1650
+ * The optional third argument is the request's `ExecutionContext`, for a scheme
1651
+ * whose credential the platform supplies out-of-band rather than on the request
1652
+ * (`context.access` under Worker-scoped Cloudflare Access). It is `undefined`
1653
+ * wherever the host gave the worker no context.
1600
1654
  */
1601
- type IdentityResolver = (request: Request, env: unknown) => Promise<ResolvedIdentity | null> | ResolvedIdentity | null;
1655
+ type IdentityResolver = (request: Request, env: unknown, context?: ExecutionContextLike) => Promise<ResolvedIdentity | null> | ResolvedIdentity | null;
1602
1656
  /** Error policy for {@link composeIdentityResolvers} when a participant resolver throws. */
1603
1657
  type ComposeIdentityResolversErrorMode = "fail-closed" | "skip";
1604
1658
  /** Options for {@link composeIdentityResolvers}. */
@@ -2439,12 +2493,12 @@ type RestRateLimit = (request: Request, functionPath: string) => Promise<Respons
2439
2493
  /**
2440
2494
  * A built REST route. Takes the same `(request, env, url, context)` shape as the
2441
2495
  * runtime's internal route table so it can be spread straight into it; `url` is
2442
- * unused here (the route re-parses it) and `context` is read only for its
2443
- * `waitUntil`, which keeps dispatch telemetry alive past the response.
2496
+ * unused here (the route re-parses it). The context is the real
2497
+ * {@link ExecutionContextLike} rather than a `waitUntil`-only projection, because
2498
+ * the cache decision reads `context.access` too — see the `applyRestCache` call
2499
+ * below.
2444
2500
  */
2445
- type RestRoute = (request: Request, env: unknown, url?: URL, context?: {
2446
- waitUntil?: (promise: Promise<unknown>) => void;
2447
- }) => Promise<Response>;
2501
+ type RestRoute = (request: Request, env: unknown, url?: URL, context?: ExecutionContextLike) => Promise<Response>;
2448
2502
  interface RestRouteDeps {
2449
2503
  /** The generated function registry — the source of which procedures are exposed. */
2450
2504
  functions: RestRegistryLike;
@@ -3393,11 +3447,15 @@ interface WorkerOptions {
3393
3447
  * The intended producer is `@lunora/cloudflare-access`'s `accessAdminGate(...)`,
3394
3448
  * which verifies the request's `Cf-Access-Jwt-Assertion` JWT and applies an
3395
3449
  * `isAdmin(claims)` predicate — so the Studio can sit behind Cloudflare Access
3396
- * instead of (or alongside) a shared admin token. It takes only the request
3397
- * (verification needs static team-domain/aud config + the remote JWKS, no env
3398
- * binding), so it composes without threading async through every admin route.
3450
+ * instead of (or alongside) a shared admin token. It needs no `env` binding
3451
+ * (verification is static team-domain/aud config + the remote JWKS), so it
3452
+ * composes without threading async through every admin route.
3453
+ *
3454
+ * The second argument is the request's `ExecutionContext`, carrying
3455
+ * `context.access` when the Access policy is attached to the Worker rather
3456
+ * than to a hostname. It is `undefined` when the host supplied no context.
3399
3457
  */
3400
- adminGate?: (request: Request) => boolean | Promise<boolean>;
3458
+ adminGate?: (request: Request, context?: ExecutionContextLike) => boolean | Promise<boolean>;
3401
3459
  /**
3402
3460
  * Admin bearer token expected by the export/import endpoints. When unset,
3403
3461
  * the endpoints respond with `ADMIN_FORBIDDEN` — the same posture the
@@ -3804,8 +3862,16 @@ interface WorkerOptions {
3804
3862
  * forwarded as `x-lunora-identity` so `ctx.auth.getIdentity()` can
3805
3863
  * return them. Returning `null` (or omitting this option) means
3806
3864
  * anonymous — no identity headers are injected.
3865
+ *
3866
+ * The third argument is the request's `ExecutionContext`, forwarded so a
3867
+ * resolver can read identity the platform supplies out-of-band rather than
3868
+ * off the request — `context.access` on a Worker protected by Cloudflare
3869
+ * Access is the one that exists today. It is `undefined` on the paths that
3870
+ * have no context to give (a direct {@link LunoraWorker.serverQuery} call, a
3871
+ * host that mounts the worker without one), so a resolver that uses it must
3872
+ * still handle its absence.
3807
3873
  */
3808
- resolveIdentity?: (request: Request, env: unknown) => Promise<ResolvedIdentity | null> | ResolvedIdentity | null;
3874
+ resolveIdentity?: (request: Request, env: unknown, context?: ExecutionContextLike) => Promise<ResolvedIdentity | null> | ResolvedIdentity | null;
3809
3875
  /**
3810
3876
  * Resolve a table's sharding metadata. Required by the import endpoint to
3811
3877
  * bucket rows; when omitted, every row routes to the default shard.
@@ -4074,12 +4140,18 @@ interface LunoraWorker {
4074
4140
  * `__lunoraRef` is the `"namespace:fn"` dispatched.
4075
4141
  * @param args The function arguments.
4076
4142
  * @param options Call options mirroring the RPC envelope.
4143
+ * @param options.context The host's `ExecutionContext`. Required to reach an
4144
+ * identity the platform supplies out-of-band rather than on the
4145
+ * request — `context.access` under a Worker-scoped Cloudflare
4146
+ * Access policy. Omit it there and the call resolves anonymous
4147
+ * while the same user's `/_lunora/rpc` traffic is authenticated.
4077
4148
  * @param options.shardKey Routes to a specific shard (omitted → the worker's
4078
4149
  * `defaultShardKey`).
4079
4150
  * @param options.waitUntil The host's `waitUntil`, so dispatch telemetry
4080
4151
  * whose export is deferred (a gzipped OTLP body) survives isolate teardown.
4081
4152
  */
4082
4153
  serverQuery: (request: Request, env: unknown, reference: unknown, args?: Record<string, unknown>, options?: {
4154
+ context?: ExecutionContextLike;
4083
4155
  shardKey?: string;
4084
4156
  waitUntil?: (promise: Promise<unknown>) => void;
4085
4157
  }) => Promise<Response>;
@@ -4799,8 +4871,16 @@ declare const combineSinks: (...sinks: ObservabilitySink[]) => ObservabilitySink
4799
4871
  * as caller-specific. Checks the built-in identity headers plus anything the
4800
4872
  * policy declares via `credentialHeaders` — an app whose `resolveIdentity` reads
4801
4873
  * a bespoke header must say so, or its callers read as anonymous here.
4874
+ *
4875
+ * A credential does not have to be on the request at all: under a Cloudflare
4876
+ * Access policy attached to the Worker, the caller is authenticated by the edge
4877
+ * and their identity arrives on the `ExecutionContext` as `access`, with no
4878
+ * header this function could see. Its mere presence means Access authorized this
4879
+ * specific caller, so it counts as a credential — otherwise a per-user response
4880
+ * would be labelled `public` and a shared cache could hand it to the next
4881
+ * visitor.
4802
4882
  */
4803
- declare const requestCarriesCredentials: (request: Request, policy: RestCachePolicy) => boolean;
4883
+ declare const requestCarriesCredentials: (request: Request, policy: RestCachePolicy, context?: ExecutionContextLike) => boolean;
4804
4884
  /**
4805
4885
  * Build the cache headers for one exchange, or `undefined` when the exchange
4806
4886
  * isn't cacheable at all (non-`GET`, or a non-2xx result — an error body must
@@ -4809,14 +4889,14 @@ declare const requestCarriesCredentials: (request: Request, policy: RestCachePol
4809
4889
  * The effective scope is `policy.scope` narrowed by {@link requestCarriesCredentials};
4810
4890
  * `"public"` survives only for a genuinely anonymous request.
4811
4891
  */
4812
- declare const restCacheHeaders: (policy: RestCachePolicy, request: Request, status: number) => Record<string, string> | undefined;
4892
+ declare const restCacheHeaders: (policy: RestCachePolicy, request: Request, status: number, context?: ExecutionContextLike) => Record<string, string> | undefined;
4813
4893
  /**
4814
4894
  * Return `response` with the declared cache headers applied. A shard `Response`
4815
4895
  * has immutable headers, so this rebuilds it (status/statusText/existing headers
4816
4896
  * are carried over, the body is streamed through untouched). When the exchange
4817
4897
  * isn't cacheable the original response is returned as-is — no copy.
4818
4898
  */
4819
- declare const applyRestCache: (response: Response, policy: RestCachePolicy | undefined, request: Request) => Response;
4899
+ declare const applyRestCache: (response: Response, policy: RestCachePolicy | undefined, request: Request, context?: ExecutionContextLike) => Response;
4820
4900
  /**
4821
4901
  * Structural mirror of `@lunora/client`'s `FunctionReference`, re-declared so this
4822
4902
  * module carries no `runtime → client` (browser SDK) dependency. The phantom
@@ -4910,4 +4990,11 @@ declare const createShardClient: (namespace: ShardNamespaceLike, options?: Shard
4910
4990
  */
4911
4991
  declare const STORAGE_UPLOAD_MAX_BODY_BYTES: number;
4912
4992
  declare const VERSION: string;
4913
- export { type AdminTableResolver, type AirbyteMessage, type AnalyticsEngineDataPointLike, type AnalyticsEngineDatasetLike, type AnalyticsEngineSinkOptions, type AuthAdmin, type AuthCapabilities, type AuthConfigInfo, type AuthImpersonation, type AuthPage, type AuthSession, type AuthUser, type AuthUserFieldSpec, BACKUP_KEY_PREFIX, type BackupManifest, type BackupManifestEntry, type BackupRetentionPreview, 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_LOG_COLUMNS, DEFAULT_LOG_LIMIT, DEFAULT_REGISTRY_CACHE_TTL_MS, type DurableObjectJurisdiction, type DynamicShardRegistry, type DynamicShardRegistryOptions, type ExecutionContextLike, type ExportBatch, type ExportChange, type ExportCursorStore, type ExportFanOutRequest, type ExportFanOutResult, type ExportSink, type ExportTapFailure, type ExportTapResult, 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, HEALTH_PATH, HEALTH_READY_PATH, type HealthAuthPosture, type HealthBody, type HealthCheckReport, type HealthProbe, type HealthProbeKind, type HealthProbeResult, type HealthRouteDeps, 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, LOG_ARCHIVE_NOT_CONFIGURED, LOG_ARCHIVE_PATH, type ListAuthUsersOptions, type LogArchiveConfig, type LogEvent, type LogFields, type LogLevel, LunoraError, type LunoraErrorBody, type LunoraHandlerOptions, type LunoraWorker, type MemoizeIdentityOptions, type MergeStrategy, type MetricEvent, type MetricKind, type MigrationFanOutRequest, type MigrationFanOutResult, NOOP_EXECUTION_CONTEXT, type NotifySubscriptionDevice, type NotifySubscriptionStoreLike, type ObservabilityEvent, type ObservabilitySink, type ObservabilitySinkContext, type OtlpResourceAttributes, type OtlpSinkOptions, type PipelineLike, type PipelineLogColumnMap, type PipelineLogCursor, type PipelineLogField, type PipelineLogPage, type PipelineLogQuery, type PipelineLogReader, type PipelineLogReaderOptions, type PipelineLogRow, type PipelineLogSinkOptions, type PrunedBackups, type QueryCoordinator, type QueryCoordinatorOptions, type RankFanOutRequest, type RankFanOutResult, type RankPageFanOutRequest, type RankPageFanOutResult, type RateLimiterLike, type ResolvedSecurity, type ResolvedShard, type RestInvoke, type RestRateLimit, type RestRegistryEntry, type RestRegistryLike, type RestRoute, type RestRouteDeps, type Route, type RpcContext, type RpcEnvelope, type RunExportTapOptions, SHARD_REGISTRY_DO_NAME, STORAGE_UPLOAD_MAX_BODY_BYTES, type ScheduledControllerLike, type SecurityHeadersOptions, type SecurityOptions, type SentrySinkOptions, type ShardCallArgs, type ShardCallOptions, type ShardCallReturn, type ShardCallerIdentity, type ShardClient, type ShardClientOptions, type ShardError, type ShardExportOutcome, type ShardFunctionReference, type ShardImportOutcome, type ShardMigrationOutcome, type ShardNamespaceInput, type ShardNamespaceLike, type ShardRankOutcome, type ShardRankPageOutcome, type ShardRegistry, type ShardTrafficEntry, type ShardTrafficFanOutRequest, type ShardTrafficFanOutResult, type ShardingInfo, type SpanEvent, type StorageListFunction as StorageListFn, type StorageObject, type TraceSamplingConfig, type TraceTrustSignal, type TrustInboundTraceContext, VERSION, type VectorIndexSummary, type VectorIntrospector, type VectorQueryMatch, type WebhookSinkOptions, type WorkerOptions, analyticsEngineSink, applyJurisdiction, applyRestCache, argsFromQuery, backupManifestKey, backupObjectKey, backupObjectKeyOfManifest, buildHealthRoutes, buildRestRoutes, combineSinks, composeIdentityResolvers, composeWorker, consoleSink, createCrossShardRelationCapabilities, createDynamicShardRegistry, createKvCursorStore, createLunoraHandler, createMemoryCursorStore, createPipelineLogReader, createQueryCoordinator, createRestRateLimit, createShardClient, createStaticShardRegistry, createWorker, d1Probe, decorateResponse, defineExportSink, defineRpcEnvelope, durableObjectProbe, emitLogEvent, emitRpcEvent, enforceOrigin, handleCorsPreflight, isBackupManifestEntry, isBackupManifestKey, memoizeIdentity, memoizeIdentityPerRequest, mergeStrategyForAggregate, normalizeBackupPrefix, otlpSink, pipelineLogSink, presenceProbe, r2Sink, readShardKey, requestCarriesCredentials, resolveLogArchiveFromEnv, resolveLunoraOptions, resolveSecurity, resolveShard, restCacheHeaders, restSurfaceFromRegistry, routeIdentityResolvers, runExportTap, sanitizeChange, sentrySink, toAirbyteMessages, toErrorResponse, toFivetranResponse, webhookExportSink, webhookSink, withFrameworkWorker };
4993
+ export { type AccessContextLike, type AccessIdentityLike, type AdminTableResolver, type AirbyteMessage, type AnalyticsEngineDataPointLike, type AnalyticsEngineDatasetLike, type AnalyticsEngineSinkOptions, type AuthAdmin, type AuthCapabilities, type AuthConfigInfo, type AuthImpersonation, type AuthPage, type AuthSession, type AuthUser, type AuthUserFieldSpec, BACKUP_KEY_PREFIX, type BackupManifest, type BackupManifestEntry, type BackupRetentionPreview, 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_LOG_COLUMNS, DEFAULT_LOG_LIMIT, DEFAULT_REGISTRY_CACHE_TTL_MS, type DurableObjectJurisdiction, type DynamicShardRegistry, type DynamicShardRegistryOptions, type ExecutionContextLike, type ExportBatch, type ExportChange, type ExportCursorStore, type ExportFanOutRequest, type ExportFanOutResult, type ExportSink, type ExportTapFailure, type ExportTapResult, 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, HEALTH_PATH, HEALTH_READY_PATH, type HealthAuthPosture, type HealthBody, type HealthCheckReport, type HealthProbe, type HealthProbeKind, type HealthProbeResult, type HealthRouteDeps, 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, LOG_ARCHIVE_NOT_CONFIGURED, LOG_ARCHIVE_PATH, type ListAuthUsersOptions, type LogArchiveConfig, type LogEvent, type LogFields, type LogLevel, LunoraError, type LunoraErrorBody, type LunoraHandlerOptions, type LunoraWorker, type MemoizeIdentityOptions, type MergeStrategy, type MetricEvent, type MetricKind, type MigrationFanOutRequest, type MigrationFanOutResult, NOOP_EXECUTION_CONTEXT, type NotifySubscriptionDevice, type NotifySubscriptionStoreLike, type ObservabilityEvent, type ObservabilitySink, type ObservabilitySinkContext,
4994
+ /**
4995
+ * Resource attribute bag used by OTLP exporters. Re-exported from `shared/otlp`
4996
+ * because {@link OtlpSinkOptions.resourceAttributes} is part of the public
4997
+ * surface — without a name for it, a caller cannot hoist a shared attribute bag
4998
+ * into a typed constant.
4999
+ */
5000
+ type OtlpResourceAttributes, type OtlpSinkOptions, type PipelineLike, type PipelineLogColumnMap, type PipelineLogCursor, type PipelineLogField, type PipelineLogPage, type PipelineLogQuery, type PipelineLogReader, type PipelineLogReaderOptions, type PipelineLogRow, type PipelineLogSinkOptions, type PrunedBackups, type QueryCoordinator, type QueryCoordinatorOptions, type RankFanOutRequest, type RankFanOutResult, type RankPageFanOutRequest, type RankPageFanOutResult, type RateLimiterLike, type ResolvedSecurity, type ResolvedShard, type RestInvoke, type RestRateLimit, type RestRegistryEntry, type RestRegistryLike, type RestRoute, type RestRouteDeps, type Route, type RpcContext, type RpcEnvelope, type RunExportTapOptions, SHARD_REGISTRY_DO_NAME, STORAGE_UPLOAD_MAX_BODY_BYTES, type ScheduledControllerLike, type SecurityHeadersOptions, type SecurityOptions, type SentrySinkOptions, type ShardCallArgs, type ShardCallOptions, type ShardCallReturn, type ShardCallerIdentity, type ShardClient, type ShardClientOptions, type ShardError, type ShardExportOutcome, type ShardFunctionReference, type ShardImportOutcome, type ShardMigrationOutcome, type ShardNamespaceInput, type ShardNamespaceLike, type ShardRankOutcome, type ShardRankPageOutcome, type ShardRegistry, type ShardTrafficEntry, type ShardTrafficFanOutRequest, type ShardTrafficFanOutResult, type ShardingInfo, type SpanEvent, type StorageListFunction as StorageListFn, type StorageObject, type TraceSamplingConfig, type TraceTrustSignal, type TrustInboundTraceContext, VERSION, type VectorIndexSummary, type VectorIntrospector, type VectorQueryMatch, type WebhookSinkOptions, type WorkerOptions, analyticsEngineSink, applyJurisdiction, applyRestCache, argsFromQuery, backupManifestKey, backupObjectKey, backupObjectKeyOfManifest, buildHealthRoutes, buildRestRoutes, combineSinks, composeIdentityResolvers, composeWorker, consoleSink, createCrossShardRelationCapabilities, createDynamicShardRegistry, createKvCursorStore, createLunoraHandler, createMemoryCursorStore, createPipelineLogReader, createQueryCoordinator, createRestRateLimit, createShardClient, createStaticShardRegistry, createWorker, d1Probe, decorateResponse, defineExportSink, defineRpcEnvelope, durableObjectProbe, emitLogEvent, emitRpcEvent, enforceOrigin, handleCorsPreflight, isBackupManifestEntry, isBackupManifestKey, memoizeIdentity, memoizeIdentityPerRequest, mergeStrategyForAggregate, normalizeBackupPrefix, otlpSink, pipelineLogSink, presenceProbe, r2Sink, readShardKey, requestCarriesCredentials, resolveLogArchiveFromEnv, resolveLunoraOptions, resolveSecurity, resolveShard, restCacheHeaders, restSurfaceFromRegistry, routeIdentityResolvers, runExportTap, sanitizeChange, sentrySink, toAirbyteMessages, toErrorResponse, toFivetranResponse, webhookExportSink, webhookSink, withFrameworkWorker };
package/dist/index.d.ts CHANGED
@@ -208,6 +208,13 @@ declare const toAirbyteMessages: (page: ConnectorSyncPage, emittedAt?: number) =
208
208
  * fall back to {@link NOOP_EXECUTION_CONTEXT}.
209
209
  */
210
210
  interface ExecutionContextLike {
211
+ /**
212
+ * Present only when Cloudflare Access authenticated the request against a
213
+ * policy attached to the **Worker** (rather than to a hostname). `undefined`
214
+ * on every unauthenticated request, so its presence is itself the "Access
215
+ * authorized this caller" signal — see {@link AccessContextLike}.
216
+ */
217
+ access?: AccessContextLike;
211
218
  cache?: {
212
219
  purge: (options: {
213
220
  purgeEverything?: boolean;
@@ -217,6 +224,48 @@ interface ExecutionContextLike {
217
224
  passThroughOnException?: () => void;
218
225
  waitUntil?: (promise: Promise<unknown>) => void;
219
226
  }
227
+ /**
228
+ * The identity Cloudflare Access attaches to a Worker-protected request.
229
+ *
230
+ * Shape follows the Access application-token payload: `sub` is the stable per-user
231
+ * id, `email` the verified address, `common_name` the service-token name (machine
232
+ * callers, whose `sub` is empty), and `exp` the credential expiry in epoch
233
+ * **seconds**. Group membership is whatever the Access policy emits — a list of
234
+ * names, or of `{ id, name }` objects — hence `unknown`; normalize before use.
235
+ *
236
+ * Cloudflare may add further fields, so the index signature keeps them rather
237
+ * than dropping them: this is a view of a payload we do not own.
238
+ */
239
+ interface AccessIdentityLike {
240
+ [claim: string]: unknown;
241
+ /** Service-token name. Present for non-interactive (machine) callers instead of `email`. */
242
+ common_name?: string;
243
+ /** Verified user email. Present for interactive (SSO) callers. */
244
+ email?: string;
245
+ /** Credential expiry, epoch **seconds**. */
246
+ exp?: number;
247
+ /** IdP group membership — names or `{ id, name }` objects, depending on the policy. */
248
+ groups?: unknown;
249
+ /** Display name from the identity provider, when it emits one. */
250
+ name?: string;
251
+ /** Stable per-user id, and what consumers key a user on. Empty for service tokens. */
252
+ sub?: string;
253
+ /** Cloudflare's per-user UUID. Carried through, but deliberately not used as an id — only this path emits it, so keying on it would not match the JWT path. */
254
+ user_uuid?: string;
255
+ }
256
+ /**
257
+ * The `ctx.access` facade Cloudflare exposes on a Worker protected by Access.
258
+ *
259
+ * Reading the identity from here is preferable to verifying the
260
+ * `Cf-Access-Jwt-Assertion` header: the platform has already authenticated the
261
+ * caller, so there is no JWKS fetch, no audience check to get wrong, and nothing
262
+ * a request can forge — the field simply does not exist unless Access authorized
263
+ * the call. The header path remains the fallback for hostname-scoped Access
264
+ * applications, which do not populate this.
265
+ */
266
+ interface AccessContextLike {
267
+ getIdentity: () => AccessIdentityLike | null | undefined | Promise<AccessIdentityLike | null | undefined>;
268
+ }
220
269
  /**
221
270
  * No-op `ExecutionContext` used when the host runtime didn't supply one (a
222
271
  * non-Cloudflare preview, or a unit test), so the worker's `fetch` always
@@ -1597,8 +1646,13 @@ interface ResolvedIdentity {
1597
1646
  * so `.auth()`'s better-auth session resolver, a signed-preview-link verifier, a
1598
1647
  * per-tenant bearer check, an upstream-JWT reader, … are all just `IdentityResolver`s
1599
1648
  * — the identity layer is generic over every scheme, not coupled to any one.
1649
+ *
1650
+ * The optional third argument is the request's `ExecutionContext`, for a scheme
1651
+ * whose credential the platform supplies out-of-band rather than on the request
1652
+ * (`context.access` under Worker-scoped Cloudflare Access). It is `undefined`
1653
+ * wherever the host gave the worker no context.
1600
1654
  */
1601
- type IdentityResolver = (request: Request, env: unknown) => Promise<ResolvedIdentity | null> | ResolvedIdentity | null;
1655
+ type IdentityResolver = (request: Request, env: unknown, context?: ExecutionContextLike) => Promise<ResolvedIdentity | null> | ResolvedIdentity | null;
1602
1656
  /** Error policy for {@link composeIdentityResolvers} when a participant resolver throws. */
1603
1657
  type ComposeIdentityResolversErrorMode = "fail-closed" | "skip";
1604
1658
  /** Options for {@link composeIdentityResolvers}. */
@@ -2439,12 +2493,12 @@ type RestRateLimit = (request: Request, functionPath: string) => Promise<Respons
2439
2493
  /**
2440
2494
  * A built REST route. Takes the same `(request, env, url, context)` shape as the
2441
2495
  * runtime's internal route table so it can be spread straight into it; `url` is
2442
- * unused here (the route re-parses it) and `context` is read only for its
2443
- * `waitUntil`, which keeps dispatch telemetry alive past the response.
2496
+ * unused here (the route re-parses it). The context is the real
2497
+ * {@link ExecutionContextLike} rather than a `waitUntil`-only projection, because
2498
+ * the cache decision reads `context.access` too — see the `applyRestCache` call
2499
+ * below.
2444
2500
  */
2445
- type RestRoute = (request: Request, env: unknown, url?: URL, context?: {
2446
- waitUntil?: (promise: Promise<unknown>) => void;
2447
- }) => Promise<Response>;
2501
+ type RestRoute = (request: Request, env: unknown, url?: URL, context?: ExecutionContextLike) => Promise<Response>;
2448
2502
  interface RestRouteDeps {
2449
2503
  /** The generated function registry — the source of which procedures are exposed. */
2450
2504
  functions: RestRegistryLike;
@@ -3393,11 +3447,15 @@ interface WorkerOptions {
3393
3447
  * The intended producer is `@lunora/cloudflare-access`'s `accessAdminGate(...)`,
3394
3448
  * which verifies the request's `Cf-Access-Jwt-Assertion` JWT and applies an
3395
3449
  * `isAdmin(claims)` predicate — so the Studio can sit behind Cloudflare Access
3396
- * instead of (or alongside) a shared admin token. It takes only the request
3397
- * (verification needs static team-domain/aud config + the remote JWKS, no env
3398
- * binding), so it composes without threading async through every admin route.
3450
+ * instead of (or alongside) a shared admin token. It needs no `env` binding
3451
+ * (verification is static team-domain/aud config + the remote JWKS), so it
3452
+ * composes without threading async through every admin route.
3453
+ *
3454
+ * The second argument is the request's `ExecutionContext`, carrying
3455
+ * `context.access` when the Access policy is attached to the Worker rather
3456
+ * than to a hostname. It is `undefined` when the host supplied no context.
3399
3457
  */
3400
- adminGate?: (request: Request) => boolean | Promise<boolean>;
3458
+ adminGate?: (request: Request, context?: ExecutionContextLike) => boolean | Promise<boolean>;
3401
3459
  /**
3402
3460
  * Admin bearer token expected by the export/import endpoints. When unset,
3403
3461
  * the endpoints respond with `ADMIN_FORBIDDEN` — the same posture the
@@ -3804,8 +3862,16 @@ interface WorkerOptions {
3804
3862
  * forwarded as `x-lunora-identity` so `ctx.auth.getIdentity()` can
3805
3863
  * return them. Returning `null` (or omitting this option) means
3806
3864
  * anonymous — no identity headers are injected.
3865
+ *
3866
+ * The third argument is the request's `ExecutionContext`, forwarded so a
3867
+ * resolver can read identity the platform supplies out-of-band rather than
3868
+ * off the request — `context.access` on a Worker protected by Cloudflare
3869
+ * Access is the one that exists today. It is `undefined` on the paths that
3870
+ * have no context to give (a direct {@link LunoraWorker.serverQuery} call, a
3871
+ * host that mounts the worker without one), so a resolver that uses it must
3872
+ * still handle its absence.
3807
3873
  */
3808
- resolveIdentity?: (request: Request, env: unknown) => Promise<ResolvedIdentity | null> | ResolvedIdentity | null;
3874
+ resolveIdentity?: (request: Request, env: unknown, context?: ExecutionContextLike) => Promise<ResolvedIdentity | null> | ResolvedIdentity | null;
3809
3875
  /**
3810
3876
  * Resolve a table's sharding metadata. Required by the import endpoint to
3811
3877
  * bucket rows; when omitted, every row routes to the default shard.
@@ -4074,12 +4140,18 @@ interface LunoraWorker {
4074
4140
  * `__lunoraRef` is the `"namespace:fn"` dispatched.
4075
4141
  * @param args The function arguments.
4076
4142
  * @param options Call options mirroring the RPC envelope.
4143
+ * @param options.context The host's `ExecutionContext`. Required to reach an
4144
+ * identity the platform supplies out-of-band rather than on the
4145
+ * request — `context.access` under a Worker-scoped Cloudflare
4146
+ * Access policy. Omit it there and the call resolves anonymous
4147
+ * while the same user's `/_lunora/rpc` traffic is authenticated.
4077
4148
  * @param options.shardKey Routes to a specific shard (omitted → the worker's
4078
4149
  * `defaultShardKey`).
4079
4150
  * @param options.waitUntil The host's `waitUntil`, so dispatch telemetry
4080
4151
  * whose export is deferred (a gzipped OTLP body) survives isolate teardown.
4081
4152
  */
4082
4153
  serverQuery: (request: Request, env: unknown, reference: unknown, args?: Record<string, unknown>, options?: {
4154
+ context?: ExecutionContextLike;
4083
4155
  shardKey?: string;
4084
4156
  waitUntil?: (promise: Promise<unknown>) => void;
4085
4157
  }) => Promise<Response>;
@@ -4799,8 +4871,16 @@ declare const combineSinks: (...sinks: ObservabilitySink[]) => ObservabilitySink
4799
4871
  * as caller-specific. Checks the built-in identity headers plus anything the
4800
4872
  * policy declares via `credentialHeaders` — an app whose `resolveIdentity` reads
4801
4873
  * a bespoke header must say so, or its callers read as anonymous here.
4874
+ *
4875
+ * A credential does not have to be on the request at all: under a Cloudflare
4876
+ * Access policy attached to the Worker, the caller is authenticated by the edge
4877
+ * and their identity arrives on the `ExecutionContext` as `access`, with no
4878
+ * header this function could see. Its mere presence means Access authorized this
4879
+ * specific caller, so it counts as a credential — otherwise a per-user response
4880
+ * would be labelled `public` and a shared cache could hand it to the next
4881
+ * visitor.
4802
4882
  */
4803
- declare const requestCarriesCredentials: (request: Request, policy: RestCachePolicy) => boolean;
4883
+ declare const requestCarriesCredentials: (request: Request, policy: RestCachePolicy, context?: ExecutionContextLike) => boolean;
4804
4884
  /**
4805
4885
  * Build the cache headers for one exchange, or `undefined` when the exchange
4806
4886
  * isn't cacheable at all (non-`GET`, or a non-2xx result — an error body must
@@ -4809,14 +4889,14 @@ declare const requestCarriesCredentials: (request: Request, policy: RestCachePol
4809
4889
  * The effective scope is `policy.scope` narrowed by {@link requestCarriesCredentials};
4810
4890
  * `"public"` survives only for a genuinely anonymous request.
4811
4891
  */
4812
- declare const restCacheHeaders: (policy: RestCachePolicy, request: Request, status: number) => Record<string, string> | undefined;
4892
+ declare const restCacheHeaders: (policy: RestCachePolicy, request: Request, status: number, context?: ExecutionContextLike) => Record<string, string> | undefined;
4813
4893
  /**
4814
4894
  * Return `response` with the declared cache headers applied. A shard `Response`
4815
4895
  * has immutable headers, so this rebuilds it (status/statusText/existing headers
4816
4896
  * are carried over, the body is streamed through untouched). When the exchange
4817
4897
  * isn't cacheable the original response is returned as-is — no copy.
4818
4898
  */
4819
- declare const applyRestCache: (response: Response, policy: RestCachePolicy | undefined, request: Request) => Response;
4899
+ declare const applyRestCache: (response: Response, policy: RestCachePolicy | undefined, request: Request, context?: ExecutionContextLike) => Response;
4820
4900
  /**
4821
4901
  * Structural mirror of `@lunora/client`'s `FunctionReference`, re-declared so this
4822
4902
  * module carries no `runtime → client` (browser SDK) dependency. The phantom
@@ -4910,4 +4990,11 @@ declare const createShardClient: (namespace: ShardNamespaceLike, options?: Shard
4910
4990
  */
4911
4991
  declare const STORAGE_UPLOAD_MAX_BODY_BYTES: number;
4912
4992
  declare const VERSION: string;
4913
- export { type AdminTableResolver, type AirbyteMessage, type AnalyticsEngineDataPointLike, type AnalyticsEngineDatasetLike, type AnalyticsEngineSinkOptions, type AuthAdmin, type AuthCapabilities, type AuthConfigInfo, type AuthImpersonation, type AuthPage, type AuthSession, type AuthUser, type AuthUserFieldSpec, BACKUP_KEY_PREFIX, type BackupManifest, type BackupManifestEntry, type BackupRetentionPreview, 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_LOG_COLUMNS, DEFAULT_LOG_LIMIT, DEFAULT_REGISTRY_CACHE_TTL_MS, type DurableObjectJurisdiction, type DynamicShardRegistry, type DynamicShardRegistryOptions, type ExecutionContextLike, type ExportBatch, type ExportChange, type ExportCursorStore, type ExportFanOutRequest, type ExportFanOutResult, type ExportSink, type ExportTapFailure, type ExportTapResult, 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, HEALTH_PATH, HEALTH_READY_PATH, type HealthAuthPosture, type HealthBody, type HealthCheckReport, type HealthProbe, type HealthProbeKind, type HealthProbeResult, type HealthRouteDeps, 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, LOG_ARCHIVE_NOT_CONFIGURED, LOG_ARCHIVE_PATH, type ListAuthUsersOptions, type LogArchiveConfig, type LogEvent, type LogFields, type LogLevel, LunoraError, type LunoraErrorBody, type LunoraHandlerOptions, type LunoraWorker, type MemoizeIdentityOptions, type MergeStrategy, type MetricEvent, type MetricKind, type MigrationFanOutRequest, type MigrationFanOutResult, NOOP_EXECUTION_CONTEXT, type NotifySubscriptionDevice, type NotifySubscriptionStoreLike, type ObservabilityEvent, type ObservabilitySink, type ObservabilitySinkContext, type OtlpResourceAttributes, type OtlpSinkOptions, type PipelineLike, type PipelineLogColumnMap, type PipelineLogCursor, type PipelineLogField, type PipelineLogPage, type PipelineLogQuery, type PipelineLogReader, type PipelineLogReaderOptions, type PipelineLogRow, type PipelineLogSinkOptions, type PrunedBackups, type QueryCoordinator, type QueryCoordinatorOptions, type RankFanOutRequest, type RankFanOutResult, type RankPageFanOutRequest, type RankPageFanOutResult, type RateLimiterLike, type ResolvedSecurity, type ResolvedShard, type RestInvoke, type RestRateLimit, type RestRegistryEntry, type RestRegistryLike, type RestRoute, type RestRouteDeps, type Route, type RpcContext, type RpcEnvelope, type RunExportTapOptions, SHARD_REGISTRY_DO_NAME, STORAGE_UPLOAD_MAX_BODY_BYTES, type ScheduledControllerLike, type SecurityHeadersOptions, type SecurityOptions, type SentrySinkOptions, type ShardCallArgs, type ShardCallOptions, type ShardCallReturn, type ShardCallerIdentity, type ShardClient, type ShardClientOptions, type ShardError, type ShardExportOutcome, type ShardFunctionReference, type ShardImportOutcome, type ShardMigrationOutcome, type ShardNamespaceInput, type ShardNamespaceLike, type ShardRankOutcome, type ShardRankPageOutcome, type ShardRegistry, type ShardTrafficEntry, type ShardTrafficFanOutRequest, type ShardTrafficFanOutResult, type ShardingInfo, type SpanEvent, type StorageListFunction as StorageListFn, type StorageObject, type TraceSamplingConfig, type TraceTrustSignal, type TrustInboundTraceContext, VERSION, type VectorIndexSummary, type VectorIntrospector, type VectorQueryMatch, type WebhookSinkOptions, type WorkerOptions, analyticsEngineSink, applyJurisdiction, applyRestCache, argsFromQuery, backupManifestKey, backupObjectKey, backupObjectKeyOfManifest, buildHealthRoutes, buildRestRoutes, combineSinks, composeIdentityResolvers, composeWorker, consoleSink, createCrossShardRelationCapabilities, createDynamicShardRegistry, createKvCursorStore, createLunoraHandler, createMemoryCursorStore, createPipelineLogReader, createQueryCoordinator, createRestRateLimit, createShardClient, createStaticShardRegistry, createWorker, d1Probe, decorateResponse, defineExportSink, defineRpcEnvelope, durableObjectProbe, emitLogEvent, emitRpcEvent, enforceOrigin, handleCorsPreflight, isBackupManifestEntry, isBackupManifestKey, memoizeIdentity, memoizeIdentityPerRequest, mergeStrategyForAggregate, normalizeBackupPrefix, otlpSink, pipelineLogSink, presenceProbe, r2Sink, readShardKey, requestCarriesCredentials, resolveLogArchiveFromEnv, resolveLunoraOptions, resolveSecurity, resolveShard, restCacheHeaders, restSurfaceFromRegistry, routeIdentityResolvers, runExportTap, sanitizeChange, sentrySink, toAirbyteMessages, toErrorResponse, toFivetranResponse, webhookExportSink, webhookSink, withFrameworkWorker };
4993
+ export { type AccessContextLike, type AccessIdentityLike, type AdminTableResolver, type AirbyteMessage, type AnalyticsEngineDataPointLike, type AnalyticsEngineDatasetLike, type AnalyticsEngineSinkOptions, type AuthAdmin, type AuthCapabilities, type AuthConfigInfo, type AuthImpersonation, type AuthPage, type AuthSession, type AuthUser, type AuthUserFieldSpec, BACKUP_KEY_PREFIX, type BackupManifest, type BackupManifestEntry, type BackupRetentionPreview, 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_LOG_COLUMNS, DEFAULT_LOG_LIMIT, DEFAULT_REGISTRY_CACHE_TTL_MS, type DurableObjectJurisdiction, type DynamicShardRegistry, type DynamicShardRegistryOptions, type ExecutionContextLike, type ExportBatch, type ExportChange, type ExportCursorStore, type ExportFanOutRequest, type ExportFanOutResult, type ExportSink, type ExportTapFailure, type ExportTapResult, 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, HEALTH_PATH, HEALTH_READY_PATH, type HealthAuthPosture, type HealthBody, type HealthCheckReport, type HealthProbe, type HealthProbeKind, type HealthProbeResult, type HealthRouteDeps, 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, LOG_ARCHIVE_NOT_CONFIGURED, LOG_ARCHIVE_PATH, type ListAuthUsersOptions, type LogArchiveConfig, type LogEvent, type LogFields, type LogLevel, LunoraError, type LunoraErrorBody, type LunoraHandlerOptions, type LunoraWorker, type MemoizeIdentityOptions, type MergeStrategy, type MetricEvent, type MetricKind, type MigrationFanOutRequest, type MigrationFanOutResult, NOOP_EXECUTION_CONTEXT, type NotifySubscriptionDevice, type NotifySubscriptionStoreLike, type ObservabilityEvent, type ObservabilitySink, type ObservabilitySinkContext,
4994
+ /**
4995
+ * Resource attribute bag used by OTLP exporters. Re-exported from `shared/otlp`
4996
+ * because {@link OtlpSinkOptions.resourceAttributes} is part of the public
4997
+ * surface — without a name for it, a caller cannot hoist a shared attribute bag
4998
+ * into a typed constant.
4999
+ */
5000
+ type OtlpResourceAttributes, type OtlpSinkOptions, type PipelineLike, type PipelineLogColumnMap, type PipelineLogCursor, type PipelineLogField, type PipelineLogPage, type PipelineLogQuery, type PipelineLogReader, type PipelineLogReaderOptions, type PipelineLogRow, type PipelineLogSinkOptions, type PrunedBackups, type QueryCoordinator, type QueryCoordinatorOptions, type RankFanOutRequest, type RankFanOutResult, type RankPageFanOutRequest, type RankPageFanOutResult, type RateLimiterLike, type ResolvedSecurity, type ResolvedShard, type RestInvoke, type RestRateLimit, type RestRegistryEntry, type RestRegistryLike, type RestRoute, type RestRouteDeps, type Route, type RpcContext, type RpcEnvelope, type RunExportTapOptions, SHARD_REGISTRY_DO_NAME, STORAGE_UPLOAD_MAX_BODY_BYTES, type ScheduledControllerLike, type SecurityHeadersOptions, type SecurityOptions, type SentrySinkOptions, type ShardCallArgs, type ShardCallOptions, type ShardCallReturn, type ShardCallerIdentity, type ShardClient, type ShardClientOptions, type ShardError, type ShardExportOutcome, type ShardFunctionReference, type ShardImportOutcome, type ShardMigrationOutcome, type ShardNamespaceInput, type ShardNamespaceLike, type ShardRankOutcome, type ShardRankPageOutcome, type ShardRegistry, type ShardTrafficEntry, type ShardTrafficFanOutRequest, type ShardTrafficFanOutResult, type ShardingInfo, type SpanEvent, type StorageListFunction as StorageListFn, type StorageObject, type TraceSamplingConfig, type TraceTrustSignal, type TrustInboundTraceContext, VERSION, type VectorIndexSummary, type VectorIntrospector, type VectorQueryMatch, type WebhookSinkOptions, type WorkerOptions, analyticsEngineSink, applyJurisdiction, applyRestCache, argsFromQuery, backupManifestKey, backupObjectKey, backupObjectKeyOfManifest, buildHealthRoutes, buildRestRoutes, combineSinks, composeIdentityResolvers, composeWorker, consoleSink, createCrossShardRelationCapabilities, createDynamicShardRegistry, createKvCursorStore, createLunoraHandler, createMemoryCursorStore, createPipelineLogReader, createQueryCoordinator, createRestRateLimit, createShardClient, createStaticShardRegistry, createWorker, d1Probe, decorateResponse, defineExportSink, defineRpcEnvelope, durableObjectProbe, emitLogEvent, emitRpcEvent, enforceOrigin, handleCorsPreflight, isBackupManifestEntry, isBackupManifestKey, memoizeIdentity, memoizeIdentityPerRequest, mergeStrategyForAggregate, normalizeBackupPrefix, otlpSink, pipelineLogSink, presenceProbe, r2Sink, readShardKey, requestCarriesCredentials, resolveLogArchiveFromEnv, resolveLunoraOptions, resolveSecurity, resolveShard, restCacheHeaders, restSurfaceFromRegistry, routeIdentityResolvers, runExportTap, sanitizeChange, sentrySink, toAirbyteMessages, toErrorResponse, toFivetranResponse, webhookExportSink, webhookSink, withFrameworkWorker };
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{BACKUP_KEY_PREFIX as t,backupManifestKey as a,backupObjectKey as s,backupObjectKeyOfManifest as i,isBackupManifestEntry as n,isBackupManifestKey as p,normalizeBackupPrefix as m}from"./packem_shared/BACKUP_KEY_PREFIX-DhFUE3VL.mjs";import{toAirbyteMessages as f,toFivetranResponse as E}from"./packem_shared/toAirbyteMessages-DTk8e2f9.mjs";import{composeWorker as S,createLunoraHandler as x,createWorker as _,defineRpcEnvelope as d,resolveLunoraOptions as l,withFrameworkWorker as u}from"./packem_shared/composeWorker-rVokGnPq.mjs";import{createCrossShardRelationCapabilities as k}from"./packem_shared/createCrossShardRelationCapabilities-CQfrCIWR.mjs";import{DEFAULT_REGISTRY_CACHE_TTL_MS as A,SHARD_REGISTRY_DO_NAME as C,createDynamicShardRegistry as L}from"./packem_shared/DEFAULT_REGISTRY_CACHE_TTL_MS-DqWtiFAk.mjs";import{LunoraError as g,toErrorResponse as b}from"./packem_shared/LunoraError-ByasbDmd.mjs";import{createKvCursorStore as H,createMemoryCursorStore as I,defineExportSink as P,r2Sink as v,runExportTap as D,sanitizeChange as F,webhookExportSink as M}from"./packem_shared/createKvCursorStore-C24tEuYk.mjs";import{HEALTH_PATH as G,HEALTH_READY_PATH as K,buildHealthRoutes as N,d1Probe as B,durableObjectProbe as Y,presenceProbe as w}from"./packem_shared/HEALTH_PATH-BwWsxoqV.mjs";import{LOG_ARCHIVE_PATH as X,resolveLogArchiveFromEnv as j}from"./packem_shared/LOG_ARCHIVE_PATH-CuHKuDCS.mjs";import{memoizeIdentity as W,memoizeIdentityPerRequest as q}from"./packem_shared/memoizeIdentity-CX3xEPYw.mjs";import{e as J,a as Z}from"./packem_shared/observability-DWlkDJJw.mjs";import{analyticsEngineSink as ee,combineSinks as re,consoleSink as oe,otlpSink as te,pipelineLogSink as ae,sentrySink as se,webhookSink as ie}from"./packem_shared/analyticsEngineSink-iIRy11I9.mjs";import{D as pe,a as me,c as ce}from"./packem_shared/pipeline-log-reader-FF1V32O2.mjs";import{createQueryCoordinator as Ee,createStaticShardRegistry as Re,mergeStrategyForAggregate as Se}from"./packem_shared/createQueryCoordinator-D8GY_boW.mjs";import{applyJurisdiction as _e,resolveShard as de}from"./packem_shared/applyJurisdiction-DX_lQ6fY.mjs";import{R as ue,d as ye,o as ke}from"./packem_shared/rest-cache-5unAzdFN.mjs";import{g as Ae,E as Ce,U as Le,p as Te,y as ge}from"./packem_shared/rest-routes-BqldHiaH.mjs";import{decorateResponse as he,enforceOrigin as He,handleCorsPreflight as Ie,resolveSecurity as Pe}from"./packem_shared/decorateResponse-BeLVRQuJ.mjs";import{createShardClient as De}from"./packem_shared/createShardClient-DoSOeXwx.mjs";import{STORAGE_UPLOAD_MAX_BODY_BYTES as Me}from"./packem_shared/STORAGE_UPLOAD_MAX_BODY_BYTES-K0uZPIUj.mjs";import{LOG_ARCHIVE_NOT_CONFIGURED as Ge}from"./packem_shared/LOG_ARCHIVE_NOT_CONFIGURED-CDpi4yFD.mjs";import{NOOP_EXECUTION_CONTEXT as Ne}from"./packem_shared/NOOP_EXECUTION_CONTEXT-YmXqH-jH.mjs";import{composeIdentityResolvers as Ye,routeIdentityResolvers as we}from"./packem_shared/composeIdentityResolvers-DwE0Jbww.mjs";const e="0.0.0";export{t as BACKUP_KEY_PREFIX,pe as DEFAULT_LOG_COLUMNS,me as DEFAULT_LOG_LIMIT,A as DEFAULT_REGISTRY_CACHE_TTL_MS,G as HEALTH_PATH,K as HEALTH_READY_PATH,Ge as LOG_ARCHIVE_NOT_CONFIGURED,X as LOG_ARCHIVE_PATH,g as LunoraError,Ne as NOOP_EXECUTION_CONTEXT,C as SHARD_REGISTRY_DO_NAME,Me as STORAGE_UPLOAD_MAX_BODY_BYTES,e as VERSION,ee as analyticsEngineSink,_e as applyJurisdiction,ue as applyRestCache,Ae as argsFromQuery,a as backupManifestKey,s as backupObjectKey,i as backupObjectKeyOfManifest,N as buildHealthRoutes,Ce as buildRestRoutes,re as combineSinks,Ye as composeIdentityResolvers,S as composeWorker,oe as consoleSink,k as createCrossShardRelationCapabilities,L as createDynamicShardRegistry,H as createKvCursorStore,x as createLunoraHandler,I as createMemoryCursorStore,ce as createPipelineLogReader,Ee as createQueryCoordinator,Le as createRestRateLimit,De as createShardClient,Re as createStaticShardRegistry,_ as createWorker,B as d1Probe,he as decorateResponse,P as defineExportSink,d as defineRpcEnvelope,Y as durableObjectProbe,J as emitLogEvent,Z as emitRpcEvent,He as enforceOrigin,Ie as handleCorsPreflight,n as isBackupManifestEntry,p as isBackupManifestKey,W as memoizeIdentity,q as memoizeIdentityPerRequest,Se as mergeStrategyForAggregate,m as normalizeBackupPrefix,te as otlpSink,ae as pipelineLogSink,w as presenceProbe,v as r2Sink,Te as readShardKey,ye as requestCarriesCredentials,j as resolveLogArchiveFromEnv,l as resolveLunoraOptions,Pe as resolveSecurity,de as resolveShard,ke as restCacheHeaders,ge as restSurfaceFromRegistry,we as routeIdentityResolvers,D as runExportTap,F as sanitizeChange,se as sentrySink,f as toAirbyteMessages,b as toErrorResponse,E as toFivetranResponse,M as webhookExportSink,ie as webhookSink,u as withFrameworkWorker};
1
+ import{BACKUP_KEY_PREFIX as t,backupManifestKey as a,backupObjectKey as s,backupObjectKeyOfManifest as i,isBackupManifestEntry as n,isBackupManifestKey as p,normalizeBackupPrefix as c}from"./packem_shared/BACKUP_KEY_PREFIX-BOtSu-_3.mjs";import{toAirbyteMessages as f,toFivetranResponse as E}from"./packem_shared/toAirbyteMessages-Cy3uaySU.mjs";import{composeWorker as S,createLunoraHandler as x,createWorker as _,defineRpcEnvelope as d,resolveLunoraOptions as l,withFrameworkWorker as u}from"./packem_shared/composeWorker-CTKu1qZV.mjs";import{createCrossShardRelationCapabilities as k}from"./packem_shared/createCrossShardRelationCapabilities-DgQYQzd1.mjs";import{DEFAULT_REGISTRY_CACHE_TTL_MS as A,SHARD_REGISTRY_DO_NAME as C,createDynamicShardRegistry as L}from"./packem_shared/DEFAULT_REGISTRY_CACHE_TTL_MS-D5O7elXI.mjs";import{LunoraError as b,toErrorResponse as g}from"./packem_shared/LunoraError-DksAgIpa.mjs";import{createKvCursorStore as H,createMemoryCursorStore as I,defineExportSink as P,r2Sink as v,runExportTap as D,sanitizeChange as F,webhookExportSink as M}from"./packem_shared/createKvCursorStore-VOd1DFsf.mjs";import{HEALTH_PATH as K,HEALTH_READY_PATH as N,buildHealthRoutes as U,d1Probe as B,durableObjectProbe as Y,presenceProbe as w}from"./packem_shared/HEALTH_PATH-jZsuCmSs.mjs";import{LOG_ARCHIVE_PATH as X,resolveLogArchiveFromEnv as j}from"./packem_shared/LOG_ARCHIVE_PATH-jgHjdsz2.mjs";import{memoizeIdentity as W,memoizeIdentityPerRequest as q}from"./packem_shared/memoizeIdentity-DnOj3QRi.mjs";import{e as J,a as Z}from"./packem_shared/observability-vDK-rMbs.mjs";import{analyticsEngineSink as ee,combineSinks as re,consoleSink as oe,otlpSink as te,pipelineLogSink as ae,sentrySink as se,webhookSink as ie}from"./packem_shared/analyticsEngineSink-D7qu89f2.mjs";import{D as pe,a as ce,c as me}from"./packem_shared/pipeline-log-reader-BGrl66P5.mjs";import{createQueryCoordinator as Ee,createStaticShardRegistry as Re,mergeStrategyForAggregate as Se}from"./packem_shared/createQueryCoordinator-CnNyazLX.mjs";import{applyJurisdiction as _e,resolveShard as de}from"./packem_shared/applyJurisdiction-C0ddU7Tg.mjs";import{a as ue,r as ye,b as ke}from"./packem_shared/rest-cache-BnMq2hbO.mjs";import{a as Ae,b as Ce,c as Le,r as Te,d as be}from"./packem_shared/rest-routes-D2b3HXA9.mjs";import{decorateResponse as he,enforceOrigin as He,handleCorsPreflight as Ie,resolveSecurity as Pe}from"./packem_shared/decorateResponse-D3NzOIvB.mjs";import{createShardClient as De}from"./packem_shared/createShardClient-Yb6_Mzd6.mjs";import{STORAGE_UPLOAD_MAX_BODY_BYTES as Me}from"./packem_shared/STORAGE_UPLOAD_MAX_BODY_BYTES-BqyO-1l6.mjs";import{LOG_ARCHIVE_NOT_CONFIGURED as Ke}from"./packem_shared/LOG_ARCHIVE_NOT_CONFIGURED-CDpi4yFD.mjs";import{NOOP_EXECUTION_CONTEXT as Ue}from"./packem_shared/NOOP_EXECUTION_CONTEXT-YmXqH-jH.mjs";import{composeIdentityResolvers as Ye,routeIdentityResolvers as we}from"./packem_shared/composeIdentityResolvers-BHZ4jH8o.mjs";const e="0.0.0";export{t as BACKUP_KEY_PREFIX,pe as DEFAULT_LOG_COLUMNS,ce as DEFAULT_LOG_LIMIT,A as DEFAULT_REGISTRY_CACHE_TTL_MS,K as HEALTH_PATH,N as HEALTH_READY_PATH,Ke as LOG_ARCHIVE_NOT_CONFIGURED,X as LOG_ARCHIVE_PATH,b as LunoraError,Ue as NOOP_EXECUTION_CONTEXT,C as SHARD_REGISTRY_DO_NAME,Me as STORAGE_UPLOAD_MAX_BODY_BYTES,e as VERSION,ee as analyticsEngineSink,_e as applyJurisdiction,ue as applyRestCache,Ae as argsFromQuery,a as backupManifestKey,s as backupObjectKey,i as backupObjectKeyOfManifest,U as buildHealthRoutes,Ce as buildRestRoutes,re as combineSinks,Ye as composeIdentityResolvers,S as composeWorker,oe as consoleSink,k as createCrossShardRelationCapabilities,L as createDynamicShardRegistry,H as createKvCursorStore,x as createLunoraHandler,I as createMemoryCursorStore,me as createPipelineLogReader,Ee as createQueryCoordinator,Le as createRestRateLimit,De as createShardClient,Re as createStaticShardRegistry,_ as createWorker,B as d1Probe,he as decorateResponse,P as defineExportSink,d as defineRpcEnvelope,Y as durableObjectProbe,J as emitLogEvent,Z as emitRpcEvent,He as enforceOrigin,Ie as handleCorsPreflight,n as isBackupManifestEntry,p as isBackupManifestKey,W as memoizeIdentity,q as memoizeIdentityPerRequest,Se as mergeStrategyForAggregate,c as normalizeBackupPrefix,te as otlpSink,ae as pipelineLogSink,w as presenceProbe,v as r2Sink,Te as readShardKey,ye as requestCarriesCredentials,j as resolveLogArchiveFromEnv,l as resolveLunoraOptions,Pe as resolveSecurity,de as resolveShard,ke as restCacheHeaders,be as restSurfaceFromRegistry,we as routeIdentityResolvers,D as runExportTap,F as sanitizeChange,se as sentrySink,f as toAirbyteMessages,g as toErrorResponse,E as toFivetranResponse,M as webhookExportSink,ie as webhookSink,u as withFrameworkWorker};
@@ -0,0 +1 @@
1
+ const e="backups/",c=t=>t===""||t.endsWith("/")?t:`${t}/`,n=".manifest.json",o=(t,s)=>`${c(t)}lunora-backup-${s.replaceAll(/[.:]/gu,"-")}.ndjson`,a=t=>`${t}${n}`,i=t=>t.endsWith(n),p=t=>t.slice(0,-n.length),b=t=>typeof t=="object"&&t!==null&&typeof t.id=="string"&&typeof t.file=="string";export{e as BACKUP_KEY_PREFIX,a as backupManifestKey,o as backupObjectKey,p as backupObjectKeyOfManifest,b as isBackupManifestEntry,i as isBackupManifestKey,c as normalizeBackupPrefix};
@@ -0,0 +1 @@
1
+ import{D as a,a as r,c as _}from"./pipeline-log-reader-BGrl66P5.mjs";export{a as DEFAULT_LOG_COLUMNS,r as DEFAULT_LOG_LIMIT,_ as createPipelineLogReader};
@@ -0,0 +1 @@
1
+ import{LunoraError as a}from"./LunoraError-DksAgIpa.mjs";import{applyJurisdiction as _,resolveShard as l}from"./applyJurisdiction-C0ddU7Tg.mjs";const f="__lunora_shard_registry__",m=3e4,g="https://shard-registry.internal",p=async r=>await r.json(),E=r=>{const w=r.instanceName??f,c=r.cacheTtlMs??m,n=new Map,S=_(r.namespace,r.jurisdiction);let i;const d=()=>(i??=l(S,w),i),h=async(e,t)=>d().fetch(new Request(`${g}${e}`,{body:JSON.stringify(t),headers:{"content-type":"application/json"},method:"POST"})),u=async e=>d().fetch(new Request(`${g}${e}`,{method:"GET"}));return{invalidate(e){e===void 0?n.clear():n.delete(e)},async listShardKeys(e){const t=Date.now(),s=n.get(e);if(s&&s.expiresAt>t)return s.shardKeys;const o=await u(`/list?table=${encodeURIComponent(e)}`);if(!o.ok)throw new a(`shard registry /list returned ${String(o.status)}`);const{shardKeys:y}=await p(o);return c>0&&n.set(e,{expiresAt:t+c,shardKeys:y}),y},async register(e,t){const s=await h("/register",{shardKey:t,table:e});if(!s.ok)throw new a(`shard registry /register returned ${String(s.status)}`);n.delete(e)},async snapshot(){const e=await u("/snapshot");if(!e.ok)throw new a(`shard registry /snapshot returned ${String(e.status)}`);const{tables:t}=await p(e);return t},async unregister(e,t){const s=await h("/unregister",{shardKey:t,table:e});if(!s.ok)throw new a(`shard registry /unregister returned ${String(s.status)}`);n.delete(e)}}};export{m as DEFAULT_REGISTRY_CACHE_TTL_MS,f as SHARD_REGISTRY_DO_NAME,E as createDynamicShardRegistry};
@@ -0,0 +1 @@
1
+ import{LunoraError as T}from"./LunoraError-DksAgIpa.mjs";import{m as A}from"./method-guard-BG_vJNTl.mjs";import{resolveShard as R}from"./applyJurisdiction-C0ddU7Tg.mjs";const C="/_lunora/health",H="/_lunora/health/ready",N=t=>t==="liveness"?["liveness"]:t==="readiness"?["readiness"]:["liveness","readiness"];class P{#e=new Map;addChecker(e,s,r){this.#e.set(e,{run:s,types:r.type})}async getReport(e){const s=[...this.#e].filter(([,a])=>e===void 0||a.types.includes(e)),r=await Promise.all(s.map(async([a,o])=>[a,await o.run()]));return{healthy:r.every(([,a])=>a.health.healthy),report:Object.fromEntries(r)}}}const S=t=>{const e=new P,s=new Set;for(const r of t)r.critical&&s.add(r.name),e.addChecker(r.name,async()=>{let a;try{a=await r.check()}catch(o){a={healthy:!1,message:o instanceof Error?o.message:"probe failed"}}return{health:{healthy:a.healthy,...a.message===void 0?{}:{message:a.message}}}},{type:N(r.kind)});return{criticalNames:s,registry:e}},_=(t,e)=>{const s=t.includes(":")?t.slice(0,t.indexOf(":")):"probe",r=(e.get(s)??0)+1;return e.set(s,r),r===1?s:`${s}#${String(r)}`},j=(t,e)=>t?"unhealthy":e?"degraded":"healthy",M=(t,e,s,r,a)=>{const o=[];let u=!1,d=!1;const y=new Map;for(const[h,i]of Object.entries(t)){const n=e.has(h),c=i.health.healthy;d=d||!c,u=u||!c&&n;const l=s==="admin"?h:_(h,y);o.push({critical:n,...s==="admin"&&i.health.message!==void 0?{message:i.health.message}:{},name:l,status:c?"up":"down"})}return o.sort((h,i)=>h.name.localeCompare(i.name)),{anyCriticalDown:u,body:{appName:r,appVersion:a,checks:o,status:j(u,d),timestamp:new Date().toISOString()}}},G=t=>{const{appName:e="lunora",appVersion:s="0.0.0",auth:r="public",cacheTtlMs:a,isAdmin:o,resolveProbes:u}=t,d=n=>a!==void 0?a:n==="readiness"?0:r==="public"?5e3:0,y={},h=n=>{if(r==="admin"&&!o(n))throw new T("health endpoint requires a valid admin bearer",{code:"ADMIN_FORBIDDEN",status:403})},i=async(n,c,l)=>{const p=A(n,["GET","HEAD"]);if(p)return p;h(n);const f=d(l);if(f>0){const m=y[l];if(m!==void 0&&Date.now()<m.expiresAt)return Response.json(m.body,{headers:{"cache-control":"no-store"},status:m.down?503:200})}const{criticalNames:b,registry:v}=S(u(c)),{healthy:E,report:k}=await v.getReport(l==="readiness"?"readiness":void 0),{anyCriticalDown:D,body:g}=M(k,b,r,e,s),w=l==="readiness"?!E:D;return f>0&&(y[l]={body:g,down:w,expiresAt:Date.now()+f}),Response.json(g,{headers:{"cache-control":"no-store"},status:w?503:200})};return{[C]:(n,c)=>i(n,c,"aggregate"),[H]:(n,c)=>i(n,c,"readiness")}},I=(t,e,s)=>({check:async()=>{try{return await R(e,s).fetch(new Request("https://shard.internal/_lunora/status",{method:"GET"})),{healthy:!0}}catch{return{healthy:!1,message:"durable object unreachable"}}},critical:!0,name:t}),q=(t,e)=>({check:async()=>{try{return await e.prepare("SELECT 1").first(),{healthy:!0}}catch{return{healthy:!1,message:"d1 query failed"}}},critical:!0,name:t}),B=(t,e)=>({check:()=>e?{healthy:!0}:{healthy:!1,message:"binding not configured"},critical:!1,name:t});export{C as HEALTH_PATH,H as HEALTH_READY_PATH,G as buildHealthRoutes,q as d1Probe,I as durableObjectProbe,B as presenceProbe};
@@ -0,0 +1 @@
1
+ import{createR2Sql as R}from"@lunora/bindings/r2sql";import{LOG_ARCHIVE_NOT_CONFIGURED as _}from"./LOG_ARCHIVE_NOT_CONFIGURED-CDpi4yFD.mjs";import{L as d,c as h}from"./pipeline-log-reader-BGrl66P5.mjs";import{LunoraError as a}from"./LunoraError-DksAgIpa.mjs";import{a as A}from"./method-guard-BG_vJNTl.mjs";const m="/_lunora/admin/logs/archive",v="LUNORA_LOG_ARCHIVE_TABLE",C="LUNORA_LOG_ARCHIVE_NAMESPACE",V=o=>{if(typeof o!="object"||o===null)return;const e=o,t=e[v];if(typeof t!="string"||t==="")return;const r=e[C];return{table:t,...typeof r=="string"&&r!==""?{namespace:r}:{}}},O=new Set(d),T=o=>typeof o=="string"&&o!==""?o:void 0,S=(o,e)=>{if(o!==void 0){if(typeof o!="string"||!O.has(o))throw new a(`logs archive: invalid \`${e}\` — expected one of ${d.join(", ")}`,{code:"BAD_REQUEST",status:400});return o}},u=(o,e)=>{if(o!==void 0){if(typeof o!="number"||!Number.isFinite(o))throw new a(`logs archive: invalid \`${e}\` — expected a finite number`,{code:"BAD_REQUEST",status:400});return o}},b=o=>{const e={},t=s=>{const n=T(o[s]);n!==void 0&&(e[s]=n)},r=s=>{const n=S(o[s],s);n!==void 0&&(e[s]=n)},i=s=>{const n=u(o[s],s);n!==void 0&&(e[s]=n)};t("functionPath"),t("functionPathPrefix"),t("traceId"),t("shardKey"),t("userId"),r("level"),r("minLevel"),i("sinceTs"),i("untilTs"),i("limit");const c=o.cursor;if(typeof c=="object"&&c!==null){const s=u(c.ts,"cursor.ts");s!==void 0&&(e.cursor={ts:s})}return e},N=o=>{const e=o.R2_SQL_ACCOUNT_ID??o.CLOUDFLARE_ACCOUNT_ID,t=o.R2_SQL_TOKEN,r=o.R2_SQL_BUCKET,i=[];if((e===void 0||e==="")&&i.push("R2_SQL_ACCOUNT_ID"),(t===void 0||t==="")&&i.push("R2_SQL_TOKEN"),(r===void 0||r==="")&&i.push("R2_SQL_BUCKET"),i.length>0)throw new a(`log archive not configured (missing ${i.join(", ")}). The Pipeline must write to an R2 Data Catalog (Iceberg) table, and R2_SQL_ACCOUNT_ID / R2_SQL_TOKEN / R2_SQL_BUCKET must be set — see the observability docs.`,{code:_,status:400});return{accountId:e,apiToken:t,bucket:r}},G=o=>{const{createReader:e=h,readJsonBody:t,requireAdminOption:r}=o,i=async(c,s)=>{A(c,"POST","Log-archive");const n=r(c,o.logArchive,{code:_,message:"log archive requires a `logArchive` config (an R2 Data Catalog table) on the worker — see the observability docs"}),{accountId:L,apiToken:p,bucket:l}=N(s??{}),E=b(await t(c)),g=R({accountId:L,apiToken:p,bucket:l}),f=await e(g,{columnMap:n.columnMap,namespace:n.namespace,table:n.table}).query(E);return Response.json(f,{headers:{"content-type":"application/json"},status:200})};return{[m]:i}};export{_ as LOG_ARCHIVE_NOT_CONFIGURED,m as LOG_ARCHIVE_PATH,G as buildLogArchiveAdminRoutes,V as resolveLogArchiveFromEnv};
@@ -1 +1 @@
1
- import{LunoraError as t,toErrorBody as n}from"@lunora/errors";const a=e=>{const{body:o,redacted:r,status:s}=n(e,{fallbackCode:"INTERNAL",redactedMessage:"Internal error"});return r&&console.error("[lunora] internal error:",e),Response.json({error:o},{headers:{"content-type":"application/json"},status:s})};class u extends t{constructor(o,r){super(r?.code??"INTERNAL",o,{cause:r?.cause,status:r?.status})}toResponse(){return a(this)}}export{u as LunoraError,a as toErrorResponse};
1
+ import{LunoraError as t,toErrorBody as a}from"@lunora/errors";const n=e=>{const{body:o,redacted:r,status:s}=a(e,{fallbackCode:"INTERNAL",redactedMessage:"Internal error"});return r&&console.error("[lunora] internal error:",e),Response.json({error:o},{headers:{"content-type":"application/json"},status:s})};class u extends t{constructor(o,r){super(r?.code??"INTERNAL",o,{cause:r?.cause,status:r?.status})}toResponse(){return n(this)}}export{u as LunoraError,n as toErrorResponse};
@@ -0,0 +1 @@
1
+ import{LunoraError as p}from"./LunoraError-DksAgIpa.mjs";import{a as _}from"./method-guard-BG_vJNTl.mjs";const N="/_lunora/admin/storage",f="/_lunora/admin/storage/object",j="/_lunora/admin/storage/url",P="/_lunora/admin/storage/buckets",C=10080*60,B=32*1048576,I=new Set(["GET","PUT"]),M=E=>{const h=new Uint8Array(E);let S="";for(const o of h)S+=o.toString(16).padStart(2,"0");return S},x=E=>{const{assertAdmin:h,parsePaging:S,queryParameter:o,readBodyBytes:w,requireAdminOption:i,storage:c}=E,T=e=>{const s=o(e,"key");if(s===void 0)throw new p("Storage endpoint requires a `key` query parameter",{code:"BAD_REQUEST",status:400});return s},y=async e=>{const s=i(e,c.storageList,{code:"STORAGE_NOT_CONFIGURED",message:"storage endpoint requires a `storageList` function on the worker"}),t=new URL(e.url),a=await s(o(t,"prefix"),{bucket:o(t,"bucket"),cursor:o(t,"cursor"),...S(e)});return Response.json(a,{headers:{"content-type":"application/json"},status:200})},R=e=>(_(e,"GET","Storage-buckets"),h(e),Response.json({buckets:c.storageBuckets??[]},{headers:{"content-type":"application/json"},status:200})),U=async e=>{const s=i(e,c.storageDelete,{code:"STORAGE_DELETE_NOT_CONFIGURED",message:"storage delete requires a `storageDelete` function on the worker"}),t=new URL(e.url),a=T(t);return await s(a,{bucket:o(t,"bucket")}),Response.json({deleted:!0,key:a},{headers:{"content-type":"application/json"},status:200})},m=async e=>{const s=i(e,c.storageUpload,{code:"STORAGE_UPLOAD_NOT_CONFIGURED",message:"storage upload requires a `storageUpload` function on the worker"}),t=new URL(e.url),a=T(t),n=await w(e,B),d=e.headers.get("content-type"),u=d===null||d===""?void 0:d,l=o(t,"expectedSha256"),g=o(t,"expectedSize");let r;if(l!==void 0||g!==void 0){const D=await crypto.subtle.digest("SHA-256",n);r=M(D);const G=g!==void 0&&n.byteLength!==Number(g),L=l!==void 0&&r!==l.toLowerCase();if(G||L)throw new p("Upload failed verification — the body did not match the declared size or SHA-256 checksum, so nothing was written",{code:"STORAGE_CHECKSUM_MISMATCH",status:400})}const O=await s(a,n,{bucket:o(t,"bucket"),contentType:u,sha256:r});return Response.json(r===void 0?O:{...O,sha256:r},{headers:{"content-type":"application/json"},status:200})},A=async e=>{switch(e.method){case"DELETE":return U(e);case"GET":return y(e);case"POST":case"PUT":return m(e);default:throw new p("Storage endpoint requires GET, PUT, POST, or DELETE",{code:"METHOD_NOT_ALLOWED",status:405})}},b=async e=>{_(e,"GET","Storage-object");const s=i(e,c.storageDownload,{code:"STORAGE_DOWNLOAD_NOT_CONFIGURED",message:"storage download requires a `storageDownload` function on the worker"}),t=new URL(e.url),a=T(t),n=await s(a,{bucket:o(t,"bucket")});if(!n?.body)throw new p(`No object at key ${a}`,{code:"STORAGE_OBJECT_NOT_FOUND",status:404});return new Response(n.body,{headers:{"content-type":n.httpMetadata?.contentType??"application/octet-stream",...n.size===void 0?{}:{"content-length":String(n.size)}},status:200})},k=async e=>{_(e,"GET","Storage URL");const s=i(e,c.storageSignedUrl,{code:"STORAGE_URL_NOT_CONFIGURED",message:"storage URL endpoint requires a `storageSignedUrl` function on the worker"}),t=new URL(e.url),a=T(t),n=Number(o(t,"expiresIn")??""),d=Number.isFinite(n)&&n>0?Math.min(n,C):void 0,u=o(t,"method");if(u!==void 0&&!I.has(u))throw new p("Storage URL `method` must be GET or PUT",{code:"BAD_REQUEST",status:400});const l=u,g=o(t,"contentType"),r=await s(a,{bucket:o(t,"bucket"),contentType:g,expiresInSeconds:d,method:l});return Response.json({key:a,url:r},{headers:{"content-type":"application/json"},status:200})};return{[P]:R,[f]:b,[N]:A,[j]:k}};export{P as STORAGE_BUCKETS_PATH,N as STORAGE_PATH,B as STORAGE_UPLOAD_MAX_BODY_BYTES,j as STORAGE_URL_PATH,x as buildStorageAdminRoutes,M as toHex};
@@ -0,0 +1 @@
1
+ import{e as d,L as y,o as j,c as S,O as $,f as C,g as X,h as B,w as Y,i as q,j as G,m as Z}from"./otlp-resource-B4Yylr0V.mjs";const Q=r=>{if(typeof r=="string")return r;try{return JSON.stringify(r)??String(r)}catch{return String(r)}},J=r=>typeof r=="boolean"||typeof r=="number"||typeof r=="string"?r:Q(r),v=512,rr=200,tr=r=>{const s=r.maxItems??v,t=r.maxDelayMs??rr;let o=[],e,i,l;const f=()=>{e!==void 0&&(clearTimeout(e),e=void 0)},h=async()=>{f();const u=o;o=[];const a=l;i=void 0,l=void 0;try{u.length>0&&await r.export(u)}catch{}finally{a?.()}},m=u=>{i===void 0&&(i=new Promise(a=>{l=a}),e=setTimeout(()=>{h()},t)),u?.(i)};return{add:(u,a)=>{for(o.push(u);o.length>s;)o.shift();m(a),o.length>=s&&h()},flush:async u=>{if(o.length===0){f();return}const a=h();return u?.(a),a},get size(){return o.length}}},or=(r,s)=>r<s?-1:r>s?1:0,L=r=>{if(r===void 0)return"null";if(typeof r=="bigint")throw new TypeError("stableStringify: cannot use a bigint in a stable JSON cache key — pass it as a string, or use stableWireKey");if(r===null||typeof r!="object")return JSON.stringify(r);if(Array.isArray(r))return`[${r.map(i=>L(i)).join(",")}]`;const s=Object.getPrototypeOf(r);if(s!==null&&s!==Object.prototype){const i=r.constructor?.name??"value";throw new TypeError(`stableStringify: cannot use a ${i} in a stable JSON cache key — only plain objects, arrays, and JSON primitives are supported (wire-typed values key via stableWireKey)`)}const t=r,o=Object.keys(t).toSorted(or),e=[];for(const i of o){const l=t[i];l!==void 0&&e.push(`${JSON.stringify(i)}:${L(l)}`)}return`{${e.join(",")}}`},sr=(r,s)=>{const t=[d(y.functionPath,r.functionPath),d(y.ok,r.ok)];r.method!==void 0&&t.push(d("http.request.method",r.method)),r.path!==void 0&&t.push(d("url.path",r.path)),t.push(d("http.route",r.functionPath)),r.scheme!==void 0&&t.push(d("url.scheme",r.scheme)),r.host!==void 0&&t.push(d("server.address",r.host)),r.port!==void 0&&t.push(d("server.port",r.port)),r.userAgent!==void 0&&t.push(d("user_agent.original",r.userAgent)),r.shardKey!==void 0&&t.push(d(y.shardKey,r.shardKey)),t.push(d("http.response.status_code",r.error?.status??200)),r.error&&t.push(d(y.errorType,r.error.code),d("lunora.error_status",r.error.status)),r.fanOut&&t.push(d("lunora.fanout.table",r.fanOut.table),d("lunora.fanout.shards",r.fanOut.shards),d("lunora.fanout.failed",r.fanOut.failed));const o={attributes:t,endTimeUnixNano:S(s),kind:$.server,name:r.functionPath,...r.parentSpanId===void 0?{}:{parentSpanId:r.parentSpanId},spanId:r.spanId??j(8),startTimeUnixNano:S(s-r.durationMs),status:r.ok?{code:1}:{code:2,message:r.error?.message??""},traceId:r.traceId??j(16)};return r.traceFlags!==void 0&&(o.flags=r.traceFlags),r.error&&(o.events=[{attributes:[d("exception.type",r.error.code),d("exception.message",r.error.message)],name:"exception",timeUnixNano:S(s)}]),o},R=(r,s)=>{const t=new Map([[y.functionPath,d(y.functionPath,r.functionPath)]]);r.shardKey!==void 0&&t.set(y.shardKey,d(y.shardKey,r.shardKey)),r.userId!==void 0&&t.set(y.userId,d(y.userId,r.userId)),r.errorType!==void 0&&t.set(y.errorType,d(y.errorType,r.errorType));for(const[o,e]of Object.entries(s??{}))t.set(o,d(o,J(e)));return[...t.values()]},er=r=>{const s={attributes:R({errorType:r.error?.type,functionPath:r.functionPath,shardKey:r.shardKey,userId:r.userId},r.attributes),endTimeUnixNano:S(r.startTs+r.durationMs),kind:$[r.kind??"internal"],name:r.name,parentSpanId:r.parentSpanId,spanId:r.spanId,startTimeUnixNano:S(r.startTs),status:r.ok?{code:1}:{code:2,message:r.error?.message??""},traceId:r.traceId},t=o=>X(Object.fromEntries(Object.entries(o??{}).map(([e,i])=>[e,J(i)])));return r.events!==void 0&&r.events.length>0&&(s.events=r.events.map(o=>({attributes:t(o.attributes),name:o.name,timeUnixNano:S(o.ts)}))),r.links!==void 0&&r.links.length>0&&(s.links=r.links.map(o=>({attributes:t(o.attributes),spanId:o.spanId,traceId:o.traceId}))),s},nr=r=>{const s=S(r.ts),t=R({functionPath:r.functionPath,shardKey:r.shardKey},r.attributes),o={asDouble:r.value,attributes:t,timeUnixNano:s};return r.kind==="gauge"?{gauge:{dataPoints:[o]},name:r.name}:r.kind==="histogram"?{histogram:{aggregationTemporality:1,dataPoints:[{attributes:t,bucketCounts:["1"],count:"1",explicitBounds:[],max:r.value,min:r.value,sum:r.value,timeUnixNano:s}]},name:r.name}:{name:r.name,sum:{aggregationTemporality:1,dataPoints:[o],isMonotonic:!0}}},ir=r=>{const s={attributes:R({functionPath:r.functionPath,shardKey:r.shardKey,userId:r.userId},r.fields),body:{stringValue:r.message},severityNumber:C[r.level],severityText:r.level.toUpperCase(),timeUnixNano:S(r.ts)};return r.traceId!==void 0&&(s.traceId=r.traceId),r.spanId!==void 0&&(s.spanId=r.spanId),r.eventName!==void 0&&(s.eventName=r.eventName,s.attributes.push(d("event.name",r.eventName))),s},ar=1024,cr=async r=>{const s=new Blob([r]).stream().pipeThrough(new CompressionStream("gzip"));return new Response(s).arrayBuffer()},z=async(r,s,t,o)=>{try{const e=JSON.stringify(s),{byteLength:i}=new TextEncoder().encode(e),l=(i<ar?fetch(r,{body:e,headers:t,method:"POST"}):cr(e).then(f=>fetch(r,{body:f,headers:{...t,"content-encoding":"gzip"},method:"POST"}))).then(()=>{},()=>{});o?.(l),await l}catch{}},dr=(r,s,t,o)=>{z(r,s,t,o?.waitUntil).catch(()=>{})},O=(r,s)=>s===!0&&r.ok,ur=r=>r.kind==="metric"?void 0:r.event.traceId,pr=r=>{const s=Map.groupBy(r,o=>ur(o)),t=s.get(void 0)??[];return s.delete(void 0),{byTrace:s,untraced:t}},D=5,lr=(r,s,t)=>{if(s===void 0)return r;const{byTrace:o,untraced:e}=pr(r),i=[...e];let l=0,f;for(const[h,m]of o){let u;try{u=s({logs:m.filter(a=>a.kind==="log").map(a=>a.event),rpc:m.filter(a=>a.kind==="rpc").map(a=>a.event),spans:m.filter(a=>a.kind==="span").map(a=>a.event),traceId:h})}catch(a){l+=1,l===1&&(f=a),u=!0}u&&i.push(...m)}return l>0&&t(f,l),i},P=(r,s)=>{if(s===void 0)return r;try{return s(r)??void 0}catch{return}},F=(r,s)=>{if(r.kind==="rpc"){const o=P(r.event,s?.rpc);return o===void 0?void 0:{bucket:"spans",encoded:sr(o,r.endMs)}}if(r.kind==="span"){const o=P(r.event,s?.span);return o===void 0?void 0:{bucket:"spans",encoded:er(o)}}if(r.kind==="log"){const o=P(r.event,s?.log);return o===void 0?void 0:{bucket:"logs",encoded:ir(o)}}const t=P(r.event,s?.metric);return t===void 0?void 0:{bucket:"metrics",encoded:nr(t)}},mr=(r={})=>{const{onlyErrors:s}=r;return{onLog:t=>{t.level==="error"||t.level==="fatal"?console.error("[lunora:log]",t.functionPath,t.message):console.log("[lunora:log]",t.functionPath,t.message)},onMetric:t=>{console.log("[lunora:metric]",`${t.name}=${String(t.value)}`,t.kind,t.functionPath)},onRpc:t=>{O(t,s)||(t.ok?console.log("[lunora:rpc]",t):console.error("[lunora:rpc]",t))},onSpan:t=>{const o=t.ok?"ok":`error ${t.error?.type??""}`.trim();console.log("[lunora:span]",t.name,`${String(t.durationMs)}ms`,o,t.functionPath)}}},hr=r=>{const{headers:s,onlyErrors:t,transform:o,transformLog:e,url:i}=r,l=B({"content-type":"application/json"},s),f=(h,m)=>{try{const u=fetch(i,{body:JSON.stringify(h),headers:l,method:"POST"}).catch(()=>{});m?.waitUntil&&m.waitUntil(u)}catch{}};return{onLog:(h,m)=>{const u=P(h,e);u!==void 0&&f(u,m)},onRpc:(h,m)=>{if(O(h,t))return;const u=P(h,o);u!==void 0&&f(u,m)}}},yr=r=>{const{capture:s,captureLog:t}=r,o=r.onlyErrors??!0;return{onLog:t?e=>{try{t(e)}catch{}}:void 0,onRpc:e=>{if(!O(e,o))try{s(e)}catch{}}}},gr=r=>{const{dataset:s,onlyErrors:t}=r;return{onRpc:o=>{if(!O(o,t))try{s.writeDataPoint({blobs:[o.functionPath,o.ok?"ok":"error",o.shardKey??"",o.error?.code??"",o.fanOut?.table??""],doubles:[o.durationMs,o.ok?0:1,o.fanOut?.shards??0,o.fanOut?.failed??0],indexes:[o.functionPath]})}catch{}}}},br=r=>{const{pipeline:s,serializeFields:t}=r;return{onLog:(o,e)=>{try{const i={functionPath:o.functionPath,level:o.level,message:o.message,ts:o.ts};o.fields&&(i.fields=t===!0?JSON.stringify(o.fields):o.fields);for(const f of["shardKey","userId","traceId","spanId"])o[f]!==void 0&&(i[f]=o[f]);const l=s.send([i]).catch(()=>{});e?.waitUntil&&e.waitUntil(l)}catch{}}}},kr=r=>{const{batch:s,deploymentEnvironment:t,detectResources:o,endpoint:e,headers:i,onlyErrors:l,postProcessor:f,resourceAttributes:h,serviceNamespace:m,serviceVersion:u,tailSampler:a,token:H}=r,U=r.serviceName??"lunora",E={...u===void 0?{}:{"service.version":u},...m===void 0?{}:{"service.namespace":m},...t===void 0?{}:{"deployment.environment":t},...h},x=new WeakMap,k=c=>{if(o!==!0||c?.resourceAttributes===void 0)return E;const n=x.get(c);if(n!==void 0)return n;const p=Z(c.resourceAttributes(),E);return x.set(c,p),p};let I=e;for(;I.endsWith("/");)I=I.slice(0,-1);const K={logs:{url:`${I}/v1/logs`,wrap:G},metrics:{url:`${I}/v1/metrics`,wrap:q},spans:{url:`${I}/v1/traces`,wrap:Y}},_=B({"content-type":"application/json"},i,H);let A=0;const V=(c,n)=>{if(A>=D)return;A+=1;const p=A===D?" Further tailSampler failures from this sink are silenced until the isolate restarts.":"";console.error(`[lunora:otlp] tailSampler threw for ${String(n)} trace(s) in this flush window; keeping them (fail-open), so the sampling policy did NOT apply.${p}`,c)},W=async c=>{const n=lr(c,a,V),p=new Map;for(const g of n){const b=F(g,f);if(b===void 0)continue;const M=L(g.resource);let T=p.get(M);T===void 0&&(T={logs:[],metrics:[],resource:g.resource,spans:[]},p.set(M,T)),T[b.bucket].push(b.encoded)}const w=[];for(const[,g]of p)for(const b of["spans","logs","metrics"])if(g[b].length>0){const{url:M,wrap:T}=K[b];w.push(z(M,T(g[b],"@lunora/runtime",U,g.resource),_))}await Promise.all(w)};if(s===!1){const c=(n,p)=>{const w=F(n,f);if(w!==void 0){const{url:g,wrap:b}=K[w.bucket];dr(g,b(w.encoded,"@lunora/runtime",U,n.resource),_,p)}};return{onLog:(n,p)=>{c({event:n,kind:"log",resource:k(p)},p)},onMetric:(n,p)=>{c({event:n,kind:"metric",resource:k(p)},p)},onRpc:(n,p)=>{O(n,l)||c({endMs:Date.now(),event:n,kind:"rpc",resource:k(p)},p)},onSpan:(n,p)=>{c({event:n,kind:"span",resource:k(p)},p)}}}const N=tr({export:W,...s?.maxDelayMs===void 0?{}:{maxDelayMs:s.maxDelayMs},...s?.maxItems===void 0?{}:{maxItems:s.maxItems}});return{flush:c=>{N.flush(c?.waitUntil).catch(()=>{})},onLog:(c,n)=>{N.add({event:c,kind:"log",resource:k(n)},n?.waitUntil)},onMetric:(c,n)=>{N.add({event:c,kind:"metric",resource:k(n)},n?.waitUntil)},onRpc:(c,n)=>{O(c,l)||N.add({endMs:Date.now(),event:c,kind:"rpc",resource:k(n)},n?.waitUntil)},onSpan:(c,n)=>{N.add({event:c,kind:"span",resource:k(n)},n?.waitUntil)}}},Sr=(...r)=>{const s=(t,o)=>{for(const e of r){const i=e[t];if(i)try{i.apply(e,o)}catch{}}};return{flush:t=>{s("flush",[t])},onLog:(t,o)=>{s("onLog",[t,o])},onMetric:(t,o)=>{s("onMetric",[t,o])},onRpc:(t,o)=>{s("onRpc",[t,o])},onSpan:(t,o)=>{s("onSpan",[t,o])}}};export{gr as analyticsEngineSink,Sr as combineSinks,mr as consoleSink,kr as otlpSink,br as pipelineLogSink,yr as sentrySink,hr as webhookSink};
@@ -0,0 +1 @@
1
+ import{resolveShard as u}from"@lunora/platform";const s=new WeakMap,n=o=>o===void 0?void 0:{locationHint:o},f=o=>typeof o.idFromName=="function",a=o=>{if(!f(o))return o;const e=o,i=s.get(o);if(i!==void 0)return i;const c=typeof e.jurisdiction=="function"?r=>a(e.jurisdiction(r)):void 0,d=typeof e.getByName=="function"?{get:(r,t)=>e.get(r,n(t)),getByName:(r,t)=>e.getByName(r,n(t)),idForName:r=>e.idFromName(r),jurisdiction:c}:{get:(r,t)=>e.get(r,n(t)),idForName:r=>e.idFromName(r),jurisdiction:c};return s.set(o,d),d},y=(o,e)=>{if(e===void 0)return o;if(typeof o.jurisdiction!="function")throw new TypeError(`@lunora/runtime: Durable Object namespace does not support jurisdiction("${e}") — update @cloudflare/workers-types or remove the jurisdiction option`);return o.jurisdiction(e)},p=(o,e,i)=>u(a(o),e,i);export{y as applyJurisdiction,p as resolveShard};
@@ -0,0 +1 @@
1
+ import{a as r,r as s,b as t}from"./rest-cache-BnMq2hbO.mjs";export{r as applyRestCache,s as requestCarriesCredentials,t as restCacheHeaders};
@@ -0,0 +1 @@
1
+ import"./rest-cache-BnMq2hbO.mjs";import{a as t,b as o,c as i,r as m,d as R}from"./rest-routes-D2b3HXA9.mjs";import"./method-guard-BG_vJNTl.mjs";export{t as argsFromQuery,o as buildRestRoutes,i as createRestRateLimit,m as readShardKey,R as restSurfaceFromRegistry};
@@ -0,0 +1 @@
1
+ const a=e=>{let n="";for(let t=0;t<e.length;t+=32768)n+=String.fromCharCode(...e.subarray(t,t+32768));return btoa(n)},o=e=>{const n=atob(e),r=new Uint8Array(n.length);for(let t=0;t<n.length;t+=1)r[t]=n.codePointAt(t)??0;return r},l=e=>a(e).replaceAll("+","-").replaceAll("/","_").replace(/=+$/,"");export{l as a,o as f,a as t};
@@ -0,0 +1 @@
1
+ import{LunoraError as a}from"./LunoraError-DksAgIpa.mjs";const u=(t,o={})=>{const r=o.onError??"fail-closed";return async(n,c,e)=>{for(const s of t){let i;try{i=await s(n,c,e)}catch(l){if(r==="skip")continue;throw l}if(i)return i}return null}},f=t=>{const o=Object.keys(t).filter(r=>r!=="*").toSorted((r,n)=>n.length-r.length);return(r,n,c)=>{const{pathname:e}=new URL(r.url),s=o.find(l=>e===l||e.startsWith(l.endsWith("/")?l:`${l}/`)),i=s===void 0?t["*"]:t[s];return i===void 0?null:i(r,n,c)}},h=(t,o)=>o===void 0||t===void 0?t:async(r,n,c)=>{const e=await t(r,n,c);if(!e)return e;const s=o.validate(e);if(s.ok)return e;if(o.onInvalid==="reject")throw new a(`identity claims failed the declared contract: ${s.error}`,{code:"UNAUTHENTICATED",status:401});return null};export{u as composeIdentityResolvers,f as routeIdentityResolvers,h as wrapResolverWithContract};