@palbase/backend 25.0.1 → 25.0.3

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 +7 -7
  2. package/dist/bin/palbase-backend.cjs.map +1 -1
  3. package/dist/bin/palbase-backend.js +1 -1
  4. package/dist/{chunk-HBOJLP2Z.js → chunk-7JSEN7UR.js} +2 -1
  5. package/dist/chunk-7JSEN7UR.js.map +1 -0
  6. package/dist/{chunk-34I4GB7D.js → chunk-WH2EV2LT.js} +8 -8
  7. package/dist/{chunk-34I4GB7D.js.map → chunk-WH2EV2LT.js.map} +1 -1
  8. package/dist/db/index.cjs.map +1 -1
  9. package/dist/db/index.d.cts +2 -2
  10. package/dist/db/index.d.ts +2 -2
  11. package/dist/db/index.js +1 -1
  12. package/dist/{endpoint-DMwJjEHQ.d.ts → endpoint-CTEHhb7A.d.ts} +19 -8
  13. package/dist/{endpoint-BSGw1pTu.d.cts → endpoint-DYHMo6cC.d.cts} +19 -8
  14. package/dist/engine/index.cjs +7 -7
  15. package/dist/engine/index.cjs.map +1 -1
  16. package/dist/engine/index.d.cts +4 -4
  17. package/dist/engine/index.d.ts +4 -4
  18. package/dist/engine/index.js +1 -1
  19. package/dist/{index-B8v6hVyU.d.ts → index-CUomTA3e.d.ts} +3 -3
  20. package/dist/{index-B4CcpqLb.d.ts → index-CW21M9Z3.d.ts} +1 -1
  21. package/dist/{index-VsjBQ4Kw.d.cts → index-ClpDeSos.d.cts} +3 -3
  22. package/dist/{index-DmVyY6N7.d.cts → index-CmBK76nx.d.cts} +1 -1
  23. package/dist/index.cjs +5 -2
  24. package/dist/index.cjs.map +1 -1
  25. package/dist/index.d.cts +9 -8
  26. package/dist/index.d.ts +9 -8
  27. package/dist/index.js +5 -3
  28. package/dist/index.js.map +1 -1
  29. package/dist/openapi/index.d.cts +2 -2
  30. package/dist/openapi/index.d.ts +2 -2
  31. package/dist/{registry-CgJvDYUW.d.cts → registry-CC0WBQq6.d.cts} +1 -1
  32. package/dist/{registry-B8pld3fj.d.ts → registry-dZZ5JKYg.d.ts} +1 -1
  33. package/dist/test/index.d.cts +1 -1
  34. package/dist/test/index.d.ts +1 -1
  35. package/docs/README.md +29 -28
  36. package/docs/database.md +2 -2
  37. package/docs/endpoints.md +6 -5
  38. package/docs/getting-started.md +1 -1
  39. package/docs/llms-full.txt +58 -53
  40. package/docs/migrations.md +16 -14
  41. package/docs/schema.md +2 -2
  42. package/docs/services.md +2 -1
  43. package/package.json +1 -1
  44. package/dist/chunk-HBOJLP2Z.js.map +0 -1
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/clients/http.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/env-gen.ts","../src/stack-gen.ts","../src/decorators/methods.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 * 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 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 // 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 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 * - `auth`, `functions`, `analytics`, `links` — the SDK exports no singleton\n * for any of them (`runtime.ts` exports ten, and these four are not among\n * them), so no handler could reach them. They were constructed on every\n * boot and thrown away.\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 { 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 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","/**\n * env-gen.ts — generate the `palbase-env.d.ts` text from a `defineSchema()`\n * result.\n *\n * The CLI (`palbase build`) and the deploy pipeline call\n * {@link makeEnvDts} with the project's schema and write the returned string to\n * `palbase-env.d.ts` at the project root. That file AUGMENTS the\n * `@palbase/backend/env` `Tables` interface (controlled global augmentation,\n * C5) so `Database.tables.<name>` is typed with no import and no generic.\n *\n * The output is FLAT: each table gets a `{ row: {...}; insert: {...} }` entry\n * with plain TypeScript object types. The phantom `ColumnBuilder<...>` type\n * NEVER appears in the generated `.d.ts` — that type only lives at authoring\n * time inside the project's `db/*.ts` schema files.\n */\n\nimport type { ColumnDef } from \"./columns.js\";\n// FR-058: the \"public is bare, everything else is qualified\" rule lives in ONE\n// helper. This file used to carry two more copies of it — a module-level\n// `qualify` and a second, identical local one inside `makeEnvDts` — and the\n// duplication was not cosmetic: re-deriving the key here instead of reading the\n// one `resolveReferences` already wrote is exactly how a public foreign key got\n// relabelled onto another schema's table. Two names for one truth are two\n// interpreters of it.\nimport { qualifiedTableKey } from \"./schema-json.js\";\nimport type { SchemaDef, TableDef } from \"./schema.js\";\n\n/** The TypeScript value type for a column, ignoring nullability (added by the\n * caller). Mirrors the `ColValue` mapped type in columns.ts exactly. */\nfunction baseTsType(def: ColumnDef): string {\n switch (def.type) {\n case \"uuid\":\n case \"text\":\n case \"timestamp\":\n return \"string\";\n case \"integer\":\n return \"number\";\n // Both are exact-precision in Postgres and lossy as a JSON number, so the\n // database proxy serializes them as strings — measured: 9007199254740993\n // used to arrive as ...992 and 41.00821234567890123 as 41.0082123456789.\n // numeric had no case at all and fell through to `unknown`, which typed\n // every numeric column out of existence.\n case \"bigint\":\n case \"numeric\":\n return \"string\";\n case \"boolean\":\n return \"boolean\";\n case \"jsonb\":\n return \"unknown\";\n // FR-008: the authoring type of a pgvector column. The default `unknown`\n // branch below STAYS — an unknown wire type is refused on the Go side\n // (FR-005), never papered over here.\n case \"vector\":\n return \"number[]\";\n case \"enum\": {\n const values = def.enumValues ?? [];\n if (values.length === 0) return \"string\";\n return values.map((v) => JSON.stringify(v)).join(\" | \");\n }\n default:\n return \"unknown\";\n }\n}\n\n/** The full row type for a column: base type, `| null` when nullable. */\nfunction rowType(def: ColumnDef): string {\n const base = baseTsType(def);\n return def.nullable ? `${base} | null` : base;\n}\n\n/** True when a column may be omitted on INSERT — nullable OR has any default.\n * Mirrors `ColIsOptionalOnInsert` in columns.ts. */\nfunction optionalOnInsert(def: ColumnDef): boolean {\n return (\n def.nullable === true ||\n def.defaultRandom === true ||\n def.defaultNow === true ||\n def.defaultValue !== undefined\n );\n}\n\n\n\nexport type Relation = {\n name: string;\n to: string;\n kind: \"one\" | \"many\";\n /**\n * The foreign-key COLUMN the relation runs through.\n *\n * Without it \"there is a relation\" is half the fact, and everything that\n * consumes the map — the query builder, the seed engine, the cross-boundary\n * lock — has to re-derive the column: a second interpreter of the same graph.\n */\n via: string;\n};\n\n/** `list_id` → `list`; anything else keeps its column name (FR-019). */\nfunction forwardName(column: string): string {\n return column.endsWith(\"_id\") ? column.slice(0, -3) : column;\n}\n\n/**\n * Where a relation name came from, so a refusal can say it out loud.\n *\n * A collision on a parent table can be between two REVERSE edges, or between a\n * reverse edge and the parent's own FORWARD one — `lists.todos_id` names a\n * forward `todos`, and `todos.list_id` reverses onto `lists` as `todos` too.\n * The old message called both sides \"reverse relations\", which sent the reader\n * looking for a second reverse edge that was never there.\n */\ntype NameOrigin = {\n /** The table the foreign-key COLUMN is declared on. */\n table: string;\n column: string;\n direction: \"forward\" | \"reverse\";\n def: ColumnDef;\n};\n\nfunction describeOrigin(o: NameOrigin): string {\n return o.direction === \"forward\"\n ? `the foreign key \"${o.table}.${o.column}\"`\n : `the reverse of \"${o.table}.${o.column}\"`;\n}\n\n/**\n * The call that renames THIS relation — named per verb, because the verbs do\n * not take the same options.\n *\n * NFR-002 asks every refusal to name a remedy the reader can apply. The old\n * message said `references(() => …, { as: \"…\" })` for every case, and\n * `ownedByUser()` takes no arguments at all while `userRef` /\n * `installationRef` take `{ onDelete, as }` — so following it literally was\n * impossible for exactly the columns that most often collide.\n *\n * A reverse edge only ever exists for a target that is a DECLARED table, and\n * only `references()` can point at one: `auth.*` is not declared (no reverse\n * edge) and a self-reference has no separate parent (skipped). So the reverse\n * remedy has one form and it is always the right one.\n */\nfunction renameCall(o: NameOrigin): string {\n if (o.direction === \"reverse\") return `references(() => …, { reverseAs: \"…\" })`;\n if (o.def.owns === true) {\n return `ownedByUser() takes no { as } — if \"${o.column}\" only POINTS at a user, declare it userRef({ onDelete: … }) instead`;\n }\n const target = o.def.references?.table;\n if (target === \"auth.users\") return `userRef({ onDelete: …, as: \"…\" })`;\n if (target === \"auth.installations\") return `installationRef({ onDelete: …, as: \"…\" })`;\n if (o.def.selfRefColumn !== undefined) return `selfReferences(\"…\", { as: \"…\" })`;\n return `references(() => …, { as: \"…\" })`;\n}\n\n/**\n * Derive the relation graph from the declared foreign keys.\n *\n * Until now a SECOND foreign key onto the same parent was silently dropped: only\n * the first column in declaration order was recorded, and the other one quietly\n * became an ordinary writable column. Which relation you got was decided by the\n * order somebody happened to type the columns in. That silence is what this\n * function exists to end — ambiguity is rejected and named, never resolved by\n * declaration order.\n *\n * THE HAZARD IS ONE NAME WITH TWO RELATIONS (FR-022), not two foreign keys onto\n * one target. Those are not the same set, and treating them as one refused the\n * package's own documented shape: a table with `ownedByUser()` beside a\n * `userRef()` has two foreign keys onto `auth.users` and no ambiguity whatever —\n * the names are `owner` and the pointing column's own, and `auth.users` is not a\n * declared table, so neither takes a reverse edge to collide over. The gate\n * counted the owner toward the total while exempting it from the naming\n * requirement, so `docs/schema.md`'s example threw, naming a remedy no verb in\n * it accepts.\n *\n * The two directions are named SEPARATELY. `as` sets the forward name (FR-019),\n * `reverseAs` sets the reverse one (FR-020, whose default is the child table's\n * name). One option cannot set both: two children that each name their forward\n * edge `author` collided on the parent as `author`, and the refusal asked for\n * the `{ as }` they had both already written — a refusal with no exit.\n */\nexport function buildRelations(schemas: readonly SchemaDef[]): Map<string, Relation[]> {\n const out = new Map<string, Relation[]>();\n /** Per table key: relation name → where that name came from. */\n const taken = new Map<string, Map<string, NameOrigin>>();\n for (const schema of schemas) {\n for (const t of Object.values(schema.tables)) {\n const key = qualifiedTableKey(schema.name, t.name);\n out.set(key, []);\n taken.set(key, new Map());\n }\n }\n\n /** Record one edge on `tableKey`, or refuse the name it would take twice. */\n const claim = (tableKey: string, name: string, origin: NameOrigin, edge: Relation): void => {\n const names = taken.get(tableKey);\n if (names === undefined) return;\n const held = names.get(name);\n if (held !== undefined) {\n // FR-015 asks this one to LIST the conflicting columns; it used to name\n // neither, so the reader had to find them.\n if (held.def.owns === true && origin.def.owns === true) {\n throw new Error(\n `table \"${tableKey}\" declares TWO owner columns (${held.column}, ${origin.column}) — a table has at most ONE ownedByUser(). If the other column only POINTS at a user, declare it userRef({ onDelete: … }) instead.`,\n );\n }\n const heldFix = renameCall(held);\n const originFix = renameCall(origin);\n const remedy =\n heldFix === originFix\n ? `rename one of them: ${heldFix}`\n : `rename one of them — \"${held.table}.${held.column}\": ${heldFix}; \"${origin.table}.${origin.column}\": ${originFix}`;\n throw new Error(\n `table \"${tableKey}\": ${describeOrigin(held)} and ${describeOrigin(origin)} both resolve to the relation name \"${name}\" — ${remedy}.`,\n );\n }\n names.set(name, origin);\n out.get(tableKey)?.push(edge);\n };\n\n for (const schema of schemas) {\n for (const table of Object.values(schema.tables)) {\n const childKey = qualifiedTableKey(schema.name, table.name);\n if (!out.has(childKey)) continue;\n\n for (const [col, builder] of Object.entries(table.columns)) {\n const def = builder._def;\n if (def.references === undefined) continue;\n // `references.table` IS the canonical key — `resolveReferences` wrote it\n // with `qualifiedTableKey`, so public is bare and everything else is\n // qualified, `auth.users` included.\n //\n // It used to be re-derived here from a bare-name → key map, which gave a\n // DIFFERENT answer in exactly one case: two schemas declaring the same\n // table name. The map kept whichever was declared LAST, so a public FK\n // was relabelled onto another schema's table and the real parent got no\n // reverse edge — silently, while RefJSON (and therefore the DDL) went on\n // pointing at the right one. The generated type and the database\n // disagreed, and nothing said so.\n const targetKey = def.references.table;\n\n const name = def.owns === true ? \"owner\" : (def.refAs ?? forwardName(col));\n claim(\n childKey,\n name,\n { table: table.name, column: col, direction: \"forward\", def },\n { name, to: targetKey, kind: \"one\", via: col },\n );\n\n // Reverse edge, unless the FK points outside the declared schemas (auth.users)\n // or back at the declaring table (a self-reference has no separate parent).\n if (!out.has(targetKey) || targetKey === childKey) continue;\n // FR-020: the reverse name is the CHILD TABLE's, not the forward name.\n // `as` used to set this too, which both broke FR-020 for a single named\n // FK (`users.author` where `users.posts` was required) and left two\n // children that chose the same forward name with no way to be declared.\n const reverse = def.reverseAs ?? table.name;\n claim(\n targetKey,\n reverse,\n { table: table.name, column: col, direction: \"reverse\", def },\n { name: reverse, to: childKey, kind: \"many\", via: col },\n );\n }\n }\n }\n return out;\n}\n\n\n\n\n/** Emit the `row` / `insert` / `relations` blocks for one table at the given\n * base indentation. */\nfunction tableBlock(table: TableDef, relations: Relation[], indent: string): string {\n const cols = Object.entries(table.columns);\n const rowLines = cols.map(([col, builder]) => {\n return `${indent} ${col}: ${rowType(builder._def)};`;\n });\n const insertLines = cols.map(([col, builder]) => {\n const def = builder._def;\n const opt = optionalOnInsert(def) ? \"?\" : \"\";\n return `${indent} ${col}${opt}: ${rowType(def)};`;\n });\n const relEntries = relations\n .map(\n (r) =>\n `${r.name}: { to: ${JSON.stringify(r.to)}; kind: ${JSON.stringify(r.kind)}; via: ${JSON.stringify(r.via)} }`,\n )\n .join(\"; \");\n return [\n `${indent}${table.name}: {`,\n `${indent} row: {`,\n ...rowLines,\n `${indent} };`,\n `${indent} insert: {`,\n ...insertLines,\n `${indent} };`,\n `${indent} relations: {${relEntries === \"\" ? \"\" : ` ${relEntries} `}};`,\n // searchable: vector kolonu YA DA search beyanı → EnvTypedTable'da search()\n // üyesini açan yapısal bayrak (FR-013). Yokken satır hiç üretilmez ki\n // mevcut şemaların d.ts'i bayt-aynı kalsın.\n ...(cols.some(([, b]) => b._def.type === \"vector\") || table.search !== undefined\n ? [`${indent} searchable: true;`]\n : []),\n `${indent}};`,\n ].join(\"\\n\");\n}\n\n/**\n * Generate the full `palbase-env.d.ts` text for the project's schemas.\n *\n * The emitted file ends in `export {};` — same as `makeStackDts`. Without it the\n * `.d.ts` is a global script, and `declare module \"…\"` there DECLARES an ambient\n * module (shadowing the real one, so every export of `@palbase/backend/env`\n * silently becomes invalid) instead of AUGMENTING it. Measured on a minimal tsc\n * repro: with the line, exit 0; without it, `TS2305: Module '\"…\"' has no\n * exported member`. The line was dropped once in a rewrite and nothing caught\n * it, so `env-gen.test.ts` now gates it directly.\n *\n * @example\n * import { makeEnvDts } from \"@palbase/backend\";\n * import publicSchema from \"./db/public.js\";\n * import billing from \"./db/billing.js\";\n * writeFileSync(\"palbase-env.d.ts\", makeEnvDts([publicSchema, billing]));\n */\nexport function makeEnvDts(schemas: readonly SchemaDef[]): string {\n // No pruning: `relations` is a flat literal map, so it cannot expand into an\n // infinite type the way the old recursive `children` could. Dropping a back-edge\n // here would delete a REAL relation and make the type lie about the schema.\n const relations = buildRelations(schemas);\n\n const publicSchema = schemas.find((s) => s.name === \"public\");\n const others = schemas.filter((s) => s.name !== \"public\");\n\n const publicBlocks = Object.keys(publicSchema?.tables ?? {}).map((name) =>\n tableBlock(publicSchema!.tables[name]!, relations.get(name) ?? [], \" \"),\n );\n const body = publicBlocks.length > 0 ? `\\n${publicBlocks.join(\"\\n\")}\\n ` : \"\";\n\n const schemaBlocks = others.map((schema) => {\n const inner = Object.keys(schema.tables).map((name) =>\n tableBlock(schema.tables[name]!, relations.get(qualifiedTableKey(schema.name, name)) ?? [], \" \"),\n );\n return ` ${schema.name}: {\\n${inner.join(\"\\n\")}\\n };`;\n });\n const schemasBody = schemaBlocks.length > 0 ? `\\n${schemaBlocks.join(\"\\n\")}\\n ` : \"\";\n\n return `// AUTO-GENERATED by @palbase/backend — DO NOT EDIT.\n// Regenerated from db/*.ts by \\`palbase build\\` and by every deploy.\n// Augments the @palbase/backend/env \\`Tables\\` interface so \\`Database.tables.*\\`\n// is typed with no import and no generic. Schemas other than \\`public\\` land\n// under \\`Schemas\\`, reached with \\`Database.schema(\"<name>\").tables.*\\`.\n\ndeclare module \"@palbase/backend/env\" {\n interface Tables {${body}}\n interface Schemas {${schemasBody}}\n}\n\nexport {};\n`;\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. */\ntype MethodDecorator = (\n target: object,\n propertyKey: string | symbol,\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) {\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","import { assertZeroArgConstructor } from \"./controller.js\";\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\";\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 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. */\nexport function getWebhookConfig(ctor: object): ResolvedWebhook {\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 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\n // The `new ()` in the cast below is a CLAIM — that the class is constructible\n // with no arguments — and this check is what makes it true. Without it the\n // cast quietly held for `constructor(dep: Repo)` too: the call compiled, it\n // deployed, and the field arrived as `undefined` at the first delivery. Same refusal\n // as the controller's (engine/router.ts, FR-010).\n assertZeroArgConstructor(ctor, \"webhook class\");\n\n const instance = new (ctor as new () => 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","import { assertZeroArgConstructor } from \"./controller.js\";\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\";\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): 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 // The `new ()` in the cast below is a CLAIM — that the class is constructible\n // with no arguments — and this check is what makes it true. Without it the\n // cast quietly held for `constructor(dep: Repo)` too: the call compiled, it\n // deployed, and the field arrived as `undefined` at the first event. Same refusal\n // as the controller's (engine/router.ts, FR-010).\n assertZeroArgConstructor(ctor, \"hook class\");\n\n const instance = new (ctor as new () => Record<string, HookFn>)();\n return {\n blocking: bind(instance, blockingEntries, \"@Hook\"),\n listeners: bind(instance, listenerEntries, \"@On\"),\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 * Define a middleware function for use in the middleware/ directory or\n * as endpoint-specific middleware.\n *\n * Middleware runs before the handler. Call `next()` to pass control\n * to the next middleware or handler. If `next()` is not called, the\n * handler will not execute.\n *\n * Errors thrown in middleware are caught by the pipeline and returned\n * as error responses.\n */\nexport function defineMiddleware(fn: MiddlewareHandler): MiddlewareHandler {\n return fn;\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","import { assertZeroArgConstructor } from \"./controller.js\";\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\";\n\nexport interface JobOptions {\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 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\nexport function getJobConfig(ctor: object): ResolvedJob {\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 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 // The `new ()` in the cast below is a CLAIM — that the class is constructible\n // with no arguments — and this check is what makes it true. Without it the\n // cast quietly held for `constructor(dep: Repo)` too: the call compiled, it\n // deployed, and the field arrived as `undefined` at the first scheduled run. Same refusal\n // as the controller's (engine/router.ts, FR-010).\n assertZeroArgConstructor(ctor, \"job class\");\n\n const instance = new (ctor as new () => { 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 { schedule: meta.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 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\";\nexport type { ModuleTransport, RequestOptions, TransportConfig } from \"./clients/http.js\";\n\nexport type {\n PalbaseAuthClient,\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 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 PalbaseInboxSendParams,\n PalbaseInboxSendResponse,\n PalbaseInboxMessage,\n PalbaseInboxListOptions,\n PalbaseInboxListResult,\n PalbasePreferences,\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 } from \"./db/schema.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 } 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 } from \"./db/schema.js\";\nexport { policy, PolicyBuilder } from \"./db/policy.js\";\nexport type { PolicyDef, PolicyCommand, PolicyMode } 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 } from \"./db/typed-db.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} 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 { 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\";\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, 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} 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, On, Webhook } from \"./decorators/webhook.js\";\nexport type { ResolvedWebhook, SignatureSpec, WebhookEventHandler, WebhookOptions } from \"./decorators/webhook.js\";\nexport { getJobConfig, 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"],"mappings":"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","names":["raw","raw","text","now"]}
1
+ {"version":3,"sources":["../src/clients/http.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/env-gen.ts","../src/stack-gen.ts","../src/decorators/methods.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 * 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 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 // 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 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 * - `auth`, `functions`, `analytics`, `links` — the SDK exports no singleton\n * for any of them (`runtime.ts` exports ten, and these four are not among\n * them), so no handler could reach them. They were constructed on every\n * boot and thrown away.\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 { 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 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","/**\n * env-gen.ts — generate the `palbase-env.d.ts` text from a `defineSchema()`\n * result.\n *\n * The CLI (`palbase build`) and the deploy pipeline call\n * {@link makeEnvDts} with the project's schema and write the returned string to\n * `palbase-env.d.ts` at the project root. That file AUGMENTS the\n * `@palbase/backend/env` `Tables` interface (controlled global augmentation,\n * C5) so `Database.tables.<name>` is typed with no import and no generic.\n *\n * The output is FLAT: each table gets a `{ row: {...}; insert: {...} }` entry\n * with plain TypeScript object types. The phantom `ColumnBuilder<...>` type\n * NEVER appears in the generated `.d.ts` — that type only lives at authoring\n * time inside the project's `db/*.ts` schema files.\n */\n\nimport type { ColumnDef } from \"./columns.js\";\n// FR-058: the \"public is bare, everything else is qualified\" rule lives in ONE\n// helper. This file used to carry two more copies of it — a module-level\n// `qualify` and a second, identical local one inside `makeEnvDts` — and the\n// duplication was not cosmetic: re-deriving the key here instead of reading the\n// one `resolveReferences` already wrote is exactly how a public foreign key got\n// relabelled onto another schema's table. Two names for one truth are two\n// interpreters of it.\nimport { qualifiedTableKey } from \"./schema-json.js\";\nimport type { SchemaDef, TableDef } from \"./schema.js\";\n\n/** The TypeScript value type for a column, ignoring nullability (added by the\n * caller). Mirrors the `ColValue` mapped type in columns.ts exactly. */\nfunction baseTsType(def: ColumnDef): string {\n switch (def.type) {\n case \"uuid\":\n case \"text\":\n case \"timestamp\":\n return \"string\";\n case \"integer\":\n return \"number\";\n // Both are exact-precision in Postgres and lossy as a JSON number, so the\n // database proxy serializes them as strings — measured: 9007199254740993\n // used to arrive as ...992 and 41.00821234567890123 as 41.0082123456789.\n // numeric had no case at all and fell through to `unknown`, which typed\n // every numeric column out of existence.\n case \"bigint\":\n case \"numeric\":\n return \"string\";\n case \"boolean\":\n return \"boolean\";\n case \"jsonb\":\n return \"unknown\";\n // FR-008: the authoring type of a pgvector column. The default `unknown`\n // branch below STAYS — an unknown wire type is refused on the Go side\n // (FR-005), never papered over here.\n case \"vector\":\n return \"number[]\";\n case \"enum\": {\n const values = def.enumValues ?? [];\n if (values.length === 0) return \"string\";\n return values.map((v) => JSON.stringify(v)).join(\" | \");\n }\n default:\n return \"unknown\";\n }\n}\n\n/** The full row type for a column: base type, `| null` when nullable. */\nfunction rowType(def: ColumnDef): string {\n const base = baseTsType(def);\n return def.nullable ? `${base} | null` : base;\n}\n\n/** True when a column may be omitted on INSERT — nullable OR has any default.\n * Mirrors `ColIsOptionalOnInsert` in columns.ts. */\nfunction optionalOnInsert(def: ColumnDef): boolean {\n return (\n def.nullable === true ||\n def.defaultRandom === true ||\n def.defaultNow === true ||\n def.defaultValue !== undefined\n );\n}\n\n\n\nexport type Relation = {\n name: string;\n to: string;\n kind: \"one\" | \"many\";\n /**\n * The foreign-key COLUMN the relation runs through.\n *\n * Without it \"there is a relation\" is half the fact, and everything that\n * consumes the map — the query builder, the seed engine, the cross-boundary\n * lock — has to re-derive the column: a second interpreter of the same graph.\n */\n via: string;\n};\n\n/** `list_id` → `list`; anything else keeps its column name (FR-019). */\nfunction forwardName(column: string): string {\n return column.endsWith(\"_id\") ? column.slice(0, -3) : column;\n}\n\n/**\n * Where a relation name came from, so a refusal can say it out loud.\n *\n * A collision on a parent table can be between two REVERSE edges, or between a\n * reverse edge and the parent's own FORWARD one — `lists.todos_id` names a\n * forward `todos`, and `todos.list_id` reverses onto `lists` as `todos` too.\n * The old message called both sides \"reverse relations\", which sent the reader\n * looking for a second reverse edge that was never there.\n */\ntype NameOrigin = {\n /** The table the foreign-key COLUMN is declared on. */\n table: string;\n column: string;\n direction: \"forward\" | \"reverse\";\n def: ColumnDef;\n};\n\nfunction describeOrigin(o: NameOrigin): string {\n return o.direction === \"forward\"\n ? `the foreign key \"${o.table}.${o.column}\"`\n : `the reverse of \"${o.table}.${o.column}\"`;\n}\n\n/**\n * The call that renames THIS relation — named per verb, because the verbs do\n * not take the same options.\n *\n * NFR-002 asks every refusal to name a remedy the reader can apply. The old\n * message said `references(() => …, { as: \"…\" })` for every case, and\n * `ownedByUser()` takes no arguments at all while `userRef` /\n * `installationRef` take `{ onDelete, as }` — so following it literally was\n * impossible for exactly the columns that most often collide.\n *\n * A reverse edge only ever exists for a target that is a DECLARED table, and\n * only `references()` can point at one: `auth.*` is not declared (no reverse\n * edge) and a self-reference has no separate parent (skipped). So the reverse\n * remedy has one form and it is always the right one.\n */\nfunction renameCall(o: NameOrigin): string {\n if (o.direction === \"reverse\") return `references(() => …, { reverseAs: \"…\" })`;\n if (o.def.owns === true) {\n return `ownedByUser() takes no { as } — if \"${o.column}\" only POINTS at a user, declare it userRef({ onDelete: … }) instead`;\n }\n const target = o.def.references?.table;\n if (target === \"auth.users\") return `userRef({ onDelete: …, as: \"…\" })`;\n if (target === \"auth.installations\") return `installationRef({ onDelete: …, as: \"…\" })`;\n if (o.def.selfRefColumn !== undefined) return `selfReferences(\"…\", { as: \"…\" })`;\n return `references(() => …, { as: \"…\" })`;\n}\n\n/**\n * Derive the relation graph from the declared foreign keys.\n *\n * Until now a SECOND foreign key onto the same parent was silently dropped: only\n * the first column in declaration order was recorded, and the other one quietly\n * became an ordinary writable column. Which relation you got was decided by the\n * order somebody happened to type the columns in. That silence is what this\n * function exists to end — ambiguity is rejected and named, never resolved by\n * declaration order.\n *\n * THE HAZARD IS ONE NAME WITH TWO RELATIONS (FR-022), not two foreign keys onto\n * one target. Those are not the same set, and treating them as one refused the\n * package's own documented shape: a table with `ownedByUser()` beside a\n * `userRef()` has two foreign keys onto `auth.users` and no ambiguity whatever —\n * the names are `owner` and the pointing column's own, and `auth.users` is not a\n * declared table, so neither takes a reverse edge to collide over. The gate\n * counted the owner toward the total while exempting it from the naming\n * requirement, so `docs/schema.md`'s example threw, naming a remedy no verb in\n * it accepts.\n *\n * The two directions are named SEPARATELY. `as` sets the forward name (FR-019),\n * `reverseAs` sets the reverse one (FR-020, whose default is the child table's\n * name). One option cannot set both: two children that each name their forward\n * edge `author` collided on the parent as `author`, and the refusal asked for\n * the `{ as }` they had both already written — a refusal with no exit.\n */\nexport function buildRelations(schemas: readonly SchemaDef[]): Map<string, Relation[]> {\n const out = new Map<string, Relation[]>();\n /** Per table key: relation name → where that name came from. */\n const taken = new Map<string, Map<string, NameOrigin>>();\n for (const schema of schemas) {\n for (const t of Object.values(schema.tables)) {\n const key = qualifiedTableKey(schema.name, t.name);\n out.set(key, []);\n taken.set(key, new Map());\n }\n }\n\n /** Record one edge on `tableKey`, or refuse the name it would take twice. */\n const claim = (tableKey: string, name: string, origin: NameOrigin, edge: Relation): void => {\n const names = taken.get(tableKey);\n if (names === undefined) return;\n const held = names.get(name);\n if (held !== undefined) {\n // FR-015 asks this one to LIST the conflicting columns; it used to name\n // neither, so the reader had to find them.\n if (held.def.owns === true && origin.def.owns === true) {\n throw new Error(\n `table \"${tableKey}\" declares TWO owner columns (${held.column}, ${origin.column}) — a table has at most ONE ownedByUser(). If the other column only POINTS at a user, declare it userRef({ onDelete: … }) instead.`,\n );\n }\n const heldFix = renameCall(held);\n const originFix = renameCall(origin);\n const remedy =\n heldFix === originFix\n ? `rename one of them: ${heldFix}`\n : `rename one of them — \"${held.table}.${held.column}\": ${heldFix}; \"${origin.table}.${origin.column}\": ${originFix}`;\n throw new Error(\n `table \"${tableKey}\": ${describeOrigin(held)} and ${describeOrigin(origin)} both resolve to the relation name \"${name}\" — ${remedy}.`,\n );\n }\n names.set(name, origin);\n out.get(tableKey)?.push(edge);\n };\n\n for (const schema of schemas) {\n for (const table of Object.values(schema.tables)) {\n const childKey = qualifiedTableKey(schema.name, table.name);\n if (!out.has(childKey)) continue;\n\n for (const [col, builder] of Object.entries(table.columns)) {\n const def = builder._def;\n if (def.references === undefined) continue;\n // `references.table` IS the canonical key — `resolveReferences` wrote it\n // with `qualifiedTableKey`, so public is bare and everything else is\n // qualified, `auth.users` included.\n //\n // It used to be re-derived here from a bare-name → key map, which gave a\n // DIFFERENT answer in exactly one case: two schemas declaring the same\n // table name. The map kept whichever was declared LAST, so a public FK\n // was relabelled onto another schema's table and the real parent got no\n // reverse edge — silently, while RefJSON (and therefore the DDL) went on\n // pointing at the right one. The generated type and the database\n // disagreed, and nothing said so.\n const targetKey = def.references.table;\n\n const name = def.owns === true ? \"owner\" : (def.refAs ?? forwardName(col));\n claim(\n childKey,\n name,\n { table: table.name, column: col, direction: \"forward\", def },\n { name, to: targetKey, kind: \"one\", via: col },\n );\n\n // Reverse edge, unless the FK points outside the declared schemas (auth.users)\n // or back at the declaring table (a self-reference has no separate parent).\n if (!out.has(targetKey) || targetKey === childKey) continue;\n // FR-020: the reverse name is the CHILD TABLE's, not the forward name.\n // `as` used to set this too, which both broke FR-020 for a single named\n // FK (`users.author` where `users.posts` was required) and left two\n // children that chose the same forward name with no way to be declared.\n const reverse = def.reverseAs ?? table.name;\n claim(\n targetKey,\n reverse,\n { table: table.name, column: col, direction: \"reverse\", def },\n { name: reverse, to: childKey, kind: \"many\", via: col },\n );\n }\n }\n }\n return out;\n}\n\n\n\n\n/** Emit the `row` / `insert` / `relations` blocks for one table at the given\n * base indentation. */\nfunction tableBlock(table: TableDef, relations: Relation[], indent: string): string {\n const cols = Object.entries(table.columns);\n const rowLines = cols.map(([col, builder]) => {\n return `${indent} ${col}: ${rowType(builder._def)};`;\n });\n const insertLines = cols.map(([col, builder]) => {\n const def = builder._def;\n const opt = optionalOnInsert(def) ? \"?\" : \"\";\n return `${indent} ${col}${opt}: ${rowType(def)};`;\n });\n const relEntries = relations\n .map(\n (r) =>\n `${r.name}: { to: ${JSON.stringify(r.to)}; kind: ${JSON.stringify(r.kind)}; via: ${JSON.stringify(r.via)} }`,\n )\n .join(\"; \");\n return [\n `${indent}${table.name}: {`,\n `${indent} row: {`,\n ...rowLines,\n `${indent} };`,\n `${indent} insert: {`,\n ...insertLines,\n `${indent} };`,\n `${indent} relations: {${relEntries === \"\" ? \"\" : ` ${relEntries} `}};`,\n // searchable: vector kolonu YA DA search beyanı → EnvTypedTable'da search()\n // üyesini açan yapısal bayrak (FR-013). Yokken satır hiç üretilmez ki\n // mevcut şemaların d.ts'i bayt-aynı kalsın.\n ...(cols.some(([, b]) => b._def.type === \"vector\") || table.search !== undefined\n ? [`${indent} searchable: true;`]\n : []),\n `${indent}};`,\n ].join(\"\\n\");\n}\n\n/**\n * Generate the full `palbase-env.d.ts` text for the project's schemas.\n *\n * The emitted file ends in `export {};` — same as `makeStackDts`. Without it the\n * `.d.ts` is a global script, and `declare module \"…\"` there DECLARES an ambient\n * module (shadowing the real one, so every export of `@palbase/backend/env`\n * silently becomes invalid) instead of AUGMENTING it. Measured on a minimal tsc\n * repro: with the line, exit 0; without it, `TS2305: Module '\"…\"' has no\n * exported member`. The line was dropped once in a rewrite and nothing caught\n * it, so `env-gen.test.ts` now gates it directly.\n *\n * @example\n * import { makeEnvDts } from \"@palbase/backend\";\n * import publicSchema from \"./db/public.js\";\n * import billing from \"./db/billing.js\";\n * writeFileSync(\"palbase-env.d.ts\", makeEnvDts([publicSchema, billing]));\n */\nexport function makeEnvDts(schemas: readonly SchemaDef[]): string {\n // No pruning: `relations` is a flat literal map, so it cannot expand into an\n // infinite type the way the old recursive `children` could. Dropping a back-edge\n // here would delete a REAL relation and make the type lie about the schema.\n const relations = buildRelations(schemas);\n\n const publicSchema = schemas.find((s) => s.name === \"public\");\n const others = schemas.filter((s) => s.name !== \"public\");\n\n const publicBlocks = Object.keys(publicSchema?.tables ?? {}).map((name) =>\n tableBlock(publicSchema!.tables[name]!, relations.get(name) ?? [], \" \"),\n );\n const body = publicBlocks.length > 0 ? `\\n${publicBlocks.join(\"\\n\")}\\n ` : \"\";\n\n const schemaBlocks = others.map((schema) => {\n const inner = Object.keys(schema.tables).map((name) =>\n tableBlock(schema.tables[name]!, relations.get(qualifiedTableKey(schema.name, name)) ?? [], \" \"),\n );\n return ` ${schema.name}: {\\n${inner.join(\"\\n\")}\\n };`;\n });\n const schemasBody = schemaBlocks.length > 0 ? `\\n${schemaBlocks.join(\"\\n\")}\\n ` : \"\";\n\n return `// AUTO-GENERATED by @palbase/backend — DO NOT EDIT.\n// Regenerated from db/*.ts by \\`palbase build\\` and by every deploy.\n// Augments the @palbase/backend/env \\`Tables\\` interface so \\`Database.tables.*\\`\n// is typed with no import and no generic. Schemas other than \\`public\\` land\n// under \\`Schemas\\`, reached with \\`Database.schema(\"<name>\").tables.*\\`.\n\ndeclare module \"@palbase/backend/env\" {\n interface Tables {${body}}\n interface Schemas {${schemasBody}}\n}\n\nexport {};\n`;\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. */\ntype MethodDecorator = (\n target: object,\n propertyKey: string | symbol,\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) {\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","import { assertZeroArgConstructor } from \"./controller.js\";\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\";\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 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. */\nexport function getWebhookConfig(ctor: object): ResolvedWebhook {\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 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\n // The `new ()` in the cast below is a CLAIM — that the class is constructible\n // with no arguments — and this check is what makes it true. Without it the\n // cast quietly held for `constructor(dep: Repo)` too: the call compiled, it\n // deployed, and the field arrived as `undefined` at the first delivery. Same refusal\n // as the controller's (engine/router.ts, FR-010).\n assertZeroArgConstructor(ctor, \"webhook class\");\n\n const instance = new (ctor as new () => 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","import { assertZeroArgConstructor } from \"./controller.js\";\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\";\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): 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 // The `new ()` in the cast below is a CLAIM — that the class is constructible\n // with no arguments — and this check is what makes it true. Without it the\n // cast quietly held for `constructor(dep: Repo)` too: the call compiled, it\n // deployed, and the field arrived as `undefined` at the first event. Same refusal\n // as the controller's (engine/router.ts, FR-010).\n assertZeroArgConstructor(ctor, \"hook class\");\n\n const instance = new (ctor as new () => Record<string, HookFn>)();\n return {\n blocking: bind(instance, blockingEntries, \"@Hook\"),\n listeners: bind(instance, listenerEntries, \"@On\"),\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","import { assertZeroArgConstructor } from \"./controller.js\";\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\";\n\nexport interface JobOptions {\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 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\nexport function getJobConfig(ctor: object): ResolvedJob {\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 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 // The `new ()` in the cast below is a CLAIM — that the class is constructible\n // with no arguments — and this check is what makes it true. Without it the\n // cast quietly held for `constructor(dep: Repo)` too: the call compiled, it\n // deployed, and the field arrived as `undefined` at the first scheduled run. Same refusal\n // as the controller's (engine/router.ts, FR-010).\n assertZeroArgConstructor(ctor, \"job class\");\n\n const instance = new (ctor as new () => { 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 { schedule: meta.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 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\";\nexport type { ModuleTransport, RequestOptions, TransportConfig } from \"./clients/http.js\";\n\nexport type {\n PalbaseAuthClient,\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 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 PalbaseInboxSendParams,\n PalbaseInboxSendResponse,\n PalbaseInboxMessage,\n PalbaseInboxListOptions,\n PalbaseInboxListResult,\n PalbasePreferences,\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 } from \"./db/schema.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 } 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 } from \"./db/schema.js\";\nexport { policy, PolicyBuilder } from \"./db/policy.js\";\nexport type { PolicyDef, PolicyCommand, PolicyMode } 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 } from \"./db/typed-db.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} 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 { 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\";\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, 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} 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, On, Webhook } from \"./decorators/webhook.js\";\nexport type { ResolvedWebhook, SignatureSpec, WebhookEventHandler, WebhookOptions } from \"./decorators/webhook.js\";\nexport { getJobConfig, 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"],"mappings":"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","names":["raw","raw","text","now"]}