@palbase/backend 39.1.7 → 40.0.1

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 (44) hide show
  1. package/dist/bin/palbase-backend.cjs.map +1 -1
  2. package/dist/bin/palbase-backend.js +2 -2
  3. package/dist/{chunk-C525N4OW.js → chunk-AS2HDWVQ.js} +3 -2
  4. package/dist/{chunk-C525N4OW.js.map → chunk-AS2HDWVQ.js.map} +1 -1
  5. package/dist/{chunk-H7EKL6HC.js → chunk-RA7KFELX.js} +88 -2
  6. package/dist/chunk-RA7KFELX.js.map +1 -0
  7. package/dist/db/index.d.cts +1 -1
  8. package/dist/db/index.d.ts +1 -1
  9. package/dist/engine/index.cjs +2 -0
  10. package/dist/engine/index.cjs.map +1 -1
  11. package/dist/engine/index.d.cts +3 -3
  12. package/dist/engine/index.d.ts +3 -3
  13. package/dist/engine/index.js +4 -2
  14. package/dist/{index-fLaf0PN2.d.ts → index-B8zC9oV0.d.ts} +3 -3
  15. package/dist/{index-Db5QHdTa.d.cts → index-BAjRbjnq.d.cts} +3 -3
  16. package/dist/{index-QWN1Ncrv.d.ts → index-Ck2K1TgC.d.ts} +3 -3
  17. package/dist/{index-CCY1h_J2.d.cts → index-t7Ie44mM.d.cts} +3 -3
  18. package/dist/index.cjs +84 -59
  19. package/dist/index.cjs.map +1 -1
  20. package/dist/index.d.cts +20 -18
  21. package/dist/index.d.ts +20 -18
  22. package/dist/index.js +2 -61
  23. package/dist/index.js.map +1 -1
  24. package/dist/openapi/index.d.cts +2 -2
  25. package/dist/openapi/index.d.ts +2 -2
  26. package/dist/{registry-CH6HRR6T.d.cts → registry-C88au7ti.d.cts} +1 -1
  27. package/dist/{registry-C7tCRyPm.d.ts → registry-wwVUGunv.d.ts} +1 -1
  28. package/dist/stack.cjs.map +1 -1
  29. package/dist/stack.d.cts +21 -6
  30. package/dist/stack.d.ts +21 -6
  31. package/dist/test/index.cjs +19 -1
  32. package/dist/test/index.cjs.map +1 -1
  33. package/dist/test/index.d.cts +21 -2
  34. package/dist/test/index.d.ts +21 -2
  35. package/dist/test/index.js +18 -1
  36. package/dist/test/index.js.map +1 -1
  37. package/docs/README.md +6 -6
  38. package/docs/llms-full.txt +6 -6
  39. package/package.json +3 -6
  40. package/template/AGENTS.md +14 -14
  41. package/template/modules/notes/notes.e2e.test.ts +53 -0
  42. package/template/package.json +2 -2
  43. package/dist/chunk-H7EKL6HC.js.map +0 -1
  44. package/template/scripts/test.sh +0 -33
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/clients/http.ts","../src/clients/auth.ts","../src/clients/documents.ts","../src/clients/flags.ts","../src/clients/notifications.ts","../src/clients/realtime.ts","../src/clients/storage.ts","../src/clients/index.ts","../src/channels.ts","../src/db/repository.ts","../src/stack-gen.ts","../src/decorators/methods.ts","../src/decorators/surface-name.ts","../src/decorators/webhook.ts","../src/decorators/hook.ts","../src/decorators/upload.ts","../src/decorators/sse.ts","../src/decorators/room.ts","../src/decorators/params.ts","../src/middleware.ts","../src/job.ts","../src/decorators/job.ts","../src/index.ts"],"sourcesContent":["/**\n * http.ts — the transport every module client speaks over.\n *\n * WHY IT IS HERE. This code, and the five clients built on it, spent their life\n * in `v2/runtime/internal/runtime/module-clients.js`: 1,768 lines of untyped\n * CommonJS that entered the SDK through an `@ts-expect-error` and left through\n * `unknown` casts. The interfaces those clients implement were always in this\n * package — only the implementations were outside it, where nothing checked one\n * against the other. Two defects came through that gap on 2026-08-15 (a type\n * that described a different server's columns; an accessor that was `undefined`\n * in a deployed handler), and both were green on each side alone.\n *\n * WHAT IT IS NOT. Nothing Bun-specific lives here. The transport is a `fetch`\n * the caller may supply, so this package stays runtime-agnostic and the process\n * that knows which runtime it is decides what to hand in.\n */\n\nimport type { PalbaseResult } from \"../endpoint.js\";\n\n/** Per-request options a module client may pass. */\nexport interface RequestOptions {\n /** JSON-serialised unless it is a string, a Uint8Array, a Blob or FormData. */\n body?: unknown;\n headers?: Record<string, string>;\n signal?: AbortSignal;\n}\n\n/**\n * What a module client is given. An INTERFACE rather than a class, because the\n * clients depend on this shape and not on the thing that implements it — which\n * is what lets a test drive a whole client without a server.\n */\nexport interface ModuleTransport {\n /** The platform's base URL, for the rare client that must build a URL. */\n readonly baseUrl: string;\n request<T = unknown>(\n method: string,\n path: string,\n options?: RequestOptions,\n ): Promise<PalbaseResult<T>>;\n}\n\nexport interface TransportConfig {\n baseUrl: string;\n apiKey: string;\n /**\n * The `fetch` to use. Omitted means the ambient one — resolved at CALL time,\n * never captured here: the egress fence replaces `globalThis.fetch` after the\n * clients are built, and a captured reference would keep calling the\n * un-fenced original.\n */\n fetchImpl?: typeof fetch;\n}\n\n/**\n * A module call that failed.\n *\n * `code` is the platform's own error code (`forbidden`, `not_found`, …) so a\n * caller can branch on it without matching message text.\n */\nexport class PalbaseModuleError extends Error {\n readonly code: string;\n readonly status: number;\n readonly details: Record<string, unknown>;\n\n constructor(code: string, message: string, status: number, details: Record<string, unknown> = {}) {\n super(message);\n this.name = \"PalbaseModuleError\";\n this.code = code;\n this.status = status;\n this.details = details;\n }\n}\n\nexport function makeHttpClient(cfg: TransportConfig): ModuleTransport {\n async function request<T>(\n method: string,\n path: string,\n options: RequestOptions = {},\n ): Promise<PalbaseResult<T>> {\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n ...(options.headers ?? {}),\n };\n if (cfg.apiKey) headers[\"apikey\"] = cfg.apiKey;\n\n const init: RequestInit = { method, headers };\n if (options.body !== undefined) {\n if (typeof options.body === \"string\" || options.body instanceof Uint8Array) {\n init.body = options.body as RequestInit[\"body\"];\n } else if (typeof FormData !== \"undefined\" && options.body instanceof FormData) {\n // The platform writes Content-Type itself, WITH the multipart boundary.\n // Setting it here omits the boundary, and the server then parses zero\n // parts from a request that looks perfectly well formed.\n delete headers[\"Content-Type\"];\n init.body = options.body;\n } else if (typeof Blob !== \"undefined\" && options.body instanceof Blob) {\n delete headers[\"Content-Type\"];\n init.body = options.body;\n } else {\n init.body = JSON.stringify(options.body);\n }\n }\n if (options.signal) init.signal = options.signal;\n\n // Resolved HERE, per call. See TransportConfig.fetchImpl.\n const doFetch = cfg.fetchImpl ?? globalThis.fetch;\n\n let response: Response;\n try {\n response = await doFetch(`${cfg.baseUrl}${path}`, init);\n } catch (err) {\n // AN ENVELOPE, not an exception.\n //\n // This threw until 2026-08-15, and the throw made three separate claims\n // false at once:\n //\n // 1. The package's own rule — \"Response: { data, error }, no thrown API\n // errors\". Every client here is written to that contract.\n // 2. `Flags.get(key, default)`, whose documented behaviour is that the\n // default applies when the flag is absent AND when the service is\n // unreachable. It reads `resp.error !== null` to decide, and a throw\n // never reaches that branch: measured, `get(\"beta\", \"DEFAULT\")`\n // raised `connect ECONNREFUSED` instead of answering \"DEFAULT\". The\n // test that was supposed to cover it handed the client a hand-made\n // error envelope — a shape this code could not produce.\n // 3. Consistency with the Realtime client, which already envelopes a\n // network failure so a handler that wrote a row does not lose it\n // because pubsub was down.\n //\n // A caller destructuring { data, error } and checking `error` was being\n // defeated by an exception: the defensive code existed and did not help,\n // which is the worst kind of surprise to leave in a package.\n return {\n data: null,\n error: new PalbaseModuleError(\n \"network_error\",\n err instanceof Error ? err.message : \"Network request failed\",\n 0,\n ),\n status: 0,\n };\n }\n\n const contentType = response.headers.get(\"Content-Type\") ?? \"\";\n let parsed: unknown = null;\n if (method !== \"HEAD\" && contentType.includes(\"json\")) {\n parsed = await response.json().catch(() => null);\n } else if (method !== \"HEAD\" && contentType.startsWith(\"image/\")) {\n // QR codes and the like: hand back bytes the caller can write or forward.\n parsed = new Uint8Array(await response.arrayBuffer());\n } else if (method !== \"HEAD\" && response.body) {\n // A non-JSON error still says something; \"request failed\" says nothing.\n parsed = await response.text().catch(() => null);\n }\n\n if (!response.ok) {\n const body = (parsed && typeof parsed === \"object\" ? parsed : {}) as Record<string, unknown>;\n const code = typeof body.error === \"string\" && body.error ? body.error : \"unknown_error\";\n const message =\n (typeof body.error_description === \"string\" && body.error_description) ||\n response.statusText ||\n \"request failed\";\n return {\n data: null,\n error: new PalbaseModuleError(code, message, response.status, body),\n status: response.status,\n };\n }\n\n return { data: parsed as T, error: null, status: response.status };\n }\n\n return { baseUrl: cfg.baseUrl, request };\n}\n","/**\n * auth.ts — the role-assignment half of auth, as a backend handler reaches it.\n *\n * WHAT THIS IS NOT. It is not the client SDK's `auth` (sign-up, sign-in, MFA,\n * device attestation): those are a person acting on their OWN account, they run\n * in the app, and a server has no business holding them. This is the operator\n * verb — \"make this user an agent\" — and it exists because the product itself is\n * often where the promotion happens: a supervisor taps a button in the tenant's\n * own app, and the tenant's handler has to be able to write the assignment.\n *\n * THE CREDENTIAL IS THE POINT. `/admin/users/{uid}/roles/{role}` answers 403 to\n * anon and to `authenticated` alike (FR-013), so these calls ride the transport\n * built with the SERVICE-ROLE key. A backend is the only place that key exists;\n * putting this surface anywhere a client SDK could reach it would let an end\n * user grant themselves the permission the rest of the feature is about.\n *\n * IT THROWS, and the rest of this package envelopes. That is a deliberate split\n * and it comes from the SHAPE OF THE ANSWER: `assignRole` returns nothing, so a\n * failure it did not throw for would be indistinguishable from a write that\n * happened. The named `RoleNotDefined` is the one refusal a caller can act on —\n * the role names live in git, so a miss is a typo, not a runtime condition —\n * and every other refusal arrives as the transport's own `PalbaseModuleError`\n * with the platform's code on it.\n */\n\nimport type { PalbaseAuthAdminClient } from \"../clients.js\";\n\nimport { PalbaseModuleError, type ModuleTransport } from \"./http.js\";\n\n/**\n * The named refusal: this stack declares no role by that name.\n *\n * A role's DEFINITION is committed (`palbase roles`, lowered into the generated\n * client as an enum), so a name that misses is a typo in code rather than a\n * state a retry could fix. It carries the name it was asked for, because the\n * message alone would make a handler parse text to log which one failed.\n */\nexport class RoleNotDefined extends Error {\n readonly role: string;\n\n constructor(role: string, message?: string) {\n super(message ?? `No role named \"${role}\" is defined for this stack`);\n this.name = \"RoleNotDefined\";\n this.role = role;\n }\n}\n\n/** The wire body all three routes answer with: the assignment's RESULT. */\ninterface UserRolesBody {\n roles?: string[];\n}\n\n/**\n * Raise whatever the platform refused with.\n *\n * `role_not_defined` becomes the named class; everything else keeps the\n * transport's error, which already carries the platform's code and status, so a\n * caller can branch on `err.code` without matching message text.\n */\nfunction refuse(error: { message?: string; code?: string }, role: string): never {\n if (error.code === \"role_not_defined\") throw new RoleNotDefined(role, error.message);\n if (error instanceof PalbaseModuleError) throw error;\n throw new PalbaseModuleError(error.code ?? \"unknown_error\", error.message ?? \"request failed\", 0);\n}\n\n/** `/admin/users/{uid}/roles[/{role}]`, with both ids escaped: an id that\n * carried a slash would otherwise reach a different route entirely. */\nfunction rolesPath(userId: string, role?: string): string {\n const base = `/admin/users/${encodeURIComponent(userId)}/roles`;\n return role === undefined ? base : `${base}/${encodeURIComponent(role)}`;\n}\n\nexport function buildAuthClient(http: ModuleTransport): PalbaseAuthAdminClient {\n return {\n async assignRole(userId: string, role: string): Promise<void> {\n const { error } = await http.request<UserRolesBody>(\"PUT\", rolesPath(userId, role));\n if (error) refuse(error, role);\n },\n\n async revokeRole(userId: string, role: string): Promise<void> {\n const { error } = await http.request<UserRolesBody>(\"DELETE\", rolesPath(userId, role));\n if (error) refuse(error, role);\n },\n\n async rolesOf(userId: string): Promise<string[]> {\n const { data, error } = await http.request<UserRolesBody>(\"GET\", rolesPath(userId));\n // A FAILED READ IS NOT AN EMPTY LIST. Answering `[]` here would tell a\n // handler that a user holds nothing when the truth is that nobody could\n // say — and the handler would then deny them everything they hold.\n if (error) refuse(error, \"\");\n return data?.roles ?? [];\n },\n };\n}\n","/**\n * documents.ts — the Documents client, Firestore-shaped.\n *\n * Moved in from `v2/runtime/internal/runtime/module-clients.js:705-773` (plus\n * the `buildDocumentRef` / `buildCollectionRef` helpers above it) with its\n * behaviour intact: the same methods, the same paths, the same bodies. What\n * changed is that it now sits beside the interface it implements, so a drift\n * between the two is a compile error rather than a runtime surprise.\n */\n\nimport type {\n PalbaseCollectionRef,\n PalbaseDocsClient,\n PalbaseDocumentRef,\n PalbaseDocumentSnapshot,\n PalbaseQuerySnapshot,\n PalbaseResult,\n PalbaseWhereOperator,\n} from \"../endpoint.js\";\nimport { PalbaseModuleError, type ModuleTransport } from \"./http.js\";\n\n/**\n * A path segment the platform will accept.\n *\n * Validated HERE rather than at the server, because a rejected segment is a\n * programming mistake and the useful moment to hear about it is the call.\n */\nconst SEGMENT_RE = /^[A-Za-z0-9_-]+$/;\n\nfunction validateSegment(segment: string, label: string): void {\n if (!SEGMENT_RE.test(segment)) {\n throw new Error(`Invalid ${label}: \"${segment}\". Must match ${SEGMENT_RE.source}`);\n }\n}\n\ninterface WhereClause {\n field: string;\n op: PalbaseWhereOperator;\n value: unknown;\n}\ninterface OrderClause {\n field: string;\n direction: \"asc\" | \"desc\";\n}\ninterface ChainState {\n where: WhereClause[];\n orderBy: OrderClause[];\n limit?: number;\n}\n\ninterface RawDocument {\n id?: string;\n exists?: boolean;\n data?: Record<string, unknown>;\n}\n\nfunction buildDocumentRef<T extends Record<string, unknown>>(\n http: ModuleTransport,\n path: string,\n): PalbaseDocumentRef<T> {\n return {\n path,\n async set(data: T) {\n return http.request<void>(\"PUT\", `/v1/docs/${path}`, { body: data });\n },\n async get(): Promise<PalbaseResult<PalbaseDocumentSnapshot<T>>> {\n const response = await http.request<RawDocument>(\"GET\", `/v1/docs/${path}`);\n if (response.error) return { data: null, error: response.error, status: response.status };\n const raw = response.data ?? {};\n const exists = raw.exists !== undefined ? raw.exists : Boolean(raw.data || raw.id);\n const segments = path.split(\"/\");\n const id = raw.id || segments[segments.length - 1] || \"\";\n return {\n data: { id, exists, data: () => raw.data as T | undefined, ref: { path } },\n error: null,\n status: response.status,\n };\n },\n async update(data: Partial<T>) {\n return http.request<void>(\"PATCH\", `/v1/docs/${path}`, { body: data });\n },\n async delete() {\n return http.request<void>(\"DELETE\", `/v1/docs/${path}`);\n },\n collection<C extends Record<string, unknown>>(name: string): PalbaseCollectionRef<C> {\n validateSegment(name, \"subcollection name\");\n return buildCollectionRef<C>(http, `${path}/${name}`);\n },\n };\n}\n\nfunction buildCollectionRef<T extends Record<string, unknown>>(\n http: ModuleTransport,\n path: string,\n state: ChainState = { where: [], orderBy: [] },\n): PalbaseCollectionRef<T> {\n function snapshot(doc: { id: string; data: Record<string, unknown> }): PalbaseDocumentSnapshot<T> {\n return {\n id: doc.id,\n exists: true,\n data: () => doc.data as T,\n ref: { path: `${path}/${doc.id}` },\n };\n }\n\n function querySnapshot(docs: PalbaseDocumentSnapshot<T>[]): PalbaseQuerySnapshot<T> {\n return {\n docs,\n empty: docs.length === 0,\n size: docs.length,\n docChanges: () => docs.map((doc) => ({ type: \"added\" as const, doc })),\n };\n }\n\n return {\n path,\n\n doc(id: string) {\n validateSegment(id, \"document ID\");\n return buildDocumentRef<T>(http, `${path}/${id}`);\n },\n\n async add(data: T) {\n const resp = await http.request<{ id: string }>(\"POST\", `/v1/docs/${path}`, { body: data });\n if (resp.error || !resp.data) {\n return { data: null, error: resp.error, status: resp.status };\n }\n return {\n data: buildDocumentRef<T>(http, `${path}/${resp.data.id}`),\n error: null,\n status: resp.status,\n };\n },\n\n // Each narrowing returns a NEW ref. A builder that mutated in place would\n // leak one caller's filter into a query another caller had already held.\n where(field: string, op: PalbaseWhereOperator, value: unknown) {\n return buildCollectionRef<T>(http, path, {\n ...state,\n where: [...state.where, { field, op, value }],\n });\n },\n orderBy(field: string, direction: \"asc\" | \"desc\" = \"asc\") {\n return buildCollectionRef<T>(http, path, {\n ...state,\n orderBy: [...state.orderBy, { field, direction }],\n });\n },\n limit(n: number) {\n return buildCollectionRef<T>(http, path, { ...state, limit: n });\n },\n\n async get(): Promise<PalbaseResult<PalbaseQuerySnapshot<T>>> {\n const narrowed =\n state.where.length > 0 || state.orderBy.length > 0 || state.limit !== undefined;\n\n const resp = narrowed\n ? await http.request<{ documents?: { id: string; data: Record<string, unknown> }[] }>(\n \"POST\",\n `/v1/docs/${path}/query`,\n { body: queryBody(state) },\n )\n : await http.request<{ documents?: { id: string; data: Record<string, unknown> }[] }>(\n \"GET\",\n `/v1/docs/${path}`,\n );\n\n if (resp.error) return { data: null, error: resp.error, status: resp.status };\n const docs = (resp.data?.documents ?? []).map(snapshot);\n return { data: querySnapshot(docs), error: null, status: resp.status };\n },\n };\n}\n\nfunction queryBody(state: ChainState): Record<string, unknown> {\n const body: Record<string, unknown> = {};\n if (state.where.length > 0) {\n body.where = state.where.map((w) => ({ field: w.field, op: w.op, value: w.value }));\n }\n if (state.orderBy.length > 0) {\n body.orderBy = state.orderBy.map((o) => ({ field: o.field, direction: o.direction }));\n }\n if (state.limit !== undefined) body.limit = state.limit;\n return body;\n}\n\n/** The largest batch the platform accepts in one call. */\nconst MAX_BATCH = 500;\n\nexport function buildDocumentsClient(http: ModuleTransport): PalbaseDocsClient {\n return {\n /**\n * `Documents.doc(\"users/alice\")` — segments are collection/documentId PAIRS,\n * so an odd count addresses a COLLECTION and is refused. Accepting it would\n * write a document whose id happens to be a collection's name.\n */\n doc<T extends Record<string, unknown>>(path: string): PalbaseDocumentRef<T> {\n const segments = String(path)\n .split(\"/\")\n .filter((s) => s.length > 0);\n if (segments.length === 0 || segments.length % 2 !== 0) {\n throw new Error(\n `Invalid document path: \"${path}\". Expected collection/documentId pairs, got ${segments.length} segment(s).`,\n );\n }\n segments.forEach((s, i) => validateSegment(s, i % 2 === 0 ? \"collection name\" : \"document ID\"));\n return buildDocumentRef<T>(http, segments.join(\"/\"));\n },\n\n collection<T extends Record<string, unknown>>(name: string): PalbaseCollectionRef<T> {\n validateSegment(name, \"collection name\");\n return buildCollectionRef<T>(http, name);\n },\n\n async batch(operations) {\n // Refused HERE, without a request: the server would refuse it too, and\n // spending a round trip to be told so is the caller's time.\n if (operations.length > MAX_BATCH) {\n return {\n data: null,\n error: new PalbaseModuleError(\n \"batch_too_large\",\n `Batch size ${operations.length} exceeds maximum of ${MAX_BATCH}`,\n 400,\n ),\n status: 400,\n };\n }\n if (operations.length === 0) return { data: null, error: null, status: 200 };\n\n return http.request<void>(\"POST\", \"/v1/docs/batch\", {\n body: operations.map((op) => ({ op: op.op, path: op.ref.path, data: op.data })),\n });\n },\n };\n}\n","/**\n * flags.ts — feature flags, resolved for the request's own user.\n *\n * Moved in from `v2/runtime/internal/runtime/module-clients.js:941-1164`.\n *\n * THE ONE RULE WORTH STATING: the user a flag resolves for comes from the\n * SDK's own request scope, never from anything the caller passed on the wire.\n * A handler can pass an explicit context (including an explicit `null` for a\n * deliberate anonymous read) and that wins — but the default is the person the\n * request is being served for, which is what makes `Flags.get(\"x\")` mean the\n * obvious thing inside a handler.\n *\n * Writes mirror the Database model: `setOverride` writes for the CURRENT user\n * and needs no admin power; cross-user writes live behind `asService()` so they\n * are explicit and greppable.\n */\n\nimport type {\n PalbaseBatchOverrideOperation,\n PalbaseFlagContext,\n PalbaseFlagValue,\n PalbaseFlagsClient,\n PalbaseFlagsServiceClient,\n} from \"../clients.js\";\nimport type { PalbaseResult } from \"../endpoint.js\";\nimport type { ModuleTransport } from \"./http.js\";\n\nconst FLAG_NAME_RE = /^[A-Za-z0-9_.-]+$/;\n\nexport interface FlagsConfig {\n /** The request's user, read from the SDK's ALS box — never from the caller. */\n getCurrentUserId: () => string | null;\n}\n\nfunction assertFlagName(flagName: string): void {\n if (!FLAG_NAME_RE.test(flagName)) {\n throw new Error(`Invalid flag name: \"${flagName}\". Flag names must match ${FLAG_NAME_RE.source}`);\n }\n}\n\n/** A truthy flag value, in the platform's own terms. */\nfunction flagEnabled(value: unknown): boolean {\n if (typeof value === \"boolean\") return value;\n return value != null && value !== 0 && value !== \"\";\n}\n\nfunction flagVariant(value: unknown): { name: string } | null {\n return typeof value === \"string\" ? { name: value } : null;\n}\n\n/**\n * A context object carries `userId`/`properties`; anything else passed in that\n * position is a DEFAULT VALUE. This is what tells `Flags.get(key, ctx)` apart\n * from `Flags.get(key, someObjectDefault)`.\n */\nfunction isContextObject(v: unknown): v is PalbaseFlagContext {\n return (\n v !== null && typeof v === \"object\" && !Array.isArray(v) && (\"userId\" in v || \"properties\" in v)\n );\n}\n\ninterface MergedSnapshot {\n values?: Record<string, PalbaseFlagValue>;\n}\n\nexport function buildFlagsClient(http: ModuleTransport, cfg: FlagsConfig): PalbaseFlagsClient {\n /**\n * The effective user for a call. An explicit `userId` in the context wins —\n * INCLUDING an explicit `null`, which is a deliberate anonymous read.\n */\n function resolveUserId(context?: PalbaseFlagContext): string | null | undefined {\n if (context && \"userId\" in context) return context.userId ?? null;\n return cfg.getCurrentUserId() || undefined;\n }\n\n function mergedPath(context?: PalbaseFlagContext): string {\n const uid = resolveUserId(context);\n return uid ? `/v1/user-flags/users/${encodeURIComponent(uid)}` : \"/v1/user-flags\";\n }\n\n function fetchMerged(context?: PalbaseFlagContext) {\n return http.request<MergedSnapshot>(\"GET\", mergedPath(context));\n }\n\n const service: PalbaseFlagsServiceClient = {\n async setOverrideForUser(userId, key, value) {\n return http.request(\n \"PUT\",\n `/v1/user-flags/users/${encodeURIComponent(userId)}/${encodeURIComponent(key)}`,\n { body: { value } },\n );\n },\n async setOverridesForUser(userId, values) {\n return http.request(\"PUT\", `/v1/user-flags/users/${encodeURIComponent(userId)}`, {\n body: { values },\n });\n },\n async clearOverrideForUser(userId, key) {\n return http.request(\n \"DELETE\",\n `/v1/user-flags/users/${encodeURIComponent(userId)}/${encodeURIComponent(key)}`,\n );\n },\n async clearAllOverridesForUser(userId) {\n return http.request(\"DELETE\", `/v1/user-flags/users/${encodeURIComponent(userId)}`);\n },\n async batchSetOverrides(operations: ReadonlyArray<PalbaseBatchOverrideOperation>) {\n // The argument is camelCase, the wire is snake_case. Mapped here so a\n // stray `userId` never reaches the server — and an explicit `user_id`, if\n // a caller already wrote one, is preserved.\n const ops = (operations ?? []).map((op) => {\n const raw = op as unknown as { userId?: string; user_id?: string; values: unknown };\n return { user_id: raw.userId ?? raw.user_id, values: raw.values };\n });\n return http.request(\"POST\", \"/v1/user-flags/batch\", { body: { operations: ops } });\n },\n };\n\n return {\n async isEnabled(flagName: string, context?: PalbaseFlagContext) {\n assertFlagName(flagName);\n const res = await fetchMerged(context);\n if (res.error || res.data == null) return { data: null, error: res.error, status: res.status };\n return { data: flagEnabled(res.data.values?.[flagName]), error: null, status: res.status };\n },\n\n async getVariant(flagName: string, context?: PalbaseFlagContext) {\n assertFlagName(flagName);\n const res = await fetchMerged(context);\n // A missing or non-string value is a NULL variant on a successful read;\n // errors and empty bodies pass through as null too, which is why this is\n // written out rather than mapped.\n if (res.error || res.data == null) return { data: null, error: res.error, status: res.status };\n return { data: flagVariant(res.data.values?.[flagName]), error: null, status: res.status };\n },\n\n /**\n * `get(key)` · `get(key, default)` · `get(key, default, ctx)` · `get(key, ctx)`.\n *\n * The default is substituted when the flag is ABSENT or when the flags\n * service is unreachable — a product that hides a feature because a lookup\n * timed out is behaving correctly; one that crashes is not.\n */\n async get(\n flagName: string,\n defaultOrContext?: PalbaseFlagValue | PalbaseFlagContext,\n maybeContext?: PalbaseFlagContext,\n ): Promise<PalbaseResult<PalbaseFlagValue>> {\n assertFlagName(flagName);\n\n let defaultValue: PalbaseFlagValue | undefined;\n let context: PalbaseFlagContext | undefined;\n let hasDefault = false;\n if (maybeContext !== undefined) {\n defaultValue = defaultOrContext as PalbaseFlagValue;\n hasDefault = true;\n context = maybeContext;\n } else if (isContextObject(defaultOrContext)) {\n context = defaultOrContext;\n } else if (defaultOrContext !== undefined) {\n defaultValue = defaultOrContext as PalbaseFlagValue;\n hasDefault = true;\n }\n\n const resp = await fetchMerged(context);\n if (resp.error !== null) {\n if (hasDefault) return { data: defaultValue ?? null, error: null, status: resp.status };\n return { data: null, error: resp.error, status: resp.status };\n }\n const values = resp.data?.values ?? {};\n const value = values[flagName];\n // An absent key on a SUCCESSFUL read is not an error.\n if (value === undefined) {\n return { data: hasDefault ? (defaultValue ?? null) : null, error: null, status: resp.status };\n }\n return { data: value, error: null, status: resp.status };\n },\n\n async getAll(context?: PalbaseFlagContext) {\n const res = await fetchMerged(context);\n if (res.error || res.data == null) return { data: null, error: res.error, status: res.status };\n const values = res.data.values ?? {};\n return {\n data: Object.keys(values).map((name) => {\n const value = values[name];\n const flag: { name: string; enabled: boolean; variant?: { name: string } } = {\n name,\n enabled: flagEnabled(value),\n };\n if (typeof value === \"string\") flag.variant = { name: value };\n return flag;\n }),\n error: null,\n status: res.status,\n };\n },\n\n /**\n * Override a flag for the CURRENT request user.\n *\n * On an anonymous request this does not silently no-op and does not write\n * for nobody: it refuses and names the call that does cross-user writes.\n */\n async setOverride(key: string, value: PalbaseFlagValue) {\n const uid = cfg.getCurrentUserId();\n if (!uid) {\n return {\n data: null,\n error: {\n message:\n \"setOverride requires a signed-in user; use Flags.$asService().setOverrideForUser(userId, key, value) for cross-user writes\",\n },\n status: 400,\n };\n }\n return http.request(\n \"PUT\",\n `/v1/user-flags/users/${encodeURIComponent(uid)}/${encodeURIComponent(key)}`,\n { body: { value } },\n );\n },\n\n asService() {\n return service;\n },\n };\n}\n","/**\n * notifications.ts — push, email, SMS, verifications, inbox, preferences and\n * the two template surfaces.\n *\n * Moved in from `v2/runtime/internal/runtime/module-clients.js:1180-1379`.\n *\n * The theme of this file is a NAME GAP: the SDK speaks camelCase and palnotify\n * speaks snake_case, and every place they meet is a place a field can be\n * dropped in silence. One of them cost a live afternoon — `email.send({ html })`\n * was forwarded verbatim, palnotify reads `html_body`, and the answer was a 400\n * about a field the caller had supplied. The mappings below are that lesson,\n * and they are now checked against the declared parameter types instead of\n * being hand-carried across a package boundary.\n */\n\nimport type {\n PalbaseEmailClient,\n PalbaseEmailTemplate,\n PalbaseEmailTemplatesClient,\n PalbaseInboxClient,\n PalbaseNotificationsClient,\n PalbasePreferencesClient,\n PalbasePushClient,\n PalbaseSMSTemplate,\n PalbaseSMSTemplatesClient,\n PalbaseSmsClient,\n PalbaseWhatsAppClient,\n PalbaseVerificationsClient,\n} from \"../clients.js\";\nimport type { PalbaseResult } from \"../endpoint.js\";\nimport type { ModuleTransport } from \"./http.js\";\n\n/** Re-map the data of a SUCCESSFUL envelope; errors pass through untouched. */\nfunction mapEnvelope<In, Out>(res: PalbaseResult<In>, map: (data: In) => Out): PalbaseResult<Out> {\n if (res.error !== null || res.data === null || res.data === undefined) {\n return { data: null, error: res.error, status: res.status };\n }\n return { data: map(res.data), error: null, status: res.status };\n}\n\ntype Wire = Record<string, unknown>;\n\nfunction toEmailTemplate(wire: Wire): PalbaseEmailTemplate {\n const view: PalbaseEmailTemplate = {\n id: wire.id as string,\n slug: wire.slug as string,\n locale: wire.locale as string,\n subject: wire.subject as string,\n htmlBody: wire.html_body as string,\n variables: (wire.variables as string[]) ?? [],\n isDefault: wire.is_default as boolean,\n createdAt: wire.created_at as string,\n updatedAt: wire.updated_at as string,\n };\n if (wire.text_body !== undefined) view.textBody = wire.text_body as string;\n return view;\n}\n\nfunction toSmsTemplate(wire: Wire): PalbaseSMSTemplate {\n return {\n id: wire.id as string,\n slug: wire.slug as string,\n locale: wire.locale as string,\n body: wire.body as string,\n variables: (wire.variables as string[]) ?? [],\n isDefault: wire.is_default as boolean,\n createdAt: wire.created_at as string,\n updatedAt: wire.updated_at as string,\n };\n}\n\nexport function buildNotificationsClient(http: ModuleTransport): PalbaseNotificationsClient {\n const push: PalbasePushClient = {\n async send(params) {\n return http.request(\"POST\", \"/v1/notifications/push\", { body: params });\n },\n };\n\n const email: PalbaseEmailClient = {\n async send(params) {\n // `html`/`text` are what the SDK declares; palnotify reads\n // `html_body`/`text_body`. Forwarding them verbatim answered 400 about a\n // field the caller HAD supplied — live on todoapp, 2026-07-30.\n const { templateSlug, html, text, ...rest } = params;\n const body: Record<string, unknown> = { ...rest };\n if (templateSlug !== undefined) body.template_slug = templateSlug;\n if (html !== undefined) body.html_body = html;\n if (text !== undefined) body.text_body = text;\n return http.request(\"POST\", \"/v1/notifications/email\", { body });\n },\n };\n\n const sms: PalbaseSmsClient = {\n async send(params) {\n const { templateSlug, ...rest } = params;\n const body = templateSlug !== undefined ? { ...rest, template_slug: templateSlug } : rest;\n return http.request(\"POST\", \"/v1/notifications/sms\", { body });\n },\n };\n\n const whatsapp: PalbaseWhatsAppClient = {\n async send(params) {\n const { templateSlug, userId, ...rest } = params;\n const body = {\n ...rest,\n ...(templateSlug === undefined ? {} : { template_slug: templateSlug }),\n ...(userId === undefined ? {} : { user_id: userId }),\n };\n return http.request(\"POST\", \"/v1/notifications/whatsapp\", { body });\n },\n async events(options = {}) {\n const query = options.limit === undefined ? \"\" : `?limit=${encodeURIComponent(String(options.limit))}`;\n return http.request(\"GET\", `/v1/notifications/whatsapp/events${query}`);\n },\n };\n\n // Phone verification (OTP). Separate from sms.send on purpose: there is no\n // body here — the provider generates the code and the message text itself.\n const verifications: PalbaseVerificationsClient = {\n async start(params) {\n return http.request(\"POST\", \"/v1/notifications/verifications\", { body: params });\n },\n async check(params) {\n return http.request(\"POST\", \"/v1/notifications/verifications/check\", { body: params });\n },\n };\n\n const inbox: PalbaseInboxClient = {\n async send(params) {\n return http.request(\"POST\", \"/v1/notifications/inbox\", { body: params });\n },\n async list(options?: {\n cursor?: string;\n limit?: number;\n is_read?: boolean;\n category?: string;\n include_archived?: boolean;\n }) {\n const opts = options ?? {};\n const params = new URLSearchParams();\n if (opts.cursor) params.set(\"cursor\", opts.cursor);\n if (opts.limit !== undefined) params.set(\"limit\", String(opts.limit));\n if (opts.is_read !== undefined) params.set(\"is_read\", opts.is_read ? \"true\" : \"false\");\n if (opts.category) params.set(\"category\", opts.category);\n if (opts.include_archived) params.set(\"include_archived\", \"true\");\n const query = params.toString();\n return http.request(\"GET\", `/v1/notifications/inbox${query ? `?${query}` : \"\"}`);\n },\n async unreadCount() {\n return http.request(\"GET\", \"/v1/notifications/inbox/unread-count\");\n },\n async markRead(id: string) {\n return http.request(\"PATCH\", `/v1/notifications/inbox/${encodeURIComponent(id)}/read`);\n },\n async markAllRead() {\n return http.request(\"POST\", \"/v1/notifications/inbox/read-all\");\n },\n async archive(id: string) {\n return http.request(\"DELETE\", `/v1/notifications/inbox/${encodeURIComponent(id)}`);\n },\n };\n\n const preferences: PalbasePreferencesClient = {\n async get() {\n return http.request(\"GET\", \"/v1/notifications/preferences\");\n },\n async update(params) {\n return http.request(\"PUT\", \"/v1/notifications/preferences\", { body: params });\n },\n };\n\n const emailTemplates: PalbaseEmailTemplatesClient = {\n async list() {\n const resp = await http.request<Wire[]>(\"GET\", \"/v1/notifications/templates\");\n return mapEnvelope(resp, (rows) => (rows ?? []).map(toEmailTemplate));\n },\n async get(id: string) {\n const resp = await http.request<Wire>(\n \"GET\",\n `/v1/notifications/templates/${encodeURIComponent(id)}`,\n );\n return mapEnvelope(resp, toEmailTemplate);\n },\n async create(input: { slug: string; subject: string; htmlBody: string; textBody?: string; variables?: string[] }) {\n const body: Record<string, unknown> = {\n slug: input.slug,\n subject: input.subject,\n html_body: input.htmlBody,\n };\n if (input.textBody !== undefined) body.text_body = input.textBody;\n if (input.variables !== undefined) body.variables = input.variables;\n const resp = await http.request<Wire>(\"POST\", \"/v1/notifications/templates\", { body });\n return mapEnvelope(resp, toEmailTemplate);\n },\n async update(\n id: string,\n input: { subject?: string; htmlBody?: string; textBody?: string; variables?: string[] },\n ) {\n const body: Record<string, unknown> = {};\n if (input.subject !== undefined) body.subject = input.subject;\n if (input.htmlBody !== undefined) body.html_body = input.htmlBody;\n if (input.textBody !== undefined) body.text_body = input.textBody;\n if (input.variables !== undefined) body.variables = input.variables;\n const resp = await http.request<Wire>(\n \"PUT\",\n `/v1/notifications/templates/${encodeURIComponent(id)}`,\n { body },\n );\n return mapEnvelope(resp, toEmailTemplate);\n },\n async delete(id: string) {\n return http.request(\"DELETE\", `/v1/notifications/templates/${encodeURIComponent(id)}`);\n },\n };\n\n const smsTemplates: PalbaseSMSTemplatesClient = {\n async list() {\n const resp = await http.request<Wire[]>(\"GET\", \"/v1/notifications/sms-templates\");\n return mapEnvelope(resp, (rows) => (rows ?? []).map(toSmsTemplate));\n },\n async get(id: string) {\n const resp = await http.request<Wire>(\n \"GET\",\n `/v1/notifications/sms-templates/${encodeURIComponent(id)}`,\n );\n return mapEnvelope(resp, toSmsTemplate);\n },\n async create(input: { slug: string; body: string; variables?: string[] }) {\n const body: Record<string, unknown> = { slug: input.slug, body: input.body };\n if (input.variables !== undefined) body.variables = input.variables;\n const resp = await http.request<Wire>(\"POST\", \"/v1/notifications/sms-templates\", { body });\n return mapEnvelope(resp, toSmsTemplate);\n },\n async update(id: string, input: { body?: string; variables?: string[] }) {\n const body: Record<string, unknown> = {};\n if (input.body !== undefined) body.body = input.body;\n if (input.variables !== undefined) body.variables = input.variables;\n const resp = await http.request<Wire>(\n \"PUT\",\n `/v1/notifications/sms-templates/${encodeURIComponent(id)}`,\n { body },\n );\n return mapEnvelope(resp, toSmsTemplate);\n },\n async delete(id: string) {\n return http.request(\"DELETE\", `/v1/notifications/sms-templates/${encodeURIComponent(id)}`);\n },\n };\n\n return {\n push,\n email,\n sms,\n whatsapp,\n verifications,\n inbox,\n preferences,\n templates: { email: emailTemplates, sms: smsTemplates },\n async registerDevice(params) {\n return http.request(\"POST\", \"/v1/notifications/devices\", { body: params });\n },\n async unregisterDevice(deviceId: string) {\n return http.request(\"DELETE\", `/v1/notifications/devices/${encodeURIComponent(deviceId)}`);\n },\n };\n}\n","/**\n * realtime.ts — broadcast, and only broadcast.\n *\n * Moved in from `v2/runtime/internal/runtime/module-clients.js:811-883`.\n *\n * There is no `subscribe()` here, deliberately: a backend handler answers one\n * request and ends, so there is no honest place to hold a long-lived socket.\n * Subscription lives in the client SDKs; this side pushes.\n *\n * The V1 host/executor branch is GONE. It existed so an isolate could delegate\n * the secret-bearing token mint to a host that held the credential — and the\n * isolate was removed on 2026-08-14. A single-tenant process has nobody to hide\n * its own tenant's key from.\n */\n\nimport { createHmac } from \"node:crypto\";\n\nimport type { PalbaseRealtimeClient } from \"../clients.js\";\nimport { PalbaseModuleError } from \"./http.js\";\n\nexport interface RealtimeConfig {\n baseUrl: string;\n /**\n * The shared Realtime API secret. Empty means realtime is not provisioned for\n * this environment, and broadcast says so by name rather than failing oddly.\n */\n apiJwtSecret: string;\n /** Resolved at CALL time — see the note in http.ts. */\n fetchImpl?: typeof fetch;\n}\n\n/**\n * A short-lived HS256 token Realtime's broadcast pipeline accepts.\n *\n * It needs a valid signature and a future `exp`, nothing more — this is a\n * service-to-service hop inside the stack, not a user session.\n */\nfunction mintToken(secret: string): string {\n const now = Math.floor(Date.now() / 1000);\n const header = Buffer.from(JSON.stringify({ alg: \"HS256\", typ: \"JWT\" })).toString(\"base64url\");\n const payload = Buffer.from(\n JSON.stringify({ iss: \"backend-runtime\", role: \"service_role\", iat: now, exp: now + 60 }),\n ).toString(\"base64url\");\n const sig = createHmac(\"sha256\", secret).update(`${header}.${payload}`).digest(\"base64url\");\n return `${header}.${payload}.${sig}`;\n}\n\nexport function buildRealtimeClient(cfg: RealtimeConfig): PalbaseRealtimeClient {\n const url = `${cfg.baseUrl}/realtime/api/broadcast`;\n const stateUrl = `${cfg.baseUrl}/realtime/api/state`;\n\n /** One state write or clear. Same credential, same fire-and-forget contract\n * as broadcast: a handler that wrote a row must not lose it because the\n * pubsub layer was unreachable. */\n async function writeState(\n topic: string,\n key: string,\n value: Record<string, unknown> | undefined,\n del: boolean,\n ) {\n if (typeof topic !== \"string\" || topic.length === 0) {\n return {\n data: null,\n error: new PalbaseModuleError(\"invalid_argument\", \"topic must be a non-empty string\", 400),\n };\n }\n if (typeof key !== \"string\" || key.length === 0) {\n return {\n data: null,\n error: new PalbaseModuleError(\"invalid_argument\", \"key must be a non-empty string\", 400),\n };\n }\n if (!cfg.apiJwtSecret) {\n return {\n data: null,\n error: new PalbaseModuleError(\n \"realtime_unconfigured\",\n \"Realtime.state is unavailable: realtime is not provisioned for this Environment \" +\n \"(PALBASE_REALTIME_API_JWT_SECRET unset).\",\n 503,\n ),\n };\n }\n\n let token: string;\n try {\n token = mintToken(cfg.apiJwtSecret);\n } catch (err) {\n return {\n data: null,\n error: new PalbaseModuleError(\n \"realtime_token_error\",\n err instanceof Error ? err.message : \"token mint failed\",\n 500,\n ),\n };\n }\n\n const op = del ? { topic, key, del: true } : { topic, key, value: value ?? {} };\n const doFetch = cfg.fetchImpl ?? globalThis.fetch;\n let response: Response;\n try {\n response = await doFetch(stateUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", Authorization: `Bearer ${token}` },\n body: JSON.stringify({ ops: [op] }),\n });\n } catch (err) {\n return {\n data: null,\n error: new PalbaseModuleError(\n \"network_error\",\n err instanceof Error ? err.message : \"state request failed\",\n 0,\n ),\n };\n }\n if (response.status === 202 || response.status === 200) {\n return { data: undefined, error: null };\n }\n const detail = await response.text().catch(() => \"\");\n return {\n data: null,\n error: new PalbaseModuleError(\n \"realtime_state_failed\",\n `realtime state write returned ${response.status}${detail ? `: ${detail}` : \"\"}`,\n response.status,\n ),\n };\n }\n\n return {\n state: {\n /** Write one DURABLE entry on a channel's shared state.\n *\n * The difference from broadcast is WHO it reaches: a broadcast reaches\n * whoever is listening at that instant, while state is also handed to\n * whoever joins afterwards. \"This value is now X\" wants the second — a\n * client connecting a second later should not have to wait for the next\n * change to learn X. */\n set: (topic: string, key: string, value: Record<string, unknown>) =>\n writeState(topic, key, value, false),\n /** Remove one entry. */\n clear: (topic: string, key: string) => writeState(topic, key, undefined, true),\n },\n\n async broadcast(channel: string, event: string, payload?: Record<string, unknown>) {\n // Cheap argument checks first, locally: a bad call gets an answer without\n // spending a round trip to be told the obvious.\n if (typeof channel !== \"string\" || channel.length === 0) {\n return {\n data: null,\n error: new PalbaseModuleError(\"invalid_argument\", \"channel must be a non-empty string\", 400),\n };\n }\n if (typeof event !== \"string\" || event.length === 0) {\n return {\n data: null,\n error: new PalbaseModuleError(\"invalid_argument\", \"event must be a non-empty string\", 400),\n };\n }\n if (!cfg.apiJwtSecret) {\n return {\n data: null,\n error: new PalbaseModuleError(\n \"realtime_unconfigured\",\n \"Realtime.broadcast is unavailable: realtime is not provisioned for this Environment \" +\n \"(PALBASE_REALTIME_API_JWT_SECRET unset).\",\n 503,\n ),\n };\n }\n\n let token: string;\n try {\n token = mintToken(cfg.apiJwtSecret);\n } catch (err) {\n return {\n data: null,\n error: new PalbaseModuleError(\n \"realtime_token_error\",\n err instanceof Error ? err.message : \"token mint failed\",\n 500,\n ),\n };\n }\n\n // The BARE sub-topic. Realtime prepends \"realtime:\" on delivery, and a\n // pre-prefixed topic double-prefixes and is silently dropped — proven live.\n const body = JSON.stringify({\n messages: [{ topic: channel, event, payload: payload ?? {}, private: false }],\n });\n\n const doFetch = cfg.fetchImpl ?? globalThis.fetch;\n let response: Response;\n try {\n response = await doFetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", Authorization: `Bearer ${token}` },\n body,\n });\n } catch (err) {\n // FIRE AND FORGET: a handler that wrote a row and then broadcast must\n // not lose the row because the pubsub layer was unreachable. This is the\n // one client that answers with an envelope on a network failure rather\n // than throwing, and it is why.\n return {\n data: null,\n error: new PalbaseModuleError(\n \"network_error\",\n err instanceof Error ? err.message : \"broadcast request failed\",\n 0,\n ),\n };\n }\n\n if (response.status === 202 || response.status === 200) {\n return { data: undefined, error: null };\n }\n\n const detail = await response.text().catch(() => \"\");\n return {\n data: null,\n error: new PalbaseModuleError(\n \"realtime_broadcast_failed\",\n `broadcast returned ${response.status}: ${detail.slice(0, 200)}`,\n response.status,\n ),\n };\n },\n };\n}\n","/**\n * storage.ts — the Storage client.\n *\n * Moved in from `v2/runtime/internal/runtime/module-clients.js:474-589`. That\n * code addressed the native Supabase Storage wire under `/storage/v1` until\n * 2026-08-15, when it was repointed at this stack's own module — measured\n * against the live stack, where the old path answers 404 and the new one 200.\n * It arrives here so the SHAPE it returns and the type that declares that shape\n * are checked against each other: they were not, and the type spent a major\n * version describing another server's columns.\n */\n\nimport type {\n PalbaseBucketClient,\n PalbaseFileObject,\n PalbaseListOptions,\n PalbaseSignedUrlResponse,\n PalbaseStorageClient,\n PalbaseUploadOptions,\n} from \"../clients.js\";\nimport type { PalbaseResult } from \"../endpoint.js\";\nimport type { ModuleTransport } from \"./http.js\";\n\n/** What the platform accepts as a bucket name (schema: `^[a-z][a-z0-9-]{1,62}$`). */\nconst BUCKET_NAME_RE = /^[a-zA-Z0-9_-]+$/;\n/** What the platform accepts as an object path. */\nconst STORAGE_PATH_RE = /^[a-zA-Z0-9_./-]+$/;\nconst STORAGE_TRAVERSAL_RE = /(?:^|\\/)\\.\\.(?:\\/|$)/;\n\n/**\n * Refused HERE, before any request.\n *\n * A traversing path is a programming mistake, and the useful moment to hear\n * about it is the call that made it — not a 400 three layers away.\n */\nfunction validateStoragePath(p: string): void {\n if (!STORAGE_PATH_RE.test(p) || STORAGE_TRAVERSAL_RE.test(p)) {\n throw new Error(\n `Invalid file path: \"${p}\". Paths must not contain traversal sequences and must match ${STORAGE_PATH_RE.source}`,\n );\n }\n}\n\n/**\n * The wire's own shape, mapped onto what this package declares.\n *\n * v2's storage answers in camelCase with the variants and the thumbhash already\n * in it, so this maps rather than translates. The snake_case unwrapping that\n * used to live here (`metadata.mimetype`, `bucket_id`, `created_at`) belonged to\n * a different server, and reading those names off this wire produced an object\n * whose size was 0 and whose content type was \"\".\n */\nfunction toFileObject(bucket: string, row: Record<string, unknown>): PalbaseFileObject {\n return {\n name: (row.path as string) ?? \"\",\n path: (row.path as string) ?? \"\",\n bucket: (row.bucket as string) ?? bucket,\n size: typeof row.size === \"number\" ? row.size : 0,\n contentType: (row.contentType as string) ?? \"\",\n checksum: (row.checksum as string) ?? \"\",\n width: row.width as number | undefined,\n height: row.height as number | undefined,\n thumbhash: row.thumbhash as string | undefined,\n variants: (row.variants as Record<string, string>) ?? {},\n };\n}\n\n/** Re-map the data of a SUCCESSFUL envelope; pass errors through untouched. */\nfunction mapResponse<In, Out>(\n res: PalbaseResult<In>,\n map: (data: In) => Out,\n): PalbaseResult<Out> {\n if (res.error || res.data === null || res.data === undefined) {\n return { data: null, error: res.error, status: res.status };\n }\n return { data: map(res.data), error: null, status: res.status };\n}\n\nfunction buildBucketClient(\n http: ModuleTransport,\n bucketName: string,\n publicOrigin: string,\n): PalbaseBucketClient {\n const objectPath = (path: string) => `/v1/storage/object/${bucketName}/${path}`;\n\n return {\n async upload(path, file, options?: PalbaseUploadOptions) {\n validateStoragePath(path);\n const headers: Record<string, string> = {\n \"Content-Type\": options?.contentType ?? \"application/octet-stream\",\n };\n if (options?.upsert) headers[\"x-upsert\"] = \"true\";\n // The BYTES, as the body. Storage sniffs the content and decides for\n // itself what this is; the declared type is a hint it may overrule,\n // because a name and a header are both things a caller can be wrong about.\n const body = file instanceof ArrayBuffer ? new Uint8Array(file) : file;\n const res = await http.request<Record<string, unknown>>(\"PUT\", objectPath(path), {\n body,\n headers,\n });\n return mapResponse(res, (r) => toFileObject(bucketName, r ?? {}));\n },\n\n async download(path) {\n validateStoragePath(path);\n // The AUTHENTICATED read: the project already holds a credential this\n // stack verified, so it does not have to mint a signature to open its own\n // object — and this route serves private buckets, which the public one\n // refuses on purpose.\n return http.request<Blob>(\"GET\", objectPath(path), { headers: { Accept: \"*/*\" } });\n },\n\n getPublicUrl(path, options) {\n validateStoragePath(path);\n const variant = options?.variant ? `?variant=${encodeURIComponent(options.variant)}` : \"\";\n // ABSOLUTE — and the origin is a value the stack is TOLD, not the\n // transport's baseUrl.\n //\n // Those are two different addresses and conflating them is how this broke\n // once already: the transport points at palsvc over the loopback\n // (`http://127.0.0.1:8080`), and a URL built from it resolves nowhere\n // outside the pod. So this used to return the path alone.\n //\n // The path alone is not a smaller answer, it is a wrong one. A public URL\n // LEAVES the response body — into an <img>, an email, another app on\n // another host — and none of those have a base to resolve it against.\n // Measured live 24.08.2026: an iOS client handed the returned\n // `/v1/files/post-images/…` straight to URLSession and got\n // NSURLErrorUnsupportedURL (-1002). The upload had worked; only the URL\n // was unusable.\n //\n // `PALBASE_PUBLIC_ORIGIN` is set by whoever publishes the stack, because\n // only they know it: in the cloud the operator writes\n // `https://<ref>.<domain>`, and a self-hosted stack carries whatever\n // domain its certificate is for.\n if (!publicOrigin) {\n // NAMED, not silent — the same doctrine as the other unconfigured\n // modules in engine/config.ts (\"throw a named error on first use rather\n // than silently no-op\"). A returned path would pass every test here and\n // fail in the one place nobody is watching.\n throw new Error(\n `Storage.bucket(\"${bucketName}\").getPublicUrl() needs this stack's public origin, ` +\n \"and it was not configured. Set PALBASE_PUBLIC_ORIGIN to the address clients reach \" +\n \"this stack at (e.g. https://myproject.palbase.studio).\",\n );\n }\n return `${publicOrigin}/v1/files/${bucketName}/${path}${variant}`;\n },\n\n async createSignedUrl(path, options): Promise<PalbaseResult<PalbaseSignedUrlResponse>> {\n validateStoragePath(path);\n // A DURATION — `{ expiresIn: \"1h\" }`. A bare number is ambiguous between\n // seconds and minutes at every call site that reads it, and the ambiguity\n // is only discovered when a link outlives the object it opened.\n return http.request<PalbaseSignedUrlResponse>(\"POST\", `/v1/storage/sign/${bucketName}/${path}`, {\n body: { expiresIn: options.expiresIn },\n });\n },\n\n async list(prefix?: string, options?: PalbaseListOptions) {\n if (prefix) validateStoragePath(prefix);\n const params = new URLSearchParams();\n if (prefix) params.set(\"prefix\", prefix);\n if (options?.limit !== undefined) params.set(\"limit\", String(options.limit));\n const query = params.toString();\n const res = await http.request<{ objects?: Record<string, unknown>[] }>(\n \"GET\",\n `/v1/storage/bucket/${bucketName}${query ? `?${query}` : \"\"}`,\n );\n // `{objects: [...]}`, not a bare array: the envelope leaves room for the\n // paging this will grow, and unwrapping it here keeps that off callers.\n return mapResponse(res, (body) => (body?.objects ?? []).map((row) => toFileObject(bucketName, row)));\n },\n\n async remove(paths) {\n for (const p of paths) validateStoragePath(p);\n // One request per object: the module deletes an object WITH its variants,\n // and a batch endpoint reporting partial success would need a result shape\n // nobody would read. The first refusal ends it — continuing would report a\n // partial delete as a whole one.\n const removed: PalbaseFileObject[] = [];\n for (const p of paths) {\n const res = await http.request<void>(\"DELETE\", objectPath(p));\n if (res.error) return { data: null, error: res.error, status: res.status };\n removed.push(toFileObject(bucketName, { path: p }));\n }\n return { data: removed, error: null, status: 200 };\n },\n\n async move(from, to) {\n validateStoragePath(from);\n validateStoragePath(to);\n return http.request<void>(\"POST\", `/v1/storage/move/${bucketName}`, { body: { from, to } });\n },\n\n async copy(from, to) {\n validateStoragePath(from);\n validateStoragePath(to);\n return http.request<void>(\"POST\", `/v1/storage/copy/${bucketName}`, { body: { from, to } });\n },\n };\n}\n\n/**\n * @param publicOrigin the address CLIENTS reach this stack at — never the\n * transport's base, which is this process's internal route to palsvc. Empty\n * means it was not configured, and `getPublicUrl` refuses by name.\n */\nexport function buildStorageClient(\n http: ModuleTransport,\n publicOrigin: string,\n): PalbaseStorageClient {\n return {\n bucket(name: string) {\n if (!BUCKET_NAME_RE.test(name)) {\n throw new Error(`Invalid bucket name: \"${name}\". Bucket names must match ${BUCKET_NAME_RE.source}`);\n }\n // Sondaki eğik çizgi BURADA kırpılır: `${origin}/v1/files/...` iki\n // eğik çizgiyle biten bir yol üretirdi ve bazı sunucular onu ayrı bir\n // nesne sayar.\n return buildBucketClient(http, name, publicOrigin.replace(/\\/+$/, \"\"));\n },\n };\n}\n","/**\n * clients/index.ts — the composition root for the module clients.\n *\n * This is what the process calls once at boot. It builds the five clients the\n * engine injects and nothing else.\n *\n * WHAT IS NOT BUILT HERE, and why each one is absent rather than forgotten:\n *\n * - `functions`, `analytics`, `links` — the SDK exports no singleton for any\n * of them, so no handler could reach them. They were constructed on every\n * boot and thrown away. `auth` was in this list until roles arrived: the\n * sign-in half still belongs to the client SDK, but the ASSIGNMENT half is\n * an operator verb a handler has to be able to call, so `Auth` is built\n * above — as `PalbaseAuthAdminClient`, three methods and no more.\n * - `Purchases` — its client talked to palstore, and v2 contains no palstore\n * at all. The surface was unbacked before it was untyped. Dropped from v2\n * by the user's decision on 2026-08-15, with the SDK's `src/purchases/`\n * tree left in place because that decision was \"deferred, not silently\n * taken\". It is taken now: the tree is GONE (2026-08-29), because a\n * decorator standing in front of a service nothing serves is the same\n * defect as `Resource` and `config/*`, which went with it.\n * - The V1 host/executor transport — the isolate it existed for was removed\n * on 2026-08-14. A single-tenant process has nobody to hide its own\n * tenant's credentials from.\n */\n\nimport type { ModuleClients } from \"../engine/index.js\";\nimport { buildAuthClient } from \"./auth.js\";\nimport { buildDocumentsClient } from \"./documents.js\";\nimport { buildFlagsClient } from \"./flags.js\";\nimport { makeHttpClient } from \"./http.js\";\nimport { buildNotificationsClient } from \"./notifications.js\";\nimport { buildRealtimeClient } from \"./realtime.js\";\nimport { buildStorageClient } from \"./storage.js\";\n\nexport interface ModuleClientsConfig {\n /** Where the platform answers. Empty means \"not configured\" — see below. */\n baseUrl: string;\n /** The publishable key. Used only when no service-role key is supplied. */\n apiKey: string;\n /**\n * The service-role key, which is what a backend actually holds. Preferred\n * over `apiKey`: this process IS the project's server.\n */\n serviceRoleKey: string;\n /** The shared Realtime secret. Empty means realtime is not provisioned. */\n realtimeApiJwtSecret: string;\n /**\n * The address CLIENTS reach this stack at. Used ONLY to build public object\n * URLs; every request this bundle makes still goes over `baseUrl`.\n */\n publicOrigin: string;\n /** The request's user, read from the SDK's own scope — never from a caller. */\n getCurrentUserId: () => string | null;\n /** Injected in tests; resolved at call time in production. */\n fetchImpl?: typeof fetch;\n}\n\n/**\n * Build the module clients.\n *\n * Returns an EMPTY bundle when there is no base URL, deliberately: the engine\n * then injects its named stubs, so a handler that reaches for `Storage` gets an\n * error saying which module is unconfigured rather than a crash reading a\n * property of undefined. Booting is not blocked — a project that never touches\n * a module runs fine without one.\n */\nexport function buildModuleClients(cfg: ModuleClientsConfig): ModuleClients {\n const baseUrl = (cfg.baseUrl || \"\").replace(/\\/+$/, \"\");\n if (!baseUrl) return {};\n\n // The service-role key when present: this process is the project's own\n // server, and the publishable key would refuse half of what it needs.\n const apiKey = cfg.serviceRoleKey || cfg.apiKey || \"\";\n const http = makeHttpClient({ baseUrl, apiKey, fetchImpl: cfg.fetchImpl });\n\n return {\n // The ROLE half of auth only (`clients/auth.ts` says why the rest is not\n // here). It rides the same service-role transport, which is exactly the\n // credential the assignment routes demand.\n Auth: buildAuthClient(http),\n Documents: buildDocumentsClient(http),\n Storage: buildStorageClient(http, cfg.publicOrigin),\n Notifications: buildNotificationsClient(http),\n Flags: buildFlagsClient(http, { getCurrentUserId: cfg.getCurrentUserId }),\n Realtime: buildRealtimeClient({\n baseUrl,\n apiJwtSecret: cfg.realtimeApiJwtSecret,\n fetchImpl: cfg.fetchImpl,\n }),\n };\n}\n","/**\n * channels.ts — the realtime channel authorization DSL (spec C-5).\n *\n * `defineChannels({...})` is evaluated at bundle load; the declaration is\n * anchored on globalThis under Symbol.for (the error-registry.ts pattern) so\n * the runtime — a separate module instance — reads the SAME object. The runtime\n * empties that slot before each bundle import and puts it back afterwards, so\n * the declaration belongs to the bundle that made it and not to the process.\n * Entry ORDER is the object's key order and is semantic: first match wins.\n *\n * Undeclared channels are DENIED by the server (fail-closed). ownerOnly()\n * patterns resolve with ZERO server hops; custom entries' authorize() runs\n * in the customer's own runtime with the request scope a controller gets.\n */\n\nconst CHANNELS: unique symbol = Symbol.for(\"palbase.backend.channels\") as never;\n\nexport interface ChannelGrant {\n subscribe: boolean;\n publish?: boolean;\n state?: { read?: boolean; write?: boolean };\n}\n\nexport interface ChannelAuthorizeCtx {\n user: { id: string };\n params: Record<string, string>;\n}\n\ninterface OwnerEntry { kind: \"owner\" }\ninterface PublicEntry {\n kind: \"public\";\n publish?: boolean;\n state?: { read?: boolean; write?: boolean };\n}\n/** What a handler receives: who published, on which channel, and what. */\nexport interface ChannelHandlerCtx {\n user: { id: string };\n params: Record<string, string>;\n channel: string;\n event: string;\n payload: Record<string, unknown>;\n}\n\ninterface CustomEntry {\n authorize: (ctx: ChannelAuthorizeCtx) => ChannelGrant | null | Promise<ChannelGrant | null>;\n /**\n * Take over publishes on this channel instead of fanning them out.\n *\n * Without it, `channel.send(...)` is relayed to the other subscribers\n * verbatim — fine for a chat message, wrong for anything the client should\n * not be trusted to assert. A bid, a vote, a game move is a REQUEST, and the\n * result is whatever this function decides and then publishes (through\n * `Realtime.broadcast` or `Realtime.state.set`).\n *\n * A function rather than the name of a route: `authorize` is already one and\n * runs in this same scope, so naming an endpoint would mean inventing a\n * resolution step for no gain.\n */\n handler?: (ctx: ChannelHandlerCtx) => void | Promise<void>;\n}\nexport type ChannelEntry = OwnerEntry | PublicEntry | CustomEntry;\nexport type ChannelsInput = Record<string, ChannelEntry>;\n\nexport interface ChannelsDef {\n entries: Array<{\n pattern: string;\n kind: \"owner\" | \"public\" | \"custom\";\n publish?: boolean;\n state?: { read?: boolean; write?: boolean };\n authorize?: CustomEntry[\"authorize\"];\n handler?: CustomEntry[\"handler\"];\n }>;\n}\n\n/** Full-access-to-the-owner pattern: the pattern must carry EXACTLY one {param};\n * the server compares its value to the verified token subject with zero hops. */\nexport function ownerOnly(): OwnerEntry {\n return { kind: \"owner\" };\n}\n\n/** Anyone with a valid token may subscribe; publish/state are explicit opt-ins. */\nexport function publicChannel(\n opts: { publish?: boolean; state?: { read?: boolean; write?: boolean } } = {},\n): PublicEntry {\n return { kind: \"public\", publish: opts.publish ?? false, state: opts.state };\n}\n\nfunction paramCount(pattern: string): number {\n return pattern.split(\":\").filter((s) => s.startsWith(\"{\") && s.endsWith(\"}\")).length;\n}\n\nexport function defineChannels(map: ChannelsInput): ChannelsDef {\n const entries: ChannelsDef[\"entries\"] = [];\n for (const [pattern, entry] of Object.entries(map)) {\n if (\"kind\" in entry && entry.kind === \"owner\") {\n if (paramCount(pattern) !== 1) {\n throw new Error(\n `defineChannels: ownerOnly() pattern \"${pattern}\" must carry exactly one {param} ` +\n `(its value is compared to the token subject)`,\n );\n }\n entries.push({ pattern, kind: \"owner\" });\n } else if (\"kind\" in entry && entry.kind === \"public\") {\n entries.push({ pattern, kind: \"public\", publish: entry.publish, state: entry.state });\n } else {\n const c = entry as CustomEntry;\n entries.push({ pattern, kind: \"custom\", authorize: c.authorize, handler: c.handler });\n }\n }\n const def: ChannelsDef = { entries };\n\n // A SECOND, DIFFERENT declaration is a hard error rather than an overwrite.\n //\n // The same bundle can legitimately be evaluated twice in one process — the\n // error registry beside this file documents exactly that case — so an\n // identical re-declaration passes silently. But two DIFFERENT declarations\n // mean two channels files, and overwriting would delete the first one's\n // channels. Undeclared channels are DENIED, so the symptom would be joins\n // refused in production for channels the developer can see declared in their\n // own source, with nothing anywhere saying why. Loud here beats silent there.\n //\n // \"Already\" means WITHIN ONE BUNDLE LOAD. The runtime hands each import an\n // empty slot, so this compares two calls from the same bundle — which is what\n // it was written for. It used to reach across imports as well, and then a\n // deploy that merely ADDED a channel was refused as a second channels file,\n // with a message pointing at a file the customer did not have.\n const carrier = globalThis as Record<symbol, unknown>;\n const existing = carrier[CHANNELS] as ChannelsDef | undefined;\n if (existing && !sameDeclaration(existing, def)) {\n throw new Error(\n `defineChannels: channels were already declared (${existing.entries.length} ` +\n `pattern(s): ${existing.entries.map((e) => e.pattern).join(\", \")}). ` +\n `A project declares its channels ONCE — a second call would overwrite the ` +\n `first, and channels nobody declared are refused.`,\n );\n }\n carrier[CHANNELS] = def;\n return def;\n}\n\n/**\n * One entry as the runtime will compile it, rendered for comparison.\n *\n * NORMALIZED, because the runtime normalizes: `collectChannels` applies\n * `?? false` to publish and both state flags before the table goes on the wire.\n * Comparing the raw entries called two spellings of ONE entry a conflict —\n * `publicChannel()` fills `publish: false` where a hand-written\n * `{ kind: \"public\" }` leaves it undefined, and the two produce a byte-identical\n * table. There is one source of truth for what an entry IS, and it is the row.\n *\n * The authorize function is compared by SOURCE TEXT. Comparing the closures\n * themselves is wrong — two evaluations of one module produce two distinct\n * functions for the same source, which is the case this guard has to let\n * through — but comparing only `Boolean(fn)` called two unrelated\n * authorization rules \"the same declaration\", so the guard stayed silent while\n * one channel's access rule was swapped for another's. Same source, same text;\n * different logic, different text. Not exhaustive (two closures over different\n * captured values share a source), and better than a boolean by the whole\n * distance between \"some rule\" and \"this rule\".\n */\nfunction wireRow(e: ChannelsDef[\"entries\"][number]): string {\n return JSON.stringify([\n e.pattern,\n e.kind,\n e.publish ?? false,\n e.state?.read ?? false,\n e.state?.write ?? false,\n // The handler is compared by SOURCE, like authorize: two evaluations of one\n // module give the same text, while different logic gives different text.\n e.handler ? e.handler.toString() : \"\",\n e.authorize ? e.authorize.toString() : \"\",\n ]);\n}\n\n/** Two declarations are the same when they compile to the same rows in the same\n * ORDER — order is semantic here (first match wins). */\nfunction sameDeclaration(a: ChannelsDef, b: ChannelsDef): boolean {\n if (a.entries.length !== b.entries.length) return false;\n return a.entries.every((x, i) => wireRow(x) === wireRow(b.entries[i]!));\n}\n","import { NotFound } from \"../errors.js\";\n\n/**\n * repository.ts — kiracıya kapsanmış CRUD'un TEK yazımı.\n *\n * Ölçülen kusur: tüketici katmanında 61 forwarding metodu vardı ve her biri\n * aynı iki satırı tekrar ediyordu — kiracı kolonunu yükleme ekle, sonucu\n * çevir. Aynı olan bir şeyi 61 kez yazmak onu 61 kez UNUTULABİLİR yapar; ve\n * unutulan tek bir yüklem, RLS'in altında bir kiracının satırını başka bir\n * kiracıya gösterir.\n *\n * ```ts\n * export class TodoRepository extends defineRepository(\n * Database.public.todos,\n * { tenant: \"household_id\" },\n * ) {}\n * ```\n *\n * Satır anahtarı `id` DEĞİLSE adıyla verilir — `defineTable` bir `id` kolonu\n * şart koşmuyor, birincil anahtar herhangi bir kolonda olabilir:\n *\n * ```ts\n * export class DocRepository extends defineRepository(\n * Database.public.docs,\n * { tenant: \"org_id\", key: \"slug\" },\n * ) {}\n * ```\n *\n * `Database` AMBIENT kalır ve enjekte EDİLMEZ: istek kapsamlıdır, yani bir\n * kurucuya kapatılan bir referans bir isteğin istemcisini bir başkasına\n * taşırdı. Tablo erişimcisi argüman olarak geçer ve her çağrıda güncel istek\n * kapsamını çözen proxy'ye iner; taban sınıfın kurucusu ARGÜMANSIZ kalır, o\n * yüzden container onu ek metadata olmadan çözer.\n */\n\n/**\n * Repo'nun tablodan İSTEDİĞİ dört üye — `Database.public.<t>`'nin alt kümesi.\n *\n * Yüklemler `Record<string, unknown>`: kiracı kolonunun adı ÇALIŞMA ANINDA\n * gelen bir değer, ve TypeScript jenerik bir anahtarla kurulan nesne\n * literalini mapped type'a bağlayamaz (ölçüldü: `{ [k]: v }` → `{ [x: string]:\n * V }`, `{ [P in K]: V }`'ye atanamaz). Kapsamı DAR tutup burada gevşetmek,\n * çağıranın tarafında `as` yazmaktan farklıdır: dışa bakan yüzey — `list`,\n * `find`, `insert`, `update`, `updateScoped`, `delete` — tamamen tipli kalır.\n *\n * `NoInfer`: `Row` YALNIZ `insert`'ün dönüşünden çıkarılır. `findMany` motorda\n * jenerik (`select`/`with`) ve kısıtlarıyla örneklendiğinde ilişki anahtarları\n * taşıyan BAŞKA bir satır tipi önerir; iki aday birleşince satır tipi sessizce\n * genişlerdi.\n */\nexport interface RepositoryTable<Row, Insert, Patch> {\n insert(data: Insert): Promise<Row>;\n findMany(q: { where: Record<string, unknown>; limit?: number }): Promise<NoInfer<Row>[]>;\n updateMany(q: { where: Record<string, unknown>; set: Patch }): Promise<NoInfer<Row>[]>;\n deleteMany(q: { where: Record<string, unknown> }): Promise<number>;\n}\n\n/**\n * Satır anahtarının VARSAYILANI: tablo bir `id` kolonu taşıyorsa `\"id\"`.\n *\n * `defineTable` bir `id` kolonu ŞART KOŞMUYOR — birincil anahtar herhangi bir\n * kolonda `.primaryKey()` ile ya da `primaryKey: [...]` ile bildirilebiliyor.\n * Bu yüzden anahtar sabit değil, PARAMETRE; ama `id` taşıyan tabloların\n * (çoğunluk) hiçbir şey yazmaması gerekiyor.\n */\nexport type DefaultRowKey<Row> = Extract<keyof Row & string, \"id\">;\n\n/**\n * Anahtar bulunamadığında REDDİ ADIYLA söyleyen tip.\n *\n * `id`'si olmayan bir tabloda `key` verilmezse {@link DefaultRowKey} `never`\n * olur ve `Row[never]` de `never`'dır: kapı doğru kapanır ama \"type 'string' is\n * not assignable to type 'never'\" diyerek ÇAREYİ söylemez. Buradaki tek alanlı\n * arayüz aynı reddi verir ve alanın adı hatanın içinde çareyi yazar.\n */\nexport interface MissingRowKey {\n \"defineRepository: bu satırda `id` kolonu yok — anahtarı { key: \\\"...\\\" } ile adlandır\": never;\n}\n\n/** Anahtar kolonunun DEĞER tipi; anahtar bilinmiyorsa {@link MissingRowKey}. */\nexport type RowKey<Row, PK extends keyof Row & string> = [PK] extends [never]\n ? MissingRowKey\n : Row[PK];\n\n/**\n * Kiracıya kapsanmış repo yüzeyi. `K` kiracı kolonu, `Row[K]` onun DEĞERİ.\n *\n * `insert` yükünde kiracı kolonu YOKTUR: onu repo yazar — `Omit` bunu ifade\n * edilemez kılıyor, anlatmıyor. `update`/`updateScoped` patch'i tablonun kendi\n * `set` şeklidir ve kiracı kolonunu DIŞLAMAZ: satırı başka bir kiracıya\n * taşımak tablonun `WITH CHECK` politikasının kararıdır, repo'nun değil — ve\n * repo'nun yüklemi zaten çağıranın kiracısına kapanmış durumda.\n */\nexport interface RepositoryOf<\n Row,\n Insert,\n Patch,\n K extends keyof Row & string,\n PK extends keyof Row & string = DefaultRowKey<Row>,\n> {\n /** Kiracının tüm satırları. */\n list(tenant: Row[K]): Promise<Row[]>;\n /** Kiracının bu anahtarlı satırı, ya da yoksa `null` — yokluk bir DEĞER. */\n find(tenant: Row[K], id: RowKey<Row, PK>): Promise<Row | null>;\n /** Satırı kiracıya YAZAR: kiracı kolonu yükte değil, burada. */\n insert(tenant: Row[K], values: Omit<Insert, K>): Promise<Row>;\n /**\n * Kiracının bu id'li satırını günceller ve GÜNCEL satırı döner.\n *\n * Eşleşen satır yoksa `NotFound` ATAR — çağıran `!` yazmak ya da `null`\n * dallanması yazmak zorunda kalmasın. Yokluğu DEĞER olarak isteyen\n * {@link RepositoryOf.updateScoped} kullanır.\n */\n update(tenant: Row[K], id: RowKey<Row, PK>, patch: Patch): Promise<Row>;\n /**\n * {@link RepositoryOf.update} ile AYNI yüklem, ama bulunamazsa `null` döner.\n *\n * Tüketicinin bugün elle yazdığı `updateMany(…).then(rows => rows[0] ?? null)`\n * kalıbının adı budur.\n */\n updateScoped(tenant: Row[K], id: RowKey<Row, PK>, patch: Patch): Promise<Row | null>;\n /** Kiracının bu anahtarlı satırını siler. Yoksa bir şey olmaz. */\n delete(tenant: Row[K], id: RowKey<Row, PK>): Promise<void>;\n}\n\n/**\n * Kiracıya kapsanmış bir repo TABAN SINIFI üretir.\n *\n * Dönen sınıf `abstract`: doğrudan `new` edilemez, çünkü DI'ın çözeceği ad alt\n * sınıfın adıdır (`TodoRepository`), üretilen anonim sınıfınki değil.\n */\nexport function defineRepository<\n Row,\n Insert,\n Patch,\n K extends keyof Row & string,\n PK extends keyof Row & string = DefaultRowKey<Row>,\n>(\n table: RepositoryTable<Row, Insert, Patch>,\n opts: { tenant: K; key?: PK },\n): abstract new () => RepositoryOf<Row, Insert, Patch, K, PK> {\n const tenantColumn = opts.tenant;\n // Anahtar `string` olarak tutuluyor: yüklemler zaten `Record<string, unknown>`\n // ve `opts.key ?? \"id\"`'yi `PK`'ye daraltmak bir `as` gerektirirdi — tipin\n // taşıdığı güvence dışa bakan imzalarda, burada değil.\n const rowKey: string = opts.key ?? \"id\";\n\n // Yüklem TEK yerde kuruluyor. 61 forwarding metodunun her birinde ayrı ayrı\n // yazılıyor olması, birinde unutulmasını mümkün kılan şeydi.\n const scope = (tenant: Row[K]): Record<string, unknown> => ({ [tenantColumn]: tenant });\n const scopeRow = (tenant: Row[K], id: RowKey<Row, PK>): Record<string, unknown> => ({\n [tenantColumn]: tenant,\n [rowKey]: id,\n });\n\n /**\n * Kiracı kolonunu YAZMA yüküne ekleyen tek yer — ve bu dosyadaki tek\n * daraltma.\n *\n * Gerekçesi TypeScript'in ölçülmüş bir sınırı: jenerik bir anahtarla kurulan\n * nesne literali mapped type'a bağlanmıyor (`{ [k]: v }` → `{ [x: string]:\n * V }`, `{ [P in K]: V }`'ye TS2322 ile atanamıyor). Daraltma TEK satırda ve\n * çağıranın göremediği bir yerde duruyor; dışa bakan altı metodun imzası\n * tamamen tipli.\n *\n * Kiracı SONRA yazılıyor: yükte aynı adda bir alan kalmışsa (tip onu\n * yasaklıyor, ama bu yol JavaScript'ten de çağrılabilir) repo'nunki kazanır.\n * Kapsamı çağıranın verisi belirlemez.\n */\n const scopedPayload = (values: Omit<Insert, K>, tenant: Row[K]): Insert =>\n ({ ...values, [tenantColumn]: tenant }) as Insert;\n\n abstract class Repository implements RepositoryOf<Row, Insert, Patch, K, PK> {\n list(tenant: Row[K]): Promise<Row[]> {\n return table.findMany({ where: scope(tenant) });\n }\n\n async find(tenant: Row[K], id: RowKey<Row, PK>): Promise<Row | null> {\n const rows = await table.findMany({ where: scopeRow(tenant, id), limit: 1 });\n return rows[0] ?? null;\n }\n\n insert(tenant: Row[K], values: Omit<Insert, K>): Promise<Row> {\n return table.insert(scopedPayload(values, tenant));\n }\n\n async update(tenant: Row[K], id: RowKey<Row, PK>, patch: Patch): Promise<Row> {\n const row = await this.updateScoped(tenant, id, patch);\n if (row === null) {\n throw new NotFound(\n `${String(tenantColumn)}=${String(tenant)} kapsamında ${rowKey}=${String(id)} bulunamadı`,\n );\n }\n return row;\n }\n\n async updateScoped(tenant: Row[K], id: RowKey<Row, PK>, patch: Patch): Promise<Row | null> {\n const rows = await table.updateMany({ where: scopeRow(tenant, id), set: patch });\n return rows[0] ?? null;\n }\n\n async delete(tenant: Row[K], id: RowKey<Row, PK>): Promise<void> {\n await table.deleteMany({ where: scopeRow(tenant, id) });\n }\n }\n\n return Repository;\n}\n","/**\n * stack-gen.ts — generate the `palbase-stack.d.ts` text from the names the\n * linked environment's stack holds.\n *\n * The twin of `db/env-gen.ts`: the CLI calls\n * {@link makeStackDts} with the three name sets it read off the stack and\n * writes the result to `palbase-stack.d.ts` at the project root. That file\n * augments the `@palbase/backend/stack` interfaces, so `Secrets.get(...)`, the\n * Flags client and `@Upload({ bucket })` accept the project's real names and\n * nothing else.\n *\n * The generator does NOT reach the network and does NOT decide what a name is:\n * it renders what it is handed. The stack is the authority on which names exist\n * (`GET /v1/management/secrets`, `/flags`, `/storage/buckets`); re-deciding that\n * here would be a second, weaker copy of it.\n *\n * The emitted file ends in `export {};` — same as `makeEnvDts` and\n * `makePurchasesDts`. Without it the `.d.ts` is a global script, and\n * `declare module \"…\"` there DECLARES an ambient module (shadowing the real one,\n * so every name silently becomes invalid) instead of AUGMENTING it.\n */\n\n/** The three name sets read off the stack. Order is irrelevant — each set is\n * sorted here so the same stack always renders the same bytes and a diff shows\n * what CHANGED rather than how the API happened to order its answer. */\n/** One bucket and the renditions it declares. */\nexport interface BucketInput {\n name: string;\n variants: readonly string[];\n}\n\nexport interface StackNames {\n /** Secret names from the project's vault. */\n secrets: readonly string[];\n /** Flag keys from the project's flag store. */\n flags: readonly string[];\n /**\n * Buckets from the project's storage — a bare name, or a name with the\n * renditions it declares.\n *\n * A bucket is not only a NAME: `Storage.buckets.docs.getPublicUrl(p, {\n * variant })` refuses a rendition the bucket does not have, so the variant\n * union has to travel with it. The bare-string form is shorthand for \"no\n * variants\", which renders `never` and accepts none.\n */\n buckets: readonly (string | BucketInput)[];\n}\n\n/** Sorted, de-duplicated names. A stack that reports one twice (two pages of a\n * listing overlapping, say) must not render a duplicate member — TypeScript\n * accepts it, but the file stops being a function of the stack's contents. */\nfunction liveNames(names: readonly string[]): string[] {\n return [...new Set(names)].sort();\n}\n\n/** A bare identifier stays bare; anything else is quoted. Bucket names carry\n * dashes and dots (the Storage module's allowed shape), and an unquoted\n * `my-bucket` parses as a subtraction rather than a member name. */\nfunction memberName(name: string): string {\n return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name) ? name : JSON.stringify(name);\n}\n\nfunction members(names: string[]): string {\n if (names.length === 0) return \"\";\n return `\\n${names.map((n) => ` ${memberName(n)}: true;`).join(\"\\n\")}\\n `;\n}\n\n/** Buckets render a SHAPE rather than a marker, because each carries its variant\n * union. `never` for a bucket with none: the type then accepts no variant name\n * at all, which is exactly what a bucket without renditions offers. */\nfunction bucketMembers(buckets: readonly (string | BucketInput)[]): string {\n const normalized = buckets.map((b) => (typeof b === \"string\" ? { name: b, variants: [] as readonly string[] } : b));\n const byName = new Map<string, readonly string[]>();\n for (const b of normalized) byName.set(b.name, b.variants);\n const names = [...byName.keys()].sort();\n if (names.length === 0) return \"\";\n const rows = names.map((name) => {\n const variants = [...new Set(byName.get(name) ?? [])].sort();\n const union = variants.length === 0 ? \"never\" : variants.map((v) => JSON.stringify(v)).join(\" | \");\n return ` ${memberName(name)}: { variants: ${union} };`;\n });\n return `\\n${rows.join(\"\\n\")}\\n `;\n}\n\n/**\n * Render the project's `palbase-stack.d.ts`.\n *\n * An empty set renders an empty interface, which is a MEANINGFUL value: the\n * stack holds no such names, so the corresponding union is `never` and every\n * call spelling one fails to compile. It is not the same as \"the file was never\n * generated\" only in that the file exists — both states refuse every name, and\n * both are correct.\n */\nexport function makeStackDts(names: StackNames): string {\n const secrets = liveNames(names.secrets);\n const flags = liveNames(names.flags);\n\n\n return `// palbase-stack.d.ts — GENERATED by @palbase/backend. Do not edit.\n// Source: the linked environment's stack.\n\ndeclare module \"@palbase/backend/stack\" {\n interface Secrets {${members(secrets)}}\n\n interface Flags {${members(flags)}}\n\n interface Buckets {${bucketMembers(names.buckets)}}\n}\n\nexport {};\n`;\n}\n","// Method decorators: `@Get` / `@Post` / `@Put` / `@Patch` / `@Delete` /\n// `@Query` declare a route (verb + subpath + options) on a controller method. These are LEGACY\n// method decorators (`experimentalDecorators`), receiving\n// `(prototype, methodName, descriptor)`. They write into the per-class registry\n// (registry.ts). The success-response schema is NOT declared here: it is derived\n// from the method's RETURN TYPE by a codegen step and injected onto the route at\n// runtime via `recordReturn` (registry.ts).\nimport {\n recordRoute,\n type HttpMethodUpper,\n type RouteOptions,\n} from \"./registry.js\";\n\n/** A legacy method decorator.\n *\n * The third argument is typed `unknown`, not `PropertyDescriptor`, on purpose:\n * when the decorator is applied to a PARAMETER (`m(@Query(\"q\") q: string)`),\n * TypeScript calls it with the parameter INDEX there. The type would let the\n * runtime pretend that cannot happen; the runtime measures it instead. */\n// `descriptor` is OPTIONAL but stays a PropertyDescriptor: optional so a\n// property-position call (descriptor undefined) type-checks, narrow so a\n// parameter-position call (`m(@Query(\"q\") q)`, third argument a number) is\n// still TS1239 at compile time. `unknown` here would trade that compile-time\n// refusal for the runtime one below; keeping both is the point (W4 r2 I-3).\ntype MethodDecorator = (\n target: object,\n propertyKey: string | symbol | undefined,\n descriptor?: PropertyDescriptor,\n) => void;\n\n/** Build a method decorator for one HTTP verb. The decorated method's name is\n * the route `fnName` — and it is PUBLIC API, not authoring sugar: the runtime\n * derives the operationId as `<controllerName>.<fnName>` (the dotted namespace\n * the SDKs expose as `pb.todos.list()`), so renaming this method renames every\n * client call. The flat verb+path id is only the fallback for routes with no\n * controller metadata. See openapi/discover.ts. */\nfunction makeMethodDecorator(method: HttpMethodUpper) {\n return function (subpath: string, options: RouteOptions = {}): MethodDecorator {\n // Runtime guard for stale pre-9.0.0 code: `@Query(zodSchema)` used to be\n // the query-string PARAM decorator. Applied against this SDK it would\n // silently record a garbage route (schema-as-subpath) and fail the deploy\n // with a baffling self-conflict — fail loud and name the migration instead.\n if (typeof subpath !== \"string\") {\n throw new Error(\n `@${method[0]}${method.slice(1).toLowerCase()}(subpath) expects a string subpath, got ${typeof subpath}.` +\n (method === \"QUERY\"\n ? \" If this is a zod schema on a method parameter: the query-string param decorator was renamed @QueryParams(schema) in @palbase/backend 9.0.0.\"\n : \"\"),\n );\n }\n return function (target, propertyKey, descriptor?: PropertyDescriptor) {\n const verb = `${method[0]}${method.slice(1).toLowerCase()}`;\n // POSITION guard, and it runs BEFORE `recordRoute`: `m(@Query(\"q\") q)`\n // passes the subpath guard above (the argument IS a string) and arrives\n // here as a parameter-decorator call — the third argument is the\n // parameter index, not a descriptor. Recording it would register a\n // route the author never wrote, named after the method, and the deploy\n // would fail later, elsewhere, on that route. Refuse here, by position,\n // and name the decorators that DO go on a parameter.\n if (typeof (descriptor as unknown) === \"number\") {\n throw new Error(\n `@${verb}(...) is a ROUTE decorator and was applied to parameter #${descriptor} of ${propertyKey === undefined ? \"the constructor\" : String(propertyKey)}; ` +\n \"for query-string params use @QueryParams(schema), for the body @Body(schema), for a path segment @Param(name)\",\n );\n }\n // CLASS position: `@Get(\"/x\") class C {}` arrives with no propertyKey\n // and would record a route literally named \"undefined\". AFTER the\n // parameter check: a constructor parameter (`constructor(@Get(\"/x\") x)`)\n // arrives as (C, undefined, 0) and deserves the parameter message.\n if (propertyKey === undefined) {\n throw new Error(`@${verb}(...) goes on a METHOD, not on a class; put it on the handler method inside @Controller`);\n }\n recordRoute(target, String(propertyKey), method, subpath, options);\n };\n };\n}\n\n/** `@Get(subpath, options?)` — declare a GET route. */\nexport const Get = makeMethodDecorator(\"GET\");\n/** `@Post(subpath, options?)` — declare a POST route. */\nexport const Post = makeMethodDecorator(\"POST\");\n/** `@Put(subpath, options?)` — declare a PUT route. */\nexport const Put = makeMethodDecorator(\"PUT\");\n/** `@Patch(subpath, options?)` — declare a PATCH route. */\nexport const Patch = makeMethodDecorator(\"PATCH\");\n/** `@Delete(subpath, options?)` — declare a DELETE route. */\nexport const Delete = makeMethodDecorator(\"DELETE\");\n/** `@Query(subpath, options?)` — declare an HTTP QUERY route (RFC 10008):\n * safe + idempotent like GET, body-carrying like POST. Input rides `@Body`. */\nexport const Query = makeMethodDecorator(\"QUERY\");\n","/**\n * The one rule for a declared surface name.\n *\n * A job's name is the row the scheduler holds it under; a webhook's name is the\n * path segment its endpoint is served at. Both used to be the FILE's name, which\n * made a public identity a property of where a class happened to sit — rename\n * the file and the scheduler starts a different job, or a sender's configured\n * URL stops resolving.\n *\n * Declaring it puts the identity beside the schedule and the secret, where a\n * reader is already looking. There is no default: a default would be a SECOND\n * source for the identity, and the whole design rests on there being one.\n */\nconst SHAPE = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/;\n\nexport function assertSurfaceName(name: unknown, decorator: string, kind: string): void {\n if (typeof name !== \"string\" || name.trim() === \"\") {\n throw new Error(\n `${decorator} requires a \\`name\\` — it is this ${kind}'s identity, and it is ` +\n `declared rather than taken from the file name.`,\n );\n }\n if (!SHAPE.test(name)) {\n throw new Error(\n `${decorator} name \"${name}\" is not usable: it reaches a URL and a log line, so it ` +\n `must be lowercase letters, digits and dashes, starting and ending with one of those.`,\n );\n }\n}\n","// @Webhook / @On — the inbound-webhook half of the decorator surface.\n//\n// Mirrors decorators/controller.ts exactly: symbol-keyed, non-enumerable\n// metadata on the constructor plus a `__palbase` discriminant, read back by a\n// resolver. The resolver is the ONLY translation point — it returns the shape\n// the runtime already consumes, so the isolate's dispatch and the signature\n// engine's cross-binding golden are untouched by the authoring change.\nimport type { WebhookMeta, WebhookProvider } from \"../webhook.js\";\nimport type { Container } from \"../container.js\";\nimport { assertSurfaceName } from \"./surface-name.js\";\n\n/** A signature scheme spelled out, for a service with no preset. The presets\n * (`provider`) are named configurations of this same shape. */\nexport interface SignatureSpec {\n /** Header carrying the signature. */\n header: string;\n /** Stripped before comparison (e.g. `sha256=`). Omit when absent. */\n prefix?: string;\n algo: \"hmac-sha256\" | \"hmac-sha1\";\n encoding: \"hex\" | \"base64\";\n /** What the HMAC covers. Exactly two placeholders: `{body}` and `{ts}`.\n * Everything else is literal. `{ts}` requires `timestampHeader` and brings\n * the five-minute replay window with it. */\n signs: string;\n timestampHeader?: string;\n}\n\nexport interface WebhookOptions {\n /**\n * The path segment this webhook is served at: `/webhooks/<name>`.\n *\n * DECLARED, not derived. It used to be the file's name, which put a PUBLIC\n * URL — the one a sender is configured with — in the file system rather than\n * beside the provider and the secret, where a reader looks for it.\n */\n name: string;\n provider?: WebhookProvider;\n signature?: SignatureSpec;\n /** Env-var REFERENCE for the signing secret — the platform never holds it. */\n secret: { env: string };\n}\n\nexport type WebhookEventHandler = (event: unknown, meta: WebhookMeta) => Promise<void>;\n\nexport interface ResolvedWebhook {\n provider?: WebhookProvider;\n signature?: SignatureSpec;\n secret: { env: string };\n events: Record<string, WebhookEventHandler>;\n}\n\nexport const WEBHOOK_META: unique symbol = Symbol.for(\"palbase.backend.webhookMeta\");\nexport const WEBHOOK_EVENTS: unique symbol = Symbol.for(\"palbase.backend.webhookEvents\");\n\ninterface EventEntry {\n event: string;\n fnName: string;\n}\n\ninterface WebhookCarrier {\n __palbase?: \"webhook\";\n [WEBHOOK_META]?: WebhookOptions;\n [WEBHOOK_EVENTS]?: EventEntry[];\n}\n\nfunction carrierOf(ctor: object): WebhookCarrier {\n return ctor as WebhookCarrier;\n}\n\n/** Mark a class as an inbound webhook. The mount name is the FILE name — there\n * is deliberately no `name` option, because the file name IS the public URL. */\nexport function Webhook(options: WebhookOptions) {\n return function <T extends abstract new (...args: never[]) => object>(ctor: T): T {\n const carrier = carrierOf(ctor);\n Object.defineProperty(carrier, WEBHOOK_META, {\n value: options,\n enumerable: false,\n configurable: true,\n writable: false,\n });\n Object.defineProperty(carrier, \"__palbase\", {\n value: \"webhook\",\n enumerable: false,\n configurable: true,\n writable: false,\n });\n return ctor;\n };\n}\n\n/** Bind a method to one event name. Any string is valid: presets provide\n * autocomplete, never a constraint, because we do not carry provider catalogs. */\nexport function On(event: string) {\n return function (target: object, fnName: string | symbol): void {\n // Method decorators receive the PROTOTYPE; metadata belongs on the ctor.\n const carrier = carrierOf((target as { constructor: object }).constructor);\n const existing = carrier[WEBHOOK_EVENTS];\n const entries: EventEntry[] = existing ? [...existing] : [];\n entries.push({ event, fnName: String(fnName) });\n Object.defineProperty(carrier, WEBHOOK_EVENTS, {\n value: entries,\n enumerable: false,\n configurable: true,\n writable: false,\n });\n };\n}\n\n/** Read a decorated class back as the resolved config the runtime consumes.\n * Every misuse throws HERE, at build time, rather than becoming a webhook that\n * answers 200 and does nothing.\n *\n * @throws when the class declares constructor parameters (FR-011) — nothing\n * here supplies them, so the field would be `undefined` on every delivery. */\n/**\n * Everything a webhook DECLARES — provider or signature template, the secret's\n * env var, and the event names — validated, without constructing the class.\n *\n * Same split as jobs and hooks: reading a declaration should not build an\n * object. `getWebhookConfig` is what needs an instance, and it needs a\n * container to get one.\n */\nexport function getWebhookManifest(ctor: object): {\n name: string;\n provider: string | undefined;\n secretEnv: string;\n events: string[];\n} {\n const { meta, entries } = validateWebhook(ctor);\n return {\n name: meta.name,\n provider: meta.provider,\n secretEnv: meta.secret.env,\n events: entries.map((e) => e.event),\n };\n}\n\n/** The declaration half: every refusal, and no construction. */\nfunction validateWebhook(ctor: object): {\n meta: NonNullable<ReturnType<typeof carrierOf>[typeof WEBHOOK_META]>;\n entries: NonNullable<ReturnType<typeof carrierOf>[typeof WEBHOOK_EVENTS]>;\n} {\n const carrier = carrierOf(ctor);\n const meta = carrier[WEBHOOK_META];\n const entries = carrier[WEBHOOK_EVENTS] ?? [];\n\n if (!meta) {\n throw new Error(\n `@On used on a class that is not decorated with @Webhook (${(ctor as { name?: string }).name ?? \"anonymous\"})`,\n );\n }\n assertSurfaceName(meta.name, \"@Webhook\", \"webhook\");\n if (!meta.provider && !meta.signature) {\n throw new Error(\n \"@Webhook requires either a `provider` preset or an explicit `signature` — \" +\n \"an endpoint with no verification would accept forged deliveries\",\n );\n }\n // EITHER, not both. The isolate picks `provider` when both are present and\n // never looks at `signature`, so a tenant that wrote both gets deliveries\n // verified against a scheme they did not choose — silently, and with no way to\n // tell from the outside which one ran. Ambiguity about WHICH signature check\n // guards an endpoint is not something to resolve by precedence.\n if (meta.provider && meta.signature) {\n throw new Error(\n \"@Webhook declares BOTH a `provider` preset and an explicit `signature` — \" +\n \"these are alternatives; keep the one that describes the sender, because only `provider` would be used\",\n );\n }\n if (meta.signature) {\n const sig = meta.signature;\n // Mirrors Go's NewTemplateVerifier (internal/webhook/verify.go). Both sides\n // reject the same specs; this one rejects at build, which is the only place\n // a tenant can still act on it.\n if (!sig.header) {\n throw new Error(\"@Webhook signature requires `header` — the header the signature arrives in\");\n }\n if (sig.algo !== \"hmac-sha256\" && sig.algo !== \"hmac-sha1\") {\n throw new Error(`@Webhook signature has an unsupported algo \"${sig.algo}\"`);\n }\n if (sig.encoding !== \"hex\" && sig.encoding !== \"base64\") {\n throw new Error(`@Webhook signature has an unsupported encoding \"${sig.encoding}\"`);\n }\n if (!sig.signs?.includes(\"{body}\")) {\n throw new Error(\"@Webhook signature `signs` must contain {body} — signing a constant is not a signature\");\n }\n if (sig.signs.includes(\"{ts}\") && !sig.timestampHeader) {\n throw new Error(\"@Webhook signature uses {ts} but declares no `timestampHeader` to read it from\");\n }\n }\n if (!meta.secret?.env) {\n throw new Error(\"@Webhook requires `secret: { env: \\\"VAR_NAME\\\" }`\");\n }\n if (entries.length === 0) {\n throw new Error(\"@Webhook requires at least one @On handler\");\n }\n return { meta, entries };\n}\n\nexport function getWebhookConfig(ctor: object, container: Container): ResolvedWebhook {\n const { meta, entries } = validateWebhook(ctor);\n\n const instance = container.get(ctor as never) as Record<string, WebhookEventHandler>;\n // Object.create(null), not {} — event names are free-form, so `@On(\"constructor\")`\n // and `@On(\"toString\")` are legal. A plain literal inherits those keys from\n // Object.prototype, and the duplicate check below would reject the FIRST and\n // only handler for them as a redeclaration.\n const events: Record<string, WebhookEventHandler> = Object.create(null) as Record<string, WebhookEventHandler>;\n for (const entry of entries) {\n if (Object.prototype.hasOwnProperty.call(events, entry.event)) {\n throw new Error(`@On(\"${entry.event}\") declared twice on the same webhook`);\n }\n events[entry.event] = (event, metaArg) =>\n (instance[entry.fnName] as WebhookEventHandler).call(instance, event, metaArg);\n }\n\n return {\n ...(meta.provider ? { provider: meta.provider } : {}),\n ...(meta.signature ? { signature: meta.signature } : {}),\n secret: meta.secret,\n events,\n };\n}\n","// @Hook — the BLOCKING half of the internal-event surface.\n//\n// Two axes decide which decorator a handler wants. Where does the event come\n// from, and can the handler stop it?\n//\n// @Webhook + @On an OUTSIDE service (Stripe, GitHub…) — cannot block\n// @Hook an event this stack raised — CAN block: `throw` cancels it\n// @On an event this stack raised — listens only, a monitor\n//\n// The blocking power lives in the NAME `@Hook`, not in the method decorator's\n// shape, which is why `@On` keeps meaning \"listener\" in both worlds and needs\n// no change. `@Upload` is the same pattern already shipped: the storage module\n// calls the tenant's method, and a method that answers 4xx discards the object\n// and hands its exact status, body and content-type back to the client.\n//\n// Mirrors decorators/webhook.ts: symbol-keyed, non-enumerable metadata on the\n// constructor, read back by one resolver. The resolver is the only translation\n// point, so the runtime consumes a shape the authoring surface never leaks.\nimport type { HookMeta } from \"../hooks.js\";\nimport { WEBHOOK_EVENTS } from \"./webhook.js\";\nimport type { Container } from \"../container.js\";\n\n/** A hook handler. Returning quietly ALLOWS; throwing DENIES (blocking hooks). */\nexport type HookFn = (event: unknown, meta: HookMeta) => Promise<unknown>;\n\nexport interface ResolvedHookClass {\n /** `@Hook` handlers, by event. A throw here cancels the operation. */\n blocking: Record<string, HookFn>;\n /** `@On` handlers, by event. A throw here reaches nobody but the log. */\n listeners: Record<string, HookFn>;\n}\n\n/** A hook's refusal, with the reason the caller will see.\n *\n * Any thrown error denies — this class exists so the REASON travels as a\n * deliberate message rather than as whatever a stray TypeError happened to say.\n * The engine is fail-closed by design (an unreachable hook denies), so a hook\n * body should stay narrow: an accidental throw refuses a real user. */\nexport class Deny extends Error {\n constructor(reason: string) {\n super(reason);\n this.name = \"Deny\";\n }\n}\n\nexport const HOOK_BLOCKING: unique symbol = Symbol.for(\"palbase.backend.hookBlocking\");\n\ninterface EventEntry {\n event: string;\n fnName: string;\n}\n\n/** `@Hook(\"before.user.create\")` — a blocking handler for one stack event. */\nexport function Hook(event: string) {\n return function (target: object, fnName: string | symbol): void {\n const carrier = (target as { constructor: object }).constructor as Record<symbol, unknown>;\n const existing = carrier[HOOK_BLOCKING] as EventEntry[] | undefined;\n const entries: EventEntry[] = existing ? [...existing] : [];\n entries.push({ event, fnName: String(fnName) });\n Object.defineProperty(carrier, HOOK_BLOCKING, {\n value: entries,\n enumerable: false,\n configurable: true,\n writable: false,\n });\n };\n}\n\n/** Binds one decorator's entries onto a single instance of the class.\n *\n * ONE instance for the whole class, built here rather than per call: a hook\n * that opens a client or reads a list in its constructor would otherwise pay\n * for it on every signup. */\nfunction bind(instance: Record<string, HookFn>, entries: EventEntry[], kind: string) {\n const out: Record<string, HookFn> = Object.create(null) as Record<string, HookFn>;\n for (const entry of entries) {\n if (Object.prototype.hasOwnProperty.call(out, entry.event)) {\n throw new Error(`${kind}(\"${entry.event}\") declared twice on the same hook class`);\n }\n // Resolved ONCE, here, so a decorator naming a method that does not exist\n // fails at build time with the name in the message — rather than at the\n // first signup, as \"instance[fnName] is not a function\".\n const fn = instance[entry.fnName];\n if (typeof fn !== \"function\") {\n throw new Error(`${kind}(\"${entry.event}\") names no method \"${entry.fnName}\" on the class`);\n }\n out[entry.event] = (event, meta) => fn.call(instance, event, meta);\n }\n return out;\n}\n\n/** Resolves a hook class into the two maps the runtime dispatches from.\n *\n * Every misuse throws HERE, at build time, rather than becoming a hook that is\n * silently never called — the failure mode this whole change exists to end.\n *\n * @throws when the class declares constructor parameters (FR-011) — nothing\n * here supplies them, so the field would be `undefined` on every event. */\nexport function getHookConfig(ctor: object, container: Container): ResolvedHookClass {\n const carrier = ctor as Record<symbol, unknown>;\n const blockingEntries = (carrier[HOOK_BLOCKING] ?? []) as EventEntry[];\n const listenerEntries = (carrier[WEBHOOK_EVENTS] ?? []) as EventEntry[];\n\n if (blockingEntries.length === 0 && listenerEntries.length === 0) {\n throw new Error(\n `${(ctor as { name?: string }).name ?? \"a hook class\"} carries no handler — ` +\n \"a hook file must declare at least one @Hook (blocking) or @On (listener) method\",\n );\n }\n\n const instance = container.get(ctor as never) as Record<string, HookFn>;\n return {\n blocking: bind(instance, blockingEntries, \"@Hook\"),\n listeners: bind(instance, listenerEntries, \"@On\"),\n };\n}\n\n/**\n * Which events a hook class declares, and which of them BLOCK.\n *\n * Metadata only — the class is not constructed. Deploy's `hooks.manifest.json`\n * needs exactly this and has no container to build with.\n */\nexport function getHookManifest(ctor: object): { blocking: string[]; listeners: string[] } {\n const carrier = ctor as Record<symbol, unknown>;\n const blockingEntries = (carrier[HOOK_BLOCKING] ?? []) as EventEntry[];\n const listenerEntries = (carrier[WEBHOOK_EVENTS] ?? []) as EventEntry[];\n if (blockingEntries.length === 0 && listenerEntries.length === 0) {\n throw new Error(\n `${(ctor as { name?: string }).name ?? \"a hook class\"} carries no handler — ` +\n \"a hook file must declare at least one @Hook (blocking) or @On (listener) method\",\n );\n }\n return {\n blocking: blockingEntries.map((e) => e.event),\n listeners: listenerEntries.map((e) => e.event),\n };\n}\n","// `@Upload` — the single-method direct-storage upload decorator, and its\n// `@UploadedObject` parameter companion + `UploadConfig`/`UploadedObject` types.\n//\n// Unlike `@Get`/`@Post`/… (where bytes flow THROUGH the br-pod), an `@Upload`\n// route never sees the file bytes: the client uploads DIRECTLY to storage via a\n// signed URL the br-pod mints in an authorize pre-flight. The decorated method\n// body is the COMPLETION handler — it runs once, after storage confirms the\n// object landed (via an HMAC-signed completion webhook), and returns the typed\n// result the client awaits. There is exactly one method: it is BOTH the\n// authorize gate (its uploadConfig drives the guard + signed-URL pinning) AND\n// the completion handler (its body).\n//\n// On the wire the authorize pre-flight is a POST; what marks a route as an\n// upload route through the whole pipeline (registry → flatten → openapi →\n// codegen) is the PRESENCE of `uploadConfig` on the route — never a special HTTP\n// verb. The `@Get`/`@Post`/… decorators never set it.\nimport { recordRoute, recordParam } from \"./registry.js\";\nimport type { RouteOptions } from \"./registry.js\";\nimport type { PalbaseBucketName } from \"../stack.js\";\n\n/** A legacy method decorator (`experimentalDecorators`): `(prototype, name,\n * descriptor)`. */\ntype MethodDecorator = (\n target: object,\n propertyKey: string | symbol,\n descriptor: PropertyDescriptor,\n) => void;\n\n/** A legacy parameter decorator: `(prototype, name, paramIndex)`. */\ntype ParameterDecorator = (\n target: object,\n propertyKey: string | symbol,\n parameterIndex: number,\n) => void;\n\n/**\n * Direct-storage upload settings for an `@Upload` route. The br-pod validates an\n * authorize request against these (size/type), then mints a signed upload URL\n * that PINS the limits so storage itself rejects an over-limit / wrong-type PUT\n * — the client cannot exceed what it declared.\n */\nexport interface UploadConfig {\n /**\n * Target bucket NAME — one the STACK holds.\n *\n * The union comes from the generated `palbase-stack.d.ts`, so a bucket the\n * stack does not carry is a compile error. It used to say \"MUST exist in\n * `config/storage.ts` defineStorage(...)\", and that invariant was carried by\n * this sentence plus a cross-check nothing called; it is carried by the type\n * now.\n *\n * The bucket is the SINGLE SOURCE OF TRUTH for the size limit + MIME allowlist:\n * `bucket({ fileSizeLimit, allowedMimeTypes })`. Storage enforces those at the\n * actual PUT (the only guard a client cannot skip), so `@Upload` deliberately\n * does NOT take its own `maxSize`/`allowedTypes` — duplicating them here would\n * let a route declare a tighter limit than its bucket that storage would not\n * enforce (a real bypass: declare 10 bytes at authorize, then PUT up to the\n * bucket ceiling straight at the signed URL). One bucket, one limit, enforced.\n */\n bucket: PalbaseBucketName;\n /**\n * SERVER-side object key template. The client NEVER chooses the path. Tokens:\n * `{userId}` (authenticated user id), `{uploadId}` (server-minted), and\n * `{filename}` (the client-declared filename, sanitized). e.g.\n * `\"{userId}/{uploadId}-{filename}\"`.\n */\n pathTemplate: string;\n}\n\n/**\n * The uploaded object, injected into an `@Upload` method body by\n * `@UploadedObject()` once storage confirms the upload. Bytes are NOT present\n * (they went straight to storage) — this is the metadata the completion handler\n * persists.\n */\nexport interface UploadedObject {\n /** Server-minted id correlating authorize ↔ completion (idempotency key). */\n uploadId: string;\n /** Final object key in the bucket (rendered from `pathTemplate`). */\n path: string;\n /** Bucket the object landed in. */\n bucket: string;\n /** Object size in bytes, as reported by storage. */\n size: number;\n /** Object MIME type, as reported by storage — detected from the BYTES, not\n * from the filename or from what the client claimed. */\n contentType: string;\n /** SHA-256 of the stored bytes, hex. The same value the object's ETag is\n * derived from, so a client that has it can tell whether it already holds\n * these bytes. */\n checksum: string;\n /** Pixel width, for an image. Absent otherwise — a PDF has no dimensions,\n * and reporting 0 would be a measurement rather than an absence. */\n width?: number;\n /** Pixel height, for an image. */\n height?: number;\n /**\n * A ~25-byte placeholder the client paints INSTANTLY while the real image\n * downloads — the thing that replaces a grey skeleton with something already\n * shaped like the picture. Absent for non-images.\n *\n * Persist it beside the object's path: it costs a column and saves a request\n * per picture on every gallery render.\n */\n thumbhash?: string;\n /**\n * The renditions the bucket declared, by name, as URLs ready to use.\n *\n * Present on the completion input so the handler that stores the row has\n * everything it needs in one place — asking for them afterwards would be a\n * second call per upload, and per picture on every read.\n */\n variants: Record<string, string>;\n}\n\n/**\n * `@Upload(subpath, config)` — declare a direct-storage upload route. The method\n * body is the completion handler; `config.uploadConfig` drives the authorize\n * guard + signed-URL pinning.\n *\n * @example\n * @Upload(\"/\", { bucket: \"docs\", pathTemplate: \"{userId}/{uploadId}-{filename}\" })\n * async upload(@UploadedObject() obj: UploadedObject, @User() user): Promise<DocResult> { ... }\n * // The size limit + MIME allowlist come from the \"docs\" bucket ON THE STACK\n * // — storage enforces them at the PUT.\n */\nexport function Upload(\n subpath: string,\n config: UploadConfig & Pick<RouteOptions, \"auth\" | \"rateLimit\">,\n): MethodDecorator {\n const { auth, rateLimit, ...uploadConfig } = config;\n validateUploadConfigShape(uploadConfig);\n const options: RouteOptions = {\n uploadConfig,\n ...(auth !== undefined ? { auth } : {}),\n ...(rateLimit !== undefined ? { rateLimit } : {}),\n };\n return function (target, propertyKey) {\n // On the wire the authorize pre-flight is a POST; `uploadConfig` is what\n // marks this as an upload route downstream.\n recordRoute(target, String(propertyKey), \"POST\", subpath, options);\n };\n}\n\n/**\n * `@UploadedObject()` — inject the uploaded object (`: UploadedObject`) into an\n * `@Upload` method body (the completion input). Only valid on an `@Upload`\n * route; the bytes are NOT present (they went directly to storage), this is the\n * confirmed object's metadata.\n *\n * Co-located with the {@link UploadedObject} TYPE so a single exported name\n * `UploadedObject` carries BOTH the decorator value and the type annotation.\n */\nexport function UploadedObject(): ParameterDecorator {\n return function (target, propertyKey, parameterIndex) {\n recordParam(target, String(propertyKey), {\n index: parameterIndex,\n kind: \"uploadedObject\",\n });\n };\n}\n\n/**\n * Shape-validate an UploadConfig at decoration time (author-time failure beats a\n * silent deploy bug). Does NOT check that the bucket EXISTS — the generated\n * `palbase-stack.d.ts` union does that, and it does it at compile time rather\n * than at deploy.\n */\nexport function validateUploadConfigShape(c: UploadConfig): void {\n if (c === null || typeof c !== \"object\") {\n throw new Error(\"@Upload config must be an object { bucket, pathTemplate, ... }\");\n }\n // Read the bucket through a WIDENED view on purpose. Its declared type is\n // `PalbaseBucketName`, which is `never` until the project generates\n // `palbase-stack.d.ts` — and `never.length` does not typecheck. This function\n // is a RUNTIME guard against a shape the compiler never saw (a plain-JS\n // caller, a bundle boundary), so the value arriving here is genuinely unknown\n // and reading it as such is the honest signature, not a cast to dodge an error.\n const bucket: unknown = (c as { bucket?: unknown }).bucket;\n if (typeof bucket !== \"string\" || bucket.length === 0) {\n throw new Error(\"@Upload config.bucket must be a non-empty bucket name\");\n }\n if (typeof c.pathTemplate !== \"string\" || c.pathTemplate.length === 0) {\n throw new Error(\"@Upload config.pathTemplate must be a non-empty key template\");\n }\n}\n\n","// `@Sse` — the streaming-response decorator, and its `@SseOut` / `@Signal`\n// parameter companions.\n//\n// Unlike `@Get`/`@Post`/… (where the handler's RETURN VALUE is serialised to\n// JSON), an `@Sse` route's method body WRITES frames as it goes and its return\n// value is discarded. The response is `text/event-stream` and stays open until\n// the body returns or the client disconnects.\n//\n// On the wire an `@Sse` route is a POST — a stream is started by a request that\n// carries input. What marks it as a streaming route through the whole pipeline\n// (registry → flatten → openapi → codegen) is the PRESENCE of `sseConfig` on the\n// route, NEVER the verb: an ordinary `@Post` route is also POST, so the verb\n// cannot carry the distinction. This is the same rule `@Upload` states, for the\n// same reason.\n//\n// The problem this solves: a provider on the server (an AI client, a job queue,\n// any long-running producer) streams from a session; while a client is connected\n// the frames reach it, and when the client disconnects the provider must stop\n// being pulled. That last half is what `@Signal()` exists for.\nimport { recordRoute, recordParam } from \"./registry.js\";\nimport type { RouteOptions } from \"./registry.js\";\nimport type { ZodTypeAny } from \"zod\";\n\n/** A legacy method decorator (`experimentalDecorators`): `(prototype, name,\n * descriptor)`. */\ntype MethodDecorator = (\n target: object,\n propertyKey: string | symbol,\n descriptor: PropertyDescriptor,\n) => void;\n\n/** A legacy parameter decorator: `(prototype, name, paramIndex)`. */\ntype ParameterDecorator = (\n target: object,\n propertyKey: string | symbol,\n parameterIndex: number,\n) => void;\n\n/**\n * Settings for an `@Sse` route.\n *\n * EMPTY in v1, and deliberately so: the pipeline keys off this object's\n * PRESENCE, not its contents (see the file header). Declaring the type now means\n * a later setting arrives as a field on an existing marker rather than as a\n * second marker nothing downstream reads.\n */\nexport interface SseConfig {\n /**\n * The shape of ONE frame — what a single `out.write(value)` carries.\n *\n * REQUIRED, not optional, and that is the whole point. An `@Sse` handler\n * returns `Promise<void>`, so the codegen-injected `recordReturn` has no type\n * to record and nothing downstream can infer what a frame is. A route without\n * this declares a stream whose element type is unknown, and every generated\n * client from that contract is opaque — which is precisely the failure\n * `x-palbase-sse` exists to prevent. Making it optional would have left that\n * failure one forgotten field away.\n *\n * Measured live on a real pushed stack (2026-08-29): the contract gate refused\n * the deploy with \"2 untyped response(s) — every generated client from it is\n * opaque\", naming both routes that omitted it.\n */\n frame: ZodTypeAny;\n}\n\n/**\n * The writer injected by `@SseOut()`. Each `write` emits ONE SSE `data:` frame\n * carrying `value` JSON-encoded.\n *\n * The FIRST `write` is load-bearing beyond its frame: it settles the request's\n * database transaction. A streaming response may run for minutes, and the\n * handler runs inside the request's transaction — holding one open for the life\n * of a stream exhausts the connection pool, a failure invisible to a unit test\n * that only dies under load. So the first frame is the point at which the\n * request phase is declared over, and database access after it is refused by\n * name rather than silently run against a settled transaction.\n *\n * The practical rule for a handler: do the database work BEFORE the first write.\n */\nexport interface SseWriter {\n write(value: unknown): void;\n}\n\n/**\n * `@Sse(subpath, config)` — declare a streaming route.\n *\n * @example\n * @Sse(\"/chat\", { frame: ChatFrame })\n * async chat(@Body() b: ChatInput, @SseOut() out: SseWriter, @Signal() signal: AbortSignal) {\n * const stream = await openai.chat.completions.create(\n * { model: \"gpt-5.6\", messages: b.messages, stream: true },\n * { signal },\n * );\n * for await (const chunk of stream) out.write(chunk);\n * }\n * // The client disconnects → `signal` aborts → the provider stops being pulled.\n * // The signal is a plain AbortSignal, so it goes wherever the provider takes\n * // one: `{ signal }` for the OpenAI and Anthropic SDKs, `abortSignal:` for the\n * // Vercel AI SDK, `fetch(url, { signal })` for a raw call.\n */\nexport function Sse(\n subpath = \"\",\n config: SseConfig & Pick<RouteOptions, \"auth\" | \"rateLimit\">,\n): MethodDecorator {\n const { auth, rateLimit, ...sseConfig } = config;\n const options: RouteOptions = {\n sseConfig,\n ...(auth !== undefined ? { auth } : {}),\n ...(rateLimit !== undefined ? { rateLimit } : {}),\n };\n return function (target, propertyKey) {\n recordRoute(target, String(propertyKey), \"POST\", subpath, options);\n };\n}\n\n/**\n * `@SseOut()` — inject the frame writer (`: SseWriter`) into an `@Sse` method\n * body. Only meaningful on an `@Sse` route.\n */\nexport function SseOut(): ParameterDecorator {\n return function (target, propertyKey, parameterIndex) {\n recordParam(target, String(propertyKey), { index: parameterIndex, kind: \"sseOut\" });\n };\n}\n\n/**\n * `@Signal()` — inject the request's `AbortSignal`, which enters the aborted\n * state when the client disconnects.\n *\n * NOT derivable from `@Req()`: `PBRequest` carries only request-scoped data —\n * the typed input, route/query params, headers, the authenticated user, calling\n * client metadata, trace ids, and the declared error throwers — and no signal\n * (endpoint.ts:358-363).\n *\n * Measured 2026-08-29 on Bun: an infinite producer guarded by this signal\n * stopped four frames after the client was killed, and the handler's `finally`\n * ran. It is the same mechanism a NestJS handler reaches through\n * `req.on(\"close\")`.\n */\nexport function Signal(): ParameterDecorator {\n return function (target, propertyKey, parameterIndex) {\n recordParam(target, String(propertyKey), { index: parameterIndex, kind: \"signal\" });\n };\n}\n","// @Room — the realtime surface a backend can actually MANAGE.\n//\n// palbase's realtime lets a backend TALK (broadcast, state.set, push.send) and\n// lets it INTERCEPT a client's publish (defineChannels' handler). What it never\n// let a backend do is SEE the connection: who joined, who left, whether anyone\n// is still watching. A room is that missing half, in the shape this SDK already\n// uses for HTTP — a class with decorated methods.\n//\n// The cost of the gap was concrete: nothing could tell a project that the last\n// device left, so an expensive upstream (an AI session, a market feed, a game\n// loop) kept running and kept billing with nobody reading it. `@OnFirst` and\n// `@OnEmpty` exist for exactly that pair of moments.\n//\n// WHAT A ROOM IS NOT: it does not know where the room id came from, what the\n// history is, or what `@OnFirst` starts. All three belong to the project. The\n// primitive is infrastructure; it carries messages both ways and reports who is\n// present.\n\nimport type { ZodTypeAny } from \"zod\";\nimport {\n recordRoom,\n recordRoomHook,\n recordRoomMessage,\n type RoomHook,\n} from \"./registry.js\";\n\nexport interface RoomOptions {\n /**\n * The events this room sends to its clients, by name.\n *\n * Declared rather than inferred, because a room emits from anywhere in the\n * class — there is no return type to read. The map is the room's public\n * surface: it becomes a Swift enum and a TypeScript union in the generated\n * clients, so a device gets `case .tick(n:)` instead of an opaque bag.\n *\n * Per-event rather than one blob because realtime is event-ADDRESSED all the\n * way down (`Realtime.broadcast(channel, EVENT, payload)`).\n */\n events: Record<string, ZodTypeAny>;\n\n /**\n * How long a room is held after its last sign of life, in milliseconds.\n *\n * Default 60_000, and the floor is not a matter of taste: the decision must\n * survive the SLOWEST client's heartbeat gap twice over, and the web SDK\n * beats every 25 s (palbe/src/realtime/connection.ts:133) against iOS's 2 s\n * (RealtimeConnection.swift:162). A shorter default would declare healthy web\n * clients dead between two beats.\n *\n * Raise it for an upstream that is expensive to restart; lower it (never\n * below ~50 s while web beats at 25 s) for one that is cheap.\n */\n graceMs?: number;\n}\n\n/** Twice the slowest client heartbeat, plus margin. See RoomOptions.graceMs. */\nconst DEFAULT_GRACE_MS = 60_000;\n\n/**\n * A room pattern IS a channel pattern, so it obeys the channel matcher's rules.\n *\n * Both ends of the wire split on `:` — Go's `matchPattern`\n * (internal/modules/rt/channels.go) and this SDK's `matchDeclared` — so a\n * pattern written with slashes matches NO live topic. It fails silently: the\n * room compiles, ships, and simply never fires. Refused here, by name, at the\n * only moment a human is looking.\n *\n * The duplicate-param rule is carried over for the reason channels.ts states:\n * `dm:{uid}:{uid}` against `dm:victim:attacker` lets the last segment win, and\n * an owner check then compares the attacker's id with itself and passes.\n */\nfunction assertPattern(pattern: string): void {\n if (pattern.includes(\"/\")) {\n throw new Error(\n `@Room(\"${pattern}\"): channel patterns are colon-separated, not slash-separated. ` +\n `Write \"${pattern.replace(/\\//g, \":\")}\" — a slash matches no live topic.`,\n );\n }\n const segments = pattern.split(\":\");\n if (segments.some((s) => s === \"\")) {\n throw new Error(`@Room(\"${pattern}\"): empty segment — every segment must be non-empty.`);\n }\n const seen = new Set<string>();\n for (const s of segments) {\n if (!s.startsWith(\"{\") || !s.endsWith(\"}\")) continue;\n const name = s.slice(1, -1);\n if (name === \"\") throw new Error(`@Room(\"${pattern}\"): \"{}\" names no parameter.`);\n if (seen.has(name)) {\n throw new Error(`@Room(\"${pattern}\"): parameter \"{${name}}\" appears twice.`);\n }\n seen.add(name);\n }\n}\n\n/**\n * Declare a class as a room.\n *\n * ```ts\n * @Room(\"chat:{roomId}\", { events: { message: Message } })\n * class ChatRoom {\n * @OnAuthorize() can({ user, params }) { … }\n * @OnFirst() open(ctx) { … } // the room filled\n * @OnEmpty() close(ctx) { … } // nobody is watching any more\n * @OnMessage(\"say\", Say) say(ctx) { … }\n * }\n * ```\n *\n * The pattern is the topic: `chat:{roomId}` addresses `chat:42`. A room is\n * marked by the PRESENCE of this config — never by a name, a base class or a\n * naming convention.\n */\nexport function Room(pattern: string, options: RoomOptions) {\n return function <T extends abstract new (...args: never[]) => object>(ctor: T): T {\n assertPattern(pattern);\n // Member decorators have already run (TypeScript evaluates members before\n // the class), so the hook buffer is complete here and `recordRoom` drains\n // it. controller.ts:203 documents and depends on the same ordering.\n recordRoom(ctor, {\n pattern,\n events: options.events,\n graceMs: options.graceMs ?? DEFAULT_GRACE_MS,\n });\n return ctor;\n };\n}\n\nfunction hookDecorator(hook: RoomHook): () => MethodDecorator {\n return () =>\n function (target: object, propertyKey: string | symbol): void {\n recordRoomHook(target, hook, String(propertyKey));\n };\n}\n\n/** Who may enter. Return a grant to admit, `null` to refuse. */\nexport const OnAuthorize = hookDecorator(\"authorize\");\n\n/**\n * The room is occupied and nobody owns it — start whatever the room needs.\n *\n * Deliberately a CONDITION rather than a 0→1 transition, and the difference is\n * load-bearing: a runtime restart, a deploy pointer swap (the previous release\n * is never torn down) and an owner that died all leave a full room with nobody\n * holding it. A transition would fire once and never again; a condition\n * recovers every time.\n *\n * Exactly one runtime in the cluster enters this hook for a given room, so\n * three devices never open three upstreams.\n */\nexport const OnFirst = hookDecorator(\"first\");\n\n/** A device arrived. Anything emitted here reaches ONLY that device. */\nexport const OnJoin = hookDecorator(\"join\");\n\n/** A device left. */\nexport const OnLeave = hookDecorator(\"leave\");\n\n/** Nobody is watching any more — stop whatever `@OnFirst` started. */\nexport const OnEmpty = hookDecorator(\"empty\");\n\n/**\n * A message from a client, validated against `schema` before the method runs.\n *\n * A payload that fails the schema never reaches the method: the client is told\n * why, and the room's code only ever sees the shape it declared.\n */\nexport function OnMessage(name: string, schema: ZodTypeAny): MethodDecorator {\n return function (target: object, propertyKey: string | symbol): void {\n recordRoomMessage(target, name, String(propertyKey), schema);\n };\n}\n","// Parameter decorators: `@Body` / `@QueryParams` / `@Param` / `@Headers` / `@User` /\n// `@OptionalUser` / `@Client` / `@RequestId` / `@TraceId` / `@Req`. Each records\n// `{ index, kind, schema?, name? }` into the per-class registry for the method\n// it decorates. These are LEGACY parameter decorators\n// (`experimentalDecorators`), receiving `(prototype, methodName, paramIndex)` —\n// esbuild/tsc preserve the param index at runtime (verified, design §0), which\n// is how dispatch injects positionally. No type reflection\n// (`emitDecoratorMetadata`) is used: validation comes from the zod schema, the\n// type annotation the developer writes is purely for autocomplete.\nimport type { ZodTypeAny } from \"zod\";\nimport { recordParam, type ParamKind } from \"./registry.js\";\n\n/** A legacy parameter decorator. */\ntype ParameterDecorator = (\n target: object,\n propertyKey: string | symbol,\n parameterIndex: number,\n) => void;\n\n/** Build a parameter decorator that records the given kind (+ optional schema /\n * name) at the decorated parameter's index. */\nfunction makeParamDecorator(\n kind: ParamKind,\n extra?: { schema?: ZodTypeAny; name?: string },\n): ParameterDecorator {\n return function (target, propertyKey, parameterIndex) {\n recordParam(target, String(propertyKey), {\n index: parameterIndex,\n kind,\n ...(extra?.schema !== undefined ? { schema: extra.schema } : {}),\n ...(extra?.name !== undefined ? { name: extra.name } : {}),\n });\n };\n}\n\n/** `@Body(schema)` — inject the request body, validated against `schema`. The\n * developer writes `: T` (= `z.infer<schema>`, same name) for autocomplete. */\nexport function Body(schema: ZodTypeAny): ParameterDecorator {\n return makeParamDecorator(\"body\", { schema });\n}\n\n/** `@QueryParams(schema)` — inject the parsed query params, validated against\n * `schema`. */\nexport function QueryParams(schema: ZodTypeAny): ParameterDecorator {\n return makeParamDecorator(\"query\", { schema });\n}\n\n/** `@Headers(schema?)` — inject the request headers (lowercase keys). With a\n * schema, headers are validated + the codegen emits header parameters. */\nexport function Headers(schema?: ZodTypeAny): ParameterDecorator {\n return makeParamDecorator(\"headers\", schema !== undefined ? { schema } : undefined);\n}\n\n/** `@Param(\"id\")` — inject one matched path param by name. */\nexport function Param(name: string): ParameterDecorator {\n return makeParamDecorator(\"param\", { name });\n}\n\n/** `@User()` — inject the authenticated user (`: User`, non-null for an\n * effective-required route). The runtime resolves the effective auth. */\nexport function User(): ParameterDecorator {\n return makeParamDecorator(\"user\");\n}\n\n/** `@OptionalUser()` — inject the user as `User | null` (for routes whose\n * effective auth is `false` / `{ required: false }`). */\nexport function OptionalUser(): ParameterDecorator {\n return makeParamDecorator(\"optionalUser\");\n}\n\n/** `@Client()` — inject the parsed calling-client metadata (`: ClientInfo`). */\nexport function Client(): ParameterDecorator {\n return makeParamDecorator(\"client\");\n}\n\n/** `@RequestId()` — inject the per-request id (`: string`). */\nexport function RequestId(): ParameterDecorator {\n return makeParamDecorator(\"requestId\");\n}\n\n/** `@TraceId()` — inject the W3C trace id (`: string`). */\nexport function TraceId(): ParameterDecorator {\n return makeParamDecorator(\"traceId\");\n}\n\n/** `@Req()` — inject the raw request object (escape hatch, `: PBRequest`). */\nexport function Req(): ParameterDecorator {\n return makeParamDecorator(\"req\");\n}\n\n// NOTE: `@UploadedObject()` lives in decorators/upload.ts (co-located with the\n// `UploadedObject` TYPE) so a single exported name carries both the value (the\n// decorator) and the type — TS can only merge value+type under one export name\n// when both are declared in the SAME module.\n","import type { DBClient, Logger, CacheClient, PalbaseModuleClients } from \"./endpoint.js\";\nimport type { User } from \"./types.js\";\n\n/** Middleware context — subset of EndpointContext without input (not yet validated). */\nexport interface MiddlewareContext extends PalbaseModuleClients {\n params: Record<string, string>;\n query: Record<string, string>;\n headers: Record<string, string>;\n user: User | null;\n db: DBClient;\n env: Record<string, string>;\n log: Logger;\n cache: CacheClient;\n requestId: string;\n environmentId: string;\n}\n\n/** Middleware function signature — receives context and next function. */\nexport type MiddlewareHandler = (\n ctx: MiddlewareContext,\n next: () => Promise<void>,\n) => Promise<void>;\n\n/**\n * REMOVED IN BEHAVIOUR, KEPT IN NAME.\n *\n * There is no middleware pipeline in this runtime. No bundler reads a\n * `middleware/` directory, the engine never calls a handler defined here, and\n * measured on 2026-08-31 this function had no caller anywhere in the runtime or\n * the CLI. It returned its argument unchanged, so code written against it\n * compiled, deployed, and then never ran — with nothing reporting that.\n *\n * A silent shell is the worst version of a retired feature: it lets a user (or a\n * coding assistant, which is how this surfaced) ship a request logger, an auth\n * check or a rate limiter that simply does not exist in production. So the call\n * refuses, and says where the work belongs.\n *\n * The SYMBOL survives because removing a published export costs a major and\n * 25.0.1 had just shipped. Deleting it is a proposal for the next one; the types\n * below stay either way, so a file that only annotates with them still compiles.\n *\n * This is the shape the SDK already uses for a retired surface: `@Query(schema)`\n * on a parameter throws at decoration time with a message naming its\n * replacement.\n */\nexport function defineMiddleware(_fn: MiddlewareHandler): never {\n throw new Error(\n \"defineMiddleware() is not wired to anything: no bundler reads a `middleware/` \" +\n \"directory and the engine has no middleware pipeline, so a handler defined \" +\n \"here deploys and never runs. Put cross-cutting work in a service the \" +\n \"controllers call, and use route options for auth (`@Controller(path, { auth })`) \" +\n \"and rate limits (`@Get(path, { rateLimit })`).\",\n );\n}\n","/** Non-service, per-invocation data for job handlers.\n * Services (Database, Log, …) are imported as singletons, not passed here. */\nexport interface JobMeta {\n /** Environment-scoped env vars. */\n env: Record<string, string>;\n /** The globally unique Environment runtime identifier. */\n environmentId: string;\n}\n\n/**\n * Cron expression validation.\n * Supports standard 5-field cron: minute hour day-of-month month day-of-week.\n * Each field allows: number, *, ranges (1-5), steps (star/2), lists (1,3,5).\n */\nexport function validateCronExpression(expression: string): string | null {\n const trimmed = expression.trim();\n if (trimmed === \"\") {\n return \"Cron expression is required\";\n }\n\n const parts = trimmed.split(/\\s+/);\n if (parts.length !== 5) {\n return `Invalid cron expression \"${trimmed}\": expected 5 fields (minute hour day month weekday), got ${parts.length}`;\n }\n\n const fieldNames = [\"minute\", \"hour\", \"day of month\", \"month\", \"day of week\"];\n const fieldRanges: [number, number][] = [\n [0, 59],\n [0, 23],\n [1, 31],\n [1, 12],\n [0, 7],\n ];\n\n for (let i = 0; i < 5; i++) {\n const field = parts[i]!;\n const name = fieldNames[i]!;\n const [min, max] = fieldRanges[i]!;\n\n const error = validateCronField(field, name, min, max);\n if (error !== null) {\n return error;\n }\n }\n\n return null;\n}\n\nfunction validateCronField(\n field: string,\n name: string,\n min: number,\n max: number,\n): string | null {\n // Split by comma for lists\n const listParts = field.split(\",\");\n for (const part of listParts) {\n // Check for step: */2, 1-5/2\n const stepParts = part.split(\"/\");\n if (stepParts.length > 2) {\n return `Invalid ${name} field: \"${field}\"`;\n }\n\n const base = stepParts[0]!;\n const step = stepParts[1];\n\n if (step !== undefined) {\n const stepNum = Number(step);\n if (!Number.isInteger(stepNum) || stepNum < 1) {\n return `Invalid step value in ${name} field: \"${field}\"`;\n }\n }\n\n if (base === \"*\") {\n continue;\n }\n\n // Check for range: 1-5\n if (base.includes(\"-\")) {\n const rangeParts = base.split(\"-\");\n if (rangeParts.length !== 2) {\n return `Invalid range in ${name} field: \"${field}\"`;\n }\n const rangeStart = Number(rangeParts[0]);\n const rangeEnd = Number(rangeParts[1]);\n if (\n !Number.isInteger(rangeStart) ||\n !Number.isInteger(rangeEnd) ||\n rangeStart < min ||\n rangeEnd > max ||\n rangeStart > rangeEnd\n ) {\n return `Invalid range in ${name} field: \"${field}\"`;\n }\n continue;\n }\n\n // Single number\n const num = Number(base);\n if (!Number.isInteger(num) || num < min || num > max) {\n return `Invalid value in ${name} field: \"${field}\"`;\n }\n }\n\n return null;\n}\n","// @Job — the cron half of the decorator surface. Same metadata mechanism as\n// @Webhook/@Controller. The job's NAME is not here on purpose: it is the file\n// name, which is also what the Temporal schedule id is built from. Two names\n// with nothing reconciling them is what this replaces.\nimport type { JobMeta } from \"../job.js\";\nimport { validateCronExpression } from \"../job.js\";\nimport type { Container } from \"../container.js\";\nimport { assertSurfaceName } from \"./surface-name.js\";\n\nexport interface JobOptions {\n /**\n * The job's identity, and the name the scheduler holds its rows under.\n *\n * DECLARED, not derived. It used to be the file's name, which made the\n * identity a property of where the class sat — rename the file and the\n * scheduler starts a different job. Ownership and identity both come from a\n * declaration now, and this is where a reader looks for it.\n *\n * Lowercase, digits and dashes: it reaches a scheduler row and a log line.\n */\n name: string;\n /** Cron expression, five fields (e.g. \"0 3 * * *\"). */\n schedule: string;\n /** Execution timeout in seconds. Defaults to 30, ceiling 300 (sandbox limit). */\n timeout?: number;\n /**\n * How many times a FAILED run is retried before the run is recorded failed.\n * Defaults to 5, ceiling 10; 0 disables retrying entirely.\n *\n * Retries exist for the transient half of the failure space — the runtime\n * still waking, a network blip — not for a job that is wrong. A permanent\n * failure still lands in the run history, it just lands after the retries\n * are spent rather than instead of them.\n */\n retry?: number;\n}\n\nexport interface ResolvedJob {\n /** The declared identity — the scheduler's row name. */\n name: string;\n schedule: string;\n timeout: number;\n retry: number;\n handler: (meta: JobMeta) => Promise<void>;\n}\n\nconst DEFAULT_TIMEOUT_SECONDS = 30;\nconst MAX_TIMEOUT_SECONDS = 300;\nconst DEFAULT_RETRY = 5;\nconst MAX_RETRY = 10;\n\nexport const JOB_META: unique symbol = Symbol.for(\"palbase.backend.jobMeta\");\n\ninterface JobCarrier {\n __palbase?: \"job\";\n [JOB_META]?: JobOptions;\n}\n\nexport function Job(options: JobOptions) {\n return function <T extends abstract new (...args: never[]) => object>(ctor: T): T {\n const carrier = ctor as unknown as JobCarrier;\n Object.defineProperty(carrier, JOB_META, {\n value: options,\n enumerable: false,\n configurable: true,\n writable: false,\n });\n Object.defineProperty(carrier, \"__palbase\", {\n value: \"job\",\n enumerable: false,\n configurable: true,\n writable: false,\n });\n return ctor;\n };\n}\n\n/**\n * What a job DECLARES — schedule, timeout, retry. Reads metadata and nothing\n * else: the class is NOT constructed.\n *\n * Deploy's manifest script needs exactly this and no instance (stack_bundle.go\n * writes `jobs.manifest.json` from it, with no runtime and therefore no\n * container). Constructing a class to read a cron string was a side effect, and\n * it is the side effect that made the container look optional — which in turn\n * let a caller that never passes one compile quietly.\n */\nexport interface JobManifest {\n name: string;\n schedule: string;\n timeout: number;\n retry: number;\n}\n\nexport function getJobManifest(ctor: object): JobManifest {\n const meta = (ctor as JobCarrier)[JOB_META];\n if (!meta) {\n throw new Error(\n `getJobConfig on a class with no @Job decorator (${(ctor as { name?: string }).name ?? \"anonymous\"})`,\n );\n }\n assertSurfaceName(meta.name, \"@Job\", \"job\");\n if (!meta.schedule || meta.schedule.trim() === \"\") {\n throw new Error(\"@Job requires a `schedule` cron expression\");\n }\n const cronError = validateCronExpression(meta.schedule);\n if (cronError) {\n throw new Error(`@Job has an invalid cron schedule: ${cronError}`);\n }\n\n const timeout = meta.timeout ?? DEFAULT_TIMEOUT_SECONDS;\n if (!Number.isInteger(timeout) || timeout <= 0) {\n throw new Error(\"@Job `timeout` must be a positive whole number of seconds\");\n }\n if (timeout > MAX_TIMEOUT_SECONDS) {\n throw new Error(`@Job \\`timeout\\` exceeds the ${MAX_TIMEOUT_SECONDS}s sandbox ceiling`);\n }\n\n const retry = meta.retry ?? DEFAULT_RETRY;\n if (!Number.isInteger(retry) || retry < 0) {\n throw new Error(\"@Job `retry` must be a whole number of attempts, zero or more\");\n }\n if (retry > MAX_RETRY) {\n throw new Error(`@Job \\`retry\\` exceeds the ceiling of ${MAX_RETRY}`);\n }\n\n return { name: meta.name, schedule: meta.schedule, timeout, retry };\n}\n\n/**\n * The job, ready to run — manifest plus a bound `run`.\n *\n * `container` is REQUIRED. It used to be absent (the class was built with\n * `new`), and then briefly optional, which is worse: an optional parameter lets\n * a caller that forgot it compile, and the job would receive `undefined` for\n * every dependency at its first scheduled run, hours after deploy, in a process\n * nobody is watching. Required makes the two runtime call sites a TYPE error.\n */\nexport function getJobConfig(ctor: object, container: Container): ResolvedJob {\n const { name, schedule, timeout, retry } = getJobManifest(ctor);\n\n const instance = container.get(ctor as never) as { run?: (meta: JobMeta) => Promise<void> };\n if (typeof instance.run !== \"function\") {\n throw new Error(\"@Job class must declare an async run() method\");\n }\n const run = instance.run.bind(instance);\n\n return { name, schedule, timeout, retry, handler: run };\n}\n","export type {\n PBRequest,\n ClientInfo,\n RateLimitConfig,\n DBClient,\n DBOps,\n FileContext,\n Logger,\n CacheClient,\n SecretsService,\n PalbaseDocsClient,\n PalbaseCollectionRef,\n PalbaseDocumentRef,\n PalbaseDocumentSnapshot,\n PalbaseQuerySnapshot,\n PalbaseWhereOperator,\n PalbaseResult,\n Middleware,\n ErrorDef,\n ErrorMap,\n ErrorThrowers,\n} from \"./endpoint.js\";\nexport {\n Database,\n Auth,\n Documents,\n Storage,\n Cache,\n Secrets,\n Log,\n Notifications,\n Flags,\n Realtime,\n __setRuntime,\n __runWithRuntime,\n __requestALS,\n __getRuntime,\n // Where a long-lived resource lives: opened once as the app comes up, closed\n // when it goes away. `__runStartHooks` is the engine's door to them (it\n // CLAIMS the declarations, so a candidate release loaded beside the live one\n // never closes the live one's pool); `__resetLifecycleHooks` is for tests.\n onStart,\n onShutdown,\n __runStartHooks,\n __resetLifecycleHooks,\n} from \"./runtime.js\";\nexport type {\n RuntimeServices,\n RequestStore,\n LifecycleHook,\n ShutdownRunner,\n} from \"./runtime.js\";\n\n// The module clients and their composition root. The PROCESS calls\n// buildModuleClients once at boot and hands the result to createApp — which is\n// the whole reason this package now contains the implementations and not just\n// the interfaces they were being checked against by nobody.\nexport { buildModuleClients } from \"./clients/index.js\";\nexport type { ModuleClientsConfig } from \"./clients/index.js\";\nexport { makeHttpClient, PalbaseModuleError } from \"./clients/http.js\";\n// The one named refusal the role surface raises. Exported because a handler\n// branches on it: a role name that misses is a typo in committed code.\nexport { RoleNotDefined } from \"./clients/auth.js\";\nexport type { ModuleTransport, RequestOptions, TransportConfig } from \"./clients/http.js\";\n\nexport type {\n PalbaseAuthClient,\n PalbaseAuthAdminClient,\n PalbaseStorageClient,\n PalbaseBucketClient,\n PalbaseRealtimeClient,\n PalbaseFunctionsClient,\n PalbaseInvokeOptions,\n PalbaseFlagsClient,\n PalbaseFlagsServiceClient,\n PalbaseFlagContext,\n PalbaseFlagVariant,\n PalbaseFlag,\n PalbaseFlagValue,\n PalbaseFlagSource,\n PalbaseSetOverrideResult,\n PalbaseSetOverridesResult,\n PalbaseClearOverrideResult,\n PalbaseClearAllOverridesResult,\n PalbaseBatchOverrideOperation,\n PalbaseBatchSetOverridesResult,\n PalbaseNotificationsClient,\n PalbasePushClient,\n PalbaseEmailClient,\n PalbaseSmsClient,\n PalbaseWhatsAppClient,\n PalbaseInboxClient,\n PalbasePreferencesClient,\n PalbaseAnalyticsClient,\n PalbaseAnalyticsQueryNamespace,\n PalbaseAnalyticsManagementNamespace,\n PalbaseLinksClient,\n // Shared local types\n PalbaseUser,\n PalbaseSession,\n PalbaseDeviceInfo,\n PalbaseAttestAndroidParams,\n PalbaseAttestAndroidResult,\n PalbaseAttestiOSParams,\n PalbaseAttestiOSResult,\n PalbaseBindDeviceParams,\n PalbaseVerifyRequestSignatureParams,\n PalbaseFileObject,\n PalbaseSignedUrlResponse,\n PalbaseUploadOptions,\n PalbaseTransformOptions,\n PalbaseListOptions,\n PalbasePushSendParams,\n PalbasePushSendResponse,\n PalbaseEmailSendParams,\n PalbaseEmailSendResponse,\n PalbaseSmsSendParams,\n PalbaseSmsSendResponse,\n PalbaseWhatsAppTemplate,\n PalbaseWhatsAppSendParams,\n PalbaseWhatsAppSendResponse,\n PalbaseWhatsAppEvent,\n PalbaseInboxSendParams,\n PalbaseInboxSendResponse,\n PalbaseInboxMessage,\n PalbaseInboxListOptions,\n PalbaseInboxListResult,\n PalbasePreferences,\n PalbaseNotificationChannel,\n PalbaseRegisterDeviceParams,\n PalbaseDeviceTokenView,\n PalbaseMultiChannelResponse,\n PalbaseAnalyticsProperties,\n PalbaseIdentifyTraits,\n PalbaseCountQueryInput,\n PalbaseCountResult,\n PalbaseEventsQueryInput,\n PalbaseEventsResult,\n PalbaseUsersQueryInput,\n PalbaseUsersResult,\n PalbaseFunnelQueryInput,\n PalbaseFunnelResult,\n PalbaseRetentionQueryInput,\n PalbaseRetentionResult,\n PalbaseCohortQueryInput,\n PalbaseCohortResult,\n PalbaseOverviewResult,\n PalbaseEventNamesResult,\n PalbaseUserDetailResult,\n PalbaseCreateLinkParams,\n PalbaseUpdateLinkParams,\n PalbaseLink,\n PalbaseLinkDetails,\n PalbaseLinkAnalytics,\n PalbaseQrCodeOptions,\n PalbaseMatchParams,\n PalbaseInitialLink,\n PalbaseListLinksOptions,\n PalbaseListLinksResult,\n} from \"./clients.js\";\nexport { defineSchema, defineTable, TABLE_META, index, IndexBuilder, foreignKey, freeze, guard, backfill } from \"./db/schema.js\";\nexport type { ForeignKeyBuilder, ForeignKeyDef, FkAction, FkMatch, FreezeBuilder, FreezeDef } from \"./db/foreign-key.js\";\nexport type { GuardBuilder, GuardDef, GuardEvent } from \"./db/guard.js\";\nexport type { BackfillDef } from \"./db/backfill.js\";\n// The declaration as DATA — what the deploy reads to build the database. The\n// bundler calls this; a project never has to.\nexport { toSchemaJSON } from \"./db/schema-json.js\";\nexport type { SchemaJSON, TableJSON, ColumnJSON, PolicyJSON, ForeignKeyJSON, FreezeJSON, GuardJSON, BackfillJSON } from \"./db/schema-json.js\";\n// `SchemaInput` is NOT here. It typed the retired dictionary form —\n// `defineSchema({ tables: { todos: { columns } } })` — which `defineSchema`\n// now refuses by name (FR-061), so nothing can be assigned to it and nothing\n// ever imported it. Publishing the type of a shape the code rejects is a\n// second way in that only exists in the editor: its JSDoc taught the old\n// layout to anyone who hovered it.\nexport type { SchemaDef, TableDef, TableInput, ColumnMap, TableHandle, IndexDef } from \"./db/schema.js\";\nexport { policy, can, check, PolicyBuilder, PolicyExprRef, exprCtx } from \"./db/policy.js\";\n// `TableRef` bir tablo bildiriminin ANNOTATION'ı: iki tablo birbirinin\n// kolonuna `existsIn` ile bakınca TypeScript ikisini de birbirinden\n// çıkarmaya çalışır ve döngüyü `any` ile keser. Annotation döngüyü kırar ve\n// kolon adlarını tipli bırakır — bu yüzden TÜKETİCİNİN yazabilmesi gerekir.\nexport type { PolicyDef, PolicyCommand, PolicyMode, PolicyExpr, PolicyBinOp, PolicyExprCtx, PolicyOperand, CheckDef, TableRef } from \"./db/policy.js\";\n// The realtime twin of `policy`: which channels exist and who may join them.\n// Undeclared channels are denied by the server, so this declaration is the\n// whole surface — the runtime reads it back off globalThis at boot.\nexport { defineChannels, ownerOnly, publicChannel } from \"./channels.js\";\nexport type { ChannelsDef, ChannelEntry, ChannelsInput, ChannelGrant, ChannelAuthorizeCtx } from \"./channels.js\";\nexport { PALBASE_EXTENSIONS, EXTENSION_DEPENDENCIES, isPalbaseExtension } from \"./db/extensions.js\";\nexport type { PalbaseExtension } from \"./db/extensions.js\";\nexport {\n uuid, text, integer, bigint, numeric, boolean, timestamp, jsonb, enumType, vector,\n ownedByUser, userRef, installationRef,\n} from \"./db/columns.js\";\nexport type { ColumnBuilder, ColumnDef, ColumnType, OnDeleteAction, AnyColumn } from \"./db/columns.js\";\nexport { raw } from \"./db/raw.js\";\nexport type { RawConstraintDef } from \"./db/raw.js\";\nexport { openai } from \"./db/embedding.js\";\nexport type { EmbeddingModelRef } from \"./db/embedding.js\";\nexport { makeTypedDB, col, sqlFragment, withRetry } from \"./db/typed-db.js\";\nexport type { AtomicDatabase, PageInput } from \"./db/typed-db.js\";\nexport type { Page, PageInfo, PageNavigation, RawPageOptions } from \"./db/page.js\";\nexport type { InsertManyOptions } from \"./db/bulk.js\";\nexport type { CommandOptions } from \"./db/command.js\";\nexport type { AtomicOptions, TransactionIsolation } from \"./db/transaction-options.js\";\nexport type {\n TypedDB,\n TypedTx,\n TypedTable,\n InsertShape,\n RowShape,\n EnvTypedDatabase,\n EnvServiceDatabase,\n EnvTypedTable,\n EnvTables,\n EnvSchemas,\n TxPlan,\n TxTables,\n ColRef,\n SqlFragment,\n SetValue,\n SetShape,\n // FİLTRE TİPLERİ — bir sorguyu parça parça kurup fonksiyonlar arasında\n // geçirebilmek için ADLANDIRILABİLİR olmaları gerekiyor. Yoksa\n // `function siparisFiltresi(): ???` yazılamıyor ve yazar ya `Parameters<...>`\n // gibi bir kaçamağa ya da her şeyi tek çağrıda toplamaya mecbur kalıyor.\n // (`TxWhere` — plan yolunun filtresi — zaten dışa aktarılıyordu; düz yolunki\n // atlanmıştı.)\n WhereFilter,\n WhereOp,\n QueryInput,\n MutateInput,\n AggregateInput,\n AggregateResult,\n InsertValues,\n OrderBySpec,\n FindManyOpts,\n} from \"./db/typed-db.js\";\n// Transaction plans: the `tx.tables.*` operation surface, its handles, and the\n// expressions a plan may write. `Database.$transaction()` is on `Database`.\nexport { increment, decrement, inc, dec, now, TxRefError, TxPlanError } from \"./db/tx-plan.js\";\nexport type {\n Ref,\n TxRow,\n TxRows,\n TxTable,\n TxPlanHandle,\n Materialized,\n TxNow,\n TxColumnExpr,\n TxInsertValue,\n TxSetValue,\n TxInsertShape,\n TxSetShape,\n TxWhere,\n TxSelectOptions,\n TxPlanBody,\n TxPlanResponse,\n TxPlanOpResult,\n TxPlanRejection,\n TxWireOp,\n TxWireRef,\n TxWireExpr,\n TxWireGuard,\n TxWireValue,\n} from \"./db/tx-plan.js\";\n// Kiracıya kapsanmış CRUD'un TEK yazımı. `defineRepository` bir TABAN SINIFI\n// üretir (`class TodoRepository extends defineRepository(Database.public.todos,\n// { tenant: \"household_id\" }) {}`); `RepositoryOf` onun yüzeyi, `RepositoryTable`\n// ise repo'nun tablodan istediği alt küme — kendi tablo sarmalayıcısını yazan\n// bir proje ona göre yazar. Satır anahtarı varsayılan olarak `id`, ama SABİT\n// DEĞİL: `defineTable` bir `id` kolonu şart koşmadığı için `{ key: \"slug\" }`\n// ile adlandırılabiliyor (`DefaultRowKey`/`RowKey` o seçimin tipleri).\nexport { defineRepository } from \"./db/repository.js\";\nexport type {\n DefaultRowKey,\n MissingRowKey,\n RepositoryOf,\n RepositoryTable,\n RowKey,\n} from \"./db/repository.js\";\nexport type { Tables, TableTypes } from \"./db/env.js\";\nexport { makeEnvDts } from \"./db/env-gen.js\";\n// `config/` IS GONE, and so is the purchases family. Both were author-facing\n// surfaces with nothing behind them.\n//\n// The five config declarations nobody applied — storage, flags, notifications,\n// egress, auth — stopped being applied when the server-side declaration applier\n// was retired (v2 S-005, \"settings have one door, and a second one is how the\n// two disagree\"); `contract_lock_test.go` keeps it retired, and its own comment\n// records that the applier produced that silent failure FIVE times. The two that\n// still worked travelled by CLI courier: `config/secrets.ts` gated the push and\n// `config/test-users.ts` was PUT at the stack. Both jobs are now done where the\n// setting lives — `palbase secret set`, `palbase test-user templates set` — and\n// what a controller may SPELL comes back as a type instead of a declaration.\n//\n// `purchases` never had a v2 backend at all: v2 contains no palstore, which\n// `clients/index.ts` recorded on 2026-08-15 while deliberately leaving the tree\n// in place. It is taken now.\n//\n// The rule that replaced all of it: the schema files under `db/` and\n// behaviour-carrying code\n// live in the repo; everything else is CONFIGURATION and is set through the CLI\n// (later MCP) against the stack. Codegen exists so that code can be written\n// against it — a generated type is not a declaration, and it produces no file an\n// author edits.\nexport type { PalbaseSecretName, PalbaseFlagKey, PalbaseBucketName } from \"./stack.js\";\nexport { makeStackDts } from \"./stack-gen.js\";\nexport type { StackNames } from \"./stack-gen.js\";\n// Class-controller decorator model (replaces defineController/defineHandler/route).\n// `getRegisteredControllers` is what makes exporting a controller OPTIONAL:\n// importing the file registers it. `Controller` stays exported for authoring.\nexport { Controller, getRegisteredControllers, __resetRegisteredControllers } from \"./decorators/controller.js\";\n// The APPLICATION-level ring of the auth cascade (route → controller →\n// application → true). Declared once at module scope instead of repeating the\n// same `auth` on every @Controller — the repetition is what gets forgotten.\nexport { defineDefaultAuth, __resetDefaultAuth, assertZeroArgConstructor, resolveEffectiveAuth } from \"./decorators/controller.js\";\nexport type { ControllerOptions } from \"./decorators/controller.js\";\nexport { Get, Post, Put, Patch, Delete, Query } from \"./decorators/methods.js\";\nexport { Deny, getHookConfig, getHookManifest, Hook } from \"./decorators/hook.js\";\nexport type { HookFn, ResolvedHookClass } from \"./decorators/hook.js\";\nexport { Upload } from \"./decorators/upload.js\";\nexport type { UploadConfig } from \"./decorators/upload.js\";\n// `UploadedObject` is exported from upload.js, where BOTH the `@UploadedObject()`\n// decorator value AND the `UploadedObject` type are declared. One module → one\n// export name carries both — authors write `@UploadedObject()` (value) and\n// `: UploadedObject` (type) with a single imported name.\nexport { UploadedObject } from \"./decorators/upload.js\";\n// `@Sse` + its two parameter companions. `SseWriter` is the writer `@SseOut()`\n// injects; `SseConfig` is the route marker's type. The pipeline keys off the\n// config's PRESENCE, not the HTTP verb — see decorators/sse.ts.\nexport { Sse, SseOut, Signal } from \"./decorators/sse.js\";\nexport type { SseConfig, SseWriter } from \"./decorators/sse.js\";\n\n// `@Room` + its six lifecycle hooks. A room is the realtime surface a backend\n// can MANAGE rather than only talk on: it sees who joined, who left, and when\n// nobody is watching any more. Marked by the config's PRESENCE, like every\n// other decorator here — see decorators/room.ts.\nexport {\n Room,\n OnAuthorize,\n OnFirst,\n OnJoin,\n OnLeave,\n OnEmpty,\n OnMessage,\n} from \"./decorators/room.js\";\nexport type { RoomOptions } from \"./decorators/room.js\";\nexport {\n Body,\n QueryParams,\n Headers,\n Param,\n User,\n OptionalUser,\n Client,\n RequestId,\n TraceId,\n Req,\n} from \"./decorators/params.js\";\nexport type { RouteOptions, HttpMethodUpper, ThrowDescriptor, RouteMeta, ParamMeta, ParamKind } from \"./decorators/registry.js\";\n// recordThrows is the stager-injected carrier for inferred throw descriptors\n// (the recordReturn twin) — public so the injected IIFE in a deployed bundle\n// can call it via `require(\"@palbase/backend\").recordThrows(...)`.\nexport { recordThrows } from \"./decorators/registry.js\";\n// getRoutes reads a controller's RouteMeta[] straight from the registry — the\n// isolate runtime enumerates routes with it instead of the worker.js raw-Symbol\n// fallback (the ROUTES symbol stays, both fallbacks keep reading it).\nexport { getRoutes } from \"./decorators/registry.js\";\nexport { defineMiddleware } from \"./middleware.js\";\nexport type { MiddlewareContext, MiddlewareHandler } from \"./middleware.js\";\n// The authenticated-user TYPE is exported as `UserT` (not `User`) because the\n// value name `User` is the @User() parameter decorator (exported above). A\n// controller annotates `@User() user: UserT` — decorator for the value\n// position, `UserT` for the type. (NestJS-style: same name as the decorator\n// would collide in the value+type namespaces.)\nexport type { User as UserT, VerifiedDevice, HttpMethod, AuthConfig } from \"./types.js\";\nexport {\n HttpError,\n PalError,\n BadRequest,\n Unauthorized,\n Forbidden,\n NotFound,\n Conflict,\n TooManyRequests,\n // 23505, typed. The engine throws it; a caller branches on `.constraint`\n // instead of matching the driver's message string.\n UniqueViolation,\n SerializationFailure,\n DeadlockDetected,\n isRetryable,\n} from \"./errors.js\";\n// Typed project errors — defineError returns an HttpError subclass and\n// self-registers {code, status, dataSchema} in the project-global error\n// registry (the OpenAPI spec twins join `RouteMeta.throws` against it).\nexport { defineError, getErrorRegistry } from \"./error-registry.js\";\nexport type { RegisteredError, DefinedError, DefinedErrorWithData } from \"./error-registry.js\";\nexport type { JobMeta } from \"./job.js\";\nexport type { WebhookProvider, WebhookMeta, WebhookRequest } from \"./webhook.js\";\n// Webhooks and jobs are classes: `@Webhook`/`@On` for inbound webhooks,\n// `@Job` for cron. Both take their name from their file — see decorators/*.\nexport { getWebhookConfig, getWebhookManifest, On, Webhook } from \"./decorators/webhook.js\";\n\n// ── dependency injection ───────────────────────────────────────────────────\n//\n// `Injectable` and `Module` are the whole authoring surface: a class says it can\n// be resolved, and ONE module says who owns it, what it exports and what it may\n// reach. There is no `inject()`, no `@Inject`, no token registry — a dependency\n// is named by its constructor parameter's type and by nothing else.\nexport { Injectable } from \"./decorators/injectable.js\";\n// Which of a container's owned classes are entry points of each kind. Discovery\n// used to be a DIRECTORY (jobs/*.ts); now a module lists the class and the\n// decorator says what it is.\nexport { controllersOf, hooksOf, jobsOf, roomsOf, webhooksOf } from \"./decorators/kinds.js\";\nexport { Module } from \"./decorators/module.js\";\nexport type { ModuleDef, Token } from \"./decorators/module.js\";\n// Internal seam, exported for the same reason __runStartHooks is: the engine and\n// the bundle carry SEPARATE copies of this package, and claiming has to be done\n// by the copy that builds the container.\nexport { __claimModules } from \"./decorators/module.js\";\n// The `@Injectable()` half of the same seam. It is what FR-010 counts, and a\n// test fixture that builds two containers in one process has to drain it\n// between them the way it drains modules — a leftover fails the NEXT build with\n// a true refusal about the wrong test.\nexport { __claimInjectables } from \"./decorators/injectable.js\";\nexport { DiError } from \"./container.js\";\n// THE ORPHAN CHECK, and it was a READER WITH NO WRITER.\n//\n// `build-check.js` has always guarded its call with\n// `typeof sdk.assertNoOrphanEntryPoints === 'function'` — and this line was\n// missing, so the guard was false every time and the check never ran on the\n// build path. Measured 2026-09-02 through the real CLI: a `@Controller` that no\n// module lists entered the route table and `palbase build` printed\n// \"build OK — 6 route(s)\", exit 0. The runtime refuses it at boot, which is\n// exactly the failure `palbase build` exists to catch first.\n//\n// `createApp` calls it too; it is exported because the LOCAL build has to reach\n// the same decision with the same code, which is the whole premise of that file.\nexport { assertNoOrphanEntryPoints } from \"./container.js\";\n// `createApp` calls this and hands the result back as `App.container`; a project\n// almost never needs it directly. It is exported because the runtime is the\n// framework's OTHER HALF and builds containers of its own, and because a\n// hand-built one is validated exactly like the engine's — same claim, same\n// refusals, no second way to get an unvalidated graph.\nexport { buildContainer } from \"./container.js\";\nexport type { Container, DiKind, ModulePressure } from \"./container.js\";\nexport type { ResolvedWebhook, SignatureSpec, WebhookEventHandler, WebhookOptions } from \"./decorators/webhook.js\";\nexport { getJobConfig, getJobManifest, Job } from \"./decorators/job.js\";\nexport type { JobOptions, ResolvedJob } from \"./decorators/job.js\";\n// `Resource` is GONE, not deprecated. Its boot registry was never wired: nothing\n// in the runtime ever called `__runResourceBoot` (measured 2026-08-29 —\n// `grep -rn \"ResourceBoot\"` across v2/runtime and palsvc returned nothing), so\n// `init(env)` never ran, the declared secrets never arrived, and a project that\n// wrote one got an object whose fields sat at their initializers with no error\n// anywhere. That is the same silence the `auth`/`storage`/`documents` hook\n// helpers were removed for, one surface down.\n//\n// Nothing replaces it, because the thing it was ceremony around is already the\n// stack's: the VAULT holds what a backend may read, the runtime lists those names\n// off it and mirrors them into `process.env` at boot, and `Secrets.get()` reads a\n// value with the rotation the deploy generation already carries. A field frozen\n// once inside `init(env)` could not have that. `static secrets` was therefore a\n// third list of names, behind the vault and behind `config/secrets.ts` — which is\n// itself down to a hint rather than a constraint (v2/runtime/src/server.ts:517).\n// `config/egress.ts` fences the calls a resource would have made and\n// `openai.embedding(...)` in the schema puts the one vendor client the platform\n// actually runs where the platform runs it. `resources/` stays exactly what the\n// bundler already treats it as — a directory of plain modules a controller\n// imports.\n// Types only. A hook is declared with @Hook/@On in hooks/*.ts.\n//\n// The `auth`/`storage`/`documents` helpers that used to live here are gone, not\n// deprecated: they returned a record nothing in the runtime or the bundler ever\n// read, so a project that called one got a handler that never ran and no error\n// anywhere. api-surface.mjs asks for a deprecation bridge because a major locks\n// every tenant's deploy — a real cost, and the reason this shipped as a bridge\n// in 20.0.0. There are no production tenants to lock yet (owner's call,\n// 2026-08-22), so the bridge is spending a release to soften a break nobody can\n// feel, and the honest surface is the one with no dead names in it.\nexport type {\n HookMeta,\n AuthHookEvent,\n DocumentHookEvent,\n FileUploadedEvent,\n FileDeletedEvent,\n} from \"./hooks.js\";\nexport { z } from \"zod\";\n\nexport { DeclarationRefused, isDeclarationRefused, DECLARATION_REFUSAL } from \"./refusals.js\";\nexport type { UniqueWhere } from \"./db/unique.js\";\nexport type { DatabaseBudget, DatabaseDiagnostics, DatabaseDiagnosticsOptions, DatabaseQueryEvent } from \"./db/diagnostics.js\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4DO,IAAMA,qBAAN,cAAiCC,MAAAA;EA5DxC,OA4DwCA;;;EAC7BC;EACAC;EACAC;EAET,YAAYF,MAAcG,SAAiBF,QAAgBC,UAAmC,CAAC,GAAG;AAChG,UAAMC,OAAAA;AACN,SAAKC,OAAO;AACZ,SAAKJ,OAAOA;AACZ,SAAKC,SAASA;AACd,SAAKC,UAAUA;EACjB;AACF;AAEO,SAASG,eAAeC,KAAoB;AACjD,iBAAeC,QACbC,QACAC,MACAC,UAA0B,CAAC,GAAC;AAE5B,UAAMC,UAAkC;MACtC,gBAAgB;MAChB,GAAID,QAAQC,WAAW,CAAC;IAC1B;AACA,QAAIL,IAAIM,OAAQD,SAAQ,QAAA,IAAYL,IAAIM;AAExC,UAAMC,OAAoB;MAAEL;MAAQG;IAAQ;AAC5C,QAAID,QAAQI,SAASC,QAAW;AAC9B,UAAI,OAAOL,QAAQI,SAAS,YAAYJ,QAAQI,gBAAgBE,YAAY;AAC1EH,aAAKC,OAAOJ,QAAQI;MACtB,WAAW,OAAOG,aAAa,eAAeP,QAAQI,gBAAgBG,UAAU;AAI9E,eAAON,QAAQ,cAAA;AACfE,aAAKC,OAAOJ,QAAQI;MACtB,WAAW,OAAOI,SAAS,eAAeR,QAAQI,gBAAgBI,MAAM;AACtE,eAAOP,QAAQ,cAAA;AACfE,aAAKC,OAAOJ,QAAQI;MACtB,OAAO;AACLD,aAAKC,OAAOK,KAAKC,UAAUV,QAAQI,IAAI;MACzC;IACF;AACA,QAAIJ,QAAQW,OAAQR,MAAKQ,SAASX,QAAQW;AAG1C,UAAMC,UAAUhB,IAAIiB,aAAaC,WAAWC;AAE5C,QAAIC;AACJ,QAAI;AACFA,iBAAW,MAAMJ,QAAQ,GAAGhB,IAAIqB,OAAO,GAAGlB,IAAAA,IAAQI,IAAAA;IACpD,SAASe,KAAK;AAsBZ,aAAO;QACLC,MAAM;QACNC,OAAO,IAAIhC,mBACT,iBACA8B,eAAe7B,QAAQ6B,IAAIzB,UAAU,0BACrC,CAAA;QAEFF,QAAQ;MACV;IACF;AAEA,UAAM8B,cAAcL,SAASf,QAAQqB,IAAI,cAAA,KAAmB;AAC5D,QAAIC,SAAkB;AACtB,QAAIzB,WAAW,UAAUuB,YAAYG,SAAS,MAAA,GAAS;AACrDD,eAAS,MAAMP,SAASS,KAAI,EAAGC,MAAM,MAAM,IAAA;IAC7C,WAAW5B,WAAW,UAAUuB,YAAYM,WAAW,QAAA,GAAW;AAEhEJ,eAAS,IAAIjB,WAAW,MAAMU,SAASY,YAAW,CAAA;IACpD,WAAW9B,WAAW,UAAUkB,SAASZ,MAAM;AAE7CmB,eAAS,MAAMP,SAASa,KAAI,EAAGH,MAAM,MAAM,IAAA;IAC7C;AAEA,QAAI,CAACV,SAASc,IAAI;AAChB,YAAM1B,OAAQmB,UAAU,OAAOA,WAAW,WAAWA,SAAS,CAAC;AAC/D,YAAMjC,OAAO,OAAOc,KAAKgB,UAAU,YAAYhB,KAAKgB,QAAQhB,KAAKgB,QAAQ;AACzE,YAAM3B,UACH,OAAOW,KAAK2B,sBAAsB,YAAY3B,KAAK2B,qBACpDf,SAASgB,cACT;AACF,aAAO;QACLb,MAAM;QACNC,OAAO,IAAIhC,mBAAmBE,MAAMG,SAASuB,SAASzB,QAAQa,IAAAA;QAC9Db,QAAQyB,SAASzB;MACnB;IACF;AAEA,WAAO;MAAE4B,MAAMI;MAAaH,OAAO;MAAM7B,QAAQyB,SAASzB;IAAO;EACnE;AAhGeM;AAkGf,SAAO;IAAEoB,SAASrB,IAAIqB;IAASpB;EAAQ;AACzC;AApGgBF;;;ACrCT,IAAMsC,iBAAN,cAA6BC,MAAAA;EArCpC,OAqCoCA;;;EACzBC;EAET,YAAYA,MAAcC,SAAkB;AAC1C,UAAMA,WAAW,kBAAkBD,IAAAA,6BAAiC;AACpE,SAAKE,OAAO;AACZ,SAAKF,OAAOA;EACd;AACF;AAcA,SAASG,OAAOC,OAA4CJ,MAAY;AACtE,MAAII,MAAMC,SAAS,mBAAoB,OAAM,IAAIP,eAAeE,MAAMI,MAAMH,OAAO;AACnF,MAAIG,iBAAiBE,mBAAoB,OAAMF;AAC/C,QAAM,IAAIE,mBAAmBF,MAAMC,QAAQ,iBAAiBD,MAAMH,WAAW,kBAAkB,CAAA;AACjG;AAJSE;AAQT,SAASI,UAAUC,QAAgBR,MAAa;AAC9C,QAAMS,OAAO,gBAAgBC,mBAAmBF,MAAAA,CAAAA;AAChD,SAAOR,SAASW,SAAYF,OAAO,GAAGA,IAAAA,IAAQC,mBAAmBV,IAAAA,CAAAA;AACnE;AAHSO;AAKF,SAASK,gBAAgBC,MAAqB;AACnD,SAAO;IACL,MAAMC,WAAWN,QAAgBR,MAAY;AAC3C,YAAM,EAAEI,MAAK,IAAK,MAAMS,KAAKE,QAAuB,OAAOR,UAAUC,QAAQR,IAAAA,CAAAA;AAC7E,UAAII,MAAOD,QAAOC,OAAOJ,IAAAA;IAC3B;IAEA,MAAMgB,WAAWR,QAAgBR,MAAY;AAC3C,YAAM,EAAEI,MAAK,IAAK,MAAMS,KAAKE,QAAuB,UAAUR,UAAUC,QAAQR,IAAAA,CAAAA;AAChF,UAAII,MAAOD,QAAOC,OAAOJ,IAAAA;IAC3B;IAEA,MAAMiB,QAAQT,QAAc;AAC1B,YAAM,EAAEU,MAAMd,MAAK,IAAK,MAAMS,KAAKE,QAAuB,OAAOR,UAAUC,MAAAA,CAAAA;AAI3E,UAAIJ,MAAOD,QAAOC,OAAO,EAAA;AACzB,aAAOc,MAAMC,SAAS,CAAA;IACxB;EACF;AACF;AArBgBP;;;AC7ChB,IAAMQ,aAAa;AAEnB,SAASC,gBAAgBC,SAAiBC,OAAa;AACrD,MAAI,CAACH,WAAWI,KAAKF,OAAAA,GAAU;AAC7B,UAAM,IAAIG,MAAM,WAAWF,KAAAA,MAAWD,OAAAA,iBAAwBF,WAAWM,MAAM,EAAE;EACnF;AACF;AAJSL;AA2BT,SAASM,iBACPC,MACAC,MAAY;AAEZ,SAAO;IACLA;IACA,MAAMC,IAAIC,MAAO;AACf,aAAOH,KAAKI,QAAc,OAAO,YAAYH,IAAAA,IAAQ;QAAEI,MAAMF;MAAK,CAAA;IACpE;IACA,MAAMG,MAAAA;AACJ,YAAMC,WAAW,MAAMP,KAAKI,QAAqB,OAAO,YAAYH,IAAAA,EAAM;AAC1E,UAAIM,SAASC,MAAO,QAAO;QAAEL,MAAM;QAAMK,OAAOD,SAASC;QAAOC,QAAQF,SAASE;MAAO;AACxF,YAAMC,OAAMH,SAASJ,QAAQ,CAAC;AAC9B,YAAMQ,SAASD,KAAIC,WAAWC,SAAYF,KAAIC,SAASE,QAAQH,KAAIP,QAAQO,KAAII,EAAE;AACjF,YAAMC,WAAWd,KAAKe,MAAM,GAAA;AAC5B,YAAMF,KAAKJ,KAAII,MAAMC,SAASA,SAASE,SAAS,CAAA,KAAM;AACtD,aAAO;QACLd,MAAM;UAAEW;UAAIH;UAAQR,MAAM,6BAAMO,KAAIP,MAAV;UAAiCe,KAAK;YAAEjB;UAAK;QAAE;QACzEO,OAAO;QACPC,QAAQF,SAASE;MACnB;IACF;IACA,MAAMU,OAAOhB,MAAgB;AAC3B,aAAOH,KAAKI,QAAc,SAAS,YAAYH,IAAAA,IAAQ;QAAEI,MAAMF;MAAK,CAAA;IACtE;IACA,MAAMiB,SAAAA;AACJ,aAAOpB,KAAKI,QAAc,UAAU,YAAYH,IAAAA,EAAM;IACxD;IACAoB,WAA8CC,MAAY;AACxD7B,sBAAgB6B,MAAM,oBAAA;AACtB,aAAOC,mBAAsBvB,MAAM,GAAGC,IAAAA,IAAQqB,IAAAA,EAAM;IACtD;EACF;AACF;AAjCSvB;AAmCT,SAASwB,mBACPvB,MACAC,MACAuB,QAAoB;EAAEC,OAAO,CAAA;EAAIC,SAAS,CAAA;AAAG,GAAC;AAE9C,WAASC,SAASC,KAAkD;AAClE,WAAO;MACLd,IAAIc,IAAId;MACRH,QAAQ;MACRR,MAAM,6BAAMyB,IAAIzB,MAAV;MACNe,KAAK;QAAEjB,MAAM,GAAGA,IAAAA,IAAQ2B,IAAId,EAAE;MAAG;IACnC;EACF;AAPSa;AAST,WAASE,cAAcC,MAAkC;AACvD,WAAO;MACLA;MACAC,OAAOD,KAAKb,WAAW;MACvBe,MAAMF,KAAKb;MACXgB,YAAY,6BAAMH,KAAKI,IAAI,CAACN,SAAS;QAAEO,MAAM;QAAkBP;MAAI,EAAA,GAAvD;IACd;EACF;AAPSC;AAST,SAAO;IACL5B;IAEA2B,IAAId,IAAU;AACZrB,sBAAgBqB,IAAI,aAAA;AACpB,aAAOf,iBAAoBC,MAAM,GAAGC,IAAAA,IAAQa,EAAAA,EAAI;IAClD;IAEA,MAAMsB,IAAIjC,MAAO;AACf,YAAMkC,OAAO,MAAMrC,KAAKI,QAAwB,QAAQ,YAAYH,IAAAA,IAAQ;QAAEI,MAAMF;MAAK,CAAA;AACzF,UAAIkC,KAAK7B,SAAS,CAAC6B,KAAKlC,MAAM;AAC5B,eAAO;UAAEA,MAAM;UAAMK,OAAO6B,KAAK7B;UAAOC,QAAQ4B,KAAK5B;QAAO;MAC9D;AACA,aAAO;QACLN,MAAMJ,iBAAoBC,MAAM,GAAGC,IAAAA,IAAQoC,KAAKlC,KAAKW,EAAE,EAAE;QACzDN,OAAO;QACPC,QAAQ4B,KAAK5B;MACf;IACF;;;IAIAgB,MAAMa,OAAeC,IAA0BC,OAAc;AAC3D,aAAOjB,mBAAsBvB,MAAMC,MAAM;QACvC,GAAGuB;QACHC,OAAO;aAAID,MAAMC;UAAO;YAAEa;YAAOC;YAAIC;UAAM;;MAC7C,CAAA;IACF;IACAd,QAAQY,OAAeG,YAA4B,OAAK;AACtD,aAAOlB,mBAAsBvB,MAAMC,MAAM;QACvC,GAAGuB;QACHE,SAAS;aAAIF,MAAME;UAAS;YAAEY;YAAOG;UAAU;;MACjD,CAAA;IACF;IACAC,MAAMC,GAAS;AACb,aAAOpB,mBAAsBvB,MAAMC,MAAM;QAAE,GAAGuB;QAAOkB,OAAOC;MAAE,CAAA;IAChE;IAEA,MAAMrC,MAAAA;AACJ,YAAMsC,WACJpB,MAAMC,MAAMR,SAAS,KAAKO,MAAME,QAAQT,SAAS,KAAKO,MAAMkB,UAAU9B;AAExE,YAAMyB,OAAOO,WACT,MAAM5C,KAAKI,QACT,QACA,YAAYH,IAAAA,UACZ;QAAEI,MAAMwC,UAAUrB,KAAAA;MAAO,CAAA,IAE3B,MAAMxB,KAAKI,QACT,OACA,YAAYH,IAAAA,EAAM;AAGxB,UAAIoC,KAAK7B,MAAO,QAAO;QAAEL,MAAM;QAAMK,OAAO6B,KAAK7B;QAAOC,QAAQ4B,KAAK5B;MAAO;AAC5E,YAAMqB,QAAQO,KAAKlC,MAAM2C,aAAa,CAAA,GAAIZ,IAAIP,QAAAA;AAC9C,aAAO;QAAExB,MAAM0B,cAAcC,IAAAA;QAAOtB,OAAO;QAAMC,QAAQ4B,KAAK5B;MAAO;IACvE;EACF;AACF;AAjFSc;AAmFT,SAASsB,UAAUrB,OAAiB;AAClC,QAAMnB,OAAgC,CAAC;AACvC,MAAImB,MAAMC,MAAMR,SAAS,GAAG;AAC1BZ,SAAKoB,QAAQD,MAAMC,MAAMS,IAAI,CAACa,OAAO;MAAET,OAAOS,EAAET;MAAOC,IAAIQ,EAAER;MAAIC,OAAOO,EAAEP;IAAM,EAAA;EAClF;AACA,MAAIhB,MAAME,QAAQT,SAAS,GAAG;AAC5BZ,SAAKqB,UAAUF,MAAME,QAAQQ,IAAI,CAACc,OAAO;MAAEV,OAAOU,EAAEV;MAAOG,WAAWO,EAAEP;IAAU,EAAA;EACpF;AACA,MAAIjB,MAAMkB,UAAU9B,OAAWP,MAAKqC,QAAQlB,MAAMkB;AAClD,SAAOrC;AACT;AAVSwC;AAaT,IAAMI,YAAY;AAEX,SAASC,qBAAqBlD,MAAqB;AACxD,SAAO;;;;;;IAML4B,IAAuC3B,MAAY;AACjD,YAAMc,WAAWoC,OAAOlD,IAAAA,EACrBe,MAAM,GAAA,EACNoC,OAAO,CAACC,MAAMA,EAAEpC,SAAS,CAAA;AAC5B,UAAIF,SAASE,WAAW,KAAKF,SAASE,SAAS,MAAM,GAAG;AACtD,cAAM,IAAIpB,MACR,2BAA2BI,IAAAA,gDAAoDc,SAASE,MAAM,cAAc;MAEhH;AACAF,eAASuC,QAAQ,CAACD,GAAGE,MAAM9D,gBAAgB4D,GAAGE,IAAI,MAAM,IAAI,oBAAoB,aAAA,CAAA;AAChF,aAAOxD,iBAAoBC,MAAMe,SAASyC,KAAK,GAAA,CAAA;IACjD;IAEAnC,WAA8CC,MAAY;AACxD7B,sBAAgB6B,MAAM,iBAAA;AACtB,aAAOC,mBAAsBvB,MAAMsB,IAAAA;IACrC;IAEA,MAAMmC,MAAMC,YAAU;AAGpB,UAAIA,WAAWzC,SAASgC,WAAW;AACjC,eAAO;UACL9C,MAAM;UACNK,OAAO,IAAImD,mBACT,mBACA,cAAcD,WAAWzC,MAAM,uBAAuBgC,SAAAA,IACtD,GAAA;UAEFxC,QAAQ;QACV;MACF;AACA,UAAIiD,WAAWzC,WAAW,EAAG,QAAO;QAAEd,MAAM;QAAMK,OAAO;QAAMC,QAAQ;MAAI;AAE3E,aAAOT,KAAKI,QAAc,QAAQ,kBAAkB;QAClDC,MAAMqD,WAAWxB,IAAI,CAACK,QAAQ;UAAEA,IAAIA,GAAGA;UAAItC,MAAMsC,GAAGrB,IAAIjB;UAAME,MAAMoC,GAAGpC;QAAK,EAAA;MAC9E,CAAA;IACF;EACF;AACF;AA9CgB+C;;;AClKhB,IAAMU,eAAe;AAOrB,SAASC,eAAeC,UAAgB;AACtC,MAAI,CAACF,aAAaG,KAAKD,QAAAA,GAAW;AAChC,UAAM,IAAIE,MAAM,uBAAuBF,QAAAA,4BAAoCF,aAAaK,MAAM,EAAE;EAClG;AACF;AAJSJ;AAOT,SAASK,YAAYC,OAAc;AACjC,MAAI,OAAOA,UAAU,UAAW,QAAOA;AACvC,SAAOA,SAAS,QAAQA,UAAU,KAAKA,UAAU;AACnD;AAHSD;AAKT,SAASE,YAAYD,OAAc;AACjC,SAAO,OAAOA,UAAU,WAAW;IAAEE,MAAMF;EAAM,IAAI;AACvD;AAFSC;AAST,SAASE,gBAAgBC,GAAU;AACjC,SACEA,MAAM,QAAQ,OAAOA,MAAM,YAAY,CAACC,MAAMC,QAAQF,CAAAA,MAAO,YAAYA,KAAK,gBAAgBA;AAElG;AAJSD;AAUF,SAASI,iBAAiBC,MAAuBC,KAAgB;AAKtE,WAASC,cAAcC,SAA4B;AACjD,QAAIA,WAAW,YAAYA,QAAS,QAAOA,QAAQC,UAAU;AAC7D,WAAOH,IAAII,iBAAgB,KAAMC;EACnC;AAHSJ;AAKT,WAASK,WAAWJ,SAA4B;AAC9C,UAAMK,MAAMN,cAAcC,OAAAA;AAC1B,WAAOK,MAAM,wBAAwBC,mBAAmBD,GAAAA,CAAAA,KAAS;EACnE;AAHSD;AAKT,WAASG,YAAYP,SAA4B;AAC/C,WAAOH,KAAKW,QAAwB,OAAOJ,WAAWJ,OAAAA,CAAAA;EACxD;AAFSO;AAIT,QAAME,UAAqC;IACzC,MAAMC,mBAAmBT,QAAQU,KAAKtB,OAAK;AACzC,aAAOQ,KAAKW,QACV,OACA,wBAAwBF,mBAAmBL,MAAAA,CAAAA,IAAWK,mBAAmBK,GAAAA,CAAAA,IACzE;QAAEC,MAAM;UAAEvB;QAAM;MAAE,CAAA;IAEtB;IACA,MAAMwB,oBAAoBZ,QAAQa,QAAM;AACtC,aAAOjB,KAAKW,QAAQ,OAAO,wBAAwBF,mBAAmBL,MAAAA,CAAAA,IAAW;QAC/EW,MAAM;UAAEE;QAAO;MACjB,CAAA;IACF;IACA,MAAMC,qBAAqBd,QAAQU,KAAG;AACpC,aAAOd,KAAKW,QACV,UACA,wBAAwBF,mBAAmBL,MAAAA,CAAAA,IAAWK,mBAAmBK,GAAAA,CAAAA,EAAM;IAEnF;IACA,MAAMK,yBAAyBf,QAAM;AACnC,aAAOJ,KAAKW,QAAQ,UAAU,wBAAwBF,mBAAmBL,MAAAA,CAAAA,EAAS;IACpF;IACA,MAAMgB,kBAAkBC,YAAwD;AAI9E,YAAMC,OAAOD,cAAc,CAAA,GAAIE,IAAI,CAACC,OAAAA;AAClC,cAAMC,OAAMD;AACZ,eAAO;UAAEE,SAASD,KAAIrB,UAAUqB,KAAIC;UAAST,QAAQQ,KAAIR;QAAO;MAClE,CAAA;AACA,aAAOjB,KAAKW,QAAQ,QAAQ,wBAAwB;QAAEI,MAAM;UAAEM,YAAYC;QAAI;MAAE,CAAA;IAClF;EACF;AAEA,SAAO;IACL,MAAMK,UAAUxC,UAAkBgB,SAA4B;AAC5DjB,qBAAeC,QAAAA;AACf,YAAMyC,MAAM,MAAMlB,YAAYP,OAAAA;AAC9B,UAAIyB,IAAIC,SAASD,IAAIE,QAAQ,KAAM,QAAO;QAAEA,MAAM;QAAMD,OAAOD,IAAIC;QAAOE,QAAQH,IAAIG;MAAO;AAC7F,aAAO;QAAED,MAAMvC,YAAYqC,IAAIE,KAAKb,SAAS9B,QAAAA,CAAS;QAAG0C,OAAO;QAAME,QAAQH,IAAIG;MAAO;IAC3F;IAEA,MAAMC,WAAW7C,UAAkBgB,SAA4B;AAC7DjB,qBAAeC,QAAAA;AACf,YAAMyC,MAAM,MAAMlB,YAAYP,OAAAA;AAI9B,UAAIyB,IAAIC,SAASD,IAAIE,QAAQ,KAAM,QAAO;QAAEA,MAAM;QAAMD,OAAOD,IAAIC;QAAOE,QAAQH,IAAIG;MAAO;AAC7F,aAAO;QAAED,MAAMrC,YAAYmC,IAAIE,KAAKb,SAAS9B,QAAAA,CAAS;QAAG0C,OAAO;QAAME,QAAQH,IAAIG;MAAO;IAC3F;;;;;;;;IASA,MAAME,IACJ9C,UACA+C,kBACAC,cAAiC;AAEjCjD,qBAAeC,QAAAA;AAEf,UAAIiD;AACJ,UAAIjC;AACJ,UAAIkC,aAAa;AACjB,UAAIF,iBAAiB7B,QAAW;AAC9B8B,uBAAeF;AACfG,qBAAa;AACblC,kBAAUgC;MACZ,WAAWxC,gBAAgBuC,gBAAAA,GAAmB;AAC5C/B,kBAAU+B;MACZ,WAAWA,qBAAqB5B,QAAW;AACzC8B,uBAAeF;AACfG,qBAAa;MACf;AAEA,YAAMC,OAAO,MAAM5B,YAAYP,OAAAA;AAC/B,UAAImC,KAAKT,UAAU,MAAM;AACvB,YAAIQ,WAAY,QAAO;UAAEP,MAAMM,gBAAgB;UAAMP,OAAO;UAAME,QAAQO,KAAKP;QAAO;AACtF,eAAO;UAAED,MAAM;UAAMD,OAAOS,KAAKT;UAAOE,QAAQO,KAAKP;QAAO;MAC9D;AACA,YAAMd,SAASqB,KAAKR,MAAMb,UAAU,CAAC;AACrC,YAAMzB,QAAQyB,OAAO9B,QAAAA;AAErB,UAAIK,UAAUc,QAAW;AACvB,eAAO;UAAEwB,MAAMO,aAAcD,gBAAgB,OAAQ;UAAMP,OAAO;UAAME,QAAQO,KAAKP;QAAO;MAC9F;AACA,aAAO;QAAED,MAAMtC;QAAOqC,OAAO;QAAME,QAAQO,KAAKP;MAAO;IACzD;IAEA,MAAMQ,OAAOpC,SAA4B;AACvC,YAAMyB,MAAM,MAAMlB,YAAYP,OAAAA;AAC9B,UAAIyB,IAAIC,SAASD,IAAIE,QAAQ,KAAM,QAAO;QAAEA,MAAM;QAAMD,OAAOD,IAAIC;QAAOE,QAAQH,IAAIG;MAAO;AAC7F,YAAMd,SAASW,IAAIE,KAAKb,UAAU,CAAC;AACnC,aAAO;QACLa,MAAMU,OAAOC,KAAKxB,MAAAA,EAAQM,IAAI,CAAC7B,SAAAA;AAC7B,gBAAMF,QAAQyB,OAAOvB,IAAAA;AACrB,gBAAMgD,OAAuE;YAC3EhD;YACAiD,SAASpD,YAAYC,KAAAA;UACvB;AACA,cAAI,OAAOA,UAAU,SAAUkD,MAAKE,UAAU;YAAElD,MAAMF;UAAM;AAC5D,iBAAOkD;QACT,CAAA;QACAb,OAAO;QACPE,QAAQH,IAAIG;MACd;IACF;;;;;;;IAQA,MAAMc,YAAY/B,KAAatB,OAAuB;AACpD,YAAMgB,MAAMP,IAAII,iBAAgB;AAChC,UAAI,CAACG,KAAK;AACR,eAAO;UACLsB,MAAM;UACND,OAAO;YACLiB,SACE;UACJ;UACAf,QAAQ;QACV;MACF;AACA,aAAO/B,KAAKW,QACV,OACA,wBAAwBF,mBAAmBD,GAAAA,CAAAA,IAAQC,mBAAmBK,GAAAA,CAAAA,IACtE;QAAEC,MAAM;UAAEvB;QAAM;MAAE,CAAA;IAEtB;IAEAuD,YAAAA;AACE,aAAOnC;IACT;EACF;AACF;AAjKgBb;;;AChChB,SAASiD,YAAqBC,KAAwBC,KAAsB;AAC1E,MAAID,IAAIE,UAAU,QAAQF,IAAIG,SAAS,QAAQH,IAAIG,SAASC,QAAW;AACrE,WAAO;MAAED,MAAM;MAAMD,OAAOF,IAAIE;MAAOG,QAAQL,IAAIK;IAAO;EAC5D;AACA,SAAO;IAAEF,MAAMF,IAAID,IAAIG,IAAI;IAAGD,OAAO;IAAMG,QAAQL,IAAIK;EAAO;AAChE;AALSN;AAST,SAASO,gBAAgBC,MAAU;AACjC,QAAMC,OAA6B;IACjCC,IAAIF,KAAKE;IACTC,MAAMH,KAAKG;IACXC,QAAQJ,KAAKI;IACbC,SAASL,KAAKK;IACdC,UAAUN,KAAKO;IACfC,WAAYR,KAAKQ,aAA0B,CAAA;IAC3CC,WAAWT,KAAKU;IAChBC,WAAWX,KAAKY;IAChBC,WAAWb,KAAKc;EAClB;AACA,MAAId,KAAKe,cAAclB,OAAWI,MAAKe,WAAWhB,KAAKe;AACvD,SAAOd;AACT;AAdSF;AAgBT,SAASkB,cAAcjB,MAAU;AAC/B,SAAO;IACLE,IAAIF,KAAKE;IACTC,MAAMH,KAAKG;IACXC,QAAQJ,KAAKI;IACbc,MAAMlB,KAAKkB;IACXV,WAAYR,KAAKQ,aAA0B,CAAA;IAC3CC,WAAWT,KAAKU;IAChBC,WAAWX,KAAKY;IAChBC,WAAWb,KAAKc;EAClB;AACF;AAXSG;AAaF,SAASE,yBAAyBC,MAAqB;AAC5D,QAAMC,OAA0B;IAC9B,MAAMC,KAAKC,QAAM;AACf,aAAOH,KAAKI,QAAQ,QAAQ,0BAA0B;QAAEN,MAAMK;MAAO,CAAA;IACvE;EACF;AAEA,QAAME,QAA4B;IAChC,MAAMH,KAAKC,QAAM;AAIf,YAAM,EAAEG,cAAcC,MAAMC,MAAAA,OAAM,GAAGC,KAAAA,IAASN;AAC9C,YAAML,OAAgC;QAAE,GAAGW;MAAK;AAChD,UAAIH,iBAAiB7B,OAAWqB,MAAKY,gBAAgBJ;AACrD,UAAIC,SAAS9B,OAAWqB,MAAKX,YAAYoB;AACzC,UAAIC,UAAS/B,OAAWqB,MAAKH,YAAYa;AACzC,aAAOR,KAAKI,QAAQ,QAAQ,2BAA2B;QAAEN;MAAK,CAAA;IAChE;EACF;AAEA,QAAMa,MAAwB;IAC5B,MAAMT,KAAKC,QAAM;AACf,YAAM,EAAEG,cAAc,GAAGG,KAAAA,IAASN;AAClC,YAAML,OAAOQ,iBAAiB7B,SAAY;QAAE,GAAGgC;QAAMC,eAAeJ;MAAa,IAAIG;AACrF,aAAOT,KAAKI,QAAQ,QAAQ,yBAAyB;QAAEN;MAAK,CAAA;IAC9D;EACF;AAEA,QAAMc,WAAkC;IACtC,MAAMV,KAAKC,QAAM;AACf,YAAM,EAAEG,cAAcO,QAAQ,GAAGJ,KAAAA,IAASN;AAC1C,YAAML,OAAO;QACX,GAAGW;QACH,GAAIH,iBAAiB7B,SAAY,CAAC,IAAI;UAAEiC,eAAeJ;QAAa;QACpE,GAAIO,WAAWpC,SAAY,CAAC,IAAI;UAAEqC,SAASD;QAAO;MACpD;AACA,aAAOb,KAAKI,QAAQ,QAAQ,8BAA8B;QAAEN;MAAK,CAAA;IACnE;IACA,MAAMiB,OAAOC,UAAU,CAAC,GAAC;AACvB,YAAMC,QAAQD,QAAQE,UAAUzC,SAAY,KAAK,UAAU0C,mBAAmBC,OAAOJ,QAAQE,KAAK,CAAA,CAAA;AAClG,aAAOlB,KAAKI,QAAQ,OAAO,oCAAoCa,KAAAA,EAAO;IACxE;EACF;AAIA,QAAMI,gBAA4C;IAChD,MAAMC,MAAMnB,QAAM;AAChB,aAAOH,KAAKI,QAAQ,QAAQ,mCAAmC;QAAEN,MAAMK;MAAO,CAAA;IAChF;IACA,MAAMoB,MAAMpB,QAAM;AAChB,aAAOH,KAAKI,QAAQ,QAAQ,yCAAyC;QAAEN,MAAMK;MAAO,CAAA;IACtF;EACF;AAEA,QAAMqB,QAA4B;IAChC,MAAMtB,KAAKC,QAAM;AACf,aAAOH,KAAKI,QAAQ,QAAQ,2BAA2B;QAAEN,MAAMK;MAAO,CAAA;IACxE;IACA,MAAMsB,KAAKT,SAMV;AACC,YAAMU,OAAOV,WAAW,CAAC;AACzB,YAAMb,SAAS,IAAIwB,gBAAAA;AACnB,UAAID,KAAKE,OAAQzB,QAAO0B,IAAI,UAAUH,KAAKE,MAAM;AACjD,UAAIF,KAAKR,UAAUzC,OAAW0B,QAAO0B,IAAI,SAAST,OAAOM,KAAKR,KAAK,CAAA;AACnE,UAAIQ,KAAKI,YAAYrD,OAAW0B,QAAO0B,IAAI,WAAWH,KAAKI,UAAU,SAAS,OAAA;AAC9E,UAAIJ,KAAKK,SAAU5B,QAAO0B,IAAI,YAAYH,KAAKK,QAAQ;AACvD,UAAIL,KAAKM,iBAAkB7B,QAAO0B,IAAI,oBAAoB,MAAA;AAC1D,YAAMZ,QAAQd,OAAO8B,SAAQ;AAC7B,aAAOjC,KAAKI,QAAQ,OAAO,0BAA0Ba,QAAQ,IAAIA,KAAAA,KAAU,EAAA,EAAI;IACjF;IACA,MAAMiB,cAAAA;AACJ,aAAOlC,KAAKI,QAAQ,OAAO,sCAAA;IAC7B;IACA,MAAM+B,SAASrD,IAAU;AACvB,aAAOkB,KAAKI,QAAQ,SAAS,2BAA2Be,mBAAmBrC,EAAAA,CAAAA,OAAU;IACvF;IACA,MAAMsD,cAAAA;AACJ,aAAOpC,KAAKI,QAAQ,QAAQ,kCAAA;IAC9B;IACA,MAAMiC,QAAQvD,IAAU;AACtB,aAAOkB,KAAKI,QAAQ,UAAU,2BAA2Be,mBAAmBrC,EAAAA,CAAAA,EAAK;IACnF;EACF;AAEA,QAAMwD,cAAwC;IAC5C,MAAMC,MAAAA;AACJ,aAAOvC,KAAKI,QAAQ,OAAO,+BAAA;IAC7B;IACA,MAAMoC,OAAOrC,QAAM;AACjB,aAAOH,KAAKI,QAAQ,OAAO,iCAAiC;QAAEN,MAAMK;MAAO,CAAA;IAC7E;EACF;AAEA,QAAMsC,iBAA8C;IAClD,MAAMhB,OAAAA;AACJ,YAAMiB,OAAO,MAAM1C,KAAKI,QAAgB,OAAO,6BAAA;AAC/C,aAAOhC,YAAYsE,MAAM,CAACC,UAAUA,QAAQ,CAAA,GAAIrE,IAAIK,eAAAA,CAAAA;IACtD;IACA,MAAM4D,IAAIzD,IAAU;AAClB,YAAM4D,OAAO,MAAM1C,KAAKI,QACtB,OACA,+BAA+Be,mBAAmBrC,EAAAA,CAAAA,EAAK;AAEzD,aAAOV,YAAYsE,MAAM/D,eAAAA;IAC3B;IACA,MAAMiE,OAAOC,OAAmG;AAC9G,YAAM/C,OAAgC;QACpCf,MAAM8D,MAAM9D;QACZE,SAAS4D,MAAM5D;QACfE,WAAW0D,MAAM3D;MACnB;AACA,UAAI2D,MAAMjD,aAAanB,OAAWqB,MAAKH,YAAYkD,MAAMjD;AACzD,UAAIiD,MAAMzD,cAAcX,OAAWqB,MAAKV,YAAYyD,MAAMzD;AAC1D,YAAMsD,OAAO,MAAM1C,KAAKI,QAAc,QAAQ,+BAA+B;QAAEN;MAAK,CAAA;AACpF,aAAO1B,YAAYsE,MAAM/D,eAAAA;IAC3B;IACA,MAAM6D,OACJ1D,IACA+D,OAAuF;AAEvF,YAAM/C,OAAgC,CAAC;AACvC,UAAI+C,MAAM5D,YAAYR,OAAWqB,MAAKb,UAAU4D,MAAM5D;AACtD,UAAI4D,MAAM3D,aAAaT,OAAWqB,MAAKX,YAAY0D,MAAM3D;AACzD,UAAI2D,MAAMjD,aAAanB,OAAWqB,MAAKH,YAAYkD,MAAMjD;AACzD,UAAIiD,MAAMzD,cAAcX,OAAWqB,MAAKV,YAAYyD,MAAMzD;AAC1D,YAAMsD,OAAO,MAAM1C,KAAKI,QACtB,OACA,+BAA+Be,mBAAmBrC,EAAAA,CAAAA,IAClD;QAAEgB;MAAK,CAAA;AAET,aAAO1B,YAAYsE,MAAM/D,eAAAA;IAC3B;IACA,MAAMmE,OAAOhE,IAAU;AACrB,aAAOkB,KAAKI,QAAQ,UAAU,+BAA+Be,mBAAmBrC,EAAAA,CAAAA,EAAK;IACvF;EACF;AAEA,QAAMiE,eAA0C;IAC9C,MAAMtB,OAAAA;AACJ,YAAMiB,OAAO,MAAM1C,KAAKI,QAAgB,OAAO,iCAAA;AAC/C,aAAOhC,YAAYsE,MAAM,CAACC,UAAUA,QAAQ,CAAA,GAAIrE,IAAIuB,aAAAA,CAAAA;IACtD;IACA,MAAM0C,IAAIzD,IAAU;AAClB,YAAM4D,OAAO,MAAM1C,KAAKI,QACtB,OACA,mCAAmCe,mBAAmBrC,EAAAA,CAAAA,EAAK;AAE7D,aAAOV,YAAYsE,MAAM7C,aAAAA;IAC3B;IACA,MAAM+C,OAAOC,OAA2D;AACtE,YAAM/C,OAAgC;QAAEf,MAAM8D,MAAM9D;QAAMe,MAAM+C,MAAM/C;MAAK;AAC3E,UAAI+C,MAAMzD,cAAcX,OAAWqB,MAAKV,YAAYyD,MAAMzD;AAC1D,YAAMsD,OAAO,MAAM1C,KAAKI,QAAc,QAAQ,mCAAmC;QAAEN;MAAK,CAAA;AACxF,aAAO1B,YAAYsE,MAAM7C,aAAAA;IAC3B;IACA,MAAM2C,OAAO1D,IAAY+D,OAA8C;AACrE,YAAM/C,OAAgC,CAAC;AACvC,UAAI+C,MAAM/C,SAASrB,OAAWqB,MAAKA,OAAO+C,MAAM/C;AAChD,UAAI+C,MAAMzD,cAAcX,OAAWqB,MAAKV,YAAYyD,MAAMzD;AAC1D,YAAMsD,OAAO,MAAM1C,KAAKI,QACtB,OACA,mCAAmCe,mBAAmBrC,EAAAA,CAAAA,IACtD;QAAEgB;MAAK,CAAA;AAET,aAAO1B,YAAYsE,MAAM7C,aAAAA;IAC3B;IACA,MAAMiD,OAAOhE,IAAU;AACrB,aAAOkB,KAAKI,QAAQ,UAAU,mCAAmCe,mBAAmBrC,EAAAA,CAAAA,EAAK;IAC3F;EACF;AAEA,SAAO;IACLmB;IACAI;IACAM;IACAC;IACAS;IACAG;IACAc;IACAU,WAAW;MAAE3C,OAAOoC;MAAgB9B,KAAKoC;IAAa;IACtD,MAAME,eAAe9C,QAAM;AACzB,aAAOH,KAAKI,QAAQ,QAAQ,6BAA6B;QAAEN,MAAMK;MAAO,CAAA;IAC1E;IACA,MAAM+C,iBAAiBC,UAAgB;AACrC,aAAOnD,KAAKI,QAAQ,UAAU,6BAA6Be,mBAAmBgC,QAAAA,CAAAA,EAAW;IAC3F;EACF;AACF;AAlMgBpD;;;ACxDhB,SAASqD,kBAAkB;AAsB3B,SAASC,UAAUC,QAAc;AAC/B,QAAMC,OAAMC,KAAKC,MAAMC,KAAKH,IAAG,IAAK,GAAA;AACpC,QAAMI,SAASC,OAAOC,KAAKC,KAAKC,UAAU;IAAEC,KAAK;IAASC,KAAK;EAAM,CAAA,CAAA,EAAIC,SAAS,WAAA;AAClF,QAAMC,UAAUP,OAAOC,KACrBC,KAAKC,UAAU;IAAEK,KAAK;IAAmBC,MAAM;IAAgBC,KAAKf;IAAKgB,KAAKhB,OAAM;EAAG,CAAA,CAAA,EACvFW,SAAS,WAAA;AACX,QAAMM,MAAMC,WAAW,UAAUnB,MAAAA,EAAQoB,OAAO,GAAGf,MAAAA,IAAUQ,OAAAA,EAAS,EAAEQ,OAAO,WAAA;AAC/E,SAAO,GAAGhB,MAAAA,IAAUQ,OAAAA,IAAWK,GAAAA;AACjC;AARSnB;AAUF,SAASuB,oBAAoBC,KAAmB;AACrD,QAAMC,MAAM,GAAGD,IAAIE,OAAO;AAC1B,QAAMC,WAAW,GAAGH,IAAIE,OAAO;AAK/B,iBAAeE,WACbC,OACAC,KACAC,OACAC,KAAY;AAEZ,QAAI,OAAOH,UAAU,YAAYA,MAAMI,WAAW,GAAG;AACnD,aAAO;QACLC,MAAM;QACNC,OAAO,IAAIC,mBAAmB,oBAAoB,oCAAoC,GAAA;MACxF;IACF;AACA,QAAI,OAAON,QAAQ,YAAYA,IAAIG,WAAW,GAAG;AAC/C,aAAO;QACLC,MAAM;QACNC,OAAO,IAAIC,mBAAmB,oBAAoB,kCAAkC,GAAA;MACtF;IACF;AACA,QAAI,CAACZ,IAAIa,cAAc;AACrB,aAAO;QACLH,MAAM;QACNC,OAAO,IAAIC,mBACT,yBACA,4HAEA,GAAA;MAEJ;IACF;AAEA,QAAIE;AACJ,QAAI;AACFA,cAAQtC,UAAUwB,IAAIa,YAAY;IACpC,SAASE,KAAK;AACZ,aAAO;QACLL,MAAM;QACNC,OAAO,IAAIC,mBACT,wBACAG,eAAeC,QAAQD,IAAIE,UAAU,qBACrC,GAAA;MAEJ;IACF;AAEA,UAAMC,KAAKV,MAAM;MAAEH;MAAOC;MAAKE,KAAK;IAAK,IAAI;MAAEH;MAAOC;MAAKC,OAAOA,SAAS,CAAC;IAAE;AAC9E,UAAMY,UAAUnB,IAAIoB,aAAaC,WAAWC;AAC5C,QAAIC;AACJ,QAAI;AACFA,iBAAW,MAAMJ,QAAQhB,UAAU;QACjCqB,QAAQ;QACRC,SAAS;UAAE,gBAAgB;UAAoBC,eAAe,UAAUZ,KAAAA;QAAQ;QAChFa,MAAM1C,KAAKC,UAAU;UAAE0C,KAAK;YAACV;;QAAI,CAAA;MACnC,CAAA;IACF,SAASH,KAAK;AACZ,aAAO;QACLL,MAAM;QACNC,OAAO,IAAIC,mBACT,iBACAG,eAAeC,QAAQD,IAAIE,UAAU,wBACrC,CAAA;MAEJ;IACF;AACA,QAAIM,SAASM,WAAW,OAAON,SAASM,WAAW,KAAK;AACtD,aAAO;QAAEnB,MAAMoB;QAAWnB,OAAO;MAAK;IACxC;AACA,UAAMoB,SAAS,MAAMR,SAASS,KAAI,EAAGC,MAAM,MAAM,EAAA;AACjD,WAAO;MACLvB,MAAM;MACNC,OAAO,IAAIC,mBACT,yBACA,iCAAiCW,SAASM,MAAM,GAAGE,SAAS,KAAKA,MAAAA,KAAW,EAAA,IAC5ER,SAASM,MAAM;IAEnB;EACF;AA3EezB;AA6Ef,SAAO;IACL8B,OAAO;;;;;;;;MAQLC,KAAK,wBAAC9B,OAAeC,KAAaC,UAChCH,WAAWC,OAAOC,KAAKC,OAAO,KAAA,GAD3B;;MAGL6B,OAAO,wBAAC/B,OAAeC,QAAgBF,WAAWC,OAAOC,KAAKwB,QAAW,IAAA,GAAlE;IACT;IAEA,MAAMO,UAAUC,SAAiBC,OAAejD,SAAiC;AAG/E,UAAI,OAAOgD,YAAY,YAAYA,QAAQ7B,WAAW,GAAG;AACvD,eAAO;UACLC,MAAM;UACNC,OAAO,IAAIC,mBAAmB,oBAAoB,sCAAsC,GAAA;QAC1F;MACF;AACA,UAAI,OAAO2B,UAAU,YAAYA,MAAM9B,WAAW,GAAG;AACnD,eAAO;UACLC,MAAM;UACNC,OAAO,IAAIC,mBAAmB,oBAAoB,oCAAoC,GAAA;QACxF;MACF;AACA,UAAI,CAACZ,IAAIa,cAAc;AACrB,eAAO;UACLH,MAAM;UACNC,OAAO,IAAIC,mBACT,yBACA,gIAEA,GAAA;QAEJ;MACF;AAEA,UAAIE;AACJ,UAAI;AACFA,gBAAQtC,UAAUwB,IAAIa,YAAY;MACpC,SAASE,KAAK;AACZ,eAAO;UACLL,MAAM;UACNC,OAAO,IAAIC,mBACT,wBACAG,eAAeC,QAAQD,IAAIE,UAAU,qBACrC,GAAA;QAEJ;MACF;AAIA,YAAMU,OAAO1C,KAAKC,UAAU;QAC1BsD,UAAU;UAAC;YAAEnC,OAAOiC;YAASC;YAAOjD,SAASA,WAAW,CAAC;YAAGmD,SAAS;UAAM;;MAC7E,CAAA;AAEA,YAAMtB,UAAUnB,IAAIoB,aAAaC,WAAWC;AAC5C,UAAIC;AACJ,UAAI;AACFA,mBAAW,MAAMJ,QAAQlB,KAAK;UAC5BuB,QAAQ;UACRC,SAAS;YAAE,gBAAgB;YAAoBC,eAAe,UAAUZ,KAAAA;UAAQ;UAChFa;QACF,CAAA;MACF,SAASZ,KAAK;AAKZ,eAAO;UACLL,MAAM;UACNC,OAAO,IAAIC,mBACT,iBACAG,eAAeC,QAAQD,IAAIE,UAAU,4BACrC,CAAA;QAEJ;MACF;AAEA,UAAIM,SAASM,WAAW,OAAON,SAASM,WAAW,KAAK;AACtD,eAAO;UAAEnB,MAAMoB;UAAWnB,OAAO;QAAK;MACxC;AAEA,YAAMoB,SAAS,MAAMR,SAASS,KAAI,EAAGC,MAAM,MAAM,EAAA;AACjD,aAAO;QACLvB,MAAM;QACNC,OAAO,IAAIC,mBACT,6BACA,sBAAsBW,SAASM,MAAM,KAAKE,OAAOW,MAAM,GAAG,GAAA,CAAA,IAC1DnB,SAASM,MAAM;MAEnB;IACF;EACF;AACF;AAxLgB9B;;;ACvBhB,IAAM4C,iBAAiB;AAEvB,IAAMC,kBAAkB;AACxB,IAAMC,uBAAuB;AAQ7B,SAASC,oBAAoBC,GAAS;AACpC,MAAI,CAACH,gBAAgBI,KAAKD,CAAAA,KAAMF,qBAAqBG,KAAKD,CAAAA,GAAI;AAC5D,UAAM,IAAIE,MACR,uBAAuBF,CAAAA,gEAAiEH,gBAAgBM,MAAM,EAAE;EAEpH;AACF;AANSJ;AAiBT,SAASK,aAAaC,QAAgBC,KAA4B;AAChE,SAAO;IACLC,MAAOD,IAAIE,QAAmB;IAC9BA,MAAOF,IAAIE,QAAmB;IAC9BH,QAASC,IAAID,UAAqBA;IAClCI,MAAM,OAAOH,IAAIG,SAAS,WAAWH,IAAIG,OAAO;IAChDC,aAAcJ,IAAII,eAA0B;IAC5CC,UAAWL,IAAIK,YAAuB;IACtCC,OAAON,IAAIM;IACXC,QAAQP,IAAIO;IACZC,WAAWR,IAAIQ;IACfC,UAAWT,IAAIS,YAAuC,CAAC;EACzD;AACF;AAbSX;AAgBT,SAASY,YACPC,KACAC,KAAsB;AAEtB,MAAID,IAAIE,SAASF,IAAIG,SAAS,QAAQH,IAAIG,SAASC,QAAW;AAC5D,WAAO;MAAED,MAAM;MAAMD,OAAOF,IAAIE;MAAOG,QAAQL,IAAIK;IAAO;EAC5D;AACA,SAAO;IAAEF,MAAMF,IAAID,IAAIG,IAAI;IAAGD,OAAO;IAAMG,QAAQL,IAAIK;EAAO;AAChE;AARSN;AAUT,SAASO,kBACPC,MACAC,YACAC,cAAoB;AAEpB,QAAMC,aAAa,wBAACnB,SAAiB,sBAAsBiB,UAAAA,IAAcjB,IAAAA,IAAtD;AAEnB,SAAO;IACL,MAAMoB,OAAOpB,MAAMqB,MAAMC,SAA8B;AACrD/B,0BAAoBS,IAAAA;AACpB,YAAMuB,UAAkC;QACtC,gBAAgBD,SAASpB,eAAe;MAC1C;AACA,UAAIoB,SAASE,OAAQD,SAAQ,UAAA,IAAc;AAI3C,YAAME,OAAOJ,gBAAgBK,cAAc,IAAIC,WAAWN,IAAAA,IAAQA;AAClE,YAAMZ,MAAM,MAAMO,KAAKY,QAAiC,OAAOT,WAAWnB,IAAAA,GAAO;QAC/EyB;QACAF;MACF,CAAA;AACA,aAAOf,YAAYC,KAAK,CAACoB,MAAMjC,aAAaqB,YAAYY,KAAK,CAAC,CAAA,CAAA;IAChE;IAEA,MAAMC,SAAS9B,MAAI;AACjBT,0BAAoBS,IAAAA;AAKpB,aAAOgB,KAAKY,QAAc,OAAOT,WAAWnB,IAAAA,GAAO;QAAEuB,SAAS;UAAEQ,QAAQ;QAAM;MAAE,CAAA;IAClF;IAEAC,aAAahC,MAAMsB,SAAO;AACxB/B,0BAAoBS,IAAAA;AACpB,YAAMiC,UAAUX,SAASW,UAAU,YAAYC,mBAAmBZ,QAAQW,OAAO,CAAA,KAAM;AAqBvF,UAAI,CAACf,cAAc;AAKjB,cAAM,IAAIxB,MACR,mBAAmBuB,UAAAA,8LAEjB;MAEN;AACA,aAAO,GAAGC,YAAAA,aAAyBD,UAAAA,IAAcjB,IAAAA,GAAOiC,OAAAA;IAC1D;IAEA,MAAME,gBAAgBnC,MAAMsB,SAAO;AACjC/B,0BAAoBS,IAAAA;AAIpB,aAAOgB,KAAKY,QAAkC,QAAQ,oBAAoBX,UAAAA,IAAcjB,IAAAA,IAAQ;QAC9FyB,MAAM;UAAEW,WAAWd,QAAQc;QAAU;MACvC,CAAA;IACF;IAEA,MAAMC,KAAKC,QAAiBhB,SAA4B;AACtD,UAAIgB,OAAQ/C,qBAAoB+C,MAAAA;AAChC,YAAMC,SAAS,IAAIC,gBAAAA;AACnB,UAAIF,OAAQC,QAAOE,IAAI,UAAUH,MAAAA;AACjC,UAAIhB,SAASoB,UAAU7B,OAAW0B,QAAOE,IAAI,SAASE,OAAOrB,QAAQoB,KAAK,CAAA;AAC1E,YAAME,QAAQL,OAAOM,SAAQ;AAC7B,YAAMpC,MAAM,MAAMO,KAAKY,QACrB,OACA,sBAAsBX,UAAAA,GAAa2B,QAAQ,IAAIA,KAAAA,KAAU,EAAA,EAAI;AAI/D,aAAOpC,YAAYC,KAAK,CAACgB,UAAUA,MAAMqB,WAAW,CAAA,GAAIpC,IAAI,CAACZ,QAAQF,aAAaqB,YAAYnB,GAAAA,CAAAA,CAAAA;IAChG;IAEA,MAAMiD,OAAOC,OAAK;AAChB,iBAAWxD,KAAKwD,MAAOzD,qBAAoBC,CAAAA;AAK3C,YAAMyD,UAA+B,CAAA;AACrC,iBAAWzD,KAAKwD,OAAO;AACrB,cAAMvC,MAAM,MAAMO,KAAKY,QAAc,UAAUT,WAAW3B,CAAAA,CAAAA;AAC1D,YAAIiB,IAAIE,MAAO,QAAO;UAAEC,MAAM;UAAMD,OAAOF,IAAIE;UAAOG,QAAQL,IAAIK;QAAO;AACzEmC,gBAAQC,KAAKtD,aAAaqB,YAAY;UAAEjB,MAAMR;QAAE,CAAA,CAAA;MAClD;AACA,aAAO;QAAEoB,MAAMqC;QAAStC,OAAO;QAAMG,QAAQ;MAAI;IACnD;IAEA,MAAMqC,KAAKC,MAAMC,IAAE;AACjB9D,0BAAoB6D,IAAAA;AACpB7D,0BAAoB8D,EAAAA;AACpB,aAAOrC,KAAKY,QAAc,QAAQ,oBAAoBX,UAAAA,IAAc;QAAEQ,MAAM;UAAE2B;UAAMC;QAAG;MAAE,CAAA;IAC3F;IAEA,MAAMC,KAAKF,MAAMC,IAAE;AACjB9D,0BAAoB6D,IAAAA;AACpB7D,0BAAoB8D,EAAAA;AACpB,aAAOrC,KAAKY,QAAc,QAAQ,oBAAoBX,UAAAA,IAAc;QAAEQ,MAAM;UAAE2B;UAAMC;QAAG;MAAE,CAAA;IAC3F;EACF;AACF;AA3HStC;AAkIF,SAASwC,mBACdvC,MACAE,cAAoB;AAEpB,SAAO;IACLrB,OAAOE,MAAY;AACjB,UAAI,CAACX,eAAeK,KAAKM,IAAAA,GAAO;AAC9B,cAAM,IAAIL,MAAM,yBAAyBK,IAAAA,8BAAkCX,eAAeO,MAAM,EAAE;MACpG;AAIA,aAAOoB,kBAAkBC,MAAMjB,MAAMmB,aAAasC,QAAQ,QAAQ,EAAA,CAAA;IACpE;EACF;AACF;AAfgBD;;;AC7IT,SAASE,mBAAmBC,KAAwB;AACzD,QAAMC,WAAWD,IAAIC,WAAW,IAAIC,QAAQ,QAAQ,EAAA;AACpD,MAAI,CAACD,QAAS,QAAO,CAAC;AAItB,QAAME,SAASH,IAAII,kBAAkBJ,IAAIG,UAAU;AACnD,QAAME,OAAOC,eAAe;IAAEL;IAASE;IAAQI,WAAWP,IAAIO;EAAU,CAAA;AAExE,SAAO;;;;IAILC,MAAMC,gBAAgBJ,IAAAA;IACtBK,WAAWC,qBAAqBN,IAAAA;IAChCO,SAASC,mBAAmBR,MAAML,IAAIc,YAAY;IAClDC,eAAeC,yBAAyBX,IAAAA;IACxCY,OAAOC,iBAAiBb,MAAM;MAAEc,kBAAkBnB,IAAImB;IAAiB,CAAA;IACvEC,UAAUC,oBAAoB;MAC5BpB;MACAqB,cAActB,IAAIuB;MAClBhB,WAAWP,IAAIO;IACjB,CAAA;EACF;AACF;AAxBgBR;;;ACpDhB,IAAMyB,WAA0BC,uBAAOC,IAAI,0BAAA;AA6DpC,SAASC,YAAAA;AACd,SAAO;IAAEC,MAAM;EAAQ;AACzB;AAFgBD;AAKT,SAASE,cACdC,OAA2E,CAAC,GAAC;AAE7E,SAAO;IAAEF,MAAM;IAAUG,SAASD,KAAKC,WAAW;IAAOC,OAAOF,KAAKE;EAAM;AAC7E;AAJgBH;AAMhB,SAASI,WAAWC,SAAe;AACjC,SAAOA,QAAQC,MAAM,GAAA,EAAKC,OAAO,CAACC,MAAMA,EAAEC,WAAW,GAAA,KAAQD,EAAEE,SAAS,GAAA,CAAA,EAAMC;AAChF;AAFSP;AAIF,SAASQ,eAAeC,KAAkB;AAC/C,QAAMC,UAAkC,CAAA;AACxC,aAAW,CAACT,SAASU,KAAAA,KAAUC,OAAOF,QAAQD,GAAAA,GAAM;AAClD,QAAI,UAAUE,SAASA,MAAMhB,SAAS,SAAS;AAC7C,UAAIK,WAAWC,OAAAA,MAAa,GAAG;AAC7B,cAAM,IAAIY,MACR,wCAAwCZ,OAAAA,+EACM;MAElD;AACAS,cAAQI,KAAK;QAAEb;QAASN,MAAM;MAAQ,CAAA;IACxC,WAAW,UAAUgB,SAASA,MAAMhB,SAAS,UAAU;AACrDe,cAAQI,KAAK;QAAEb;QAASN,MAAM;QAAUG,SAASa,MAAMb;QAASC,OAAOY,MAAMZ;MAAM,CAAA;IACrF,OAAO;AACL,YAAMgB,IAAIJ;AACVD,cAAQI,KAAK;QAAEb;QAASN,MAAM;QAAUqB,WAAWD,EAAEC;QAAWC,SAASF,EAAEE;MAAQ,CAAA;IACrF;EACF;AACA,QAAMC,MAAmB;IAAER;EAAQ;AAiBnC,QAAMS,UAAUC;AAChB,QAAMC,WAAWF,QAAQ5B,QAAAA;AACzB,MAAI8B,YAAY,CAACC,gBAAgBD,UAAUH,GAAAA,GAAM;AAC/C,UAAM,IAAIL,MACR,mDAAmDQ,SAASX,QAAQH,MAAM,gBACzDc,SAASX,QAAQD,IAAI,CAACc,MAAMA,EAAEtB,OAAO,EAAEuB,KAAK,IAAA,CAAA,mIAET;EAExD;AACAL,UAAQ5B,QAAAA,IAAY2B;AACpB,SAAOA;AACT;AA/CgBV;AAqEhB,SAASiB,QAAQF,GAAiC;AAChD,SAAOG,KAAKC,UAAU;IACpBJ,EAAEtB;IACFsB,EAAE5B;IACF4B,EAAEzB,WAAW;IACbyB,EAAExB,OAAO6B,QAAQ;IACjBL,EAAExB,OAAO8B,SAAS;;;IAGlBN,EAAEN,UAAUM,EAAEN,QAAQa,SAAQ,IAAK;IACnCP,EAAEP,YAAYO,EAAEP,UAAUc,SAAQ,IAAK;GACxC;AACH;AAZSL;AAgBT,SAASH,gBAAgBS,GAAgBC,GAAc;AACrD,MAAID,EAAErB,QAAQH,WAAWyB,EAAEtB,QAAQH,OAAQ,QAAO;AAClD,SAAOwB,EAAErB,QAAQuB,MAAM,CAACC,GAAGC,MAAMV,QAAQS,CAAAA,MAAOT,QAAQO,EAAEtB,QAAQyB,CAAAA,CAAE,CAAA;AACtE;AAHSb;;;AC7CF,SAASc,iBAOdC,OACAC,MAA6B;AAE7B,QAAMC,eAAeD,KAAKE;AAI1B,QAAMC,SAAiBH,KAAKI,OAAO;AAInC,QAAMC,QAAQ,wBAACH,YAA6C;IAAE,CAACD,YAAAA,GAAeC;EAAO,IAAvE;AACd,QAAMI,WAAW,wBAACJ,QAAgBK,QAAkD;IAClF,CAACN,YAAAA,GAAeC;IAChB,CAACC,MAAAA,GAASI;EACZ,IAHiB;AAmBjB,QAAMC,gBAAgB,wBAACC,QAAyBP,YAC7C;IAAE,GAAGO;IAAQ,CAACR,YAAAA,GAAeC;EAAO,IADjB;AAGtB,MAAeQ,aAAf,MAAeA,WAAAA;IA5KjB,OA4KiBA;;;IACbC,KAAKT,QAAgC;AACnC,aAAOH,MAAMa,SAAS;QAAEC,OAAOR,MAAMH,MAAAA;MAAQ,CAAA;IAC/C;IAEA,MAAMY,KAAKZ,QAAgBK,IAA0C;AACnE,YAAMQ,OAAO,MAAMhB,MAAMa,SAAS;QAAEC,OAAOP,SAASJ,QAAQK,EAAAA;QAAKS,OAAO;MAAE,CAAA;AAC1E,aAAOD,KAAK,CAAA,KAAM;IACpB;IAEAE,OAAOf,QAAgBO,QAAuC;AAC5D,aAAOV,MAAMkB,OAAOT,cAAcC,QAAQP,MAAAA,CAAAA;IAC5C;IAEA,MAAMgB,OAAOhB,QAAgBK,IAAqBY,OAA4B;AAC5E,YAAMC,MAAM,MAAM,KAAKC,aAAanB,QAAQK,IAAIY,KAAAA;AAChD,UAAIC,QAAQ,MAAM;AAChB,cAAM,IAAIE,SACR,GAAGC,OAAOtB,YAAAA,CAAAA,IAAiBsB,OAAOrB,MAAAA,CAAAA,oBAAsBC,MAAAA,IAAUoB,OAAOhB,EAAAA,CAAAA,kBAAgB;MAE7F;AACA,aAAOa;IACT;IAEA,MAAMC,aAAanB,QAAgBK,IAAqBY,OAAmC;AACzF,YAAMJ,OAAO,MAAMhB,MAAMyB,WAAW;QAAEX,OAAOP,SAASJ,QAAQK,EAAAA;QAAKkB,KAAKN;MAAM,CAAA;AAC9E,aAAOJ,KAAK,CAAA,KAAM;IACpB;IAEA,MAAMW,OAAOxB,QAAgBK,IAAoC;AAC/D,YAAMR,MAAM4B,WAAW;QAAEd,OAAOP,SAASJ,QAAQK,EAAAA;MAAI,CAAA;IACvD;EACF;AAEA,SAAOG;AACT;AA5EgBZ;;;AChFhB,SAAS8B,UAAUC,OAAwB;AACzC,SAAO;OAAI,IAAIC,IAAID,KAAAA;IAAQE,KAAI;AACjC;AAFSH;AAOT,SAASI,WAAWC,MAAY;AAC9B,SAAO,6BAA6BC,KAAKD,IAAAA,IAAQA,OAAOE,KAAKC,UAAUH,IAAAA;AACzE;AAFSD;AAIT,SAASK,QAAQR,OAAe;AAC9B,MAAIA,MAAMS,WAAW,EAAG,QAAO;AAC/B,SAAO;EAAKT,MAAMU,IAAI,CAACC,MAAM,OAAOR,WAAWQ,CAAAA,CAAAA,SAAW,EAAEC,KAAK,IAAA,CAAA;;AACnE;AAHSJ;AAQT,SAASK,cAAcC,SAA0C;AAC/D,QAAMC,aAAaD,QAAQJ,IAAI,CAACM,MAAO,OAAOA,MAAM,WAAW;IAAEZ,MAAMY;IAAGC,UAAU,CAAA;EAAwB,IAAID,CAAAA;AAChH,QAAME,SAAS,oBAAIC,IAAAA;AACnB,aAAWH,KAAKD,WAAYG,QAAOE,IAAIJ,EAAEZ,MAAMY,EAAEC,QAAQ;AACzD,QAAMjB,QAAQ;OAAIkB,OAAOG,KAAI;IAAInB,KAAI;AACrC,MAAIF,MAAMS,WAAW,EAAG,QAAO;AAC/B,QAAMa,OAAOtB,MAAMU,IAAI,CAACN,SAAAA;AACtB,UAAMa,WAAW;SAAI,IAAIhB,IAAIiB,OAAOK,IAAInB,IAAAA,KAAS,CAAA,CAAE;MAAGF,KAAI;AAC1D,UAAMsB,QAAQP,SAASR,WAAW,IAAI,UAAUQ,SAASP,IAAI,CAACe,MAAMnB,KAAKC,UAAUkB,CAAAA,CAAAA,EAAIb,KAAK,KAAA;AAC5F,WAAO,OAAOT,WAAWC,IAAAA,CAAAA,iBAAsBoB,KAAAA;EACjD,CAAA;AACA,SAAO;EAAKF,KAAKV,KAAK,IAAA,CAAA;;AACxB;AAZSC;AAuBF,SAASa,aAAa1B,OAAiB;AAC5C,QAAM2B,UAAU5B,UAAUC,MAAM2B,OAAO;AACvC,QAAMC,QAAQ7B,UAAUC,MAAM4B,KAAK;AAGnC,SAAO;;;;uBAIcpB,QAAQmB,OAAAA,CAAAA;;qBAEVnB,QAAQoB,KAAAA,CAAAA;;uBAENf,cAAcb,MAAMc,OAAO,CAAA;;;;;AAKlD;AAlBgBY;;;ACzDhB,SAASG,oBAAoBC,QAAuB;AAClD,SAAO,SAAUC,SAAiBC,UAAwB,CAAC,GAAC;AAK1D,QAAI,OAAOD,YAAY,UAAU;AAC/B,YAAM,IAAIE,MACR,IAAIH,OAAO,CAAA,CAAE,GAAGA,OAAOI,MAAM,CAAA,EAAGC,YAAW,CAAA,2CAA6C,OAAOJ,OAAAA,OAC5FD,WAAW,UACR,iJACA,GAAC;IAEX;AACA,WAAO,SAAUM,QAAQC,aAAaC,YAA+B;AACnE,YAAMC,OAAO,GAAGT,OAAO,CAAA,CAAE,GAAGA,OAAOI,MAAM,CAAA,EAAGC,YAAW,CAAA;AAQvD,UAAI,OAAQG,eAA2B,UAAU;AAC/C,cAAM,IAAIL,MACR,IAAIM,IAAAA,4DAAgED,UAAAA,OAAiBD,gBAAgBG,SAAY,oBAAoBC,OAAOJ,WAAAA,CAAAA,iHAC1I;MAEN;AAKA,UAAIA,gBAAgBG,QAAW;AAC7B,cAAM,IAAIP,MAAM,IAAIM,IAAAA,yFAA6F;MACnH;AACAG,kBAAYN,QAAQK,OAAOJ,WAAAA,GAAcP,QAAQC,SAASC,OAAAA;IAC5D;EACF;AACF;AAvCSH;AA0CF,IAAMc,MAAMd,oBAAoB,KAAA;AAEhC,IAAMe,OAAOf,oBAAoB,MAAA;AAEjC,IAAMgB,MAAMhB,oBAAoB,KAAA;AAEhC,IAAMiB,QAAQjB,oBAAoB,OAAA;AAElC,IAAMkB,SAASlB,oBAAoB,QAAA;AAGnC,IAAMmB,QAAQnB,oBAAoB,OAAA;;;AC5EzC,IAAMoB,QAAQ;AAEP,SAASC,kBAAkBC,MAAeC,WAAmBC,MAAY;AAC9E,MAAI,OAAOF,SAAS,YAAYA,KAAKG,KAAI,MAAO,IAAI;AAClD,UAAM,IAAIC,MACR,GAAGH,SAAAA,0CAA8CC,IAAAA,uEACC;EAEtD;AACA,MAAI,CAACJ,MAAMO,KAAKL,IAAAA,GAAO;AACrB,UAAM,IAAII,MACR,GAAGH,SAAAA,UAAmBD,IAAAA,8IACkE;EAE5F;AACF;AAbgBD;;;ACoCT,IAAMO,eAA8BC,uBAAOC,IAAI,6BAAA;AAC/C,IAAMC,iBAAgCF,uBAAOC,IAAI,+BAAA;AAaxD,SAASE,UAAUC,MAAY;AAC7B,SAAOA;AACT;AAFSD;AAMF,SAASE,QAAQC,SAAuB;AAC7C,SAAO,SAA+DF,MAAO;AAC3E,UAAMG,UAAUJ,UAAUC,IAAAA;AAC1BI,WAAOC,eAAeF,SAASR,cAAc;MAC3CW,OAAOJ;MACPK,YAAY;MACZC,cAAc;MACdC,UAAU;IACZ,CAAA;AACAL,WAAOC,eAAeF,SAAS,aAAa;MAC1CG,OAAO;MACPC,YAAY;MACZC,cAAc;MACdC,UAAU;IACZ,CAAA;AACA,WAAOT;EACT;AACF;AAjBgBC;AAqBT,SAASS,GAAGC,OAAa;AAC9B,SAAO,SAAUC,QAAgBC,QAAuB;AAEtD,UAAMV,UAAUJ,UAAWa,OAAmC,WAAW;AACzE,UAAME,WAAWX,QAAQL,cAAAA;AACzB,UAAMiB,UAAwBD,WAAW;SAAIA;QAAY,CAAA;AACzDC,YAAQC,KAAK;MAAEL;MAAOE,QAAQI,OAAOJ,MAAAA;IAAQ,CAAA;AAC7CT,WAAOC,eAAeF,SAASL,gBAAgB;MAC7CQ,OAAOS;MACPR,YAAY;MACZC,cAAc;MACdC,UAAU;IACZ,CAAA;EACF;AACF;AAdgBC;AA8BT,SAASQ,mBAAmBlB,MAAY;AAM7C,QAAM,EAAEmB,MAAMJ,QAAO,IAAKK,gBAAgBpB,IAAAA;AAC1C,SAAO;IACLqB,MAAMF,KAAKE;IACXC,UAAUH,KAAKG;IACfC,WAAWJ,KAAKK,OAAOC;IACvBC,QAAQX,QAAQY,IAAI,CAACC,MAAMA,EAAEjB,KAAK;EACpC;AACF;AAbgBO;AAgBhB,SAASE,gBAAgBpB,MAAY;AAInC,QAAMG,UAAUJ,UAAUC,IAAAA;AAC1B,QAAMmB,OAAOhB,QAAQR,YAAAA;AACrB,QAAMoB,UAAUZ,QAAQL,cAAAA,KAAmB,CAAA;AAE3C,MAAI,CAACqB,MAAM;AACT,UAAM,IAAIU,MACR,4DAA6D7B,KAA2BqB,QAAQ,WAAA,GAAc;EAElH;AACAS,oBAAkBX,KAAKE,MAAM,YAAY,SAAA;AACzC,MAAI,CAACF,KAAKG,YAAY,CAACH,KAAKY,WAAW;AACrC,UAAM,IAAIF,MACR,gJACE;EAEN;AAMA,MAAIV,KAAKG,YAAYH,KAAKY,WAAW;AACnC,UAAM,IAAIF,MACR,qLACE;EAEN;AACA,MAAIV,KAAKY,WAAW;AAClB,UAAMC,MAAMb,KAAKY;AAIjB,QAAI,CAACC,IAAIC,QAAQ;AACf,YAAM,IAAIJ,MAAM,iFAAA;IAClB;AACA,QAAIG,IAAIE,SAAS,iBAAiBF,IAAIE,SAAS,aAAa;AAC1D,YAAM,IAAIL,MAAM,+CAA+CG,IAAIE,IAAI,GAAG;IAC5E;AACA,QAAIF,IAAIG,aAAa,SAASH,IAAIG,aAAa,UAAU;AACvD,YAAM,IAAIN,MAAM,mDAAmDG,IAAIG,QAAQ,GAAG;IACpF;AACA,QAAI,CAACH,IAAII,OAAOC,SAAS,QAAA,GAAW;AAClC,YAAM,IAAIR,MAAM,6FAAA;IAClB;AACA,QAAIG,IAAII,MAAMC,SAAS,MAAA,KAAW,CAACL,IAAIM,iBAAiB;AACtD,YAAM,IAAIT,MAAM,gFAAA;IAClB;EACF;AACA,MAAI,CAACV,KAAKK,QAAQC,KAAK;AACrB,UAAM,IAAII,MAAM,iDAAA;EAClB;AACA,MAAId,QAAQwB,WAAW,GAAG;AACxB,UAAM,IAAIV,MAAM,4CAAA;EAClB;AACA,SAAO;IAAEV;IAAMJ;EAAQ;AACzB;AA3DSK;AA6DF,SAASoB,iBAAiBxC,MAAcyC,WAAoB;AACjE,QAAM,EAAEtB,MAAMJ,QAAO,IAAKK,gBAAgBpB,IAAAA;AAE1C,QAAM0C,WAAWD,UAAUE,IAAI3C,IAAAA;AAK/B,QAAM0B,SAA8CtB,uBAAOwC,OAAO,IAAA;AAClE,aAAWC,SAAS9B,SAAS;AAC3B,QAAIX,OAAO0C,UAAUC,eAAeC,KAAKtB,QAAQmB,MAAMlC,KAAK,GAAG;AAC7D,YAAM,IAAIkB,MAAM,QAAQgB,MAAMlC,KAAK,uCAAuC;IAC5E;AACAe,WAAOmB,MAAMlC,KAAK,IAAI,CAACA,OAAOsC,YAC3BP,SAASG,MAAMhC,MAAM,EAA0BmC,KAAKN,UAAU/B,OAAOsC,OAAAA;EAC1E;AAEA,SAAO;IACL,GAAI9B,KAAKG,WAAW;MAAEA,UAAUH,KAAKG;IAAS,IAAI,CAAC;IACnD,GAAIH,KAAKY,YAAY;MAAEA,WAAWZ,KAAKY;IAAU,IAAI,CAAC;IACtDP,QAAQL,KAAKK;IACbE;EACF;AACF;AAvBgBc;;;ACjKT,IAAMU,OAAN,cAAmBC,MAAAA;EAtC1B,OAsC0BA;;;EACxB,YAAYC,QAAgB;AAC1B,UAAMA,MAAAA;AACN,SAAKC,OAAO;EACd;AACF;AAEO,IAAMC,gBAA+BC,uBAAOC,IAAI,8BAAA;AAQhD,SAASC,KAAKC,OAAa;AAChC,SAAO,SAAUC,QAAgBC,QAAuB;AACtD,UAAMC,UAAWF,OAAmC;AACpD,UAAMG,WAAWD,QAAQP,aAAAA;AACzB,UAAMS,UAAwBD,WAAW;SAAIA;QAAY,CAAA;AACzDC,YAAQC,KAAK;MAAEN;MAAOE,QAAQK,OAAOL,MAAAA;IAAQ,CAAA;AAC7CM,WAAOC,eAAeN,SAASP,eAAe;MAC5Cc,OAAOL;MACPM,YAAY;MACZC,cAAc;MACdC,UAAU;IACZ,CAAA;EACF;AACF;AAbgBd;AAoBhB,SAASe,KAAKC,UAAkCV,SAAuBW,MAAY;AACjF,QAAMC,MAA8BT,uBAAOU,OAAO,IAAA;AAClD,aAAWC,SAASd,SAAS;AAC3B,QAAIG,OAAOY,UAAUC,eAAeC,KAAKL,KAAKE,MAAMnB,KAAK,GAAG;AAC1D,YAAM,IAAIP,MAAM,GAAGuB,IAAAA,KAASG,MAAMnB,KAAK,0CAA0C;IACnF;AAIA,UAAMuB,KAAKR,SAASI,MAAMjB,MAAM;AAChC,QAAI,OAAOqB,OAAO,YAAY;AAC5B,YAAM,IAAI9B,MAAM,GAAGuB,IAAAA,KAASG,MAAMnB,KAAK,uBAAuBmB,MAAMjB,MAAM,gBAAgB;IAC5F;AACAe,QAAIE,MAAMnB,KAAK,IAAI,CAACA,OAAOwB,SAASD,GAAGD,KAAKP,UAAUf,OAAOwB,IAAAA;EAC/D;AACA,SAAOP;AACT;AAhBSH;AAyBF,SAASW,cAAcC,MAAcC,WAAoB;AAC9D,QAAMxB,UAAUuB;AAChB,QAAME,kBAAmBzB,QAAQP,aAAAA,KAAkB,CAAA;AACnD,QAAMiC,kBAAmB1B,QAAQ2B,cAAAA,KAAmB,CAAA;AAEpD,MAAIF,gBAAgBG,WAAW,KAAKF,gBAAgBE,WAAW,GAAG;AAChE,UAAM,IAAItC,MACR,GAAIiC,KAA2B/B,QAAQ,cAAA,4GACrC;EAEN;AAEA,QAAMoB,WAAWY,UAAUK,IAAIN,IAAAA;AAC/B,SAAO;IACLO,UAAUnB,KAAKC,UAAUa,iBAAiB,OAAA;IAC1CM,WAAWpB,KAAKC,UAAUc,iBAAiB,KAAA;EAC7C;AACF;AAjBgBJ;AAyBT,SAASU,gBAAgBT,MAAY;AAC1C,QAAMvB,UAAUuB;AAChB,QAAME,kBAAmBzB,QAAQP,aAAAA,KAAkB,CAAA;AACnD,QAAMiC,kBAAmB1B,QAAQ2B,cAAAA,KAAmB,CAAA;AACpD,MAAIF,gBAAgBG,WAAW,KAAKF,gBAAgBE,WAAW,GAAG;AAChE,UAAM,IAAItC,MACR,GAAIiC,KAA2B/B,QAAQ,cAAA,4GACrC;EAEN;AACA,SAAO;IACLsC,UAAUL,gBAAgBQ,IAAI,CAACC,MAAMA,EAAErC,KAAK;IAC5CkC,WAAWL,gBAAgBO,IAAI,CAACC,MAAMA,EAAErC,KAAK;EAC/C;AACF;AAdgBmC;;;ACGT,SAASG,OACdC,SACAC,QAA+D;AAE/D,QAAM,EAAEC,MAAMC,WAAW,GAAGC,aAAAA,IAAiBH;AAC7CI,4BAA0BD,YAAAA;AAC1B,QAAME,UAAwB;IAC5BF;IACA,GAAIF,SAASK,SAAY;MAAEL;IAAK,IAAI,CAAC;IACrC,GAAIC,cAAcI,SAAY;MAAEJ;IAAU,IAAI,CAAC;EACjD;AACA,SAAO,SAAUK,QAAQC,aAAW;AAGlCC,gBAAYF,QAAQG,OAAOF,WAAAA,GAAc,QAAQT,SAASM,OAAAA;EAC5D;AACF;AAhBgBP;AA2BT,SAASa,iBAAAA;AACd,SAAO,SAAUJ,QAAQC,aAAaI,gBAAc;AAClDC,gBAAYN,QAAQG,OAAOF,WAAAA,GAAc;MACvCM,OAAOF;MACPG,MAAM;IACR,CAAA;EACF;AACF;AAPgBJ;AAeT,SAASP,0BAA0BY,GAAe;AACvD,MAAIA,MAAM,QAAQ,OAAOA,MAAM,UAAU;AACvC,UAAM,IAAIC,MAAM,gEAAA;EAClB;AAOA,QAAMC,SAAmBF,EAA2BE;AACpD,MAAI,OAAOA,WAAW,YAAYA,OAAOC,WAAW,GAAG;AACrD,UAAM,IAAIF,MAAM,uDAAA;EAClB;AACA,MAAI,OAAOD,EAAEI,iBAAiB,YAAYJ,EAAEI,aAAaD,WAAW,GAAG;AACrE,UAAM,IAAIF,MAAM,8DAAA;EAClB;AACF;AAjBgBb;;;ACpET,SAASiB,IACdC,UAAU,IACVC,QAA4D;AAE5D,QAAM,EAAEC,MAAMC,WAAW,GAAGC,UAAAA,IAAcH;AAC1C,QAAMI,UAAwB;IAC5BD;IACA,GAAIF,SAASI,SAAY;MAAEJ;IAAK,IAAI,CAAC;IACrC,GAAIC,cAAcG,SAAY;MAAEH;IAAU,IAAI,CAAC;EACjD;AACA,SAAO,SAAUI,QAAQC,aAAW;AAClCC,gBAAYF,QAAQG,OAAOF,WAAAA,GAAc,QAAQR,SAASK,OAAAA;EAC5D;AACF;AAbgBN;AAmBT,SAASY,SAAAA;AACd,SAAO,SAAUJ,QAAQC,aAAaI,gBAAc;AAClDC,gBAAYN,QAAQG,OAAOF,WAAAA,GAAc;MAAEM,OAAOF;MAAgBG,MAAM;IAAS,CAAA;EACnF;AACF;AAJgBJ;AAoBT,SAASK,SAAAA;AACd,SAAO,SAAUT,QAAQC,aAAaI,gBAAc;AAClDC,gBAAYN,QAAQG,OAAOF,WAAAA,GAAc;MAAEM,OAAOF;MAAgBG,MAAM;IAAS,CAAA;EACnF;AACF;AAJgBC;;;ACnFhB,IAAMC,mBAAmB;AAezB,SAASC,cAAcC,SAAe;AACpC,MAAIA,QAAQC,SAAS,GAAA,GAAM;AACzB,UAAM,IAAIC,MACR,UAAUF,OAAAA,yEACEA,QAAQG,QAAQ,OAAO,GAAA,CAAA,yCAAwC;EAE/E;AACA,QAAMC,WAAWJ,QAAQK,MAAM,GAAA;AAC/B,MAAID,SAASE,KAAK,CAACC,MAAMA,MAAM,EAAA,GAAK;AAClC,UAAM,IAAIL,MAAM,UAAUF,OAAAA,2DAA6D;EACzF;AACA,QAAMQ,OAAO,oBAAIC,IAAAA;AACjB,aAAWF,KAAKH,UAAU;AACxB,QAAI,CAACG,EAAEG,WAAW,GAAA,KAAQ,CAACH,EAAEI,SAAS,GAAA,EAAM;AAC5C,UAAMC,OAAOL,EAAEM,MAAM,GAAG,EAAC;AACzB,QAAID,SAAS,GAAI,OAAM,IAAIV,MAAM,UAAUF,OAAAA,8BAAqC;AAChF,QAAIQ,KAAKM,IAAIF,IAAAA,GAAO;AAClB,YAAM,IAAIV,MAAM,UAAUF,OAAAA,mBAA0BY,IAAAA,mBAAuB;IAC7E;AACAJ,SAAKO,IAAIH,IAAAA;EACX;AACF;AArBSb;AAwCF,SAASiB,KAAKhB,SAAiBiB,SAAoB;AACxD,SAAO,SAA+DC,MAAO;AAC3EnB,kBAAcC,OAAAA;AAIdmB,eAAWD,MAAM;MACflB;MACAoB,QAAQH,QAAQG;MAChBC,SAASJ,QAAQI,WAAWvB;IAC9B,CAAA;AACA,WAAOoB;EACT;AACF;AAbgBF;AAehB,SAASM,cAAcC,MAAc;AACnC,SAAO,MACL,SAAUC,QAAgBC,aAA4B;AACpDC,mBAAeF,QAAQD,MAAMI,OAAOF,WAAAA,CAAAA;EACtC;AACJ;AALSH;AAQF,IAAMM,cAAcN,cAAc,WAAA;AAclC,IAAMO,UAAUP,cAAc,OAAA;AAG9B,IAAMQ,SAASR,cAAc,MAAA;AAG7B,IAAMS,UAAUT,cAAc,OAAA;AAG9B,IAAMU,UAAUV,cAAc,OAAA;AAQ9B,SAASW,UAAUrB,MAAcsB,QAAkB;AACxD,SAAO,SAAUV,QAAgBC,aAA4B;AAC3DU,sBAAkBX,QAAQZ,MAAMe,OAAOF,WAAAA,GAAcS,MAAAA;EACvD;AACF;AAJgBD;;;AChJhB,SAASG,mBACPC,MACAC,OAA8C;AAE9C,SAAO,SAAUC,QAAQC,aAAaC,gBAAc;AAClDC,gBAAYH,QAAQI,OAAOH,WAAAA,GAAc;MACvCI,OAAOH;MACPJ;MACA,GAAIC,OAAOO,WAAWC,SAAY;QAAED,QAAQP,MAAMO;MAAO,IAAI,CAAC;MAC9D,GAAIP,OAAOS,SAASD,SAAY;QAAEC,MAAMT,MAAMS;MAAK,IAAI,CAAC;IAC1D,CAAA;EACF;AACF;AAZSX;AAgBF,SAASY,KAAKH,QAAkB;AACrC,SAAOT,mBAAmB,QAAQ;IAAES;EAAO,CAAA;AAC7C;AAFgBG;AAMT,SAASC,YAAYJ,QAAkB;AAC5C,SAAOT,mBAAmB,SAAS;IAAES;EAAO,CAAA;AAC9C;AAFgBI;AAMT,SAASC,QAAQL,QAAmB;AACzC,SAAOT,mBAAmB,WAAWS,WAAWC,SAAY;IAAED;EAAO,IAAIC,MAAAA;AAC3E;AAFgBI;AAKT,SAASC,MAAMJ,MAAY;AAChC,SAAOX,mBAAmB,SAAS;IAAEW;EAAK,CAAA;AAC5C;AAFgBI;AAMT,SAASC,OAAAA;AACd,SAAOhB,mBAAmB,MAAA;AAC5B;AAFgBgB;AAMT,SAASC,eAAAA;AACd,SAAOjB,mBAAmB,cAAA;AAC5B;AAFgBiB;AAKT,SAASC,SAAAA;AACd,SAAOlB,mBAAmB,QAAA;AAC5B;AAFgBkB;AAKT,SAASC,YAAAA;AACd,SAAOnB,mBAAmB,WAAA;AAC5B;AAFgBmB;AAKT,SAASC,UAAAA;AACd,SAAOpB,mBAAmB,SAAA;AAC5B;AAFgBoB;AAKT,SAASC,MAAAA;AACd,SAAOrB,mBAAmB,KAAA;AAC5B;AAFgBqB;;;ACzCT,SAASC,iBAAiBC,KAAsB;AACrD,QAAM,IAAIC,MACR,8VAIE;AAEN;AARgBF;;;AC/BT,SAASG,uBAAuBC,YAAkB;AACvD,QAAMC,UAAUD,WAAWE,KAAI;AAC/B,MAAID,YAAY,IAAI;AAClB,WAAO;EACT;AAEA,QAAME,QAAQF,QAAQG,MAAM,KAAA;AAC5B,MAAID,MAAME,WAAW,GAAG;AACtB,WAAO,4BAA4BJ,OAAAA,6DAAoEE,MAAME,MAAM;EACrH;AAEA,QAAMC,aAAa;IAAC;IAAU;IAAQ;IAAgB;IAAS;;AAC/D,QAAMC,cAAkC;IACtC;MAAC;MAAG;;IACJ;MAAC;MAAG;;IACJ;MAAC;MAAG;;IACJ;MAAC;MAAG;;IACJ;MAAC;MAAG;;;AAGN,WAASC,IAAI,GAAGA,IAAI,GAAGA,KAAK;AAC1B,UAAMC,QAAQN,MAAMK,CAAAA;AACpB,UAAME,OAAOJ,WAAWE,CAAAA;AACxB,UAAM,CAACG,KAAKC,GAAAA,IAAOL,YAAYC,CAAAA;AAE/B,UAAMK,QAAQC,kBAAkBL,OAAOC,MAAMC,KAAKC,GAAAA;AAClD,QAAIC,UAAU,MAAM;AAClB,aAAOA;IACT;EACF;AAEA,SAAO;AACT;AAhCgBd;AAkChB,SAASe,kBACPL,OACAC,MACAC,KACAC,KAAW;AAGX,QAAMG,YAAYN,MAAML,MAAM,GAAA;AAC9B,aAAWY,QAAQD,WAAW;AAE5B,UAAME,YAAYD,KAAKZ,MAAM,GAAA;AAC7B,QAAIa,UAAUZ,SAAS,GAAG;AACxB,aAAO,WAAWK,IAAAA,YAAgBD,KAAAA;IACpC;AAEA,UAAMS,OAAOD,UAAU,CAAA;AACvB,UAAME,OAAOF,UAAU,CAAA;AAEvB,QAAIE,SAASC,QAAW;AACtB,YAAMC,UAAUC,OAAOH,IAAAA;AACvB,UAAI,CAACG,OAAOC,UAAUF,OAAAA,KAAYA,UAAU,GAAG;AAC7C,eAAO,yBAAyBX,IAAAA,YAAgBD,KAAAA;MAClD;IACF;AAEA,QAAIS,SAAS,KAAK;AAChB;IACF;AAGA,QAAIA,KAAKM,SAAS,GAAA,GAAM;AACtB,YAAMC,aAAaP,KAAKd,MAAM,GAAA;AAC9B,UAAIqB,WAAWpB,WAAW,GAAG;AAC3B,eAAO,oBAAoBK,IAAAA,YAAgBD,KAAAA;MAC7C;AACA,YAAMiB,aAAaJ,OAAOG,WAAW,CAAA,CAAE;AACvC,YAAME,WAAWL,OAAOG,WAAW,CAAA,CAAE;AACrC,UACE,CAACH,OAAOC,UAAUG,UAAAA,KAClB,CAACJ,OAAOC,UAAUI,QAAAA,KAClBD,aAAaf,OACbgB,WAAWf,OACXc,aAAaC,UACb;AACA,eAAO,oBAAoBjB,IAAAA,YAAgBD,KAAAA;MAC7C;AACA;IACF;AAGA,UAAMmB,MAAMN,OAAOJ,IAAAA;AACnB,QAAI,CAACI,OAAOC,UAAUK,GAAAA,KAAQA,MAAMjB,OAAOiB,MAAMhB,KAAK;AACpD,aAAO,oBAAoBF,IAAAA,YAAgBD,KAAAA;IAC7C;EACF;AAEA,SAAO;AACT;AAzDSK;;;ACFT,IAAMe,0BAA0B;AAChC,IAAMC,sBAAsB;AAC5B,IAAMC,gBAAgB;AACtB,IAAMC,YAAY;AAEX,IAAMC,WAA0BC,uBAAOC,IAAI,yBAAA;AAO3C,SAASC,IAAIC,SAAmB;AACrC,SAAO,SAA+DC,MAAO;AAC3E,UAAMC,UAAUD;AAChBE,WAAOC,eAAeF,SAASN,UAAU;MACvCS,OAAOL;MACPM,YAAY;MACZC,cAAc;MACdC,UAAU;IACZ,CAAA;AACAL,WAAOC,eAAeF,SAAS,aAAa;MAC1CG,OAAO;MACPC,YAAY;MACZC,cAAc;MACdC,UAAU;IACZ,CAAA;AACA,WAAOP;EACT;AACF;AAjBgBF;AAoCT,SAASU,eAAeR,MAAY;AACzC,QAAMS,OAAQT,KAAoBL,QAAAA;AAClC,MAAI,CAACc,MAAM;AACT,UAAM,IAAIC,MACR,mDAAoDV,KAA2BW,QAAQ,WAAA,GAAc;EAEzG;AACAC,oBAAkBH,KAAKE,MAAM,QAAQ,KAAA;AACrC,MAAI,CAACF,KAAKI,YAAYJ,KAAKI,SAASC,KAAI,MAAO,IAAI;AACjD,UAAM,IAAIJ,MAAM,4CAAA;EAClB;AACA,QAAMK,YAAYC,uBAAuBP,KAAKI,QAAQ;AACtD,MAAIE,WAAW;AACb,UAAM,IAAIL,MAAM,sCAAsCK,SAAAA,EAAW;EACnE;AAEA,QAAME,UAAUR,KAAKQ,WAAW1B;AAChC,MAAI,CAAC2B,OAAOC,UAAUF,OAAAA,KAAYA,WAAW,GAAG;AAC9C,UAAM,IAAIP,MAAM,2DAAA;EAClB;AACA,MAAIO,UAAUzB,qBAAqB;AACjC,UAAM,IAAIkB,MAAM,gCAAgClB,mBAAAA,mBAAsC;EACxF;AAEA,QAAM4B,QAAQX,KAAKW,SAAS3B;AAC5B,MAAI,CAACyB,OAAOC,UAAUC,KAAAA,KAAUA,QAAQ,GAAG;AACzC,UAAM,IAAIV,MAAM,+DAAA;EAClB;AACA,MAAIU,QAAQ1B,WAAW;AACrB,UAAM,IAAIgB,MAAM,yCAAyChB,SAAAA,EAAW;EACtE;AAEA,SAAO;IAAEiB,MAAMF,KAAKE;IAAME,UAAUJ,KAAKI;IAAUI;IAASG;EAAM;AACpE;AAjCgBZ;AA4CT,SAASa,aAAarB,MAAcsB,WAAoB;AAC7D,QAAM,EAAEX,MAAME,UAAUI,SAASG,MAAK,IAAKZ,eAAeR,IAAAA;AAE1D,QAAMuB,WAAWD,UAAUE,IAAIxB,IAAAA;AAC/B,MAAI,OAAOuB,SAASE,QAAQ,YAAY;AACtC,UAAM,IAAIf,MAAM,+CAAA;EAClB;AACA,QAAMe,MAAMF,SAASE,IAAIC,KAAKH,QAAAA;AAE9B,SAAO;IAAEZ;IAAME;IAAUI;IAASG;IAAOO,SAASF;EAAI;AACxD;AAVgBJ;;;AC2VhB,SAASO,SAAS;","names":["PalbaseModuleError","Error","code","status","details","message","name","makeHttpClient","cfg","request","method","path","options","headers","apiKey","init","body","undefined","Uint8Array","FormData","Blob","JSON","stringify","signal","doFetch","fetchImpl","globalThis","fetch","response","baseUrl","err","data","error","contentType","get","parsed","includes","json","catch","startsWith","arrayBuffer","text","ok","error_description","statusText","RoleNotDefined","Error","role","message","name","refuse","error","code","PalbaseModuleError","rolesPath","userId","base","encodeURIComponent","undefined","buildAuthClient","http","assignRole","request","revokeRole","rolesOf","data","roles","SEGMENT_RE","validateSegment","segment","label","test","Error","source","buildDocumentRef","http","path","set","data","request","body","get","response","error","status","raw","exists","undefined","Boolean","id","segments","split","length","ref","update","delete","collection","name","buildCollectionRef","state","where","orderBy","snapshot","doc","querySnapshot","docs","empty","size","docChanges","map","type","add","resp","field","op","value","direction","limit","n","narrowed","queryBody","documents","w","o","MAX_BATCH","buildDocumentsClient","String","filter","s","forEach","i","join","batch","operations","PalbaseModuleError","FLAG_NAME_RE","assertFlagName","flagName","test","Error","source","flagEnabled","value","flagVariant","name","isContextObject","v","Array","isArray","buildFlagsClient","http","cfg","resolveUserId","context","userId","getCurrentUserId","undefined","mergedPath","uid","encodeURIComponent","fetchMerged","request","service","setOverrideForUser","key","body","setOverridesForUser","values","clearOverrideForUser","clearAllOverridesForUser","batchSetOverrides","operations","ops","map","op","raw","user_id","isEnabled","res","error","data","status","getVariant","get","defaultOrContext","maybeContext","defaultValue","hasDefault","resp","getAll","Object","keys","flag","enabled","variant","setOverride","message","asService","mapEnvelope","res","map","error","data","undefined","status","toEmailTemplate","wire","view","id","slug","locale","subject","htmlBody","html_body","variables","isDefault","is_default","createdAt","created_at","updatedAt","updated_at","text_body","textBody","toSmsTemplate","body","buildNotificationsClient","http","push","send","params","request","email","templateSlug","html","text","rest","template_slug","sms","whatsapp","userId","user_id","events","options","query","limit","encodeURIComponent","String","verifications","start","check","inbox","list","opts","URLSearchParams","cursor","set","is_read","category","include_archived","toString","unreadCount","markRead","markAllRead","archive","preferences","get","update","emailTemplates","resp","rows","create","input","delete","smsTemplates","templates","registerDevice","unregisterDevice","deviceId","createHmac","mintToken","secret","now","Math","floor","Date","header","Buffer","from","JSON","stringify","alg","typ","toString","payload","iss","role","iat","exp","sig","createHmac","update","digest","buildRealtimeClient","cfg","url","baseUrl","stateUrl","writeState","topic","key","value","del","length","data","error","PalbaseModuleError","apiJwtSecret","token","err","Error","message","op","doFetch","fetchImpl","globalThis","fetch","response","method","headers","Authorization","body","ops","status","undefined","detail","text","catch","state","set","clear","broadcast","channel","event","messages","private","slice","BUCKET_NAME_RE","STORAGE_PATH_RE","STORAGE_TRAVERSAL_RE","validateStoragePath","p","test","Error","source","toFileObject","bucket","row","name","path","size","contentType","checksum","width","height","thumbhash","variants","mapResponse","res","map","error","data","undefined","status","buildBucketClient","http","bucketName","publicOrigin","objectPath","upload","file","options","headers","upsert","body","ArrayBuffer","Uint8Array","request","r","download","Accept","getPublicUrl","variant","encodeURIComponent","createSignedUrl","expiresIn","list","prefix","params","URLSearchParams","set","limit","String","query","toString","objects","remove","paths","removed","push","move","from","to","copy","buildStorageClient","replace","buildModuleClients","cfg","baseUrl","replace","apiKey","serviceRoleKey","http","makeHttpClient","fetchImpl","Auth","buildAuthClient","Documents","buildDocumentsClient","Storage","buildStorageClient","publicOrigin","Notifications","buildNotificationsClient","Flags","buildFlagsClient","getCurrentUserId","Realtime","buildRealtimeClient","apiJwtSecret","realtimeApiJwtSecret","CHANNELS","Symbol","for","ownerOnly","kind","publicChannel","opts","publish","state","paramCount","pattern","split","filter","s","startsWith","endsWith","length","defineChannels","map","entries","entry","Object","Error","push","c","authorize","handler","def","carrier","globalThis","existing","sameDeclaration","e","join","wireRow","JSON","stringify","read","write","toString","a","b","every","x","i","defineRepository","table","opts","tenantColumn","tenant","rowKey","key","scope","scopeRow","id","scopedPayload","values","Repository","list","findMany","where","find","rows","limit","insert","update","patch","row","updateScoped","NotFound","String","updateMany","set","delete","deleteMany","liveNames","names","Set","sort","memberName","name","test","JSON","stringify","members","length","map","n","join","bucketMembers","buckets","normalized","b","variants","byName","Map","set","keys","rows","get","union","v","makeStackDts","secrets","flags","makeMethodDecorator","method","subpath","options","Error","slice","toLowerCase","target","propertyKey","descriptor","verb","undefined","String","recordRoute","Get","Post","Put","Patch","Delete","Query","SHAPE","assertSurfaceName","name","decorator","kind","trim","Error","test","WEBHOOK_META","Symbol","for","WEBHOOK_EVENTS","carrierOf","ctor","Webhook","options","carrier","Object","defineProperty","value","enumerable","configurable","writable","On","event","target","fnName","existing","entries","push","String","getWebhookManifest","meta","validateWebhook","name","provider","secretEnv","secret","env","events","map","e","Error","assertSurfaceName","signature","sig","header","algo","encoding","signs","includes","timestampHeader","length","getWebhookConfig","container","instance","get","create","entry","prototype","hasOwnProperty","call","metaArg","Deny","Error","reason","name","HOOK_BLOCKING","Symbol","for","Hook","event","target","fnName","carrier","existing","entries","push","String","Object","defineProperty","value","enumerable","configurable","writable","bind","instance","kind","out","create","entry","prototype","hasOwnProperty","call","fn","meta","getHookConfig","ctor","container","blockingEntries","listenerEntries","WEBHOOK_EVENTS","length","get","blocking","listeners","getHookManifest","map","e","Upload","subpath","config","auth","rateLimit","uploadConfig","validateUploadConfigShape","options","undefined","target","propertyKey","recordRoute","String","UploadedObject","parameterIndex","recordParam","index","kind","c","Error","bucket","length","pathTemplate","Sse","subpath","config","auth","rateLimit","sseConfig","options","undefined","target","propertyKey","recordRoute","String","SseOut","parameterIndex","recordParam","index","kind","Signal","DEFAULT_GRACE_MS","assertPattern","pattern","includes","Error","replace","segments","split","some","s","seen","Set","startsWith","endsWith","name","slice","has","add","Room","options","ctor","recordRoom","events","graceMs","hookDecorator","hook","target","propertyKey","recordRoomHook","String","OnAuthorize","OnFirst","OnJoin","OnLeave","OnEmpty","OnMessage","schema","recordRoomMessage","makeParamDecorator","kind","extra","target","propertyKey","parameterIndex","recordParam","String","index","schema","undefined","name","Body","QueryParams","Headers","Param","User","OptionalUser","Client","RequestId","TraceId","Req","defineMiddleware","_fn","Error","validateCronExpression","expression","trimmed","trim","parts","split","length","fieldNames","fieldRanges","i","field","name","min","max","error","validateCronField","listParts","part","stepParts","base","step","undefined","stepNum","Number","isInteger","includes","rangeParts","rangeStart","rangeEnd","num","DEFAULT_TIMEOUT_SECONDS","MAX_TIMEOUT_SECONDS","DEFAULT_RETRY","MAX_RETRY","JOB_META","Symbol","for","Job","options","ctor","carrier","Object","defineProperty","value","enumerable","configurable","writable","getJobManifest","meta","Error","name","assertSurfaceName","schedule","trim","cronError","validateCronExpression","timeout","Number","isInteger","retry","getJobConfig","container","instance","get","run","bind","handler","z"]}
1
+ {"version":3,"sources":["../src/clients/http.ts","../src/clients/auth.ts","../src/clients/documents.ts","../src/clients/flags.ts","../src/clients/notifications.ts","../src/clients/realtime.ts","../src/clients/storage.ts","../src/clients/index.ts","../src/channels.ts","../src/db/repository.ts","../src/decorators/methods.ts","../src/decorators/surface-name.ts","../src/decorators/webhook.ts","../src/decorators/hook.ts","../src/decorators/upload.ts","../src/decorators/sse.ts","../src/decorators/room.ts","../src/decorators/params.ts","../src/middleware.ts","../src/job.ts","../src/decorators/job.ts","../src/index.ts"],"sourcesContent":["/**\n * http.ts — the transport every module client speaks over.\n *\n * WHY IT IS HERE. This code, and the five clients built on it, spent their life\n * in `v2/runtime/internal/runtime/module-clients.js`: 1,768 lines of untyped\n * CommonJS that entered the SDK through an `@ts-expect-error` and left through\n * `unknown` casts. The interfaces those clients implement were always in this\n * package — only the implementations were outside it, where nothing checked one\n * against the other. Two defects came through that gap on 2026-08-15 (a type\n * that described a different server's columns; an accessor that was `undefined`\n * in a deployed handler), and both were green on each side alone.\n *\n * WHAT IT IS NOT. Nothing Bun-specific lives here. The transport is a `fetch`\n * the caller may supply, so this package stays runtime-agnostic and the process\n * that knows which runtime it is decides what to hand in.\n */\n\nimport type { PalbaseResult } from \"../endpoint.js\";\n\n/** Per-request options a module client may pass. */\nexport interface RequestOptions {\n /** JSON-serialised unless it is a string, a Uint8Array, a Blob or FormData. */\n body?: unknown;\n headers?: Record<string, string>;\n signal?: AbortSignal;\n}\n\n/**\n * What a module client is given. An INTERFACE rather than a class, because the\n * clients depend on this shape and not on the thing that implements it — which\n * is what lets a test drive a whole client without a server.\n */\nexport interface ModuleTransport {\n /** The platform's base URL, for the rare client that must build a URL. */\n readonly baseUrl: string;\n request<T = unknown>(\n method: string,\n path: string,\n options?: RequestOptions,\n ): Promise<PalbaseResult<T>>;\n}\n\nexport interface TransportConfig {\n baseUrl: string;\n apiKey: string;\n /**\n * The `fetch` to use. Omitted means the ambient one — resolved at CALL time,\n * never captured here: the egress fence replaces `globalThis.fetch` after the\n * clients are built, and a captured reference would keep calling the\n * un-fenced original.\n */\n fetchImpl?: typeof fetch;\n}\n\n/**\n * A module call that failed.\n *\n * `code` is the platform's own error code (`forbidden`, `not_found`, …) so a\n * caller can branch on it without matching message text.\n */\nexport class PalbaseModuleError extends Error {\n readonly code: string;\n readonly status: number;\n readonly details: Record<string, unknown>;\n\n constructor(code: string, message: string, status: number, details: Record<string, unknown> = {}) {\n super(message);\n this.name = \"PalbaseModuleError\";\n this.code = code;\n this.status = status;\n this.details = details;\n }\n}\n\nexport function makeHttpClient(cfg: TransportConfig): ModuleTransport {\n async function request<T>(\n method: string,\n path: string,\n options: RequestOptions = {},\n ): Promise<PalbaseResult<T>> {\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n ...(options.headers ?? {}),\n };\n if (cfg.apiKey) headers[\"apikey\"] = cfg.apiKey;\n\n const init: RequestInit = { method, headers };\n if (options.body !== undefined) {\n if (typeof options.body === \"string\" || options.body instanceof Uint8Array) {\n init.body = options.body as RequestInit[\"body\"];\n } else if (typeof FormData !== \"undefined\" && options.body instanceof FormData) {\n // The platform writes Content-Type itself, WITH the multipart boundary.\n // Setting it here omits the boundary, and the server then parses zero\n // parts from a request that looks perfectly well formed.\n delete headers[\"Content-Type\"];\n init.body = options.body;\n } else if (typeof Blob !== \"undefined\" && options.body instanceof Blob) {\n delete headers[\"Content-Type\"];\n init.body = options.body;\n } else {\n init.body = JSON.stringify(options.body);\n }\n }\n if (options.signal) init.signal = options.signal;\n\n // Resolved HERE, per call. See TransportConfig.fetchImpl.\n const doFetch = cfg.fetchImpl ?? globalThis.fetch;\n\n let response: Response;\n try {\n response = await doFetch(`${cfg.baseUrl}${path}`, init);\n } catch (err) {\n // AN ENVELOPE, not an exception.\n //\n // This threw until 2026-08-15, and the throw made three separate claims\n // false at once:\n //\n // 1. The package's own rule — \"Response: { data, error }, no thrown API\n // errors\". Every client here is written to that contract.\n // 2. `Flags.get(key, default)`, whose documented behaviour is that the\n // default applies when the flag is absent AND when the service is\n // unreachable. It reads `resp.error !== null` to decide, and a throw\n // never reaches that branch: measured, `get(\"beta\", \"DEFAULT\")`\n // raised `connect ECONNREFUSED` instead of answering \"DEFAULT\". The\n // test that was supposed to cover it handed the client a hand-made\n // error envelope — a shape this code could not produce.\n // 3. Consistency with the Realtime client, which already envelopes a\n // network failure so a handler that wrote a row does not lose it\n // because pubsub was down.\n //\n // A caller destructuring { data, error } and checking `error` was being\n // defeated by an exception: the defensive code existed and did not help,\n // which is the worst kind of surprise to leave in a package.\n return {\n data: null,\n error: new PalbaseModuleError(\n \"network_error\",\n err instanceof Error ? err.message : \"Network request failed\",\n 0,\n ),\n status: 0,\n };\n }\n\n const contentType = response.headers.get(\"Content-Type\") ?? \"\";\n let parsed: unknown = null;\n if (method !== \"HEAD\" && contentType.includes(\"json\")) {\n parsed = await response.json().catch(() => null);\n } else if (method !== \"HEAD\" && contentType.startsWith(\"image/\")) {\n // QR codes and the like: hand back bytes the caller can write or forward.\n parsed = new Uint8Array(await response.arrayBuffer());\n } else if (method !== \"HEAD\" && response.body) {\n // A non-JSON error still says something; \"request failed\" says nothing.\n parsed = await response.text().catch(() => null);\n }\n\n if (!response.ok) {\n const body = (parsed && typeof parsed === \"object\" ? parsed : {}) as Record<string, unknown>;\n const code = typeof body.error === \"string\" && body.error ? body.error : \"unknown_error\";\n const message =\n (typeof body.error_description === \"string\" && body.error_description) ||\n response.statusText ||\n \"request failed\";\n return {\n data: null,\n error: new PalbaseModuleError(code, message, response.status, body),\n status: response.status,\n };\n }\n\n return { data: parsed as T, error: null, status: response.status };\n }\n\n return { baseUrl: cfg.baseUrl, request };\n}\n","/**\n * auth.ts — the role-assignment half of auth, as a backend handler reaches it.\n *\n * WHAT THIS IS NOT. It is not the client SDK's `auth` (sign-up, sign-in, MFA,\n * device attestation): those are a person acting on their OWN account, they run\n * in the app, and a server has no business holding them. This is the operator\n * verb — \"make this user an agent\" — and it exists because the product itself is\n * often where the promotion happens: a supervisor taps a button in the tenant's\n * own app, and the tenant's handler has to be able to write the assignment.\n *\n * THE CREDENTIAL IS THE POINT. `/admin/users/{uid}/roles/{role}` answers 403 to\n * anon and to `authenticated` alike (FR-013), so these calls ride the transport\n * built with the SERVICE-ROLE key. A backend is the only place that key exists;\n * putting this surface anywhere a client SDK could reach it would let an end\n * user grant themselves the permission the rest of the feature is about.\n *\n * IT THROWS, and the rest of this package envelopes. That is a deliberate split\n * and it comes from the SHAPE OF THE ANSWER: `assignRole` returns nothing, so a\n * failure it did not throw for would be indistinguishable from a write that\n * happened. The named `RoleNotDefined` is the one refusal a caller can act on —\n * the role names live in git, so a miss is a typo, not a runtime condition —\n * and every other refusal arrives as the transport's own `PalbaseModuleError`\n * with the platform's code on it.\n */\n\nimport type { PalbaseAuthAdminClient } from \"../clients.js\";\n\nimport { PalbaseModuleError, type ModuleTransport } from \"./http.js\";\n\n/**\n * The named refusal: this stack declares no role by that name.\n *\n * A role's DEFINITION is committed (`palbase roles`, lowered into the generated\n * client as an enum), so a name that misses is a typo in code rather than a\n * state a retry could fix. It carries the name it was asked for, because the\n * message alone would make a handler parse text to log which one failed.\n */\nexport class RoleNotDefined extends Error {\n readonly role: string;\n\n constructor(role: string, message?: string) {\n super(message ?? `No role named \"${role}\" is defined for this stack`);\n this.name = \"RoleNotDefined\";\n this.role = role;\n }\n}\n\n/** The wire body all three routes answer with: the assignment's RESULT. */\ninterface UserRolesBody {\n roles?: string[];\n}\n\n/**\n * Raise whatever the platform refused with.\n *\n * `role_not_defined` becomes the named class; everything else keeps the\n * transport's error, which already carries the platform's code and status, so a\n * caller can branch on `err.code` without matching message text.\n */\nfunction refuse(error: { message?: string; code?: string }, role: string): never {\n if (error.code === \"role_not_defined\") throw new RoleNotDefined(role, error.message);\n if (error instanceof PalbaseModuleError) throw error;\n throw new PalbaseModuleError(error.code ?? \"unknown_error\", error.message ?? \"request failed\", 0);\n}\n\n/** `/admin/users/{uid}/roles[/{role}]`, with both ids escaped: an id that\n * carried a slash would otherwise reach a different route entirely. */\nfunction rolesPath(userId: string, role?: string): string {\n const base = `/admin/users/${encodeURIComponent(userId)}/roles`;\n return role === undefined ? base : `${base}/${encodeURIComponent(role)}`;\n}\n\nexport function buildAuthClient(http: ModuleTransport): PalbaseAuthAdminClient {\n return {\n async assignRole(userId: string, role: string): Promise<void> {\n const { error } = await http.request<UserRolesBody>(\"PUT\", rolesPath(userId, role));\n if (error) refuse(error, role);\n },\n\n async revokeRole(userId: string, role: string): Promise<void> {\n const { error } = await http.request<UserRolesBody>(\"DELETE\", rolesPath(userId, role));\n if (error) refuse(error, role);\n },\n\n async rolesOf(userId: string): Promise<string[]> {\n const { data, error } = await http.request<UserRolesBody>(\"GET\", rolesPath(userId));\n // A FAILED READ IS NOT AN EMPTY LIST. Answering `[]` here would tell a\n // handler that a user holds nothing when the truth is that nobody could\n // say — and the handler would then deny them everything they hold.\n if (error) refuse(error, \"\");\n return data?.roles ?? [];\n },\n };\n}\n","/**\n * documents.ts — the Documents client, Firestore-shaped.\n *\n * Moved in from `v2/runtime/internal/runtime/module-clients.js:705-773` (plus\n * the `buildDocumentRef` / `buildCollectionRef` helpers above it) with its\n * behaviour intact: the same methods, the same paths, the same bodies. What\n * changed is that it now sits beside the interface it implements, so a drift\n * between the two is a compile error rather than a runtime surprise.\n */\n\nimport type {\n PalbaseCollectionRef,\n PalbaseDocsClient,\n PalbaseDocumentRef,\n PalbaseDocumentSnapshot,\n PalbaseQuerySnapshot,\n PalbaseResult,\n PalbaseWhereOperator,\n} from \"../endpoint.js\";\nimport { PalbaseModuleError, type ModuleTransport } from \"./http.js\";\n\n/**\n * A path segment the platform will accept.\n *\n * Validated HERE rather than at the server, because a rejected segment is a\n * programming mistake and the useful moment to hear about it is the call.\n */\nconst SEGMENT_RE = /^[A-Za-z0-9_-]+$/;\n\nfunction validateSegment(segment: string, label: string): void {\n if (!SEGMENT_RE.test(segment)) {\n throw new Error(`Invalid ${label}: \"${segment}\". Must match ${SEGMENT_RE.source}`);\n }\n}\n\ninterface WhereClause {\n field: string;\n op: PalbaseWhereOperator;\n value: unknown;\n}\ninterface OrderClause {\n field: string;\n direction: \"asc\" | \"desc\";\n}\ninterface ChainState {\n where: WhereClause[];\n orderBy: OrderClause[];\n limit?: number;\n}\n\ninterface RawDocument {\n id?: string;\n exists?: boolean;\n data?: Record<string, unknown>;\n}\n\nfunction buildDocumentRef<T extends Record<string, unknown>>(\n http: ModuleTransport,\n path: string,\n): PalbaseDocumentRef<T> {\n return {\n path,\n async set(data: T) {\n return http.request<void>(\"PUT\", `/v1/docs/${path}`, { body: data });\n },\n async get(): Promise<PalbaseResult<PalbaseDocumentSnapshot<T>>> {\n const response = await http.request<RawDocument>(\"GET\", `/v1/docs/${path}`);\n if (response.error) return { data: null, error: response.error, status: response.status };\n const raw = response.data ?? {};\n const exists = raw.exists !== undefined ? raw.exists : Boolean(raw.data || raw.id);\n const segments = path.split(\"/\");\n const id = raw.id || segments[segments.length - 1] || \"\";\n return {\n data: { id, exists, data: () => raw.data as T | undefined, ref: { path } },\n error: null,\n status: response.status,\n };\n },\n async update(data: Partial<T>) {\n return http.request<void>(\"PATCH\", `/v1/docs/${path}`, { body: data });\n },\n async delete() {\n return http.request<void>(\"DELETE\", `/v1/docs/${path}`);\n },\n collection<C extends Record<string, unknown>>(name: string): PalbaseCollectionRef<C> {\n validateSegment(name, \"subcollection name\");\n return buildCollectionRef<C>(http, `${path}/${name}`);\n },\n };\n}\n\nfunction buildCollectionRef<T extends Record<string, unknown>>(\n http: ModuleTransport,\n path: string,\n state: ChainState = { where: [], orderBy: [] },\n): PalbaseCollectionRef<T> {\n function snapshot(doc: { id: string; data: Record<string, unknown> }): PalbaseDocumentSnapshot<T> {\n return {\n id: doc.id,\n exists: true,\n data: () => doc.data as T,\n ref: { path: `${path}/${doc.id}` },\n };\n }\n\n function querySnapshot(docs: PalbaseDocumentSnapshot<T>[]): PalbaseQuerySnapshot<T> {\n return {\n docs,\n empty: docs.length === 0,\n size: docs.length,\n docChanges: () => docs.map((doc) => ({ type: \"added\" as const, doc })),\n };\n }\n\n return {\n path,\n\n doc(id: string) {\n validateSegment(id, \"document ID\");\n return buildDocumentRef<T>(http, `${path}/${id}`);\n },\n\n async add(data: T) {\n const resp = await http.request<{ id: string }>(\"POST\", `/v1/docs/${path}`, { body: data });\n if (resp.error || !resp.data) {\n return { data: null, error: resp.error, status: resp.status };\n }\n return {\n data: buildDocumentRef<T>(http, `${path}/${resp.data.id}`),\n error: null,\n status: resp.status,\n };\n },\n\n // Each narrowing returns a NEW ref. A builder that mutated in place would\n // leak one caller's filter into a query another caller had already held.\n where(field: string, op: PalbaseWhereOperator, value: unknown) {\n return buildCollectionRef<T>(http, path, {\n ...state,\n where: [...state.where, { field, op, value }],\n });\n },\n orderBy(field: string, direction: \"asc\" | \"desc\" = \"asc\") {\n return buildCollectionRef<T>(http, path, {\n ...state,\n orderBy: [...state.orderBy, { field, direction }],\n });\n },\n limit(n: number) {\n return buildCollectionRef<T>(http, path, { ...state, limit: n });\n },\n\n async get(): Promise<PalbaseResult<PalbaseQuerySnapshot<T>>> {\n const narrowed =\n state.where.length > 0 || state.orderBy.length > 0 || state.limit !== undefined;\n\n const resp = narrowed\n ? await http.request<{ documents?: { id: string; data: Record<string, unknown> }[] }>(\n \"POST\",\n `/v1/docs/${path}/query`,\n { body: queryBody(state) },\n )\n : await http.request<{ documents?: { id: string; data: Record<string, unknown> }[] }>(\n \"GET\",\n `/v1/docs/${path}`,\n );\n\n if (resp.error) return { data: null, error: resp.error, status: resp.status };\n const docs = (resp.data?.documents ?? []).map(snapshot);\n return { data: querySnapshot(docs), error: null, status: resp.status };\n },\n };\n}\n\nfunction queryBody(state: ChainState): Record<string, unknown> {\n const body: Record<string, unknown> = {};\n if (state.where.length > 0) {\n body.where = state.where.map((w) => ({ field: w.field, op: w.op, value: w.value }));\n }\n if (state.orderBy.length > 0) {\n body.orderBy = state.orderBy.map((o) => ({ field: o.field, direction: o.direction }));\n }\n if (state.limit !== undefined) body.limit = state.limit;\n return body;\n}\n\n/** The largest batch the platform accepts in one call. */\nconst MAX_BATCH = 500;\n\nexport function buildDocumentsClient(http: ModuleTransport): PalbaseDocsClient {\n return {\n /**\n * `Documents.doc(\"users/alice\")` — segments are collection/documentId PAIRS,\n * so an odd count addresses a COLLECTION and is refused. Accepting it would\n * write a document whose id happens to be a collection's name.\n */\n doc<T extends Record<string, unknown>>(path: string): PalbaseDocumentRef<T> {\n const segments = String(path)\n .split(\"/\")\n .filter((s) => s.length > 0);\n if (segments.length === 0 || segments.length % 2 !== 0) {\n throw new Error(\n `Invalid document path: \"${path}\". Expected collection/documentId pairs, got ${segments.length} segment(s).`,\n );\n }\n segments.forEach((s, i) => validateSegment(s, i % 2 === 0 ? \"collection name\" : \"document ID\"));\n return buildDocumentRef<T>(http, segments.join(\"/\"));\n },\n\n collection<T extends Record<string, unknown>>(name: string): PalbaseCollectionRef<T> {\n validateSegment(name, \"collection name\");\n return buildCollectionRef<T>(http, name);\n },\n\n async batch(operations) {\n // Refused HERE, without a request: the server would refuse it too, and\n // spending a round trip to be told so is the caller's time.\n if (operations.length > MAX_BATCH) {\n return {\n data: null,\n error: new PalbaseModuleError(\n \"batch_too_large\",\n `Batch size ${operations.length} exceeds maximum of ${MAX_BATCH}`,\n 400,\n ),\n status: 400,\n };\n }\n if (operations.length === 0) return { data: null, error: null, status: 200 };\n\n return http.request<void>(\"POST\", \"/v1/docs/batch\", {\n body: operations.map((op) => ({ op: op.op, path: op.ref.path, data: op.data })),\n });\n },\n };\n}\n","/**\n * flags.ts — feature flags, resolved for the request's own user.\n *\n * Moved in from `v2/runtime/internal/runtime/module-clients.js:941-1164`.\n *\n * THE ONE RULE WORTH STATING: the user a flag resolves for comes from the\n * SDK's own request scope, never from anything the caller passed on the wire.\n * A handler can pass an explicit context (including an explicit `null` for a\n * deliberate anonymous read) and that wins — but the default is the person the\n * request is being served for, which is what makes `Flags.get(\"x\")` mean the\n * obvious thing inside a handler.\n *\n * Writes mirror the Database model: `setOverride` writes for the CURRENT user\n * and needs no admin power; cross-user writes live behind `asService()` so they\n * are explicit and greppable.\n */\n\nimport type {\n PalbaseBatchOverrideOperation,\n PalbaseFlagContext,\n PalbaseFlagValue,\n PalbaseFlagsClient,\n PalbaseFlagsServiceClient,\n} from \"../clients.js\";\nimport type { PalbaseResult } from \"../endpoint.js\";\nimport type { ModuleTransport } from \"./http.js\";\n\nconst FLAG_NAME_RE = /^[A-Za-z0-9_.-]+$/;\n\nexport interface FlagsConfig {\n /** The request's user, read from the SDK's ALS box — never from the caller. */\n getCurrentUserId: () => string | null;\n}\n\nfunction assertFlagName(flagName: string): void {\n if (!FLAG_NAME_RE.test(flagName)) {\n throw new Error(`Invalid flag name: \"${flagName}\". Flag names must match ${FLAG_NAME_RE.source}`);\n }\n}\n\n/** A truthy flag value, in the platform's own terms. */\nfunction flagEnabled(value: unknown): boolean {\n if (typeof value === \"boolean\") return value;\n return value != null && value !== 0 && value !== \"\";\n}\n\nfunction flagVariant(value: unknown): { name: string } | null {\n return typeof value === \"string\" ? { name: value } : null;\n}\n\n/**\n * A context object carries `userId`/`properties`; anything else passed in that\n * position is a DEFAULT VALUE. This is what tells `Flags.get(key, ctx)` apart\n * from `Flags.get(key, someObjectDefault)`.\n */\nfunction isContextObject(v: unknown): v is PalbaseFlagContext {\n return (\n v !== null && typeof v === \"object\" && !Array.isArray(v) && (\"userId\" in v || \"properties\" in v)\n );\n}\n\ninterface MergedSnapshot {\n values?: Record<string, PalbaseFlagValue>;\n}\n\nexport function buildFlagsClient(http: ModuleTransport, cfg: FlagsConfig): PalbaseFlagsClient {\n /**\n * The effective user for a call. An explicit `userId` in the context wins —\n * INCLUDING an explicit `null`, which is a deliberate anonymous read.\n */\n function resolveUserId(context?: PalbaseFlagContext): string | null | undefined {\n if (context && \"userId\" in context) return context.userId ?? null;\n return cfg.getCurrentUserId() || undefined;\n }\n\n function mergedPath(context?: PalbaseFlagContext): string {\n const uid = resolveUserId(context);\n return uid ? `/v1/user-flags/users/${encodeURIComponent(uid)}` : \"/v1/user-flags\";\n }\n\n function fetchMerged(context?: PalbaseFlagContext) {\n return http.request<MergedSnapshot>(\"GET\", mergedPath(context));\n }\n\n const service: PalbaseFlagsServiceClient = {\n async setOverrideForUser(userId, key, value) {\n return http.request(\n \"PUT\",\n `/v1/user-flags/users/${encodeURIComponent(userId)}/${encodeURIComponent(key)}`,\n { body: { value } },\n );\n },\n async setOverridesForUser(userId, values) {\n return http.request(\"PUT\", `/v1/user-flags/users/${encodeURIComponent(userId)}`, {\n body: { values },\n });\n },\n async clearOverrideForUser(userId, key) {\n return http.request(\n \"DELETE\",\n `/v1/user-flags/users/${encodeURIComponent(userId)}/${encodeURIComponent(key)}`,\n );\n },\n async clearAllOverridesForUser(userId) {\n return http.request(\"DELETE\", `/v1/user-flags/users/${encodeURIComponent(userId)}`);\n },\n async batchSetOverrides(operations: ReadonlyArray<PalbaseBatchOverrideOperation>) {\n // The argument is camelCase, the wire is snake_case. Mapped here so a\n // stray `userId` never reaches the server — and an explicit `user_id`, if\n // a caller already wrote one, is preserved.\n const ops = (operations ?? []).map((op) => {\n const raw = op as unknown as { userId?: string; user_id?: string; values: unknown };\n return { user_id: raw.userId ?? raw.user_id, values: raw.values };\n });\n return http.request(\"POST\", \"/v1/user-flags/batch\", { body: { operations: ops } });\n },\n };\n\n return {\n async isEnabled(flagName: string, context?: PalbaseFlagContext) {\n assertFlagName(flagName);\n const res = await fetchMerged(context);\n if (res.error || res.data == null) return { data: null, error: res.error, status: res.status };\n return { data: flagEnabled(res.data.values?.[flagName]), error: null, status: res.status };\n },\n\n async getVariant(flagName: string, context?: PalbaseFlagContext) {\n assertFlagName(flagName);\n const res = await fetchMerged(context);\n // A missing or non-string value is a NULL variant on a successful read;\n // errors and empty bodies pass through as null too, which is why this is\n // written out rather than mapped.\n if (res.error || res.data == null) return { data: null, error: res.error, status: res.status };\n return { data: flagVariant(res.data.values?.[flagName]), error: null, status: res.status };\n },\n\n /**\n * `get(key)` · `get(key, default)` · `get(key, default, ctx)` · `get(key, ctx)`.\n *\n * The default is substituted when the flag is ABSENT or when the flags\n * service is unreachable — a product that hides a feature because a lookup\n * timed out is behaving correctly; one that crashes is not.\n */\n async get(\n flagName: string,\n defaultOrContext?: PalbaseFlagValue | PalbaseFlagContext,\n maybeContext?: PalbaseFlagContext,\n ): Promise<PalbaseResult<PalbaseFlagValue>> {\n assertFlagName(flagName);\n\n let defaultValue: PalbaseFlagValue | undefined;\n let context: PalbaseFlagContext | undefined;\n let hasDefault = false;\n if (maybeContext !== undefined) {\n defaultValue = defaultOrContext as PalbaseFlagValue;\n hasDefault = true;\n context = maybeContext;\n } else if (isContextObject(defaultOrContext)) {\n context = defaultOrContext;\n } else if (defaultOrContext !== undefined) {\n defaultValue = defaultOrContext as PalbaseFlagValue;\n hasDefault = true;\n }\n\n const resp = await fetchMerged(context);\n if (resp.error !== null) {\n if (hasDefault) return { data: defaultValue ?? null, error: null, status: resp.status };\n return { data: null, error: resp.error, status: resp.status };\n }\n const values = resp.data?.values ?? {};\n const value = values[flagName];\n // An absent key on a SUCCESSFUL read is not an error.\n if (value === undefined) {\n return { data: hasDefault ? (defaultValue ?? null) : null, error: null, status: resp.status };\n }\n return { data: value, error: null, status: resp.status };\n },\n\n async getAll(context?: PalbaseFlagContext) {\n const res = await fetchMerged(context);\n if (res.error || res.data == null) return { data: null, error: res.error, status: res.status };\n const values = res.data.values ?? {};\n return {\n data: Object.keys(values).map((name) => {\n const value = values[name];\n const flag: { name: string; enabled: boolean; variant?: { name: string } } = {\n name,\n enabled: flagEnabled(value),\n };\n if (typeof value === \"string\") flag.variant = { name: value };\n return flag;\n }),\n error: null,\n status: res.status,\n };\n },\n\n /**\n * Override a flag for the CURRENT request user.\n *\n * On an anonymous request this does not silently no-op and does not write\n * for nobody: it refuses and names the call that does cross-user writes.\n */\n async setOverride(key: string, value: PalbaseFlagValue) {\n const uid = cfg.getCurrentUserId();\n if (!uid) {\n return {\n data: null,\n error: {\n message:\n \"setOverride requires a signed-in user; use Flags.$asService().setOverrideForUser(userId, key, value) for cross-user writes\",\n },\n status: 400,\n };\n }\n return http.request(\n \"PUT\",\n `/v1/user-flags/users/${encodeURIComponent(uid)}/${encodeURIComponent(key)}`,\n { body: { value } },\n );\n },\n\n asService() {\n return service;\n },\n };\n}\n","/**\n * notifications.ts — push, email, SMS, verifications, inbox, preferences and\n * the two template surfaces.\n *\n * Moved in from `v2/runtime/internal/runtime/module-clients.js:1180-1379`.\n *\n * The theme of this file is a NAME GAP: the SDK speaks camelCase and palnotify\n * speaks snake_case, and every place they meet is a place a field can be\n * dropped in silence. One of them cost a live afternoon — `email.send({ html })`\n * was forwarded verbatim, palnotify reads `html_body`, and the answer was a 400\n * about a field the caller had supplied. The mappings below are that lesson,\n * and they are now checked against the declared parameter types instead of\n * being hand-carried across a package boundary.\n */\n\nimport type {\n PalbaseEmailClient,\n PalbaseEmailTemplate,\n PalbaseEmailTemplatesClient,\n PalbaseInboxClient,\n PalbaseNotificationsClient,\n PalbasePreferencesClient,\n PalbasePushClient,\n PalbaseSMSTemplate,\n PalbaseSMSTemplatesClient,\n PalbaseSmsClient,\n PalbaseWhatsAppClient,\n PalbaseVerificationsClient,\n} from \"../clients.js\";\nimport type { PalbaseResult } from \"../endpoint.js\";\nimport type { ModuleTransport } from \"./http.js\";\n\n/** Re-map the data of a SUCCESSFUL envelope; errors pass through untouched. */\nfunction mapEnvelope<In, Out>(res: PalbaseResult<In>, map: (data: In) => Out): PalbaseResult<Out> {\n if (res.error !== null || res.data === null || res.data === undefined) {\n return { data: null, error: res.error, status: res.status };\n }\n return { data: map(res.data), error: null, status: res.status };\n}\n\ntype Wire = Record<string, unknown>;\n\nfunction toEmailTemplate(wire: Wire): PalbaseEmailTemplate {\n const view: PalbaseEmailTemplate = {\n id: wire.id as string,\n slug: wire.slug as string,\n locale: wire.locale as string,\n subject: wire.subject as string,\n htmlBody: wire.html_body as string,\n variables: (wire.variables as string[]) ?? [],\n isDefault: wire.is_default as boolean,\n createdAt: wire.created_at as string,\n updatedAt: wire.updated_at as string,\n };\n if (wire.text_body !== undefined) view.textBody = wire.text_body as string;\n return view;\n}\n\nfunction toSmsTemplate(wire: Wire): PalbaseSMSTemplate {\n return {\n id: wire.id as string,\n slug: wire.slug as string,\n locale: wire.locale as string,\n body: wire.body as string,\n variables: (wire.variables as string[]) ?? [],\n isDefault: wire.is_default as boolean,\n createdAt: wire.created_at as string,\n updatedAt: wire.updated_at as string,\n };\n}\n\nexport function buildNotificationsClient(http: ModuleTransport): PalbaseNotificationsClient {\n const push: PalbasePushClient = {\n async send(params) {\n return http.request(\"POST\", \"/v1/notifications/push\", { body: params });\n },\n };\n\n const email: PalbaseEmailClient = {\n async send(params) {\n // `html`/`text` are what the SDK declares; palnotify reads\n // `html_body`/`text_body`. Forwarding them verbatim answered 400 about a\n // field the caller HAD supplied — live on todoapp, 2026-07-30.\n const { templateSlug, html, text, ...rest } = params;\n const body: Record<string, unknown> = { ...rest };\n if (templateSlug !== undefined) body.template_slug = templateSlug;\n if (html !== undefined) body.html_body = html;\n if (text !== undefined) body.text_body = text;\n return http.request(\"POST\", \"/v1/notifications/email\", { body });\n },\n };\n\n const sms: PalbaseSmsClient = {\n async send(params) {\n const { templateSlug, ...rest } = params;\n const body = templateSlug !== undefined ? { ...rest, template_slug: templateSlug } : rest;\n return http.request(\"POST\", \"/v1/notifications/sms\", { body });\n },\n };\n\n const whatsapp: PalbaseWhatsAppClient = {\n async send(params) {\n const { templateSlug, userId, ...rest } = params;\n const body = {\n ...rest,\n ...(templateSlug === undefined ? {} : { template_slug: templateSlug }),\n ...(userId === undefined ? {} : { user_id: userId }),\n };\n return http.request(\"POST\", \"/v1/notifications/whatsapp\", { body });\n },\n async events(options = {}) {\n const query = options.limit === undefined ? \"\" : `?limit=${encodeURIComponent(String(options.limit))}`;\n return http.request(\"GET\", `/v1/notifications/whatsapp/events${query}`);\n },\n };\n\n // Phone verification (OTP). Separate from sms.send on purpose: there is no\n // body here — the provider generates the code and the message text itself.\n const verifications: PalbaseVerificationsClient = {\n async start(params) {\n return http.request(\"POST\", \"/v1/notifications/verifications\", { body: params });\n },\n async check(params) {\n return http.request(\"POST\", \"/v1/notifications/verifications/check\", { body: params });\n },\n };\n\n const inbox: PalbaseInboxClient = {\n async send(params) {\n return http.request(\"POST\", \"/v1/notifications/inbox\", { body: params });\n },\n async list(options?: {\n cursor?: string;\n limit?: number;\n is_read?: boolean;\n category?: string;\n include_archived?: boolean;\n }) {\n const opts = options ?? {};\n const params = new URLSearchParams();\n if (opts.cursor) params.set(\"cursor\", opts.cursor);\n if (opts.limit !== undefined) params.set(\"limit\", String(opts.limit));\n if (opts.is_read !== undefined) params.set(\"is_read\", opts.is_read ? \"true\" : \"false\");\n if (opts.category) params.set(\"category\", opts.category);\n if (opts.include_archived) params.set(\"include_archived\", \"true\");\n const query = params.toString();\n return http.request(\"GET\", `/v1/notifications/inbox${query ? `?${query}` : \"\"}`);\n },\n async unreadCount() {\n return http.request(\"GET\", \"/v1/notifications/inbox/unread-count\");\n },\n async markRead(id: string) {\n return http.request(\"PATCH\", `/v1/notifications/inbox/${encodeURIComponent(id)}/read`);\n },\n async markAllRead() {\n return http.request(\"POST\", \"/v1/notifications/inbox/read-all\");\n },\n async archive(id: string) {\n return http.request(\"DELETE\", `/v1/notifications/inbox/${encodeURIComponent(id)}`);\n },\n };\n\n const preferences: PalbasePreferencesClient = {\n async get() {\n return http.request(\"GET\", \"/v1/notifications/preferences\");\n },\n async update(params) {\n return http.request(\"PUT\", \"/v1/notifications/preferences\", { body: params });\n },\n };\n\n const emailTemplates: PalbaseEmailTemplatesClient = {\n async list() {\n const resp = await http.request<Wire[]>(\"GET\", \"/v1/notifications/templates\");\n return mapEnvelope(resp, (rows) => (rows ?? []).map(toEmailTemplate));\n },\n async get(id: string) {\n const resp = await http.request<Wire>(\n \"GET\",\n `/v1/notifications/templates/${encodeURIComponent(id)}`,\n );\n return mapEnvelope(resp, toEmailTemplate);\n },\n async create(input: { slug: string; subject: string; htmlBody: string; textBody?: string; variables?: string[] }) {\n const body: Record<string, unknown> = {\n slug: input.slug,\n subject: input.subject,\n html_body: input.htmlBody,\n };\n if (input.textBody !== undefined) body.text_body = input.textBody;\n if (input.variables !== undefined) body.variables = input.variables;\n const resp = await http.request<Wire>(\"POST\", \"/v1/notifications/templates\", { body });\n return mapEnvelope(resp, toEmailTemplate);\n },\n async update(\n id: string,\n input: { subject?: string; htmlBody?: string; textBody?: string; variables?: string[] },\n ) {\n const body: Record<string, unknown> = {};\n if (input.subject !== undefined) body.subject = input.subject;\n if (input.htmlBody !== undefined) body.html_body = input.htmlBody;\n if (input.textBody !== undefined) body.text_body = input.textBody;\n if (input.variables !== undefined) body.variables = input.variables;\n const resp = await http.request<Wire>(\n \"PUT\",\n `/v1/notifications/templates/${encodeURIComponent(id)}`,\n { body },\n );\n return mapEnvelope(resp, toEmailTemplate);\n },\n async delete(id: string) {\n return http.request(\"DELETE\", `/v1/notifications/templates/${encodeURIComponent(id)}`);\n },\n };\n\n const smsTemplates: PalbaseSMSTemplatesClient = {\n async list() {\n const resp = await http.request<Wire[]>(\"GET\", \"/v1/notifications/sms-templates\");\n return mapEnvelope(resp, (rows) => (rows ?? []).map(toSmsTemplate));\n },\n async get(id: string) {\n const resp = await http.request<Wire>(\n \"GET\",\n `/v1/notifications/sms-templates/${encodeURIComponent(id)}`,\n );\n return mapEnvelope(resp, toSmsTemplate);\n },\n async create(input: { slug: string; body: string; variables?: string[] }) {\n const body: Record<string, unknown> = { slug: input.slug, body: input.body };\n if (input.variables !== undefined) body.variables = input.variables;\n const resp = await http.request<Wire>(\"POST\", \"/v1/notifications/sms-templates\", { body });\n return mapEnvelope(resp, toSmsTemplate);\n },\n async update(id: string, input: { body?: string; variables?: string[] }) {\n const body: Record<string, unknown> = {};\n if (input.body !== undefined) body.body = input.body;\n if (input.variables !== undefined) body.variables = input.variables;\n const resp = await http.request<Wire>(\n \"PUT\",\n `/v1/notifications/sms-templates/${encodeURIComponent(id)}`,\n { body },\n );\n return mapEnvelope(resp, toSmsTemplate);\n },\n async delete(id: string) {\n return http.request(\"DELETE\", `/v1/notifications/sms-templates/${encodeURIComponent(id)}`);\n },\n };\n\n return {\n push,\n email,\n sms,\n whatsapp,\n verifications,\n inbox,\n preferences,\n templates: { email: emailTemplates, sms: smsTemplates },\n async registerDevice(params) {\n return http.request(\"POST\", \"/v1/notifications/devices\", { body: params });\n },\n async unregisterDevice(deviceId: string) {\n return http.request(\"DELETE\", `/v1/notifications/devices/${encodeURIComponent(deviceId)}`);\n },\n };\n}\n","/**\n * realtime.ts — broadcast, and only broadcast.\n *\n * Moved in from `v2/runtime/internal/runtime/module-clients.js:811-883`.\n *\n * There is no `subscribe()` here, deliberately: a backend handler answers one\n * request and ends, so there is no honest place to hold a long-lived socket.\n * Subscription lives in the client SDKs; this side pushes.\n *\n * The V1 host/executor branch is GONE. It existed so an isolate could delegate\n * the secret-bearing token mint to a host that held the credential — and the\n * isolate was removed on 2026-08-14. A single-tenant process has nobody to hide\n * its own tenant's key from.\n */\n\nimport { createHmac } from \"node:crypto\";\n\nimport type { PalbaseRealtimeClient } from \"../clients.js\";\nimport { PalbaseModuleError } from \"./http.js\";\n\nexport interface RealtimeConfig {\n baseUrl: string;\n /**\n * The shared Realtime API secret. Empty means realtime is not provisioned for\n * this environment, and broadcast says so by name rather than failing oddly.\n */\n apiJwtSecret: string;\n /** Resolved at CALL time — see the note in http.ts. */\n fetchImpl?: typeof fetch;\n}\n\n/**\n * A short-lived HS256 token Realtime's broadcast pipeline accepts.\n *\n * It needs a valid signature and a future `exp`, nothing more — this is a\n * service-to-service hop inside the stack, not a user session.\n */\nfunction mintToken(secret: string): string {\n const now = Math.floor(Date.now() / 1000);\n const header = Buffer.from(JSON.stringify({ alg: \"HS256\", typ: \"JWT\" })).toString(\"base64url\");\n const payload = Buffer.from(\n JSON.stringify({ iss: \"backend-runtime\", role: \"service_role\", iat: now, exp: now + 60 }),\n ).toString(\"base64url\");\n const sig = createHmac(\"sha256\", secret).update(`${header}.${payload}`).digest(\"base64url\");\n return `${header}.${payload}.${sig}`;\n}\n\nexport function buildRealtimeClient(cfg: RealtimeConfig): PalbaseRealtimeClient {\n const url = `${cfg.baseUrl}/realtime/api/broadcast`;\n const stateUrl = `${cfg.baseUrl}/realtime/api/state`;\n\n /** One state write or clear. Same credential, same fire-and-forget contract\n * as broadcast: a handler that wrote a row must not lose it because the\n * pubsub layer was unreachable. */\n async function writeState(\n topic: string,\n key: string,\n value: Record<string, unknown> | undefined,\n del: boolean,\n ) {\n if (typeof topic !== \"string\" || topic.length === 0) {\n return {\n data: null,\n error: new PalbaseModuleError(\"invalid_argument\", \"topic must be a non-empty string\", 400),\n };\n }\n if (typeof key !== \"string\" || key.length === 0) {\n return {\n data: null,\n error: new PalbaseModuleError(\"invalid_argument\", \"key must be a non-empty string\", 400),\n };\n }\n if (!cfg.apiJwtSecret) {\n return {\n data: null,\n error: new PalbaseModuleError(\n \"realtime_unconfigured\",\n \"Realtime.state is unavailable: realtime is not provisioned for this Environment \" +\n \"(PALBASE_REALTIME_API_JWT_SECRET unset).\",\n 503,\n ),\n };\n }\n\n let token: string;\n try {\n token = mintToken(cfg.apiJwtSecret);\n } catch (err) {\n return {\n data: null,\n error: new PalbaseModuleError(\n \"realtime_token_error\",\n err instanceof Error ? err.message : \"token mint failed\",\n 500,\n ),\n };\n }\n\n const op = del ? { topic, key, del: true } : { topic, key, value: value ?? {} };\n const doFetch = cfg.fetchImpl ?? globalThis.fetch;\n let response: Response;\n try {\n response = await doFetch(stateUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", Authorization: `Bearer ${token}` },\n body: JSON.stringify({ ops: [op] }),\n });\n } catch (err) {\n return {\n data: null,\n error: new PalbaseModuleError(\n \"network_error\",\n err instanceof Error ? err.message : \"state request failed\",\n 0,\n ),\n };\n }\n if (response.status === 202 || response.status === 200) {\n return { data: undefined, error: null };\n }\n const detail = await response.text().catch(() => \"\");\n return {\n data: null,\n error: new PalbaseModuleError(\n \"realtime_state_failed\",\n `realtime state write returned ${response.status}${detail ? `: ${detail}` : \"\"}`,\n response.status,\n ),\n };\n }\n\n return {\n state: {\n /** Write one DURABLE entry on a channel's shared state.\n *\n * The difference from broadcast is WHO it reaches: a broadcast reaches\n * whoever is listening at that instant, while state is also handed to\n * whoever joins afterwards. \"This value is now X\" wants the second — a\n * client connecting a second later should not have to wait for the next\n * change to learn X. */\n set: (topic: string, key: string, value: Record<string, unknown>) =>\n writeState(topic, key, value, false),\n /** Remove one entry. */\n clear: (topic: string, key: string) => writeState(topic, key, undefined, true),\n },\n\n async broadcast(channel: string, event: string, payload?: Record<string, unknown>) {\n // Cheap argument checks first, locally: a bad call gets an answer without\n // spending a round trip to be told the obvious.\n if (typeof channel !== \"string\" || channel.length === 0) {\n return {\n data: null,\n error: new PalbaseModuleError(\"invalid_argument\", \"channel must be a non-empty string\", 400),\n };\n }\n if (typeof event !== \"string\" || event.length === 0) {\n return {\n data: null,\n error: new PalbaseModuleError(\"invalid_argument\", \"event must be a non-empty string\", 400),\n };\n }\n if (!cfg.apiJwtSecret) {\n return {\n data: null,\n error: new PalbaseModuleError(\n \"realtime_unconfigured\",\n \"Realtime.broadcast is unavailable: realtime is not provisioned for this Environment \" +\n \"(PALBASE_REALTIME_API_JWT_SECRET unset).\",\n 503,\n ),\n };\n }\n\n let token: string;\n try {\n token = mintToken(cfg.apiJwtSecret);\n } catch (err) {\n return {\n data: null,\n error: new PalbaseModuleError(\n \"realtime_token_error\",\n err instanceof Error ? err.message : \"token mint failed\",\n 500,\n ),\n };\n }\n\n // The BARE sub-topic. Realtime prepends \"realtime:\" on delivery, and a\n // pre-prefixed topic double-prefixes and is silently dropped — proven live.\n const body = JSON.stringify({\n messages: [{ topic: channel, event, payload: payload ?? {}, private: false }],\n });\n\n const doFetch = cfg.fetchImpl ?? globalThis.fetch;\n let response: Response;\n try {\n response = await doFetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", Authorization: `Bearer ${token}` },\n body,\n });\n } catch (err) {\n // FIRE AND FORGET: a handler that wrote a row and then broadcast must\n // not lose the row because the pubsub layer was unreachable. This is the\n // one client that answers with an envelope on a network failure rather\n // than throwing, and it is why.\n return {\n data: null,\n error: new PalbaseModuleError(\n \"network_error\",\n err instanceof Error ? err.message : \"broadcast request failed\",\n 0,\n ),\n };\n }\n\n if (response.status === 202 || response.status === 200) {\n return { data: undefined, error: null };\n }\n\n const detail = await response.text().catch(() => \"\");\n return {\n data: null,\n error: new PalbaseModuleError(\n \"realtime_broadcast_failed\",\n `broadcast returned ${response.status}: ${detail.slice(0, 200)}`,\n response.status,\n ),\n };\n },\n };\n}\n","/**\n * storage.ts — the Storage client.\n *\n * Moved in from `v2/runtime/internal/runtime/module-clients.js:474-589`. That\n * code addressed the native Supabase Storage wire under `/storage/v1` until\n * 2026-08-15, when it was repointed at this stack's own module — measured\n * against the live stack, where the old path answers 404 and the new one 200.\n * It arrives here so the SHAPE it returns and the type that declares that shape\n * are checked against each other: they were not, and the type spent a major\n * version describing another server's columns.\n */\n\nimport type {\n PalbaseBucketClient,\n PalbaseFileObject,\n PalbaseListOptions,\n PalbaseSignedUrlResponse,\n PalbaseStorageClient,\n PalbaseUploadOptions,\n} from \"../clients.js\";\nimport type { PalbaseResult } from \"../endpoint.js\";\nimport type { ModuleTransport } from \"./http.js\";\n\n/** What the platform accepts as a bucket name (schema: `^[a-z][a-z0-9-]{1,62}$`). */\nconst BUCKET_NAME_RE = /^[a-zA-Z0-9_-]+$/;\n/** What the platform accepts as an object path. */\nconst STORAGE_PATH_RE = /^[a-zA-Z0-9_./-]+$/;\nconst STORAGE_TRAVERSAL_RE = /(?:^|\\/)\\.\\.(?:\\/|$)/;\n\n/**\n * Refused HERE, before any request.\n *\n * A traversing path is a programming mistake, and the useful moment to hear\n * about it is the call that made it — not a 400 three layers away.\n */\nfunction validateStoragePath(p: string): void {\n if (!STORAGE_PATH_RE.test(p) || STORAGE_TRAVERSAL_RE.test(p)) {\n throw new Error(\n `Invalid file path: \"${p}\". Paths must not contain traversal sequences and must match ${STORAGE_PATH_RE.source}`,\n );\n }\n}\n\n/**\n * The wire's own shape, mapped onto what this package declares.\n *\n * v2's storage answers in camelCase with the variants and the thumbhash already\n * in it, so this maps rather than translates. The snake_case unwrapping that\n * used to live here (`metadata.mimetype`, `bucket_id`, `created_at`) belonged to\n * a different server, and reading those names off this wire produced an object\n * whose size was 0 and whose content type was \"\".\n */\nfunction toFileObject(bucket: string, row: Record<string, unknown>): PalbaseFileObject {\n return {\n name: (row.path as string) ?? \"\",\n path: (row.path as string) ?? \"\",\n bucket: (row.bucket as string) ?? bucket,\n size: typeof row.size === \"number\" ? row.size : 0,\n contentType: (row.contentType as string) ?? \"\",\n checksum: (row.checksum as string) ?? \"\",\n width: row.width as number | undefined,\n height: row.height as number | undefined,\n thumbhash: row.thumbhash as string | undefined,\n variants: (row.variants as Record<string, string>) ?? {},\n };\n}\n\n/** Re-map the data of a SUCCESSFUL envelope; pass errors through untouched. */\nfunction mapResponse<In, Out>(\n res: PalbaseResult<In>,\n map: (data: In) => Out,\n): PalbaseResult<Out> {\n if (res.error || res.data === null || res.data === undefined) {\n return { data: null, error: res.error, status: res.status };\n }\n return { data: map(res.data), error: null, status: res.status };\n}\n\nfunction buildBucketClient(\n http: ModuleTransport,\n bucketName: string,\n publicOrigin: string,\n): PalbaseBucketClient {\n const objectPath = (path: string) => `/v1/storage/object/${bucketName}/${path}`;\n\n return {\n async upload(path, file, options?: PalbaseUploadOptions) {\n validateStoragePath(path);\n const headers: Record<string, string> = {\n \"Content-Type\": options?.contentType ?? \"application/octet-stream\",\n };\n if (options?.upsert) headers[\"x-upsert\"] = \"true\";\n // The BYTES, as the body. Storage sniffs the content and decides for\n // itself what this is; the declared type is a hint it may overrule,\n // because a name and a header are both things a caller can be wrong about.\n const body = file instanceof ArrayBuffer ? new Uint8Array(file) : file;\n const res = await http.request<Record<string, unknown>>(\"PUT\", objectPath(path), {\n body,\n headers,\n });\n return mapResponse(res, (r) => toFileObject(bucketName, r ?? {}));\n },\n\n async download(path) {\n validateStoragePath(path);\n // The AUTHENTICATED read: the project already holds a credential this\n // stack verified, so it does not have to mint a signature to open its own\n // object — and this route serves private buckets, which the public one\n // refuses on purpose.\n return http.request<Blob>(\"GET\", objectPath(path), { headers: { Accept: \"*/*\" } });\n },\n\n getPublicUrl(path, options) {\n validateStoragePath(path);\n const variant = options?.variant ? `?variant=${encodeURIComponent(options.variant)}` : \"\";\n // ABSOLUTE — and the origin is a value the stack is TOLD, not the\n // transport's baseUrl.\n //\n // Those are two different addresses and conflating them is how this broke\n // once already: the transport points at palsvc over the loopback\n // (`http://127.0.0.1:8080`), and a URL built from it resolves nowhere\n // outside the pod. So this used to return the path alone.\n //\n // The path alone is not a smaller answer, it is a wrong one. A public URL\n // LEAVES the response body — into an <img>, an email, another app on\n // another host — and none of those have a base to resolve it against.\n // Measured live 24.08.2026: an iOS client handed the returned\n // `/v1/files/post-images/…` straight to URLSession and got\n // NSURLErrorUnsupportedURL (-1002). The upload had worked; only the URL\n // was unusable.\n //\n // `PALBASE_PUBLIC_ORIGIN` is set by whoever publishes the stack, because\n // only they know it: in the cloud the operator writes\n // `https://<ref>.<domain>`, and a self-hosted stack carries whatever\n // domain its certificate is for.\n if (!publicOrigin) {\n // NAMED, not silent — the same doctrine as the other unconfigured\n // modules in engine/config.ts (\"throw a named error on first use rather\n // than silently no-op\"). A returned path would pass every test here and\n // fail in the one place nobody is watching.\n throw new Error(\n `Storage.bucket(\"${bucketName}\").getPublicUrl() needs this stack's public origin, ` +\n \"and it was not configured. Set PALBASE_PUBLIC_ORIGIN to the address clients reach \" +\n \"this stack at (e.g. https://myproject.palbase.studio).\",\n );\n }\n return `${publicOrigin}/v1/files/${bucketName}/${path}${variant}`;\n },\n\n async createSignedUrl(path, options): Promise<PalbaseResult<PalbaseSignedUrlResponse>> {\n validateStoragePath(path);\n // A DURATION — `{ expiresIn: \"1h\" }`. A bare number is ambiguous between\n // seconds and minutes at every call site that reads it, and the ambiguity\n // is only discovered when a link outlives the object it opened.\n return http.request<PalbaseSignedUrlResponse>(\"POST\", `/v1/storage/sign/${bucketName}/${path}`, {\n body: { expiresIn: options.expiresIn },\n });\n },\n\n async list(prefix?: string, options?: PalbaseListOptions) {\n if (prefix) validateStoragePath(prefix);\n const params = new URLSearchParams();\n if (prefix) params.set(\"prefix\", prefix);\n if (options?.limit !== undefined) params.set(\"limit\", String(options.limit));\n const query = params.toString();\n const res = await http.request<{ objects?: Record<string, unknown>[] }>(\n \"GET\",\n `/v1/storage/bucket/${bucketName}${query ? `?${query}` : \"\"}`,\n );\n // `{objects: [...]}`, not a bare array: the envelope leaves room for the\n // paging this will grow, and unwrapping it here keeps that off callers.\n return mapResponse(res, (body) => (body?.objects ?? []).map((row) => toFileObject(bucketName, row)));\n },\n\n async remove(paths) {\n for (const p of paths) validateStoragePath(p);\n // One request per object: the module deletes an object WITH its variants,\n // and a batch endpoint reporting partial success would need a result shape\n // nobody would read. The first refusal ends it — continuing would report a\n // partial delete as a whole one.\n const removed: PalbaseFileObject[] = [];\n for (const p of paths) {\n const res = await http.request<void>(\"DELETE\", objectPath(p));\n if (res.error) return { data: null, error: res.error, status: res.status };\n removed.push(toFileObject(bucketName, { path: p }));\n }\n return { data: removed, error: null, status: 200 };\n },\n\n async move(from, to) {\n validateStoragePath(from);\n validateStoragePath(to);\n return http.request<void>(\"POST\", `/v1/storage/move/${bucketName}`, { body: { from, to } });\n },\n\n async copy(from, to) {\n validateStoragePath(from);\n validateStoragePath(to);\n return http.request<void>(\"POST\", `/v1/storage/copy/${bucketName}`, { body: { from, to } });\n },\n };\n}\n\n/**\n * @param publicOrigin the address CLIENTS reach this stack at — never the\n * transport's base, which is this process's internal route to palsvc. Empty\n * means it was not configured, and `getPublicUrl` refuses by name.\n */\nexport function buildStorageClient(\n http: ModuleTransport,\n publicOrigin: string,\n): PalbaseStorageClient {\n return {\n bucket(name: string) {\n if (!BUCKET_NAME_RE.test(name)) {\n throw new Error(`Invalid bucket name: \"${name}\". Bucket names must match ${BUCKET_NAME_RE.source}`);\n }\n // Sondaki eğik çizgi BURADA kırpılır: `${origin}/v1/files/...` iki\n // eğik çizgiyle biten bir yol üretirdi ve bazı sunucular onu ayrı bir\n // nesne sayar.\n return buildBucketClient(http, name, publicOrigin.replace(/\\/+$/, \"\"));\n },\n };\n}\n","/**\n * clients/index.ts — the composition root for the module clients.\n *\n * This is what the process calls once at boot. It builds the five clients the\n * engine injects and nothing else.\n *\n * WHAT IS NOT BUILT HERE, and why each one is absent rather than forgotten:\n *\n * - `functions`, `analytics`, `links` — the SDK exports no singleton for any\n * of them, so no handler could reach them. They were constructed on every\n * boot and thrown away. `auth` was in this list until roles arrived: the\n * sign-in half still belongs to the client SDK, but the ASSIGNMENT half is\n * an operator verb a handler has to be able to call, so `Auth` is built\n * above — as `PalbaseAuthAdminClient`, three methods and no more.\n * - `Purchases` — its client talked to palstore, and v2 contains no palstore\n * at all. The surface was unbacked before it was untyped. Dropped from v2\n * by the user's decision on 2026-08-15, with the SDK's `src/purchases/`\n * tree left in place because that decision was \"deferred, not silently\n * taken\". It is taken now: the tree is GONE (2026-08-29), because a\n * decorator standing in front of a service nothing serves is the same\n * defect as `Resource` and `config/*`, which went with it.\n * - The V1 host/executor transport — the isolate it existed for was removed\n * on 2026-08-14. A single-tenant process has nobody to hide its own\n * tenant's credentials from.\n */\n\nimport type { ModuleClients } from \"../engine/index.js\";\nimport { buildAuthClient } from \"./auth.js\";\nimport { buildDocumentsClient } from \"./documents.js\";\nimport { buildFlagsClient } from \"./flags.js\";\nimport { makeHttpClient } from \"./http.js\";\nimport { buildNotificationsClient } from \"./notifications.js\";\nimport { buildRealtimeClient } from \"./realtime.js\";\nimport { buildStorageClient } from \"./storage.js\";\n\nexport interface ModuleClientsConfig {\n /** Where the platform answers. Empty means \"not configured\" — see below. */\n baseUrl: string;\n /** The publishable key. Used only when no service-role key is supplied. */\n apiKey: string;\n /**\n * The service-role key, which is what a backend actually holds. Preferred\n * over `apiKey`: this process IS the project's server.\n */\n serviceRoleKey: string;\n /** The shared Realtime secret. Empty means realtime is not provisioned. */\n realtimeApiJwtSecret: string;\n /**\n * The address CLIENTS reach this stack at. Used ONLY to build public object\n * URLs; every request this bundle makes still goes over `baseUrl`.\n */\n publicOrigin: string;\n /** The request's user, read from the SDK's own scope — never from a caller. */\n getCurrentUserId: () => string | null;\n /** Injected in tests; resolved at call time in production. */\n fetchImpl?: typeof fetch;\n}\n\n/**\n * Build the module clients.\n *\n * Returns an EMPTY bundle when there is no base URL, deliberately: the engine\n * then injects its named stubs, so a handler that reaches for `Storage` gets an\n * error saying which module is unconfigured rather than a crash reading a\n * property of undefined. Booting is not blocked — a project that never touches\n * a module runs fine without one.\n */\nexport function buildModuleClients(cfg: ModuleClientsConfig): ModuleClients {\n const baseUrl = (cfg.baseUrl || \"\").replace(/\\/+$/, \"\");\n if (!baseUrl) return {};\n\n // The service-role key when present: this process is the project's own\n // server, and the publishable key would refuse half of what it needs.\n const apiKey = cfg.serviceRoleKey || cfg.apiKey || \"\";\n const http = makeHttpClient({ baseUrl, apiKey, fetchImpl: cfg.fetchImpl });\n\n return {\n // The ROLE half of auth only (`clients/auth.ts` says why the rest is not\n // here). It rides the same service-role transport, which is exactly the\n // credential the assignment routes demand.\n Auth: buildAuthClient(http),\n Documents: buildDocumentsClient(http),\n Storage: buildStorageClient(http, cfg.publicOrigin),\n Notifications: buildNotificationsClient(http),\n Flags: buildFlagsClient(http, { getCurrentUserId: cfg.getCurrentUserId }),\n Realtime: buildRealtimeClient({\n baseUrl,\n apiJwtSecret: cfg.realtimeApiJwtSecret,\n fetchImpl: cfg.fetchImpl,\n }),\n };\n}\n","/**\n * channels.ts — the realtime channel authorization DSL (spec C-5).\n *\n * `defineChannels({...})` is evaluated at bundle load; the declaration is\n * anchored on globalThis under Symbol.for (the error-registry.ts pattern) so\n * the runtime — a separate module instance — reads the SAME object. The runtime\n * empties that slot before each bundle import and puts it back afterwards, so\n * the declaration belongs to the bundle that made it and not to the process.\n * Entry ORDER is the object's key order and is semantic: first match wins.\n *\n * Undeclared channels are DENIED by the server (fail-closed). ownerOnly()\n * patterns resolve with ZERO server hops; custom entries' authorize() runs\n * in the customer's own runtime with the request scope a controller gets.\n */\n\nconst CHANNELS: unique symbol = Symbol.for(\"palbase.backend.channels\") as never;\n\nexport interface ChannelGrant {\n subscribe: boolean;\n publish?: boolean;\n state?: { read?: boolean; write?: boolean };\n}\n\nexport interface ChannelAuthorizeCtx {\n user: { id: string };\n params: Record<string, string>;\n}\n\ninterface OwnerEntry { kind: \"owner\" }\ninterface PublicEntry {\n kind: \"public\";\n publish?: boolean;\n state?: { read?: boolean; write?: boolean };\n}\n/** What a handler receives: who published, on which channel, and what. */\nexport interface ChannelHandlerCtx {\n user: { id: string };\n params: Record<string, string>;\n channel: string;\n event: string;\n payload: Record<string, unknown>;\n}\n\ninterface CustomEntry {\n authorize: (ctx: ChannelAuthorizeCtx) => ChannelGrant | null | Promise<ChannelGrant | null>;\n /**\n * Take over publishes on this channel instead of fanning them out.\n *\n * Without it, `channel.send(...)` is relayed to the other subscribers\n * verbatim — fine for a chat message, wrong for anything the client should\n * not be trusted to assert. A bid, a vote, a game move is a REQUEST, and the\n * result is whatever this function decides and then publishes (through\n * `Realtime.broadcast` or `Realtime.state.set`).\n *\n * A function rather than the name of a route: `authorize` is already one and\n * runs in this same scope, so naming an endpoint would mean inventing a\n * resolution step for no gain.\n */\n handler?: (ctx: ChannelHandlerCtx) => void | Promise<void>;\n}\nexport type ChannelEntry = OwnerEntry | PublicEntry | CustomEntry;\nexport type ChannelsInput = Record<string, ChannelEntry>;\n\nexport interface ChannelsDef {\n entries: Array<{\n pattern: string;\n kind: \"owner\" | \"public\" | \"custom\";\n publish?: boolean;\n state?: { read?: boolean; write?: boolean };\n authorize?: CustomEntry[\"authorize\"];\n handler?: CustomEntry[\"handler\"];\n }>;\n}\n\n/** Full-access-to-the-owner pattern: the pattern must carry EXACTLY one {param};\n * the server compares its value to the verified token subject with zero hops. */\nexport function ownerOnly(): OwnerEntry {\n return { kind: \"owner\" };\n}\n\n/** Anyone with a valid token may subscribe; publish/state are explicit opt-ins. */\nexport function publicChannel(\n opts: { publish?: boolean; state?: { read?: boolean; write?: boolean } } = {},\n): PublicEntry {\n return { kind: \"public\", publish: opts.publish ?? false, state: opts.state };\n}\n\nfunction paramCount(pattern: string): number {\n return pattern.split(\":\").filter((s) => s.startsWith(\"{\") && s.endsWith(\"}\")).length;\n}\n\nexport function defineChannels(map: ChannelsInput): ChannelsDef {\n const entries: ChannelsDef[\"entries\"] = [];\n for (const [pattern, entry] of Object.entries(map)) {\n if (\"kind\" in entry && entry.kind === \"owner\") {\n if (paramCount(pattern) !== 1) {\n throw new Error(\n `defineChannels: ownerOnly() pattern \"${pattern}\" must carry exactly one {param} ` +\n `(its value is compared to the token subject)`,\n );\n }\n entries.push({ pattern, kind: \"owner\" });\n } else if (\"kind\" in entry && entry.kind === \"public\") {\n entries.push({ pattern, kind: \"public\", publish: entry.publish, state: entry.state });\n } else {\n const c = entry as CustomEntry;\n entries.push({ pattern, kind: \"custom\", authorize: c.authorize, handler: c.handler });\n }\n }\n const def: ChannelsDef = { entries };\n\n // A SECOND, DIFFERENT declaration is a hard error rather than an overwrite.\n //\n // The same bundle can legitimately be evaluated twice in one process — the\n // error registry beside this file documents exactly that case — so an\n // identical re-declaration passes silently. But two DIFFERENT declarations\n // mean two channels files, and overwriting would delete the first one's\n // channels. Undeclared channels are DENIED, so the symptom would be joins\n // refused in production for channels the developer can see declared in their\n // own source, with nothing anywhere saying why. Loud here beats silent there.\n //\n // \"Already\" means WITHIN ONE BUNDLE LOAD. The runtime hands each import an\n // empty slot, so this compares two calls from the same bundle — which is what\n // it was written for. It used to reach across imports as well, and then a\n // deploy that merely ADDED a channel was refused as a second channels file,\n // with a message pointing at a file the customer did not have.\n const carrier = globalThis as Record<symbol, unknown>;\n const existing = carrier[CHANNELS] as ChannelsDef | undefined;\n if (existing && !sameDeclaration(existing, def)) {\n throw new Error(\n `defineChannels: channels were already declared (${existing.entries.length} ` +\n `pattern(s): ${existing.entries.map((e) => e.pattern).join(\", \")}). ` +\n `A project declares its channels ONCE — a second call would overwrite the ` +\n `first, and channels nobody declared are refused.`,\n );\n }\n carrier[CHANNELS] = def;\n return def;\n}\n\n/**\n * One entry as the runtime will compile it, rendered for comparison.\n *\n * NORMALIZED, because the runtime normalizes: `collectChannels` applies\n * `?? false` to publish and both state flags before the table goes on the wire.\n * Comparing the raw entries called two spellings of ONE entry a conflict —\n * `publicChannel()` fills `publish: false` where a hand-written\n * `{ kind: \"public\" }` leaves it undefined, and the two produce a byte-identical\n * table. There is one source of truth for what an entry IS, and it is the row.\n *\n * The authorize function is compared by SOURCE TEXT. Comparing the closures\n * themselves is wrong — two evaluations of one module produce two distinct\n * functions for the same source, which is the case this guard has to let\n * through — but comparing only `Boolean(fn)` called two unrelated\n * authorization rules \"the same declaration\", so the guard stayed silent while\n * one channel's access rule was swapped for another's. Same source, same text;\n * different logic, different text. Not exhaustive (two closures over different\n * captured values share a source), and better than a boolean by the whole\n * distance between \"some rule\" and \"this rule\".\n */\nfunction wireRow(e: ChannelsDef[\"entries\"][number]): string {\n return JSON.stringify([\n e.pattern,\n e.kind,\n e.publish ?? false,\n e.state?.read ?? false,\n e.state?.write ?? false,\n // The handler is compared by SOURCE, like authorize: two evaluations of one\n // module give the same text, while different logic gives different text.\n e.handler ? e.handler.toString() : \"\",\n e.authorize ? e.authorize.toString() : \"\",\n ]);\n}\n\n/** Two declarations are the same when they compile to the same rows in the same\n * ORDER — order is semantic here (first match wins). */\nfunction sameDeclaration(a: ChannelsDef, b: ChannelsDef): boolean {\n if (a.entries.length !== b.entries.length) return false;\n return a.entries.every((x, i) => wireRow(x) === wireRow(b.entries[i]!));\n}\n","import { NotFound } from \"../errors.js\";\n\n/**\n * repository.ts — kiracıya kapsanmış CRUD'un TEK yazımı.\n *\n * Ölçülen kusur: tüketici katmanında 61 forwarding metodu vardı ve her biri\n * aynı iki satırı tekrar ediyordu — kiracı kolonunu yükleme ekle, sonucu\n * çevir. Aynı olan bir şeyi 61 kez yazmak onu 61 kez UNUTULABİLİR yapar; ve\n * unutulan tek bir yüklem, RLS'in altında bir kiracının satırını başka bir\n * kiracıya gösterir.\n *\n * ```ts\n * export class TodoRepository extends defineRepository(\n * Database.public.todos,\n * { tenant: \"household_id\" },\n * ) {}\n * ```\n *\n * Satır anahtarı `id` DEĞİLSE adıyla verilir — `defineTable` bir `id` kolonu\n * şart koşmuyor, birincil anahtar herhangi bir kolonda olabilir:\n *\n * ```ts\n * export class DocRepository extends defineRepository(\n * Database.public.docs,\n * { tenant: \"org_id\", key: \"slug\" },\n * ) {}\n * ```\n *\n * `Database` AMBIENT kalır ve enjekte EDİLMEZ: istek kapsamlıdır, yani bir\n * kurucuya kapatılan bir referans bir isteğin istemcisini bir başkasına\n * taşırdı. Tablo erişimcisi argüman olarak geçer ve her çağrıda güncel istek\n * kapsamını çözen proxy'ye iner; taban sınıfın kurucusu ARGÜMANSIZ kalır, o\n * yüzden container onu ek metadata olmadan çözer.\n */\n\n/**\n * Repo'nun tablodan İSTEDİĞİ dört üye — `Database.public.<t>`'nin alt kümesi.\n *\n * Yüklemler `Record<string, unknown>`: kiracı kolonunun adı ÇALIŞMA ANINDA\n * gelen bir değer, ve TypeScript jenerik bir anahtarla kurulan nesne\n * literalini mapped type'a bağlayamaz (ölçüldü: `{ [k]: v }` → `{ [x: string]:\n * V }`, `{ [P in K]: V }`'ye atanamaz). Kapsamı DAR tutup burada gevşetmek,\n * çağıranın tarafında `as` yazmaktan farklıdır: dışa bakan yüzey — `list`,\n * `find`, `insert`, `update`, `updateScoped`, `delete` — tamamen tipli kalır.\n *\n * `NoInfer`: `Row` YALNIZ `insert`'ün dönüşünden çıkarılır. `findMany` motorda\n * jenerik (`select`/`with`) ve kısıtlarıyla örneklendiğinde ilişki anahtarları\n * taşıyan BAŞKA bir satır tipi önerir; iki aday birleşince satır tipi sessizce\n * genişlerdi.\n */\nexport interface RepositoryTable<Row, Insert, Patch> {\n insert(data: Insert): Promise<Row>;\n findMany(q: { where: Record<string, unknown>; limit?: number }): Promise<NoInfer<Row>[]>;\n updateMany(q: { where: Record<string, unknown>; set: Patch }): Promise<NoInfer<Row>[]>;\n deleteMany(q: { where: Record<string, unknown> }): Promise<number>;\n}\n\n/**\n * Satır anahtarının VARSAYILANI: tablo bir `id` kolonu taşıyorsa `\"id\"`.\n *\n * `defineTable` bir `id` kolonu ŞART KOŞMUYOR — birincil anahtar herhangi bir\n * kolonda `.primaryKey()` ile ya da `primaryKey: [...]` ile bildirilebiliyor.\n * Bu yüzden anahtar sabit değil, PARAMETRE; ama `id` taşıyan tabloların\n * (çoğunluk) hiçbir şey yazmaması gerekiyor.\n */\nexport type DefaultRowKey<Row> = Extract<keyof Row & string, \"id\">;\n\n/**\n * Anahtar bulunamadığında REDDİ ADIYLA söyleyen tip.\n *\n * `id`'si olmayan bir tabloda `key` verilmezse {@link DefaultRowKey} `never`\n * olur ve `Row[never]` de `never`'dır: kapı doğru kapanır ama \"type 'string' is\n * not assignable to type 'never'\" diyerek ÇAREYİ söylemez. Buradaki tek alanlı\n * arayüz aynı reddi verir ve alanın adı hatanın içinde çareyi yazar.\n */\nexport interface MissingRowKey {\n \"defineRepository: bu satırda `id` kolonu yok — anahtarı { key: \\\"...\\\" } ile adlandır\": never;\n}\n\n/** Anahtar kolonunun DEĞER tipi; anahtar bilinmiyorsa {@link MissingRowKey}. */\nexport type RowKey<Row, PK extends keyof Row & string> = [PK] extends [never]\n ? MissingRowKey\n : Row[PK];\n\n/**\n * Kiracıya kapsanmış repo yüzeyi. `K` kiracı kolonu, `Row[K]` onun DEĞERİ.\n *\n * `insert` yükünde kiracı kolonu YOKTUR: onu repo yazar — `Omit` bunu ifade\n * edilemez kılıyor, anlatmıyor. `update`/`updateScoped` patch'i tablonun kendi\n * `set` şeklidir ve kiracı kolonunu DIŞLAMAZ: satırı başka bir kiracıya\n * taşımak tablonun `WITH CHECK` politikasının kararıdır, repo'nun değil — ve\n * repo'nun yüklemi zaten çağıranın kiracısına kapanmış durumda.\n */\nexport interface RepositoryOf<\n Row,\n Insert,\n Patch,\n K extends keyof Row & string,\n PK extends keyof Row & string = DefaultRowKey<Row>,\n> {\n /** Kiracının tüm satırları. */\n list(tenant: Row[K]): Promise<Row[]>;\n /** Kiracının bu anahtarlı satırı, ya da yoksa `null` — yokluk bir DEĞER. */\n find(tenant: Row[K], id: RowKey<Row, PK>): Promise<Row | null>;\n /** Satırı kiracıya YAZAR: kiracı kolonu yükte değil, burada. */\n insert(tenant: Row[K], values: Omit<Insert, K>): Promise<Row>;\n /**\n * Kiracının bu id'li satırını günceller ve GÜNCEL satırı döner.\n *\n * Eşleşen satır yoksa `NotFound` ATAR — çağıran `!` yazmak ya da `null`\n * dallanması yazmak zorunda kalmasın. Yokluğu DEĞER olarak isteyen\n * {@link RepositoryOf.updateScoped} kullanır.\n */\n update(tenant: Row[K], id: RowKey<Row, PK>, patch: Patch): Promise<Row>;\n /**\n * {@link RepositoryOf.update} ile AYNI yüklem, ama bulunamazsa `null` döner.\n *\n * Tüketicinin bugün elle yazdığı `updateMany(…).then(rows => rows[0] ?? null)`\n * kalıbının adı budur.\n */\n updateScoped(tenant: Row[K], id: RowKey<Row, PK>, patch: Patch): Promise<Row | null>;\n /** Kiracının bu anahtarlı satırını siler. Yoksa bir şey olmaz. */\n delete(tenant: Row[K], id: RowKey<Row, PK>): Promise<void>;\n}\n\n/**\n * Kiracıya kapsanmış bir repo TABAN SINIFI üretir.\n *\n * Dönen sınıf `abstract`: doğrudan `new` edilemez, çünkü DI'ın çözeceği ad alt\n * sınıfın adıdır (`TodoRepository`), üretilen anonim sınıfınki değil.\n */\nexport function defineRepository<\n Row,\n Insert,\n Patch,\n K extends keyof Row & string,\n PK extends keyof Row & string = DefaultRowKey<Row>,\n>(\n table: RepositoryTable<Row, Insert, Patch>,\n opts: { tenant: K; key?: PK },\n): abstract new () => RepositoryOf<Row, Insert, Patch, K, PK> {\n const tenantColumn = opts.tenant;\n // Anahtar `string` olarak tutuluyor: yüklemler zaten `Record<string, unknown>`\n // ve `opts.key ?? \"id\"`'yi `PK`'ye daraltmak bir `as` gerektirirdi — tipin\n // taşıdığı güvence dışa bakan imzalarda, burada değil.\n const rowKey: string = opts.key ?? \"id\";\n\n // Yüklem TEK yerde kuruluyor. 61 forwarding metodunun her birinde ayrı ayrı\n // yazılıyor olması, birinde unutulmasını mümkün kılan şeydi.\n const scope = (tenant: Row[K]): Record<string, unknown> => ({ [tenantColumn]: tenant });\n const scopeRow = (tenant: Row[K], id: RowKey<Row, PK>): Record<string, unknown> => ({\n [tenantColumn]: tenant,\n [rowKey]: id,\n });\n\n /**\n * Kiracı kolonunu YAZMA yüküne ekleyen tek yer — ve bu dosyadaki tek\n * daraltma.\n *\n * Gerekçesi TypeScript'in ölçülmüş bir sınırı: jenerik bir anahtarla kurulan\n * nesne literali mapped type'a bağlanmıyor (`{ [k]: v }` → `{ [x: string]:\n * V }`, `{ [P in K]: V }`'ye TS2322 ile atanamıyor). Daraltma TEK satırda ve\n * çağıranın göremediği bir yerde duruyor; dışa bakan altı metodun imzası\n * tamamen tipli.\n *\n * Kiracı SONRA yazılıyor: yükte aynı adda bir alan kalmışsa (tip onu\n * yasaklıyor, ama bu yol JavaScript'ten de çağrılabilir) repo'nunki kazanır.\n * Kapsamı çağıranın verisi belirlemez.\n */\n const scopedPayload = (values: Omit<Insert, K>, tenant: Row[K]): Insert =>\n ({ ...values, [tenantColumn]: tenant }) as Insert;\n\n abstract class Repository implements RepositoryOf<Row, Insert, Patch, K, PK> {\n list(tenant: Row[K]): Promise<Row[]> {\n return table.findMany({ where: scope(tenant) });\n }\n\n async find(tenant: Row[K], id: RowKey<Row, PK>): Promise<Row | null> {\n const rows = await table.findMany({ where: scopeRow(tenant, id), limit: 1 });\n return rows[0] ?? null;\n }\n\n insert(tenant: Row[K], values: Omit<Insert, K>): Promise<Row> {\n return table.insert(scopedPayload(values, tenant));\n }\n\n async update(tenant: Row[K], id: RowKey<Row, PK>, patch: Patch): Promise<Row> {\n const row = await this.updateScoped(tenant, id, patch);\n if (row === null) {\n throw new NotFound(\n `${String(tenantColumn)}=${String(tenant)} kapsamında ${rowKey}=${String(id)} bulunamadı`,\n );\n }\n return row;\n }\n\n async updateScoped(tenant: Row[K], id: RowKey<Row, PK>, patch: Patch): Promise<Row | null> {\n const rows = await table.updateMany({ where: scopeRow(tenant, id), set: patch });\n return rows[0] ?? null;\n }\n\n async delete(tenant: Row[K], id: RowKey<Row, PK>): Promise<void> {\n await table.deleteMany({ where: scopeRow(tenant, id) });\n }\n }\n\n return Repository;\n}\n","// Method decorators: `@Get` / `@Post` / `@Put` / `@Patch` / `@Delete` /\n// `@Query` declare a route (verb + subpath + options) on a controller method. These are LEGACY\n// method decorators (`experimentalDecorators`), receiving\n// `(prototype, methodName, descriptor)`. They write into the per-class registry\n// (registry.ts). The success-response schema is NOT declared here: it is derived\n// from the method's RETURN TYPE by a codegen step and injected onto the route at\n// runtime via `recordReturn` (registry.ts).\nimport {\n recordRoute,\n type HttpMethodUpper,\n type RouteOptions,\n} from \"./registry.js\";\n\n/** A legacy method decorator.\n *\n * The third argument is typed `unknown`, not `PropertyDescriptor`, on purpose:\n * when the decorator is applied to a PARAMETER (`m(@Query(\"q\") q: string)`),\n * TypeScript calls it with the parameter INDEX there. The type would let the\n * runtime pretend that cannot happen; the runtime measures it instead. */\n// `descriptor` is OPTIONAL but stays a PropertyDescriptor: optional so a\n// property-position call (descriptor undefined) type-checks, narrow so a\n// parameter-position call (`m(@Query(\"q\") q)`, third argument a number) is\n// still TS1239 at compile time. `unknown` here would trade that compile-time\n// refusal for the runtime one below; keeping both is the point (W4 r2 I-3).\ntype MethodDecorator = (\n target: object,\n propertyKey: string | symbol | undefined,\n descriptor?: PropertyDescriptor,\n) => void;\n\n/** Build a method decorator for one HTTP verb. The decorated method's name is\n * the route `fnName` — and it is PUBLIC API, not authoring sugar: the runtime\n * derives the operationId as `<controllerName>.<fnName>` (the dotted namespace\n * the SDKs expose as `pb.todos.list()`), so renaming this method renames every\n * client call. The flat verb+path id is only the fallback for routes with no\n * controller metadata. See openapi/discover.ts. */\nfunction makeMethodDecorator(method: HttpMethodUpper) {\n return function (subpath: string, options: RouteOptions = {}): MethodDecorator {\n // Runtime guard for stale pre-9.0.0 code: `@Query(zodSchema)` used to be\n // the query-string PARAM decorator. Applied against this SDK it would\n // silently record a garbage route (schema-as-subpath) and fail the deploy\n // with a baffling self-conflict — fail loud and name the migration instead.\n if (typeof subpath !== \"string\") {\n throw new Error(\n `@${method[0]}${method.slice(1).toLowerCase()}(subpath) expects a string subpath, got ${typeof subpath}.` +\n (method === \"QUERY\"\n ? \" If this is a zod schema on a method parameter: the query-string param decorator was renamed @QueryParams(schema) in @palbase/backend 9.0.0.\"\n : \"\"),\n );\n }\n return function (target, propertyKey, descriptor?: PropertyDescriptor) {\n const verb = `${method[0]}${method.slice(1).toLowerCase()}`;\n // POSITION guard, and it runs BEFORE `recordRoute`: `m(@Query(\"q\") q)`\n // passes the subpath guard above (the argument IS a string) and arrives\n // here as a parameter-decorator call — the third argument is the\n // parameter index, not a descriptor. Recording it would register a\n // route the author never wrote, named after the method, and the deploy\n // would fail later, elsewhere, on that route. Refuse here, by position,\n // and name the decorators that DO go on a parameter.\n if (typeof (descriptor as unknown) === \"number\") {\n throw new Error(\n `@${verb}(...) is a ROUTE decorator and was applied to parameter #${descriptor} of ${propertyKey === undefined ? \"the constructor\" : String(propertyKey)}; ` +\n \"for query-string params use @QueryParams(schema), for the body @Body(schema), for a path segment @Param(name)\",\n );\n }\n // CLASS position: `@Get(\"/x\") class C {}` arrives with no propertyKey\n // and would record a route literally named \"undefined\". AFTER the\n // parameter check: a constructor parameter (`constructor(@Get(\"/x\") x)`)\n // arrives as (C, undefined, 0) and deserves the parameter message.\n if (propertyKey === undefined) {\n throw new Error(`@${verb}(...) goes on a METHOD, not on a class; put it on the handler method inside @Controller`);\n }\n recordRoute(target, String(propertyKey), method, subpath, options);\n };\n };\n}\n\n/** `@Get(subpath, options?)` — declare a GET route. */\nexport const Get = makeMethodDecorator(\"GET\");\n/** `@Post(subpath, options?)` — declare a POST route. */\nexport const Post = makeMethodDecorator(\"POST\");\n/** `@Put(subpath, options?)` — declare a PUT route. */\nexport const Put = makeMethodDecorator(\"PUT\");\n/** `@Patch(subpath, options?)` — declare a PATCH route. */\nexport const Patch = makeMethodDecorator(\"PATCH\");\n/** `@Delete(subpath, options?)` — declare a DELETE route. */\nexport const Delete = makeMethodDecorator(\"DELETE\");\n/** `@Query(subpath, options?)` — declare an HTTP QUERY route (RFC 10008):\n * safe + idempotent like GET, body-carrying like POST. Input rides `@Body`. */\nexport const Query = makeMethodDecorator(\"QUERY\");\n","/**\n * The one rule for a declared surface name.\n *\n * A job's name is the row the scheduler holds it under; a webhook's name is the\n * path segment its endpoint is served at. Both used to be the FILE's name, which\n * made a public identity a property of where a class happened to sit — rename\n * the file and the scheduler starts a different job, or a sender's configured\n * URL stops resolving.\n *\n * Declaring it puts the identity beside the schedule and the secret, where a\n * reader is already looking. There is no default: a default would be a SECOND\n * source for the identity, and the whole design rests on there being one.\n */\nconst SHAPE = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/;\n\nexport function assertSurfaceName(name: unknown, decorator: string, kind: string): void {\n if (typeof name !== \"string\" || name.trim() === \"\") {\n throw new Error(\n `${decorator} requires a \\`name\\` — it is this ${kind}'s identity, and it is ` +\n `declared rather than taken from the file name.`,\n );\n }\n if (!SHAPE.test(name)) {\n throw new Error(\n `${decorator} name \"${name}\" is not usable: it reaches a URL and a log line, so it ` +\n `must be lowercase letters, digits and dashes, starting and ending with one of those.`,\n );\n }\n}\n","// @Webhook / @On — the inbound-webhook half of the decorator surface.\n//\n// Mirrors decorators/controller.ts exactly: symbol-keyed, non-enumerable\n// metadata on the constructor plus a `__palbase` discriminant, read back by a\n// resolver. The resolver is the ONLY translation point — it returns the shape\n// the runtime already consumes, so the isolate's dispatch and the signature\n// engine's cross-binding golden are untouched by the authoring change.\nimport type { WebhookMeta, WebhookProvider } from \"../webhook.js\";\nimport type { Container } from \"../container.js\";\nimport { assertSurfaceName } from \"./surface-name.js\";\n\n/** A signature scheme spelled out, for a service with no preset. The presets\n * (`provider`) are named configurations of this same shape. */\nexport interface SignatureSpec {\n /** Header carrying the signature. */\n header: string;\n /** Stripped before comparison (e.g. `sha256=`). Omit when absent. */\n prefix?: string;\n algo: \"hmac-sha256\" | \"hmac-sha1\";\n encoding: \"hex\" | \"base64\";\n /** What the HMAC covers. Exactly two placeholders: `{body}` and `{ts}`.\n * Everything else is literal. `{ts}` requires `timestampHeader` and brings\n * the five-minute replay window with it. */\n signs: string;\n timestampHeader?: string;\n}\n\nexport interface WebhookOptions {\n /**\n * The path segment this webhook is served at: `/webhooks/<name>`.\n *\n * DECLARED, not derived. It used to be the file's name, which put a PUBLIC\n * URL — the one a sender is configured with — in the file system rather than\n * beside the provider and the secret, where a reader looks for it.\n */\n name: string;\n provider?: WebhookProvider;\n signature?: SignatureSpec;\n /** Env-var REFERENCE for the signing secret — the platform never holds it. */\n secret: { env: string };\n}\n\nexport type WebhookEventHandler = (event: unknown, meta: WebhookMeta) => Promise<void>;\n\nexport interface ResolvedWebhook {\n provider?: WebhookProvider;\n signature?: SignatureSpec;\n secret: { env: string };\n events: Record<string, WebhookEventHandler>;\n}\n\nexport const WEBHOOK_META: unique symbol = Symbol.for(\"palbase.backend.webhookMeta\");\nexport const WEBHOOK_EVENTS: unique symbol = Symbol.for(\"palbase.backend.webhookEvents\");\n\ninterface EventEntry {\n event: string;\n fnName: string;\n}\n\ninterface WebhookCarrier {\n __palbase?: \"webhook\";\n [WEBHOOK_META]?: WebhookOptions;\n [WEBHOOK_EVENTS]?: EventEntry[];\n}\n\nfunction carrierOf(ctor: object): WebhookCarrier {\n return ctor as WebhookCarrier;\n}\n\n/** Mark a class as an inbound webhook. The mount name is the FILE name — there\n * is deliberately no `name` option, because the file name IS the public URL. */\nexport function Webhook(options: WebhookOptions) {\n return function <T extends abstract new (...args: never[]) => object>(ctor: T): T {\n const carrier = carrierOf(ctor);\n Object.defineProperty(carrier, WEBHOOK_META, {\n value: options,\n enumerable: false,\n configurable: true,\n writable: false,\n });\n Object.defineProperty(carrier, \"__palbase\", {\n value: \"webhook\",\n enumerable: false,\n configurable: true,\n writable: false,\n });\n return ctor;\n };\n}\n\n/** Bind a method to one event name. Any string is valid: presets provide\n * autocomplete, never a constraint, because we do not carry provider catalogs. */\nexport function On(event: string) {\n return function (target: object, fnName: string | symbol): void {\n // Method decorators receive the PROTOTYPE; metadata belongs on the ctor.\n const carrier = carrierOf((target as { constructor: object }).constructor);\n const existing = carrier[WEBHOOK_EVENTS];\n const entries: EventEntry[] = existing ? [...existing] : [];\n entries.push({ event, fnName: String(fnName) });\n Object.defineProperty(carrier, WEBHOOK_EVENTS, {\n value: entries,\n enumerable: false,\n configurable: true,\n writable: false,\n });\n };\n}\n\n/** Read a decorated class back as the resolved config the runtime consumes.\n * Every misuse throws HERE, at build time, rather than becoming a webhook that\n * answers 200 and does nothing.\n *\n * @throws when the class declares constructor parameters (FR-011) — nothing\n * here supplies them, so the field would be `undefined` on every delivery. */\n/**\n * Everything a webhook DECLARES — provider or signature template, the secret's\n * env var, and the event names — validated, without constructing the class.\n *\n * Same split as jobs and hooks: reading a declaration should not build an\n * object. `getWebhookConfig` is what needs an instance, and it needs a\n * container to get one.\n */\nexport function getWebhookManifest(ctor: object): {\n name: string;\n provider: string | undefined;\n secretEnv: string;\n events: string[];\n} {\n const { meta, entries } = validateWebhook(ctor);\n return {\n name: meta.name,\n provider: meta.provider,\n secretEnv: meta.secret.env,\n events: entries.map((e) => e.event),\n };\n}\n\n/** The declaration half: every refusal, and no construction. */\nfunction validateWebhook(ctor: object): {\n meta: NonNullable<ReturnType<typeof carrierOf>[typeof WEBHOOK_META]>;\n entries: NonNullable<ReturnType<typeof carrierOf>[typeof WEBHOOK_EVENTS]>;\n} {\n const carrier = carrierOf(ctor);\n const meta = carrier[WEBHOOK_META];\n const entries = carrier[WEBHOOK_EVENTS] ?? [];\n\n if (!meta) {\n throw new Error(\n `@On used on a class that is not decorated with @Webhook (${(ctor as { name?: string }).name ?? \"anonymous\"})`,\n );\n }\n assertSurfaceName(meta.name, \"@Webhook\", \"webhook\");\n if (!meta.provider && !meta.signature) {\n throw new Error(\n \"@Webhook requires either a `provider` preset or an explicit `signature` — \" +\n \"an endpoint with no verification would accept forged deliveries\",\n );\n }\n // EITHER, not both. The isolate picks `provider` when both are present and\n // never looks at `signature`, so a tenant that wrote both gets deliveries\n // verified against a scheme they did not choose — silently, and with no way to\n // tell from the outside which one ran. Ambiguity about WHICH signature check\n // guards an endpoint is not something to resolve by precedence.\n if (meta.provider && meta.signature) {\n throw new Error(\n \"@Webhook declares BOTH a `provider` preset and an explicit `signature` — \" +\n \"these are alternatives; keep the one that describes the sender, because only `provider` would be used\",\n );\n }\n if (meta.signature) {\n const sig = meta.signature;\n // Mirrors Go's NewTemplateVerifier (internal/webhook/verify.go). Both sides\n // reject the same specs; this one rejects at build, which is the only place\n // a tenant can still act on it.\n if (!sig.header) {\n throw new Error(\"@Webhook signature requires `header` — the header the signature arrives in\");\n }\n if (sig.algo !== \"hmac-sha256\" && sig.algo !== \"hmac-sha1\") {\n throw new Error(`@Webhook signature has an unsupported algo \"${sig.algo}\"`);\n }\n if (sig.encoding !== \"hex\" && sig.encoding !== \"base64\") {\n throw new Error(`@Webhook signature has an unsupported encoding \"${sig.encoding}\"`);\n }\n if (!sig.signs?.includes(\"{body}\")) {\n throw new Error(\"@Webhook signature `signs` must contain {body} — signing a constant is not a signature\");\n }\n if (sig.signs.includes(\"{ts}\") && !sig.timestampHeader) {\n throw new Error(\"@Webhook signature uses {ts} but declares no `timestampHeader` to read it from\");\n }\n }\n if (!meta.secret?.env) {\n throw new Error(\"@Webhook requires `secret: { env: \\\"VAR_NAME\\\" }`\");\n }\n if (entries.length === 0) {\n throw new Error(\"@Webhook requires at least one @On handler\");\n }\n return { meta, entries };\n}\n\nexport function getWebhookConfig(ctor: object, container: Container): ResolvedWebhook {\n const { meta, entries } = validateWebhook(ctor);\n\n const instance = container.get(ctor as never) as Record<string, WebhookEventHandler>;\n // Object.create(null), not {} — event names are free-form, so `@On(\"constructor\")`\n // and `@On(\"toString\")` are legal. A plain literal inherits those keys from\n // Object.prototype, and the duplicate check below would reject the FIRST and\n // only handler for them as a redeclaration.\n const events: Record<string, WebhookEventHandler> = Object.create(null) as Record<string, WebhookEventHandler>;\n for (const entry of entries) {\n if (Object.prototype.hasOwnProperty.call(events, entry.event)) {\n throw new Error(`@On(\"${entry.event}\") declared twice on the same webhook`);\n }\n events[entry.event] = (event, metaArg) =>\n (instance[entry.fnName] as WebhookEventHandler).call(instance, event, metaArg);\n }\n\n return {\n ...(meta.provider ? { provider: meta.provider } : {}),\n ...(meta.signature ? { signature: meta.signature } : {}),\n secret: meta.secret,\n events,\n };\n}\n","// @Hook — the BLOCKING half of the internal-event surface.\n//\n// Two axes decide which decorator a handler wants. Where does the event come\n// from, and can the handler stop it?\n//\n// @Webhook + @On an OUTSIDE service (Stripe, GitHub…) — cannot block\n// @Hook an event this stack raised — CAN block: `throw` cancels it\n// @On an event this stack raised — listens only, a monitor\n//\n// The blocking power lives in the NAME `@Hook`, not in the method decorator's\n// shape, which is why `@On` keeps meaning \"listener\" in both worlds and needs\n// no change. `@Upload` is the same pattern already shipped: the storage module\n// calls the tenant's method, and a method that answers 4xx discards the object\n// and hands its exact status, body and content-type back to the client.\n//\n// Mirrors decorators/webhook.ts: symbol-keyed, non-enumerable metadata on the\n// constructor, read back by one resolver. The resolver is the only translation\n// point, so the runtime consumes a shape the authoring surface never leaks.\nimport type { HookMeta } from \"../hooks.js\";\nimport { WEBHOOK_EVENTS } from \"./webhook.js\";\nimport type { Container } from \"../container.js\";\n\n/** A hook handler. Returning quietly ALLOWS; throwing DENIES (blocking hooks). */\nexport type HookFn = (event: unknown, meta: HookMeta) => Promise<unknown>;\n\nexport interface ResolvedHookClass {\n /** `@Hook` handlers, by event. A throw here cancels the operation. */\n blocking: Record<string, HookFn>;\n /** `@On` handlers, by event. A throw here reaches nobody but the log. */\n listeners: Record<string, HookFn>;\n}\n\n/** A hook's refusal, with the reason the caller will see.\n *\n * Any thrown error denies — this class exists so the REASON travels as a\n * deliberate message rather than as whatever a stray TypeError happened to say.\n * The engine is fail-closed by design (an unreachable hook denies), so a hook\n * body should stay narrow: an accidental throw refuses a real user. */\nexport class Deny extends Error {\n constructor(reason: string) {\n super(reason);\n this.name = \"Deny\";\n }\n}\n\nexport const HOOK_BLOCKING: unique symbol = Symbol.for(\"palbase.backend.hookBlocking\");\n\ninterface EventEntry {\n event: string;\n fnName: string;\n}\n\n/** `@Hook(\"before.user.create\")` — a blocking handler for one stack event. */\nexport function Hook(event: string) {\n return function (target: object, fnName: string | symbol): void {\n const carrier = (target as { constructor: object }).constructor as Record<symbol, unknown>;\n const existing = carrier[HOOK_BLOCKING] as EventEntry[] | undefined;\n const entries: EventEntry[] = existing ? [...existing] : [];\n entries.push({ event, fnName: String(fnName) });\n Object.defineProperty(carrier, HOOK_BLOCKING, {\n value: entries,\n enumerable: false,\n configurable: true,\n writable: false,\n });\n };\n}\n\n/** Binds one decorator's entries onto a single instance of the class.\n *\n * ONE instance for the whole class, built here rather than per call: a hook\n * that opens a client or reads a list in its constructor would otherwise pay\n * for it on every signup. */\nfunction bind(instance: Record<string, HookFn>, entries: EventEntry[], kind: string) {\n const out: Record<string, HookFn> = Object.create(null) as Record<string, HookFn>;\n for (const entry of entries) {\n if (Object.prototype.hasOwnProperty.call(out, entry.event)) {\n throw new Error(`${kind}(\"${entry.event}\") declared twice on the same hook class`);\n }\n // Resolved ONCE, here, so a decorator naming a method that does not exist\n // fails at build time with the name in the message — rather than at the\n // first signup, as \"instance[fnName] is not a function\".\n const fn = instance[entry.fnName];\n if (typeof fn !== \"function\") {\n throw new Error(`${kind}(\"${entry.event}\") names no method \"${entry.fnName}\" on the class`);\n }\n out[entry.event] = (event, meta) => fn.call(instance, event, meta);\n }\n return out;\n}\n\n/** Resolves a hook class into the two maps the runtime dispatches from.\n *\n * Every misuse throws HERE, at build time, rather than becoming a hook that is\n * silently never called — the failure mode this whole change exists to end.\n *\n * @throws when the class declares constructor parameters (FR-011) — nothing\n * here supplies them, so the field would be `undefined` on every event. */\nexport function getHookConfig(ctor: object, container: Container): ResolvedHookClass {\n const carrier = ctor as Record<symbol, unknown>;\n const blockingEntries = (carrier[HOOK_BLOCKING] ?? []) as EventEntry[];\n const listenerEntries = (carrier[WEBHOOK_EVENTS] ?? []) as EventEntry[];\n\n if (blockingEntries.length === 0 && listenerEntries.length === 0) {\n throw new Error(\n `${(ctor as { name?: string }).name ?? \"a hook class\"} carries no handler — ` +\n \"a hook file must declare at least one @Hook (blocking) or @On (listener) method\",\n );\n }\n\n const instance = container.get(ctor as never) as Record<string, HookFn>;\n return {\n blocking: bind(instance, blockingEntries, \"@Hook\"),\n listeners: bind(instance, listenerEntries, \"@On\"),\n };\n}\n\n/**\n * Which events a hook class declares, and which of them BLOCK.\n *\n * Metadata only — the class is not constructed. Deploy's `hooks.manifest.json`\n * needs exactly this and has no container to build with.\n */\nexport function getHookManifest(ctor: object): { blocking: string[]; listeners: string[] } {\n const carrier = ctor as Record<symbol, unknown>;\n const blockingEntries = (carrier[HOOK_BLOCKING] ?? []) as EventEntry[];\n const listenerEntries = (carrier[WEBHOOK_EVENTS] ?? []) as EventEntry[];\n if (blockingEntries.length === 0 && listenerEntries.length === 0) {\n throw new Error(\n `${(ctor as { name?: string }).name ?? \"a hook class\"} carries no handler — ` +\n \"a hook file must declare at least one @Hook (blocking) or @On (listener) method\",\n );\n }\n return {\n blocking: blockingEntries.map((e) => e.event),\n listeners: listenerEntries.map((e) => e.event),\n };\n}\n","// `@Upload` — the single-method direct-storage upload decorator, and its\n// `@UploadedObject` parameter companion + `UploadConfig`/`UploadedObject` types.\n//\n// Unlike `@Get`/`@Post`/… (where bytes flow THROUGH the br-pod), an `@Upload`\n// route never sees the file bytes: the client uploads DIRECTLY to storage via a\n// signed URL the br-pod mints in an authorize pre-flight. The decorated method\n// body is the COMPLETION handler — it runs once, after storage confirms the\n// object landed (via an HMAC-signed completion webhook), and returns the typed\n// result the client awaits. There is exactly one method: it is BOTH the\n// authorize gate (its uploadConfig drives the guard + signed-URL pinning) AND\n// the completion handler (its body).\n//\n// On the wire the authorize pre-flight is a POST; what marks a route as an\n// upload route through the whole pipeline (registry → flatten → openapi →\n// codegen) is the PRESENCE of `uploadConfig` on the route — never a special HTTP\n// verb. The `@Get`/`@Post`/… decorators never set it.\nimport { recordRoute, recordParam } from \"./registry.js\";\nimport type { RouteOptions } from \"./registry.js\";\nimport type { PalbaseBucketName } from \"../stack.js\";\n\n/** A legacy method decorator (`experimentalDecorators`): `(prototype, name,\n * descriptor)`. */\ntype MethodDecorator = (\n target: object,\n propertyKey: string | symbol,\n descriptor: PropertyDescriptor,\n) => void;\n\n/** A legacy parameter decorator: `(prototype, name, paramIndex)`. */\ntype ParameterDecorator = (\n target: object,\n propertyKey: string | symbol,\n parameterIndex: number,\n) => void;\n\n/**\n * Direct-storage upload settings for an `@Upload` route. The br-pod validates an\n * authorize request against these (size/type), then mints a signed upload URL\n * that PINS the limits so storage itself rejects an over-limit / wrong-type PUT\n * — the client cannot exceed what it declared.\n */\nexport interface UploadConfig {\n /**\n * Target bucket NAME — one the STACK holds.\n *\n * The union comes from the generated `palbase-stack.d.ts`, so a bucket the\n * stack does not carry is a compile error. It used to say \"MUST exist in\n * `config/storage.ts` defineStorage(...)\", and that invariant was carried by\n * this sentence plus a cross-check nothing called; it is carried by the type\n * now.\n *\n * The bucket is the SINGLE SOURCE OF TRUTH for the size limit + MIME allowlist:\n * `bucket({ fileSizeLimit, allowedMimeTypes })`. Storage enforces those at the\n * actual PUT (the only guard a client cannot skip), so `@Upload` deliberately\n * does NOT take its own `maxSize`/`allowedTypes` — duplicating them here would\n * let a route declare a tighter limit than its bucket that storage would not\n * enforce (a real bypass: declare 10 bytes at authorize, then PUT up to the\n * bucket ceiling straight at the signed URL). One bucket, one limit, enforced.\n */\n bucket: PalbaseBucketName;\n /**\n * SERVER-side object key template. The client NEVER chooses the path. Tokens:\n * `{userId}` (authenticated user id), `{uploadId}` (server-minted), and\n * `{filename}` (the client-declared filename, sanitized). e.g.\n * `\"{userId}/{uploadId}-{filename}\"`.\n */\n pathTemplate: string;\n}\n\n/**\n * The uploaded object, injected into an `@Upload` method body by\n * `@UploadedObject()` once storage confirms the upload. Bytes are NOT present\n * (they went straight to storage) — this is the metadata the completion handler\n * persists.\n */\nexport interface UploadedObject {\n /** Server-minted id correlating authorize ↔ completion (idempotency key). */\n uploadId: string;\n /** Final object key in the bucket (rendered from `pathTemplate`). */\n path: string;\n /** Bucket the object landed in. */\n bucket: string;\n /** Object size in bytes, as reported by storage. */\n size: number;\n /** Object MIME type, as reported by storage — detected from the BYTES, not\n * from the filename or from what the client claimed. */\n contentType: string;\n /** SHA-256 of the stored bytes, hex. The same value the object's ETag is\n * derived from, so a client that has it can tell whether it already holds\n * these bytes. */\n checksum: string;\n /** Pixel width, for an image. Absent otherwise — a PDF has no dimensions,\n * and reporting 0 would be a measurement rather than an absence. */\n width?: number;\n /** Pixel height, for an image. */\n height?: number;\n /**\n * A ~25-byte placeholder the client paints INSTANTLY while the real image\n * downloads — the thing that replaces a grey skeleton with something already\n * shaped like the picture. Absent for non-images.\n *\n * Persist it beside the object's path: it costs a column and saves a request\n * per picture on every gallery render.\n */\n thumbhash?: string;\n /**\n * The renditions the bucket declared, by name, as URLs ready to use.\n *\n * Present on the completion input so the handler that stores the row has\n * everything it needs in one place — asking for them afterwards would be a\n * second call per upload, and per picture on every read.\n */\n variants: Record<string, string>;\n}\n\n/**\n * `@Upload(subpath, config)` — declare a direct-storage upload route. The method\n * body is the completion handler; `config.uploadConfig` drives the authorize\n * guard + signed-URL pinning.\n *\n * @example\n * @Upload(\"/\", { bucket: \"docs\", pathTemplate: \"{userId}/{uploadId}-{filename}\" })\n * async upload(@UploadedObject() obj: UploadedObject, @User() user): Promise<DocResult> { ... }\n * // The size limit + MIME allowlist come from the \"docs\" bucket ON THE STACK\n * // — storage enforces them at the PUT.\n */\nexport function Upload(\n subpath: string,\n config: UploadConfig & Pick<RouteOptions, \"auth\" | \"rateLimit\">,\n): MethodDecorator {\n const { auth, rateLimit, ...uploadConfig } = config;\n validateUploadConfigShape(uploadConfig);\n const options: RouteOptions = {\n uploadConfig,\n ...(auth !== undefined ? { auth } : {}),\n ...(rateLimit !== undefined ? { rateLimit } : {}),\n };\n return function (target, propertyKey) {\n // On the wire the authorize pre-flight is a POST; `uploadConfig` is what\n // marks this as an upload route downstream.\n recordRoute(target, String(propertyKey), \"POST\", subpath, options);\n };\n}\n\n/**\n * `@UploadedObject()` — inject the uploaded object (`: UploadedObject`) into an\n * `@Upload` method body (the completion input). Only valid on an `@Upload`\n * route; the bytes are NOT present (they went directly to storage), this is the\n * confirmed object's metadata.\n *\n * Co-located with the {@link UploadedObject} TYPE so a single exported name\n * `UploadedObject` carries BOTH the decorator value and the type annotation.\n */\nexport function UploadedObject(): ParameterDecorator {\n return function (target, propertyKey, parameterIndex) {\n recordParam(target, String(propertyKey), {\n index: parameterIndex,\n kind: \"uploadedObject\",\n });\n };\n}\n\n/**\n * Shape-validate an UploadConfig at decoration time (author-time failure beats a\n * silent deploy bug). Does NOT check that the bucket EXISTS — the generated\n * `palbase-stack.d.ts` union does that, and it does it at compile time rather\n * than at deploy.\n */\nexport function validateUploadConfigShape(c: UploadConfig): void {\n if (c === null || typeof c !== \"object\") {\n throw new Error(\"@Upload config must be an object { bucket, pathTemplate, ... }\");\n }\n // Read the bucket through a WIDENED view on purpose. Its declared type is\n // `PalbaseBucketName`, which is `never` until the project generates\n // `palbase-stack.d.ts` — and `never.length` does not typecheck. This function\n // is a RUNTIME guard against a shape the compiler never saw (a plain-JS\n // caller, a bundle boundary), so the value arriving here is genuinely unknown\n // and reading it as such is the honest signature, not a cast to dodge an error.\n const bucket: unknown = (c as { bucket?: unknown }).bucket;\n if (typeof bucket !== \"string\" || bucket.length === 0) {\n throw new Error(\"@Upload config.bucket must be a non-empty bucket name\");\n }\n if (typeof c.pathTemplate !== \"string\" || c.pathTemplate.length === 0) {\n throw new Error(\"@Upload config.pathTemplate must be a non-empty key template\");\n }\n}\n\n","// `@Sse` — the streaming-response decorator, and its `@SseOut` / `@Signal`\n// parameter companions.\n//\n// Unlike `@Get`/`@Post`/… (where the handler's RETURN VALUE is serialised to\n// JSON), an `@Sse` route's method body WRITES frames as it goes and its return\n// value is discarded. The response is `text/event-stream` and stays open until\n// the body returns or the client disconnects.\n//\n// On the wire an `@Sse` route is a POST — a stream is started by a request that\n// carries input. What marks it as a streaming route through the whole pipeline\n// (registry → flatten → openapi → codegen) is the PRESENCE of `sseConfig` on the\n// route, NEVER the verb: an ordinary `@Post` route is also POST, so the verb\n// cannot carry the distinction. This is the same rule `@Upload` states, for the\n// same reason.\n//\n// The problem this solves: a provider on the server (an AI client, a job queue,\n// any long-running producer) streams from a session; while a client is connected\n// the frames reach it, and when the client disconnects the provider must stop\n// being pulled. That last half is what `@Signal()` exists for.\nimport { recordRoute, recordParam } from \"./registry.js\";\nimport type { RouteOptions } from \"./registry.js\";\nimport type { ZodTypeAny } from \"zod\";\n\n/** A legacy method decorator (`experimentalDecorators`): `(prototype, name,\n * descriptor)`. */\ntype MethodDecorator = (\n target: object,\n propertyKey: string | symbol,\n descriptor: PropertyDescriptor,\n) => void;\n\n/** A legacy parameter decorator: `(prototype, name, paramIndex)`. */\ntype ParameterDecorator = (\n target: object,\n propertyKey: string | symbol,\n parameterIndex: number,\n) => void;\n\n/**\n * Settings for an `@Sse` route.\n *\n * EMPTY in v1, and deliberately so: the pipeline keys off this object's\n * PRESENCE, not its contents (see the file header). Declaring the type now means\n * a later setting arrives as a field on an existing marker rather than as a\n * second marker nothing downstream reads.\n */\nexport interface SseConfig {\n /**\n * The shape of ONE frame — what a single `out.write(value)` carries.\n *\n * REQUIRED, not optional, and that is the whole point. An `@Sse` handler\n * returns `Promise<void>`, so the codegen-injected `recordReturn` has no type\n * to record and nothing downstream can infer what a frame is. A route without\n * this declares a stream whose element type is unknown, and every generated\n * client from that contract is opaque — which is precisely the failure\n * `x-palbase-sse` exists to prevent. Making it optional would have left that\n * failure one forgotten field away.\n *\n * Measured live on a real pushed stack (2026-08-29): the contract gate refused\n * the deploy with \"2 untyped response(s) — every generated client from it is\n * opaque\", naming both routes that omitted it.\n */\n frame: ZodTypeAny;\n}\n\n/**\n * The writer injected by `@SseOut()`. Each `write` emits ONE SSE `data:` frame\n * carrying `value` JSON-encoded.\n *\n * The FIRST `write` is load-bearing beyond its frame: it settles the request's\n * database transaction. A streaming response may run for minutes, and the\n * handler runs inside the request's transaction — holding one open for the life\n * of a stream exhausts the connection pool, a failure invisible to a unit test\n * that only dies under load. So the first frame is the point at which the\n * request phase is declared over, and database access after it is refused by\n * name rather than silently run against a settled transaction.\n *\n * The practical rule for a handler: do the database work BEFORE the first write.\n */\nexport interface SseWriter {\n write(value: unknown): void;\n}\n\n/**\n * `@Sse(subpath, config)` — declare a streaming route.\n *\n * @example\n * @Sse(\"/chat\", { frame: ChatFrame })\n * async chat(@Body() b: ChatInput, @SseOut() out: SseWriter, @Signal() signal: AbortSignal) {\n * const stream = await openai.chat.completions.create(\n * { model: \"gpt-5.6\", messages: b.messages, stream: true },\n * { signal },\n * );\n * for await (const chunk of stream) out.write(chunk);\n * }\n * // The client disconnects → `signal` aborts → the provider stops being pulled.\n * // The signal is a plain AbortSignal, so it goes wherever the provider takes\n * // one: `{ signal }` for the OpenAI and Anthropic SDKs, `abortSignal:` for the\n * // Vercel AI SDK, `fetch(url, { signal })` for a raw call.\n */\nexport function Sse(\n subpath = \"\",\n config: SseConfig & Pick<RouteOptions, \"auth\" | \"rateLimit\">,\n): MethodDecorator {\n const { auth, rateLimit, ...sseConfig } = config;\n const options: RouteOptions = {\n sseConfig,\n ...(auth !== undefined ? { auth } : {}),\n ...(rateLimit !== undefined ? { rateLimit } : {}),\n };\n return function (target, propertyKey) {\n recordRoute(target, String(propertyKey), \"POST\", subpath, options);\n };\n}\n\n/**\n * `@SseOut()` — inject the frame writer (`: SseWriter`) into an `@Sse` method\n * body. Only meaningful on an `@Sse` route.\n */\nexport function SseOut(): ParameterDecorator {\n return function (target, propertyKey, parameterIndex) {\n recordParam(target, String(propertyKey), { index: parameterIndex, kind: \"sseOut\" });\n };\n}\n\n/**\n * `@Signal()` — inject the request's `AbortSignal`, which enters the aborted\n * state when the client disconnects.\n *\n * NOT derivable from `@Req()`: `PBRequest` carries only request-scoped data —\n * the typed input, route/query params, headers, the authenticated user, calling\n * client metadata, trace ids, and the declared error throwers — and no signal\n * (endpoint.ts:358-363).\n *\n * Measured 2026-08-29 on Bun: an infinite producer guarded by this signal\n * stopped four frames after the client was killed, and the handler's `finally`\n * ran. It is the same mechanism a NestJS handler reaches through\n * `req.on(\"close\")`.\n */\nexport function Signal(): ParameterDecorator {\n return function (target, propertyKey, parameterIndex) {\n recordParam(target, String(propertyKey), { index: parameterIndex, kind: \"signal\" });\n };\n}\n","// @Room — the realtime surface a backend can actually MANAGE.\n//\n// palbase's realtime lets a backend TALK (broadcast, state.set, push.send) and\n// lets it INTERCEPT a client's publish (defineChannels' handler). What it never\n// let a backend do is SEE the connection: who joined, who left, whether anyone\n// is still watching. A room is that missing half, in the shape this SDK already\n// uses for HTTP — a class with decorated methods.\n//\n// The cost of the gap was concrete: nothing could tell a project that the last\n// device left, so an expensive upstream (an AI session, a market feed, a game\n// loop) kept running and kept billing with nobody reading it. `@OnFirst` and\n// `@OnEmpty` exist for exactly that pair of moments.\n//\n// WHAT A ROOM IS NOT: it does not know where the room id came from, what the\n// history is, or what `@OnFirst` starts. All three belong to the project. The\n// primitive is infrastructure; it carries messages both ways and reports who is\n// present.\n\nimport type { ZodTypeAny } from \"zod\";\nimport {\n recordRoom,\n recordRoomHook,\n recordRoomMessage,\n type RoomHook,\n} from \"./registry.js\";\n\nexport interface RoomOptions {\n /**\n * The events this room sends to its clients, by name.\n *\n * Declared rather than inferred, because a room emits from anywhere in the\n * class — there is no return type to read. The map is the room's public\n * surface: it becomes a Swift enum and a TypeScript union in the generated\n * clients, so a device gets `case .tick(n:)` instead of an opaque bag.\n *\n * Per-event rather than one blob because realtime is event-ADDRESSED all the\n * way down (`Realtime.broadcast(channel, EVENT, payload)`).\n */\n events: Record<string, ZodTypeAny>;\n\n /**\n * How long a room is held after its last sign of life, in milliseconds.\n *\n * Default 60_000, and the floor is not a matter of taste: the decision must\n * survive the SLOWEST client's heartbeat gap twice over, and the web SDK\n * beats every 25 s (palbe/src/realtime/connection.ts:133) against iOS's 2 s\n * (RealtimeConnection.swift:162). A shorter default would declare healthy web\n * clients dead between two beats.\n *\n * Raise it for an upstream that is expensive to restart; lower it (never\n * below ~50 s while web beats at 25 s) for one that is cheap.\n */\n graceMs?: number;\n}\n\n/** Twice the slowest client heartbeat, plus margin. See RoomOptions.graceMs. */\nconst DEFAULT_GRACE_MS = 60_000;\n\n/**\n * A room pattern IS a channel pattern, so it obeys the channel matcher's rules.\n *\n * Both ends of the wire split on `:` — Go's `matchPattern`\n * (internal/modules/rt/channels.go) and this SDK's `matchDeclared` — so a\n * pattern written with slashes matches NO live topic. It fails silently: the\n * room compiles, ships, and simply never fires. Refused here, by name, at the\n * only moment a human is looking.\n *\n * The duplicate-param rule is carried over for the reason channels.ts states:\n * `dm:{uid}:{uid}` against `dm:victim:attacker` lets the last segment win, and\n * an owner check then compares the attacker's id with itself and passes.\n */\nfunction assertPattern(pattern: string): void {\n if (pattern.includes(\"/\")) {\n throw new Error(\n `@Room(\"${pattern}\"): channel patterns are colon-separated, not slash-separated. ` +\n `Write \"${pattern.replace(/\\//g, \":\")}\" — a slash matches no live topic.`,\n );\n }\n const segments = pattern.split(\":\");\n if (segments.some((s) => s === \"\")) {\n throw new Error(`@Room(\"${pattern}\"): empty segment — every segment must be non-empty.`);\n }\n const seen = new Set<string>();\n for (const s of segments) {\n if (!s.startsWith(\"{\") || !s.endsWith(\"}\")) continue;\n const name = s.slice(1, -1);\n if (name === \"\") throw new Error(`@Room(\"${pattern}\"): \"{}\" names no parameter.`);\n if (seen.has(name)) {\n throw new Error(`@Room(\"${pattern}\"): parameter \"{${name}}\" appears twice.`);\n }\n seen.add(name);\n }\n}\n\n/**\n * Declare a class as a room.\n *\n * ```ts\n * @Room(\"chat:{roomId}\", { events: { message: Message } })\n * class ChatRoom {\n * @OnAuthorize() can({ user, params }) { … }\n * @OnFirst() open(ctx) { … } // the room filled\n * @OnEmpty() close(ctx) { … } // nobody is watching any more\n * @OnMessage(\"say\", Say) say(ctx) { … }\n * }\n * ```\n *\n * The pattern is the topic: `chat:{roomId}` addresses `chat:42`. A room is\n * marked by the PRESENCE of this config — never by a name, a base class or a\n * naming convention.\n */\nexport function Room(pattern: string, options: RoomOptions) {\n return function <T extends abstract new (...args: never[]) => object>(ctor: T): T {\n assertPattern(pattern);\n // Member decorators have already run (TypeScript evaluates members before\n // the class), so the hook buffer is complete here and `recordRoom` drains\n // it. controller.ts:203 documents and depends on the same ordering.\n recordRoom(ctor, {\n pattern,\n events: options.events,\n graceMs: options.graceMs ?? DEFAULT_GRACE_MS,\n });\n return ctor;\n };\n}\n\nfunction hookDecorator(hook: RoomHook): () => MethodDecorator {\n return () =>\n function (target: object, propertyKey: string | symbol): void {\n recordRoomHook(target, hook, String(propertyKey));\n };\n}\n\n/** Who may enter. Return a grant to admit, `null` to refuse. */\nexport const OnAuthorize = hookDecorator(\"authorize\");\n\n/**\n * The room is occupied and nobody owns it — start whatever the room needs.\n *\n * Deliberately a CONDITION rather than a 0→1 transition, and the difference is\n * load-bearing: a runtime restart, a deploy pointer swap (the previous release\n * is never torn down) and an owner that died all leave a full room with nobody\n * holding it. A transition would fire once and never again; a condition\n * recovers every time.\n *\n * Exactly one runtime in the cluster enters this hook for a given room, so\n * three devices never open three upstreams.\n */\nexport const OnFirst = hookDecorator(\"first\");\n\n/** A device arrived. Anything emitted here reaches ONLY that device. */\nexport const OnJoin = hookDecorator(\"join\");\n\n/** A device left. */\nexport const OnLeave = hookDecorator(\"leave\");\n\n/** Nobody is watching any more — stop whatever `@OnFirst` started. */\nexport const OnEmpty = hookDecorator(\"empty\");\n\n/**\n * A message from a client, validated against `schema` before the method runs.\n *\n * A payload that fails the schema never reaches the method: the client is told\n * why, and the room's code only ever sees the shape it declared.\n */\nexport function OnMessage(name: string, schema: ZodTypeAny): MethodDecorator {\n return function (target: object, propertyKey: string | symbol): void {\n recordRoomMessage(target, name, String(propertyKey), schema);\n };\n}\n","// Parameter decorators: `@Body` / `@QueryParams` / `@Param` / `@Headers` / `@User` /\n// `@OptionalUser` / `@Client` / `@RequestId` / `@TraceId` / `@Req`. Each records\n// `{ index, kind, schema?, name? }` into the per-class registry for the method\n// it decorates. These are LEGACY parameter decorators\n// (`experimentalDecorators`), receiving `(prototype, methodName, paramIndex)` —\n// esbuild/tsc preserve the param index at runtime (verified, design §0), which\n// is how dispatch injects positionally. No type reflection\n// (`emitDecoratorMetadata`) is used: validation comes from the zod schema, the\n// type annotation the developer writes is purely for autocomplete.\nimport type { ZodTypeAny } from \"zod\";\nimport { recordParam, type ParamKind } from \"./registry.js\";\n\n/** A legacy parameter decorator. */\ntype ParameterDecorator = (\n target: object,\n propertyKey: string | symbol,\n parameterIndex: number,\n) => void;\n\n/** Build a parameter decorator that records the given kind (+ optional schema /\n * name) at the decorated parameter's index. */\nfunction makeParamDecorator(\n kind: ParamKind,\n extra?: { schema?: ZodTypeAny; name?: string },\n): ParameterDecorator {\n return function (target, propertyKey, parameterIndex) {\n recordParam(target, String(propertyKey), {\n index: parameterIndex,\n kind,\n ...(extra?.schema !== undefined ? { schema: extra.schema } : {}),\n ...(extra?.name !== undefined ? { name: extra.name } : {}),\n });\n };\n}\n\n/** `@Body(schema)` — inject the request body, validated against `schema`. The\n * developer writes `: T` (= `z.infer<schema>`, same name) for autocomplete. */\nexport function Body(schema: ZodTypeAny): ParameterDecorator {\n return makeParamDecorator(\"body\", { schema });\n}\n\n/** `@QueryParams(schema)` — inject the parsed query params, validated against\n * `schema`. */\nexport function QueryParams(schema: ZodTypeAny): ParameterDecorator {\n return makeParamDecorator(\"query\", { schema });\n}\n\n/** `@Headers(schema?)` — inject the request headers (lowercase keys). With a\n * schema, headers are validated + the codegen emits header parameters. */\nexport function Headers(schema?: ZodTypeAny): ParameterDecorator {\n return makeParamDecorator(\"headers\", schema !== undefined ? { schema } : undefined);\n}\n\n/** `@Param(\"id\")` — inject one matched path param by name. */\nexport function Param(name: string): ParameterDecorator {\n return makeParamDecorator(\"param\", { name });\n}\n\n/** `@User()` — inject the authenticated user (`: User`, non-null for an\n * effective-required route). The runtime resolves the effective auth. */\nexport function User(): ParameterDecorator {\n return makeParamDecorator(\"user\");\n}\n\n/** `@OptionalUser()` — inject the user as `User | null` (for routes whose\n * effective auth is `false` / `{ required: false }`). */\nexport function OptionalUser(): ParameterDecorator {\n return makeParamDecorator(\"optionalUser\");\n}\n\n/** `@Client()` — inject the parsed calling-client metadata (`: ClientInfo`). */\nexport function Client(): ParameterDecorator {\n return makeParamDecorator(\"client\");\n}\n\n/** `@RequestId()` — inject the per-request id (`: string`). */\nexport function RequestId(): ParameterDecorator {\n return makeParamDecorator(\"requestId\");\n}\n\n/** `@TraceId()` — inject the W3C trace id (`: string`). */\nexport function TraceId(): ParameterDecorator {\n return makeParamDecorator(\"traceId\");\n}\n\n/** `@Req()` — inject the raw request object (escape hatch, `: PBRequest`). */\nexport function Req(): ParameterDecorator {\n return makeParamDecorator(\"req\");\n}\n\n// NOTE: `@UploadedObject()` lives in decorators/upload.ts (co-located with the\n// `UploadedObject` TYPE) so a single exported name carries both the value (the\n// decorator) and the type — TS can only merge value+type under one export name\n// when both are declared in the SAME module.\n","import type { DBClient, Logger, CacheClient, PalbaseModuleClients } from \"./endpoint.js\";\nimport type { User } from \"./types.js\";\n\n/** Middleware context — subset of EndpointContext without input (not yet validated). */\nexport interface MiddlewareContext extends PalbaseModuleClients {\n params: Record<string, string>;\n query: Record<string, string>;\n headers: Record<string, string>;\n user: User | null;\n db: DBClient;\n env: Record<string, string>;\n log: Logger;\n cache: CacheClient;\n requestId: string;\n environmentId: string;\n}\n\n/** Middleware function signature — receives context and next function. */\nexport type MiddlewareHandler = (\n ctx: MiddlewareContext,\n next: () => Promise<void>,\n) => Promise<void>;\n\n/**\n * REMOVED IN BEHAVIOUR, KEPT IN NAME.\n *\n * There is no middleware pipeline in this runtime. No bundler reads a\n * `middleware/` directory, the engine never calls a handler defined here, and\n * measured on 2026-08-31 this function had no caller anywhere in the runtime or\n * the CLI. It returned its argument unchanged, so code written against it\n * compiled, deployed, and then never ran — with nothing reporting that.\n *\n * A silent shell is the worst version of a retired feature: it lets a user (or a\n * coding assistant, which is how this surfaced) ship a request logger, an auth\n * check or a rate limiter that simply does not exist in production. So the call\n * refuses, and says where the work belongs.\n *\n * The SYMBOL survives because removing a published export costs a major and\n * 25.0.1 had just shipped. Deleting it is a proposal for the next one; the types\n * below stay either way, so a file that only annotates with them still compiles.\n *\n * This is the shape the SDK already uses for a retired surface: `@Query(schema)`\n * on a parameter throws at decoration time with a message naming its\n * replacement.\n */\nexport function defineMiddleware(_fn: MiddlewareHandler): never {\n throw new Error(\n \"defineMiddleware() is not wired to anything: no bundler reads a `middleware/` \" +\n \"directory and the engine has no middleware pipeline, so a handler defined \" +\n \"here deploys and never runs. Put cross-cutting work in a service the \" +\n \"controllers call, and use route options for auth (`@Controller(path, { auth })`) \" +\n \"and rate limits (`@Get(path, { rateLimit })`).\",\n );\n}\n","/** Non-service, per-invocation data for job handlers.\n * Services (Database, Log, …) are imported as singletons, not passed here. */\nexport interface JobMeta {\n /** Environment-scoped env vars. */\n env: Record<string, string>;\n /** The globally unique Environment runtime identifier. */\n environmentId: string;\n}\n\n/**\n * Cron expression validation.\n * Supports standard 5-field cron: minute hour day-of-month month day-of-week.\n * Each field allows: number, *, ranges (1-5), steps (star/2), lists (1,3,5).\n */\nexport function validateCronExpression(expression: string): string | null {\n const trimmed = expression.trim();\n if (trimmed === \"\") {\n return \"Cron expression is required\";\n }\n\n const parts = trimmed.split(/\\s+/);\n if (parts.length !== 5) {\n return `Invalid cron expression \"${trimmed}\": expected 5 fields (minute hour day month weekday), got ${parts.length}`;\n }\n\n const fieldNames = [\"minute\", \"hour\", \"day of month\", \"month\", \"day of week\"];\n const fieldRanges: [number, number][] = [\n [0, 59],\n [0, 23],\n [1, 31],\n [1, 12],\n [0, 7],\n ];\n\n for (let i = 0; i < 5; i++) {\n const field = parts[i]!;\n const name = fieldNames[i]!;\n const [min, max] = fieldRanges[i]!;\n\n const error = validateCronField(field, name, min, max);\n if (error !== null) {\n return error;\n }\n }\n\n return null;\n}\n\nfunction validateCronField(\n field: string,\n name: string,\n min: number,\n max: number,\n): string | null {\n // Split by comma for lists\n const listParts = field.split(\",\");\n for (const part of listParts) {\n // Check for step: */2, 1-5/2\n const stepParts = part.split(\"/\");\n if (stepParts.length > 2) {\n return `Invalid ${name} field: \"${field}\"`;\n }\n\n const base = stepParts[0]!;\n const step = stepParts[1];\n\n if (step !== undefined) {\n const stepNum = Number(step);\n if (!Number.isInteger(stepNum) || stepNum < 1) {\n return `Invalid step value in ${name} field: \"${field}\"`;\n }\n }\n\n if (base === \"*\") {\n continue;\n }\n\n // Check for range: 1-5\n if (base.includes(\"-\")) {\n const rangeParts = base.split(\"-\");\n if (rangeParts.length !== 2) {\n return `Invalid range in ${name} field: \"${field}\"`;\n }\n const rangeStart = Number(rangeParts[0]);\n const rangeEnd = Number(rangeParts[1]);\n if (\n !Number.isInteger(rangeStart) ||\n !Number.isInteger(rangeEnd) ||\n rangeStart < min ||\n rangeEnd > max ||\n rangeStart > rangeEnd\n ) {\n return `Invalid range in ${name} field: \"${field}\"`;\n }\n continue;\n }\n\n // Single number\n const num = Number(base);\n if (!Number.isInteger(num) || num < min || num > max) {\n return `Invalid value in ${name} field: \"${field}\"`;\n }\n }\n\n return null;\n}\n","// @Job — the cron half of the decorator surface. Same metadata mechanism as\n// @Webhook/@Controller. The job's NAME is not here on purpose: it is the file\n// name, which is also what the Temporal schedule id is built from. Two names\n// with nothing reconciling them is what this replaces.\nimport type { JobMeta } from \"../job.js\";\nimport { validateCronExpression } from \"../job.js\";\nimport type { Container } from \"../container.js\";\nimport { assertSurfaceName } from \"./surface-name.js\";\n\nexport interface JobOptions {\n /**\n * The job's identity, and the name the scheduler holds its rows under.\n *\n * DECLARED, not derived. It used to be the file's name, which made the\n * identity a property of where the class sat — rename the file and the\n * scheduler starts a different job. Ownership and identity both come from a\n * declaration now, and this is where a reader looks for it.\n *\n * Lowercase, digits and dashes: it reaches a scheduler row and a log line.\n */\n name: string;\n /** Cron expression, five fields (e.g. \"0 3 * * *\"). */\n schedule: string;\n /** Execution timeout in seconds. Defaults to 30, ceiling 300 (sandbox limit). */\n timeout?: number;\n /**\n * How many times a FAILED run is retried before the run is recorded failed.\n * Defaults to 5, ceiling 10; 0 disables retrying entirely.\n *\n * Retries exist for the transient half of the failure space — the runtime\n * still waking, a network blip — not for a job that is wrong. A permanent\n * failure still lands in the run history, it just lands after the retries\n * are spent rather than instead of them.\n */\n retry?: number;\n}\n\nexport interface ResolvedJob {\n /** The declared identity — the scheduler's row name. */\n name: string;\n schedule: string;\n timeout: number;\n retry: number;\n handler: (meta: JobMeta) => Promise<void>;\n}\n\nconst DEFAULT_TIMEOUT_SECONDS = 30;\nconst MAX_TIMEOUT_SECONDS = 300;\nconst DEFAULT_RETRY = 5;\nconst MAX_RETRY = 10;\n\nexport const JOB_META: unique symbol = Symbol.for(\"palbase.backend.jobMeta\");\n\ninterface JobCarrier {\n __palbase?: \"job\";\n [JOB_META]?: JobOptions;\n}\n\nexport function Job(options: JobOptions) {\n return function <T extends abstract new (...args: never[]) => object>(ctor: T): T {\n const carrier = ctor as unknown as JobCarrier;\n Object.defineProperty(carrier, JOB_META, {\n value: options,\n enumerable: false,\n configurable: true,\n writable: false,\n });\n Object.defineProperty(carrier, \"__palbase\", {\n value: \"job\",\n enumerable: false,\n configurable: true,\n writable: false,\n });\n return ctor;\n };\n}\n\n/**\n * What a job DECLARES — schedule, timeout, retry. Reads metadata and nothing\n * else: the class is NOT constructed.\n *\n * Deploy's manifest script needs exactly this and no instance (stack_bundle.go\n * writes `jobs.manifest.json` from it, with no runtime and therefore no\n * container). Constructing a class to read a cron string was a side effect, and\n * it is the side effect that made the container look optional — which in turn\n * let a caller that never passes one compile quietly.\n */\nexport interface JobManifest {\n name: string;\n schedule: string;\n timeout: number;\n retry: number;\n}\n\nexport function getJobManifest(ctor: object): JobManifest {\n const meta = (ctor as JobCarrier)[JOB_META];\n if (!meta) {\n throw new Error(\n `getJobConfig on a class with no @Job decorator (${(ctor as { name?: string }).name ?? \"anonymous\"})`,\n );\n }\n assertSurfaceName(meta.name, \"@Job\", \"job\");\n if (!meta.schedule || meta.schedule.trim() === \"\") {\n throw new Error(\"@Job requires a `schedule` cron expression\");\n }\n const cronError = validateCronExpression(meta.schedule);\n if (cronError) {\n throw new Error(`@Job has an invalid cron schedule: ${cronError}`);\n }\n\n const timeout = meta.timeout ?? DEFAULT_TIMEOUT_SECONDS;\n if (!Number.isInteger(timeout) || timeout <= 0) {\n throw new Error(\"@Job `timeout` must be a positive whole number of seconds\");\n }\n if (timeout > MAX_TIMEOUT_SECONDS) {\n throw new Error(`@Job \\`timeout\\` exceeds the ${MAX_TIMEOUT_SECONDS}s sandbox ceiling`);\n }\n\n const retry = meta.retry ?? DEFAULT_RETRY;\n if (!Number.isInteger(retry) || retry < 0) {\n throw new Error(\"@Job `retry` must be a whole number of attempts, zero or more\");\n }\n if (retry > MAX_RETRY) {\n throw new Error(`@Job \\`retry\\` exceeds the ceiling of ${MAX_RETRY}`);\n }\n\n return { name: meta.name, schedule: meta.schedule, timeout, retry };\n}\n\n/**\n * The job, ready to run — manifest plus a bound `run`.\n *\n * `container` is REQUIRED. It used to be absent (the class was built with\n * `new`), and then briefly optional, which is worse: an optional parameter lets\n * a caller that forgot it compile, and the job would receive `undefined` for\n * every dependency at its first scheduled run, hours after deploy, in a process\n * nobody is watching. Required makes the two runtime call sites a TYPE error.\n */\nexport function getJobConfig(ctor: object, container: Container): ResolvedJob {\n const { name, schedule, timeout, retry } = getJobManifest(ctor);\n\n const instance = container.get(ctor as never) as { run?: (meta: JobMeta) => Promise<void> };\n if (typeof instance.run !== \"function\") {\n throw new Error(\"@Job class must declare an async run() method\");\n }\n const run = instance.run.bind(instance);\n\n return { name, schedule, timeout, retry, handler: run };\n}\n","export type {\n PBRequest,\n ClientInfo,\n RateLimitConfig,\n DBClient,\n DBOps,\n FileContext,\n Logger,\n CacheClient,\n SecretsService,\n PalbaseDocsClient,\n PalbaseCollectionRef,\n PalbaseDocumentRef,\n PalbaseDocumentSnapshot,\n PalbaseQuerySnapshot,\n PalbaseWhereOperator,\n PalbaseResult,\n Middleware,\n ErrorDef,\n ErrorMap,\n ErrorThrowers,\n} from \"./endpoint.js\";\nexport {\n Database,\n Auth,\n Documents,\n Storage,\n Cache,\n Secrets,\n Log,\n Notifications,\n Flags,\n Realtime,\n __setRuntime,\n __runWithRuntime,\n __requestALS,\n __getRuntime,\n // Where a long-lived resource lives: opened once as the app comes up, closed\n // when it goes away. `__runStartHooks` is the engine's door to them (it\n // CLAIMS the declarations, so a candidate release loaded beside the live one\n // never closes the live one's pool); `__resetLifecycleHooks` is for tests.\n onStart,\n onShutdown,\n __runStartHooks,\n __resetLifecycleHooks,\n} from \"./runtime.js\";\nexport type {\n RuntimeServices,\n RequestStore,\n LifecycleHook,\n ShutdownRunner,\n} from \"./runtime.js\";\n\n// The module clients and their composition root. The PROCESS calls\n// buildModuleClients once at boot and hands the result to createApp — which is\n// the whole reason this package now contains the implementations and not just\n// the interfaces they were being checked against by nobody.\nexport { buildModuleClients } from \"./clients/index.js\";\nexport type { ModuleClientsConfig } from \"./clients/index.js\";\nexport { makeHttpClient, PalbaseModuleError } from \"./clients/http.js\";\n// The one named refusal the role surface raises. Exported because a handler\n// branches on it: a role name that misses is a typo in committed code.\nexport { RoleNotDefined } from \"./clients/auth.js\";\nexport type { ModuleTransport, RequestOptions, TransportConfig } from \"./clients/http.js\";\n\nexport type {\n PalbaseAuthClient,\n PalbaseAuthAdminClient,\n PalbaseStorageClient,\n PalbaseBucketClient,\n PalbaseRealtimeClient,\n PalbaseFunctionsClient,\n PalbaseInvokeOptions,\n PalbaseFlagsClient,\n PalbaseFlagsServiceClient,\n PalbaseFlagContext,\n PalbaseFlagVariant,\n PalbaseFlag,\n PalbaseFlagValue,\n PalbaseFlagSource,\n PalbaseSetOverrideResult,\n PalbaseSetOverridesResult,\n PalbaseClearOverrideResult,\n PalbaseClearAllOverridesResult,\n PalbaseBatchOverrideOperation,\n PalbaseBatchSetOverridesResult,\n PalbaseNotificationsClient,\n PalbasePushClient,\n PalbaseEmailClient,\n PalbaseSmsClient,\n PalbaseWhatsAppClient,\n PalbaseInboxClient,\n PalbasePreferencesClient,\n PalbaseAnalyticsClient,\n PalbaseAnalyticsQueryNamespace,\n PalbaseAnalyticsManagementNamespace,\n PalbaseLinksClient,\n // Shared local types\n PalbaseUser,\n PalbaseSession,\n PalbaseDeviceInfo,\n PalbaseAttestAndroidParams,\n PalbaseAttestAndroidResult,\n PalbaseAttestiOSParams,\n PalbaseAttestiOSResult,\n PalbaseBindDeviceParams,\n PalbaseVerifyRequestSignatureParams,\n PalbaseFileObject,\n PalbaseSignedUrlResponse,\n PalbaseUploadOptions,\n PalbaseTransformOptions,\n PalbaseListOptions,\n PalbasePushSendParams,\n PalbasePushSendResponse,\n PalbaseEmailSendParams,\n PalbaseEmailSendResponse,\n PalbaseSmsSendParams,\n PalbaseSmsSendResponse,\n PalbaseWhatsAppTemplate,\n PalbaseWhatsAppSendParams,\n PalbaseWhatsAppSendResponse,\n PalbaseWhatsAppEvent,\n PalbaseInboxSendParams,\n PalbaseInboxSendResponse,\n PalbaseInboxMessage,\n PalbaseInboxListOptions,\n PalbaseInboxListResult,\n PalbasePreferences,\n PalbaseNotificationChannel,\n PalbaseRegisterDeviceParams,\n PalbaseDeviceTokenView,\n PalbaseMultiChannelResponse,\n PalbaseAnalyticsProperties,\n PalbaseIdentifyTraits,\n PalbaseCountQueryInput,\n PalbaseCountResult,\n PalbaseEventsQueryInput,\n PalbaseEventsResult,\n PalbaseUsersQueryInput,\n PalbaseUsersResult,\n PalbaseFunnelQueryInput,\n PalbaseFunnelResult,\n PalbaseRetentionQueryInput,\n PalbaseRetentionResult,\n PalbaseCohortQueryInput,\n PalbaseCohortResult,\n PalbaseOverviewResult,\n PalbaseEventNamesResult,\n PalbaseUserDetailResult,\n PalbaseCreateLinkParams,\n PalbaseUpdateLinkParams,\n PalbaseLink,\n PalbaseLinkDetails,\n PalbaseLinkAnalytics,\n PalbaseQrCodeOptions,\n PalbaseMatchParams,\n PalbaseInitialLink,\n PalbaseListLinksOptions,\n PalbaseListLinksResult,\n} from \"./clients.js\";\nexport { defineSchema, defineTable, TABLE_META, index, IndexBuilder, foreignKey, freeze, guard, backfill } from \"./db/schema.js\";\nexport type { ForeignKeyBuilder, ForeignKeyDef, FkAction, FkMatch, FreezeBuilder, FreezeDef } from \"./db/foreign-key.js\";\nexport type { GuardBuilder, GuardDef, GuardEvent } from \"./db/guard.js\";\nexport type { BackfillDef } from \"./db/backfill.js\";\n// The declaration as DATA — what the deploy reads to build the database. The\n// bundler calls this; a project never has to.\nexport { toSchemaJSON } from \"./db/schema-json.js\";\nexport type { SchemaJSON, TableJSON, ColumnJSON, PolicyJSON, ForeignKeyJSON, FreezeJSON, GuardJSON, BackfillJSON } from \"./db/schema-json.js\";\n// `SchemaInput` is NOT here. It typed the retired dictionary form —\n// `defineSchema({ tables: { todos: { columns } } })` — which `defineSchema`\n// now refuses by name (FR-061), so nothing can be assigned to it and nothing\n// ever imported it. Publishing the type of a shape the code rejects is a\n// second way in that only exists in the editor: its JSDoc taught the old\n// layout to anyone who hovered it.\nexport type { SchemaDef, TableDef, TableInput, ColumnMap, TableHandle, IndexDef } from \"./db/schema.js\";\nexport { policy, can, check, PolicyBuilder, PolicyExprRef, exprCtx } from \"./db/policy.js\";\n// `TableRef` bir tablo bildiriminin ANNOTATION'ı: iki tablo birbirinin\n// kolonuna `existsIn` ile bakınca TypeScript ikisini de birbirinden\n// çıkarmaya çalışır ve döngüyü `any` ile keser. Annotation döngüyü kırar ve\n// kolon adlarını tipli bırakır — bu yüzden TÜKETİCİNİN yazabilmesi gerekir.\nexport type { PolicyDef, PolicyCommand, PolicyMode, PolicyExpr, PolicyBinOp, PolicyExprCtx, PolicyOperand, CheckDef, TableRef } from \"./db/policy.js\";\n// The realtime twin of `policy`: which channels exist and who may join them.\n// Undeclared channels are denied by the server, so this declaration is the\n// whole surface — the runtime reads it back off globalThis at boot.\nexport { defineChannels, ownerOnly, publicChannel } from \"./channels.js\";\nexport type { ChannelsDef, ChannelEntry, ChannelsInput, ChannelGrant, ChannelAuthorizeCtx } from \"./channels.js\";\nexport { PALBASE_EXTENSIONS, EXTENSION_DEPENDENCIES, isPalbaseExtension } from \"./db/extensions.js\";\nexport type { PalbaseExtension } from \"./db/extensions.js\";\nexport {\n uuid, text, integer, bigint, numeric, boolean, timestamp, jsonb, enumType, vector,\n ownedByUser, userRef, installationRef,\n} from \"./db/columns.js\";\nexport type { ColumnBuilder, ColumnDef, ColumnType, OnDeleteAction, AnyColumn } from \"./db/columns.js\";\nexport { raw } from \"./db/raw.js\";\nexport type { RawConstraintDef } from \"./db/raw.js\";\nexport { openai } from \"./db/embedding.js\";\nexport type { EmbeddingModelRef } from \"./db/embedding.js\";\nexport { makeTypedDB, col, sqlFragment, withRetry } from \"./db/typed-db.js\";\nexport type { AtomicDatabase, PageInput } from \"./db/typed-db.js\";\nexport type { Page, PageInfo, PageNavigation, RawPageOptions } from \"./db/page.js\";\nexport type { InsertManyOptions } from \"./db/bulk.js\";\nexport type { CommandOptions } from \"./db/command.js\";\nexport type { AtomicOptions, TransactionIsolation } from \"./db/transaction-options.js\";\nexport type {\n TypedDB,\n TypedTx,\n TypedTable,\n InsertShape,\n RowShape,\n EnvTypedDatabase,\n EnvServiceDatabase,\n EnvTypedTable,\n EnvTables,\n EnvSchemas,\n TxPlan,\n TxTables,\n ColRef,\n SqlFragment,\n SetValue,\n SetShape,\n // FİLTRE TİPLERİ — bir sorguyu parça parça kurup fonksiyonlar arasında\n // geçirebilmek için ADLANDIRILABİLİR olmaları gerekiyor. Yoksa\n // `function siparisFiltresi(): ???` yazılamıyor ve yazar ya `Parameters<...>`\n // gibi bir kaçamağa ya da her şeyi tek çağrıda toplamaya mecbur kalıyor.\n // (`TxWhere` — plan yolunun filtresi — zaten dışa aktarılıyordu; düz yolunki\n // atlanmıştı.)\n WhereFilter,\n WhereOp,\n QueryInput,\n MutateInput,\n AggregateInput,\n AggregateResult,\n InsertValues,\n OrderBySpec,\n FindManyOpts,\n} from \"./db/typed-db.js\";\n// Transaction plans: the `tx.tables.*` operation surface, its handles, and the\n// expressions a plan may write. `Database.$transaction()` is on `Database`.\nexport { increment, decrement, inc, dec, now, TxRefError, TxPlanError } from \"./db/tx-plan.js\";\nexport type {\n Ref,\n TxRow,\n TxRows,\n TxTable,\n TxPlanHandle,\n Materialized,\n TxNow,\n TxColumnExpr,\n TxInsertValue,\n TxSetValue,\n TxInsertShape,\n TxSetShape,\n TxWhere,\n TxSelectOptions,\n TxPlanBody,\n TxPlanResponse,\n TxPlanOpResult,\n TxPlanRejection,\n TxWireOp,\n TxWireRef,\n TxWireExpr,\n TxWireGuard,\n TxWireValue,\n} from \"./db/tx-plan.js\";\n// Kiracıya kapsanmış CRUD'un TEK yazımı. `defineRepository` bir TABAN SINIFI\n// üretir (`class TodoRepository extends defineRepository(Database.public.todos,\n// { tenant: \"household_id\" }) {}`); `RepositoryOf` onun yüzeyi, `RepositoryTable`\n// ise repo'nun tablodan istediği alt küme — kendi tablo sarmalayıcısını yazan\n// bir proje ona göre yazar. Satır anahtarı varsayılan olarak `id`, ama SABİT\n// DEĞİL: `defineTable` bir `id` kolonu şart koşmadığı için `{ key: \"slug\" }`\n// ile adlandırılabiliyor (`DefaultRowKey`/`RowKey` o seçimin tipleri).\nexport { defineRepository } from \"./db/repository.js\";\nexport type {\n DefaultRowKey,\n MissingRowKey,\n RepositoryOf,\n RepositoryTable,\n RowKey,\n} from \"./db/repository.js\";\nexport type { Tables, TableTypes } from \"./db/env.js\";\nexport { makeEnvDts } from \"./db/env-gen.js\";\n// `config/` IS GONE, and so is the purchases family. Both were author-facing\n// surfaces with nothing behind them.\n//\n// The five config declarations nobody applied — storage, flags, notifications,\n// egress, auth — stopped being applied when the server-side declaration applier\n// was retired (v2 S-005, \"settings have one door, and a second one is how the\n// two disagree\"); `contract_lock_test.go` keeps it retired, and its own comment\n// records that the applier produced that silent failure FIVE times. The two that\n// still worked travelled by CLI courier: `config/secrets.ts` gated the push and\n// `config/test-users.ts` was PUT at the stack. Both jobs are now done where the\n// setting lives — `palbase secret set`, `palbase test-user templates set` — and\n// what a controller may SPELL comes back as a type instead of a declaration.\n//\n// `purchases` never had a v2 backend at all: v2 contains no palstore, which\n// `clients/index.ts` recorded on 2026-08-15 while deliberately leaving the tree\n// in place. It is taken now.\n//\n// The rule that replaced all of it: the schema files under `db/` and\n// behaviour-carrying code\n// live in the repo; everything else is CONFIGURATION and is set through the CLI\n// (later MCP) against the stack. Codegen exists so that code can be written\n// against it — a generated type is not a declaration, and it produces no file an\n// author edits.\nexport type { PalbaseSecretName, PalbaseFlagKey, PalbaseBucketName, PalbaseRoleName, Roles } from \"./stack.js\";\nexport { makeStackDts } from \"./stack-gen.js\";\nexport type { StackNames } from \"./stack-gen.js\";\n// Class-controller decorator model (replaces defineController/defineHandler/route).\n// `getRegisteredControllers` is what makes exporting a controller OPTIONAL:\n// importing the file registers it. `Controller` stays exported for authoring.\nexport { Controller, getRegisteredControllers, __resetRegisteredControllers } from \"./decorators/controller.js\";\n// The APPLICATION-level ring of the auth cascade (route → controller →\n// application → true). Declared once at module scope instead of repeating the\n// same `auth` on every @Controller — the repetition is what gets forgotten.\nexport { defineDefaultAuth, __resetDefaultAuth, assertZeroArgConstructor, resolveEffectiveAuth } from \"./decorators/controller.js\";\nexport type { ControllerOptions } from \"./decorators/controller.js\";\nexport { Get, Post, Put, Patch, Delete, Query } from \"./decorators/methods.js\";\nexport { Deny, getHookConfig, getHookManifest, Hook } from \"./decorators/hook.js\";\nexport type { HookFn, ResolvedHookClass } from \"./decorators/hook.js\";\nexport { Upload } from \"./decorators/upload.js\";\nexport type { UploadConfig } from \"./decorators/upload.js\";\n// `UploadedObject` is exported from upload.js, where BOTH the `@UploadedObject()`\n// decorator value AND the `UploadedObject` type are declared. One module → one\n// export name carries both — authors write `@UploadedObject()` (value) and\n// `: UploadedObject` (type) with a single imported name.\nexport { UploadedObject } from \"./decorators/upload.js\";\n// `@Sse` + its two parameter companions. `SseWriter` is the writer `@SseOut()`\n// injects; `SseConfig` is the route marker's type. The pipeline keys off the\n// config's PRESENCE, not the HTTP verb — see decorators/sse.ts.\nexport { Sse, SseOut, Signal } from \"./decorators/sse.js\";\nexport type { SseConfig, SseWriter } from \"./decorators/sse.js\";\n\n// `@Room` + its six lifecycle hooks. A room is the realtime surface a backend\n// can MANAGE rather than only talk on: it sees who joined, who left, and when\n// nobody is watching any more. Marked by the config's PRESENCE, like every\n// other decorator here — see decorators/room.ts.\nexport {\n Room,\n OnAuthorize,\n OnFirst,\n OnJoin,\n OnLeave,\n OnEmpty,\n OnMessage,\n} from \"./decorators/room.js\";\nexport type { RoomOptions } from \"./decorators/room.js\";\nexport {\n Body,\n QueryParams,\n Headers,\n Param,\n User,\n OptionalUser,\n Client,\n RequestId,\n TraceId,\n Req,\n} from \"./decorators/params.js\";\nexport type { RouteOptions, HttpMethodUpper, ThrowDescriptor, RouteMeta, ParamMeta, ParamKind } from \"./decorators/registry.js\";\n// recordThrows is the stager-injected carrier for inferred throw descriptors\n// (the recordReturn twin) — public so the injected IIFE in a deployed bundle\n// can call it via `require(\"@palbase/backend\").recordThrows(...)`.\nexport { recordThrows } from \"./decorators/registry.js\";\n// getRoutes reads a controller's RouteMeta[] straight from the registry — the\n// isolate runtime enumerates routes with it instead of the worker.js raw-Symbol\n// fallback (the ROUTES symbol stays, both fallbacks keep reading it).\nexport { getRoutes } from \"./decorators/registry.js\";\nexport { defineMiddleware } from \"./middleware.js\";\nexport type { MiddlewareContext, MiddlewareHandler } from \"./middleware.js\";\n// The authenticated-user TYPE is exported as `UserT` (not `User`) because the\n// value name `User` is the @User() parameter decorator (exported above). A\n// controller annotates `@User() user: UserT` — decorator for the value\n// position, `UserT` for the type. (NestJS-style: same name as the decorator\n// would collide in the value+type namespaces.)\nexport type { User as UserT, VerifiedDevice, HttpMethod, AuthConfig } from \"./types.js\";\nexport {\n HttpError,\n PalError,\n BadRequest,\n Unauthorized,\n Forbidden,\n NotFound,\n Conflict,\n TooManyRequests,\n // 23505, typed. The engine throws it; a caller branches on `.constraint`\n // instead of matching the driver's message string.\n UniqueViolation,\n SerializationFailure,\n DeadlockDetected,\n isRetryable,\n} from \"./errors.js\";\n// Typed project errors — defineError returns an HttpError subclass and\n// self-registers {code, status, dataSchema} in the project-global error\n// registry (the OpenAPI spec twins join `RouteMeta.throws` against it).\nexport { defineError, getErrorRegistry } from \"./error-registry.js\";\nexport type { RegisteredError, DefinedError, DefinedErrorWithData } from \"./error-registry.js\";\nexport type { JobMeta } from \"./job.js\";\nexport type { WebhookProvider, WebhookMeta, WebhookRequest } from \"./webhook.js\";\n// Webhooks and jobs are classes: `@Webhook`/`@On` for inbound webhooks,\n// `@Job` for cron. Both take their name from their file — see decorators/*.\nexport { getWebhookConfig, getWebhookManifest, On, Webhook } from \"./decorators/webhook.js\";\n\n// ── dependency injection ───────────────────────────────────────────────────\n//\n// `Injectable` and `Module` are the whole authoring surface: a class says it can\n// be resolved, and ONE module says who owns it, what it exports and what it may\n// reach. There is no `inject()`, no `@Inject`, no token registry — a dependency\n// is named by its constructor parameter's type and by nothing else.\nexport { Injectable } from \"./decorators/injectable.js\";\n// Which of a container's owned classes are entry points of each kind. Discovery\n// used to be a DIRECTORY (jobs/*.ts); now a module lists the class and the\n// decorator says what it is.\nexport { controllersOf, hooksOf, jobsOf, roomsOf, webhooksOf } from \"./decorators/kinds.js\";\nexport { Module } from \"./decorators/module.js\";\nexport type { ModuleDef, Token } from \"./decorators/module.js\";\n// Internal seam, exported for the same reason __runStartHooks is: the engine and\n// the bundle carry SEPARATE copies of this package, and claiming has to be done\n// by the copy that builds the container.\nexport { __claimModules } from \"./decorators/module.js\";\n// The `@Injectable()` half of the same seam. It is what FR-010 counts, and a\n// test fixture that builds two containers in one process has to drain it\n// between them the way it drains modules — a leftover fails the NEXT build with\n// a true refusal about the wrong test.\nexport { __claimInjectables } from \"./decorators/injectable.js\";\nexport { DiError } from \"./container.js\";\n// THE ORPHAN CHECK, and it was a READER WITH NO WRITER.\n//\n// `build-check.js` has always guarded its call with\n// `typeof sdk.assertNoOrphanEntryPoints === 'function'` — and this line was\n// missing, so the guard was false every time and the check never ran on the\n// build path. Measured 2026-09-02 through the real CLI: a `@Controller` that no\n// module lists entered the route table and `palbase build` printed\n// \"build OK — 6 route(s)\", exit 0. The runtime refuses it at boot, which is\n// exactly the failure `palbase build` exists to catch first.\n//\n// `createApp` calls it too; it is exported because the LOCAL build has to reach\n// the same decision with the same code, which is the whole premise of that file.\nexport { assertNoOrphanEntryPoints } from \"./container.js\";\n// `createApp` calls this and hands the result back as `App.container`; a project\n// almost never needs it directly. It is exported because the runtime is the\n// framework's OTHER HALF and builds containers of its own, and because a\n// hand-built one is validated exactly like the engine's — same claim, same\n// refusals, no second way to get an unvalidated graph.\nexport { buildContainer } from \"./container.js\";\nexport type { Container, DiKind, ModulePressure } from \"./container.js\";\nexport type { ResolvedWebhook, SignatureSpec, WebhookEventHandler, WebhookOptions } from \"./decorators/webhook.js\";\nexport { getJobConfig, getJobManifest, Job } from \"./decorators/job.js\";\nexport type { JobOptions, ResolvedJob } from \"./decorators/job.js\";\n// `Resource` is GONE, not deprecated. Its boot registry was never wired: nothing\n// in the runtime ever called `__runResourceBoot` (measured 2026-08-29 —\n// `grep -rn \"ResourceBoot\"` across v2/runtime and palsvc returned nothing), so\n// `init(env)` never ran, the declared secrets never arrived, and a project that\n// wrote one got an object whose fields sat at their initializers with no error\n// anywhere. That is the same silence the `auth`/`storage`/`documents` hook\n// helpers were removed for, one surface down.\n//\n// Nothing replaces it, because the thing it was ceremony around is already the\n// stack's: the VAULT holds what a backend may read, the runtime lists those names\n// off it and mirrors them into `process.env` at boot, and `Secrets.get()` reads a\n// value with the rotation the deploy generation already carries. A field frozen\n// once inside `init(env)` could not have that. `static secrets` was therefore a\n// third list of names, behind the vault and behind `config/secrets.ts` — which is\n// itself down to a hint rather than a constraint (v2/runtime/src/server.ts:517).\n// `config/egress.ts` fences the calls a resource would have made and\n// `openai.embedding(...)` in the schema puts the one vendor client the platform\n// actually runs where the platform runs it. `resources/` stays exactly what the\n// bundler already treats it as — a directory of plain modules a controller\n// imports.\n// Types only. A hook is declared with @Hook/@On in hooks/*.ts.\n//\n// The `auth`/`storage`/`documents` helpers that used to live here are gone, not\n// deprecated: they returned a record nothing in the runtime or the bundler ever\n// read, so a project that called one got a handler that never ran and no error\n// anywhere. api-surface.mjs asks for a deprecation bridge because a major locks\n// every tenant's deploy — a real cost, and the reason this shipped as a bridge\n// in 20.0.0. There are no production tenants to lock yet (owner's call,\n// 2026-08-22), so the bridge is spending a release to soften a break nobody can\n// feel, and the honest surface is the one with no dead names in it.\nexport type {\n HookMeta,\n AuthHookEvent,\n DocumentHookEvent,\n FileUploadedEvent,\n FileDeletedEvent,\n} from \"./hooks.js\";\nexport { z } from \"zod\";\n\nexport { DeclarationRefused, isDeclarationRefused, DECLARATION_REFUSAL } from \"./refusals.js\";\nexport type { UniqueWhere } from \"./db/unique.js\";\nexport type { DatabaseBudget, DatabaseDiagnostics, DatabaseDiagnosticsOptions, DatabaseQueryEvent } from \"./db/diagnostics.js\";\n"],"mappings":"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","names":["PalbaseModuleError","Error","code","status","details","message","name","makeHttpClient","cfg","request","method","path","options","headers","apiKey","init","body","undefined","Uint8Array","FormData","Blob","JSON","stringify","signal","doFetch","fetchImpl","globalThis","fetch","response","baseUrl","err","data","error","contentType","get","parsed","includes","json","catch","startsWith","arrayBuffer","text","ok","error_description","statusText","RoleNotDefined","Error","role","message","name","refuse","error","code","PalbaseModuleError","rolesPath","userId","base","encodeURIComponent","undefined","buildAuthClient","http","assignRole","request","revokeRole","rolesOf","data","roles","SEGMENT_RE","validateSegment","segment","label","test","Error","source","buildDocumentRef","http","path","set","data","request","body","get","response","error","status","raw","exists","undefined","Boolean","id","segments","split","length","ref","update","delete","collection","name","buildCollectionRef","state","where","orderBy","snapshot","doc","querySnapshot","docs","empty","size","docChanges","map","type","add","resp","field","op","value","direction","limit","n","narrowed","queryBody","documents","w","o","MAX_BATCH","buildDocumentsClient","String","filter","s","forEach","i","join","batch","operations","PalbaseModuleError","FLAG_NAME_RE","assertFlagName","flagName","test","Error","source","flagEnabled","value","flagVariant","name","isContextObject","v","Array","isArray","buildFlagsClient","http","cfg","resolveUserId","context","userId","getCurrentUserId","undefined","mergedPath","uid","encodeURIComponent","fetchMerged","request","service","setOverrideForUser","key","body","setOverridesForUser","values","clearOverrideForUser","clearAllOverridesForUser","batchSetOverrides","operations","ops","map","op","raw","user_id","isEnabled","res","error","data","status","getVariant","get","defaultOrContext","maybeContext","defaultValue","hasDefault","resp","getAll","Object","keys","flag","enabled","variant","setOverride","message","asService","mapEnvelope","res","map","error","data","undefined","status","toEmailTemplate","wire","view","id","slug","locale","subject","htmlBody","html_body","variables","isDefault","is_default","createdAt","created_at","updatedAt","updated_at","text_body","textBody","toSmsTemplate","body","buildNotificationsClient","http","push","send","params","request","email","templateSlug","html","text","rest","template_slug","sms","whatsapp","userId","user_id","events","options","query","limit","encodeURIComponent","String","verifications","start","check","inbox","list","opts","URLSearchParams","cursor","set","is_read","category","include_archived","toString","unreadCount","markRead","markAllRead","archive","preferences","get","update","emailTemplates","resp","rows","create","input","delete","smsTemplates","templates","registerDevice","unregisterDevice","deviceId","createHmac","mintToken","secret","now","Math","floor","Date","header","Buffer","from","JSON","stringify","alg","typ","toString","payload","iss","role","iat","exp","sig","createHmac","update","digest","buildRealtimeClient","cfg","url","baseUrl","stateUrl","writeState","topic","key","value","del","length","data","error","PalbaseModuleError","apiJwtSecret","token","err","Error","message","op","doFetch","fetchImpl","globalThis","fetch","response","method","headers","Authorization","body","ops","status","undefined","detail","text","catch","state","set","clear","broadcast","channel","event","messages","private","slice","BUCKET_NAME_RE","STORAGE_PATH_RE","STORAGE_TRAVERSAL_RE","validateStoragePath","p","test","Error","source","toFileObject","bucket","row","name","path","size","contentType","checksum","width","height","thumbhash","variants","mapResponse","res","map","error","data","undefined","status","buildBucketClient","http","bucketName","publicOrigin","objectPath","upload","file","options","headers","upsert","body","ArrayBuffer","Uint8Array","request","r","download","Accept","getPublicUrl","variant","encodeURIComponent","createSignedUrl","expiresIn","list","prefix","params","URLSearchParams","set","limit","String","query","toString","objects","remove","paths","removed","push","move","from","to","copy","buildStorageClient","replace","buildModuleClients","cfg","baseUrl","replace","apiKey","serviceRoleKey","http","makeHttpClient","fetchImpl","Auth","buildAuthClient","Documents","buildDocumentsClient","Storage","buildStorageClient","publicOrigin","Notifications","buildNotificationsClient","Flags","buildFlagsClient","getCurrentUserId","Realtime","buildRealtimeClient","apiJwtSecret","realtimeApiJwtSecret","CHANNELS","Symbol","for","ownerOnly","kind","publicChannel","opts","publish","state","paramCount","pattern","split","filter","s","startsWith","endsWith","length","defineChannels","map","entries","entry","Object","Error","push","c","authorize","handler","def","carrier","globalThis","existing","sameDeclaration","e","join","wireRow","JSON","stringify","read","write","toString","a","b","every","x","i","defineRepository","table","opts","tenantColumn","tenant","rowKey","key","scope","scopeRow","id","scopedPayload","values","Repository","list","findMany","where","find","rows","limit","insert","update","patch","row","updateScoped","NotFound","String","updateMany","set","delete","deleteMany","makeMethodDecorator","method","subpath","options","Error","slice","toLowerCase","target","propertyKey","descriptor","verb","undefined","String","recordRoute","Get","Post","Put","Patch","Delete","Query","SHAPE","assertSurfaceName","name","decorator","kind","trim","Error","test","WEBHOOK_META","Symbol","for","WEBHOOK_EVENTS","carrierOf","ctor","Webhook","options","carrier","Object","defineProperty","value","enumerable","configurable","writable","On","event","target","fnName","existing","entries","push","String","getWebhookManifest","meta","validateWebhook","name","provider","secretEnv","secret","env","events","map","e","Error","assertSurfaceName","signature","sig","header","algo","encoding","signs","includes","timestampHeader","length","getWebhookConfig","container","instance","get","create","entry","prototype","hasOwnProperty","call","metaArg","Deny","Error","reason","name","HOOK_BLOCKING","Symbol","for","Hook","event","target","fnName","carrier","existing","entries","push","String","Object","defineProperty","value","enumerable","configurable","writable","bind","instance","kind","out","create","entry","prototype","hasOwnProperty","call","fn","meta","getHookConfig","ctor","container","blockingEntries","listenerEntries","WEBHOOK_EVENTS","length","get","blocking","listeners","getHookManifest","map","e","Upload","subpath","config","auth","rateLimit","uploadConfig","validateUploadConfigShape","options","undefined","target","propertyKey","recordRoute","String","UploadedObject","parameterIndex","recordParam","index","kind","c","Error","bucket","length","pathTemplate","Sse","subpath","config","auth","rateLimit","sseConfig","options","undefined","target","propertyKey","recordRoute","String","SseOut","parameterIndex","recordParam","index","kind","Signal","DEFAULT_GRACE_MS","assertPattern","pattern","includes","Error","replace","segments","split","some","s","seen","Set","startsWith","endsWith","name","slice","has","add","Room","options","ctor","recordRoom","events","graceMs","hookDecorator","hook","target","propertyKey","recordRoomHook","String","OnAuthorize","OnFirst","OnJoin","OnLeave","OnEmpty","OnMessage","schema","recordRoomMessage","makeParamDecorator","kind","extra","target","propertyKey","parameterIndex","recordParam","String","index","schema","undefined","name","Body","QueryParams","Headers","Param","User","OptionalUser","Client","RequestId","TraceId","Req","defineMiddleware","_fn","Error","validateCronExpression","expression","trimmed","trim","parts","split","length","fieldNames","fieldRanges","i","field","name","min","max","error","validateCronField","listParts","part","stepParts","base","step","undefined","stepNum","Number","isInteger","includes","rangeParts","rangeStart","rangeEnd","num","DEFAULT_TIMEOUT_SECONDS","MAX_TIMEOUT_SECONDS","DEFAULT_RETRY","MAX_RETRY","JOB_META","Symbol","for","Job","options","ctor","carrier","Object","defineProperty","value","enumerable","configurable","writable","getJobManifest","meta","Error","name","assertSurfaceName","schedule","trim","cronError","validateCronExpression","timeout","Number","isInteger","retry","getJobConfig","container","instance","get","run","bind","handler","z"]}