@palbase/backend 38.0.16 → 39.0.0

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 (58) hide show
  1. package/dist/bin/palbase-backend.cjs +46 -1
  2. package/dist/bin/palbase-backend.cjs.map +1 -1
  3. package/dist/bin/palbase-backend.js +5 -5
  4. package/dist/{chunk-LFUNRWUE.js → chunk-4J6I4KVQ.js} +67 -3
  5. package/dist/{chunk-LFUNRWUE.js.map → chunk-4J6I4KVQ.js.map} +1 -1
  6. package/dist/{chunk-7WAGQ3VR.js → chunk-AR2I4M7I.js} +497 -17
  7. package/dist/chunk-AR2I4M7I.js.map +1 -0
  8. package/dist/{chunk-YANGWAIM.js → chunk-H7EKL6HC.js} +2 -2
  9. package/dist/{chunk-EHKEMHB4.js → chunk-JJSR4BUX.js} +49 -5
  10. package/dist/chunk-JJSR4BUX.js.map +1 -0
  11. package/dist/{chunk-CS6NQ6PO.js → chunk-JPTFYHP3.js} +2 -2
  12. package/dist/{chunk-CS6NQ6PO.js.map → chunk-JPTFYHP3.js.map} +1 -1
  13. package/dist/{chunk-X7UR3VXA.js → chunk-XZWOMPD3.js} +3 -2
  14. package/dist/chunk-XZWOMPD3.js.map +1 -0
  15. package/dist/{chunk-PDD55QWN.js → chunk-ZNQDL466.js} +2 -2
  16. package/dist/db/index.cjs +378 -14
  17. package/dist/db/index.cjs.map +1 -1
  18. package/dist/db/index.d.cts +1 -1
  19. package/dist/db/index.d.ts +1 -1
  20. package/dist/db/index.js +3 -3
  21. package/dist/engine/index.cjs +46 -1
  22. package/dist/engine/index.cjs.map +1 -1
  23. package/dist/engine/index.d.cts +3 -3
  24. package/dist/engine/index.d.ts +3 -3
  25. package/dist/engine/index.js +5 -5
  26. package/dist/{index-CI7S0Wqv.d.cts → index-B0mjUnxy.d.cts} +25 -2
  27. package/dist/{index-CUy50OLU.d.ts → index-eN4KzGa5.d.ts} +555 -29
  28. package/dist/{index-DRx880KY.d.cts → index-pK2At5Yc.d.cts} +555 -29
  29. package/dist/{index-Ogi30dbt.d.ts → index-yDno9Ju9.d.ts} +25 -2
  30. package/dist/index.cjs +628 -17
  31. package/dist/index.cjs.map +1 -1
  32. package/dist/index.d.cts +183 -8
  33. package/dist/index.d.ts +183 -8
  34. package/dist/index.js +74 -6
  35. package/dist/index.js.map +1 -1
  36. package/dist/openapi/index.cjs.map +1 -1
  37. package/dist/openapi/index.d.cts +2 -2
  38. package/dist/openapi/index.d.ts +2 -2
  39. package/dist/openapi/index.js +2 -2
  40. package/dist/{registry-C7UCkQf0.d.cts → registry-9dNeVN5d.d.cts} +1 -1
  41. package/dist/{registry-DJcvbomD.d.ts → registry-B8ddZiMY.d.ts} +1 -1
  42. package/dist/test/index.cjs +19 -0
  43. package/dist/test/index.cjs.map +1 -1
  44. package/dist/test/index.d.cts +1 -1
  45. package/dist/test/index.d.ts +1 -1
  46. package/dist/test/index.js +20 -2
  47. package/dist/test/index.js.map +1 -1
  48. package/docs/README.md +1 -1
  49. package/docs/database.md +79 -0
  50. package/docs/llms-full.txt +462 -33
  51. package/docs/schema.md +382 -32
  52. package/package.json +1 -1
  53. package/template/package.json +1 -1
  54. package/dist/chunk-7WAGQ3VR.js.map +0 -1
  55. package/dist/chunk-EHKEMHB4.js.map +0 -1
  56. package/dist/chunk-X7UR3VXA.js.map +0 -1
  57. /package/dist/{chunk-YANGWAIM.js.map → chunk-H7EKL6HC.js.map} +0 -0
  58. /package/dist/{chunk-PDD55QWN.js.map → chunk-ZNQDL466.js.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/engine/index.ts","../../src/runtime.ts","../../src/db/input-guards.ts","../../src/db/tx-plan.ts","../../src/db/transaction-options.ts","../../src/db/schema-json.ts","../../src/db/sqlstate.ts","../../src/errors.ts","../../src/engine/config.ts","../../src/refusals.ts","../../src/engine/auth.ts","../../src/engine/ratelimit.ts","../../src/engine/cache.ts","../../src/engine/db.ts","../../src/engine/schema-cache.ts","../../src/engine/cursor.ts","../../src/db/bulk.ts","../../src/db/unique.ts","../../src/engine/commands.ts","../../src/engine/admission.ts","../../src/engine/transaction-control.ts","../../src/engine/diagnostics.ts","../../src/db/columns.ts","../../src/db/env-gen.ts","../../src/engine/cancellation.ts","../../src/decorators/registry.ts","../../src/decorators/controller.ts","../../src/engine/router.ts","../../src/engine/attest.ts","../../src/engine/upload.ts","../../src/engine/sse.ts","../../src/container.ts","../../src/decorators/injectable.ts","../../src/decorators/kinds.ts","../../src/decorators/module.ts","../../src/engine/fence.ts"],"sourcesContent":["/**\n * engine/index.ts — the engine: a backend that boots itself.\n *\n * `createApp` turns a set of `@Controller` classes into a `fetch(Request)`\n * handler. No V8 isolate, no capability hop: this process owns its database\n * pool, verifies its own tokens, applies its own rate limits, and calls the\n * modules directly.\n *\n * import { createApp, loadConfig } from \"@palbase/backend/engine\";\n *\n * const app = await createApp({\n * config: loadConfig(process.env),\n * controllers: [TodosController],\n * schema,\n * });\n * Bun.serve({ port: app.config.port, fetch: app.handle });\n *\n * The Web-standard `fetch` signature is the point: the same handler runs under\n * Bun, Deno and any host that speaks Request/Response, so \"works locally\" and\n * \"works in the cloud\" are the same code path rather than two.\n */\nimport type { ZodError, ZodTypeAny } from \"zod\";\n\nimport { __runWithRuntime, __requestALS, __runStartHooks } from \"../runtime.js\";\nimport type { RuntimeServices, ShutdownRunner } from \"../runtime.js\";\nimport { isHttpError, isEngineRaised } from \"../errors.js\";\nimport type { CacheClient, ClientInfo } from \"../endpoint.js\";\n\nimport { loadConfig, BootRefused } from \"./config.js\";\nimport { DeclarationRefused, isDeclarationRefused, DECLARATION_REFUSAL } from \"../refusals.js\";\nimport type { EngineConfig } from \"./config.js\";\nimport { AuthVerifier, effectiveAuth } from \"./auth.js\";\nimport type { VerifiedDevice } from \"../types.js\";\nimport type { EffectiveAuth, VerifiedClaims } from \"./auth.js\";\nimport { RateLimiter } from \"./ratelimit.js\";\nimport { makeMemoryCache } from \"./cache.js\";\nimport { createRequestDatabase, setSchema, setSecretReader } from \"./db.js\";\nimport { setCursorKey } from \"./cursor.js\";\nimport { installCommandExecutor } from \"./commands.js\";\nimport { withQueryCancellation } from \"./cancellation.js\";\nimport { databaseAdmission } from \"./admission.js\";\nimport type { SqlDriver } from \"./db.js\";\nimport { buildRouteTable, matchRoute } from \"./router.js\";\nimport { createAttestGate, createObservationSink } from \"./attest.js\";\nimport {\n AUTHORIZE_PATH,\n SIGNATURE_HEADER,\n grantFor,\n verifySignature,\n CompletionLedger,\n type CompletionEnvelope,\n} from \"./upload.js\";\nimport {\n SSE_CONTENT_TYPE,\n encodeErrorFrame,\n makeSseWriter,\n type EngineSseWriter,\n} from \"./sse.js\";\nimport type { RouteEntry } from \"./router.js\";\nimport { assertNoOrphanEntryPoints, buildContainer, type Container } from \"../container.js\";\n\nexport { loadConfig, BootRefused } from \"./config.js\";\nexport { DeclarationRefused, isDeclarationRefused, DECLARATION_REFUSAL } from \"../refusals.js\";\nexport type { EngineConfig } from \"./config.js\";\nexport { AuthVerifier, effectiveAuth } from \"./auth.js\";\nexport { RateLimiter } from \"./ratelimit.js\";\nexport { makeMemoryCache } from \"./cache.js\";\nexport { createLazyTransaction, createOps, withTables, createRequestDatabase, quoteIdent } from \"./db.js\";\nexport type { SqlDriver, SqlTx, RequestDatabase } from \"./db.js\";\nexport { setCursorKey } from \"./cursor.js\";\nexport { installCommandExecutor, COMMAND_EXECUTOR_DDL } from \"./commands.js\";\nexport { withQueryCancellation } from \"./cancellation.js\";\nexport { buildRouteTable, matchRoute } from \"./router.js\";\nexport type { RouteEntry } from \"./router.js\";\nexport { scrubSecrets, installEgressFence, hostAllowed } from \"./fence.js\";\nexport type { EgressPolicy, ScrubResult } from \"./fence.js\";\n\n/** The `__`-prefixed request-scope seam, as re-exported by a deployed bundle. */\nexport interface RuntimeHooks {\n __runWithRuntime: typeof __runWithRuntime;\n __requestALS: typeof __requestALS;\n}\n\n/** The module singletons the engine injects, minus the two it owns itself. */\nexport type ModuleClients = Partial<\n Pick<\n RuntimeServices,\n \"Auth\" | \"Documents\" | \"Storage\" | \"Notifications\" | \"Flags\" | \"Realtime\" | \"Secrets\"\n >\n>;\n\nexport interface CreateAppOptions {\n /**\n * Vault'tan TEK secret okuma (FR-025): sorgu-anı embedding'in anahtarı\n * buradan akar. Verilmezse auto-embed'li search({query}) adlandırılmış\n * hatayla düşer — sessiz boş sonuç asla (FR-015).\n */\n secretReader?: (name: string) => Promise<string | null>;\n config: EngineConfig;\n /** `@Controller` classes. A class that collected zero routes is fatal. */\n controllers: readonly unknown[];\n /** The project's `defineSchema()` result, for the typed `.tables` surface. */\n schemas?: readonly unknown[];\n /** The SQL driver. Omitted ⇒ built from `Bun.sql` when running under Bun. */\n sql?: SqlDriver;\n /** Module clients. Omitted ⇒ each corresponding singleton throws when used. */\n modules?: ModuleClients;\n /** Cache. Omitted ⇒ this process's own memory. */\n cache?: CacheClient;\n /**\n * The request-scope hooks to run handlers inside.\n *\n * MUST come from the SAME `@palbase/backend` module instance the loaded\n * controllers were bundled against. A deployed bundle inlines its own copy of\n * the SDK and re-exports these two; the engine here has its own. Two copies\n * mean two AsyncLocalStorage instances, and the store this engine sets is not\n * the store the handler's `Database` proxy reads — every service would be\n * undefined at the first call, with nothing in the logs to say why. So the\n * host passes the BUNDLE's hooks and the seam closes.\n *\n * Omitted ⇒ this module's own, which is correct only when the controllers\n * were built against this same instance (tests, a single-package project).\n */\n runtimeHooks?: RuntimeHooks;\n logger?: Pick<Console, \"info\" | \"warn\" | \"error\" | \"debug\">;\n}\n\nexport interface App {\n /** Core/operator observation of the shared physical pool's admission queue. */\n readonly databasePressure?: ReturnType<typeof databaseAdmission>[\"snapshot\"];\n handle: (req: Request) => Promise<Response>;\n routes: readonly RouteEntry[];\n config: EngineConfig;\n /**\n * Run work that has no request behind it — a scheduled job — inside the same\n * request scope a handler gets, with its own transaction.\n */\n runInServiceScope: <T>(fn: () => T | Promise<T>) => Promise<T>;\n /** Close the pool and release resources. */\n shutdown: () => Promise<void>;\n /**\n * The container this app resolved its classes from.\n *\n * Exposed because entry points the ENGINE does not own are built elsewhere:\n * the runtime constructs rooms, jobs and hooks, and they must come from THIS\n * app's graph rather than a second one built beside it (FR-037, FR-042).\n */\n readonly container: Container;\n}\n\n/** Ceiling on a buffered request body.\n *\n * Ten megabytes: comfortably above any JSON payload a controller takes, and\n * far below what a handful of concurrent requests could use to exhaust a\n * runtime. It exists because the App Attest gate needs the bytes, so the body\n * is now read before the rate limiter — earlier than the limiter that used to\n * bound how many could arrive at once. */\nconst MAX_BODY_BYTES = 10 * 1024 * 1024;\n\nconst JSON_HEADERS = { \"content-type\": \"application/json\" } as const;\n\n/** Flatten a zod failure into the `{ field, message }[]` the SDK's own\n * `BadRequest` payload declares — one shape for the engine's automatic\n * refusals and for `throw new BadRequest({ fields })` alike. */\nfunction fieldErrors(err: ZodError): Array<{ field: string; message: string }> {\n return err.issues.map((i) => ({ field: i.path.join(\".\"), message: i.message }));\n}\n\n/** Re-key the header map onto the names an `@Headers` schema declares.\n *\n * HTTP HEADER NAMES ARE CASE-INSENSITIVE (RFC 9110 §5.1); a zod key is a\n * literal. `Headers` iteration lowercases, so `Object.fromEntries(req.headers)`\n * only ever carries `x-tenant` — while the deploy gate lowercases a declared\n * name only for its RESERVED check (`extract_meta.js` validateHeadersSchema),\n * so `z.object({ \"X-Tenant\": … })` ships. That is also the spelling every HTTP\n * document uses and the one the iOS/Android generators emit into the generated\n * call's signature, so the caller really does send it.\n *\n * Comparing case-sensitively would answer 400 on a header the caller DID send,\n * on every request, forever — the schema was inert before it was enforced, so\n * the refusal would arrive with the SDK upgrade and name a header the client\n * can see itself sending. The lowercase twin stays in the map (zod strips\n * unknown keys), so the parsed value carries exactly the declared spelling.\n */\nfunction headersFor(raw: Record<string, string>, schema: ZodTypeAny): Record<string, string> {\n const shape = (schema as { shape?: Record<string, unknown> }).shape;\n if (typeof shape !== \"object\" || shape === null) return raw;\n let aliased: Record<string, string> | null = null;\n for (const declared of Object.keys(shape)) {\n const lower = declared.toLowerCase();\n if (lower === declared) continue;\n const value = raw[lower];\n if (value === undefined) continue;\n aliased ??= { ...raw };\n aliased[declared] = value;\n }\n return aliased ?? raw;\n}\n\nfunction envelope(\n error: string,\n description: string,\n status: number,\n requestId: string,\n extra?: Record<string, unknown>,\n): Response {\n return new Response(\n JSON.stringify({ error, error_description: description, status, request_id: requestId, ...extra }),\n { status, headers: JSON_HEADERS },\n );\n}\n\n/** A module that was never configured must say so by name on first use, not\n * fail with \"Cannot read properties of undefined\". */\n/**\n * A module singleton nobody injected.\n *\n * The message names TWO causes because there are two, and pointing at only one\n * sends an operator to check a setting that is already correct. Measured on\n * 2026-08-15: a handler reaching for `Purchases` was told to set\n * MODULE_BASE_URL — which was set. Purchases is simply not part of this\n * backend, and an error that hides that costs the reader the afternoon.\n */\nfunction unavailable(name: string): never {\n throw new Error(\n `${name} is unavailable. Either this backend was started without module clients ` +\n `(set MODULE_BASE_URL and the API keys so the engine can reach the module surface), ` +\n `or ${name} is not one of the modules this backend provides.`,\n );\n}\n\nfunction stubModule(name: string): unknown {\n return new Proxy(\n {},\n {\n get: () => unavailable(name),\n apply: () => unavailable(name),\n },\n );\n}\n\nasync function defaultSqlDriver(config: EngineConfig): Promise<SqlDriver> {\n const g = globalThis as { Bun?: { SQL: new (o: { url: string; max: number }) => SqlDriver } };\n if (!g.Bun?.SQL) {\n throw new BootRefused(\n [],\n \"boot refused: no SQL driver. Running outside Bun means the driver must be supplied — \" +\n \"pass `sql` to createApp().\",\n );\n }\n return withQueryCancellation(new g.Bun.SQL({ url: config.databaseUrl, max: config.poolMax }),\n new g.Bun.SQL({ url: config.databaseUrl, max: 2 }));\n}\n\n/** The statuses an author THROWS to answer a request. Everything else that\n * reaches the catch is unplanned and gets logged — see the branch that reads\n * this. Kept beside nothing else so there is one list, not a condition spread\n * across two files.\n *\n * 409 IS IN THIS LIST, and the reason is the whole shape of the check. The\n * scaffold teaches `throw new Conflict(\"title already taken\")` as the way to\n * answer with a 409 (template/AGENTS.md), and the engine raises\n * `UniqueViolation` — also a 409 — from a duplicate write. The status cannot\n * tell them apart, so intent is read from ORIGIN instead: the engine MARKS what\n * it built (`markEngineRaised`), and the branch below logs on that mark\n * regardless of status. Splitting on the status alone wrote an \"unhandled\" line\n * every time an author took the documented path — measured. */\nconst AUTHOR_ANSWERED: ReadonlySet<number> = new Set([400, 401, 403, 404, 409, 429]);\n\n/**\n * Build the app. Fails fast: the database is reached here, at boot, rather than\n * on the first request that needs it.\n */\n\n/**\n * Refuse a caller the route's declared role/permission does not cover.\n *\n * Authority is read from `auth.user_roles` through the two SECURITY DEFINER\n * helpers, inside the transaction the handler is going to use anyway — never\n * off a JWT claim. That is what makes a revoked role take effect on the very\n * next request rather than whenever the token expires.\n *\n * It lives here, called from BOTH gates, because the alternative is two copies\n * of an authorization rule: the request path and storage's upload-authorize\n * path read the SAME `auth: { … }` declaration, and a decorator that means one\n * thing on one path and another thing on the other is a trap nobody reads twice.\n *\n * Returns the refusal to send, or null when the caller may proceed.\n */\nasync function refuseUnlessAuthorized(\n client: AuthorityClient,\n spec: EffectiveAuth,\n requestId: string,\n rolesOfCaller: () => Promise<string[]>,\n): Promise<Response | null> {\n if (spec.permission !== undefined) {\n const [row] = await client.query<{ ok: boolean }>(\n \"select auth.has_permission($1) as ok\",\n [spec.permission],\n );\n if (row?.ok !== true) {\n return envelope(\n \"forbidden\",\n `This endpoint requires the \"${spec.permission}\" permission`,\n 403,\n requestId,\n // FR-008 / D-7: reddin ÇARESİ gövdede — istemci `required`'ı görünce ilgili\n // nesneyi yeniden çeker (Entra CAE deseni); cümle değişmez.\n { required: spec.permission },\n );\n }\n }\n if (spec.role !== undefined) {\n const held = await rolesOfCaller();\n if (!held.includes(spec.role)) {\n return envelope(\"forbidden\", `This endpoint requires the \"${spec.role}\" role`, 403, requestId, {\n required_role: spec.role,\n });\n }\n }\n return null;\n}\n\n/** What both gates and the `@User()` branch need out of a request database. */\ntype AuthorityClient = { query<T = unknown>(sql: string, params?: unknown[]): Promise<T[]> };\n\n/**\n * The caller's application roles, resolved ONCE per request.\n *\n * The gate asks \"does this caller hold R\" and `@User()` asks \"what does this\n * caller hold\" — two questions with one answer, and asking twice would cost a\n * second round trip AND let the gate admit on one snapshot while the handler\n * reads another. So the LIST is what gets fetched, memoised on the promise so\n * two concurrent readers share the one query, and the gate's membership test\n * becomes an `includes` on it.\n *\n * `auth.app_roles()` returns `text[]` (sorted, `{}` when empty) and is unnested\n * here rather than parsed as an array: a row per role is what every driver in\n * front of this agrees on without a codec.\n *\n * Nothing runs until somebody asks. A route that declares no role and never\n * injects a user opens no transaction at all — the request database is lazy and\n * this is the only thing that would have touched it.\n */\nfunction makeRoleResolver(client: AuthorityClient): () => Promise<string[]> {\n let pending: Promise<string[]> | null = null;\n return () => {\n pending ??= client\n .query<{ role: string }>(\"select unnest(auth.app_roles()) as role\")\n .then((rows) => rows.map((r) => r.role));\n return pending;\n };\n}\n\nexport async function createApp(opts: CreateAppOptions): Promise<App> {\n const { config, controllers } = opts;\n\n // NOTHING PROCESS-WIDE IS WRITTEN UNTIL THIS APP IS GOING TO EXIST.\n //\n // `setSchema` and `setSecretReader` used to be the first two lines, and they\n // write MODULE state that the whole process shares. A candidate bundle is\n // built beside the live app in the same process, so a candidate that was then\n // REFUSED — for any reason, and this file has several — had already replaced\n // the serving release's schema and never put it back.\n //\n // Measured 2026-09-02:\n // live app → schema [\"notes\"]\n // candidate refused → \"Kind: unowned class\"\n // live app now → schema [\"candidate_only\"]\n //\n // Every request the still-serving release went on answering would resolve its\n // tables against a schema that no longer had them. The fix is ordering, not a\n // second mechanism: VALIDATE FIRST, take over the process afterwards. The\n // writes now sit below the last thing that can refuse.\n\n // The container is built HERE and lives exactly as long as this app.\n //\n // `buildContainer` CLAIMS the module declarations rather than reading them, so\n // a candidate bundle loaded beside a live app builds from its OWN modules and\n // leaves nothing behind if it is discarded. Keeping the graph on globalThis\n // instead would be the same defect one layer up.\n const container = buildContainer();\n // Set by `shutdown`; read by the guard below so a resolve after shutdown says\n // WHY rather than handing back an instance whose pool is closed.\n let released = false;\n const liveContainer: Container = {\n get<T>(t: never): T {\n if (released) {\n throw new Error(\n \"this app has shut down — its container no longer resolves. \" +\n \"A class resolved here would hold a closed database pool.\",\n );\n }\n return container.get(t) as T;\n },\n owned: container.owned,\n pressure: container.pressure,\n };\n\n // Nothing that decorated itself may be served unless a module claimed it.\n // Before this, a @Controller in no module still reached the route table and\n // the OpenAPI document — it worked, and that was the problem.\n assertNoOrphanEntryPoints(controllers, container.owned);\n\n const routes = buildRouteTable(controllers, liveContainer);\n if (routes.length === 0) {\n // A DECLARATION FACT, and it used to be filed under `BootRefused` beside\n // \"no DATABASE_URL\" — two refusals with opposite cures under one name. This\n // one is cured by a push and nothing else, so the runtime must be able to\n // wait on it instead of taking the pod (and palsvc) down.\n throw new DeclarationRefused(\"boot refused: zero endpoints collected — nothing would answer.\");\n }\n\n const sql = opts.sql ?? (await defaultSqlDriver(config));\n const admission = sql.admission ?? databaseAdmission(sql, { concurrency: config.poolMax, ...config.databaseAdmission });\n const inFlight = new Set<Promise<unknown>>();\n let shuttingDown: Promise<void> | undefined;\n let accepting = true;\n async function serving<T>(run: () => Promise<T>): Promise<T> {\n const work = run();\n inFlight.add(work);\n try { return await work; } finally { inFlight.delete(work); }\n }\n await sql.unsafe(\"select 1\");\n\n // Past every refusal above — including the database being unreachable, which\n // is the last thing that stops a boot. This app IS going to exist, so the\n // process-wide state is now its to hold. See the note at the top of this\n // function. Neither line above needs the schema: one builds a driver from\n // config, the other sends a literal.\n setSchema(opts.schemas ?? []);\n setCursorKey(config.cursorSecret || config.serviceRoleKey || null);\n if (config.enableCommands) await installCommandExecutor(sql, [config.dbRole, config.dbServiceRole]);\n setSecretReader(opts.secretReader ?? null);\n\n const auth = new AuthVerifier({ jwksUrl: config.authJwksUrl, issuer: config.authIssuer });\n\n // The App Attest gate and its counter, built once at boot.\n //\n // Both talk to palauth over the SAME internal base url the module clients\n // use, with the service-role key — these endpoints are the seam between two\n // processes in one pod, not a client surface.\n //\n // The gate resolves the mode itself on a 30-second cache, which is what lets\n // an operator flip the flag in Studio and see it take effect without a\n // redeploy. Unreachable palauth ⇒ \"off\", because a gate that cannot reach its\n // policy must not take the tenant's traffic down with it.\n const attestGate = createAttestGate({\n moduleBaseUrl: config.moduleBaseUrl,\n serviceRoleKey: config.serviceRoleKey,\n });\n const observations = createObservationSink({\n moduleBaseUrl: config.moduleBaseUrl,\n serviceRoleKey: config.serviceRoleKey,\n });\n const limiter = new RateLimiter();\n const cache = opts.cache ?? makeMemoryCache();\n const log = opts.logger ?? console;\n const modules = opts.modules ?? {};\n const runWithRuntime = opts.runtimeHooks?.__runWithRuntime ?? __runWithRuntime;\n const requestALS = opts.runtimeHooks?.__requestALS ?? __requestALS;\n\n // The secret storage signs its internal calls with. Absent means uploads are\n // not wired, and authorize REFUSES rather than answering with a grant anybody\n // could have asked for.\n const uploadSecret = config.uploadSecret ?? \"\";\n\n /**\n * Answer \"which bucket and path does this route write to?\".\n *\n * Storage cannot know: the answer is `@Upload({bucket, pathTemplate})`, which\n * lives in the deployed bundle. Asking the process that HAS the routes is\n * what keeps the client from naming its own bucket — the request carries the\n * route it wants to use, and this decides what that means.\n */\n // One ledger per app: a completion retried against this process must find\n // its own first answer, and a process restart legitimately forgets — the\n // window a retry lives in is far shorter than an uptime.\n const completions = new CompletionLedger();\n\n /**\n * The service bundle a scope binds, built around ONE request-scoped database.\n *\n * Extracted so the request path and the job path cannot drift: a second copy\n * of this object is a second definition of what a handler can reach, and the\n * one that goes stale is always the one nobody is looking at.\n */\n /** `db === null` is the BOOT scope: everything else is available, and\n * `Database` refuses by name because a start hook runs before any request and\n * there is no transaction for a query to belong to. One writer, so the boot\n * scope cannot drift from the request one. */\n function buildServices(db: ReturnType<typeof createRequestDatabase> | null): RuntimeServices {\n return {\n Database:\n db?.client ??\n stubModule(\"Database (a start hook runs before any request — open your own connection here)\"),\n Cache: cache,\n Log: log,\n Auth: modules.Auth ?? stubModule(\"Auth\"),\n Documents: modules.Documents ?? stubModule(\"Documents\"),\n Storage: modules.Storage ?? stubModule(\"Storage\"),\n Notifications: modules.Notifications ?? stubModule(\"Notifications\"),\n Flags: modules.Flags ?? stubModule(\"Flags\"),\n Realtime: modules.Realtime ?? stubModule(\"Realtime\"),\n // Named, never undefined. A backend started without a secrets client\n // that returned `undefined` here would fail inside the handler as\n // \"Cannot read properties of undefined\", which says nothing about what\n // to configure — the stub says the name and the variable.\n Secrets: modules.Secrets ?? stubModule(\"Secrets\"),\n } as unknown as RuntimeServices;\n }\n\n /**\n * Run `fn` as the system, with no request behind it.\n *\n * Scheduled jobs need exactly what a handler needs — Database, Log,\n * Notifications, resolved out of the request scope — but there is no request\n * to take an identity from. So the claims are EMPTY: a job is nobody, and\n * `Database` here satisfies no owner-scoped RLS policy. That is why a job\n * reaches for `Database.$asService()`, and why this does not quietly hand it\n * service_role by default.\n *\n * The transaction settles the same way a request's does: commit on return,\n * rollback on throw. A job that fails halfway leaves nothing behind that the\n * next run has to reason about.\n */\n async function runInServiceScope<T>(fn: () => T | Promise<T>): Promise<T> {\n const db = createRequestDatabase(sql, {\n role: config.dbRole,\n serviceRole: config.dbServiceRole,\n claimsJson: \"{}\",\n }, config.databaseDiagnostics === undefined ? undefined : { ...config.databaseDiagnostics, endpoint: \"scheduled job\" });\n try {\n const out = await runWithRuntime(buildServices(db), fn as () => Promise<T>);\n await db.commit();\n return out;\n } catch (err) {\n await db.rollback(err);\n throw err;\n }\n }\n\n function errorResponse(err: unknown, endpoint: string, requestId: string): Response {\n // The same branded envelope applies before dispatch, in a handler and in\n // storage authorization. A queue rejection must never escape as Bun's 500.\n if (isHttpError(err)) {\n if (isEngineRaised(err) || !AUTHOR_ANSWERED.has(err.status)) {\n log.error(`[engine] unhandled ${err.error} in ${endpoint}`, err);\n }\n return envelope(err.error, err.errorDescription, err.status, requestId,\n err.data !== undefined ? { data: err.data } : undefined);\n }\n log.error(`[engine] unhandled error in ${endpoint}`, err);\n return envelope(\"internal_error\", \"The request could not be completed\", 500, requestId);\n }\n\n async function handleAuthorize(req: Request, requestId: string): Promise<Response> {\n if (uploadSecret === \"\" ||\n !verifySignature(req.headers.get(SIGNATURE_HEADER) ?? \"\", uploadSecret)) {\n return envelope(\"unauthorized\", \"This endpoint is not callable directly\", 401, requestId);\n }\n const body = (await req.json().catch(() => null)) as {\n method?: string;\n path?: string;\n userId?: string | null;\n uploadId?: string;\n filename?: string;\n } | null;\n if (!body?.path || !body.uploadId) {\n return envelope(\"bad_request\", \"authorize needs a path and an uploadId\", 400, requestId);\n }\n const target = matchRoute(routes, body.method ?? \"POST\", body.path);\n\n // THE AUTH DECISION HAPPENS HERE, BEFORE A SINGLE BYTE IS ACCEPTED.\n //\n // Storage asks this question precisely so it can refuse early: without it,\n // an anonymous caller could push a file at a route that requires a user,\n // have it written and its variants rendered, and only then be turned away\n // by the completion — the bytes were still accepted, and the work still\n // done, once per attempt.\n //\n // The credential is the caller's own, forwarded by storage, and it is\n // verified HERE rather than trusted: the userId that ends up in the path\n // template comes from these claims and from nothing else, so neither the\n // client nor storage can name a folder that belongs to somebody else.\n const spec = effectiveAuth(target?.entry.meta.options?.auth, target?.entry.controllerAuth);\n const callerClaims = await auth.verify(req.headers.get(\"authorization\"));\n if (spec.required && !callerClaims) {\n return envelope(\"unauthorized\", \"A valid access token is required\", 401, requestId);\n }\n // Storage'ın yetkilendirme hoppası da AYNI kapıdan geçer — ve ana istek\n // yolunda olduğu gibi, `claims` olsun olmasın. Bu blok bir\n // `if (callerClaims)` guard'ının içindeydi: `{ required: false, permission }`\n // bildiren bir upload rotasında imzasız çağıran hiç sorulmadan geçiyordu.\n // Kimliksiz çağıranda `auth.uid()` null olduğu için `has_permission` false\n // döner ve ret 403 olur.\n //\n // Transaction lazy: rol/izin sorulmayan bir upload rotasında hiçbir şey\n // açılmaz, yani bildirmeyen rotaya maliyeti yoktur.\n const uploadDb = createRequestDatabase(sql, {\n role: config.dbRole,\n serviceRole: config.dbServiceRole,\n claimsJson: JSON.stringify(callerClaims ?? {}),\n }, config.databaseDiagnostics === undefined ? undefined : { ...config.databaseDiagnostics, endpoint: \"upload authorization\", requestId }, req.signal);\n try {\n const refusal = await refuseUnlessAuthorized(\n uploadDb.client,\n spec,\n requestId,\n makeRoleResolver(uploadDb.client),\n );\n if (refusal) {\n await uploadDb.commit();\n return refusal;\n }\n await uploadDb.commit();\n } catch (err) {\n await uploadDb.rollback(err);\n return errorResponse(err, \"upload authorization\", requestId);\n }\n\n const grant = grantFor(target?.entry, {\n userId: typeof callerClaims?.sub === \"string\" ? callerClaims.sub : null,\n uploadId: body.uploadId,\n filename: body.filename,\n });\n if (!grant) {\n // A route with no @Upload never offered to accept a file. Refusing by\n // NAME rather than 404 so an operator reading storage's log learns which\n // route was asked for.\n return envelope(\"not_an_upload_route\",\n `${body.method ?? \"POST\"} ${body.path} does not declare @Upload`, 400, requestId);\n }\n return new Response(JSON.stringify(grant), { status: 200, headers: JSON_HEADERS });\n }\n\n async function handle(req: Request): Promise<Response> {\n const requestId = `req_${crypto.randomUUID()}`;\n const url = new URL(req.url);\n\n // ── storage's two internal calls, before ordinary routing ───────────────\n //\n // They are not the tenant's routes and must not be reachable as one: an\n // app that declared `POST /__palbase/upload/authorize` would otherwise\n // shadow the mechanism that decides where uploads land.\n if (url.pathname === AUTHORIZE_PATH) {\n return handleAuthorize(req, requestId);\n }\n\n const hit = matchRoute(routes, req.method, url.pathname);\n if (!hit) return envelope(\"not_found\", \"No route matches this method and path\", 404, requestId);\n const { meta } = hit.entry;\n\n let attestedDevice: VerifiedDevice | null = null;\n let attestChallengeOut: string | null = null;\n\n // ── auth ────────────────────────────────────────────────────────────────\n const spec = effectiveAuth(meta.options?.auth, hit.entry.controllerAuth);\n const claims: VerifiedClaims | null = await auth.verify(req.headers.get(\"authorization\"));\n if (spec.required && !claims) {\n return envelope(\"unauthorized\", \"A valid access token is required\", 401, requestId);\n }\n const userId = typeof claims?.sub === \"string\" ? claims.sub : undefined;\n\n // Transaction'ı kapıdan ÖNCE kuruyoruz ve kapı da onu kullanıyor: yetki\n // sorgusu ilk request transaction'ını kullansın diye. Lazy olduğu için rol\n // sormayan bir rotada burada hiçbir şey açılmaz. İlk iş bağımsız $atomic\n // ise yalnız bu core okumaları erken kapanır; uygulamanın SQL'i kapanmaz.\n const db = createRequestDatabase(sql, {\n role: config.dbRole,\n serviceRole: config.dbServiceRole,\n claimsJson: JSON.stringify(claims ?? {}),\n }, config.databaseDiagnostics === undefined && meta.options.databaseBudget === undefined ? undefined : {\n ...config.databaseDiagnostics, ...meta.options.databaseBudget, endpoint: hit.entry.id, requestId,\n }, req.signal);\n\n // Authority reads and parameter injection also acquire database capacity.\n // Their failures must settle the request transaction and preserve HTTP\n // status just as failures in the handler do.\n try {\n // Yetki TOKEN'DAN değil TABLODAN okunur (FR-014/FR-015). Bir claim yalnız\n // mint edildiği anda doğrudur; bir rol geri alındığında etkisinin token\n // süresini beklemesi güvenlik açığıdır. Sorgu, handler'ın zaten kullanacağı\n // transaction içinde koşar (FR-017), yani ek bağlantı maliyeti yoktur.\n //\n // `role` claim'i burada KASTEN okunmuyor: o Postgres rolüdür (\"authenticated\")\n // ve uygulama rolüyle aynı ada sahip olması bir tesadüftür.\n // Bir kez çözülür, iki yerden okunur: kapı (aşağıda) ve `@User()`ın\n // `roles` alanı (FR-016). İkinci bir sorgu ikinci bir snapshot demekti.\n const rolesOfCaller = makeRoleResolver(db.client);\n\n // DISPATCH'TEN ÖNCEKİ HER RET, AÇILMIŞ OLABİLECEK TRANSACTION'I KAPATIR.\n //\n // `createRequestDatabase` artık kapıdan ÖNCE kuruluyor, ve kapı sorgu\n // koşturduğu an `createLazyTransaction` `sql.begin(...)` callback'ine girip\n // `await parked` üzerinde park ediyor. O park yalnız `commit()` (resolve)\n // ya da `rollback()` (reject) ile kalkar — ve ikisi de aşağıdaki `try`\n // bloğunun İÇİNDE çağrılıyor. Aradaki bir `return`, havuz bağlantısını\n // süreç ömrü boyunca `idle in transaction` bırakırdı.\n //\n // Ölçüldü: izin kapısının 403'ünde `{ begun: 1, settled: 0 }`. Yetkisiz bir\n // çağıranın aynı uca N kez vurması havuzdan N bağlantı düşürüyordu — yani\n // kapının kendisi bir DoS koluydu.\n //\n // Hiç açılmamışsa da, zaten commit edilmişse de bu çağrı işlemsizdir\n // (`createLazyTransaction`: `if (!opening) return`), bu yüzden ret yollarına\n // koşulsuz konabilir.\n let dispatched = false;\n const settleBeforeRefusal = async (): Promise<void> => {\n if (dispatched) return;\n await db.rollback(new Error(\"request refused before dispatch\"));\n };\n\n // Kapı `claims` olsun olmasın koşar.\n //\n // `{ required: false, permission: \"p\" }` bildiren bir rotada bu çağrı bir\n // `if (claims)` guard'ının içindeydi: token yoksa `required:false` 401'i de\n // engelliyordu ve kapı HİÇ sorulmuyordu, yani imzasız çağıran handler'a\n // giriyordu. Ölçüldü — Authorization başlığı olmayan istek 200 aldı.\n // İzin isteyen bir uç kimliksiz çağıranı reddetmek ZORUNDA; `auth.uid()`\n // null olduğu için `has_permission` false döner ve ret 403 olur.\n //\n // Bildirmeyen rotaya maliyeti yok: `refuseUnlessAuthorized` ne izin ne rol\n // bildirilmişse hiçbir sorgu açmadan null döner.\n const refusal = await refuseUnlessAuthorized(db.client, spec, requestId, rolesOfCaller);\n if (refusal) {\n await settleBeforeRefusal();\n return refusal;\n }\n if (claims && spec.verifiedEmail && claims.email_verified !== true) {\n await settleBeforeRefusal();\n return envelope(\"email_not_verified\", \"A verified email address is required\", 403, requestId);\n }\n\n let parsedBody: unknown;\n let bodyRead = false;\n\n // The raw body, read ONCE.\n //\n // The App Attest gate binds the assertion to a hash of the body, so it has\n // to see the bytes — and a Request body is a stream that can only be\n // consumed once. Reading it here and handing the same buffer to both the\n // gate and the parameter loop is what keeps the gate from silently\n // draining the body out from under the handler.\n //\n // `rawBody` stays null for methods that cannot carry one, so a GET pays\n // nothing for a feature it never uses.\n let rawBody: Uint8Array | null = null;\n if (req.method !== \"GET\" && req.method !== \"HEAD\") {\n // A DECLARED length over the ceiling is refused BEFORE the body is read.\n //\n // The gate needs the bytes, so the body is now buffered earlier than it\n // used to be — before the rate limiter rather than after, and for every\n // method that can carry one rather than only @Body routes. That moves a\n // memory cost in front of the thing that used to bound it, so the ceiling\n // has to live here instead.\n const declared = Number(req.headers.get(\"content-length\") ?? \"\");\n if (Number.isFinite(declared) && declared > MAX_BODY_BYTES) {\n await settleBeforeRefusal();\n return new Response(\n JSON.stringify({\n error: \"payload_too_large\",\n error_description: `Request body exceeds ${MAX_BODY_BYTES} bytes`,\n status: 413,\n request_id: requestId,\n }),\n { status: 413, headers: JSON_HEADERS },\n );\n }\n const buf = await req.arrayBuffer().catch(() => null);\n // And again on what ACTUALLY arrived: a chunked request declares nothing.\n if (buf && buf.byteLength > MAX_BODY_BYTES) {\n await settleBeforeRefusal();\n return new Response(\n JSON.stringify({\n error: \"payload_too_large\",\n error_description: `Request body exceeds ${MAX_BODY_BYTES} bytes`,\n status: 413,\n request_id: requestId,\n }),\n { status: 413, headers: JSON_HEADERS },\n );\n }\n if (buf && buf.byteLength > 0) rawBody = new Uint8Array(buf);\n }\n const readParsedBody = (): unknown => {\n if (bodyRead) return parsedBody;\n bodyRead = true;\n if (!rawBody) {\n parsedBody = {};\n return parsedBody;\n }\n try {\n parsedBody = JSON.parse(new TextDecoder().decode(rawBody));\n } catch {\n parsedBody = {};\n }\n return parsedBody;\n };\n\n // ── App Attest ──────────────────────────────────────────────────────────\n //\n // After auth (a caller with no session must hear \"unauthorized\", not\n // \"attest first\" — the first is actionable, the second is confusing) and\n // before the rate limiter (a refused request must not spend the caller's\n // budget on a call that never reached a handler).\n const attest = await attestGate(req, rawBody, { userId });\n if (attest.observation) observations.record(attest.observation);\n if (attest.outcome === \"reject\") {\n const headers: Record<string, string> = { ...JSON_HEADERS };\n if (attest.nextChallenge) headers[\"x-palbase-attest-challenge\"] = attest.nextChallenge;\n await settleBeforeRefusal();\n return new Response(\n JSON.stringify({\n error: attest.reason,\n error_description: \"This endpoint requires a verified app instance\",\n status: 401,\n request_id: requestId,\n }),\n { status: 401, headers },\n );\n }\n if (attest.device && claims) attestedDevice = attest.device;\n // The next challenge rides EVERY answer, not just the refusals.\n //\n // Dropping it on the success path is what would keep an attested client\n // paying a 401-then-retry pair for every single call: it would have no\n // fresh nonce for its next assertion and would have to be told to attest\n // all over again. Handing it back here is the entire reason the challenge\n // travels with the verdict.\n attestChallengeOut = attest.nextChallenge;\n\n // ── rate limit ──────────────────────────────────────────────────────────\n const retryAfter = limiter.check(\n meta.options?.rateLimit,\n RateLimiter.key(hit.entry.id, userId, req.headers),\n Date.now(),\n );\n if (retryAfter !== null) {\n // THE HINT GOES IN THE BODY TOO, under the name this SDK already\n // publishes for it. `error-registry.ts` declares\n // `too_many_requests: { retryAfter: number }`, so codegen types\n // `error.data.retryAfter` on every generated client and a thrown\n // `new TooManyRequests({ retryAfter })` already answers in that shape.\n // This limiter answered with the header ALONE, so the one 429 the engine\n // itself produces was the one shape no generated client could read — and\n // a browser behind a CORS gateway cannot see `Retry-After` at all unless\n // it is explicitly exposed. The header stays: it is the HTTP-correct\n // signal, and `@palbase/core`'s retry loop reads it.\n await settleBeforeRefusal();\n return new Response(\n JSON.stringify({\n error: \"too_many_requests\",\n error_description: \"Rate limit exceeded for this endpoint\",\n status: 429,\n request_id: requestId,\n data: { retryAfter },\n }),\n { status: 429, headers: { ...JSON_HEADERS, \"retry-after\": String(retryAfter) } },\n );\n }\n\n // ── arguments ───────────────────────────────────────────────────────────\n // Set when this request IS a completion, so its answer can be remembered.\n let completionUploadId: string | null = null;\n\n const args: unknown[] = [];\n\n\n\n\n\n // The SSE writer has to exist BEFORE the parameter loop (that is where it is\n // injected) but its two collaborators only exist later: the transport queue\n // is created when the ReadableStream starts, and the transaction it settles\n // is opened further down. So both are reached through holders the SSE branch\n // fills in — the writer itself stays ignorant of either.\n let sseEnqueue: ((chunk: string) => void) | null = null;\n let sseSettle: () => Promise<void> = async () => {};\n const sseWriter: EngineSseWriter = makeSseWriter({\n enqueue: (chunk) => sseEnqueue?.(chunk),\n onFirstWrite: () => sseSettle(),\n });\n for (const p of meta.params ?? []) {\n switch (p.kind) {\n case \"body\": {\n readParsedBody();\n const r = p.schema!.safeParse(parsedBody);\n if (!r.success) {\n await settleBeforeRefusal();\n return envelope(\"bad_request\", \"Request body failed validation\", 400, requestId, {\n data: { fields: fieldErrors(r.error) },\n });\n }\n args[p.index] = r.data;\n break;\n }\n case \"query\": {\n const r = p.schema!.safeParse(Object.fromEntries(url.searchParams));\n if (!r.success) {\n await settleBeforeRefusal();\n return envelope(\"bad_request\", \"Query parameters failed validation\", 400, requestId, {\n data: { fields: fieldErrors(r.error) },\n });\n }\n args[p.index] = r.data;\n break;\n }\n case \"param\":\n args[p.index] = hit.params[p.name!];\n break;\n case \"headers\": {\n // A DECLARED HEADER SCHEMA IS A CONTRACT, and three other systems\n // already treat it as one: the deploy gate REFUSES a build whose\n // schema names a reserved or non-string header\n // (cli/internal/backend/devjs/extract_meta.js), the OpenAPI document\n // lists it as an `in: header` parameter, and the iOS/Android\n // generators put it in the generated call's signature. The runtime\n // was the only one that read the schema and did nothing with it, so a\n // request with the header missing or malformed answered 200 and the\n // handler read `undefined` off a value whose type says `string`.\n //\n // Keys arrive LOWERCASE — `Headers` iteration lowercases them — so\n // the declared names are matched case-insensitively (`headersFor`)\n // and `x-tenant` and `X-Tenant` both work, as HTTP says they must.\n const raw = Object.fromEntries(req.headers);\n if (!p.schema) {\n args[p.index] = raw;\n break;\n }\n const r = p.schema.safeParse(headersFor(raw, p.schema));\n if (!r.success) {\n await settleBeforeRefusal();\n return envelope(\"bad_request\", \"Request headers failed validation\", 400, requestId, {\n data: { fields: fieldErrors(r.error) },\n });\n }\n // The PARSED value, matching @Body/@QueryParams: the parameter's type\n // is `z.infer<Schema>`, and injecting the whole header map made the\n // value wider than its own declared type. An author who wants every\n // header still writes `@Headers()` with no schema.\n args[p.index] = r.data;\n break;\n }\n case \"user\":\n case \"optionalUser\":\n args[p.index] = claims\n ? {\n id: userId,\n email: claims.email,\n role: claims.role,\n emailVerified: claims.email_verified === true,\n metadata: (claims.metadata as Record<string, unknown>) ?? {},\n // The caller's APPLICATION roles, from `auth.user_roles` — the\n // same resolution the gate used, so the handler cannot read a\n // different set than the one it was admitted on. Never from a\n // claim: a revoked role has to bite on the next request, and a\n // token says only what was true when it was minted.\n roles: await rolesOfCaller(),\n // Server-owned and only ever filled from a verdict palauth\n // returned. Never from a raw header, never from JWT metadata —\n // the type has said so since it was written and this is the\n // first writer.\n device: attestedDevice,\n }\n : null;\n break;\n case \"uploadedObject\": {\n // An @Upload route runs as a COMPLETION handler: the bytes went to\n // storage, and what arrives here is what storage recorded about them.\n // The call must be signed, or anyone who knows the route path could\n // invent an upload that never happened and make the handler write a\n // row for it.\n if (uploadSecret === \"\" ||\n !verifySignature(req.headers.get(SIGNATURE_HEADER) ?? \"\", uploadSecret)) {\n await settleBeforeRefusal();\n return envelope(\"unauthorized\",\n \"This endpoint accepts uploads through storage, not directly\", 401, requestId);\n }\n readParsedBody();\n const envelopeIn = parsedBody as CompletionEnvelope | null;\n if (!envelopeIn?.uploadedObject) {\n await settleBeforeRefusal();\n return envelope(\"bad_request\", \"the completion call carried no uploaded object\", 400, requestId);\n }\n // A RETRY MUST NOT RUN THE HANDLER AGAIN.\n //\n // Storage retries a completion it did not hear back from, and the\n // handler is a mutation: run twice, one uploaded photo becomes two\n // posts. The first answer is replayed instead, which is what makes\n // the retry invisible to the client waiting on the other end.\n const uploadId = envelopeIn.uploadedObject.uploadId;\n if (typeof uploadId === \"string\" && uploadId !== \"\") {\n const already = completions.recall(uploadId);\n if (already) {\n await settleBeforeRefusal();\n return new Response(already.body, {\n status: already.status,\n headers: already.contentType ? { \"content-type\": already.contentType } : undefined,\n });\n }\n completionUploadId = uploadId;\n }\n args[p.index] = envelopeIn.uploadedObject;\n // The author's @Body sees THEIR payload, not the envelope around it.\n parsedBody = envelopeIn.body ?? {};\n break;\n }\n case \"requestId\":\n args[p.index] = requestId;\n break;\n case \"traceId\":\n args[p.index] = requestId;\n break;\n case \"client\":\n // The data was always on the wire; nothing read it. Every shipped\n // client SDK stamps these four on every request (iOS\n // Palbe/Core/ClientInfo.swift, web core/src/http.ts), and the\n // platform already reads the same names in Go\n // (user-flags/internal/middleware/clientcontext.go). Header names are\n // canonical here, not invented: the deploy gate REFUSES an\n // `@Headers` schema that names an `x-palbase-*` key, which makes\n // `@Client()` the only sanctioned reader of them.\n //\n // `Headers.get()` answers `string | null`, which is exactly what\n // `ClientInfo` declares — a non-SDK caller (curl, server-to-server)\n // sends none of these and gets four nulls rather than a throw.\n args[p.index] = {\n sdkVersion: req.headers.get(\"x-palbase-sdk-version\"),\n appVersion: req.headers.get(\"x-palbase-client-version\"),\n platform: req.headers.get(\"x-platform\"),\n osVersion: req.headers.get(\"x-os-version\"),\n } satisfies ClientInfo;\n break;\n case \"req\":\n args[p.index] = req;\n break;\n // `@Signal()` — the raw request's AbortSignal, which enters the aborted\n // state when the client disconnects. Measured on Bun: an infinite\n // producer guarded by it stops within a few frames of the client dying.\n // It is deliberately NOT reachable through `@Req()`: PBRequest carries\n // request-scoped data and no signal.\n case \"signal\":\n args[p.index] = req.signal;\n break;\n // `@SseOut()` — the frame writer. Meaningful only on an `@Sse` route;\n // on any other route it is an inert writer whose frames go nowhere,\n // which is the same shape `@UploadedObject()` has off an `@Upload`\n // route.\n case \"sseOut\":\n args[p.index] = sseWriter;\n break;\n default:\n args[p.index] = undefined;\n }\n }\n\n // ── dispatch, inside the request's transaction(s) ───────────────────────\n //\n // One for the caller's identity, and — only if the handler asks for it —\n // one more for `Database.$asService()`. Both were built above, at the\n // authorization gate, and both settle here, together.\n db.authorizationComplete?.();\n dispatched = true;\n const services = buildServices(db);\n\n // ── the streaming branch ────────────────────────────────────────────────\n //\n // An `@Sse` route answers with `text/event-stream` and a body that stays\n // open; its return value is discarded. What makes this more than \"return a\n // stream\" is the moment of commitment: once ONE frame has gone out, the\n // 200 and the headers are spent, so a later throw can only be reported\n // in-band (FR-011). Before that first frame the status line is still ours\n // and an ordinary error envelope is both possible and much more useful\n // (FR-010). So the handler is started, and the decision waits for whichever\n // comes first — its first write, or its own completion.\n if (meta.options?.sseConfig !== undefined) {\n // The transport is built BEFORE the handler starts, so there is never a\n // window in which a written frame has nowhere to go. An unused stream\n // costs nothing: if the handler turns out never to write, the response\n // below is an ordinary envelope and this object is simply dropped.\n // (An earlier version created the stream only after the first frame and\n // held frames in a buffer meanwhile. That buffer's correctness depended\n // on microtask timing, so no test could pin it — mutation-checked: the\n // flush could be deleted with the suite still green. Untestable\n // defensive code is worse than no window at all.)\n let sseController!: ReadableStreamDefaultController<Uint8Array>;\n const sseEncoder = new TextEncoder();\n const stream = new ReadableStream<Uint8Array>({\n start(c) {\n sseController = c;\n },\n });\n sseEnqueue = (chunk) => {\n // Same exposure as the close below: a frame written after the client\n // left has nowhere to go, and saying so by throwing would kill the\n // process rather than the request.\n try {\n sseController.enqueue(sseEncoder.encode(chunk));\n } catch {\n // The reader is gone. The handler's own signal is what stops it.\n }\n };\n\n let sawFirstFrame!: () => void, refuseFirstFrame!: (error: unknown) => void;\n const firstFrame = new Promise<void>((resolve, reject) => { sawFirstFrame = resolve; refuseFirstFrame = reject; });\n\n // THE FIRST FRAME ENDS THE REQUEST PHASE.\n //\n // The handler runs inside the request's transaction, and a stream may\n // live for minutes. Holding a transaction that long exhausts the\n // connection pool — a failure no unit test sees, that appears only under\n // load, and that looks like \"the database is slow\" when it arrives. So\n // the transaction settles HERE, in the hook the writer awaits before it\n // emits anything: the ordering is structural, not a happy accident of\n // microtask scheduling.\n sseSettle = async () => {\n try { await db.commit(); sawFirstFrame(); }\n catch (error) { refuseFirstFrame(error); throw error; }\n };\n\n // …and afterwards the database is refused BY NAME. The alternative is a\n // settled transaction quietly answering a query, which is a correctness\n // bug the author would never find. The message says what happened and\n // what to do instead.\n const guarded: RuntimeServices = {\n ...services,\n Database: new Proxy(services.Database as object, {\n get(target, prop, recv) {\n // `started()` flips SYNCHRONOUSLY inside `write()`, which is the\n // only reading that works: `write` returns immediately, so a\n // handler's next line runs before the commit has finished. The\n // author's own call is the boundary, not the commit's completion.\n if (sseWriter.started()) {\n throw new Error(\n `sse_db_after_write: ${hit.entry.id} touched the database after its ` +\n `first write(). A streaming response settles its transaction with the ` +\n `first frame — do the database work before the first write.`,\n );\n }\n return Reflect.get(target, prop, recv);\n },\n }) as RuntimeServices[\"Database\"],\n };\n\n let thrown: unknown = null;\n const ran = Promise.resolve(runWithRuntime(guarded, () => {\n const box = requestALS.getStore();\n if (box) {\n box.userId = userId ?? null;\n box.requestId = requestId;\n box.idempotencyKey = req.headers.get(\"idempotency-key\");\n }\n const method = hit.entry.instance[meta.fnName];\n if (typeof method !== \"function\") {\n throw new Error(\n `route ${hit.entry.id} names method ${meta.fnName}, which the controller does not define`,\n );\n }\n return method.apply(hit.entry.instance, args);\n })).then(\n () => undefined,\n (err: unknown) => {\n thrown = err;\n },\n );\n\n await Promise.race([firstFrame, ran]);\n\n if (!sseWriter.started()) {\n // Nothing was ever written. The handler either finished silently or\n // threw before its first frame — either way the response shape is\n // still a free choice, so it gets the ordinary one.\n await ran;\n await db.commit();\n if (thrown !== null) throw thrown;\n return new Response(null, { status: 204 });\n }\n\n // A synchronous handler can finish before its queued first write.\n // Do not send HTTP 200 until that write's COMMIT has actually settled.\n await firstFrame;\n void (async () => {\n await ran;\n await sseWriter.drained();\n // THE CLIENT LEAVING IS A NORMAL ENDING, NOT AN ERROR.\n //\n // When the client disconnects the runtime closes this controller\n // itself, so the terminal write and close below arrive at a stream\n // that is already gone. Left unguarded they throw\n // `ERR_INVALID_STATE: Controller is already closed` from inside a\n // detached async task — which is an unhandled rejection, and under Bun\n // that KILLS THE SERVER PROCESS. One user closing a tab would take the\n // backend down with them.\n //\n // Measured 2026-08-29 against real OpenAI: curl was killed mid-stream\n // and the process exited with code 1 at this line. No unit test could\n // have caught it — in a test the client never disconnects at the\n // transport layer, so the controller is always still open here.\n try {\n if (thrown !== null) {\n log.error(`[engine] ${hit.entry.id} threw mid-stream`, thrown);\n sseController.enqueue(sseEncoder.encode(encodeErrorFrame(requestId)));\n }\n sseController.close();\n } catch {\n // Already closed: the client is gone and there is nobody to tell.\n }\n })();\n return new Response(stream, {\n status: 200,\n headers: { \"content-type\": SSE_CONTENT_TYPE, \"cache-control\": \"no-cache\" },\n });\n }\n\n const result = await runWithRuntime(services, () => {\n // The ALS box carries the caller's identity beside the services; Flags'\n // auto-bind reads it, and so does anything else that needs a\n // server-owned user id rather than one the caller supplied.\n const box = requestALS.getStore();\n if (box) {\n box.userId = userId ?? null;\n box.requestId = requestId;\n box.idempotencyKey = req.headers.get(\"idempotency-key\");\n }\n const method = hit.entry.instance[meta.fnName];\n if (typeof method !== \"function\") {\n throw new Error(\n `route ${hit.entry.id} names method ${meta.fnName}, which the controller does not define`,\n );\n }\n return method.apply(hit.entry.instance, args);\n });\n if (meta.returnSchema) {\n const v = meta.returnSchema.safeParse(result);\n if (!v.success) {\n log.error(`[engine] ${hit.entry.id} returned a value its declared type rejects`, v.error.issues);\n await db.rollback(new Error(\"output_invalid\"));\n return envelope(\n \"output_invalid\",\n \"The handler returned a value its declared return type rejects\",\n 500,\n requestId,\n );\n }\n }\n if (result === undefined || result === null && !meta.returnSchema) {\n await db.commit();\n if (completionUploadId) {\n completions.remember(completionUploadId, { status: 204, body: null, contentType: null });\n }\n return new Response(null, { status: 204 });\n }\n const payload = JSON.stringify(result);\n await db.commit();\n if (completionUploadId) {\n completions.remember(completionUploadId, {\n status: 200,\n body: payload,\n contentType: JSON_HEADERS[\"content-type\"] ?? \"application/json\",\n });\n }\n return new Response(payload, {\n status: 200,\n headers: attestChallengeOut\n ? { ...JSON_HEADERS, \"x-palbase-attest-challenge\": attestChallengeOut }\n : JSON_HEADERS,\n });\n } catch (err) {\n // This includes errors in authorization and parameter injection.\n await db.rollback(err);\n // Branded, not `instanceof`: the tenant's bundle carries its own copy of\n // this SDK, so class identity does not survive the hop from the handler\n // to this catch. See HTTP_ERROR_BRAND.\n return errorResponse(err, hit.entry.id, requestId);\n }\n }\n\n // The author's own long-lived resources come up HERE: after the pool has been\n // proven (`select 1` above) and before anything can be served. A hook that\n // throws REFUSES THE BOOT — an app that answers with a half-open resource\n // behind it is the silence `onStart` exists to replace — and the pool this\n // function opened is closed on the way out, because nobody will ever get the\n // `shutdown` below to close it.\n // START HOOKS RUN IN A SCOPE — a BOOT one, not a request one.\n //\n // A start hook is where a long-lived resource comes up, and the credential\n // that resource needs lives in the vault. `Secrets.get()` threw \"outside a\n // request scope\" here, so the one place an author is TOLD to open a pool could\n // not read the password for it (D-19).\n //\n // Everything that is genuinely boot-level — Secrets, Cache, Log, the module\n // clients — is handed over. `Database` is NOT, and refuses BY NAME: a start\n // hook runs before anything is served, so there is no request and no\n // transaction for a query to belong to. Handing out a real one would open a\n // transaction on the boot path that nobody closes; saying so is the honest\n // answer and the one an author can act on.\n const bootServices = buildServices(null);\n\n let runShutdownHooks: ShutdownRunner;\n try {\n runShutdownHooks = await runWithRuntime(bootServices, () => __runStartHooks());\n } catch (err) {\n await closeDriver(sql);\n throw err;\n }\n\n return {\n handle: req => !accepting\n ? Promise.resolve(envelope(\"runtime_draining\", \"This application is shutting down\", 503, `req_${crypto.randomUUID()}`))\n : serving(() => handle(req)),\n get databasePressure() { return admission.snapshot; },\n routes,\n config,\n container: liveContainer,\n runInServiceScope: fn => !accepting\n ? Promise.reject(new Error(\"This application is shutting down; no new database scope can start\"))\n : serving(() => runInServiceScope(fn)),\n shutdown() {\n accepting = false;\n return shuttingDown ??= (async () => {\n // A release may share its physical pool with its successor. Wait for\n // this app's HTTP/jobs (including COMMIT/ROLLBACK) before closing its\n // resources; closing the shared pool is no longer a drain mechanism.\n while (inFlight.size) await Promise.allSettled([...inFlight]);\n // The author's resource is released BEFORE the pool: a driver standing on\n // this pool cannot close after the pool is gone.\n await runShutdownHooks();\n await closeDriver(sql);\n // The container goes with the app. It holds one instance of every class\n // this app owns, and those instances hold whatever their constructors\n // captured — an app that shut down must not keep them reachable through\n // a handle someone still has.\n released = true;\n })();\n },\n };\n}\n\n/** Let go of the driver — `close` or `end`, whichever it carries. */\nasync function closeDriver(sql: SqlDriver): Promise<void> {\n const closable = sql as { close?: () => Promise<void> | void; end?: () => Promise<void> | void };\n await closable.close?.();\n await closable.end?.();\n}\n","/**\n * runtime.ts — request-scoped service singletons.\n *\n * The backend SDK no longer threads a `ctx` god-object through every handler.\n * Instead, controller methods import PascalCase service singletons directly:\n *\n * import { Controller, Post, Body, Database } from \"@palbase/backend\";\n *\n * \\@Controller(\"/todos\")\n * export default class TodosController {\n * \\@Post(\"\") create(\\@Body(CreateTodoBody) body: CreateTodoBody): unknown {\n * return Database.public.todos.insert({ title: body.title });\n * }\n * }\n *\n * The singletons are thin Proxies. Every property access forwards to the live\n * client for the CURRENT request scope, resolved through {@link __getRuntime}.\n *\n * # Request-scope resolution (persistent app-server)\n *\n * The runtime is a long-running Node process that serves many concurrent\n * requests on one event loop (NOT a fresh subprocess per request). A single\n * module-global slot would let one in-flight request's services bleed into\n * another's. So the services are carried in an {@link AsyncLocalStorage} store\n * ({@link __requestALS}) that the runtime sets per request with\n * {@link __runWithRuntime}; every async continuation of that request reads its\n * own store. `__getRuntime` reads the ALS store first; the module-global slot\n * (set by {@link __setRuntime}) is only a fallback for callers that run OUTSIDE\n * an ALS scope (dev-server, unit tests, the legacy single-shot path). Because\n * each `br-<ref>` pod is single-tenant, there is no cross-tenant leakage; the\n * ALS store is what prevents cross-REQUEST leakage within the shared process.\n *\n * The seam that makes `import { Database } from \"@palbase/backend\"` resolve to\n * the runtime-injected client: `@palbase/backend` is marked esbuild-EXTERNAL\n * when the tenant bundle is built, and the package is installed globally in the\n * pod (NODE_PATH=/usr/local/lib/node_modules). So worker.js's\n * `require('@palbase/backend')` and the bundle's `import` resolve to ONE shared\n * module instance — the ALS store and `__setRuntime` slot on that instance are\n * visible to the singletons the bundle imported.\n */\n\nimport type { PalbaseFlagKey } from \"./stack.js\";\nimport type { Buckets, BucketTypes, Schemas } from \"./db/env.js\";\nimport { AsyncLocalStorage } from \"node:async_hooks\";\n\nimport type {\n DBClient,\n AtomicClient,\n DBOps,\n CacheClient,\n Logger,\n PalbaseDocsClient,\n SecretsService,\n} from \"./endpoint.js\";\nimport type {\n PalbaseAuthAdminClient,\n PalbaseStorageClient,\n PalbaseBucketClient,\n PalbaseNotificationsClient,\n PalbaseFlagsClient,\n PalbaseFlagsServiceClient,\n PalbaseFlagContext,\n PalbaseFlagVariant,\n PalbaseFlag,\n PalbaseFlagValue,\n PalbaseSetOverrideResult,\n PalbaseRealtimeClient,\n} from \"./clients.js\";\nimport type { PalbaseResult } from \"./endpoint.js\";\nimport type {\n EnvTypedDatabase,\n EnvServiceDatabase,\n AtomicDatabase,\n EnvTables,\n TxPlan,\n TxTables,\n} from \"./db/typed-db.js\";\nimport type { Materialized } from \"./db/tx-plan.js\";\nimport { TxPlanBuilder, runTxPlan } from \"./db/tx-plan.js\";\nimport { assertPlanRetry, type AtomicOptions } from \"./db/transaction-options.js\";\nimport { qualifiedTableKey } from \"./db/schema-json.js\";\nimport type { DollarOps } from \"./db/typed-db.js\";\n\n/** The set of live clients the runtime injects per request scope.\n *\n * Realtime is BROADCAST-ONLY here (a stateless handler can push an event but\n * cannot hold a subscription socket — `subscribe()` lives on the client SDK).\n *\n * EXCLUDED on purpose: Functions, Links, Analytics. They are not exposed as\n * backend handler singletons — out of scope for backend endpoints. `Auth` is\n * here in its ROLE-ASSIGNMENT shape only: signing in is the client SDK's job,\n * but granting a role is an operator verb the tenant's own handler needs\n * (FR-009). */\nexport interface RuntimeServices {\n Database: DBClient;\n Auth: PalbaseAuthAdminClient;\n Secrets: SecretsService;\n Documents: PalbaseDocsClient;\n Storage: PalbaseStorageClient;\n Cache: CacheClient;\n Log: Logger;\n Notifications: PalbaseNotificationsClient;\n Flags: PalbaseFlagsClient;\n Realtime: PalbaseRealtimeClient;\n}\n\n/**\n * The per-request ALS box.\n *\n * `runtime` is the service bundle. `userId` is the request's authenticated user\n * id, written by the runtime immediately after it assembles the request object\n * (worker.js: `requestALS.getStore().userId = pbReq.user?.id || null`) and\n * `null` on an anonymous request. It was already being written there for the\n * Flags client's auto-bind; declaring it here makes the existing contract typed\n * instead of implicit, which is what lets `currentSubjectId()` read a\n * server-owned identity rather than trusting anything the caller sent.\n */\nexport interface RequestStore {\n runtime: RuntimeServices;\n userId?: string | null;\n /** This request's id (`req_…`), written by the runtime. Used as the spend\n * idempotency scope when the caller supplied no `Idempotency-Key`. */\n requestId?: string;\n /** The caller's `Idempotency-Key` header, or `null` when absent. What makes a\n * client's retry replay its first result instead of charging twice. */\n idempotencyKey?: string | null;\n}\n\n/**\n * Per-request store. The persistent runtime runs each request inside\n * {@link __runWithRuntime}, so every async continuation of that request reads\n * its OWN `runtime` (and any other request-scoped fields the runtime adds).\n *\n * Exported with a `__` prefix so the runtime (worker.js) shares the SAME ALS\n * instance across the one module instance — two ALS instances would silently\n * not see each other's stores. NOT part of the public author-facing API.\n */\n/**\n * The per-request store — ON globalThis under a well-known Symbol, for the same\n * reason `lifecycleHooks` and the controller registry are.\n *\n * MEASURED, through the production package gate: `tsup` emits `dist/index.cjs`\n * and `dist/test/index.cjs` as SEPARATE bundles and each inlines this module.\n * With a module-local `AsyncLocalStorage`, `withServices` (which ships from the\n * `/test` subpath) opened a scope in ITS copy while the `Database` singleton\n * (which ships from the root) read the OTHER copy's — and the ambient service a\n * test had just installed was invisible:\n *\n * Error: Palbase services accessed outside a request scope.\n *\n * The unit tests could not see it: inside the package there is only ever one\n * copy. It took calling the built artifact the way a consumer does. Same class\n * as the defect `@Module`'s slot comment describes — two module-local values\n * where the two halves of one contract must agree.\n *\n * SÜRÜMSÜZ, VE BU BİLİNÇLİ. Anahtar `…requestALS@32` gibi sürümlenseydi iki\n * major aynı süreçte ALS'i paylaşmayı BIRAKIRDI — yani yukarıda anlatılan kusur\n * sürüm sınırında geri gelirdi. Bedeli de gerçek ve burada yazılı:\n * `RequestStore.runtime` zorunlu bir `RuntimeServices` ve o küme büyüyor\n * (30.0.0 `Auth` ile 9→10). Eski bir majorün yazdığı kutuyu yeni bir major\n * okursa yeni alan `undefined` gelir.\n *\n * Bu pakette YEDİ well-known Symbol var ve hepsi sürümsüz (`httpError`,\n * `engineRaised`, `channels`, `errorRegistry`, `declarationRefusal`,\n * `lifecycleHooks`, ve bu). Yalnız BİRİNİ sürümlemek tutarsızlıktan başka bir\n * şey üretmez: karar paket geneli olmalı ve `RequestStore`'un şekil\n * sözleşmesiyle birlikte alınmalı (sapma defteri D-05).\n */\nconst REQUEST_ALS: unique symbol = Symbol.for(\"palbase.backend.requestALS\") as never;\n\nexport const __requestALS: AsyncLocalStorage<RequestStore> = ((): AsyncLocalStorage<RequestStore> => {\n const g = globalThis as unknown as Record<symbol, AsyncLocalStorage<RequestStore> | undefined>;\n return (g[REQUEST_ALS] ??= new AsyncLocalStorage<RequestStore>());\n})();\n\n/** Process-global fallback slot. Used only OUTSIDE an ALS scope (dev-server,\n * unit tests, legacy single-shot worker). Inside the persistent server every\n * request runs in {@link __requestALS}, which takes precedence. */\nlet runtime: RuntimeServices | null = null;\n\n/** Install the live clients in the process-global fallback slot.\n *\n * Persistent-server requests should use {@link __runWithRuntime} instead; this\n * remains for dev-server / tests / the legacy single-shot path that run without\n * an ALS scope. NOT part of the public author-facing API. */\nexport function __setRuntime(services: RuntimeServices): void {\n runtime = services;\n}\n\n/** Run `fn` with `services` bound as the request-scoped runtime.\n *\n * The persistent worker calls this once per request so concurrent requests\n * never share a services slot. NOT part of the public author-facing API. */\nexport function __runWithRuntime<T>(services: RuntimeServices, fn: () => T): T {\n return __requestALS.run({ runtime: services }, fn);\n}\n\n/** Read the live clients, throwing if accessed outside a request scope.\n *\n * Resolves the ALS store first (persistent server, per-request), then the\n * process-global fallback (dev-server / tests). NOT part of the public\n * author-facing API — used by the runtime and the singleton Proxies. */\n/**\n * Bir kutunun TAŞIMASI GEREKEN servisler.\n *\n * `withServices`'in listesiyle aynı gerçeği söylüyor ama BURADA yaşamak\n * zorunda: `test/` yalnız test yüzeyinde, bu kontrol ise her isteğin yolunda.\n * İkisi de `satisfies` ile `RuntimeServices`'a pinli, yani biri eksik kalırsa\n * derleme durur.\n */\nconst REQUIRED_SERVICES = [\n \"Database\",\n \"Auth\",\n \"Secrets\",\n \"Documents\",\n \"Storage\",\n \"Cache\",\n \"Log\",\n \"Notifications\",\n \"Flags\",\n \"Realtime\",\n] as const satisfies readonly (keyof RuntimeServices)[];\n\n/**\n * ÇAPRAZ-MAJOR KUTUYU ADIYLA REDDET (sapma defteri D-05).\n *\n * `__requestALS` sürümSÜZ bir `Symbol.for` altında ve bu bilinçli: iki bundle\n * (`dist/index.cjs` ve `dist/test/index.cjs`) ambient kapsamı ancak öyle\n * paylaşır. Bedeli de gerçek — tek süreçte iki major varsa ESKİ olanın yazdığı\n * kutuyu YENİ olan okur, ve servis kümesi büyümüşse (30.0.0'da 9→10, `Auth`)\n * yeni alan `undefined` gelir.\n *\n * `undefined` bir servis, erişildiğinde `Reflect.get called on non-object`\n * verir: ne eksik olanın adı, ne sebebi. Bu kontrol o sessizliği bir cümleye\n * çevirir. Maliyeti istek başına on `in` kontrolü.\n */\nfunction refuseIncompleteBox(services: RuntimeServices): RuntimeServices {\n const missing = REQUIRED_SERVICES.filter((k) => services[k] === undefined);\n if (missing.length > 0) {\n throw new Error(\n `the request scope is missing ${missing.join(\", \")} — this box was most likely written by a ` +\n `DIFFERENT @palbase/backend major sharing the same process (the request store is a ` +\n `process-wide well-known Symbol, deliberately, so two bundles of ONE version can share it). ` +\n `Align the versions, or pass every service when building the scope yourself.`,\n );\n }\n return services;\n}\n\nexport function __getRuntime(): RuntimeServices {\n const scoped = __requestALS.getStore();\n if (scoped) return refuseIncompleteBox(scoped.runtime);\n if (runtime === null) {\n throw new Error(\n \"Palbase services accessed outside a request scope. The Database/Documents/… \" +\n \"singletons are only available inside an endpoint handler (or after the \" +\n \"runtime has called __runWithRuntime / __setRuntime).\",\n );\n }\n return runtime;\n}\n\n// ─── lifecycle: where a long-lived resource lives (FR-013) ─────────────────\n//\n// `Resource` was removed in 23.0.0 and nothing replaced the LIFECYCLE half of\n// it. What that left behind is measurable: a connection pool (the driver in\n// `docs/resources.md`'s own example was Neo4j) had no documented place to be\n// opened and NO WAY AT ALL to be closed, so every deploy left the pool it\n// opened behind. These two hooks are that half — and only that half. The\n// secret-distribution half does not come back: a handler reads `Secrets.get`,\n// and a start hook, which runs before any request scope exists, reads the\n// `process.env` the runtime mirrors the vault into at boot.\n\n/** A lifecycle hook. Sync or async; the runtime awaits what it returns. */\nexport type LifecycleHook = () => void | Promise<void>;\n\n/** Runs one release's shutdown hooks. Handed back by {@link __runStartHooks}\n * and called by the engine's `app.shutdown()`. Idempotent. */\nexport type ShutdownRunner = () => Promise<void>;\n\ninterface DeclaredHook {\n name: string;\n run: LifecycleHook;\n}\n\ninterface DeclaredLifecycle {\n start: DeclaredHook[];\n shutdown: DeclaredHook[];\n}\n\n/**\n * What has been DECLARED and not yet claimed by an app.\n *\n * On globalThis under a well-known Symbol for the reason the controller\n * registry is (`decorators/controller.ts`): a deployed bundle inlines its own\n * copy of this package, and the engine that has to RUN these hooks holds the\n * other copy. Two module-local arrays would mean the engine reads the empty one\n * and every declared hook is silently never run — which is exactly how\n * `Resource`'s `init(env)` died.\n */\nconst LIFECYCLE: unique symbol = Symbol.for(\"palbase.backend.lifecycleHooks\") as never;\n\nfunction declaredLifecycle(): DeclaredLifecycle {\n const g = globalThis as unknown as Record<symbol, DeclaredLifecycle | undefined>;\n return (g[LIFECYCLE] ??= { start: [], shutdown: [] });\n}\n\n/**\n * Run `hook` ONCE while the application comes up, before it serves anything.\n *\n * Call it at MODULE SCOPE in a file the application imports — the same rule\n * `defineDefaultAuth` and `@Controller` follow, and for the same reason: the\n * declaration is claimed when the app boots, which is after module loading and\n * before the first request. `name` is not decoration: a hook that throws is\n * reported by that name and the boot is REFUSED, so it is what tells an\n * operator which resource did not come up.\n *\n * There is no request scope yet, so the `Database`/`Secrets`/… singletons are\n * NOT available inside a start hook. A secret is read from `process.env` here\n * (the runtime mirrors the vault into it at boot).\n *\n * @example\n * // resources/graph.ts\n * import neo4j from \"neo4j-driver\";\n * import { onStart, onShutdown } from \"@palbase/backend\";\n *\n * export let graph: Driver;\n * onStart(\"graph\", () => {\n * graph = neo4j.driver(process.env.NEO4J_URL!, neo4j.auth.basic(\"neo4j\", process.env.NEO4J_PASSWORD!));\n * });\n * onShutdown(\"graph\", () => graph.close());\n */\nexport function onStart(name: string, hook: LifecycleHook): void {\n declaredLifecycle().start.push({ name, run: hook });\n}\n\n/**\n * Run `hook` while the application shuts down — the place a pool opened in\n * {@link onStart} is closed.\n *\n * Shutdown is BEST-EFFORT by design: a hook that throws is reported by name and\n * the rest still run. A drain that abandoned the remaining hooks on the first\n * failure would leak exactly what this exists to release, and the process is\n * leaving anyway.\n *\n * Hooks run in REVERSE declaration order, so a resource is released before what\n * it was built on.\n */\nexport function onShutdown(name: string, hook: LifecycleHook): void {\n declaredLifecycle().shutdown.push({ name, run: hook });\n}\n\nfunction reason(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n\n/** Best-effort drain: every hook runs, a failure is reported, none is silent. */\nasync function drain(hooks: DeclaredHook[]): Promise<void> {\n for (const h of [...hooks].reverse()) {\n try {\n await h.run();\n } catch (err) {\n console.error(`[palbase] shutdown hook \"${h.name}\" failed: ${reason(err)}`, err);\n }\n }\n}\n\n/**\n * CLAIM what has been declared, run the start hooks, and hand back the runner\n * for this release's shutdown hooks. Called by the engine's `createApp`; the\n * `App.shutdown()` it builds calls what comes back. NOT part of the public\n * author-facing API.\n *\n * IT CLAIMS RATHER THAN READS, which is what makes it correct in this runtime:\n * a candidate release is loaded BESIDE the live one in one process\n * (`v2/runtime/src/registry-scope.ts`), and both bundles append to the one\n * shared slot above. If each app read the whole list, the live app's shutdown\n * would close the candidate's pool and the candidate's would close the live\n * app's. Taking the declarations leaves each app holding exactly its own.\n *\n * A start hook that throws REFUSES THE BOOT — with the hook's name in the\n * message — after releasing whatever the earlier hooks already opened. Serving\n * from a half-initialised app is the silence this whole surface replaces, and a\n * boot that dies holding an open pool is the leak it replaces.\n */\nexport async function __runStartHooks(): Promise<ShutdownRunner> {\n const slot = declaredLifecycle();\n const start = slot.start.splice(0);\n const shutdown = slot.shutdown.splice(0);\n\n for (const h of start) {\n try {\n await h.run();\n } catch (err) {\n await drain(shutdown);\n throw new Error(`[palbase] start hook \"${h.name}\" failed: ${reason(err)}`, { cause: err });\n }\n }\n\n let drained = false;\n return async () => {\n // SIGTERM racing a redeploy asks twice; a pool is closed once.\n if (drained) return;\n drained = true;\n await drain(shutdown);\n };\n}\n\n/** Drop every declaration. For tests, which declare repeatedly in one process.\n * NOT part of the public author-facing API. */\nexport function __resetLifecycleHooks(): void {\n const g = globalThis as unknown as Record<symbol, DeclaredLifecycle | undefined>;\n delete g[LIFECYCLE];\n}\n\n/**\n * Build a Proxy singleton that forwards every property access to the live\n * client named `key` on the current runtime.\n *\n * The single `as RuntimeServices[K]` is the only contained cast in the surface:\n * `Reflect.get` on a typed object returns `unknown` for a `string | symbol`\n * key, but `prop` is constrained to keys of the client interface at the call\n * sites (the exported singletons are typed below), so the forward is sound.\n */\nfunction makeServiceProxy<K extends keyof RuntimeServices>(key: K): RuntimeServices[K] {\n const handler: ProxyHandler<RuntimeServices[K]> = {\n get(_target, prop, receiver) {\n const client = __getRuntime()[key];\n const value = Reflect.get(client as object, prop, receiver) as unknown;\n // Bind methods to their owning client so `this` stays correct when the\n // author destructures or calls `Database.query(...)`.\n return typeof value === \"function\" ? value.bind(client) : value;\n },\n };\n // The Proxy target is irrelevant (all access goes through `get`); the cast\n // names the surface type the singleton presents to authors.\n return new Proxy({} as RuntimeServices[K], handler);\n}\n\n/**\n * Build the `.tables` accessor for the top-level `Database`. Each\n * `tables.<name>` access returns a small object that forwards the five CRUD ops\n * to the underlying client using `name` as the string table identifier. The\n * shapes are typed against the generated `palbase-env.d.ts` (`EnvTables`); at\n * runtime they are plain string-keyed calls, so no schema value is needed here.\n *\n * Returns `EnvTables` — TS cannot infer the mapped type through the Proxy, so\n * a single structural narrowing names the surface (the proxy returns a\n * correctly-shaped accessor for whatever string member is read).\n */\n/** T018 (C-8): similar/recommend'in string-keyed yüzü. DBOps'a (endpoint.ts)\n * BİLEREK eklenmedi — search-param imza üçlüsü (engine/db + typed-db +\n * endpoint) büyümesin: proxy dispatch runtime'da engine ops'una zaten ulaşır,\n * derleme güvenliğini typed yüzey (EnvTypedTable) verir. */\nexport interface RecoOps {\n similar(table: string, id: string, params?: Record<string, unknown>): Promise<Record<string, unknown>[]>;\n recommend(table: string, params: Record<string, unknown>): Promise<Record<string, unknown>[]>;\n}\n\n/**\n * The Proxy behind EVERY `.tables` map — public's and every other schema's.\n *\n * `prefix` is what the wire name is built from: `\"\"` for `public`, so its tables\n * stay BARE, and `\"<schema>.\"` for any other, so `schema(\"billing\").tables\n * .invoices` reaches the broker as `billing.invoices` (D-10 — the same\n * schema-qualified key `toSchemaJSON` and the generated `relations` use).\n *\n * One trap for both surfaces: two copies would be two op lists that can drift,\n * and the one that forgets an op does not complain — it answers `undefined`.\n */\nfunction makeTableProxy(ops: () => DBOps & RecoOps, prefix: string): object {\n return new Proxy(\n {},\n {\n get(_t, prop: string | symbol) {\n if (typeof prop !== \"string\") return undefined;\n const name = `${prefix}${prop}`;\n return {\n insert: (data: Record<string, unknown>) => ops().insert(name, data),\n // DÖRDÜNCÜ FİİL, aynı gerekçeyle: tip söz veriyor, ops katmanı\n // uyguluyor, ve bir handler'ın gerçekten dokunduğu yer BURASI.\n // `runtime-table-verbs` kapısı bunu adıyla saydı.\n aggregate: (q: Parameters<DBOps[\"aggregate\"]>[1]) => ops().aggregate(name, q),\n insertMany: (\n rows: readonly Record<string, unknown>[],\n opts?: import(\"./db/bulk.js\").InsertManyOptions,\n ) => ops().insertMany(name, rows, opts),\n update: (q: { where: { id: string }; set: Record<string, unknown> }) =>\n ops().update(name, q.where.id, q.set),\n delete: (id: string) => ops().delete(name, id),\n findById: (id: string) => ops().findById(name, id),\n findUnique: (q: { where: Record<string, unknown>; select?: readonly string[]; with?: Record<string, unknown> }) =>\n ops().findUnique(name, q.where, { select: q.select, with: q.with }),\n page: (q?: Record<string, unknown>) => {\n const { where, ...opts } = q ?? {};\n return ops().page(name, where as Record<string, unknown> | undefined, opts as import(\"./db/page.js\").RawPageOptions);\n },\n findMany: (q?: Record<string, unknown>) => {\n // `where` AYIKLANIR; kalan alanlar (orderBy/limit/offset) ham op'un\n // ikinci parametresine gider. Tümünü geçirmek `where`'i tel üstünde\n // ikinci kez gönderirdi — `typed-db.test.ts` bunu yakalıyor.\n const { where, ...opts } = q ?? {};\n return ops().findMany(\n name,\n where as Record<string, unknown> | undefined,\n opts as Parameters<DBOps[\"findMany\"]>[2],\n );\n },\n put: (q: { data: Record<string, unknown>; onConflict: readonly string[] }) =>\n ops().put(name, q.data, { onConflict: q.onConflict }),\n // THREE VERBS THE TYPE PROMISED AND THIS PROXY DID NOT EMIT.\n //\n // `EnvTypedTableBase` declares `updateMany`, `deleteMany` and `count`\n // (typed-db.ts) and the ops layer implements all three — only this\n // proxy, which is what a handler actually touches, left them out. So\n // the type said the verb exists, autocomplete offered it, and the call\n // answered `undefined is not a function`.\n //\n // Older than this run, but the run rewrote this proxy for\n // `Database.schema(name).tables.*` and would have carried the gap onto\n // the new surface too.\n updateMany: (q: { where: Record<string, unknown>; set: Record<string, unknown>; returning?: boolean }) =>\n ops().updateMany(name, q.where, q.set, q.returning === undefined ? undefined : { returning: q.returning }),\n deleteMany: (q: { where: Record<string, unknown> }) => ops().deleteMany(name, q.where),\n count: (q?: { where?: Record<string, unknown> }) => ops().count(name, q?.where),\n search: (params?: Record<string, unknown>) => ops().search(name, params),\n similar: (id: string, params?: Record<string, unknown>) => ops().similar(name, id, params),\n recommend: (params: Record<string, unknown>) => ops().recommend(name, params),\n facets: (params: { facets: string[] } & Record<string, unknown>) => ops().facets(name, params),\n supersede: (id: string, row: Record<string, unknown>) => ops().supersede(name, id, row),\n claim: (unique: Record<string, unknown>, extra?: Record<string, unknown>) =>\n ops().claim(name, unique, extra),\n };\n },\n },\n );\n}\n\n\n/** The raw string-keyed `DBClient` for the current request scope. */\nconst rawDatabase: DBClient = makeServiceProxy(\"Database\");\n\n/**\n * Wrap a raw `DBClient` into the typed `{ ...ops, tables, transaction }`\n * surface. The five string ops forward straight through; `tables` is the\n * env-typed accessor; `transaction` yields typed tables. Reused for both the\n * default (RLS-enforced) `Database` and the `asService()` sibling — each is\n * fed its own raw client (the default proxy vs `rawDatabase.asService()`).\n *\n * The `satisfies` pins the op surface so a missing/renamed op is a compile\n * error; the assembled object carries `tables`/`transaction` alongside.\n */\n/**\n * PACKAGE-INTERNAL, and deliberately NOT re-exported from `index.ts`.\n *\n * `test/fake-db.ts` builds the fake's surface with the SAME constructor\n * production uses, so the two cannot drift: the day a `$op` is added here, the\n * fake grows it in the same commit. Exporting it from the public index instead\n * would put a runtime-assembly detail on the author-facing API (FR-006).\n */\nexport function makeTypedSurface(raw: AtomicClient & Partial<Pick<DBClient, \"atomic\">>): EnvServiceDatabase {\n // Proxy dispatch her üyeyi taşır; RecoOps tipi DBClient'a eklenmediğinden\n // (yukarıdaki karar) similar/recommend erişimi bu daraltmadan geçer.\n const reco = raw as Omit<DBClient, \"asService\"> & RecoOps;\n // `$` ÖNEKİ AÇIKÇA YAZILIR, dinamik üretilmez.\n //\n // Bir tur `Object.fromEntries(Object.entries(ops).map(…))` ile üretilmişti ve\n // `database.test.ts`'in sayımı onu göremedi: sayım DEKLARASYONLARI okuyor,\n // string literal'leri değil. Görünmeyen bir yüzey denetlenemez — ve o testin\n // varlık sebebi tam olarak budur (FR-044: yüzeyde bağlantı bilgisi olmadığını\n // kanıtlamak, ama önce yüzeye gerçekten ULAŞTIĞINI kanıtlamak).\n const ops = {\n $query: (sql: string, params?: unknown[]) => raw.query(sql, params),\n $diagnostics: () => raw.diagnostics(),\n $insert: (table: string, data: Record<string, unknown>) => raw.insert(table, data),\n $update: (table: string, id: string, data: Record<string, unknown>) =>\n raw.update(table, id, data),\n $delete: (table: string, id: string) => raw.delete(table, id),\n $findById: (table: string, id: string) => raw.findById(table, id),\n $findUnique: (table: string, where: Record<string, unknown>, opts?: Parameters<DBOps[\"findUnique\"]>[2]) => raw.findUnique(table, where, opts),\n $page: (table: string, query?: Record<string, unknown>, opts?: import(\"./db/page.js\").RawPageOptions) => raw.page(table, query, opts),\n $findMany: (table: string, query?: Record<string, unknown>, opts?: Parameters<DBOps[\"findMany\"]>[2]) =>\n raw.findMany(table, query, opts),\n $put: (table: string, data: Record<string, unknown>, opts: { onConflict: readonly string[] }) =>\n raw.put(table, data, opts),\n // `opts` İLETİLİR. Düşürüldüğü sürece `Database.$updateMany(t, w, s,\n // { returning: false })` sessizce SATIRLARI döndürüyordu, sayıyı değil —\n // ve `if (n === 0) throw new Conflict(...)` guard'ı HİÇ çalışmıyordu,\n // çünkü `[] === 0` yanlıştır. Komşu forwarder'lar (`$findMany`, `$put`)\n // kendi opsiyonlarını zaten iletiyordu; bu biri unutulmuştu.\n $updateMany: (\n table: string,\n where: Record<string, unknown>,\n set: Record<string, unknown>,\n opts?: Parameters<DBOps[\"updateMany\"]>[3],\n ) => raw.updateMany(table, where, set, opts),\n $deleteMany: (table: string, where: Record<string, unknown>) => raw.deleteMany(table, where),\n $count: (table: string, where?: Record<string, unknown>) => raw.count(table, where),\n $search: (table: string, params?: Record<string, unknown>) => raw.search(table, params),\n $similar: (table: string, id: string, params?: Record<string, unknown>) =>\n reco.similar(table, id, params),\n $recommend: (table: string, params: Record<string, unknown>) => reco.recommend(table, params),\n $facets: (table: string, params: { facets: string[] } & Record<string, unknown>) => reco.facets(table, params),\n $claim: (table: string, unique: Record<string, unknown>, extra?: Record<string, unknown>) =>\n reco.claim(table, unique, extra),\n $lockRows: (table: string, ids: readonly string[]) => reco.lockRows(table, ids),\n $advisoryXactLock: (key: string) => reco.advisoryXactLock(key),\n $aggregate: (table: string, q: Parameters<DBOps[\"aggregate\"]>[1]) => raw.aggregate(table, q),\n $insertMany: ((\n table: string,\n rows: readonly Record<string, unknown>[],\n opts?: import(\"./db/bulk.js\").InsertManyOptions,\n ) => raw.insertMany(table, rows, opts)) as DBOps[\"insertMany\"],\n $supersede: (table: string, id: string, row: Record<string, unknown>) =>\n raw.supersede(table, id, row),\n } satisfies DollarOps<Omit<DBOps & RecoOps, \"attempt\">>;\n // `ops` DOĞRUDAN verilir, spread edilmez: sayım (`database.test.ts`) nesneyi\n // deklarasyonundan takip ediyor ve bir spread onu kaybettiriyor. Görünmeyen\n // yüzey denetlenemez.\n const base = Object.assign(ops as unknown as Record<string, unknown>, {\n $atomic<T>(fn: (tx: AtomicDatabase) => Promise<T>, options?: AtomicOptions): Promise<T> {\n if (typeof raw.atomic !== \"function\") {\n throw new Error(\"This Database handle cannot open a root transaction; nested $atomic is not supported\");\n }\n // ALS.run scopes only this callback and its continuations, never another\n // Promise.all branch. Calls made by ordinary services through Database\n // therefore share the callback's physical transaction and identity.\n const parent = __requestALS.getStore();\n let runtime: RuntimeServices | undefined;\n try { runtime = __getRuntime(); } catch { /* Direct typed engine handles need no ambient runtime. */ }\n return raw.atomic(async (tx) => {\n const typed = makeTypedSurface(tx);\n const invoke = () => fn(typed);\n if (!runtime) return invoke();\n const refuse = (): never => { throw new Error(\"Database.$atomic owns one transaction and identity; nested roots and $asService are not allowed\"); };\n const ambient = Object.assign({}, tx, { atomic: refuse, asService: refuse });\n return __requestALS.run({ ...parent, runtime: { ...runtime, Database: ambient } }, invoke);\n }, options);\n },\n // Both surfaces get it: a savepoint on the service transaction is as useful\n // as one on the request's, and each is bound to its own connection.\n $attempt: <T,>(fn: (tx: DBOps) => Promise<T>) => raw.attempt(fn),\n $transaction<T>(\n fn: (tx: TxPlan) => T extends Promise<unknown> ? never : T,\n opts?: { retry?: number },\n ): Promise<Materialized<T>> {\n // A FRESH builder per call: it holds this transaction's ops and its error\n // slot table, and the runtime serves concurrent requests on one event loop.\n // A shared builder would splice one request's writes into another's plan.\n //\n assertPlanRetry(opts);\n const builder = new TxPlanBuilder();\n return runTxPlan(raw, makeTxPlanHandle(builder), builder, fn) as Promise<Materialized<T>>;\n },\n $command<T>(fn: (tx: TxPlan) => T extends Promise<unknown> ? never : T, options?: import(\"./db/command.js\").CommandOptions): Promise<Materialized<T>> {\n const builder = new TxPlanBuilder();\n return runTxPlan({ txPlan: plan => raw.command(plan, options) }, makeTxPlanHandle(builder), builder, fn) as Promise<Materialized<T>>;\n },\n });\n // ŞEMA ERİŞİMİ BİR PROXY'DİR, çünkü hangi şemaların bildirildiğini yalnız TİP\n // bilir — runtime'da `Database.billing` diye bir üye yoktur, o ada dokunulduğu\n // anda üretilir. `$`'la başlamayan her ad bir ŞEMA adıdır; ayrım tam olarak\n // budur ve tip tarafındaki DollarOps ile aynı kuralı uygular.\n return new Proxy(base, {\n get(target, prop, receiver) {\n // `tables` DOĞRUDAN YÜZEYDE DE public'in takma adı.\n //\n // Plan tutamağı `tx.tables.todos`'u öğretiyor (göç notu da öyle), ama\n // `Database.public.todos` aynı kelimeyi ADI `tables` OLAN BİR ŞEMA sanıp\n // tele `tables.todos` yazıyordu. Tip onu reddettiği için derlenen kodda\n // erişilemezdi — ama `as any` ya da düz JS ile geçen biri sessizce\n // olmayan bir şemaya gidiyordu, ve iki yüzeyin aynı kelimeye zıt cevap\n // vermesi bu run'ın kapattığı sınıfın kendisi (gözcü M-6).\n if (prop === \"tables\") return makeTableProxy(() => reco, \"\");\n if (typeof prop === \"string\" && !prop.startsWith(\"$\") && !(prop in target)) {\n // Nitelikli tablo anahtarının kuralı BURADA TEKRARLANMAZ (FR-058): tek\n // yazıcı `qualifiedTableKey` ve `table-key-single-source.test.ts` ikinci\n // bir yazıcıyı reddediyor. Prefix ondan türetilir — boş tablo adıyla\n // çağrıldığında geriye ya \"\" (public) ya \"<şema>.\" kalır.\n return makeTableProxy(() => reco, qualifiedTableKey(prop, \"\"));\n }\n return Reflect.get(target, prop, receiver);\n },\n }) as unknown as EnvServiceDatabase;\n}\n\n/**\n * `makeTableProxy`'nin plan ikizi: `tables.<name>` yields the\n * table's PLAN operations, recorded into `builder` instead of sent one by one.\n *\n * Same Proxy shape and same reason for the single narrowing — TS cannot infer a\n * mapped type through a Proxy, so the cast names what the trap returns.\n */\nfunction makeTxTablesAccessor(builder: TxPlanBuilder, prefix = \"\"): TxTables {\n const tablesProxy = new Proxy(\n {},\n {\n get(_t, prop: string | symbol) {\n if (typeof prop !== \"string\") return undefined;\n return builder.table(prefix + prop);\n },\n },\n );\n return tablesProxy as TxTables;\n}\n\n/**\n * Plan tutamağı — `Database` ile AYNI şekil: `tx.public.x`, `tx.<şema>.x`, ve\n * geriye dönük `tx.tables.x`.\n *\n * Şema adı tablo adının ÖNÜNE geçiyor (`billing.invoices`), tıpkı doğrudan\n * yüzeyin `makeTypedSurface` proxy'sinin yaptığı gibi — ve motor artık onu\n * `quoteTable` ile İKİ parça hâlinde tırnaklıyor. Bu ikisi olmadan `billing`\n * şemasındaki iki tabloyu tek atomik planda yazmak imkânsızdı.\n *\n * `tables` ve `public` DIŞINDAKİ HER ad şema kabul edilir ve altındaki tablolar\n * `<ad>.<tablo>` diye adlanır. Yanlış bir şema adı TİPTE yakalanıyor\n * (`keyof Schemas`) — `tx.constructor.x` ve `tx.toString.x` dahil, ölçüldü.\n *\n * TİPTEN KAÇAN bir ad için savunma `quoteTable`'ın KAÇIŞIDIR, başka bir şey\n * değil: `runPlanOp` `op.table`'ı doğrulamadan ona veriyor ve `quoteTable`\n * tırnak ikizleyerek tek bir tanımlayıcı üretiyor. Ölçüldü: `a\"; DROP TABLE t; --`\n * → `\"a\"\"; DROP TABLE t; --\"`, yani enjeksiyon değil, `relation does not exist`.\n * (Bu yorum bir zamanlar `validateSchemaIdentifier`'a atıf yapıyordu — o\n * fonksiyon Go tarafında yaşıyor ve BU yolu hiç görmüyor; gözcü yakaladı.)\n */\nfunction makeTxPlanHandle(builder: TxPlanBuilder): TxPlan {\n const publicTables = makeTxTablesAccessor(builder);\n return new Proxy(\n {},\n {\n get(_t, prop: string | symbol) {\n if (typeof prop !== \"string\") return undefined;\n if (prop === \"tables\") return publicTables;\n // ÖNEK TEK YAZICIDAN (FR-058): `qualifiedTableKey`. Bu kuralı burada\n // elle yazmıştım — public'i çıplak bırakıp diğerine nokta ekleyen bir\n // if/return çifti — ve FR-058 kapısı onu GÖRMEDİ, çünkü kapı yalnız\n // ternary arıyordu. (Kural burada KELİMEYLE anlatılıyor, kod biçiminde\n // DEĞİL: kapı metni tarıyor ve bir yorumdaki kopya da onu tetikler.)\n // İkinci bir yazıcı, kapının var olma sebebi olan sınıfın kendisi:\n // `env-gen.ts`'in kendi kopyası bir public FK'yi başka bir şemanın\n // tablosuna etiketlemişti ve hiçbir şey bunu söylememişti.\n // Boş tablo adıyla çağrılınca geriye ya \"\" (public) ya \"<şema>.\" kalır.\n return makeTxTablesAccessor(builder, qualifiedTableKey(prop, \"\"));\n },\n },\n ) as TxPlan;\n}\n\n/**\n * The project's own Postgres (pgx, schema `env_<envId>`).\n *\n * Typed by default: `Database.public.<name>.insert({...})` is typed against\n * the project's generated `palbase-env.d.ts` with NO import and NO generic.\n * The raw string ops (`Database.$query`/`$insert`/`$update`/`$delete`/\n * `$findById`/`$findMany`) are also available for read-only SQL and for a table\n * name only known at runtime — which the typed surface cannot express past\n * seven tables (see `db/tx-union-key.test-d.ts`).\n *\n * RLS is enforced by default (the runtime runs each op as `authenticated` with\n * the verified user's claims). To bypass RLS, call `Database.$asService()` —\n * explicit and greppable — which runs as the `service_role` (BYPASSRLS).\n *\n * @example\n * import { Database } from \"@palbase/backend\";\n *\n * const todo = await Database.public.todos.insert({ title: req.input.title });\n * todo.id; // string ✓\n * const rows = await Database.$query(\"SELECT id FROM todos WHERE done = $1\", [false]);\n * const all = await Database.$asService().public.todos.findMany({}); // RLS bypass\n */\nexport const Database: EnvTypedDatabase = Object.assign(makeTypedSurface(rawDatabase), {\n /**\n * Lazily resolve the runtime's service-role sibling on each call. We do NOT\n * cache it: `rawDatabase.asService()` reads the CURRENT request scope through\n * the runtime proxy, and the per-request runtime injects a service client\n * bound to that request's identity headers — caching would leak one request's\n * sibling into another concurrent request.\n */\n $asService(): EnvServiceDatabase {\n return makeTypedSurface(rawDatabase.asService());\n },\n}) as unknown as EnvTypedDatabase;\n\n/** Firestore-like document client (PalDocs). */\nexport const Documents: PalbaseDocsClient = makeServiceProxy(\"Documents\");\n\n/**\n * `buckets.<name>` — the storage twin of `Database.public.<name>`, and the same\n * mechanism: `config/storage.ts` generates a `Buckets` augmentation into\n * `palbase-env.d.ts`, so a bucket name is a property with no import and no\n * generic, and a typo is a compile error.\n *\n * The intermediate `.buckets` is there for the reason `.tables` is: bucket\n * names must not share a namespace with the client's own methods, or the day\n * somebody declares a bucket called `bucket` the surface breaks.\n */\nexport type EnvBuckets = {\n [K in keyof Buckets]: TypedBucketClient<Buckets[K] extends BucketTypes ? Buckets[K] : BucketTypes>;\n};\n\n/** One bucket, with its declared variant names in the type. */\nexport interface TypedBucketClient<B extends BucketTypes> extends Omit<PalbaseBucketClient, \"getPublicUrl\"> {\n /** The public URL for the object, or for one of THIS bucket's declared\n * renditions. A name the bucket does not declare is a compile error. */\n getPublicUrl(path: string, options?: { variant?: B[\"variants\"] }): string;\n}\n\nfunction makeBucketsAccessor(storage: () => PalbaseStorageClient): EnvBuckets {\n return new Proxy(\n {},\n {\n get(_t, prop: string | symbol) {\n if (typeof prop !== \"string\") return undefined;\n return storage().bucket(prop);\n },\n },\n ) as EnvBuckets;\n}\n\nconst rawStorage: PalbaseStorageClient = makeServiceProxy(\"Storage\");\n\n/**\n * Object storage: buckets, objects, renditions and signed URLs.\n *\n * `Storage.buckets.posts.upload(...)` is the typed path. `Storage.bucket(name)`\n * remains for a name computed at runtime — rare, and it gives up the typing,\n * which is the honest trade rather than a second blessed way to do it.\n */\nexport const Storage: PalbaseStorageClient & { buckets: EnvBuckets } = Object.assign(\n {\n // FORWARDED explicitly, not assigned onto the service proxy.\n //\n // `Object.assign(rawStorage, {buckets})` writes onto the proxy's TARGET, and\n // the proxy's only trap is `get`, which forwards every read to the module\n // client — so the property landed somewhere nothing reads and\n // `Storage.buckets.docs` was `undefined` in a deployed handler. It\n // typechecked, every test passed, and the live call answered\n // \"TypeError: undefined is not an object\". `Database` never had the bug\n // because it builds a plain surface the same way this now does.\n bucket: (name: string) => rawStorage.bucket(name),\n },\n { buckets: makeBucketsAccessor(() => rawStorage) },\n);\n\n/** JSON-typed cache (get/set/incr/getOrSet). */\nexport const Cache: CacheClient = makeServiceProxy(\"Cache\");\n\n\n/**\n * This tenant's secrets — API keys, provider credentials, signing material the\n * BACKEND owns.\n *\n * `await Secrets.get(\"STRIPE_KEY\")` in a handler. There is no `.env` to read\n * and no file to mount: a secret is written through the vault's authenticated\n * API (or the CLI/MCP that calls it), and this is how the deployed code reads\n * it back. A name this tenant has not set answers null — as does every name\n * the STACK holds, because no route returns a platform secret's value at all.\n */\nexport const Secrets: SecretsService = makeServiceProxy(\"Secrets\");\n\n/**\n * Role assignment, as an operator — `Auth.assignRole(userId, \"agent\")`.\n *\n * The half of auth a SERVER owns. Signing in, MFA and device attestation are a\n * person acting on their own account and live on the client SDK; granting a\n * role is the tenant's product doing something to somebody else, which is\n * exactly what a handler is for. It writes with the service-role credential,\n * because an end user who could write their own assignment would make every\n * permission underneath it meaningless.\n *\n * The write is visible to the very next request: authority is read from the\n * table on each call, never carried on a token.\n */\nexport const Auth: PalbaseAuthAdminClient = makeServiceProxy(\"Auth\");\n\n/** Structured logger. */\nexport const Log: Logger = makeServiceProxy(\"Log\");\n\n/** Push / email / SMS / in-app notifications. */\nexport const Notifications: PalbaseNotificationsClient = makeServiceProxy(\"Notifications\");\n\n\n/**\n * The raw runtime Flags client for the current request scope. Carries the\n * default-surface reads + `setOverride` AND the runtime's `asService()` sibling\n * (the br-pod's `buildFlagsClient` returns both). The default `Flags` singleton\n * below forwards reads + `setOverride` through here; `Flags.$asService()`\n * forwards to this client's own `asService()`.\n */\nconst rawFlags: PalbaseFlagsClient = makeServiceProxy(\"Flags\");\n\n/**\n * Feature flags.\n *\n * Mirrors the `Database` / `Database.$asService()` model. The default surface is\n * RLS-equivalent for flags: reads resolve against the CURRENT request user and\n * `Flags.setOverride(key, value)` writes an override for that same signed-in\n * user (no userId argument, no admin power). Cross-user admin writes\n * (`setOverrideForUser`, …) live behind `Flags.$asService()` — explicit and\n * greppable, just like `Database.$asService()`.\n *\n * @example\n * import { Flags } from \"@palbase/backend\";\n *\n * if (await Flags.isEnabled(\"new_checkout\")) { ... } // current user\n * await Flags.setOverride(\"new_checkout\", true); // current user\n * await Flags.$asService().setOverrideForUser(\"u_9\", \"x\", true); // cross-user\n */\n/**\n * The ambient `Flags` singleton's own surface — NOT the raw client's.\n *\n * MEASURED, as a consumer, against the built tarball: annotating the singleton\n * as `PalbaseFlagsClient` ERASED the `$asService` that `Object.assign` adds, so\n * `Flags.$asService()` did not exist for anyone outside this package —\n *\n * TS2551: Property '$asService' does not exist on type 'PalbaseFlagsClient'.\n * Did you mean 'asService'?\n *\n * — while the only path that DID compile (`asService()`) throws by design. The\n * feature was written and unreachable, which is the defect class this surface\n * exists to remove.\n *\n * `Database` never had the problem because its singleton carries its OWN type\n * (`EnvTypedDatabase`) rather than the raw client's (`DBClient`). This is that,\n * for `Flags`. The raw `PalbaseFlagsClient.asService()` is untouched (FR-023) —\n * it is the seam this forwards to.\n */\nexport type PalbaseFlagsAmbient = Omit<PalbaseFlagsClient, \"asService\"> & {\n /** RLS'i aşan, kullanıcılar arası yazma yüzeyi. */\n $asService(): PalbaseFlagsServiceClient;\n /** 31.0.0 öncesinin adı — SESSİZCE çalışmaz, yerini söyleyerek fırlatır. */\n asService(): never;\n};\n\nexport const Flags: PalbaseFlagsAmbient = Object.assign(\n {\n isEnabled(\n flagName: PalbaseFlagKey,\n context?: PalbaseFlagContext,\n ): Promise<PalbaseResult<boolean>> {\n return rawFlags.isEnabled(flagName, context);\n },\n getVariant(\n flagName: PalbaseFlagKey,\n context?: PalbaseFlagContext,\n ): Promise<PalbaseResult<PalbaseFlagVariant>> {\n return rawFlags.getVariant(flagName, context);\n },\n getAll(context?: PalbaseFlagContext): Promise<PalbaseResult<PalbaseFlag[]>> {\n return rawFlags.getAll(context);\n },\n /**\n * Resolve a flag's value, with an optional fallback.\n *\n * FORWARDED as of 2026-08-15. This surface is written out by hand, method\n * by method, and `get` was missing from it — so the client implemented it,\n * thirty assertions covered it, and `Flags.get(\"x\")` was `undefined` in a\n * deployed handler. Exactly the shape of the `Storage.buckets` defect found\n * the same day: a hand-maintained forwarding list is a list somebody has to\n * remember to update.\n */\n get(\n flagName: PalbaseFlagKey,\n defaultOrContext?: PalbaseFlagValue | PalbaseFlagContext,\n maybeContext?: PalbaseFlagContext,\n ): Promise<PalbaseResult<PalbaseFlagValue>> {\n return rawFlags.get(flagName, defaultOrContext, maybeContext);\n },\n setOverride(\n key: PalbaseFlagKey,\n value: PalbaseFlagValue,\n ): Promise<PalbaseResult<PalbaseSetOverrideResult>> {\n return rawFlags.setOverride(key, value);\n },\n },\n {\n /**\n * Lazily resolve the runtime's cross-user sibling on each call. We do NOT\n * cache it: `rawFlags.asService()` reads the CURRENT request scope through\n * the runtime proxy, so caching would leak one request's sibling into\n * another concurrent request. Mirrors `Database.$asService()`.\n */\n $asService(): PalbaseFlagsServiceClient {\n return rawFlags.asService();\n },\n /**\n * The name this member carried before 32.0.0.\n *\n * It does NOT work silently. A retired member that quietly keeps returning\n * is how a rename becomes a mystery: the old call site goes on compiling,\n * the new name never spreads, and the two live side by side until somebody\n * greps for one and misses half the codebase. `Database` made this split\n * first (`$asService`), and this JSDoc promised \"exactly like\n * Database.$asService()\" while the promise went unkept.\n */\n asService(): never {\n throw new Error(\n \"Flags.asService() was renamed to Flags.$asService() in 32.0.0 — system members carry the `$` prefix, like Database.$asService().\",\n );\n },\n },\n);\n\n/**\n * The Realtime broadcast singleton for the current request scope. Backend-side\n * Realtime is BROADCAST-ONLY (a stateless handler can push but not subscribe —\n * `subscribe()` lives on the client SDK's `pb.realtime`). Fire-and-forget:\n * `broadcast` resolves once accepted (or with an `error`), never blocking the\n * handler on subscribers.\n *\n * @example\n * import { Realtime } from \"@palbase/backend\";\n *\n * await Realtime.broadcast(\"room:42\", \"message\", { text, from: user.id });\n */\nexport const Realtime: PalbaseRealtimeClient = makeServiceProxy(\"Realtime\");\n","/**\n * The refusals a Database call gets BEFORE any SQL exists — written once, so the\n * engine and the test double cannot disagree about them.\n *\n * WHY THIS FILE EXISTS. `fakeDatabase()` is a second implementation of the same\n * surface (`__tests__/helpers/mock-db.ts`), and it never touched `compileWhere`\n * or `asBindParams`. Measured against the published 24.1.0: all four of the\n * calls that release had just started refusing went through the fake SILENTLY —\n * `update{title:undefined}`, `insert{title:undefined}`, `findMany{done:{}}`,\n * `deleteMany{owner,created_at:{}}`.\n *\n * The scaffold tells authors to test the service layer against exactly that\n * fake. So a test went green on a call production would throw on, and the\n * author found out in production instead — the same \"the surface does not match\n * the engine\" shape these refusals exist to end, arriving through the door the\n * SDK hands people for testing.\n *\n * These are pure and SQL-free on purpose: an in-memory store can run them as\n * easily as the driver path can.\n */\n\n/**\n * İşaretçilerin MARKASI — `col()` ve `sqlFragment()` ürünlerini bu süreçte\n * üretilmiş olmakla tanımlar.\n *\n * NEDEN ŞEKİL DEĞİL DE MARKA (gözcü W2-A/C1 ve W2-B/C3, ikisi de ÖLÇTÜ):\n * şekil kontrolü, işaretçiyi güvenilmeyen bir istek gövdesinden UYDURULABİLİR\n * kılıyordu. Ölçülen iki sonuç:\n *\n * findMany(\"docs\", { owner_id: JSON.parse('{\"$col\":\"owner_id\"}') })\n * → WHERE true AND t.\"owner_id\" = t.\"owner_id\" ← kiracılık predikatı totoloji\n * findMany(\"todos\", JSON.parse('{\"$sql\":{\"text\":[\"1=1 -- pwned\"],\"values\":[]}}'))\n * → WHERE true AND 1=1 -- pwned ← saldırganın metni SQL'e HARFİYEN\n *\n * `{ where: { tenant_id: tid, ...req.body.filter } }` bu SDK'nın öğrettiği\n * desen; T010/T014 öncesinde aynı anahtarlar \"bilinmeyen operatör\" diye\n * REDDEDİLİYORDU. Marka o reddi geri getiriyor.\n *\n * Sembol GLOBAL kayıttan (`Symbol.for`) ve ENUMERABLE DEĞİL. İkisi de kasıtlı:\n * global kayıt paketin iki kopyası arasında da eşleşir; enumerable olmaması ise\n * `JSON.stringify` ve `{...ref, gt: 5}` yayılımının markayı DÜŞÜRMESİNİ sağlar —\n * yani telden geçen ya da elle karıştırılan hiçbir şey işaretçi sayılmaz.\n * Kardeş özellik (`increment`) zaten `Symbol.for(\"palbase.tx.expr\")` kullanıyor;\n * bu onun aynısı.\n */\nconst REF_BRAND = Symbol.for(\"palbase.db.ref\");\n\n/** İşaretçiyi markalar. Yalnız `col()` ve `sqlFragment()` çağırır. */\nexport function brandRef<T extends object>(v: T, kind: \"col\" | \"sql\" | \"ref\"): T {\n Object.defineProperty(v, REF_BRAND, { value: kind, enumerable: false });\n return v;\n}\n\nfunction brandOf(v: unknown): unknown {\n if (typeof v !== \"object\" || v === null) return undefined;\n // KENDİ özelliği olmalı, prototip zincirinden MİRAS ALINMIŞ değil:\n // `Object.create(col(\"x\"))` markayı zincirden okuyup işaretçi sayılıyordu\n // (gözcü ölçtü). Telden erişilemez — JSON `__proto__` üstünden sembol\n // yazamaz — ama daraltmak bedava ve \"işaretçi bu süreçte ÜRETİLDİ\"\n // iddiasının tam karşılığı budur.\n return Object.hasOwn(v, REF_BRAND) ? (v as Record<symbol, unknown>)[REF_BRAND] : undefined;\n}\n\n/**\n * Bir değer, MARKASIZ bir işaretçi taklidi mi? (`{$col:…}` / `{$sql:…}`)\n *\n * Üst düzeyde bunlar zaten \"bilinmeyen operatör\" diye reddediliyor. Ama\n * operatörün SAĞINDA — `{ amount: { gt: {\"$col\":\"other\"} } }` — sessizce\n * PARAMETRE olarak bağlanıyorlardı: sayısal kolonda sürücünün 22P02'si,\n * jsonb/text kolonunda ise HİÇBİR SATIR, hatasız (gözcü ölçtü).\n *\n * `in` listesindeki aynı kusur adıyla reddediliyor; bu onun bir seviye\n * yanındaki hâli ve aynı cevabı hak ediyor.\n */\nexport function looksLikeUnbrandedRef(v: unknown): \"col\" | \"sql\" | \"expr\" | null {\n if (typeof v !== \"object\" || v === null) return null;\n if (brandOf(v) !== undefined) return null; // gerçek işaretçi\n if (isColumnExpr(v)) return null; // gerçek ifade tutamağı (kendi markası var)\n const o = v as { $col?: unknown; $sql?: unknown; $expr?: unknown };\n if (typeof o.$col === \"string\") return \"col\";\n if (o.$sql !== undefined && typeof o.$sql === \"object\" && o.$sql !== null) return \"sql\";\n // `$expr` `now()`/`increment()`'in TEL BİÇİMİ. `now()` filtrede geçerli bir\n // değer olduğu andan itibaren bu şekil de uydurulabilir hâle geldi: ÖLÇÜLDÜ,\n // gövdeden gelen `{\"$expr\":{\"fn\":\"now\"}}` sessizce PARAMETRE olarak bağlanıp\n // sorguyu hatasız biçimde boş sonuca çeviriyordu. `$col`/`$sql`/`$ref` ile\n // aynı kapı, aynı gerekçe.\n if (o.$expr !== undefined && typeof o.$expr === \"object\" && o.$expr !== null) return \"expr\";\n return null;\n}\n\n/**\n * `col()` ürünü mü? (FR-011)\n *\n * Burada, çünkü bu dosya \"iki uygulamanın da okuduğu kurallar\" dosyası: motor,\n * `fakeDatabase` ve guard AYNI cevabı vermek zorunda.\n */\nexport function isColRef(v: unknown): v is { readonly $col: string } {\n return brandOf(v) === \"col\" && typeof (v as { $col?: unknown }).$col === \"string\";\n}\n\n/**\n * `sqlFragment` ürünü mü? (FR-018)\n *\n * `isColRef` ile aynı gerekçeyle burada: motor, guard ve `fakeDatabase` üçü de\n * aynı cevabı vermek zorunda — biri fragment'i \"kolon haritası\" sanarsa filtre\n * sessizce düşer.\n */\n/**\n * Plan REFERANSI mı? (`{ $ref: { op, field } }`)\n *\n * `$ref` bu dilin MARKASIZ KALAN TEK işaretçisiydi — `engine/db.ts` onu\n * `\"$ref\" in v` diye tanıyordu — ve SDK'nın öğrettiği desen\n * `{ where: { tenant_id: tid, ...req.body.filter } }`. Ölçüldü (gözcü):\n * istek gövdesinden gelen `{\"id\":{\"$ref\":{\"op\":0,\"field\":\"id\"}}}` filtreyi\n * ÖNCEKİ bir işlemin satır değeriyle karşılaştırtıyor —\n * DELETE … WHERE t.\"tenant_id\" = $1 AND t.\"id\" = $2 PRM [\"t1\",\"SIZAN_DEGER\"]\n * gövdenin hiç görmediği bir değer. Enjeksiyon değil (değerler bound) ama bir\n * ORACLE: `op`/`field` seçip `rows_affected`'tan o değeri öğrenmek.\n *\n * Marka `Symbol.for` olduğu için SDK'nın İKİ KOPYASI arasında da eşleşiyor —\n * kontrolcü bundle'ı kendi kopyasını inline ediyor, planı çalıştıran ise\n * runtime'ınki. Ve plan gövdesi JSON'lanmıyor: tek üretim `txPlan` uygulaması\n * süreç içi (`engine/db.ts`), doğrulandı.\n */\nexport function isPlanRef(v: unknown): v is { readonly $ref: { op: number; field: string } } {\n if (brandOf(v) !== \"ref\") return false;\n const r = (v as { $ref?: { op?: unknown; field?: unknown } }).$ref;\n return r !== undefined && typeof r.op === \"number\" && typeof r.field === \"string\";\n}\n\n/** Markasız bir `{ $ref: … }` taklidi mi? Adıyla reddedilmesi için. */\nexport function looksLikeUnbrandedPlanRef(v: unknown): boolean {\n if (typeof v !== \"object\" || v === null || brandOf(v) !== undefined) return false;\n const r = (v as { $ref?: unknown }).$ref;\n return r !== undefined && typeof r === \"object\" && r !== null;\n}\n\nexport function isSqlFragment(v: unknown): v is { readonly $sql: { text: string[]; values: unknown[] } } {\n if (brandOf(v) !== \"sql\") return false;\n const f = (v as { $sql?: { text?: unknown; values?: unknown } }).$sql;\n return f !== undefined && Array.isArray(f.text) && Array.isArray(f.values);\n}\n\n/**\n * İFADE TUTAMAĞI DEĞER DEĞİLDİR — değer bekleyen yollarda adıyla reddedilir.\n *\n * `increment()` / `decrement()` / `now()` bir Proxy döndürür ve yalnız\n * `updateMany` ile plan yolunun `updateWhere`'i onu SQL'e derler. `insert` /\n * `update` / `put` / `supersede` derlemez; oralarda tutamak bound parametre\n * olarak sürücüye gidiyordu ve reddi SÜRÜCÜ veriyordu (\"Unknown object is not\n * a valid PostgreSQL type\") — yazarın yazdığı hiçbir şeyi adlandırmayan bir\n * mesaj (inceleme I-2/I8, ölçüldü). Plan yolu aynı hatayı kendi diliyle\n * reddediyor; bu, doğrudan yolun karşılığı.\n *\n * Sembol `tx-plan.ts`'in markasıyla AYNI global kayıttan okunuyor; bu dosya\n * kural dosyası olduğu için oraya bağımlılık kurmuyor.\n */\nconst TX_EXPR = Symbol.for(\"palbase.tx.expr\");\n\n/**\n * `now()` — SUNUCU SAATİ, karşılaştırma değeri olarak.\n *\n * `increment()`/`decrement()` bir YAZMA ifadesidir ve filtrede anlamsızdır;\n * `now()` öyle değil: `expires_at > now()` sıradan bir karşılaştırma ve her\n * backend'in en sık yazdığı yüklemlerden biri. Filtrede TÜM ifade tutamaklarını\n * reddetmek, yazarı bunun için `sqlFragment`e düşürüyordu — yani sorgunun\n * içine giren parça, en sıradan koşul için gerekiyordu.\n *\n * Ayrım MARKAYLA: bir istek gövdesinden gelen `{\"$expr\":{\"fn\":\"now\"}}` bu\n * süreçte `now()` ile üretilmediği için marka taşımaz ve reddedilir.\n */\nexport function isNowExpr(v: unknown): boolean {\n if (!isColumnExpr(v)) return false;\n try {\n const e = (v as Record<symbol, unknown>)[TX_EXPR];\n return typeof e === \"object\" && e !== null && (e as { fn?: unknown }).fn === \"now\";\n } catch {\n return false;\n }\n}\n\nexport function isColumnExpr(v: unknown): boolean {\n if (typeof v !== \"object\" && typeof v !== \"function\") return false;\n if (v === null) return false;\n try {\n return (v as Record<symbol, unknown>)[TX_EXPR] !== undefined;\n } catch {\n // Tutamak bir Proxy; bilinmeyen bir prop'ta trap fırlatabilir.\n return false;\n }\n}\n\n/**\n * Değer bekleyen bir yazma yolunda ifade tutamağı ya da `col()` var mı?\n *\n * Motor ve `fakeDatabase` AYNI cevabı vermek zorunda: fake tutamağı satıra\n * YAZIYORDU (`row[k] = proxy`) ve satır artık JSON'a bile çevrilemiyordu, motor\n * ise sürücüde patlıyordu. İki farklı yanlış, tek doğru.\n */\nexport function assertNoExpressionHandles(\n caller: string,\n table: string,\n cols: readonly string[],\n data: Record<string, unknown>,\n): void {\n for (const c of cols) {\n const v = data[c];\n // `now()` ile sayaç ifadeleri AYRI cevaplar hak ediyor: ikisinin de\n // çalışan alternatifi var ama farklı (P6 — hata çalışan bir alternatifi\n // ADIYLA söyler). Tek bir \"ifade tutamağı\" mesajı, `now()` yazan kişiye\n // `increment()` öneriyordu.\n if (isNowExpr(v)) {\n throw new Error(\n `${caller}(${table}): \"${c}\" now() aldı — bu yolda değer beklenir. ` +\n `Satır EKLENİRKEN sunucu saatini yazmanın yolu kolonu defaultNow() ile ` +\n `bildirmek (varsayılan kolonun yanında durur, her çağrıda tekrarlanmaz); ` +\n `var olan bir satırı damgalamak için updateMany({ where, set: { ${c}: now() } }) ` +\n `ya da $transaction içinde tx.public.${table}.updateWhere(where, { ${c}: now() }).`,\n );\n }\n if (isColumnExpr(v)) {\n throw new Error(\n `${caller}(${table}): \"${c}\" bir ifade tutamağı aldı (increment()/decrement()). ` +\n `Bu yolda değer beklenir. Sayaç artışı için updateMany({ where, set: { ${c}: increment(n) } }) ` +\n `ya da $transaction içinde tx.public.${table}.updateWhere(where, { ${c}: increment(n) }) kullanın.`,\n );\n }\n if (isColRef(v)) {\n throw new Error(\n `${caller}(${table}): \"${c}\" bir col() aldı. Kolon referansı yalnız FİLTREDE durabilir; ` +\n `bir kolonun değerini başka bir kolona yazmak için $query kullanın.`,\n );\n }\n }\n}\n\n/** The comparison operators a filter value may carry. Kept here because the\n * guard has to tell an operator object from a plain value. */\nconst KNOWN_OPS = new Set([\n \"gt\", \"gte\", \"lt\", \"lte\", \"neq\", \"in\",\n // K1 metin operatörleri (FR-005) ve null testi (FR-006). Bu küme\n // `fakeDatabase()` ile ORTAK kaynaktır: fake bir çağrıyı motorun reddettiği\n // yerde kabul ederse, yazarın testi üretimde patlayan koda karşı yeşil verir.\n \"contains\", \"icontains\", \"startsWith\", \"endsWith\", \"isNull\",\n]);\n\n/**\n * `eq` ADIYLA reddedilir, ve reddi buradadır çünkü guard'ı motor da fake de\n * okuyor.\n *\n * Eşitliğin yazımı ÇIPLAK DEĞERDİR: `{ owner: \"u1\" }`. `eq`'i ikinci bir yazım\n * olarak eklemek, bu run'ın kapatmak için var olduğu şeyi — aynı iş için iki\n * uyumsuz yazım — filtre dilinin İÇİNDE yeniden açardı. Ve eskiden kabul eden\n * ile reddeden ayrışıyordu: guard `eq`'i geçiriyor, derleyici\n * `bilinmeyen operatör \"eq\"` diyordu (gözcü ölçtü).\n */\nconst REFUSED_OPS: Record<string, string> = {\n eq: 'eşitlik ÇIPLAK yazılır: { <kolon>: <değer> } (ya da kolon karşılaştırması için { <kolon>: col(\"…\") })',\n};\n\n/**\n * Refuse a filter that would compile to something other than what it reads like.\n *\n * Three shapes, each measured in production before it was closed:\n *\n * `{ col: undefined }` binds NULL; `= NULL` matches no row, so the query\n * answered \"no records\" and said nothing.\n * `{ col: {} }` produces no term at all — every row on the read\n * path, a dropped condition on the write path.\n * `{ col: { gte: undefined } }` and an `undefined` inside `in`: the same NULL,\n * one level down.\n */\nexport function assertUsableFilter(\n caller: string,\n table: string,\n where: Record<string, unknown> | undefined,\n): void {\n // Bileşim anahtarları (FR-007) bir KOLON adı değildir; kolon doğrulamasından\n // ve operatör kontrolünden muaftır, kendi dalları özyinelemeli olarak aynı\n // kurallardan geçer.\n const COMPOSITES = new Set([\"OR\", \"AND\", \"NOT\"]);\n\n if (!where) return;\n // Fragment bir kolon haritası DEĞİLDİR (FR-018): içeriği SQL'dir, kolon\n // doğrulaması ona uygulanamaz. Değerleri zaten bound gidiyor.\n if (isSqlFragment(where)) return;\n for (const [col, cond] of Object.entries(where)) {\n // Bileşim anahtarları (FR-007) kolon DEĞİLDİR: dalları aynı kurallardan\n // özyinelemeli geçer, ama kendileri operatör kontrolüne girmez.\n if (COMPOSITES.has(col)) {\n const branches = col === \"NOT\" ? [cond] : cond;\n if (!Array.isArray(branches) && col !== \"NOT\") {\n throw new Error(`${caller}(${table}): where.${col} bir dizi olmalı`);\n }\n for (const b of branches as unknown[]) {\n if (b === null || typeof b !== \"object\") {\n throw new Error(`${caller}(${table}): where.${col} dalları filtre nesnesi olmalı`);\n }\n assertUsableFilter(caller, table, b as Record<string, unknown>);\n }\n continue;\n }\n // `has` de kolon DEĞİLDİR: anahtarları İLİŞKİ adları, değerleri BİR TABLO\n // ÖTESİNİN filtresi. İç filtre aynı kurallardan geçiyor — `has` ikinci bir\n // filtre dili değil, aynı dilin bir tablo ötesi.\n //\n // İlişki ADI burada doğrulanMIYOR: grafiği yalnız motor tanıyor (ve tip,\n // derleme anında). Guard'ın onu bilmesi ilişki grafiğinin İKİNCİ bir\n // yorumcusu demekti — `buildRelations`'ın yorumunun adıyla yasakladığı şey.\n if (col === \"has\") {\n if (cond === null || typeof cond !== \"object\" || Array.isArray(cond)) {\n throw new Error(`${caller}(${table}): where.has bir ilişki haritası olmalı ({ <ilişki>: { … } })`);\n }\n for (const [rel, inner] of Object.entries(cond as Record<string, unknown>)) {\n if (inner === null || typeof inner !== \"object\" || Array.isArray(inner)) {\n throw new Error(`${caller}(${table}): where.has.${rel} bir filtre nesnesi olmalı`);\n }\n assertUsableFilter(caller, table, inner as Record<string, unknown>);\n }\n continue;\n }\n if (cond === undefined) {\n throw new Error(\n `${caller}(${table}): where.${col} değeri undefined — bu bir filtre değeri değil. ` +\n `Bağlanınca NULL olur ve '= NULL' hiçbir satıra uymaz, yani sorgu sessizce ` +\n `boş sonuç dönerdi. Değer yoksa anahtarı filtreye hiç koymayın.`,\n );\n }\n if (cond === null || typeof cond !== \"object\" || Array.isArray(cond)) continue;\n // `col()` ürünü bir DEĞER'dir, operatör nesnesi değil (FR-011). Ayırt\n // edilmezse `{ $col: \"x\" }` bir operatör haritası sanılır ve \"bilinmeyen\n // operatör $col\" diye reddedilirdi.\n if (isColRef(cond)) continue;\n // `now()` de bir DEĞER'dir, aynı gerekçeyle — ve tutamak bir Proxy olduğu\n // için `Object.entries` BOŞ döner: ayırt edilmezse \"boş operatör nesnesi\"\n // diye reddedilirdi, yani doğru yazım yanlış bir hatayla karşılanırdı.\n if (isNowExpr(cond)) continue;\n\n const entries = Object.entries(cond as Record<string, unknown>);\n if (entries.length === 0) {\n throw new Error(\n `${caller}(${table}): where.${col} boş bir operatör nesnesi ({}) — hiçbir koşul ` +\n `üretmez, yani bu alan filtreden sessizce DÜŞERDİ. Koşul kurulmayacaksa ` +\n `anahtarı filtreye hiç koymayın (D-21).`,\n );\n }\n for (const [op, v] of entries) {\n if (op === \"in\") {\n if (!Array.isArray(v)) throw new Error(`${caller}(${table}): where.${col}.in bir dizi olmalı`);\n if (v.some((x) => x === undefined)) {\n throw new Error(\n `${caller}(${table}): where.${col}.in listesinde undefined var — sessizce NULL'a ` +\n `bağlanır ve o eleman hiçbir satırla eşleşmez. Listeyi kurarken eleyin.`,\n );\n }\n continue;\n }\n // Sağ tarafta kolon durabilir: `{ total: { gt: col(\"amount_paid\") } }`.\n // Değer kontrolleri (undefined) ona da uygulanır, ama `in` gibi şekil\n // kontrolleri değil — o dal aşağıda zaten ayrı.\n if (REFUSED_OPS[op] !== undefined) {\n // Bilinmeyen değil — BİLİNEREK reddedilen. Hata çalışan yazımı söylüyor.\n throw new Error(`${caller}(${table}): where.${col}.${op} bu filtre dilinde yok — ${REFUSED_OPS[op]}`);\n }\n if (!KNOWN_OPS.has(op)) {\n throw new Error(\n `${caller}(${table}): where.${col} bilinmeyen operatör \"${op}\" (gt/gte/lt/lte/neq/in/contains/icontains/startsWith/endsWith/isNull)`,\n );\n }\n if (v === undefined) {\n throw new Error(\n `${caller}(${table}): where.${col}.${op} değeri undefined — karşılaştırmanın ` +\n `sağ tarafı NULL olur ve sonuç hiçbir satıra uymaz. Koşulu kurmayın.`,\n );\n }\n }\n }\n}\n\n/**\n * Refuse a write whose value never arrived.\n *\n * `{ title: req.body.title }` with no `title` in the body bound NULL and\n * answered 200 — the column was ERASED. `null` is untouched, and the difference\n * is the whole point: null is an author SAYING \"empty this column\"; undefined is\n * nobody saying anything.\n */\nexport function assertUsableWriteValues(\n caller: string,\n table: string,\n cols: readonly string[],\n data: Record<string, unknown>,\n): void {\n for (const c of cols) {\n if (data[c] === undefined) {\n throw new Error(\n `${caller}(${table}): \"${c}\" değeri undefined — bu bir yazma değeri değil. ` +\n `Kolonu boşaltmak istiyorsan null yaz; kolonu değiştirmek istemiyorsan nesneye hiç koyma ` +\n `(bir eksik istek alanı sessizce NULL yazıyordu — FR-016).`,\n );\n }\n }\n}\n","/**\n * tx-plan.ts — `Database.$transaction()` as a PLAN, not a pinned session.\n *\n * A transaction used to be a conversation: BEGIN, then one network round trip\n * per operation, then COMMIT. Each of those round trips cost ~4 ms and, because\n * the pooler runs in transaction mode, an open transaction pinned a Postgres\n * backend for the whole conversation. A 121-operation statement upload pinned\n * one backend for ~490 ms.\n *\n * So the callback no longer TALKS to the database. It DESCRIBES what should\n * happen; the description is serialised and sent once; the broker runs the whole\n * thing inside one transaction and answers once. Committing on return and\n * rolling back on throw is unchanged — that is the only property tenant code\n * actually asked for.\n *\n * The consequences, stated plainly, because they are the whole design:\n *\n * - The callback is SYNCHRONOUS. There is nothing to await: no statement has\n * run yet when it returns. `async` on the callback and `await` inside it are\n * both compile errors (see {@link TxPlan} and {@link NotAwaitable}).\n * - `insert()` does not hand back a row, it hands back {@link TxRows}. Reading\n * a field requires `.expectOne(err)` first, which makes \"what if the row\n * isn't there\" a question you cannot route around: it is the argument.\n * - A field read from a row is a {@link Ref} — a PROMISE OF A VALUE THE SERVER\n * WILL PRODUCE, not the value. It can be written into a later operation and\n * it can be returned from the callback (it is substituted for the real value\n * before `transaction()` resolves). It cannot be branched on. See the\n * \"Truthiness\" note below — this is the sharp edge of the whole design.\n * - Control flow that needs a real value must move OUT of the callback: read\n * before the transaction, or express the condition as a guard\n * (`updateWhere({ id, accepted_at: null }, …).expectOne(new Conflict(…))`)\n * which the server evaluates and which rolls the whole plan back.\n *\n * # Truthiness — the hole this file CANNOT close\n *\n * JavaScript does not let a Proxy trap truthiness. `if (ref)` takes the true\n * branch, always, for every Ref, and no `get` handler ever runs. `tsc` is silent\n * because a Ref is a perfectly good object. So:\n *\n * const pot = tx.tables.pots.select({ id }, { limit: 1 }).expectOne(e);\n * if (!pot.balance) { … } // ← ALWAYS false. Silently wrong data.\n *\n * What this file does close: coercion (`Symbol.toPrimitive`/`valueOf`/\n * `toString`), awaiting (`then` is a callable member with a non-thenable\n * signature, which is a *compile* error), serialisation (`toJSON`), and nesting\n * a Ref inside a literal value where the server would store it as data. What it\n * cannot close is a bare truthiness test. The real defence is the build-time\n * static analysis (`tx_analysis.js`, phase P4); until that ships, this hole is\n * open and this comment is the only warning.\n *\n * # Wire contract\n *\n * The JSON this file emits is consumed by\n * the plan executor in `engine/db.ts`. That executor rejects\n * unknown fields at every level, so an op carries EXACTLY the fields its kind\n * takes. Everything here that looks like a needless restriction is one of the\n * server's rules made visible early:\n *\n * - `$ref` only points BACKWARDS, and only at an op statically known to yield\n * at most one row (insert, or a `one`/`atMost 1` guard, or `select limit 1`).\n * `.expectOne()` is what this file uses to satisfy that, always.\n * - `$expr` is a closed set: `inc`/`dec` (update only — they read the column's\n * current value) and `now()`.\n * - `update`/`delete` require a `where`; `insert` refuses one.\n * - `insertMany` rows must all set the same columns.\n * - ≤1000 ops, ≤5000 rows per insertMany, ≤8 MiB of JSON.\n *\n * Column keys are emitted SORTED, so the same callback always produces byte-\n * identical JSON. That is what lets the Go decoder be locked to golden files\n * this SDK emits (`testdata/tx_plan_golden/`).\n */\n\n// ---------------------------------------------------------------------------\n// Errors\n// ---------------------------------------------------------------------------\n\n/**\n * A plan handle was used as if it were a value: awaited, coerced to a string or\n * number, serialised, or nested inside another value.\n *\n * Thrown while the callback is still BUILDING the plan, so nothing has been sent\n * and nothing has been written.\n */\n// TİP-ONLY, ve döngü kasıtlı: `typed-db.ts` bu dosyadan tip alıyor, bu dosya\n// ondan `WhereOp` alıyor. Çalışma zamanında hiçbir şey ithal edilmiyor (import\n// type), yani modül döngüsü yok — paylaşılan olan şey TEK FİLTRE DİLİ, ve onu\n// iki yerde ayrı ayrı tanımlamak bu run'ın kapattığı \"iki yazım\"ın tipteki\n// hâli olurdu.\nimport type { WhereOpWith, ColRefOf, HasOnly, SqlFragment } from \"./typed-db.js\";\nimport { isColRef, isSqlFragment, brandRef, isNowExpr } from \"./input-guards.js\";\n\nexport class TxRefError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"TxRefError\";\n }\n}\n\n/**\n * The plan the callback described cannot be sent: it breaks a rule the server\n * would reject, and rejecting it here names the line that wrote it instead of\n * returning a 400 about an op index.\n */\nexport class TxPlanError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"TxPlanError\";\n }\n}\n\n// ---------------------------------------------------------------------------\n// Wire types — mirror the plan executor in `engine/db.ts` exactly.\n// ---------------------------------------------------------------------------\n\n/** A backwards reference to an earlier op's single-row result. */\nexport interface TxWireRef {\n $ref: { op: number; field: string };\n}\n\n/** A call from the server's closed function set. */\nexport interface TxWireExpr {\n $expr: { fn: \"inc\" | \"dec\"; by: number | string } | { fn: \"now\" };\n}\n\n/** One value in a `values`/`set`/`where` map: a literal, a `$ref` or a `$expr`. */\nexport type TxWireValue = TxWireRef | TxWireExpr | unknown;\n\n/** The tenant's declared expectation about an op's row count. `slot` indexes the\n * client-side error table — the error OBJECT never travels. */\nexport interface TxWireGuard {\n kind: \"one\" | \"none\" | \"atLeast\" | \"atMost\";\n n: number;\n slot: number;\n}\n\n/** One operation in the wire plan. Fields are omitted, never null: the decoder\n * rejects a field that does not belong to the op's kind. */\nexport interface TxWireOp {\n /** upsert and insertMany: the columns Postgres matches on. */\n onConflict?: readonly string[];\n /** insertMany only: what a collision does. Absent means no ON CONFLICT clause\n * at all, which is what every insertMany did before this option existed. */\n action?: \"ignore\" | \"update\";\n op: \"insert\" | \"insertMany\" | \"upsert\" | \"update\" | \"delete\" | \"select\";\n table: string;\n values?: Record<string, TxWireValue>;\n rows?: Record<string, TxWireValue>[];\n set?: Record<string, TxWireValue>;\n where?: Record<string, TxWireValue>;\n limit?: number;\n lock?: \"update\";\n guard?: TxWireGuard;\n}\n\n/** The plan the engine executes on the request's own transaction. */\nexport interface TxPlanBody {\n ops: TxWireOp[];\n}\n\n/** One op's outcome, positionally matched to the plan's ops. */\nexport interface TxPlanOpResult {\n rows: Record<string, unknown>[];\n rows_affected: number;\n}\n\n/** One result per op, in plan order. */\nexport interface TxPlanResponse {\n results: TxPlanOpResult[];\n}\n\n/**\n * The fields the runtime must copy from the broker's error envelope onto the\n * rejection it throws out of {@link DBClient.txPlan}.\n *\n * `slot` is the whole point: on a guard failure the server answers with the\n * INDEX of the expectation that did not hold, never with an error message of its\n * own, and this SDK maps that index back to the `Error` the callback handed to\n * `.expectOne(…)`. Without `slot` a guard failure degrades to a generic 409.\n */\nexport interface TxPlanRejection {\n status?: number;\n /** `tx_plan_invalid` | `tx_guard_failed` | `tx_ref_unresolved` | a pg class. */\n error_code?: string;\n /** Present only for `tx_guard_failed`: the client-side error table index. */\n slot?: number;\n /** Present on a database error: which op failed. */\n op?: number;\n}\n\n// ---------------------------------------------------------------------------\n// Handle types\n// ---------------------------------------------------------------------------\n\ndeclare const refBrand: unique symbol;\ndeclare const rowBrand: unique symbol;\ndeclare const rowsBrand: unique symbol;\n\n/**\n * Makes a handle a compile error to `await`.\n *\n * `then` is declared as a CALLABLE member whose signature is not `PromiseLike`,\n * which is precisely the shape TypeScript rejects: `await handle` is TS1320 and\n * `async () => handle` is TS1058. A non-callable `then` would not do it — the\n * compiler simply ignores those.\n */\nexport interface NotAwaitable {\n /** Not a promise. Nothing here has run yet; there is nothing to await. */\n then(doNotAwaitAPlanHandle: \"a transaction plan is built synchronously\"): never;\n}\n\n/**\n * A value the SERVER will produce, standing in for a column of a row this plan\n * writes or reads.\n *\n * Legal uses: write it into a later operation's `values`/`set`/`where`, or\n * return it from the callback (it is replaced by the real value before\n * `transaction()` resolves).\n *\n * Illegal, and caught: `await`, `String(ref)`, `` `${ref}` ``, `ref + 1`,\n * `JSON.stringify(ref)`, burying it inside a jsonb object.\n *\n * Illegal, and NOT caught: `if (ref)`. See the truthiness note at the top.\n */\nexport interface Ref<T> extends NotAwaitable {\n readonly [refBrand]: T;\n}\n\n/** The brand carried by a single-row handle, and the seam `Materialized` reads\n * to turn `return st` into the whole row. */\nexport interface TxRowHandle<Row> extends NotAwaitable {\n readonly [rowBrand]: Row;\n}\n\n/**\n * A row this plan is known to produce exactly one of. Every property is a\n * {@link Ref}; returning the handle itself yields the whole row.\n *\n * Only `.expectOne(err)` produces one — which is the design: a row you can read\n * fields from is a row whose absence you have already answered for.\n */\nexport type TxRow<Row> = { readonly [K in keyof Row]: Ref<Row[K]> } & TxRowHandle<Row>;\n\n/**\n * The result of one operation, before any expectation is declared about it.\n *\n * Deliberately not a row and not a list: an operation's row count is not known\n * until the server runs it, so the only thing that can be said about it here is\n * an EXPECTATION. Declaring one is also the only way to get a readable row.\n *\n * At most one expectation per operation — the wire carries one guard per op, and\n * a second call throws rather than silently dropping the first.\n */\nexport interface TxRows<Row> extends NotAwaitable {\n readonly [rowsBrand]: Row;\n /**\n * Require exactly one row, and read it. On any other count the server rolls\n * the whole transaction back and this `error` is thrown to the caller.\n *\n * This is the only way to reach a row's fields, and the only shape a `$ref`\n * may point at.\n */\n expectOne(error: Error): TxRow<Row>;\n /** Require zero rows (e.g. \"this membership must not already exist\"). */\n expectNone(error: Error): void;\n /** Require at least `n` rows. */\n expectAtLeast(n: number, error: Error): void;\n /** Require at most `n` rows. */\n expectAtMost(n: number, error: Error): void;\n}\n\n/** `now()` — the server's clock, usable wherever a value is. */\nexport interface TxNow extends NotAwaitable {\n readonly $expr: { fn: \"now\" };\n}\n\n/** `inc(n)` / `dec(n)` — read the column's CURRENT value and write it back\n * changed. Only meaningful in an update's `set`, which is where the types allow\n * it and where the server allows it. */\nexport interface TxColumnExpr extends NotAwaitable {\n readonly $expr: { fn: \"inc\" | \"dec\"; by: number | string };\n}\n\n/**\n * Resolve a callback's return type against what actually comes back: every\n * {@link Ref} becomes its value, every {@link TxRow} becomes its row, and\n * anything else keeps its shape.\n *\n * A {@link TxRows} resolves to an explanatory string type rather than a row\n * list: it has no single answer to give, and saying so in the type is louder\n * than a runtime throw.\n */\nexport type Materialized<T> = T extends Ref<infer U>\n ? U\n : T extends TxRowHandle<infer R>\n ? R\n : T extends TxRows<unknown>\n ? \"a TxRows cannot leave the transaction callback — read a row with .expectOne(err) first\"\n : T extends Date\n ? T\n : T extends object\n ? { [K in keyof T]: Materialized<T[K]> }\n : T;\n\n// ---------------------------------------------------------------------------\n// Author-facing value types\n// ---------------------------------------------------------------------------\n\n/** A value written by an INSERT: a literal, an earlier row's field, or `now()`.\n * `inc`/`dec` are absent on purpose — they read a current value, and an inserted\n * row has none. */\nexport type TxInsertValue<V> = V | Ref<V> | TxNow;\n\n/** A value written by an UPDATE's `set`: everything an insert takes, plus the\n * read-modify-write expressions. */\n/**\n * TEK KURAL: ifade tutamağı yalnız sayısal-benzeri kolonlarda.\n *\n * Bu tip KOŞULSUZDU ve doğrudan yolun `SetValue<V>`'si koşulluydu, yani aynı\n * nesne için İKİ tip kuralı vardı: `tx.tables.todos.updateWhere({id}, { done:\n * increment(1) })` (boolean kolon!) DERLENİYOR, `updateMany`'nin aynısı derleme\n * hatası veriyordu. Bu run'ın kapatmak için var olduğu şey \"aynı iş için iki\n * uyumsuz yazım\"dı; tip kuralı ikinci yazımın kendisi olmuştu (gözcü I6/I-1).\n */\nexport type TxSetValue<V> =\n | V\n | Ref<V>\n | TxNow\n | (NonNullable<V> extends number | string ? TxColumnExpr : never);\n\n/** An insert payload: the table's insert shape, with refs and `now()` allowed. */\nexport type TxInsertShape<Insert> = { [K in keyof Insert]: TxInsertValue<Insert[K]> };\n\n/** An update's `set`: any subset of the insert shape, with expressions allowed. */\nexport type TxSetShape<Insert> = { [K in keyof Insert]?: TxSetValue<Insert[K]> };\n\n/**\n * A filter. Every entry is an equality test and they are AND-ed; a `null`\n * becomes `IS NULL`, which is what makes `{ accepted_at: null }` a usable\n * \"not yet accepted\" guard rather than a clause that matches nothing.\n */\n/**\n * Plan filtresinin tipi — `WhereFilter<Row>` ile AYNI sözlük, artı `Ref`.\n *\n * Eskiden yalnız eşitlikti (`Row[K] | Ref<Row[K]>`), ve iki şeye mal oluyordu:\n * FR-014'ün amiral deseni (`{ balance: { gte: amount } }`) `$transaction`\n * İÇİNDE yazılamıyordu — koşullu bir yazmayı plana koyamayan yazar `$query`'ye\n * düşüyordu — ve motor tarafında tip atlandığında aynı nesne SESSİZCE parametre\n * olarak bağlanıyordu.\n *\n * `Ref` fazladan üye ve öyle kalmalı: bir plan filtresi ÖNCEKİ bir işlemin\n * döndürdüğü değere bakabilir, `findMany` bakamaz — plan dışında böyle bir\n * \"önceki işlem\" yok.\n */\ntype TxWhereField<Row, K extends keyof Row> = WhereOpWith<\n Row[K],\n // `Ref` KOLON REFERANSININ YANINDA duruyor, `V`'nin içinde DEĞİL: `V`'ye\n // eklenseydi `TextOps<V>`'nin `V extends string` sorusu HAYIR olur ve\n // `contains`/`startsWith` sessizce kaybolurdu (ölçüldü).\n ColRefOf<Row, Row[K]> | Ref<Row[K]>\n>;\n\nexport type TxWhere<Row, Rels = unknown> = {\n [K in keyof Row]?: TxWhereField<Row, K>;\n} & {\n // Düz op'lardaki `WhereFilter` ile AYNI: dal bir `sqlFragment` de olabilir.\n // İki filtre dilinin bir dalda ayrışması, \"tek dil\" iddiasını tam da bileşim\n // anında boşa çıkarırdı — ve motor plan yolunda da fragment'i derliyor\n // (ölçüldü: `SELECT t.* FROM \"crew\" t WHERE true AND (((a > 1)) AND (…))`).\n OR?: (TxWhere<Row, Rels> | SqlFragment)[];\n AND?: (TxWhere<Row, Rels> | SqlFragment)[];\n NOT?: TxWhere<Row, Rels> | SqlFragment;\n} & HasOnly<Rels>;\n\n/** Options for a plan `select`. */\nexport interface TxSelectOptions {\n /** Cap the rows read. */\n limit?: number;\n /** Take a real `FOR UPDATE` row lock for the rest of the transaction. */\n lock?: \"update\";\n}\n\n/** One table, as the plan sees it. */\nexport interface TxTable<Row, Insert, Rels = unknown> {\n /** Insert one row. Returns a handle — call `.expectOne(err)` to read fields. */\n insert(values: TxInsertShape<Insert>): TxRows<Row>;\n /**\n * Insert many rows in ONE statement. Every row must set the same columns\n * (a row that omits one would silently take the column's default).\n *\n * An empty list writes nothing and sends nothing.\n */\n /**\n * Insert many rows in ONE statement, optionally choosing what a collision does.\n *\n * Without `opts` this is a plain multi-row INSERT and a collision aborts the\n * transaction — the behaviour every call had before the option existed.\n *\n * `action: \"ignore\"` emits `ON CONFLICT DO NOTHING`, which is how \"insert the\n * ones that are new\" becomes one round-trip instead of one per row with a\n * 23505 caught around each. **The returned rows are the ones actually\n * INSERTED**: a row that collided is skipped, so it is absent from the result\n * — Postgres does not return what it did not write.\n *\n * `action: \"update\"` emits `ON CONFLICT DO UPDATE`, setting every non-conflict\n * column from the incoming row, and every row comes back.\n */\n insertMany(\n rows: readonly TxInsertShape<Insert>[],\n opts?: {\n onConflict: readonly Extract<keyof Row, string>[];\n action?: \"ignore\" | \"update\";\n },\n ): TxRows<Row>;\n /**\n * Satırı yaz, `onConflict` kolonlarında çakışırsa üzerine yaz — planın\n * savepoint'i içinde, `Database.<şema>.<tablo>.put()` ile AYNI anlamda.\n *\n * Adı bilerek aynı: aynı iş için transaction içinde ve dışında iki farklı\n * yazım, bu run'ın kapatmak için var olduğu şeydir (P1). TEL şekli\n * (`op: \"upsert\"`) değişmedi — o iç sözleşme, yazarın gördüğü ad değil.\n *\n * Bir operasyon olmasının sebebi: alternatifi burada yazılamaz — başarısız\n * bir insert tüm transaction'ı abort eder, yani \"dene, sonra geri düş\" iki\n * plan adımı olamaz.\n */\n put(\n values: TxInsertShape<Insert>,\n options: { onConflict: readonly Extract<keyof Row, string>[] },\n ): TxRows<Row>;\n /**\n * Update every row matching `where`. The filter comes first because it is the\n * dangerous half: an update whose `where` you got wrong rewrites rows you\n * never looked at. The server refuses an update with no `where` at all.\n */\n updateWhere(where: TxWhere<Row, Rels>, set: TxSetShape<Insert>): TxRows<Row>;\n /** Delete every row matching `where`. The server refuses an unfiltered delete. */\n deleteWhere(where: TxWhere<Row, Rels>): TxRows<Row>;\n /** Read rows, optionally locking them for the rest of the transaction. */\n select(where?: TxWhere<Row, Rels>, options?: TxSelectOptions): TxRows<Row>;\n}\n\n/**\n * The handle a transaction callback receives.\n *\n * It carries tables and nothing else: no `query`, no `findById`, no `asService`.\n * A read whose value the plan does not write belongs OUTSIDE the transaction,\n * where it costs one round trip and can be branched on like an ordinary value.\n */\nexport interface TxPlanHandle<TTables> {\n /**\n * @deprecated `tx.public` kullanın. Bu ad public'in takma adı olarak DURUYOR\n * (göç notu onu öğretiyor ve her mevcut çağrı onu kullanıyor), ama ARTIK\n * ÖĞRETİLMİYOR: doğrudan yüzeyde `Database.tables` FR-001 ile kaldırıldı, ve\n * plan yüzeyinin onu öğretmeye devam etmesi yazarı bir yüzeyde çalışıp\n * diğerinde derlenmeyen bir yazıma alıştırıyordu (gözcü M-6).\n */\n tables: TTables;\n}\n\n// ---------------------------------------------------------------------------\n// Runtime — expressions\n// ---------------------------------------------------------------------------\n\n/** Internal marker read by the serialiser. */\nconst EXPR = Symbol.for(\"palbase.tx.expr\");\nconst REF = Symbol.for(\"palbase.tx.ref\");\nconst ROW = Symbol.for(\"palbase.tx.row\");\nconst ROWS = Symbol.for(\"palbase.tx.rows\");\n\ninterface RefDescriptor {\n op: number;\n field: string;\n}\n\n/** Property reads that must not silently produce a value on a plan handle.\n * `then` is the one that matters for correctness (it makes `await` a compile\n * error AND stops a handle from being adopted by a promise); the rest turn a\n * silent wrong answer — `\"[object Object]\"`, `NaN`, `{}` — into a thrown one. */\nconst TRAPPED_PROPS: readonly (string | symbol)[] = [\n \"then\",\n \"valueOf\",\n \"toString\",\n \"toJSON\",\n Symbol.toPrimitive,\n];\n\nfunction trap(prop: string | symbol, what: string, hint: string): never {\n const name = typeof prop === \"symbol\" ? prop.description ?? String(prop) : prop;\n throw new TxRefError(\n `${what} was used as a value (via \\`${name}\\`). Nothing in a transaction ` +\n `callback has run yet, so there is no value to read. ${hint}`,\n );\n}\n\n/** The server's `now()`. */\nexport function now(): TxNow {\n return makeExpr({ fn: \"now\" }) as TxNow;\n}\n\n/** Add `by` to the column's current value. Only valid in an update's `set`. */\nexport function increment(by: number | string): TxColumnExpr {\n assertAmount(by, \"increment\");\n return makeExpr({ fn: \"inc\", by }) as TxColumnExpr;\n}\n\n/**\n * `increment`'in eski adı. AYNI fabrikadır — iki uygulama değil, iki ad.\n *\n * @deprecated `increment()` kullanın; bu ad geriye dönük uyumluluk için duruyor.\n */\nexport const inc = increment;\n\n/** Subtract `by` from the column's current value. Only valid in an update's `set`. */\nexport function decrement(by: number | string): TxColumnExpr {\n assertAmount(by, \"decrement\");\n return makeExpr({ fn: \"dec\", by }) as TxColumnExpr;\n}\n\n/**\n * `decrement`'in eski adı. AYNI fabrikadır.\n *\n * @deprecated `decrement()` kullanın.\n */\nexport const dec = decrement;\n\n/**\n * Miktarın taşınabilir olduğunu doğrular.\n *\n * String kabul edilir ve KASITLIDIR (D-007): `numeric` bir kolonda miktar JS\n * `number`'a uğrarsa 0.1 + 0.2 orada 0.30000000000000004'tür ve para hesabı\n * sessizce kayar. String hem burada hem `renderValue`'da bound parametre olarak\n * taşınır — Postgres onu tam ondalık olarak okur.\n */\nfunction assertAmount(by: number | string, fn: string): void {\n if (typeof by === \"string\") {\n // Metin SQL'e girmiyor (bound parametre), ama şekli yine de doğrulanır:\n // \"abc\" bind edilirse hata Postgres'ten gelir, çağıranın diliyle değil.\n if (!/^-?\\d+(\\.\\d+)?$/.test(by)) {\n throw new TxPlanError(\n `${fn}() ondalık bir sayı metni bekliyor, \"${by}\" aldı — kabul edilen biçim: \"12\", \"-12\", \"12.50\"`,\n );\n }\n } else if (typeof by !== \"number\" || !Number.isFinite(by)) {\n // JSON has no NaN/Infinity: they would serialise to `null` and the server\n // would reject the plan with an unhelpful decode error.\n throw new TxPlanError(`${fn}() needs a finite number, got ${String(by)}`);\n }\n // NEGATİF MİKTAR REDDEDİLİR — ve bu şekil kontrolünden çok daha fazlası.\n // `decrement(\"-5\")` `SET c = c - $1` derliyordu, `$1 = -5`, yani beş EKLİYORDU.\n // FR-014'ün amiral deseninde (`where: { balance: { gte: amount } }`) miktar\n // istek gövdesinden geliyorsa `balance >= -5` her zaman doğru: hesap\n // KREDİLENDİRİLİR ve çağrı bunu 1 satırla \"başarı\" diye raporlar. Guard\n // okunduğunda işaret kontrol edilmiş gibi duruyordu (gözcü I9, ölçüldü).\n const negative = typeof by === \"string\" ? by.trimStart().startsWith(\"-\") : by < 0;\n if (negative) {\n const other = fn === \"increment\" ? \"decrement\" : \"increment\";\n throw new TxPlanError(\n `${fn}() negatif miktar almaz (\"${String(by)}\"). Ters yön için ${other}() kullanın — ` +\n `işaretin miktarda saklanması, yönü okuyan hiçbir kod tarafından görülmezdi.`,\n );\n }\n}\n\n/**\n * Bir değer `increment()`/`decrement()` ürünü mü? Öyleyse tel şekli.\n *\n * DOĞRUDAN yol (`updateMany`) da bu ifadeyi anlamak zorunda: aynı nesnenin iki\n * yerde çalışması, \"kolona ekle\"nin tek yazımı olmasının şartı (P1).\n */\nexport function columnExprOf(v: unknown): TxWireExpr[\"$expr\"] | null {\n return exprOf(v);\n}\n\nfunction makeExpr(expr: TxWireExpr[\"$expr\"]): unknown {\n return new Proxy(\n { [EXPR]: expr } as Record<string | symbol, unknown>,\n {\n get(target, prop) {\n if (prop === EXPR) return target[EXPR];\n if (TRAPPED_PROPS.includes(prop)) {\n trap(prop, \"A plan expression\", \"Write it into an operation instead.\");\n }\n return undefined;\n },\n },\n );\n}\n\n// ---------------------------------------------------------------------------\n// Runtime — refs and row handles\n// ---------------------------------------------------------------------------\n\nfunction makeRef(op: number, field: string): unknown {\n const target: Record<string | symbol, unknown> = { [REF]: { op, field } satisfies RefDescriptor };\n return new Proxy(target, {\n get(t, prop) {\n if (prop === REF) return t[REF];\n if (TRAPPED_PROPS.includes(prop)) {\n trap(\n prop,\n `\\`${field}\\` of a row this transaction has not written yet`,\n \"Pass it to another operation in the same plan, or return it from the \" +\n \"callback and read it after `transaction()` resolves.\",\n );\n }\n return undefined;\n },\n });\n}\n\nfunction makeRowHandle(op: number): unknown {\n const target: Record<string | symbol, unknown> = { [ROW]: op };\n return new Proxy(target, {\n get(t, prop) {\n if (prop === ROW) return t[ROW];\n if (TRAPPED_PROPS.includes(prop)) {\n trap(\n prop,\n \"A row this transaction has not written yet\",\n \"Read one of its columns to reference it, or return the row from the \" +\n \"callback and read it after `transaction()` resolves.\",\n );\n }\n if (typeof prop === \"symbol\") return undefined;\n return makeRef(op, prop);\n },\n });\n}\n\nfunction refDescriptor(v: unknown): RefDescriptor | null {\n if (typeof v !== \"object\" || v === null) return null;\n const d = (v as Record<symbol, unknown>)[REF];\n return isRefDescriptor(d) ? d : null;\n}\n\nfunction isRefDescriptor(d: unknown): d is RefDescriptor {\n return (\n typeof d === \"object\" &&\n d !== null &&\n typeof (d as RefDescriptor).op === \"number\" &&\n typeof (d as RefDescriptor).field === \"string\"\n );\n}\n\nfunction rowOpIndex(v: unknown): number | null {\n if (typeof v !== \"object\" || v === null) return null;\n const op = (v as Record<symbol, unknown>)[ROW];\n return typeof op === \"number\" ? op : null;\n}\n\nfunction exprOf(v: unknown): TxWireExpr[\"$expr\"] | null {\n if (typeof v !== \"object\" || v === null) return null;\n const e = (v as Record<symbol, unknown>)[EXPR];\n return typeof e === \"object\" && e !== null ? (e as TxWireExpr[\"$expr\"]) : null;\n}\n\nfunction isRowsHandle(v: unknown): boolean {\n return typeof v === \"object\" && v !== null && (v as Record<symbol, unknown>)[ROWS] !== undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Runtime — value encoding\n// ---------------------------------------------------------------------------\n\n/**\n * Encode one value of a `values`/`set`/`where` map.\n *\n * The nesting check is not defensive tidiness. The server treats `$ref` as a\n * tagged value only at the TOP of a column's value; a ref buried inside a jsonb\n * payload is just data, and would be stored as the literal object\n * `{\"$ref\":{...}}` — a write that succeeds, commits, and is wrong. So a nested\n * handle is a hard error here, where the line that wrote it is still on the\n * stack.\n */\nfunction encodeValue(value: unknown, column: string, allowColumnExpr: boolean): TxWireValue {\n const ref = refDescriptor(value);\n if (ref) return brandRef({ $ref: { op: ref.op, field: ref.field } }, \"ref\") satisfies TxWireRef;\n\n // `now()` bir KARŞILAŞTIRMA değeri olarak geçer — sunucu saati. Diğer\n // ifadeler (increment/decrement) yazma ifadesidir ve aşağıda adıyla\n // reddediliyor. Düz op yolu ile aynı ayrım, aynı gerekçe.\n if (isNowExpr(value)) return { $expr: { fn: \"now\" } };\n const expr = exprOf(value);\n if (expr) {\n if (expr.fn !== \"now\" && !allowColumnExpr) {\n throw new TxPlanError(\n `\\`${column}\\`: ${expr.fn}() reads the column's current value, so it is ` +\n `only valid in updateWhere(where, set).`,\n );\n }\n return { $expr: expr } satisfies TxWireExpr;\n }\n\n if (rowOpIndex(value) !== null) {\n throw new TxPlanError(\n `\\`${column}\\`: a row handle is not a value. Read the column you meant ` +\n `(e.g. \\`row.id\\`).`,\n );\n }\n if (isRowsHandle(value)) {\n throw new TxPlanError(\n `\\`${column}\\`: an operation result is not a value. Declare an expectation ` +\n `first (\\`.expectOne(err)\\`) and read a column from the row.`,\n );\n }\n\n assertNoNestedHandles(value, column);\n return value;\n}\n\n/**\n * Encode a FİLTRE — `values`/`set` ile AYNI kodlayıcı değil, ve olmaması bir\n * düzeltme.\n *\n * `encodeValue` bir `$ref`'i yalnız kolonun EN ÜSTÜNDE kabul ediyor, çünkü bir\n * insert değerinin İÇİNE gömülü ref sunucuda çözülmez, literal JSON olarak\n * SAKLANIR — \"başarıyla commit olan ve yanlış olan bir yazma\". O kural DEĞER\n * yolu için doğru.\n *\n * FİLTREDE öyle değil: motorun `resolveRefsDeep`'i bir ref'i filtrenin HER\n * yerinde çözüyor — operatörün sağında, `OR`/`AND`/`NOT` dallarının içinde. Ama\n * kodlayıcı hâlâ değer kuralını uyguluyordu, yani üç katman üç farklı cevap\n * veriyordu (gözcü C-2): tip kabul, motor çözüyor, kodlayıcı REDDEDİYOR — ve\n * reddin metni değer-yuvalama vakasını anlatıyor, filtrede olmayan bir şeyi.\n *\n * İFADE TUTAMAĞI ve SATIR TUTAMAĞI filtrede HÂLÂ reddediliyor: onları motor\n * filtrede çözmüyor ve çözmemeli — `increment()` bir yazma ifadesi, bir\n * karşılaştırma değil.\n */\nfunction encodeFilterValue(value: unknown, column: string): unknown {\n const ref = refDescriptor(value);\n if (ref) return brandRef({ $ref: { op: ref.op, field: ref.field } }, \"ref\") satisfies TxWireRef;\n\n const expr = exprOf(value);\n if (expr) {\n throw new TxPlanError(\n `\\`${column}\\`: ${expr.fn}() bir YAZMA ifadesi, karşılaştırma değil — ` +\n `filtrede kullanılamaz. Kolonu bir değerle ya da col() ile karşılaştırın.`,\n );\n }\n if (rowOpIndex(value) !== null) {\n throw new TxPlanError(\n `\\`${column}\\`: a row handle is not a value. Read the column you meant (e.g. \\`row.id\\`).`,\n );\n }\n if (isRowsHandle(value)) {\n throw new TxPlanError(\n `\\`${column}\\`: an operation result is not a value. Declare an expectation ` +\n `first (\\`.expectOne(err)\\`) and read a column from the row.`,\n );\n }\n if (Array.isArray(value)) return value.map((v) => encodeFilterValue(v, column));\n // `col()` ve `sqlFragment` OLDUĞU GİBİ geçer: markaları süreç içinde korunur\n // ve derleyici ikisini de kendi tanıyor.\n if (value !== null && typeof value === \"object\" && !(value instanceof Date) && !isColRef(value) && !isSqlFragment(value)) {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n out[k] = encodeFilterValue(v, column);\n }\n return out;\n }\n return value;\n}\n\n/** Filtre haritası — anahtarlar SIRALI (aynı geri çağrı bayt-özdeş JSON üretsin). */\nfunction encodeFilterMap(map: Record<string, unknown>): Record<string, TxWireValue> {\n const out: Record<string, TxWireValue> = {};\n for (const key of Object.keys(map).sort()) {\n const value = map[key];\n if (value === undefined) continue;\n out[key] = encodeFilterValue(value, key) as TxWireValue;\n }\n return out;\n}\n\nfunction assertNoNestedHandles(value: unknown, column: string): void {\n if (typeof value !== \"object\" || value === null) return;\n if (value instanceof Date) return;\n if (refDescriptor(value) || exprOf(value) || rowOpIndex(value) !== null || isRowsHandle(value)) {\n throw new TxPlanError(\n `\\`${column}\\`: a plan handle is nested inside a value. The server would ` +\n `store it as literal JSON, not resolve it. Put the reference directly in ` +\n `the column.`,\n );\n }\n if (Array.isArray(value)) {\n for (const item of value) assertNoNestedHandles(item, column);\n return;\n }\n for (const item of Object.values(value as Record<string, unknown>)) {\n assertNoNestedHandles(item, column);\n }\n}\n\n/**\n * Encode a column map, dropping `undefined` and emitting keys SORTED.\n *\n * Sorting is what makes the same callback produce byte-identical JSON every\n * time, which is what lets the Go decoder be locked to goldens this SDK emits.\n * Dropping `undefined` mirrors what `JSON.stringify` would do anyway, but does\n * it where the resulting column list is still checkable.\n */\nfunction encodeMap(\n map: Record<string, unknown>,\n allowColumnExpr: boolean,\n): Record<string, TxWireValue> {\n const out: Record<string, TxWireValue> = {};\n for (const key of Object.keys(map).sort()) {\n const value = map[key];\n // AÇIK `undefined` REDDEDİLİR (D-017 kapandı).\n //\n // \"Kolon varsayılanını al\" demenin yolu anahtarı HİÇ KOYMAMAK; bu döngü\n // zaten yalnız var olan anahtarları geziyor, yani o niyet bozulmadan\n // çalışıyor. Ayırt edilen şey başka: anahtarın DURDUĞU ama değerinin\n // `undefined` olduğu hâl — yani `{ title: req.body.title }` gövdede\n // `title` yokken. O ölçülmüş bir olaydı: kolon sessizce yazılmadı ve\n // istek 200 döndü.\n //\n // Doğrudan yol bunu baştan beri adıyla reddediyordu; plan yolu sessizce\n // düşürüyordu. Aynı girdiye zıt iki cevap, \"tek filtre dili, tek cevap\"\n // iddiasını yazma tarafında boşa çıkarıyordu.\n if (value === undefined) {\n throw new TxPlanError(\n `${key} değeri undefined — bu bir yazma değeri değil. Anahtar duruyor ` +\n `ama değeri yok, yani kolon sessizce YAZILMAZDI (istek gövdesinden ` +\n `gelen bir alanın eksik olması bu şekilde görünür). Kolon ` +\n `varsayılanını istiyorsanız anahtarı hiç koymayın; NULL yazmak ` +\n `istiyorsanız açıkça null yazın.`,\n );\n }\n out[key] = encodeValue(value, key, allowColumnExpr);\n }\n return out;\n}\n\n// ---------------------------------------------------------------------------\n// Runtime — the builder\n// ---------------------------------------------------------------------------\n\n/** How many rows an op can produce, as far as the CLIENT can tell before it\n * runs. Only the empty `insertMany` is knowable, and knowing it is what lets a\n * doomed expectation fail on the line that declared it. */\nconst SKIPPED_OP = -1;\n\nclass TxRowsImpl<Row> implements TxRows<Row> {\n // Present so `isRowsHandle` recognises the object; never read for its value.\n readonly [ROWS] = true;\n // Phantom: the type brand that stops a bare object passing as a TxRows. Never\n // present at run time, which is what `declare` says.\n declare readonly [rowsBrand]: Row;\n private guarded = false;\n\n constructor(\n private readonly builder: TxPlanBuilder,\n private readonly opIndex: number,\n private readonly what: string,\n ) {}\n\n // The type-level `await` guard made real: TS rejects `await rows` at compile\n // time, and reaching this means someone called `.then(...)` by hand.\n then(): never {\n throw new TxRefError(\n `${this.what} cannot be awaited: a transaction callback builds a plan, it ` +\n `does not run statements. Remove the \\`await\\`.`,\n );\n }\n\n expectOne(error: Error): TxRow<Row> {\n this.declareGuard(\"one\", 1, error);\n if (this.opIndex === SKIPPED_OP) throw error;\n return makeRowHandle(this.opIndex) as TxRow<Row>;\n }\n\n expectNone(error: Error): void {\n this.declareGuard(\"none\", 0, error);\n }\n\n expectAtLeast(n: number, error: Error): void {\n assertGuardCount(n, \"expectAtLeast\");\n this.declareGuard(\"atLeast\", n, error);\n if (this.opIndex === SKIPPED_OP && n > 0) throw error;\n }\n\n expectAtMost(n: number, error: Error): void {\n assertGuardCount(n, \"expectAtMost\");\n this.declareGuard(\"atMost\", n, error);\n }\n\n private declareGuard(kind: TxWireGuard[\"kind\"], n: number, error: Error): void {\n if (!(error instanceof Error)) {\n // The error object is the ONLY thing that describes this failure to the\n // caller — the server sends back an index, never a message.\n throw new TxPlanError(\n `${this.what}: an expectation needs the Error to throw when it does not ` +\n `hold (e.g. \\`.expect…(new Conflict(\"already accepted\"))\\`).`,\n );\n }\n if (this.guarded) {\n throw new TxPlanError(\n `${this.what} already has an expectation. One operation carries one ` +\n `expectation; declare the second one on its own operation.`,\n );\n }\n this.guarded = true;\n if (this.opIndex === SKIPPED_OP) return;\n this.builder.attachGuard(this.opIndex, kind, n, error);\n }\n}\n\nfunction assertGuardCount(n: number, fn: string): void {\n if (!Number.isInteger(n) || n < 0) {\n throw new TxPlanError(`${fn}(n) needs a non-negative integer, got ${String(n)}`);\n }\n}\n\n/** Bounds mirrored from the plan executor so an over-sized plan is named here rather\n * than rejected as an opaque 400 after it has crossed the network. */\nconst MAX_OPS = 1000;\nconst MAX_ROWS = 5000;\n\n/**\n * Accumulates ops and the client-side error table while the callback runs.\n *\n * Exported for the runtime and for tests that need the serialised plan without\n * a server; author code never sees it.\n */\nexport class TxPlanBuilder {\n private readonly ops: TxWireOp[] = [];\n /** Errors handed to expectations, indexed by the `slot` the server echoes. */\n private readonly slots: Error[] = [];\n\n /** The table surface handed to the callback. Untyped here; the public\n * `transaction()` signatures put the schema types on top. */\n table(name: string): TxTable<Record<string, unknown>, Record<string, unknown>> {\n return {\n insert: (values) => {\n const encoded = encodeMap(values as Record<string, unknown>, false);\n if (Object.keys(encoded).length === 0) {\n throw new TxPlanError(`${name}.insert() needs at least one column`);\n }\n return this.push({ op: \"insert\", table: name, values: encoded }, `${name}.insert()`);\n },\n\n put: (values, options) => {\n const encoded = encodeMap(values as Record<string, unknown>, false);\n if (Object.keys(encoded).length === 0) {\n throw new TxPlanError(`${name}.put() needs at least one column`);\n }\n if (options.onConflict.length === 0) {\n throw new TxPlanError(`${name}.put() needs at least one onConflict column`);\n }\n return this.push(\n { op: \"upsert\", table: name, values: encoded, onConflict: options.onConflict },\n `${name}.upsert()`,\n );\n },\n\n insertMany: (rows, opts) => {\n if (rows.length === 0) {\n // Nothing to write. Emitting an op would be a guaranteed 400 (the\n // server requires rows), and refusing outright would punish the\n // ordinary \"filtered every candidate out\" case.\n return new TxRowsImpl(this, SKIPPED_OP, `${name}.insertMany()`);\n }\n if (rows.length > MAX_ROWS) {\n throw new TxPlanError(\n `${name}.insertMany() has ${rows.length} rows; the limit is ${MAX_ROWS}. ` +\n `Split the write across requests.`,\n );\n }\n const encoded = rows.map((row) => encodeMap(row as Record<string, unknown>, false));\n assertUniformRows(encoded, name);\n if (opts !== undefined && opts.onConflict.length === 0) {\n throw new TxPlanError(\n `${name}.insertMany() was given a conflict action with no onConflict ` +\n `columns. Postgres matches a collision on columns, so name them.`,\n );\n }\n return this.push(\n {\n op: \"insertMany\",\n table: name,\n rows: encoded,\n // Omitted entirely when no options were given, so the op a plain\n // insertMany produces is byte-identical to the one it produced\n // before this option existed.\n ...(opts !== undefined\n ? { onConflict: opts.onConflict, action: opts.action ?? \"ignore\" }\n : {}),\n },\n `${name}.insertMany()`,\n );\n },\n\n updateWhere: (where, set) => {\n const encodedWhere = encodeFilterMap(where as Record<string, unknown>);\n const encodedSet = encodeMap(set as Record<string, unknown>, true);\n if (Object.keys(encodedWhere).length === 0) {\n throw new TxPlanError(\n `${name}.updateWhere() needs a filter. An update with no filter ` +\n `rewrites the whole table.`,\n );\n }\n if (Object.keys(encodedSet).length === 0) {\n throw new TxPlanError(`${name}.updateWhere() needs at least one column to set`);\n }\n return this.push(\n { op: \"update\", table: name, set: encodedSet, where: encodedWhere },\n `${name}.updateWhere()`,\n );\n },\n\n deleteWhere: (where) => {\n const encodedWhere = encodeFilterMap(where as Record<string, unknown>);\n if (Object.keys(encodedWhere).length === 0) {\n throw new TxPlanError(\n `${name}.deleteWhere() needs a filter. A delete with no filter empties ` +\n `the table.`,\n );\n }\n return this.push(\n { op: \"delete\", table: name, where: encodedWhere },\n `${name}.deleteWhere()`,\n );\n },\n\n select: (where, options) => {\n const op: TxWireOp = { op: \"select\", table: name };\n const encodedWhere = encodeFilterMap((where ?? {}) as Record<string, unknown>);\n if (Object.keys(encodedWhere).length > 0) op.where = encodedWhere;\n if (options?.limit !== undefined) {\n if (!Number.isInteger(options.limit) || options.limit < 0) {\n throw new TxPlanError(\n `${name}.select(): limit needs a non-negative integer, got ${String(options.limit)}`,\n );\n }\n op.limit = options.limit;\n }\n if (options?.lock !== undefined) op.lock = options.lock;\n return this.push(op, `${name}.select()`);\n },\n };\n }\n\n private push(op: TxWireOp, what: string): TxRows<Record<string, unknown>> {\n if (this.ops.length >= MAX_OPS) {\n throw new TxPlanError(\n `this transaction has ${MAX_OPS} operations, which is the limit. Use ` +\n `insertMany() for bulk writes, or split the work across requests.`,\n );\n }\n const index = this.ops.length;\n this.ops.push(op);\n return new TxRowsImpl(this, index, what);\n }\n\n /** Attach an expectation to an op and record its error in the slot table. */\n attachGuard(opIndex: number, kind: TxWireGuard[\"kind\"], n: number, error: Error): void {\n const op = this.ops[opIndex];\n // Unreachable: the index came from `push`. A loud failure beats a silently\n // unguarded write if that ever stops being true.\n if (!op) throw new TxPlanError(`internal: expectation on unknown operation ${opIndex}`);\n const slot = this.slots.length;\n this.slots.push(error);\n op.guard = { kind, n, slot };\n }\n\n /** The serialisable plan. Empty when the callback described no writes. */\n body(): TxPlanBody {\n return { ops: this.ops };\n }\n\n /** The error the server's `slot` selects, or `null` when it names one this\n * plan never declared (a server/client disagreement, not a tenant error). */\n errorForSlot(slot: number): Error | null {\n return this.slots[slot] ?? null;\n }\n}\n\nfunction assertUniformRows(rows: Record<string, TxWireValue>[], table: string): void {\n const first = rows[0];\n if (!first) return;\n const want = Object.keys(first);\n const wantKey = want.join(\",\");\n for (let i = 1; i < rows.length; i++) {\n const got = Object.keys(rows[i] as Record<string, TxWireValue>);\n if (got.join(\",\") !== wantKey) {\n // One statement, one column list. A ragged row would take the DB default\n // for the column it omitted — a write that succeeds and is wrong.\n throw new TxPlanError(\n `${table}.insertMany(): every row must set the same columns. Row 0 sets ` +\n `[${want.join(\", \")}] but row ${i} sets [${got.join(\", \")}]. ` +\n `(A property set to \\`undefined\\` counts as absent — use \\`null\\`.)`,\n );\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Runtime — materialisation\n// ---------------------------------------------------------------------------\n\n/**\n * Replace every handle in the callback's return value with what the server\n * actually produced.\n *\n * Walks arrays and PLAIN objects only. Class instances (a Date, a Zod schema, a\n * domain object) are returned untouched — recursing into them would rebuild them\n * as bare objects, and nothing inside one can be a handle that this SDK created.\n */\nexport function materializeResult(value: unknown, results: TxPlanOpResult[]): unknown {\n const ref = refDescriptor(value);\n if (ref) {\n const row = rowOf(results, ref.op, `\\`${ref.field}\\``);\n if (!(ref.field in row)) {\n throw new TxPlanError(\n `the transaction's operation ${ref.op} returned no column \\`${ref.field}\\`.`,\n );\n }\n return row[ref.field];\n }\n\n const rowOp = rowOpIndex(value);\n if (rowOp !== null) return rowOf(results, rowOp, \"a row\");\n\n if (isRowsHandle(value)) {\n throw new TxPlanError(\n \"an operation result cannot be returned from a transaction callback: its \" +\n \"row count is not known until the plan runs. Declare an expectation \" +\n \"(`.expectOne(err)`) and return the row, or a column of it.\",\n );\n }\n\n if (Array.isArray(value)) return value.map((item) => materializeResult(item, results));\n\n if (isPlainObject(value)) {\n const out: Record<string, unknown> = {};\n for (const [key, item] of Object.entries(value)) out[key] = materializeResult(item, results);\n return out;\n }\n\n return value;\n}\n\nfunction rowOf(results: TxPlanOpResult[], opIndex: number, what: string): Record<string, unknown> {\n const result = results[opIndex];\n if (!result) {\n throw new TxPlanError(\n `the transaction returned no result for operation ${opIndex}, so ${what} ` +\n `cannot be read.`,\n );\n }\n const row = result.rows[0];\n if (!row) {\n // Unreachable through the public API: a handle only exists behind an\n // `expectOne`, and the server rolls back rather than answering 200 with a\n // guard unmet. Loud, because the alternative is `undefined` in tenant data.\n throw new TxPlanError(\n `the transaction's operation ${opIndex} returned no row, so ${what} cannot ` +\n `be read.`,\n );\n }\n return row;\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n if (typeof value !== \"object\" || value === null) return false;\n const proto: unknown = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n}\n\n// ---------------------------------------------------------------------------\n// Runtime — the driver\n// ---------------------------------------------------------------------------\n\n/** What {@link runTxPlan} needs from the runtime: one call, one transaction. */\nexport interface TxPlanTransport {\n txPlan(plan: TxPlanBody): Promise<TxPlanResponse>;\n}\n\n/**\n * Build the plan, send it, and resolve the callback's return value.\n *\n * A callback that throws never reaches the network: there is nothing to roll\n * back because nothing was sent. A callback that describes no writes also skips\n * the round trip entirely.\n *\n * The RETURN type is `unknown` here on purpose. `Materialized<T>` is a compile-\n * time rewrite of the callback's return type, and it belongs on the public\n * `transaction()` signatures where `T` is inferred from the author's callback;\n * threading it through this driver as well would mean inferring `T` twice, from\n * two different positions, and reconciling them. The public wrappers narrow\n * once, at the seam where the value types were erased anyway.\n */\nexport async function runTxPlan<THandle>(\n transport: TxPlanTransport,\n // TUTAMAĞIN TAMAMI, yalnız `tables` DEĞİL. Tutamak artık şema yüzeyini de\n // taşıyor (`tx.public.x`, `tx.<şema>.x`), ve onu BURADA `{ tables }` diye\n // yeniden kurmak o yüzeyi sessizce düşürürdü.\n handle: THandle,\n builder: TxPlanBuilder,\n fn: (tx: THandle) => unknown,\n): Promise<unknown> {\n const returned = fn(handle);\n const body = builder.body();\n if (body.ops.length === 0) {\n return materializeResult(returned, []);\n }\n\n let response: TxPlanResponse;\n try {\n response = await transport.txPlan(body);\n } catch (err) {\n throw translateRejection(err, builder);\n }\n return materializeResult(returned, response.results);\n}\n\n/**\n * Turn the broker's rejection back into the tenant's own error.\n *\n * The server never sees the `Error` an expectation was given — only its slot\n * index — so this is the only place the intended error can be produced. A\n * rejection this SDK does not recognise passes through untouched: inventing an\n * error for it would hide the real failure.\n */\nfunction translateRejection(err: unknown, builder: TxPlanBuilder): unknown {\n if (typeof err !== \"object\" || err === null) return err;\n const rejection = err as TxPlanRejection;\n if (rejection.error_code !== \"tx_guard_failed\" || typeof rejection.slot !== \"number\") {\n return err;\n }\n return builder.errorForSlot(rejection.slot) ?? err;\n}\n","/** A PostgreSQL isolation level supported by the explicit root transaction. */\nexport type TransactionIsolation = \"read committed\" | \"repeatable read\" | \"serializable\";\n\nexport interface AtomicOptions {\n /** Each retry opens a fresh transaction and reruns the complete callback.\n * Defaults to zero. Keep external effects outside it; persist an outbox instead. */\n retry?: number;\n isolation?: TransactionIsolation;\n readOnly?: boolean;\n /** Maximum wait for a PostgreSQL lock. Defaults to 5000 ms. */\n lockTimeoutMs?: number;\n /** PostgreSQL statement timeout; applies to every statement in this scope. */\n statementTimeoutMs?: number;\n /** Total work deadline including queueing and retries. Active Bun queries are\n * cancelled; rollback settles before release. An in-flight COMMIT is awaited. */\n timeoutMs?: number;\n signal?: AbortSignal;\n\n}\n\nexport function retryBudget(value: number | undefined): number {\n const n = value ?? 0;\n if (!Number.isInteger(n) || n < 0 || n > 10) {\n throw new Error(\"transaction retry must be an integer between 0 and 10\");\n }\n return n;\n}\n\nexport function validateAtomicOptions(options: AtomicOptions): void {\n retryBudget(options.retry);\n if (options.isolation !== undefined && ![\"read committed\", \"repeatable read\", \"serializable\"].includes(options.isolation)) {\n throw new Error(\"transaction isolation must be read committed, repeatable read or serializable\");\n }\n if (options.readOnly !== undefined && typeof options.readOnly !== \"boolean\") {\n throw new Error(\"transaction readOnly must be a boolean\");\n }\n for (const name of [\"lockTimeoutMs\", \"statementTimeoutMs\", \"timeoutMs\"] as const) {\n const n = options[name];\n if (n !== undefined && (!Number.isInteger(n) || n < 1 || n > 2_147_483_647)) {\n throw new Error(`transaction ${name} must be a positive integer in milliseconds`);\n }\n }\n if (options.signal !== undefined && (typeof options.signal.aborted !== \"boolean\" || typeof options.signal.addEventListener !== \"function\")) {\n throw new Error(\"transaction signal must be an AbortSignal\");\n }\n}\n\n/** A savepoint cannot replace the enclosing transaction's snapshot or retry COMMIT. */\nexport function assertPlanRetry(options: { retry?: number } | undefined): void {\n if (retryBudget(options?.retry) !== 0) {\n throw new Error(\n \"Database.$transaction is a savepoint plan on the request transaction and cannot retry its snapshot or COMMIT. \" +\n \"Use Database.$atomic(async tx => { ... }, { retry, isolation }) and put all decision reads and writes inside that callback.\",\n );\n }\n}\n","// The wire shape of a declared schema — what the deploy reads.\n//\n// `defineSchema(...)` produces a value full of builders and phantom types, which\n// is the right shape for authoring and the wrong shape for anything outside this\n// process. The deploy is Go: it introspects the live database, diffs it against\n// the declaration, and applies the difference. So the declaration has to leave\n// TypeScript as data, and this file is where that happens.\n//\n// It lives in the SDK because the SDK owns the DSL. The alternative — a script\n// beside the deploy that reaches into `._def` — is a second reading of a private\n// shape, and it drifts the moment a column gains a property: the DSL keeps\n// working, the emitter silently omits it, and the database is missing something\n// nobody can see in the source.\n//\n// The field names below are a CONTRACT with Go's `schema.SchemaJSON`. Renaming\n// one here without renaming it there produces a declaration that parses to\n// something emptier than it was — the failure mode being a column, a policy, or\n// a whole table that quietly never gets created.\n// Politika ifadesinin tel şekli `policy.ts`'te TEK kez bildiriliyor. İki kopya\n// olsaydı biri `exists` düğümünü alır, diğeri almaz ve fark ancak Go tarafı\n// bilmediği bir `kind` gördüğünde ortaya çıkardı.\nimport type { PolicyExpr as PolicyExprJSON } from \"./policy.js\";\nexport type { PolicyExpr as PolicyExprJSON } from \"./policy.js\";\nimport type { ColumnBuilder, ColumnDef } from \"./columns.js\";\nimport type { PolicyDef } from \"./policy.js\";\nimport type { MemoryDecl, SchemaDef, SearchDecl, TableDef } from \"./schema.js\";\n\n/** One column, flattened. Mirrors Go's `schema.ColumnJSON`. */\nexport interface ColumnJSON {\n type: string;\n nullable: boolean;\n primaryKey: boolean;\n defaultValue?: unknown;\n defaultRandom?: boolean;\n defaultNow?: boolean;\n renamedFrom?: string;\n /** See Go's `schema.ColumnJSON.Ignored` — the contraction gate's only signal. */\n ignored?: boolean;\n owns?: boolean;\n references?: { table: string; column: string };\n onDeleteAction?: string;\n /** FR-044: türev FK index'i kapatılmışsa `false`. Bildirilmemişse alan YOK. */\n index?: boolean;\n /** FR-049: kolon increment() ile güncelleniyorsa `true`. Aksi hâlde alan YOK. */\n counter?: boolean;\n enumName?: string;\n enumValues?: string[];\n unique?: boolean;\n dimensions?: number;\n}\n\n/** One RLS policy. Mirrors Go's `schema.PolicyJSON`. */\nexport interface PolicyJSON {\n name: string;\n command: string;\n roles: string[];\n /**\n * `USING (...)` — ham string (kaçış kapağı, FR-028) ya da YAPI (FR-022).\n *\n * Go tarafı ikisini de okur: string olan verbatim emit edilir, yapı olan\n * `generator.go`'da SQL'e çevrilir (C-6). Yapı hâli InitPlan sarmalamasını\n * ve `TO <rol>` daraltmasını GÜVENLE yapılabilir kılan şey — string üstünde\n * regex'le denemek yorum içindeki bir `auth.uid()`'yi de sarmalardı.\n */\n using: string | PolicyExprJSON | null;\n withCheck: string | PolicyExprJSON | null;\n permissive: boolean;\n}\n\n\n/** One table. Mirrors Go's `schema.TableJSON`. */\nexport interface TableJSON {\n /**\n * The schema this table lives in. `public` unless declared otherwise.\n *\n * The table carries it because the diff iterates over KEYS but passes the\n * VALUE around: a bare name inside a qualified key space writes the migration\n * into the wrong schema, silently.\n */\n schema: string;\n name: string;\n columns: Record<string, ColumnJSON>;\n rls: boolean;\n policies: PolicyJSON[];\n primaryKey?: string[];\n uniqueConstraints?: { name: string; columns: string[] }[];\n rawConstraints?: { name: string; up: string; down: string | null }[];\n checks?: { name: string; expr: string }[];\n indexes?: IndexJSON[];\n /**\n * appendOnly (FR-030): tablo yalnız INSERT kabul eder. Sıfır değerde OMIT —\n * bildirmeyen tablolar wire'da bayt-aynı kalır.\n */\n appendOnly?: boolean;\n search?: SearchJSON;\n memory?: MemoryJSON;\n}\n\n/**\n * Bir index'in wire şekli — Go'nun `IndexJSON`'ıyla ALAN-ADI SÖZLEŞMESİ.\n *\n * `name` + `columns` bugünkü hâl; kalanı FR-041…043'ün taşıyıcısı. Hepsi sıfır\n * değerde OMIT edilir: bildirmeyen bir index wire'da eskisiyle bayt-aynı kalır,\n * yoksa dokunulmamış her şema diff'te değişmiş görünür ve her deploy churn üretir.\n */\nexport interface IndexJSON {\n name: string;\n columns: string[];\n /** Partial index koşulu (FR-042) — filtre şekli `WhereFilter` ile aynı. */\n where?: unknown;\n /** İfade index'i (FR-043), ör. `lower(email)`. `columns` ile birlikte kullanılmaz. */\n expression?: string;\n /** Kolon sırası (FR-043). */\n sort?: \"asc\" | \"desc\";\n /** NULL sırası (FR-043). */\n nulls?: \"first\" | \"last\";\n /** Covering index — `INCLUDE (...)` (FR-043). */\n include?: string[];\n}\n\n/** C-11 wire şekli — Go'nun MemoryJSON'ıyla alan-adı sözleşmesi (D-019).\n * Beyansız tablolarda alan OMIT — eski şemalar bayt-aynı (NFR-B1). */\nexport interface MemoryJSON {\n from: string[];\n into: string;\n subject?: string;\n extract: { provider: string; model: string };\n}\n\n/** A whole declaration. Mirrors Go's `schema.SchemaJSON`. */\nexport interface SchemaJSON {\n tables: Record<string, TableJSON>;\n extensions: string[];\n /**\n * Every declared schema, with its HTTP reachability.\n *\n * The flag has nowhere else to live: `/v1/db` must know which schemas are\n * reachable, and introspection must know which schemas the project DECLARED —\n * a live database also contains internal module schemas that are none of the\n * diff's business.\n */\n schemas: SchemaMetaJSON[];\n}\n\nexport interface SchemaMetaJSON {\n name: string;\n exposed: boolean;\n}\n\n/** The definition behind a column, whichever side of the builder it arrives on. */\nfunction defOf(column: ColumnBuilder | ColumnDef): ColumnDef {\n return \"_def\" in column ? column._def : column;\n}\n\nfunction columnToJSON(column: ColumnBuilder | ColumnDef): ColumnJSON {\n const def = defOf(column);\n const out: ColumnJSON = {\n type: def.type,\n nullable: def.nullable,\n primaryKey: def.primaryKey,\n };\n // Every optional field is omitted rather than emitted as undefined: Go\n // distinguishes \"absent\" from \"present and empty\" on several of these, and a\n // `defaultValue: null` is a real default that says NULL.\n if (def.defaultValue !== undefined) out.defaultValue = def.defaultValue;\n if (def.defaultRandom === true) out.defaultRandom = true;\n if (def.defaultNow === true) out.defaultNow = true;\n if (def.renamedFrom !== undefined) out.renamedFrom = def.renamedFrom;\n // Go'daki schema.ColumnJSON'un aynası. `omitempty` karşılığı: yalnız TRUE ise yazılır,\n // böylece işaretsiz bir şemanın JSON'u bu alandan önceki hâliyle byte-eş kalır.\n if (def.ignored === true) out.ignored = true;\n // OWNERSHIP HAS TO CROSS THE WIRE, because the gate that enforces it is on the\n // other side. `ownedByUser()` sets `owns` on the column, and Go's\n // `validateOwnership` reads `ColumnJSON.Owns` to refuse a table that declares\n // two owners — but nothing was carrying the flag between them.\n //\n // Measured on the live cluster: a table with TWO `ownedByUser()` columns\n // pushed clean and both foreign keys landed on `auth.users` ON DELETE CASCADE.\n // The rule existed in the DSL and in the generator; the wire in between said\n // nothing, so the generator saw ZERO ownership columns and had nothing to\n // refuse. A flag with a reader and no writer is a dead wire.\n if (def.owns === true) out.owns = true;\n if (def.references !== undefined) {\n out.references = { table: def.references.table, column: def.references.column };\n }\n if (def.onDeleteAction !== undefined) out.onDeleteAction = def.onDeleteAction;\n // Yalnız `false` taşınıyor: \"bildirilmedi\" ile \"açık\" aynı şey ve wire'a\n // yazmak bildirmeyen her kolonu diff'te değişmiş gösterirdi.\n if (def.index === false) out.index = false;\n if (def.counter === true) out.counter = true;\n if (def.enumName !== undefined) out.enumName = def.enumName;\n if (def.enumValues !== undefined) out.enumValues = [...def.enumValues];\n if (def.unique === true) out.unique = true;\n if (def.dimensions !== undefined) out.dimensions = def.dimensions;\n return out;\n}\n\nfunction policyToJSON(policy: PolicyDef): PolicyJSON {\n return {\n name: policy.name,\n command: policy.command ?? \"all\",\n roles: policy.roles ? [...policy.roles] : [],\n // null rather than omitted: a policy with no USING clause is a different\n // thing from one whose clause the emitter forgot, and Go reads the\n // difference.\n using: policy.using ?? null,\n withCheck: policy.withCheck ?? null,\n permissive: policy.permissive !== false,\n };\n}\n\n/** C-4 wire şekli — Go'nun SearchJSON'ıyla ALAN ADI sözleşmesi (C-5).\n * `mode`/`chunks` yalnız yeni-biçim chunk-modunda emit edilir (D-010);\n * satır-modu ve eski biçim bayt-aynı kalır (NFR-B1). */\nexport interface SearchJSON {\n text?: { columns: string[] };\n vector?: {\n column?: string;\n metric: string;\n embed?: { provider: string; model: string; from: string[]; apiKeyName?: string; dimensions?: number; baseURL?: string };\n staleness?: \"null\" | \"keep\";\n mode?: \"row\" | \"chunks\";\n chunks?: { sizeChars?: number; overlapChars?: number };\n }[];\n /** FR-026: sorgu-yeniden-yazımı haritası — beyan yoksa OMIT (NFR-B1). */\n synonyms?: Record<string, string[]>;\n /** C-1: sonuç yeniden-sıralama beyanı — beyan yoksa OMIT. */\n /** FR-029: geçerlilik türevleri — beyan yoksa OMIT. */\n validity?: boolean;\n}\n\n/** T020 (C-1): iki biçimin de üst-düzey ortak alanları — beyan yoksa OMIT,\n * boş synonyms haritası da OMIT (NFR-B1 baytları kımıldamaz). */\nfunction commonSearchFields(search: SearchDecl, out: SearchJSON): void {\n if (search.synonyms !== undefined && Object.keys(search.synonyms).length > 0) {\n out.synonyms = Object.fromEntries(\n Object.entries(search.synonyms).map(([word, alts]) => [word, [...alts]]),\n );\n }\n if (search.validity === true) out.validity = true;\n}\n\n/** Beyanı normalize eder: vector her zaman DİZİ, metric her zaman dolu (vars. cosine),\n * authoring'deki `from`/`model` wire'da `embed` altında toplanır. Alan yoksa OMIT —\n * search'süz şema bayt-aynı kalır (NFR-006). */\nfunction searchToJSON(search: SearchDecl, vectorColumn: string | undefined): SearchJSON {\n if (search.from !== undefined && search.model !== undefined) {\n // YENİ biçim (D-007): from tek listedir — FTS'i de embed'i de besler.\n // Mod ŞEMADAN türer (D-010): tabloda vector kolonu varsa satır-modu\n // (column yazılır, mode OMIT — eski davranışla aynı wire), yoksa\n // chunk-modu (mode:\"chunks\", column yok — vektörler türev tabloda).\n const out: SearchJSON = {};\n const textCols =\n search.text === false ? undefined : Array.isArray(search.text) && search.text.length > 0 ? search.text : search.from;\n if (textCols !== undefined) out.text = { columns: [...textCols] };\n const v: NonNullable<SearchJSON[\"vector\"]>[number] = { metric: search.metric ?? \"cosine\" };\n if (vectorColumn !== undefined) v.column = vectorColumn;\n v.embed = {\n provider: search.model.provider,\n model: search.model.model,\n from: [...search.from],\n ...(search.model.apiKeyName !== undefined ? { apiKeyName: search.model.apiKeyName } : {}),\n ...(search.model.dimensions !== undefined ? { dimensions: search.model.dimensions } : {}),\n ...(search.model.baseURL !== undefined ? { baseURL: search.model.baseURL } : {}),\n };\n if (search.staleness !== undefined) v.staleness = search.staleness;\n if (vectorColumn === undefined) {\n v.mode = \"chunks\";\n if (search.chunks !== undefined) {\n const c: NonNullable<typeof v.chunks> = {};\n if (search.chunks.size !== undefined && search.chunks.size > 0) c.sizeChars = search.chunks.size;\n if (search.chunks.overlap !== undefined && search.chunks.overlap > 0) c.overlapChars = search.chunks.overlap;\n if (Object.keys(c).length > 0) v.chunks = c;\n }\n }\n out.vector = [v];\n commonSearchFields(search, out);\n return out;\n }\n const out: SearchJSON = {};\n // Eski biçimde text yalnız dizi olabilir (boolean'ı defineSchema zaten\n // reddediyor); Array.isArray hem tipi daraltır hem o sözleşmeyi belgeler.\n if (Array.isArray(search.text) && search.text.length > 0) out.text = { columns: [...search.text] };\n const legs = search.vector === undefined ? []\n : Array.isArray(search.vector) ? search.vector : [search.vector];\n if (legs.length > 0) {\n out.vector = legs.map((leg) => {\n const v: NonNullable<SearchJSON[\"vector\"]>[number] = { metric: leg.metric ?? \"cosine\" };\n if (leg.column !== undefined) v.column = leg.column;\n if (leg.staleness !== undefined) v.staleness = leg.staleness;\n if (leg.model !== undefined) {\n v.embed = {\n provider: leg.model.provider,\n model: leg.model.model,\n from: [...(leg.from ?? [])],\n ...(leg.model.apiKeyName !== undefined ? { apiKeyName: leg.model.apiKeyName } : {}),\n ...(leg.model.dimensions !== undefined ? { dimensions: leg.model.dimensions } : {}),\n ...(leg.model.baseURL !== undefined ? { baseURL: leg.model.baseURL } : {}),\n };\n }\n return v;\n });\n }\n commonSearchFields(search, out);\n return out;\n}\n\nfunction memoryToJSON(m: MemoryDecl): MemoryJSON {\n return {\n from: [...m.from],\n into: m.into,\n ...(m.subject !== undefined ? { subject: m.subject } : {}),\n extract: { provider: m.extract.provider, model: m.extract.model },\n };\n}\n\nfunction tableToJSON(table: TableDef, schemaName: string): TableJSON {\n const columns: Record<string, ColumnJSON> = {};\n for (const [name, column] of Object.entries(table.columns)) {\n columns[name] = columnToJSON(column);\n }\n\n const out: TableJSON = {\n name: table.name,\n schema: schemaName,\n columns,\n // Read, not re-derived. `defineSchema` already resolves the fail-closed\n // default (RLS on unless the author wrote `rls: false`, and forced on by any\n // policy), and a second copy of a SECURITY default is exactly the thing that\n // drifts — the direction it drifted last time was \"expose everything\", and\n // the live proof was one user reading another's rows.\n rls: table.rls,\n // KOŞAN SÜRÜMÜN SÖZÜ TELE ÇIKAR — yoksa daralma kapısı onu göremez.\n // `ColumnJSON.ignored` ile aynı sözleşme: işaretlenmemişse alan YOK.\n ...(table.ignored === true ? { ignored: true } : {}),\n policies: (table.policies ?? []).map(policyToJSON),\n };\n\n if (table.primaryKey !== undefined && table.primaryKey.length > 0) {\n out.primaryKey = [...table.primaryKey];\n }\n if (table.unique !== undefined && table.unique.length > 0) {\n out.uniqueConstraints = table.unique.map((u) => ({ name: u.name, columns: [...u.columns] }));\n }\n if (table.raw !== undefined && table.raw.length > 0) {\n out.rawConstraints = table.raw.map((r) => ({\n name: r.name,\n up: r.up,\n down: r.down ?? null,\n }));\n }\n if (table.checks !== undefined && table.checks.length > 0) {\n out.checks = table.checks.map((c) => ({ name: c.name, expr: c.expr }));\n }\n if (table.indexes !== undefined && table.indexes.length > 0) {\n out.indexes = table.indexes.map((i) => {\n // `columns` expression-index'te YOKTUR (ikisi birbirinin alternatifi).\n // Boş dizi ile taşınır: Go tarafı `expression` doluysa onu kullanır.\n const ix: IndexJSON = { name: i.name, columns: i.columns ? [...i.columns] : [] };\n if (i.where !== undefined) ix.where = i.where;\n if (i.expression !== undefined) ix.expression = i.expression;\n if (i.sort !== undefined) ix.sort = i.sort;\n if (i.nulls !== undefined) ix.nulls = i.nulls;\n if (i.include !== undefined) ix.include = [...i.include];\n return ix;\n });\n }\n // Sıfır değerde YAZILMAZ: `appendOnly: false` ile \"bildirilmemiş\" wire'da\n // ayırt edilemez olmalı, yoksa her eski şema diff'te değişmiş görünür.\n if (table.appendOnly === true) out.appendOnly = true;\n if (table.search !== undefined) {\n // D-010 mod kararının tek girdisi: tabloda dimensions'lı (vector) kolon\n // adı. Birden çoksa ilkini yazmak YANLIŞ olurdu — o durum eski biçimin\n // işidir ve yeni biçim + çoklu vector kolonu apply'da reddedilir.\n const vectorColumn = Object.entries(columns).find(([, c]) => c.dimensions !== undefined)?.[0];\n const sj = searchToJSON(table.search, vectorColumn);\n if (sj.text !== undefined || sj.vector !== undefined) out.search = sj;\n }\n if (table.memory !== undefined) {\n out.memory = memoryToJSON(table.memory);\n }\n return out;\n}\n\n/**\n * The key a table answers to in `SchemaJSON.tables`.\n *\n * A public table is BARE, anything else is schema-qualified. This is not a new\n * convention: `RefJSON.Table` already carries `auth.users`, and introspection\n * already returns a public referent bare and a non-public one qualified. Adding\n * a second key space would make two interpreters of the same database.\n */\nexport function qualifiedTableKey(schemaName: string, tableName: string): string {\n // An ABSENT schema means public, exactly as Go's `isPublicSchema` says. This\n // branch used to be missing here and present in the engine's private copy, so\n // the two writers of one rule answered DIFFERENTLY for `\"\"`: one qualified it\n // into a schema literally named the empty string, the other left it bare.\n return schemaName === \"\" || schemaName === \"public\" ? tableName : `${schemaName}.${tableName}`;\n}\n\n/**\n * Serialize declared schemas into the JSON the deploy applies.\n *\n * Takes every schema the project declares — one file per schema — because a\n * cross-schema foreign key can only be checked when both ends are in hand.\n */\nexport function toSchemaJSON(schemas: readonly SchemaDef[]): SchemaJSON {\n const tables: Record<string, TableJSON> = {};\n const extensions: string[] = [];\n const meta: SchemaMetaJSON[] = [];\n const seen = new Set<string>();\n for (const schema of schemas) {\n if (seen.has(schema.name)) {\n throw new Error(`two schemas declare the name \"${schema.name}\" — schema names must be unique`);\n }\n seen.add(schema.name);\n for (const table of Object.values(schema.tables)) {\n const json = tableToJSON(table, schema.name);\n tables[qualifiedTableKey(schema.name, json.name)] = json;\n }\n extensions.push(...(schema.extensions ?? []));\n // The schema list travels because the flag has nowhere else to live: without\n // it /v1/db cannot know which schemas are reachable over HTTP, and nothing\n // downstream can read the DECLARED schema set that introspection needs.\n meta.push({ name: schema.name, exposed: schema.exposed });\n }\n return { tables, extensions: [...new Set(extensions)], schemas: meta };\n}\n","/** PostgreSQL protocol identifiers, shared by error mapping and retry policy. */\nexport const SQLSTATE = Object.freeze({\n serializationFailure: \"40001\",\n deadlockDetected: \"40P01\",\n queryCancelled: \"57014\",\n commandGuardFailed: \"PBC01\",\n} as const);\n\n/** These errors confirm that PostgreSQL aborted the transaction. A connection\n * failure does not: the COMMIT may already have succeeded. */\nexport function isTransactionRollbackState(state: unknown): boolean {\n return state === SQLSTATE.serializationFailure || state === SQLSTATE.deadlockDetected;\n}\n","import { SQLSTATE, isTransactionRollbackState } from \"./db/sqlstate.js\";\n\n/**\n * The brand that identifies an HttpError ACROSS SDK instances.\n *\n * A process legitimately holds more than one copy of this SDK — the runtime\n * loads the engine from its own node_modules while the tenant's bundle carries\n * an inlined copy, which is why the controller registry and the error registry\n * are both anchored on `Symbol.for`. The one place that did not follow the\n * pattern was the engine's catch: `err instanceof HttpError` compares CLASS\n * IDENTITY, so a `throw new NotFound()` from the bundle's copy did not match\n * the engine's copy and every typed error in every deployed backend degraded to\n * `500 internal_error`. Measured through the edge on a real deploy: a route\n * throwing `NotFound` answered 500 while the runtime's own log printed the\n * error object with `status: 404` right beside it.\n *\n * `Symbol.for` puts this in the cross-realm registry, so every copy of the SDK\n * agrees on it by VALUE rather than by identity.\n */\nexport const HTTP_ERROR_BRAND: unique symbol = Symbol.for(\"palbase.backend.httpError\");\n\n/**\n * Set on an `HttpError` the ENGINE built out of a driver failure, as opposed to\n * one the author constructed to ANSWER a request.\n *\n * The distinction cannot be read off the status, and 409 is why. The scaffold\n * teaches `throw new Conflict(\"title already taken\")` as the way to answer\n * (template/AGENTS.md), and the engine raises `UniqueViolation` — also a 409 —\n * when a write hits a unique index. Logging by status therefore either loses the\n * engine's event or writes an \"unhandled\" line every time an author takes the\n * documented path. Measured: it did the second.\n *\n * `Symbol.for` so the mark survives the bundle/runtime SDK split, the same way\n * {@link HTTP_ERROR_BRAND} does.\n */\nexport const ENGINE_RAISED: unique symbol = Symbol.for(\"palbase.backend.engineRaised\") as never;\n\n/** Mark `e` as engine-raised and return it, so a conversion site reads as one expression. */\nexport function markEngineRaised<E extends object>(e: E): E {\n (e as Record<symbol, unknown>)[ENGINE_RAISED] = true;\n return e;\n}\n\n/** Whether the engine built this error, rather than the author throwing it to answer. */\nexport function isEngineRaised(e: unknown): boolean {\n return typeof e === \"object\" && e !== null && (e as Record<symbol, unknown>)[ENGINE_RAISED] === true;\n}\n\n/**\n * Whether a thrown value is an HttpError from ANY copy of this SDK.\n *\n * The shape is checked as well as the brand: the brand says \"this claims to be\n * one of ours\", the fields say the envelope can actually be built from it, and\n * a half-formed object must fall through to the 500 path rather than produce a\n * malformed response.\n */\nexport function isHttpError(err: unknown): err is HttpError {\n if (typeof err !== \"object\" || err === null) return false;\n const e = err as Record<PropertyKey, unknown>;\n return (\n e[HTTP_ERROR_BRAND] === true &&\n typeof e.status === \"number\" &&\n typeof e.error === \"string\" &&\n typeof e.errorDescription === \"string\"\n );\n}\n\n/** HTTP error with structured error response format.\n *\n * The base class for the throwable error classes (`PalError`, `Conflict`,\n * `NotFound`, …). Construct one directly with `throw new HttpError(404,\n * \"todo_not_found\", \"No such todo\")`, or throw a named subclass\n * (`throw new NotFound(\"todo not found\")`). The runtime catches any `HttpError`\n * and emits the standard envelope; on the wire (and to iOS) it surfaces as\n * `BackendError.server(code, status, message, requestId)`.\n *\n * The optional `data` field carries a structured payload alongside the\n * standard envelope — for errors that need to ship extra context\n * (e.g. `new Conflict(\"locked\", \"title_locked\", { retryAfter: 30 })`). It rides\n * through to the iOS typed enum's associated value.\n */\nexport class HttpError extends Error {\n public readonly status: number;\n public readonly error: string;\n public readonly errorDescription: string;\n public readonly data?: unknown;\n /** See {@link HTTP_ERROR_BRAND} — how the engine recognises this across SDK copies. */\n public readonly [HTTP_ERROR_BRAND] = true;\n\n constructor(status: number, error: string, errorDescription: string, data?: unknown) {\n super(errorDescription);\n this.name = \"HttpError\";\n this.status = status;\n this.error = error;\n this.errorDescription = errorDescription;\n if (data !== undefined) {\n this.data = data;\n }\n }\n\n /**\n * Serialize to the standard Palbase error response format.\n * The `requestId` is injected by the runtime layer from the request context.\n * When called without arguments (e.g. JSON.stringify), request_id is omitted.\n * When `data` is set, it is appended as a strict-superset field.\n */\n toJSON(requestId?: string): {\n error: string;\n error_description: string;\n status: number;\n request_id?: string;\n data?: unknown;\n } {\n const result: {\n error: string;\n error_description: string;\n status: number;\n request_id?: string;\n data?: unknown;\n } = {\n error: this.error,\n error_description: this.errorDescription,\n status: this.status,\n };\n if (requestId) {\n result.request_id = requestId;\n }\n if (this.data !== undefined) {\n result.data = this.data;\n }\n return result;\n }\n}\n\n/**\n * Throw with a custom HTTP status + wire code. The general-purpose escape hatch\n * when none of the named classes (`Conflict`/`NotFound`/…) fits.\n *\n * @example\n * throw new PalError(418, \"teapot\", \"I'm a teapot\");\n */\nexport class PalError extends HttpError {\n constructor(status: number, code: string, description: string, data?: unknown) {\n super(status, code, description, data);\n this.name = \"PalError\";\n }\n}\n\n/** Base for the named status classes. Each subclass fixes its HTTP status; the\n * `code` defaults to the class's canonical wire code (overridable), and the\n * `message` defaults to a human-readable label (overridable). */\nabstract class NamedHttpError extends HttpError {\n protected constructor(\n status: number,\n defaultCode: string,\n name: string,\n message?: string,\n code?: string,\n data?: unknown,\n ) {\n super(status, code ?? defaultCode, message ?? defaultMessage(name), data);\n this.name = name;\n }\n}\n\n/** Derive a default human-readable message from a class name\n * (\"NotFound\" → \"Not found\", \"TooManyRequests\" → \"Too many requests\"). */\nfunction defaultMessage(name: string): string {\n const spaced = name.replace(/([a-z0-9])([A-Z])/g, \"$1 $2\");\n return spaced.charAt(0).toUpperCase() + spaced.slice(1).toLowerCase();\n}\n\n/**\n * 400 — the request was malformed or failed validation. Carries a fixed typed\n * payload: `new BadRequest({ fields: [{ field: \"email\", message: \"invalid\" }] })`.\n * The shape is declared once in the SDK so codegen surfaces `error.data.fields`\n * typed on the client.\n */\nexport class BadRequest extends NamedHttpError {\n public declare readonly data: BadRequestData;\n constructor(data: BadRequestData, message?: string) {\n super(400, \"bad_request\", \"BadRequest\", message, undefined, data);\n }\n}\n\n/** 401 — the caller is not authenticated. */\nexport class Unauthorized extends NamedHttpError {\n constructor(message?: string, code?: string, data?: unknown) {\n super(401, \"unauthorized\", \"Unauthorized\", message, code, data);\n }\n}\n\n/** 403 — the caller is authenticated but not allowed. */\nexport class Forbidden extends NamedHttpError {\n constructor(message?: string, code?: string, data?: unknown) {\n super(403, \"forbidden\", \"Forbidden\", message, code, data);\n }\n}\n\n/** 404 — the requested resource does not exist. */\nexport class NotFound extends NamedHttpError {\n constructor(message?: string, code?: string, data?: unknown) {\n super(404, \"not_found\", \"NotFound\", message, code, data);\n }\n}\n\n/** 409 — the request conflicts with the current state. */\nexport class Conflict extends NamedHttpError {\n constructor(message?: string, code?: string, data?: unknown) {\n super(409, \"conflict\", \"Conflict\", message, code, data);\n }\n}\n\n/**\n * 409 — a write was refused because it would duplicate an existing row.\n * Carries the NAME of the unique constraint Postgres named (`users_email_key`).\n *\n * The engine produces it: a statement rejected with SQLSTATE `23505` is\n * converted here rather than surfacing as an opaque driver error (see\n * `engine/db.ts`, `diagnosingDriver`). What that removes is the string match —\n * before this, the only way to act on a duplicate was to test the driver\n * message for \"duplicate key value violates unique constraint\", a contract\n * nobody signed that breaks on a Postgres upgrade, a locale, or a constraint\n * rename, silently and in production.\n *\n * THE NAME IS A FIELD AND STAYS OUT OF THE DEFAULT MESSAGE. The two are not\n * the same audience. `constraint` is read by the code that catches this — the\n * developer, who already knows the schema. `errorDescription` is the HTTP\n * response body, and an UNCAUGHT duplicate puts it in front of the\n * application's end user: `users_email_key` there discloses how the schema is\n * built to whoever sent the request. The platform's own data API took the same\n * decision one surface over and wrote down why —\n * `v2/internal/modules/database/internal/handler/pgerror.go:83-87` collapses\n * every 23xxx to a generic conflict, \"never disclose the constraint/column\n * name\". A thrower who WANTS the name on the wire passes it deliberately\n * (`new UniqueViolation(c, \\`\\${c} already exists\\`)`, or through `data`).\n *\n * @example\n * try {\n * await Database.public.users.insert({ email });\n * } catch (e) {\n * if (UniqueViolation.is(e) && e.constraint === \"users_email_key\") {\n * throw new Conflict(\"That email is taken\", \"email_taken\");\n * }\n * throw e;\n * }\n */\nexport class UniqueViolation extends Conflict {\n /**\n * Whether `e` is a unique violation — REGARDLESS of which copy of this SDK\n * constructed it.\n *\n * Use this instead of `instanceof`. Measured on a live stack: a controller\n * bundle INLINES its own copy of `@palbase/backend`, and the engine that\n * raises this error is the runtime's copy. Two copies, two class identities,\n * and `e instanceof UniqueViolation` is false in the one place a caller\n * writes it — a check that reads as correct and silently never matches.\n */\n static is(e: unknown): e is UniqueViolation {\n return (\n typeof e === \"object\" &&\n e !== null &&\n (e as { name?: unknown }).name === \"UniqueViolation\" &&\n typeof (e as { constraint?: unknown }).constraint === \"string\"\n );\n }\n\n /** The unique constraint the statement violated, as Postgres named it.\n * `\"\"` when the driver did not say which — see `engine/db.ts`. */\n public readonly constraint: string;\n\n constructor(constraint: string, message?: string, code?: string, data?: unknown) {\n super(message ?? \"Unique constraint violated\", code ?? \"unique_violation\", data);\n this.name = \"UniqueViolation\";\n this.constraint = constraint;\n }\n}\n\n/**\n * Eşzamanlılık yüzünden BAŞARISIZ OLAN, ama TEKRAR DENENİRSE başarılı olabilecek\n * hataların ortak yüzeyi (FR-036).\n *\n * `retryable: true` bir tahmin değil, Postgres'in söylediği şey: `40001` ve\n * `40P01` \"bu işlemi baştan çalıştır\" anlamına gelir. Kümenin DAR tutulması\n * kasıtlı — `23505` buraya girseydi, tekrar denemek aynı cevabı verir ve\n * döngü sonsuza kadar dönerdi.\n */\nexport interface RetryableError extends Error {\n readonly retryable: true;\n /** Beş karakterlik SQLSTATE — hangi eşzamanlılık hatası olduğunu SÖYLER. */\n readonly sqlstate: string;\n}\n\n/**\n * `e` tekrar denenebilir mi?\n *\n * `instanceof` DEĞİL şekil kontrolü — ve sebebi ÖLÇÜLMÜŞ (bkz. {@link\n * UniqueViolation.is}): bir controller bundle'ı kendi `@palbase/backend`\n * kopyasını inline'lıyor, hatayı fırlatan motor ise runtime'ın kopyası. İki\n * sınıf kimliği, ve `e instanceof SerializationFailure` yazan tek yerde\n * sessizce hiç eşleşmiyor.\n */\nexport function isRetryable(e: unknown): e is RetryableError {\n return (\n typeof e === \"object\" &&\n e !== null &&\n (e as { retryable?: unknown }).retryable === true &&\n isTransactionRollbackState((e as { sqlstate?: unknown }).sqlstate)\n );\n}\n\n/**\n * `40001 serialization_failure` — SERIALIZABLE ya da REPEATABLE READ altında\n * eşzamanlı bir işlem bu işlemi geçersiz kıldı.\n *\n * D-016: bu hata BLOKLANMIYOR, FIRLATILIYOR. Retry'sız bir izolasyon\n * yükseltmesi sunmak defect'tir — kullanıcıya çalışmayan bir düğme vermektir:\n * SERIALIZABLE'a çıkıp `40001`'i yakalamayan kod, önceden çalışan işlemleri\n * rastgele kaybetmeye başlar.\n */\nexport class SerializationFailure extends Conflict implements RetryableError {\n public readonly retryable = true as const;\n public readonly sqlstate: string;\n\n static is(e: unknown): e is SerializationFailure {\n return (\n typeof e === \"object\" && e !== null &&\n (e as { name?: unknown }).name === \"SerializationFailure\"\n );\n }\n\n constructor(sqlstate: string = SQLSTATE.serializationFailure, message?: string, data?: unknown) {\n super(\n message ??\n \"işlem eşzamanlı bir işlemle serileştirilemedi — aynı işlemi baştan çalıştırın \" +\n \"(karar okumaları ve yazmaları $atomic içine alıp { retry: n } verin)\",\n \"serialization_failure\",\n data,\n );\n this.name = \"SerializationFailure\";\n this.sqlstate = sqlstate;\n }\n}\n\n/**\n * `40P01 deadlock_detected` — iki işlem birbirinin kilidini bekliyordu;\n * Postgres birini seçip iptal etti.\n *\n * Bu hatayı GÖRMEK bir tasarım sinyali: kilit sırası deterministik değilse\n * tekrar denemek yalnız maliyeti öteler. `Database.$lockRows(...)` (FR-035)\n * ya da çok satırlı yazmanın CTE'si (FR-015) sırayı sabitler.\n */\nexport class DeadlockDetected extends Conflict implements RetryableError {\n public readonly retryable = true as const;\n public readonly sqlstate: string;\n\n static is(e: unknown): e is DeadlockDetected {\n return (\n typeof e === \"object\" && e !== null &&\n (e as { name?: unknown }).name === \"DeadlockDetected\"\n );\n }\n\n constructor(sqlstate: string = SQLSTATE.deadlockDetected, message?: string, data?: unknown) {\n super(\n message ??\n \"deadlock: iki işlem birbirinin kilidini bekledi ve bu işlem iptal edildi — \" +\n \"kilit sırasını sabitlemek için Database.$lockRows(tablo, id'ler) kullanın\",\n \"deadlock_detected\",\n data,\n );\n this.name = \"DeadlockDetected\";\n this.sqlstate = sqlstate;\n }\n}\n\n/** A single field-level validation failure carried by {@link BadRequest}. */\nexport interface FieldError {\n /** The offending field's name (dotted path for nested fields). */\n field: string;\n /** Human-readable reason the field failed. */\n message: string;\n}\n\n/** The fixed, typed payload {@link BadRequest} ships. */\nexport interface BadRequestData {\n /** The fields that failed validation. */\n fields: FieldError[];\n}\n\n/** The fixed, typed payload {@link TooManyRequests} ships. */\nexport interface TooManyRequestsData {\n /** Seconds the caller should wait before retrying. */\n retryAfter: number;\n}\n\n/**\n * 429 — the caller has exceeded the rate limit. Carries a fixed typed payload:\n * `new TooManyRequests({ retryAfter: 30 })`. The shape is declared once in the\n * SDK (error-registry pre-seed) so codegen surfaces `error.data.retryAfter`\n * typed on the client — no per-project definition needed.\n */\nexport class TooManyRequests extends NamedHttpError {\n public declare readonly data: TooManyRequestsData;\n constructor(data: TooManyRequestsData, message?: string) {\n super(429, \"too_many_requests\", \"TooManyRequests\", message, undefined, data);\n }\n}\n","/**\n * engine/config.ts — settings from the environment, and the gate that refuses\n * to boot without them.\n *\n * A mandatory module that is not configured must stop the process, by name.\n * The failure this prevents is the expensive one: a stack that boots, passes\n * its probes, and answers 500 on first contact — where the missing value is\n * discovered by a customer rather than by the operator who could fix it.\n *\n * Database and Auth are mandatory. That is a product decision (2026-08-14), not\n * a technical necessity: a backend whose data layer or whose notion of \"who is\n * calling\" is undefined has nothing safe to do with a request.\n */\n\n/** Everything the engine needs to serve. Built once, at boot, never re-read. */\nexport interface EngineConfig {\n /** Postgres connection string. MANDATORY. */\n databaseUrl: string;\n /** Where this stack publishes its token signing keys. MANDATORY. */\n authJwksUrl: string;\n /** When set, a token whose `iss` differs is rejected. */\n authIssuer?: string;\n /** Base URL of the module surface (`/v1/*`, `/auth/*`). Empty ⇒ module\n * singletons throw a named error on first use rather than silently no-op. */\n moduleBaseUrl: string;\n /**\n * The address CLIENTS reach this stack at — `https://<ref>.palbase.studio` in\n * the cloud, whatever domain the certificate is for when self-hosted.\n *\n * NOT `moduleBaseUrl`, and the distinction is the whole point: that one is\n * this process's internal route to palsvc (`http://127.0.0.1:8080`), which\n * resolves nowhere outside the pod. A public object URL has to survive\n * leaving the response body, so it cannot be built from the internal one.\n *\n * Only the operator knows this value, so only the operator sets it\n * (`PALBASE_PUBLIC_ORIGIN`). Empty ⇒ `Storage…getPublicUrl()` throws a named\n * error, the same way an unconfigured module does.\n */\n publicOrigin: string;\n /** Shared secret storage signs its internal upload calls with. Empty means\n * uploads are not wired, and those calls are refused. */\n uploadSecret: string;\n /** Publishable key, sent as `apikey` on module calls. */\n anonKey: string;\n /** Secret key. Used for privileged module calls. */\n serviceRoleKey: string;\n /** Optional dedicated cursor encryption secret, shared by all replicas. */\n cursorSecret?: string;\n /** Install the invoker-only PostgreSQL command helper at boot. Requires DDL\n * rights on the connection role; execution retains each request's RLS role. */\n enableCommands?: boolean;\n /** HMAC the realtime broadcast token is signed with. Empty ⇒ broadcast\n * returns a clear `realtime_unconfigured` error instead of failing silently. */\n realtimeSecret: string;\n port: number;\n /** The Postgres role each request is bound to. RLS policies are written\n * against it, so changing it changes who the database thinks is asking. */\n dbRole: string;\n /**\n * The Postgres role `Database.$asService()` is bound to. It is the one that\n * carries BYPASSRLS, which is the whole of what \"as service\" means — a name\n * pointing at a role without it does not fail, it returns fewer rows.\n *\n * Configurable for the same reason `dbRole` is, and beside it on purpose: a\n * stack that renames one of the pair must rename both, or the request and its\n * service sibling stop being two identities of the same installation.\n */\n dbServiceRole: string;\n poolMax: number;\n /** Internal engine/core deployment policy; application CRUD has no capacity options. */\n databaseAdmission?: Omit<import(\"./admission.js\").DatabaseAdmissionOptions, \"concurrency\">;\n databaseDiagnostics?: import(\"../db/diagnostics.js\").DatabaseDiagnosticsOptions;\n}\n\n/**\n * THE ENVIRONMENT THIS STACK WAS HANDED IS UNUSABLE. Carries the missing names.\n *\n * ONLY the environment. A refusal about the author's own declarations is\n * `DeclarationRefused` (see `src/refusals.ts`) and the difference is not\n * severity, it is the CURE: no push fixes a missing DATABASE_URL, so the\n * runtime must keep treating this one as fatal rather than waiting for an\n * artifact that would change nothing.\n */\nexport class BootRefused extends Error {\n readonly missing: readonly string[];\n constructor(missing: readonly string[], message: string) {\n super(message);\n this.name = \"BootRefused\";\n this.missing = missing;\n }\n}\n\nconst MANDATORY: ReadonlyArray<{ key: string; what: string }> = [\n { key: \"DATABASE_URL\", what: \"the stack's Postgres (Database module)\" },\n { key: \"AUTH_JWKS_URL\", what: \"where this stack publishes its token signing keys (Auth module)\" },\n];\n\n/**\n * Read the engine's settings, or refuse.\n *\n * @throws {BootRefused} naming every missing mandatory value at once — one\n * restart per missing variable is a bad way to learn what a stack needs.\n */\nexport function loadConfig(env: Record<string, string | undefined>): EngineConfig {\n const missing = MANDATORY.filter((m) => !env[m.key]?.trim()).map((m) => m.key);\n if (missing.length > 0) {\n const detail = MANDATORY.filter((m) => missing.includes(m.key))\n .map((m) => ` ${m.key.padEnd(16)}${m.what}`)\n .join(\"\\n\");\n throw new BootRefused(\n missing,\n `boot refused: mandatory module not configured — missing ${missing.join(\", \")}.\\n${detail}`,\n );\n }\n\n const port = Number(env.PORT ?? 3000);\n if (!Number.isInteger(port) || port < 0 || port > 65535) {\n throw new BootRefused([], `boot refused: PORT is not a valid port number (got ${env.PORT}).`);\n }\n const poolMax = Number(env.DB_POOL_MAX ?? 10);\n if (!Number.isInteger(poolMax) || poolMax < 1) {\n throw new BootRefused([], `boot refused: DB_POOL_MAX must be a positive integer (got ${env.DB_POOL_MAX}).`);\n }\n const capacityNumber = (key: string, minimum: number, maximum: number): number | undefined => {\n if (env[key] === undefined) return undefined;\n const value = Number(env[key]);\n if (!Number.isSafeInteger(value) || value < minimum || value > maximum) throw new BootRefused([], `boot refused: ${key} must be between ${minimum} and ${maximum}.`);\n return value;\n };\n const queueLimit = capacityNumber(\"PALBASE_DB_QUEUE_LIMIT\", 0, 10000);\n const queueTimeoutMs = capacityNumber(\"PALBASE_DB_QUEUE_TIMEOUT_MS\", 1, 60000);\n const tenantClaim = env.PALBASE_DB_TENANT_CLAIM;\n if (tenantClaim !== undefined && !/^[a-zA-Z][a-zA-Z0-9_]{0,63}$/.test(tenantClaim)) throw new BootRefused([], \"boot refused: PALBASE_DB_TENANT_CLAIM must be a top-level trusted claim name.\");\n\n return {\n databaseUrl: env.DATABASE_URL!.trim(),\n authJwksUrl: env.AUTH_JWKS_URL!.trim(),\n authIssuer: env.AUTH_ISSUER?.trim() || undefined,\n moduleBaseUrl: (env.MODULE_BASE_URL ?? \"\").replace(/\\/+$/, \"\"),\n publicOrigin: (env.PALBASE_PUBLIC_ORIGIN ?? \"\").trim().replace(/\\/+$/, \"\"),\n // The secret storage signs its two internal calls with (authorize, and the\n // completion that runs an @Upload handler). Empty means uploads are not\n // wired, and both calls REFUSE — an unsigned completion would let anyone\n // who knows a route path invent an upload that never happened.\n uploadSecret: env.PALBASE_UPLOAD_SECRET ?? \"\",\n anonKey: env.PALBASE_ANON_KEY ?? \"\",\n serviceRoleKey: env.PALBASE_SERVICE_ROLE_KEY ?? \"\",\n cursorSecret: env.PALBASE_CURSOR_SECRET,\n enableCommands: env.PALBASE_DB_COMMANDS === \"true\",\n realtimeSecret: env.REALTIME_INGESTION_SECRET ?? \"\",\n port,\n dbRole: env.DB_ROLE ?? \"backend_authenticated\",\n // Verified against the stack that provisions them, not from memory: the six\n // roles and their attributes are declared in v2/internal/migrate/provision.go\n // (`roleBackendServiceRole = \"backend_service_role\"`, NOLOGIN BYPASSRLS),\n // and the live database agrees (pg_roles.rolbypassrls = true).\n dbServiceRole: env.DB_SERVICE_ROLE ?? \"backend_service_role\",\n poolMax,\n databaseAdmission: { ...(queueLimit === undefined ? {} : { queueLimit }),\n ...(queueTimeoutMs === undefined ? {} : { queueTimeoutMs }), ...(tenantClaim === undefined ? {} : { tenantClaim }) },\n ...(env.PALBASE_DB_DIAGNOSTICS === \"true\" ? { databaseDiagnostics: {\n onComplete: (diagnostics: import(\"../db/diagnostics.js\").DatabaseDiagnostics) => {\n console.log(\"palbase.database\", JSON.stringify(diagnostics));\n },\n } } : {}),\n };\n}\n","/**\n * The two ways a stack refuses to boot — and they are two because their CURES\n * are two.\n *\n * A LEAF MODULE ON PURPOSE. `db/` does not import from `engine/` and must not\n * start: the schema layer is below the engine, and a refusal both of them raise\n * cannot live in either. Anything imported here would invert that.\n *\n * WHY THE SPLIT EXISTS AT ALL — measured live on 2026-09-04.\n *\n * `8qitbtucm` ran for days on an image whose `setSchema` did not build\n * relations. Moved onto one that does, the same artifact hit\n * `buildRelations` at boot, threw a bare `Error`, and the runtime — which waits\n * only on its own `ArtifactRefused` — treated it as fatal. The supervisor took\n * the pod down, palsvc with it. CrashLoopBackOff, back-off 5m, and palsvc is\n * THE PROCESS THAT ACCEPTS THE PUSH the message asks for.\n *\n * That is verbatim the lesson `v2/runtime/src/loader.ts` already carries for\n * ABI refusals: *\"the cure was named in the error and made impossible by the\n * exit that carried it.\"* It cost a tenant a third time because the second\n * refusal had no type to be recognised by.\n *\n * SO THE RULE IS THE CURE, NOT THE SEVERITY:\n *\n * {@link DeclarationRefused} — what was PUSHED cannot be built. Restarting\n * re-reads the same bytes and fails identically; only a new artifact\n * changes the answer. The runtime WAITS on this, keeps palsvc alive, and\n * says the reason out loud.\n *\n * {@link BootRefused} — the ENVIRONMENT this stack was handed is unusable\n * (no DATABASE_URL, an unparseable PORT, no SQL driver). No push fixes it;\n * waiting for one would be a lie told in a log line forever. Stays fatal.\n *\n * NOT A MESSAGE PATTERN. The runtime's loader already says why: *\"The\n * distinction is the loader's TYPE, not a pattern over its wording.\"* A gate\n * that reads wording drifts from the thing it claims to measure the first time\n * someone improves an error message.\n */\n\n/**\n * The tag that survives a realm boundary.\n *\n * `instanceof` compares constructor identity, and identity is per module\n * instance. In the pod today the runtime and the bundle share one install\n * (measured: both frames resolve to `/app/node_modules/@palbase/backend`), so\n * `instanceof` would work — but it works by a coincidence of packaging, and a\n * bundle that ever carries its own copy would make every declaration refusal\n * silently fatal again. `Symbol.for` reads from the process-wide registry, so\n * the tag means the same thing in every copy.\n *\n * Exported so the runtime can recognise the refusal without importing the\n * class — see {@link isDeclarationRefused}.\n */\nexport const DECLARATION_REFUSAL = Symbol.for(\"palbase.backend.declarationRefusal\");\n\n/**\n * What was pushed cannot be built. The cure is a NEW ARTIFACT.\n *\n * Thrown by the declaration layer — relation naming, ownership, entry points —\n * wherever a fact about the author's code makes the app impossible to\n * construct. Never thrown for anything the environment could change.\n */\nexport class DeclarationRefused extends Error {\n /** @see DECLARATION_REFUSAL — realm-safe, unlike `instanceof`. */\n readonly [DECLARATION_REFUSAL] = true as const;\n\n constructor(message: string) {\n super(message);\n this.name = \"DeclarationRefused\";\n }\n}\n\n/**\n * True for a refusal whose only cure is a new artifact — across realms.\n *\n * Takes `unknown` because every caller is a `catch`. A non-object, a null, a\n * plain `Error`: all false, and false is the safe answer — it means \"keep\n * treating this as fatal\", which is what the code did before this type existed.\n */\nexport function isDeclarationRefused(e: unknown): e is DeclarationRefused {\n return typeof e === \"object\" && e !== null && (e as Record<symbol, unknown>)[DECLARATION_REFUSAL] === true;\n}\n","/**\n * engine/auth.ts — verifying the stack's own access tokens.\n *\n * The engine does this itself rather than trusting a header stamped upstream.\n * In the isolate architecture a gateway verified the token and the runtime read\n * the result; a backend that boots on its own has no such upstream, so the\n * verification lives here — against the keys the stack publishes.\n *\n * Deliberately narrow: ES256 over P-256, which is what palauth mints. An\n * unrecognised `alg` is refused rather than accommodated, because the classic\n * JWT break is a verifier that is helpful about algorithms.\n */\n\n/** A JSON Web Key, narrowed to the EC keys this verifier accepts. */\ninterface EcJwk {\n kid: string;\n kty: string;\n crv: string;\n x: string;\n y: string;\n}\n\n/** The claims the engine reads. Everything else rides along untyped. */\nexport interface VerifiedClaims extends Record<string, unknown> {\n sub?: string;\n role?: string;\n email?: string;\n email_verified?: boolean;\n exp?: number;\n iss?: string;\n}\n\nfunction b64urlToBytes(s: string): Uint8Array<ArrayBuffer> {\n const pad = s.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const full = pad.padEnd(Math.ceil(pad.length / 4) * 4, \"=\");\n const bin = atob(full);\n // Backed by a plain ArrayBuffer so the result satisfies BufferSource — a\n // Uint8Array over ArrayBufferLike could be shared memory, which the WebCrypto\n // signatures reject.\n const out = new Uint8Array(new ArrayBuffer(bin.length));\n for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);\n return out;\n}\n\nexport interface AuthVerifierOptions {\n jwksUrl: string;\n issuer?: string;\n /** Injectable for tests; defaults to global fetch. */\n fetchImpl?: typeof fetch;\n /** How long a fetched keyset is trusted before it is fetched again. A key\n * rotation must become visible without a restart, and an unknown `kid` must\n * not be able to force a fetch per request (that is a free DoS lever). */\n keysetTtlMs?: number;\n}\n\nexport class AuthVerifier {\n private keys = new Map<string, CryptoKey>();\n private fetchedAt = 0;\n private inflight: Promise<void> | null = null;\n private readonly jwksUrl: string;\n private readonly issuer?: string;\n private readonly fetchImpl: typeof fetch;\n private readonly ttl: number;\n\n constructor(opts: AuthVerifierOptions) {\n this.jwksUrl = opts.jwksUrl;\n this.issuer = opts.issuer;\n this.fetchImpl = opts.fetchImpl ?? ((...a: Parameters<typeof fetch>) => fetch(...a));\n this.ttl = opts.keysetTtlMs ?? 5 * 60_000;\n }\n\n /** Fetch the keyset at most once per TTL, and at most once concurrently. */\n private async refresh(): Promise<void> {\n if (this.inflight) return this.inflight;\n this.inflight = (async () => {\n try {\n const res = await this.fetchImpl(this.jwksUrl);\n if (!res.ok) return;\n const body = (await res.json()) as { keys?: EcJwk[] };\n const next = new Map<string, CryptoKey>();\n for (const jwk of body.keys ?? []) {\n if (jwk.kty !== \"EC\" || jwk.crv !== \"P-256\") continue;\n try {\n next.set(\n jwk.kid,\n await crypto.subtle.importKey(\n \"jwk\",\n { kty: \"EC\", crv: jwk.crv, x: jwk.x, y: jwk.y, ext: true },\n { name: \"ECDSA\", namedCurve: \"P-256\" },\n true,\n [\"verify\"],\n ),\n );\n } catch {\n // A single malformed key must not blind the verifier to the rest.\n }\n }\n if (next.size > 0) {\n this.keys = next;\n this.fetchedAt = Date.now();\n }\n } finally {\n this.inflight = null;\n }\n })();\n return this.inflight;\n }\n\n private async key(kid: string): Promise<CryptoKey | null> {\n const stale = Date.now() - this.fetchedAt > this.ttl;\n if (!this.keys.has(kid) || stale) await this.refresh();\n return this.keys.get(kid) ?? null;\n }\n\n /**\n * Verify an `Authorization` header value.\n *\n * @returns the verified claims, or `null` for absent / malformed / expired /\n * wrong-issuer / bad-signature. One `null` for every failure on purpose:\n * the caller answers 401 either way, and a detailed reason is an oracle.\n */\n async verify(authorization: string | null | undefined): Promise<VerifiedClaims | null> {\n if (!authorization || !authorization.startsWith(\"Bearer \")) return null;\n const parts = authorization.slice(7).trim().split(\".\");\n if (parts.length !== 3) return null;\n const h = parts[0];\n const p = parts[1];\n const sig = parts[2];\n if (h === undefined || p === undefined || sig === undefined) return null;\n\n let header: { alg?: string; kid?: string };\n let claims: VerifiedClaims;\n try {\n header = JSON.parse(new TextDecoder().decode(b64urlToBytes(h)));\n claims = JSON.parse(new TextDecoder().decode(b64urlToBytes(p)));\n } catch {\n return null;\n }\n // `none`, `HS256`-with-the-public-key, and friends all die here.\n if (header.alg !== \"ES256\" || !header.kid) return null;\n\n const key = await this.key(header.kid);\n if (!key) return null;\n\n let ok = false;\n try {\n ok = await crypto.subtle.verify(\n { name: \"ECDSA\", hash: \"SHA-256\" },\n key,\n b64urlToBytes(sig),\n new TextEncoder().encode(`${h}.${p}`),\n );\n } catch {\n return null;\n }\n if (!ok) return null;\n if (typeof claims.exp === \"number\" && claims.exp * 1000 <= Date.now()) return null;\n if (this.issuer && claims.iss !== this.issuer) return null;\n return claims;\n }\n}\n\n/** What a route demands, after the route's own spec and the controller's\n * default have been reconciled. */\nexport interface EffectiveAuth {\n required: boolean;\n role?: string;\n /** The permission the route demands, as `resource.action`. Resolved against\n * `auth.has_permission(...)` at the gate — see AuthConfig.permission. */\n permission?: string;\n verifiedEmail: boolean;\n}\n\n/**\n * Reconcile route-level and controller-level auth.\n *\n * The route's own spec wins when it says anything at all; otherwise the\n * controller's default applies; when NEITHER speaks, the answer is `required`.\n * That last clause is the whole point — a route that forgot to declare must be\n * closed, not open. (Measured: an engine that only read the route level served\n * a controller marked `auth: false` as 401, and would have served the reverse\n * mistake as an open endpoint.)\n */\nexport function effectiveAuth(routeAuth: unknown, controllerAuth: unknown): EffectiveAuth {\n const spec = routeAuth !== undefined ? routeAuth : controllerAuth;\n if (spec === false) return { required: false, verifiedEmail: false };\n if (spec === true || spec === undefined || spec === null) return { required: true, verifiedEmail: false };\n if (typeof spec !== \"object\") return { required: true, verifiedEmail: false };\n\n const o = spec as {\n required?: unknown;\n role?: unknown;\n permission?: unknown;\n verifiedEmail?: unknown;\n };\n const role = typeof o.role === \"string\" && o.role.trim() !== \"\" ? o.role.trim() : undefined;\n // Blank-trimmed like `role`, and for the same reason: a spec that carries\n // `permission: \"\"` is asking for nothing, and a gate that took it literally\n // would query for the empty permission and refuse everyone.\n const permission =\n typeof o.permission === \"string\" && o.permission.trim() !== \"\" ? o.permission.trim() : undefined;\n return {\n required: o.required !== false,\n role,\n permission,\n verifiedEmail: o.verifiedEmail === true,\n };\n}\n","/**\n * engine/ratelimit.ts — the customer's own per-route limit, enforced here.\n *\n * This is the PRODUCT feature (`@Get(\"/x\", { rateLimit: { max, window } })`),\n * not a quota the platform imposes. It runs in this process, on this pod,\n * because the route table lives here: the edge proxies by path and has never\n * seen a route's options, so teaching it would mean shipping the table twice\n * and keeping the copies in step.\n *\n * Fixed window, in memory. A single-tenant backend is the whole stack rather\n * than a shard of it, so \"in process\" is not an approximation. A restart\n * forgets the window, which for an endpoint guard fails in the right\n * direction: it forgives, it never invents a refusal.\n */\n\nexport interface RateLimitRule {\n max: number;\n /** Seconds. */\n window: number;\n}\n\ninterface Bucket {\n count: number;\n resetAt: number;\n}\n\nexport class RateLimiter {\n private buckets = new Map<string, Bucket>();\n /** Bound on distinct keys held, so an attacker cycling identities cannot\n * grow this map without limit. On overflow the oldest windows are dropped —\n * forgiving, consistent with the restart behaviour above. */\n constructor(private readonly maxKeys = 100_000) {}\n\n /**\n * Identify the caller: the signed-in user when the route resolved one,\n * otherwise the address the edge forwarded. Callers the edge did not\n * identify share one bucket — deliberately conservative, since the\n * alternative is a limit anyone resets by omitting a header.\n */\n static key(routeId: string, userId: string | undefined, headers: Headers): string {\n if (userId) return `${routeId}\\x00u:${userId}`;\n const fwd = headers.get(\"x-forwarded-for\");\n const addr = (fwd ? (fwd.split(\",\")[0] ?? \"\") : (headers.get(\"x-real-ip\") ?? \"\")).trim();\n return `${routeId}\\x00a:${addr || \"anonymous\"}`;\n }\n\n /**\n * @returns `null` when the request may proceed, or the number of seconds to\n * wait (never 0 — a caller told to wait 0 comes straight back to the same\n * refusal).\n */\n check(rule: RateLimitRule | undefined, key: string, now: number): number | null {\n if (!rule || !(rule.max > 0) || !(rule.window > 0)) return null;\n\n const bucket = this.buckets.get(key);\n if (!bucket || now >= bucket.resetAt) {\n if (this.buckets.size >= this.maxKeys) this.evict(now);\n this.buckets.set(key, { count: 1, resetAt: now + rule.window * 1000 });\n return null;\n }\n if (bucket.count < rule.max) {\n bucket.count++;\n return null;\n }\n return Math.max(1, Math.ceil((bucket.resetAt - now) / 1000));\n }\n\n /** Drop expired windows; if none are expired, drop the earliest-resetting\n * quarter so the map cannot wedge at the ceiling. */\n private evict(now: number): void {\n let dropped = 0;\n for (const [k, b] of this.buckets) {\n if (now >= b.resetAt) {\n this.buckets.delete(k);\n dropped++;\n }\n }\n if (dropped > 0) return;\n const byReset = [...this.buckets.entries()].sort((a, b) => a[1].resetAt - b[1].resetAt);\n for (let i = 0; i < Math.ceil(byReset.length / 4); i++) {\n const victim = byReset[i];\n if (victim) this.buckets.delete(victim[0]);\n }\n }\n\n /** Test seam. */\n get size(): number {\n return this.buckets.size;\n }\n}\n","/**\n * engine/cache.ts — the cache, in this process's own memory.\n *\n * A stack that serves one tenant has nobody to share a cache with; palsvc drew\n * exactly this conclusion for itself when it dropped Redis, and a backend that\n * reaches over a network for a hash map is paying a round trip for nothing.\n *\n * JSON-typed, matching `CacheClient`: values round-trip as whatever was stored.\n */\nimport type { CacheClient } from \"../endpoint.js\";\n\ninterface Entry {\n value: unknown;\n /** Epoch ms, or 0 for \"no expiry\". */\n expiresAt: number;\n}\n\nexport interface MemoryCacheOptions {\n /** Bound on entries held. On overflow the soonest-to-expire are dropped. */\n maxEntries?: number;\n /** Injectable clock, for tests. */\n now?: () => number;\n}\n\n/**\n * Build an in-process cache.\n *\n * `getOrSet` is single-flight: concurrent misses on one key share one fill, so\n * a cold key under load does not become N identical expensive calls.\n */\nexport function makeMemoryCache(opts: MemoryCacheOptions = {}): CacheClient {\n const maxEntries = opts.maxEntries ?? 50_000;\n const now = opts.now ?? (() => Date.now());\n const store = new Map<string, Entry>();\n const inflight = new Map<string, Promise<unknown>>();\n\n const live = (key: string): Entry | undefined => {\n const e = store.get(key);\n if (!e) return undefined;\n if (e.expiresAt !== 0 && e.expiresAt <= now()) {\n store.delete(key);\n return undefined;\n }\n return e;\n };\n\n const evict = () => {\n const t = now();\n let dropped = 0;\n for (const [k, e] of store) {\n if (e.expiresAt !== 0 && e.expiresAt <= t) {\n store.delete(k);\n dropped++;\n }\n }\n if (dropped > 0) return;\n // Nothing expired: drop the soonest-to-expire quarter (entries with no\n // expiry sort last, so an unbounded writer sheds its own oldest first).\n const order = [...store.entries()].sort(\n (a, b) => (a[1].expiresAt || Infinity) - (b[1].expiresAt || Infinity),\n );\n for (let i = 0; i < Math.ceil(order.length / 4); i++) {\n const victim = order[i];\n if (victim) store.delete(victim[0]);\n }\n };\n\n const set = async (key: string, value: unknown, ttl?: number): Promise<void> => {\n if (store.size >= maxEntries && !store.has(key)) evict();\n store.set(key, { value, expiresAt: ttl && ttl > 0 ? now() + ttl * 1000 : 0 });\n };\n\n return {\n async get<T = unknown>(key: string): Promise<T | null> {\n const e = live(key);\n return e ? (e.value as T) : null;\n },\n set,\n async del(key: string): Promise<void> {\n store.delete(key);\n },\n async incr(key: string): Promise<number> {\n const e = live(key);\n const next = (typeof e?.value === \"number\" ? e.value : 0) + 1;\n store.set(key, { value: next, expiresAt: e?.expiresAt ?? 0 });\n return next;\n },\n async getOrSet<T>(key: string, ttl: number, fn: () => Promise<T> | T): Promise<T> {\n const hit = live(key);\n if (hit) return hit.value as T;\n\n const running = inflight.get(key);\n if (running) return running as Promise<T>;\n\n const fill = (async () => {\n try {\n const value = await fn();\n await set(key, value, ttl);\n return value;\n } finally {\n inflight.delete(key);\n }\n })();\n inflight.set(key, fill);\n return fill as Promise<T>;\n },\n };\n}\n","/**\n * engine/db.ts — a real pooled connection, and the identity every request is\n * bound to inside it.\n *\n * # Why one transaction per request\n *\n * In the isolate architecture every `Database.*` call was its own HTTP hop to a\n * capability surface, so two writes in one handler could not be atomic — a\n * handler that wrote and then threw left the first write behind. Here the whole\n * request runs inside one transaction: it commits when the handler returns and\n * rolls back when it throws. Atomicity stops being something the author has to\n * ask for.\n *\n * # Why it opens lazily\n *\n * A handler that touches no table must cost no round trip. Opening eagerly cost\n * four (BEGIN + bind + … + COMMIT) on endpoints that never query — measured at\n * 1,243 rps against 31,579 for the same endpoint once the open became lazy.\n *\n * # How the caller's identity reaches RLS\n *\n * One statement, not three:\n *\n * select set_config('role',$1,true),\n * set_config('search_path','public',true),\n * set_config('request.jwt.claims',$2,true)\n *\n * `set_config(..., is_local => true)` is transaction-scoped exactly like\n * `SET LOCAL`, but takes BOUND PARAMETERS, which `SET LOCAL` cannot. So the\n * role and the caller's claims travel as parameters — user identity is never\n * spliced into SQL text — and `auth.uid()` resolves inside RLS policies, which\n * means the row filter is enforced by Postgres rather than by our code.\n */\nimport type { DBClient, DBOps, AtomicClient } from \"../endpoint.js\";\nimport { AsyncLocalStorage } from \"node:async_hooks\";\nimport { validateAtomicOptions, retryBudget, type AtomicOptions, type TransactionIsolation } from \"../db/transaction-options.js\";\nimport { memoTable, snapshotDeclaration, type SchemaMetadataCache } from \"./schema-cache.js\";\nimport { SQLSTATE } from \"../db/sqlstate.js\";\nimport { cursorKey, cursorIdentity, encodeCursor, decodeCursor, fingerprint, pageOrder, pageBoundary, type PageColumn } from \"./cursor.js\";\nimport type { Page, RawPageOptions } from \"../db/page.js\";\nimport { validateInsertManyOptions, type InsertManyOptions } from \"../db/bulk.js\";\nimport type { CommandOptions } from \"../db/command.js\";\nimport { uniqueKeysOf, assertUniqueLookup } from \"../db/unique.js\";\nimport { hasCommandExecutor, parameterChunks, type CompiledStep, type CommandBinding } from \"./commands.js\";\nimport { databaseAdmission, type AdmissionLease, type DatabaseAdmission } from \"./admission.js\";\nimport { TransactionControl, type CancellableQuery } from \"./transaction-control.js\";\nimport { DatabaseTrace } from \"./diagnostics.js\";\nimport type { DatabaseDiagnosticsOptions } from \"../db/diagnostics.js\";\n// A VALUE import, not a type: the engine constructs one (23505 → 409).\nimport { HttpError, UniqueViolation, SerializationFailure, DeadlockDetected, markEngineRaised, isRetryable,\n} from \"../errors.js\";\nimport { assertUsableFilter, assertUsableWriteValues, assertNoExpressionHandles, isColRef, isSqlFragment, isNowExpr, isColumnExpr, looksLikeUnbrandedRef, isPlanRef, looksLikeUnbrandedPlanRef } from \"../db/input-guards.js\";\nimport { CODECS, type CodecName } from \"../db/columns.js\";\nimport { columnExprOf } from \"../db/tx-plan.js\";\nimport type { PolicyDef, PolicyExpr } from \"../db/policy.js\";\nimport type { TableDef } from \"../db/schema.js\";\nimport { qualifiedTableKey } from \"../db/schema-json.js\";\nimport { buildRelations, type Relation } from \"../db/env-gen.js\";\nimport type { SchemaDef } from \"../db/schema.js\";\nimport type {\n TxPlanBody,\n TxPlanOpResult,\n TxPlanResponse,\n TxWireExpr,\n TxWireOp,\n TxWireRef,\n TxWireValue,\n} from \"../db/tx-plan.js\";\n\n/** The slice of a SQL driver the engine uses. `Bun.sql` satisfies it. */\nexport interface SqlDriver {\n /** Shared by every request and identity using this physical application pool. */\n admission?: DatabaseAdmission;\n /** Optional reliable cancellation through a separate control connection. */\n cancelBackend?(pid: number, startedAt: string): Promise<void>;\n /** Run a parameterised statement. */\n unsafe(sql: string, params?: unknown[]): Promise<unknown>;\n /** Open a transaction; the driver commits when `cb` resolves and rolls back\n * when it rejects. */\n begin<T>(cb: (tx: SqlTx) => Promise<T>): Promise<T>;\n}\n\nexport interface SqlTx {\n unsafe(sql: string, params?: unknown[], metadata?: { name?: string }): Promise<unknown>;\n savepoint<T>(cb: (sp: SqlTx) => Promise<T>): Promise<T>;\n}\n\ntype Row = Record<string, unknown>;\n\n/** Quote an identifier. Table and column names reach here from the schema and\n * from handler arguments; neither is allowed to become syntax. */\nexport function quoteIdent(name: string): string {\n return `\"${name.replace(/\"/g, '\"\"')}\"`;\n}\n\n/**\n * Quote a TABLE KEY, which is one identifier or two — never one that contains\n * a dot.\n *\n * A table travels under this system's one key convention: `public` bare,\n * anything else `schema.table` (the same rule `qualifiedTableKey` writes on the\n * Go side). Handing that key to `quoteIdent` produces `\"billing.invoices\"`,\n * which Postgres reads as a PUBLIC table whose NAME contains a dot — so every\n * call through `Database.billing.*` named a table that does\n * not exist, or, worse, a different one that does.\n *\n * The public half stays BYTE-IDENTICAL to the single-schema world, because\n * every existing query and golden asserts the bare form.\n */\nexport function quoteTable(key: string): string {\n const dot = key.indexOf(\".\");\n if (dot === -1) return quoteIdent(key);\n return `${quoteIdent(key.slice(0, dot))}.${quoteIdent(key.slice(dot + 1))}`;\n}\n\n/**\n * Render a JavaScript array as a Postgres array literal, so `= ANY($n::uuid[])`\n * works from `Database.query`.\n *\n * WHY THIS EXISTS. `Bun.SQL`'s `unsafe(text, params)` does NOT bind a JS array as\n * a Postgres array — it applies `Array.prototype.toString()`. `[\"a\",\"b\"]` arrives\n * as the text `a,b`, with no braces, and `$1::uuid[]` fails with \"malformed array\n * literal\" (measured 2026-08-29 against pgvector/pg16 + bun 1.3.9). Every fan-in\n * query a tenant writes therefore had to hand-build the literal; one of them did,\n * and reported it. node-postgres converts arrays for exactly this reason.\n *\n * Bun's own escape hatch, `sql.array()`, cannot be used here: it is a tagged-\n * template FRAGMENT that renders inline `ARRAY[...]` TEXT, and nothing that\n * travels in the `params` array can carry it.\n *\n * There is deliberately NO vector branch, and there cannot be one: this sees raw\n * SQL, so which column a parameter is destined for is unknowable. The single\n * uniform encoding is what makes a vector parameter writable at all —\n * `$n::float8[]::vector` round-trips (measured), where today nothing does.\n */\nexport function encodePgArray(value: readonly unknown[]): string {\n const element = (x: unknown): string => {\n // Unquoted NULL is the only spelling Postgres reads as the null element;\n // `\"NULL\"` would be the four-character string.\n if (x === null || x === undefined) return \"NULL\";\n if (Array.isArray(x)) return encodePgArray(x);\n return `\"${String(x).replace(/([\"\\\\])/g, \"\\\\$1\")}\"`;\n };\n return `{${value.map(element).join(\",\")}}`;\n}\n\nconst BIND_SQL =\n \"select set_config('role',$1,true), set_config('search_path','public',true), set_config('request.jwt.claims',$2,true)\";\n\n/** Per async branch: other requests and sibling Promise.all branches are unaffected. */\nconst atomicScope = new AsyncLocalStorage<symbol>();\n\n/**\n * A transaction that does not exist until somebody reads or writes.\n *\n * `begin(cb)` is callback-scoped, so to hold one open across a whole request\n * the callback parks on a promise this object controls: `commit()` resolves it\n * (the driver commits), `rollback()` rejects it (the driver rolls back). A\n * request that never touches the database never enters the callback at all.\n */\nexport function createLazyTransaction(\n sql: SqlDriver,\n role: string,\n claimsJson: string,\n options: { lockTimeout?: string; statementTimeout?: string; isolation?: TransactionIsolation; readOnly?: boolean; scope?: symbol; control?: TransactionControl; trace?: DatabaseTrace } = {},\n) {\n const { lockTimeout } = options;\n // `lock_timeout` travels as a BOUND parameter like the other two, so a value\n // from configuration can never become SQL text.\n let bindSql = lockTimeout ? `${BIND_SQL}, set_config('lock_timeout',$3,true)` : BIND_SQL;\n const bindParams = lockTimeout ? [role, claimsJson, lockTimeout] : [role, claimsJson];\n if (options.statementTimeout !== undefined) {\n bindParams.push(options.statementTimeout);\n bindSql += `, set_config('statement_timeout',$${bindParams.length},true)`;\n }\n\n let opening: Promise<SqlTx> | null = null;\n let release: (() => void) | null = null;\n let fail: ((e: unknown) => void) | null = null;\n let settled: Promise<unknown> | null = null;\n let closed = false;\n\n const assertAccess = (): void => {\n if (closed) throw new Error(\"Database transaction has settled; its handle cannot be used again\");\n options.control?.check();\n options.trace?.check();\n if (atomicScope.getStore() !== options.scope) {\n throw new Error(\"Database.$atomic cannot use a handle from another transaction or identity; use its tx argument\");\n }\n };\n let savepointALS: AsyncLocalStorage<symbol> | undefined;\n let activeSavepoint: symbol | undefined;\n const pendingSavepoints = new Set<Promise<unknown>>();\n const scoped = (tx: SqlTx, checkParent = assertAccess, owner?: symbol, children = new Set<Promise<unknown>>()): SqlTx => {\n const access = () => {\n checkParent();\n if (activeSavepoint !== owner || savepointALS?.getStore() !== owner) {\n throw new Error(\"Database connection belongs to another active savepoint; use its tx argument and await it before using the parent handle\");\n }\n };\n return {\n async unsafe(text, params, metadata) {\n access();\n const run = () => { const query = tx.unsafe(text, params); return options.control ? options.control.watch(query) : query; };\n return options.trace ? options.trace.query(text, metadata?.name, run) : run();\n },\n async savepoint(fn) {\n access();\n const token = Symbol(\"savepoint\"), descendants = new Set<Promise<unknown>>();\n savepointALS ??= new AsyncLocalStorage<symbol>();\n activeSavepoint = token;\n const work = (async () => {\n try {\n return await tx.savepoint(async sp => {\n let ended = false;\n const check = () => { checkParent(); if (ended) throw new Error(\"Database savepoint has settled; its handle cannot be used again\"); };\n try {\n const callback = savepointALS!.run(token, () => fn(scoped(sp, check, token, descendants)));\n return await (options.control ? options.control.race(callback) : callback);\n } finally {\n // Children finish their ROLLBACK TO / RELEASE before this\n // savepoint settles, including when the callback is cancelled.\n if (descendants.size) await Promise.allSettled([...descendants]);\n ended = true;\n }\n });\n } finally { activeSavepoint = owner; }\n })();\n pendingSavepoints.add(work); children.add(work);\n try { return await work; }\n finally { pendingSavepoints.delete(work); children.delete(work); }\n },\n };\n };\n const ensure = async (): Promise<SqlTx> => {\n assertAccess();\n if (opening) return opening;\n opening = new Promise<SqlTx>((resolveTx, rejectTx) => {\n const parked = new Promise<void>((res, rej) => {\n release = res;\n fail = rej;\n });\n // Opening can fail before the driver ever awaits parked. Rollback still\n // rejects it, so attach a handler at creation while retaining the original.\n void parked.catch(() => undefined);\n settled = (async () => {\n const queuedAt = performance.now();\n let lease: AdmissionLease;\n try { lease = await (sql.admission ?? databaseAdmission(sql)).acquire(claimsJson, options.control?.signal); }\n finally { options.trace?.time(\"queueMs\", queuedAt); }\n const openingAt = performance.now();\n let connectedAt: number | undefined;\n try {\n // Cancellation may win after admission and before the driver callback.\n // Never bind/cancel a backend that has not been acquired by this scope.\n options.control?.check();\n if (closed) throw new Error(\"Database transaction closed while waiting for admission\");\n return await sql.begin(async (tx) => {\n connectedAt = performance.now();\n options.trace?.time(\"poolMs\", openingAt);\n const setupAt = options.trace ? performance.now() : 0;\n options.control?.check();\n if (closed) throw new Error(\"Database transaction closed while waiting for its connection\");\n if (options.isolation !== undefined || options.readOnly !== undefined) {\n const isolation = options.isolation ?? \"read committed\";\n // Only enumerated values can become SQL; SET must precede the bind SELECT.\n validateAtomicOptions({ isolation, readOnly: options.readOnly });\n await tx.unsafe(`SET TRANSACTION ISOLATION LEVEL ${isolation.toUpperCase()}${options.readOnly === undefined ? \"\" : options.readOnly ? \" READ ONLY\" : \" READ WRITE\"}`);\n }\n if (options.control && sql.cancelBackend) {\n // The materialized input is evaluated before the outer SET ROLE\n // projection. Read only this backend, then bind RLS in the SAME\n // round trip. Scanning pg_stat_activity and binding separately\n // added an extra query to every cancellable CRUD transaction.\n // Await setup before binding cancellation: a cancellation during\n // setup may roll this transaction back, never its next borrower.\n const ticket = await tx.unsafe(`WITH backend AS MATERIALIZED (\n SELECT pid, backend_start::text AS started FROM pg_catalog.pg_stat_get_activity(pg_catalog.pg_backend_pid())\n ) ${bindSql}, backend.pid, backend.started FROM backend`, bindParams) as { pid: number; started: string }[];\n if (!Number.isInteger(ticket[0]?.pid) || typeof ticket[0]?.started !== \"string\") throw new Error(\"Database cancellation cannot identify its own backend\");\n options.control.bindBackend(() => sql.cancelBackend!(ticket[0]!.pid, ticket[0]!.started));\n options.control.check();\n } else {\n const binding = tx.unsafe(bindSql, bindParams);\n await (options.control ? options.control.watch(binding) : binding);\n }\n options.trace?.time(\"setupMs\", setupAt);\n resolveTx(scoped(tx));\n await parked;\n });\n } finally {\n if (connectedAt !== undefined) options.trace?.time(\"connectionMs\", connectedAt);\n lease.release();\n }\n })()\n .catch((e: unknown) => {\n // Both paths matter: a caller awaiting `ensure()` must see the\n // failure, and `commit()` must not hang waiting for a dead driver.\n rejectTx(e);\n throw e;\n });\n // A statement can fail before its caller reaches rollback(). The owner\n // still observes settled at COMMIT, without an unhandled rejection meanwhile.\n void settled.catch(() => undefined);\n });\n return opening;\n };\n\n return {\n ensure,\n get opened(): boolean {\n return opening !== null;\n },\n async commit(): Promise<void> {\n if (pendingSavepoints.size) await Promise.allSettled([...pendingSavepoints]);\n options.trace?.check();\n // No connection/transaction was opened. A cancelled HTTP stream may\n // still report its Signal state without a database COMMIT to cancel.\n if (!opening) { closed = true; return; }\n options.control?.check();\n closed = true;\n const started = options.trace ? performance.now() : 0;\n release!();\n try { await settled; options.trace?.committed(); }\n catch (error) { options.trace?.commitFailed(); throw error; }\n finally { options.trace?.time(\"commitMs\", started); }\n },\n async rollback(reason: unknown): Promise<void> {\n closed = true;\n if (!opening) return;\n await options.control?.drainCancellation();\n if (pendingSavepoints.size) await Promise.allSettled([...pendingSavepoints]);\n const started = options.trace ? performance.now() : 0;\n fail!(reason);\n // The rejection is the mechanism, not an error to report twice.\n await settled?.catch(() => undefined);\n options.trace?.time(\"rollbackMs\", started); options.trace?.rolledBack();\n },\n };\n}\n\nexport type LazyTransaction = ReturnType<typeof createLazyTransaction>;\n\n/** Either a live driver transaction or the lazy holder above. */\ntype TxLike = SqlTx | LazyTransaction;\n\nconst resolveTx = async (tx: TxLike): Promise<SqlTx> =>\n typeof (tx as LazyTransaction).ensure === \"function\"\n ? await (tx as LazyTransaction).ensure()\n : (tx as SqlTx);\n\n/**\n * What a row LOOKS like to the code that reads it.\n *\n * The driver hands back a `Date` for every timestamp column, while the typed\n * surface this SDK generates for the same table says `string` — and so does the\n * response schema derived from a handler's return type, and so does the JSON on\n * the wire. So a handler that returned a row straight from `Database.public.x`\n * failed its OWN declared type: measured on 2026-08-16, `POST /todos` answered\n * 500 `output_invalid` with \"expected string, received date\" for `created_at`,\n * from code that had done nothing wrong.\n *\n * ISO-8601, because that is what the schema, the generated client and every\n * JSON reader already agree on.\n */\nfunction asWireValue(value: unknown): unknown {\n if (value instanceof Date) return value.toISOString();\n if (Array.isArray(value)) return value.map(asWireValue);\n return value;\n}\n\n/** Every row a caller receives passes through here. */\nfunction asWireRow<T>(row: T): T {\n if (row === null || typeof row !== \"object\") return row;\n const out: Row = {};\n for (const [key, value] of Object.entries(row as Row)) out[key] = asWireValue(value);\n return out as T;\n}\n\nfunction asWireRows(rows: Row[]): Row[] {\n return rows.map((row) => asWireRow(row));\n}\n\n/** pgvector text literal: '[v1,v2,...]' — the driver would otherwise bind a\n * Postgres ARRAY, which vector's input function refuses. (FR-008) */\nfunction toVectorLiteral(v: number[]): string {\n return `[${v.join(\",\")}]`;\n}\n\n/**\n * The vector-typed column names of one table, read from the installed schema.\n *\n * Ops receive the PHYSICAL table name (`withTables` maps key → `def.name`), so\n * the lookup matches `def.name ?? key`. A column arrives either as a\n * ColumnBuilder (with `_def`) or as the plain def — the same double reading\n * schema-json does, for the same reason: both shapes exist in the wild.\n */\nfunction computeVectorColumns(schema: typeof currentSchema, table: string): Set<string> {\n const out = new Set<string>();\n const def = tableDefOf(table, schema);\n if (def) {\n for (const [col, c] of Object.entries(def.columns ?? {})) {\n const d = (c !== null && typeof c === \"object\" && \"_def\" in c\n ? (c as { _def: unknown })._def\n : c) as { type?: unknown } | null;\n if (d !== null && typeof d === \"object\" && d.type === \"vector\") out.add(col);\n }\n }\n return out;\n}\n\n/**\n * The one place that answers \"which declared table is this?\".\n *\n * Ops receive the table's WIRE KEY — public bare, anything else qualified —\n * and the installed schema is flattened under exactly those keys. There used to\n * be four separate scans here, each matching `def.name ?? key` against the\n * name, and every one of them missed a table outside public: the column\n * metadata (vectors, transforms, search config) came back EMPTY and the ops\n * fell through to their \"no schema to check against\" path without saying so.\n */\nfunction tableDefOf(\n key: string,\n schema: typeof currentSchema = currentSchema,\n): { name?: string; columns?: Record<string, unknown>; policies?: PolicyDef[] } | null {\n return schema.tables?.[key] ?? null;\n}\n\n/** The driver hands a vector back as its text literal; JSON.parse restores the\n * number[] the typed surface declares — the literal is valid JSON (C-9). A null\n * (row without an embedding yet) passes through untouched. */\nfunction reviveVectors<T>(row: T, vectorCols: Set<string>): T {\n if (row === null || typeof row !== \"object\" || vectorCols.size === 0) return row;\n const out = row as Row;\n for (const col of vectorCols) {\n const v = out[col];\n if (typeof v === \"string\") out[col] = JSON.parse(v);\n }\n return row;\n}\n\n/** The declared `{ fromDb, toDb }` per column of `table`, empty when none.\n *\n * Read the same way vector columns are: a column is either a ColumnBuilder\n * (with `_def`) or the flat generated shape, and both are accepted.\n *\n * WITHOUT THIS the hook is a type-level promise the runtime does not keep — the\n * declaration would say `number` and the driver would still hand over the\n * string, which is the defect class this whole surface exists to remove. */\nfunction computeTransforms(\n schema: typeof currentSchema,\n table: string,\n): Map<string, { fromDb?: (v: unknown) => unknown; toDb?: (v: unknown) => unknown }> {\n const out = new Map<string, { fromDb?: (v: unknown) => unknown; toDb?: (v: unknown) => unknown }>();\n const def = tableDefOf(table, schema);\n if (def) {\n for (const [col, c] of Object.entries(def.columns ?? {})) {\n const d = (c !== null && typeof c === \"object\" && \"_def\" in c\n ? (c as { _def: unknown })._def\n : c) as { transform?: unknown; codec?: unknown } | null;\n // A NAMED CODEC IS A TRANSFORM whose pair is looked up rather than\n // supplied. It goes through THIS map on purpose: two implementations of\n // \"how a numeric becomes a number\" would be two answers, and one day they\n // would disagree. The name is what the type generator can read; the pair\n // it resolves to is the same pair `.transform()` hands over (FR-002).\n const codec = d?.codec;\n if (typeof codec === \"string\" && codec in CODECS) {\n const c2 = CODECS[codec as CodecName];\n out.set(col, { fromDb: c2.fromDb, toDb: c2.toDb });\n continue;\n }\n const t = d?.transform;\n if (t !== null && typeof t === \"object\") {\n out.set(col, t as { fromDb?: (v: unknown) => unknown; toDb?: (v: unknown) => unknown });\n }\n }\n }\n return out;\n}\n\n/** Apply every declared `fromDb` to one row. NULL is passed through untouched:\n * \"no value\" is not a value to convert, and a `fromDb` written for a string\n * would answer `0` for it. */\nfunction applyFromDb(row: Row, transforms: ReturnType<typeof transformsOf>): Row {\n if (transforms.size === 0) return row;\n for (const [col, t] of transforms) {\n if (t.fromDb === undefined) continue;\n const v = row[col];\n if (v === null || v === undefined) continue;\n row[col] = t.fromDb(v);\n }\n return row;\n}\n\n/** `asWireRow`, made table-aware: what the table's schema calls a vector comes\n * back as number[]. Rows from tables the schema does not know pass unchanged. */\nfunction asTableRow<T>(table: string, row: T): T {\n const revived = reviveVectors(asWireRow(row), vectorColumnsOf(currentSchema, table));\n return foldCan(table, applyFromDb(revived as Row, transformsOf(currentSchema, table)) as Row, false) as T;\n}\n\n/** `partial`: `select` projeksiyonu — `can` alanı hiç yazılmaz. `with` ile gelen iç\n * içe satırlar `can:*` çiftlerini kendi JSON nesnesinde taşır (`canJsonPairs`), tam satırdır. */\nfunction asTableRows(table: string, rows: Row[], withSpec?: Record<string, unknown>, partial = false): Row[] {\n const vectorCols = vectorColumnsOf(currentSchema, table);\n const transforms = transformsOf(currentSchema, table);\n const result = rows.map((row) => applyFromDb(reviveVectors(asWireRow(row), vectorCols), transforms));\n if (withSpec) for (const rel of currentRelations.get(table) ?? []) {\n const spec = withSpec[rel.name];\n if (!spec) continue;\n const nested = typeof spec === \"object\" ? (spec as { with?: Record<string, unknown> }).with : undefined;\n for (const row of result) {\n const value = row[rel.name];\n const selected = typeof spec === \"object\" && \"select\" in spec && spec.select !== undefined;\n if (Array.isArray(value)) row[rel.name] = asTableRows(rel.to, value, nested, selected);\n else if (value && typeof value === \"object\") row[rel.name] = asTableRows(rel.to, [value as Row], nested, selected)[0];\n }\n }\n // Katlama ilişkilerden SONRA: `can` adlı bir ilişki varsa yankı zaten kapalı ve\n // `foldCan` o alana dokunmaz (hasCanColumn ilişkiyi de sayar).\n for (const row of result) foldCan(table, row, partial);\n return result;\n}\n\n/** Bind parameters for one write: a value headed for a vector column becomes\n * the pgvector text literal; everything else binds as-is. (FR-008) */\nfunction asBindParams(table: string, cols: string[], data: Row, caller: string): unknown[] {\n // AN `undefined` VALUE IS NOT A WRITE — it is a value that never arrived.\n //\n // The read path already refuses one (see compileWhere): a filter nobody filled\n // in returned an empty list and said nothing. The WRITE half is the same shape\n // and a far more expensive result: `{ title: req.body.title }` with no `title`\n // in the body bound NULL and answered 200 — the column was ERASED, silently.\n // Measured on the 24.0.x line across insert, update, updateMany, upsert and\n // supersede, all of which bind through here.\n //\n // `null` is untouched, and the difference is the whole point: null is an author\n // SAYING \"empty this column\". undefined is nobody saying anything.\n assertUsableWriteValues(caller, table, cols, data);\n // Bir ifade tutamağı ya da `col()` DEĞER değildir — ortak kural dosyasından\n // (db/input-guards.ts), böylece `fakeDatabase` de aynı cevabı veriyor.\n assertNoExpressionHandles(caller, table, cols, data);\n const vectorCols = vectorColumnsOf(currentSchema, table);\n const transforms = transformsOf(currentSchema, table);\n return cols.map((c) => {\n const v = data[c];\n if (Array.isArray(v) && vectorCols.has(c)) return toVectorLiteral(v);\n // `toDb` before the bind, and NULL straight through for the same reason\n // `fromDb` skips it.\n const t = transforms.get(c);\n if (t?.toDb !== undefined && v !== null && v !== undefined) return t.toDb(v);\n return v;\n });\n}\n\n// ---------------------------------------------------------------------------\n// search (T017, FR-013..016) — tek-SQL hibrit RRF.\n// ---------------------------------------------------------------------------\n\n/** Metrik → operatör. Tek kelimeden türetilir; opclass/operatör asla yüzeye\n * çıkmaz, uyumsuzluk yapısal olarak imkânsız (D-5, prod arıza #2). */\n// ≤ bu kadar satır eşleşiyorsa vektör kolu EXACT taranır (10K×1536d ≈ 10-20ms;\n// HNSW'nin seçici filtrede recall çöküşüne karşı — ölçüm: engine/db.ts NFR-005 yorumu).\nconst SELECTIVITY_EXACT_THRESHOLD = 10000;\n\nconst METRIC_OPERATOR: Record<string, string> = {\n cosine: \"<=>\",\n euclidean: \"<->\",\n inner_product: \"<#>\",\n};\n\ninterface SearchLeg {\n column: string;\n metric: string;\n /** Auto-embed beyanı (authoring EmbeddingModelRef — runtime şeması defineSchema çıktısıdır). */\n embed?: { model: string; apiKeyName: string; baseURL?: string; dimensions?: number };\n}\n\n/** Chunk-modu hedefi (D-010): arama bu türev tabloda koşar. */\ninterface ChunkTarget {\n table: string;\n metric: string;\n embed?: SearchLeg[\"embed\"];\n fts: boolean;\n}\n\ninterface SearchConfig {\n chunk?: ChunkTarget;\n pk: string;\n cols: string[];\n colSet: Set<string>;\n ftsCols: string[];\n legs: SearchLeg[];\n /** FR-026: beyandan gelen eş anlamlı haritası — websearch girdisi bununla genişler. */\n synonyms?: Record<string, string[]>;\n /** FR-029: beyanda validity:true — arama varsayılan yalnız günceli tarar,\n * supersede bu tabloda çalışır (T019 türev kolonları: valid_from/valid_to/superseded_by). */\n validity?: boolean;\n}\n\n/** Tablonun arama konfigürasyonu, runtime'ın kurduğu şemadan (setSchema — C-9).\n * `search` bloğu yoksa vector kolonlarının VARLIĞI yeter (D-3/FR-013): her\n * vector kolonu cosine metrikli bir leg olur. Tablo şemada yoksa null. */\nfunction searchConfigFor(table: string): SearchConfig | null {\n const t = tableDefOf(table);\n if (!t) return null;\n const columns = t.columns ?? {};\n const defOf = (c: unknown): { type?: string } =>\n c !== null && typeof c === \"object\" && \"_def\" in (c as Record<string, unknown>)\n ? ((c as { _def: { type?: string } })._def)\n : ((c ?? {}) as { type?: string });\n const cols = Object.keys(columns);\n const vectorCols = cols.filter((c) => defOf((columns as Record<string, unknown>)[c]).type === \"vector\");\n // PK adı ŞEMADAN (review I3): Go tarafı tek-kolon PK'nın adını bilinçli\n // serbest bırakır (FR-020 \"adı serbesttir\") — SQL'e 'id' gömmek, pk'sı\n // başka adla declare edilmiş searchable tabloyu runtime 500'üne çevirirdi.\n const defOfFull = (c: unknown): { type?: string; primaryKey?: boolean } =>\n c !== null && typeof c === \"object\" && \"_def\" in (c as Record<string, unknown>)\n ? ((c as { _def: { type?: string; primaryKey?: boolean } })._def)\n : ((c ?? {}) as { type?: string; primaryKey?: boolean });\n const pkCols = cols.filter((c) => defOfFull((columns as Record<string, unknown>)[c]).primaryKey === true);\n const pk = pkCols.length === 1 ? pkCols[0]! : cols.includes(\"id\") ? \"id\" : null;\n if (pk === null) {\n throw new Error(\n `search(${table}): tek-kolon primary key bulunamadı — arama sıralaması ve satır birleşimi PK ister (FR-020)`,\n );\n }\n const search = (t as {\n search?: { text?: string[] | boolean; vector?: unknown; from?: string[]; metric?: string;\n model?: { model: string; apiKeyName?: string; baseURL?: string; dimensions?: number };\n synonyms?: Record<string, string[]>; validity?: boolean };\n }).search;\n const synonyms =\n search?.synonyms !== undefined && Object.keys(search.synonyms).length > 0\n ? { synonyms: search.synonyms }\n : {};\n // T019 notu: validity beyanı wire'da SEARCH bloğunda yaşar (SearchJSON.Validity).\n const validity = search?.validity === true ? { validity: true } : {};\n // YENİ biçim (D-007/D-010): `from`+`model`. Vector kolonu varsa satır-modu\n // (tek leg, kolon o); yoksa CHUNK-modu — arama türev __palbase_chunks\n // tablosunda koşar, sonuç parent'a gruplanır (FR-015).\n if (search?.from !== undefined && search.model !== undefined) {\n const m = search.model;\n const embed = {\n model: m.model, apiKeyName: m.apiKeyName ?? \"OPENAI_API_KEY\",\n ...(m.baseURL !== undefined ? { baseURL: m.baseURL } : {}),\n ...(m.dimensions !== undefined ? { dimensions: m.dimensions } : {}),\n };\n const metric = search.metric ?? \"cosine\";\n const ftsOn = search.text !== false;\n const ftsColsNew = ftsOn\n ? (Array.isArray(search.text) && search.text.length > 0 ? search.text : search.from)\n : [];\n if (vectorCols.length > 0) {\n return { pk, cols, colSet: new Set(cols), ftsCols: ftsColsNew,\n legs: [{ column: vectorCols[0]!, metric, embed }], ...synonyms, ...validity };\n }\n return { pk, cols, colSet: new Set(cols), ftsCols: ftsColsNew, legs: [],\n chunk: { table: `${table}__palbase_chunks`, metric, embed, fts: ftsOn }, ...synonyms, ...validity };\n }\n const ftsCols = (Array.isArray(search?.text) ? search.text : undefined) ?? [];\n const rawLegs = search?.vector === undefined ? [] : Array.isArray(search.vector) ? search.vector : [search.vector];\n let legs: SearchLeg[];\n if (rawLegs.length > 0) {\n legs = rawLegs.map((leg) => {\n const l = leg as { column?: string; metric?: string };\n const column = l.column ?? (vectorCols.length === 1 ? vectorCols[0]! : undefined);\n if (column === undefined) {\n throw new Error(`search(${table}): birden çok vector kolonu var — beyanda 'column' zorunlu (FR-010)`);\n }\n const model = (l as { model?: { model: string; apiKeyName?: string; baseURL?: string; dimensions?: number } }).model;\n return {\n column,\n metric: l.metric ?? \"cosine\",\n ...(model !== undefined\n ? { embed: { model: model.model, apiKeyName: model.apiKeyName ?? \"OPENAI_API_KEY\",\n ...(model.baseURL !== undefined ? { baseURL: model.baseURL } : {}),\n ...(model.dimensions !== undefined ? { dimensions: model.dimensions } : {}) } }\n : {}),\n };\n });\n } else {\n legs = vectorCols.map((column) => ({ column, metric: \"cosine\" }));\n }\n if (ftsCols.length === 0 && legs.length === 0) return null;\n return { pk, cols, colSet: new Set(cols), ftsCols, legs, ...synonyms, ...validity };\n}\n\n/** using → hedef leg. using yok + tek leg → o; using yok + çok leg → adlandırılmış\n * hata (model geçişinde seçim bilinçli olmalı); using yanlış → adlandırılmış hata. */\nfunction pickLeg(table: string, legs: SearchLeg[], using: string | undefined): SearchLeg | null {\n if (legs.length === 0) return null;\n if (using !== undefined) {\n const hit = legs.find((l) => l.column === using);\n if (!hit) {\n throw new Error(\n `search(${table}): using \"${using}\" bir vektör kolunu adlamıyor — mevcut: ${legs.map((l) => l.column).join(\", \")}`,\n );\n }\n return hit;\n }\n if (legs.length === 1) return legs[0]!;\n throw new Error(`search(${table}): birden çok vektör kolu var — 'using' ile seçin (FR-013) — salt metin arıyorsan mode:\\\"text\\\" kullan`);\n}\n\nconst HALF_LIFE_UNIT_SECONDS: Record<string, number> = { s: 1, m: 60, h: 3600, d: 86400 };\n\n/** \"30d\" gibi bir yarı ömrü saniyeye çevirir (FR-004). Biçim <sayı>(s|m|h|d);\n * çözülemeyen YA DA sıfır süre adıyla reddedilir — SQL'e sıfır bölen gitmez. */\nfunction parseHalfLife(s: string): number {\n const m = /^(\\d+)(s|m|h|d)$/.exec(s);\n const sec = m === null ? 0 : Number(m[1]) * HALF_LIFE_UNIT_SECONDS[m[2]!]!;\n if (!Number.isFinite(sec) || sec <= 0) {\n throw new Error(`recency.halfLife \"${s}\" çözümlenemedi — beklenen: pozitif <sayı>+(s|m|h|d), örn. \"30d\" (FR-004)`);\n }\n return sec;\n}\n\n// `eq` BURADA YOK, ve bu bir eksik değil: ÇIPLAK DEĞER eşitliğin yazımı\n// (`{ owner: \"u1\" }`). İkinci bir yazım eklemek, bu run'ın kapatmak için var\n// olduğu şeyi — aynı iş için iki yazım — filtre dilinin içinde yeniden açardı.\n// Guard `eq`'i ADIYLA reddediyor ve çalışan yazımı söylüyor (P6).\nconst WHERE_OPS: Record<string, string> = { gt: \">\", gte: \">=\", lt: \"<\", lte: \"<=\", neq: \"<>\" };\n\n/** FTS kolonlarının sorted coalesce birleşimi — typo-fallback trgm ifadesi ve\n * ts_headline kaynağı (FR-028) AYNI ifadeyi kullanır (Go türev index'iyle birebir). */\nfunction ftsExprOf(ftsCols: string[]): string {\n return [...ftsCols]\n .sort()\n .map((c) => `coalesce(t.${quoteIdent(c)},'')`)\n .join(\" || ' ' || \");\n}\n\n/**\n * expandSynonyms (T020, FR-026): websearch girdisinde tek yönlü eş anlamlı\n * genişletmesi — haritadaki kelime `(kelime OR eş1 OR eş2)` olur\n * (websearch_to_tsquery OR'u tanır). Çift tırnaklı kesimler AYNEN korunur\n * (yazar tam-ifade istedi); eşleşme küçük-harf üzerinden, orijinal token\n * çıktıda kalır. Saf fonksiyon — SQL'e değil bind DEĞERİNE uygulanır.\n */\nexport function expandSynonyms(query: string, map: Record<string, string[]>): string {\n const lower: Record<string, string[]> = {};\n for (const [word, alts] of Object.entries(map)) lower[word.toLowerCase()] = alts;\n return query\n .split(/(\"[^\"]*\")/)\n .map((seg) => {\n if (seg.startsWith('\"')) return seg;\n return seg\n .split(/(\\s+)/)\n .map((tok) => {\n if (tok === \"\" || /^\\s+$/.test(tok)) return tok;\n const alts = lower[tok.toLowerCase()];\n return alts !== undefined && alts.length > 0 ? `(${tok} OR ${alts.join(\" OR \")})` : tok;\n })\n .join(\"\");\n })\n .join(\"\");\n}\n\ntype SearchLogFn = (event: string, fields: Record<string, unknown>) => void;\n// Varsayılan console'a düşer: dikiş kurulmamış runtime'da bile no-results\n// sinyali kaybolmasın (FR-025; bölüm 25-f canlıda sessiz kalmıştı).\nlet searchLogger: SearchLogFn | null = (evt, fields) => {\n console.log(evt, JSON.stringify(fields));\n};\n/** Runtime boot'ta bağlanır (setSecretReader ile aynı kanal deseni): yapısal\n * arama telemetrisi. Varsayılan console.log'tur (a8d5a03: 0-sonuç görünür kalsın); null ile susturulur\n * (FR-025; db.ts'de başka log yolu yok, grep 2026-08-29 boş döndü). */\nexport function setSearchLogger(fn: SearchLogFn | null): void {\n searchLogger = fn;\n}\n\n/** FR-025: nihai dönüş boşsa (typo-fallback DAHİL denendikten sonra) yapısal\n * satır — query HAM haliyle ve 200'e kırpılıp yazılır, sinonim genişletmesi\n * telemetriyi kirletmez. Anahtar/vektör değeri asla loglanmaz. */\nfunction logNoResults(table: string, query: string | undefined, mode: string | undefined, n: number): void {\n if (n === 0) {\n searchLogger?.(\"palbase.search.no_results\", {\n table,\n query: (query ?? \"\").slice(0, 200),\n mode: mode ?? \"hybrid\",\n });\n }\n}\n\n/**\n * fetchFacets (T020, FR-027): filtrelenmiş küme üzerinde kolon başına değer\n * sayaçları — kolon başına top-20, tek UNION ALL sorgusu (parçalar LIMIT/ORDER\n * taşıdığından parantezli). Kolon adları çağıran tarafından şemadan doğrulanmış\n * gelir; where filtreleri sayaçlara da uygulanır (sayaç, kullanıcının gördüğü\n * kümeyi anlatır). Kendi bind listesiyle koşar — ana sorgunun parametreleriyle\n * karışmaz (kullanılmayan bind Postgres'te hatadır).\n */\nasync function fetchFacets(\n live: { unsafe(sql: string, params?: unknown[]): Promise<unknown> },\n table: string,\n colSet: Set<string>,\n facets: string[],\n where: Record<string, unknown>,\n extraWhere: (add: (v: unknown) => string) => string = () => \"\",\n): Promise<Record<string, { value: string | null; count: number }[]>> {\n const bind: unknown[] = [];\n const add = (v: unknown): string => {\n bind.push(v);\n return `$${bind.length}`;\n };\n const whereSql = compileWhere(table, colSet, where, add) + extraWhere(add);\n const parts = facets.map(\n (col) =>\n `(SELECT '${col.replace(/'/g, \"''\")}' AS f, t.${quoteIdent(col)}::text AS v, count(*) AS n ` +\n `FROM ${quoteTable(table)} t WHERE true${whereSql} GROUP BY 2 ORDER BY 3 DESC LIMIT 20)`,\n );\n const rows = (await live.unsafe(parts.join(\" UNION ALL \"), bind)) as\n { f?: string; v?: string | null; n?: unknown }[];\n const out: Record<string, { value: string | null; count: number }[]> = {};\n for (const col of facets) out[col] = [];\n for (const r of rows) {\n if (typeof r.f === \"string\" && out[r.f] !== undefined) {\n out[r.f]!.push({ value: r.v ?? null, count: Number(r.n) });\n }\n }\n return out;\n}\n\n/** C-8 iç kanalı (T018): similar/recommend kaynak id'lerini sonuçtan düşürür.\n * Public search imzasında BİLEREK yok — search-param imza üçlüsü (engine/db +\n * typed-db + endpoint) büyümesin; yalnız bu dosyadaki similar/recommend yazar. */\ninterface InternalSearchParams {\n __excludeIds?: unknown[];\n}\n\n/** FR-029: validity'li tabloda zaman filtresi (T019 türev kolonları sabit:\n * valid_from/valid_to). Varsayılan yalnız güncel satır; \"all\" filtreyi\n * kaldırır; {asOf} o anda geçerli olan versiyonu seçer (tek bind, iki kullanım).\n * Çağıran yalnız cfg.validity === true iken çağırır. */\nfunction validitySql(\n v: \"all\" | { asOf: string } | undefined,\n add: (x: unknown) => string,\n): string {\n if (v === \"all\") return \"\";\n if (v !== undefined) {\n const p = add(v.asOf);\n return ` AND t.\"valid_from\" <= ${p} AND (t.\"valid_to\" IS NULL OR t.\"valid_to\" > ${p})`;\n }\n return ` AND t.\"valid_to\" IS NULL`;\n}\n\n/** Kaynak satır(lar)ı eleyen SQL parçası. Tek id düz `<>`; çoklu\n * `<> ALL(ARRAY[...])` — elemanlar AYRI placeholder: dizi bind'i sürücüde\n * Postgres array literal'ine çevrilmiyor (verify 19-3b dersi, where.in ile aynı). */\nfunction excludeSql(pk: string, ids: unknown[], add: (v: unknown) => string): string {\n if (ids.length === 0) return \"\";\n if (ids.length === 1) return ` AND t.${quoteIdent(pk)} <> ${add(ids[0])}`;\n // ::text — pk uuid'yken text bind'lerle karşılaştırma \"operator does not\n // exist: uuid <> text\" veriyordu (bölüm 25-b canlı ölçümü).\n return ` AND t.${quoteIdent(pk)}::text <> ALL(ARRAY[${ids.map((x) => add(x)).join(\", \")}])`;\n}\n\n/** What `findMany` accepts beside its filter: an ordering, a row ceiling and a\n * page offset. All three used to require dropping to raw SQL, and the docs said\n * so — which is how a tenant's controllers filled up with hand-written SELECTs. */\nexport interface FindManyOptions {\n /** Sıralama: tek obje ya da SIRALI liste (FR-008). `nulls` NULL'ların yerini\n * sabitler — Postgres varsayılanı yöne göre değişir (ASC'de son, DESC'te ilk). */\n orderBy?:\n | { column: string; direction?: \"asc\" | \"desc\"; nulls?: \"first\" | \"last\" }\n | { column: string; direction?: \"asc\" | \"desc\"; nulls?: \"first\" | \"last\" }[];\n /** Projeksiyon (FR-009): verilmezse `SELECT *`. Kolon adları ŞEMAYA karşı\n * doğrulanır — bilinmeyen ad SQL'e ulaşmadan, adıyla reddedilir. */\n select?: string[];\n /**\n * İLİŞKİLİ SATIRLARI da getir — TEK sorguda, LATERAL ile.\n *\n * `has` ilişki üzerinden SÜZER, `with` GETİRİR. İkisi aynı ilişki grafiğini\n * okuyor (yabancı anahtarlardan türetilmiş), yani ilişki adları aynı.\n */\n with?: Record<string, unknown>;\n limit?: number;\n /** Rows to skip before the page starts. Only meaningful with `limit`, and\n * refused without it — see `offsetClause`. */\n offset?: number;\n}\n\n/** The table's columns as the installed schema knows them, or null when this\n * process has no schema for it (unit tests, a table addressed by name alone).\n * Null means \"cannot validate\", never \"allow anything into SQL\": every\n * identifier still goes through quoteIdent. */\n/**\n * Tablonun tek-kolon primary key'i (FR-015). Bulunamazsa `null`.\n *\n * PK adı ŞEMADAN okunur; SQL'e \"id\" gömmek, pk'sı başka adla bildirilmiş bir\n * tabloyu çalışma zamanı hatasına çevirirdi. Çok kolonlu PK'da `null` dönüyor:\n * kilit sırası birden çok kolonla da kurulabilirdi ama bu run onu istemiyor ve\n * yanlış bir sıra, olmayan bir sıradan daha kötüdür.\n *\n * \"id\" TAHMİNİ YOK — ve bu bir sadelik tercihi değil, ÖLÇÜLMÜŞ bir veri\n * bozulmasının düzeltmesi (gözcü W2-B/C1 ve T013/C-1, ikisi de canlı pg16'da):\n * dış `UPDATE` artık orijinal yüklemi taşımıyor, tek bağı `t.pk = locked.pk`.\n * `primaryKey: [\"tenant_id\",\"id\"]` bildiren bir tabloda hiçbir kolona\n * `_def.primaryKey` yazılmıyor, eski kod `id`'yi anahtar sanıyordu, ve `id`\n * benzersiz olmadığı için filtreye UYMAYAN satırlar da içeri giriyordu —\n * ölçülen sonuç kiracılar arası yazma ve `deleteMany`'de tablonun boşalması.\n *\n * Tablo düzeyi `primaryKey` dizisi de OKUNUYOR: tek elemanlıysa anahtar odur.\n * İki şekli de tanımak `searchConfigFor`'un aynı dosyada kurduğu emsal\n * (\"both shapes exist in the wild\") — orada `_def`'siz düz kolon nesnesi de\n * kabul ediliyor, burada da edilmeli.\n */\nfunction computePrimaryKey(table: string): string | null {\n const t = tableDefOf(table) as\n | { columns?: Record<string, unknown>; primaryKey?: unknown }\n | undefined;\n const columns = (t?.columns ?? {}) as Record<string, unknown>;\n const cols = Object.keys(columns);\n if (cols.length === 0) return null;\n // Tablo düzeyi bildirim ÖNCE: composite PK burada yaşıyor ve tek doğru cevap\n // \"birden çoksa anahtar yok\"tur.\n const declared = t?.primaryKey;\n if (Array.isArray(declared)) {\n if (declared.length !== 1) return null;\n const only = declared[0];\n return typeof only === \"string\" && cols.includes(only) ? only : null;\n }\n const pkOf = (c: unknown): boolean => {\n if (c === null || typeof c !== \"object\") return false;\n const rec = c as Record<string, unknown>;\n // İki kolon şekli: `_def` taşıyan builder ve düz nesne (schema-json.ts'in\n // ürettiği şekil). `searchConfigFor` ile aynı gerekçe.\n const def = (\"_def\" in rec ? rec._def : rec) as { primaryKey?: unknown } | null;\n return def !== null && typeof def === \"object\" && def.primaryKey === true;\n };\n const pks = cols.filter((c) => pkOf(columns[c]));\n return pks.length === 1 ? pks[0]! : null;\n}\n\n/**\n * Filtre TEK bir satırı adıyla mı seçiyor? (`{ id: \"a1\" }`)\n *\n * Öyleyse kilit sırasının anlamı yok — sıra ancak birden çok satır varken\n * vardır. Tek satırlık yazmayı CTE'ye sokmak, en sık yolu bedava yavaşlatırdı.\n */\nfunction isSinglePkEquality(where: Record<string, unknown>, pk: string | null): boolean {\n if (pk === null) return false;\n const keys = Object.keys(where);\n if (keys.length !== 1 || keys[0] !== pk) return false;\n const v = where[pk];\n return v !== null && (typeof v !== \"object\" || Array.isArray(v));\n}\n\n/**\n * `appendOnly` tabloya yazma reddi (FR-032).\n *\n * Tip kapısı (`EnvTypedTable` altı üyeyi Omit ediyor) `Database.public.x` yolunu\n * kapatıyor. Ama motoru tipten geçmeden çağıran yollar var — `DBOps` doğrudan,\n * tablo adı string olarak. Bir muhasebe kaydında \"TypeScript'ten silinemez\"\n * yeterli değil.\n *\n * Hata ÇALIŞAN alternatifi adlandırıyor (P6): telafi kaydı eklemek gerçekten\n * çalışan yol, çünkü `insert` bu tabloda açık kalıyor.\n */\nfunction assertNotAppendOnly(caller: string, table: string): void {\n const def = tableDefOf(table) as { appendOnly?: boolean } | undefined;\n if (def?.appendOnly !== true) return;\n throw new Error(\n `${caller}(${table}): \"${table}\" append-only — satır güncellenemez ya da silinemez. ` +\n `Düzeltme için TELAFİ KAYDI ekleyin: insert(\"${table}\", { … }) ile ters işareti taşıyan ` +\n `yeni bir satır yazın; geçmiş olduğu gibi kalsın diye tablo böyle bildirilmiş (appendOnly: true).`,\n );\n}\n\nfunction computeSchemaColumns(table: string): Set<string> | null {\n const t = tableDefOf(table);\n const cols = t?.columns ? Object.keys(t.columns) : [];\n return cols.length > 0 ? new Set(cols) : null;\n}\n\n/** Keep PostgreSQL microseconds before a driver can reduce them to a JS Date.\n * All schema-aware result paths share this expression; predicates/order retain\n * the native timestamp column so indexes and comparison semantics stay intact. */\nfunction timestampResult(expr: string): string {\n return `CASE WHEN isfinite(${expr}) AND extract(year FROM ${expr} AT TIME ZONE 'UTC') BETWEEN 1 AND 9999 THEN to_char(${expr} AT TIME ZONE 'UTC', 'YYYY-MM-DD\"T\"HH24:MI:SS.US\"Z\"') ELSE ${expr}::text END`;\n}\n\nfunction columnResult(table: string, column: string, alias?: string): string {\n const expr = `${alias ? `${quoteIdent(alias)}.` : \"\"}${quoteIdent(column)}`;\n return columnTypeOf(table, column) === \"timestamp\" ? timestampResult(expr) : expr;\n}\n\nfunction projectedColumn(table: string, column: string, alias?: string): string {\n const expr = columnResult(table, column, alias);\n return columnTypeOf(table, column) === \"timestamp\" ? `${expr} AS ${quoteIdent(column)}` : expr;\n}\n\n/** Unknown schemas keep their raw wildcard behavior. Declared timestamps need\n * explicit expressions; the result then contains the declared row shape. */\n// ── can: policy'nin satır başına yankısı (FR-001…003 · D-15 · D-18) ────────────\n//\n// Tablonun adlandırılmış UPDATE policy'lerinin `using` ifadesi, satırı seçen\n// AYNI SELECT'te `(<using>) AS \"can:<name>\"` boolean sütunu olarak değerlendirilir;\n// `foldCan` true olanların adını `can: string[]`e katlar. Kural TEK kopya —\n// policy'de. Ham string (FR-028) BİREBİR girer; yapısal ifade `t` alias'ıyla\n// nitelenerek render edilir (Go `renderPolicyExpr`'in can-amaçlı ikizi). Render\n// edilemeyen (`using` yok, bilinmeyen kind, tablo adıyla nitelenmiş ham string)\n// DÜŞER ve warn yazar: sessiz `true` bir yetki yalanı olurdu, sessiz düşüş yalnız\n// bir düğmeyi saklar.\n//\n// Postgres'in kendi UPDATE kuralı da taşınır: `TO <rol>` listesi (policy o role\n// uygulanmıyorsa `can` da vaat etmez) ve AS RESTRICTIVE policy'ler (her izinli\n// policy'ye AND'lenir). `for(\"all\")` policy'leri `can`'e GİRMEZ — adlandırılmış\n// bir update policy'si değildir; kısıtlayıcı olanları yine AND'lenir.\nconst CAN_PREFIX = \"can:\";\ntype CanEntry = { name: string; using: string };\ntype CanDrop = { name: string; reason: string };\nconst canMemo: SchemaMetadataCache<Map<string, CanEntry[]>> = new WeakMap();\n\n/** C-1. `alias`: satır kaynağının SQL niteleyicisi — `t`, ya da alias'sız yolda tırnaklı tablo adı. */\nexport function canColumns(def: TableDef, alias: string): { sql: string[]; dropped: string[] } {\n const { entries, dropped } = canEntries(def, alias);\n return {\n sql: entries.map((e) => `${e.using} AS ${quoteIdent(CAN_PREFIX + e.name)}`),\n dropped: dropped.map((d) => d.name),\n };\n}\n\n/** Bildirilen rol üretimde `backend_<rol>` ikiziyle koşar (`config.ts` dbRole); ikisi de sayılır. Boş liste = PUBLIC. */\nfunction canRoleGate(roles: readonly string[]): string | null {\n if (roles.length === 0) return null;\n const names = roles.flatMap((r) => [r, `backend_${r}`]).map((r) => `'${r.replace(/'/g, \"''\")}'`);\n return `(current_user = ANY (ARRAY[${names.join(\", \")}]))`;\n}\n\nfunction canEntries(def: TableDef, alias: string): { entries: CanEntry[]; dropped: CanDrop[] } {\n const policies = def.policies ?? [];\n const dropped: CanDrop[] = [];\n const restrictive: string[] = [];\n for (const p of policies) {\n if (p.permissive !== false || (p.command !== \"update\" && p.command !== \"all\")) continue;\n const r = renderCanUsing(p, alias, def.name);\n if (r === null) {\n // Bir kısıtlayıcı policy değerlendirilemiyorsa HİÇBİR update policy'si vaat edilemez:\n // eksik bir AND, olmayan bir izni gösterirdi.\n return {\n entries: [],\n dropped: policies\n .filter((q) => q.command === \"update\" && q.permissive !== false)\n .map((q) => ({ name: q.name, reason: `restrictive policy \"${p.name}\" cannot be evaluated as a column` })),\n };\n }\n // Kısıtlayıcı da yalnız KENDİ `TO` rolüne uygulanır (Postgres): rol dışındaysa terim `true`.\n const rGate = canRoleGate(p.roles ?? []);\n restrictive.push(rGate === null ? r : `((NOT ${rGate}) OR ${r})`);\n }\n const entries: CanEntry[] = [];\n for (const p of policies) {\n if (p.command !== \"update\" || p.permissive === false) continue;\n // Postgres sonuç kolonunu 63 BAYTTA kırpar (NAMEDATALEN); `can:` 4 bayt yer.\n // Kırpılmış ad şemada olmayan bir değer olurdu — hiç vaat etme.\n if (Buffer.byteLength(CAN_PREFIX + p.name, \"utf8\") > 63) {\n dropped.push({ name: p.name, reason: \"its name is longer than 59 bytes and Postgres would truncate the column alias\" });\n continue;\n }\n const using = renderCanUsing(p, alias, def.name);\n if (using === null) {\n dropped.push({ name: p.name, reason: \"its using expression cannot be selected as a column (null; a raw string that is table-qualified, carries a comment or unbalanced parentheses, or calls auth.has_permission outside a (select …) wrapper; or a shape this engine does not render)\" });\n continue;\n }\n const gate = canRoleGate(p.roles ?? []);\n const parts = [...(gate === null ? [] : [gate]), using, ...restrictive];\n entries.push({ name: p.name, using: parts.length === 1 ? using : `(${parts.join(\" AND \")})` });\n }\n return { entries, dropped };\n}\n\n/** Ham string her zaman parantezlenir (içinde `a or b` olabilir); yapısal ifade\n * kendi parantezini taşıyorsa (binop/and/or/not/isNull/exists) ikinci kat açılmaz.\n * Tablo ADIYLA nitelenmiş ham string (`transfers.status`) alias altında çözülmez —\n * okuma anında 500 yerine burada düşer (fail-closed, warn). */\nclass CanRenderError extends Error {}\n\n/** Motorun kendi alias uzayı: `t` (satır), `w<n>`/`wj<n>` (with), `locked` (kilit CTE).\n * Bir `exists` alt-sorgusu bunlardan birini alsa korelasyon SESSİZCE `x = x`e çökerdi. */\nconst ENGINE_ALIASES = /^(t|locked|w\\d+|wj\\d+|x|q|g|p|upd)$/;\n\nfunction renderCanUsing(p: PolicyDef, qualifier: string, tableName: string): string | null {\n if (p.using === null || p.using === undefined) return null;\n if (typeof p.using === \"string\") {\n // String literalleri çıkar: `has_permission('transfers.approve')` içindeki\n // `transfers.` bir tablo niteleyicisi değildir.\n const withoutLiterals = p.using.replace(/'(?:[^']|'')*'/g, \"''\");\n // Yorum (`--`, `/*`) tek satırlık SELECT listesinde açık parantezi yutar ve\n // TABLOYU okunamaz yapardı; dengesiz parantez ve kapanmamış tırnak da öyle. Düşür, uyar.\n if (/--|\\/\\*/.test(withoutLiterals)) return null;\n if (withoutLiterals.replace(/''/g, \"\").includes(\"'\")) return null;\n let depth = 0;\n for (const ch of withoutLiterals) {\n if (ch === \"(\") depth++;\n else if (ch === \")\" && --depth < 0) return null;\n }\n if (depth !== 0) return null;\n // Tablo ADIYLA niteleme — çıplak (`transfers.status`), tırnaklı\n // (`\"transfers\".\"status\"`) ya da şema önekli (`public.transfers.status`) —\n // alias altında çözülmez; `CREATE POLICY` kabul eder, SELECT etmez (W1 h1 C-4 ×3).\n const tbl = tableName.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n const qualified = new RegExp(`(^|[^A-Za-z0-9_])(?:\"?[A-Za-z_][A-Za-z0-9_]*\"?\\\\s*\\\\.\\\\s*)?\"?${tbl}\"?\\\\s*\\\\.`);\n if (qualified.test(withoutLiterals)) return null;\n // FR-006: çıplak `auth.has_permission(...)` SATIR BAŞINA koşar; `(select …)`\n // sarmalı statement başına bir kez. HER çağrı sarmalı olmalı — bir sarmalı bir\n // çıplak çağrı da düşer. Noktanın çevresindeki boşluk SQL'de serbesttir (`auth . has_permission`).\n // Tanımlayıcı tırnaklı da yazılabilir (`auth.\"has_permission\"`), sarmalı biçim\n // `(select (auth.has_permission(…)))` de InitPlan'dır (W1 h1-r4 N-11/N-12).\n const calls = withoutLiterals.match(/auth\\s*\\.\\s*\"?has_permission\"?\\s*\\(/gi) ?? [];\n const wrapped = withoutLiterals.match(/\\(\\s*select\\s*[(\\s]*auth\\s*\\.\\s*\"?has_permission\"?\\s*\\(/gi) ?? [];\n if (calls.length !== wrapped.length) return null;\n return `(${p.using})`;\n }\n try {\n const rendered = canExprSql(p.using, qualifier);\n const selfParenthesized =\n p.using.kind === \"binop\" || p.using.kind === \"and\" || p.using.kind === \"or\" ||\n p.using.kind === \"not\" || p.using.kind === \"isNull\" || p.using.kind === \"exists\";\n return selfParenthesized ? rendered : `(${rendered})`;\n } catch (err) {\n if (err instanceof CanRenderError) return null;\n throw err;\n }\n}\n\nconst CAN_BINOPS: Record<string, string> = { eq: \"=\", neq: \"<>\", gt: \">\", gte: \">=\", lt: \"<\", lte: \"<=\" };\n\nfunction canLiteral(v: string | number | boolean | null): string {\n if (v === null) return \"NULL\";\n if (typeof v === \"boolean\") return v ? \"TRUE\" : \"FALSE\";\n if (typeof v === \"number\") {\n if (!Number.isFinite(v)) throw new CanRenderError(\"can: non-finite literal\");\n return String(v);\n }\n return `'${v.replace(/'/g, \"''\")}'`;\n}\n\n/** Yapısal policy ifadesini SQL'e çevirir. Alias'sız kolon = DIŞ (bizim) satır,\n * `exists` içinde de — Go emitter'ının kuralı (policy_expr.go:109-131). */\nfunction canExprSql(e: PolicyExpr, qualifier: string): string {\n switch (e.kind) {\n case \"col\":\n return e.alias !== undefined && e.alias !== \"\"\n ? `${quoteIdent(e.alias)}.${quoteIdent(e.name)}`\n : `${qualifier}.${quoteIdent(e.name)}`;\n case \"authUid\":\n return \"(SELECT auth.uid())\";\n case \"lit\":\n return canLiteral(e.value);\n case \"binop\": {\n const op = CAN_BINOPS[e.op];\n if (op === undefined) throw new CanRenderError(`can: unknown operator ${String(e.op)}`);\n return `(${canExprSql(e.left, qualifier)} ${op} ${canExprSql(e.right, qualifier)})`;\n }\n case \"and\":\n return e.parts.length === 0 ? \"(true)\" : `(${e.parts.map((p) => canExprSql(p, qualifier)).join(\" AND \")})`;\n case \"or\":\n return e.parts.length === 0 ? \"(false)\" : `(${e.parts.map((p) => canExprSql(p, qualifier)).join(\" OR \")})`;\n case \"not\":\n return `(NOT ${canExprSql(e.expr, qualifier)})`;\n case \"isNull\":\n return `(${canExprSql(e.expr, qualifier)} IS ${e.negated ? \"NOT \" : \"\"}NULL)`;\n case \"exists\":\n if (e.alias === \"\" || ENGINE_ALIASES.test(e.alias)) {\n throw new CanRenderError(`can: exists alias \"${e.alias}\" collides with the engine's own aliases — the correlation would silently collapse`);\n }\n return `EXISTS (SELECT 1 FROM ${quoteTable(e.table)} ${quoteIdent(e.alias)} WHERE ${canExprSql(e.predicate, qualifier)})`;\n default:\n throw new CanRenderError(`can: unknown policy expression kind ${String((e as { kind: unknown }).kind)}`);\n }\n}\n\n/** Şema kurulumu başına bir kez hesaplanır; uyarı tablo başına BİR kez (alias sayısı kadar değil). */\nfunction canEntriesOf(table: string, alias: string): CanEntry[] {\n const byAlias = memoTable(canMemo, currentSchema, table, () => new Map<string, CanEntry[]>());\n const hit = byAlias.get(alias);\n if (hit !== undefined) return hit;\n const def = tableDefOf(table);\n const warnOnce = (msg: string): void => {\n if (byAlias.has(\"__warned\")) return;\n byAlias.set(\"__warned\", []);\n console.warn(msg);\n };\n if (def === null || def.policies === undefined) {\n byAlias.set(alias, []);\n return [];\n }\n if (hasCanColumn(table)) {\n // Gerçek bir `can` kolonu/ilişkisi var: onu ezmek veri kaybı olurdu. Afordans bu tabloda kapalı.\n warnOnce(`can(${table}): the table declares a column or relation named \"can\", so the policy echo is disabled for it — rename it to get can`);\n byAlias.set(alias, []);\n return [];\n }\n const { entries, dropped } = canEntries(def as TableDef, alias === \"\" ? quoteTable(table) : alias);\n if (dropped.length > 0) {\n warnOnce(\n dropped\n .map((d) => `can(${table}): policy \"${d.name}\" is not exposed in can — ${d.reason}; the database still enforces it`)\n .join(\"\\n\"),\n );\n }\n byAlias.set(alias, entries);\n return entries;\n}\n\n/** Arama/sayfa gibi sarmalanmış sorgularda `can` DIŞ SELECT'te seçilir: iç\n * sorgunun FROM'u (`fused`, `sem`, `kw`) pk'yı da taşır ve niteliksiz ham `using`\n * orada \"ambiguous\" olurdu; dışta kapsamda yalnız `q` vardır (W1 r1). */\nfunction canOuter(table: string): string {\n const cols = canProjection(table, \"q\");\n return cols.length === 0 ? \"\" : `, ${cols.join(\", \")}`;\n}\n\nfunction canProjection(table: string, alias: string): string[] {\n return canEntriesOf(table, alias).map((e) => `${e.using} AS ${quoteIdent(CAN_PREFIX + e.name)}`);\n}\n\n/** `with` ile gelen iç içe satırın JSON nesnesine eklenen `'can:<name>', <expr>` çiftleri —\n * aynı statement, aynı kural (FR-002); satır tipi `can` taşıdığı için değeri de taşımalı. */\nfunction canJsonPairs(table: string, alias: string): string[] {\n return canEntriesOf(table, alias).map((e) => `${quoteLiteral(CAN_PREFIX + e.name)}, ${e.using}`);\n}\n\n/** \"can:*\" sütunlarını `can: string[]`e katlar ([PLAN-FREE] adı). `partial`: `select`\n * projeksiyonu — alan hiç yazılmaz. */\nfunction foldCan(table: string, row: Row, partial: boolean): Row {\n let can: string[] | null = null;\n for (const key of Object.keys(row)) {\n if (!key.startsWith(CAN_PREFIX)) continue;\n can ??= [];\n if (row[key] === true) can.push(key.slice(CAN_PREFIX.length));\n delete row[key];\n }\n if (hasCanColumn(table)) return row; // rezerve ad: kolon/ilişki neyse o kalır\n if (can !== null) row.can = can;\n else if (!partial && tableDefOf(table) !== null) {\n // Tam satır, sütun gelmedi: policy'si olan bir tabloda bu, sütun taşımayan\n // bir okuma yolu demektir — `[]` yazılır (fail-closed) ama SESSİZ değil\n // (W1 h1-r4 N-9: arama üç tur boyunca böyle `[]` uydurdu).\n if (canEntriesOf(table, \"\").length > 0) {\n const flags = memoTable(canMemo, currentSchema, table, () => new Map<string, CanEntry[]>());\n if (!flags.has(\"__missing_warned\")) {\n flags.set(\"__missing_warned\", []);\n console.warn(`can(${table}): a full-row read returned no \"can:*\" columns although the table declares update policies — this statement shape does not carry can; the row gets can: []`);\n }\n }\n row.can = [];\n }\n return row;\n}\n\n/** `can` adı REZERVE: gerçek bir kolon YA DA ilişki (`can_id` FK'sinden türeyen\n * `can`, ya da `refAs`/`reverseAs`) taşıyan tabloda yankı kapalı — ezmek veri\n * kaybı, `with` döngüsüyle çakışmak TypeError olurdu (W1 h1-r2 C-3). */\nfunction hasCanColumn(table: string): boolean {\n const cols = tableDefOf(table)?.columns;\n if (cols !== undefined && Object.prototype.hasOwnProperty.call(cols, \"can\")) return true;\n return (currentRelations.get(table) ?? []).some((rel) => rel.name === \"can\");\n}\n\nfunction rowProjection(table: string, alias?: string, wildcard = alias ? `${alias}.*` : \"*\"): string {\n const cols = schemaColumns(table);\n let base = wildcard;\n if (cols && memoTable(timestampMemo, currentSchema, table, () => [...cols].some(c => columnTypeOf(table, c) === \"timestamp\"))) {\n const projections = memoTable(projectionMemo, currentSchema, table, () => new Map<string, string>());\n const key = alias ?? \"\";\n let sql = projections.get(key);\n if (sql === undefined) { sql = [...cols].map(c => projectedColumn(table, c, alias)).join(\", \"); projections.set(key, sql); }\n base = sql;\n }\n const can = canProjection(table, alias ?? \"\");\n if (can.length === 0) return base;\n // `*` alias altında `t.*` olmak zorunda: `with` LATERAL join'leri kendi `d` sütununu da taşır.\n const rows = base === \"*\" && alias !== undefined ? `${alias}.*` : base;\n return `${rows}, ${can.join(\", \")}`;\n}\n\n/** ORDER BY, with the column checked BEFORE it can reach SQL. Against a known\n * schema the check is membership; without one it is a conservative identifier\n * shape. Either way an ordering column is never interpolated on trust. */\n/**\n * Projeksiyon listesi (FR-009). Verilmezse `*`.\n *\n * Her kolon `orderBy` ile AYNI kapıdan geçer: şema biliniyorsa üyelik, bilinmiyorsa\n * tanımlayıcı şekli. Listenin her öğesi ayrı doğrulanır — ilk öğe masumken\n * ikincisini atlamak, listeye bir öğe eklemeyi enjeksiyon yoluna çevirirdi.\n */\n/**\n * `col()` referansını SQL'e çevirir (FR-011).\n *\n * Kolon adı SQL METNİNE girer — parametre olarak bağlanamaz, çünkü bağlanan\n * şey bir değer olurdu ve `total > 'amount_paid'` string karşılaştırması\n * yapardı. Metne giren her ad `selectClause`/`orderClause` ile AYNI kapıdan\n * geçer: şema biliniyorsa üyelik, bilinmiyorsa tanımlayıcı şekli.\n */\nfunction colRefSql(table: string, known: Set<string> | null, ref: { $col: string }, caller: string, alias = \"t\"): string {\n const name = ref.$col;\n const shapeOK = /^[A-Za-z_][A-Za-z0-9_]*$/.test(name);\n if (known !== null ? !known.has(name) : !shapeOK) {\n throw new Error(`${caller}(${table}): col(\"${name}\") tabloda yok (FR-011)`);\n }\n return `${alias}.${quoteIdent(name)}`;\n}\n\nfunction selectClause(table: string, known: Set<string> | null, select: string[] | undefined): string {\n // BOŞ PROJEKSİYON `*` DEĞİLDİR — ve sessizce öyle davranıyordu.\n //\n // `select: []` ile `select: undefined` aynı dala düşüyor ve ikisi de HER\n // KOLONU çekiyordu. Ama anlamları zıt: birini YAZMAMAK \"projeksiyon yok,\n // hepsini ver\" demek; BOŞ BİR LİSTE yazmak \"şu kolonları ver\" deyip hiçbirini\n // saymamak demek — ve cevabı kesinlikle \"hepsi\" değil.\n //\n // Şekli üreten hâl de tam olarak sessiz kalmaması gereken hâl:\n // `select: cols.filter(isVisible)` her kolonu elediğinde çağıran, gizlemeye\n // çalıştığı kolonların TAMAMINI alıyordu. Aynı dosya boş `in` listesini\n // (`false` yazıyor) ve boş filtreyi (adıyla reddediyor) tam bu gerekçeyle\n // ele alıyor; `select` onlardan ayrışmıştı.\n if (select !== undefined && select.length === 0) {\n throw new Error(\n `findMany(${table}): select boş bir liste aldı — bu \"hepsini ver\" DEĞİL, ` +\n `\"hiçbirini saymadım\" demek. Projeksiyon istemiyorsanız anahtarı hiç koymayın; ` +\n `istiyorsanız en az bir kolon adı verin.`,\n );\n }\n if (select === undefined) return rowProjection(table, \"t\", \"*\");\n return select\n .map((col) => {\n const shapeOK = /^[A-Za-z_][A-Za-z0-9_]*$/.test(col);\n if (known !== null ? !known.has(col) : !shapeOK) {\n throw new Error(`findMany(${table}): select kolonu \"${col}\" tabloda yok`);\n }\n return columnTypeOf(table, col) === \"timestamp\" ? projectedColumn(table, col, \"t\") : `t.${quoteIdent(col)}`;\n })\n .join(\", \");\n}\n\n/** JSON anahtarı için SQL string literal'i. Kolon adı zaten şemaya karşı\n * doğrulanıyor, ama tek tırnak KAÇIRILMADAN bir literal kurmak, doğrulamanın\n * bir gün gevşediği anı enjeksiyona çevirirdi. */\nfunction quoteLiteral(v: string): string {\n return `'${v.replace(/'/g, \"''\")}'`;\n}\n\n/** {@link orderClause}'ın TAKMA ADLI ikizi — `with` alt sorgusu kendi adını\n * kullanır, dış sorgunun `t`'sini değil. */\nfunction orderClauseFor(\n table: string,\n known: Set<string> | null,\n orderBy: unknown,\n alias: string,\n): string {\n if (orderBy === undefined || orderBy === null) return \"\";\n const items = (Array.isArray(orderBy) ? orderBy : [orderBy]) as {\n column: string;\n direction?: \"asc\" | \"desc\";\n nulls?: \"first\" | \"last\";\n }[];\n if (items.length === 0) return \"\";\n const rendered = items.map((o) => {\n const col = o.column;\n const shapeOK = /^[A-Za-z_][A-Za-z0-9_]*$/.test(col);\n if (known !== null ? !known.has(col) : !shapeOK) {\n throw new Error(`with(${table}): orderBy kolonu \"${col}\" tabloda yok`);\n }\n const dir = o.direction === \"desc\" ? \"DESC\" : \"ASC\";\n const nulls = o.nulls === \"first\" ? \" NULLS FIRST\" : o.nulls === \"last\" ? \" NULLS LAST\" : \"\";\n return `${alias}.${quoteIdent(col)} ${dir}${nulls}`;\n });\n return ` ORDER BY ${rendered.join(\", \")}`;\n}\n\nfunction orderClause(\n table: string,\n known: Set<string> | null,\n orderBy: FindManyOptions[\"orderBy\"],\n): string {\n if (!orderBy) return \"\";\n // SIRA KORUNUR: `ORDER BY`ın anlamı sıralı bir listedir, küme değil. Tek obje\n // biçimi de kabul edilir — çağıranların hepsi aynı anda göç edemez ve tek\n // öğeli bir liste ile tek obje AYNI SQL'i üretir (FR-008).\n const items = Array.isArray(orderBy) ? orderBy : [orderBy];\n if (items.length === 0) return \"\";\n const rendered = items.map((o) => {\n const col = o.column;\n const shapeOK = /^[A-Za-z_][A-Za-z0-9_]*$/.test(col);\n if (known !== null ? !known.has(col) : !shapeOK) {\n throw new Error(`findMany(${table}): orderBy kolonu \"${col}\" tabloda yok`);\n }\n const dir = o.direction === \"desc\" ? \"DESC\" : \"ASC\";\n // NULL'ın YERİ ayrı bir karardır: Postgres varsayılanı ASC'de NULLS LAST,\n // DESC'te NULLS FIRST'tür ve bu, sıralama yönünü değiştirdiğinde NULL'ların\n // sessizce yer değiştirmesi demektir. Yazar isterse sabitler.\n const nulls = o.nulls === \"first\" ? \" NULLS FIRST\" : o.nulls === \"last\" ? \" NULLS LAST\" : \"\";\n return `${quoteIdent(col)} ${dir}${nulls}`;\n });\n return ` ORDER BY ${rendered.join(\", \")}`;\n}\n\n/** LIMIT, as a literal because it is a number this code produced — a bound must\n * not be bindable to something that is not one. */\nfunction limitClause(limit: number | undefined): string {\n if (limit === undefined) return \"\";\n if (!Number.isInteger(limit) || limit < 0) {\n throw new Error(`findMany: limit bir negatif olmayan tam sayı olmalı (geldi: ${String(limit)})`);\n }\n return ` LIMIT ${limit}`;\n}\n\n/** OFFSET, a literal for the same reason LIMIT is one.\n *\n * A bare `offset` — no `limit` — is refused BY NAME. Postgres accepts it, but\n * \"skip 10 rows of an unbounded result\" is not a page, and every caller that\n * writes `offset` means a page; letting it through would hand back the whole\n * tail and look like it worked. */\nfunction offsetClause(offset: number | undefined, limit: number | undefined): string {\n if (offset === undefined) return \"\";\n if (!Number.isInteger(offset) || offset < 0) {\n throw new Error(\n `findMany: offset bir negatif olmayan tam sayı olmalı (geldi: ${String(offset)})`,\n );\n }\n if (limit === undefined) {\n throw new Error(\n \"findMany: offset yalnız limit ile birlikte verilir — limitsiz offset bir sayfa değil, sınırsız bir kuyruğun kaydırılmışıdır\",\n );\n }\n return ` OFFSET ${offset}`;\n}\n\n/** where → SQL (FR-016): eşitlik + gt/gte/lt/lte/neq/in, AND'li. Kolon adı\n * şemadan doğrulanır — bilinmeyen ad SQL'e ulaşmadan, adıyla reddedilir. */\n/**\n * Filtrenin ÖNEKSİZ gövdesi: `a AND b`, baştaki `AND` olmadan.\n *\n * Ayrı duruyor çünkü {@link compileWhere} çağıranlarına ` AND …` önekiyle\n * dönüyor (`WHERE true` + dönüş deseni) ve bileşim dalları (OR/AND/NOT) o öneki\n * TAŞIYAMAZ — iç içe geçtiğinde `(( AND x) OR ( AND y))` üretirdi.\n */\nfunction compileWhereBare(\n table: string,\n colSet: Set<string> | null,\n where: Record<string, unknown>,\n add: (v: unknown, column?: string, table?: string) => string,\n caller = \"search\",\n /** Kolonların niteleneceği takma ad. `has` alt sorgusu KENDİ adını verir —\n * iç ve dış sorgu aynı `t`'yi paylaşsaydı korelasyon sessizce `x = x`'e\n * çökerdi; policy tarafında bu tam olarak ölçülmüş bir hataydı. */\n alias = \"t\",\n /** İç içe `has` derinliği — takma adları ayırmak için. */\n depth = 0,\n): string {\n const parts: string[] = [];\n // A column's `toDb` applies on the WHERE path too. Without it a transform is\n // half-wired: `insert` writes the converted value and `findMany({ at: date })`\n // binds the client-side shape, so the row that was just written does not come\n // back. The bind goes through `bind` below, never `add` directly.\n const transforms = transformsOf(currentSchema, table);\n const bindFor = (col: string) => {\n const t = transforms.get(col);\n return (v: unknown) => add(t?.toDb === undefined || v === null || v === undefined ? v : t.toDb(v), col, table);\n };\n // The refusals live in ONE place (db/input-guards.ts) because `fakeDatabase()`\n // is a second implementation of this surface and has to answer identically —\n // measured on 24.1.0: every call this function had just started refusing went\n // through the fake silently, so an author's test went green on code that\n // throws in production.\n assertUsableFilter(caller, table, where);\n // K3 (FR-018): fragment SORGUNUN İÇİNE girer. Metin parçaları SQL'e, değerler\n // BOUND parametreye — arada, birleştirilmeden. Birleştirilmiş tek string'in\n // içinden hangi kısmın kullanıcı verisi olduğu bir daha çıkarılamaz; enjeksiyon\n // tam orada doğar. Tanımlayıcı gömme kapağı yok (research B4: Drizzle\n // CVE-2026-39356, Knex CVE-2019-10757).\n if (isSqlFragment(where)) {\n const { text, values } = where.$sql;\n if (text.length !== values.length + 1) {\n throw new Error(\n `${caller}(${table}): sqlFragment parçaları bozuk (${text.length} metin, ${values.length} değer) — bunu üreten tek şey template tag'i, elle kurulmuş bir nesne değil`,\n );\n }\n let out = text[0] ?? \"\";\n for (let i = 0; i < values.length; i++) out += `${add(values[i])}${text[i + 1] ?? \"\"}`;\n // PARANTEZ: bu fonksiyonun kendi kuralı, fragment dalına da uygulanır.\n // `whereSql` üst düzeyde `WHERE true AND …` önekiyle şansa denk düşüyordu\n // ama `search`/`facets` onu BAŞKA koşullarla birleştiriyor (`… @@ … ${whereSql}`);\n // orada `hit AND a=1 OR b=2` ile `hit AND (a=1 OR b=2)` farklı sorgular ve\n // ölçüldü: 3 satır vs 1 satır (W2-B/C2).\n return `(${out})`;\n }\n for (const [col, cond] of Object.entries(where)) {\n // Boolean bileşimi (FR-007). Her dal PARANTEZLENİR: `a AND (b OR c)` ile\n // `(a AND b) OR c` farklı sorgulardır ve parantezsiz derleme ikincisini\n // SESSİZCE üretirdi. Dallar aynı derleyiciden geçer — iki filtre dili olmaz.\n if (col === \"OR\" || col === \"AND\") {\n const branches = cond as Record<string, unknown>[];\n if (branches.length === 0) {\n // Boş liste \"hiçbir satır\" demektir (OR) ya da \"koşulsuz\" (AND);\n // ikisini de AÇIKÇA yaz, sessiz tam-tarama bırakma.\n parts.push(col === \"OR\" ? \"false\" : \"true\");\n continue;\n }\n const compiled = branches.map(\n (b) => `(${compileWhereBare(table, colSet, b, add, caller, alias, depth)})`,\n );\n parts.push(`(${compiled.join(col === \"OR\" ? \" OR \" : \" AND \")})`);\n continue;\n }\n // İLİŞKİ ÜZERİNDEN SÜZME (`has`) — ve bu JOIN'in yerine geçen şey değil,\n // JOIN'in İHTİYAÇ DUYULMAYAN hâli.\n //\n // `{ has: { user_interests: { user_id: uid } } }` şuna derleniyor:\n // t.\"id\" IN (SELECT r1.\"interest_id\" FROM \"user_interests\" r1 WHERE r1.\"user_id\" = $1)\n //\n // Kolon adları ilişkinin KENDİSİNDEN geliyor (`buildRelations`), yazardan\n // değil: hangi kolonun hangi kolona baktığını bildirimden başkası bilemez,\n // ve onu elle yazdırmak \"iki yorumcu\" demekti.\n //\n // İç filtre AYNI derleyiciden geçiyor — `has` ikinci bir filtre dili DEĞİL,\n // aynı dilin bir tablo ötesi. İç sorgu KENDİ takma adını alıyor; paylaşsalardı\n // korelasyon sessizce `x = x`'e çökerdi (policy tarafında ölçülmüş hata).\n if (col === \"has\") {\n const rels = currentRelations.get(table) ?? [];\n for (const [relName, inner] of Object.entries(cond as Record<string, unknown>)) {\n const rel = rels.find((r) => r.name === relName);\n if (rel === undefined) {\n const known = rels.map((r) => r.name).sort();\n throw new Error(\n `${caller}(${table}): has.${relName} diye bir ilişki yok` +\n (known.length > 0\n ? ` (bilinenler: ${known.join(\", \")}). İlişkiler yabancı anahtarlardan TÜRETİLİR; ` +\n `adını değiştirmek için references(..., { as, reverseAs }).`\n : `. Bu tablo HİÇ yabancı anahtar bildirmiyor, ve ilişkiler onlardan TÜRETİLİR. ` +\n `Var olan bir veritabanından introspect edilmiş şemalarda bu sık olur: kolon ` +\n `\\`text()\\`/\\`uuid()\\` olarak durur, \\`references(() => <tablo>.<kolon>)\\` yoktur. ` +\n `Bildirdiğiniz anda ilişki iki tarafta da adlandırılır — ama bu CANLI veritabanına ` +\n `giden bir kısıttır ve mevcut yetim satırlar onu düşürür; önce onları sayın.`),\n );\n }\n // `many`: FK karşı tabloda, bizim tarafımız kendi PK'mız.\n // `one`: FK bizde, karşı taraf onların PK'sı.\n const [ourCol, theirCol] = relationColumns(table, rel);\n if (ourCol === null || theirCol === null) {\n const missing = ourCol === null ? table : rel.to;\n throw new Error(\n `${caller}(${table}): has.${relName} kurulamıyor — \"${missing}\" tablosunun tek kolonlu bir ` +\n `primary key'i yok. Korelasyon bir anahtar ister; çok kolonlu anahtarda ilişki üzerinden ` +\n `süzmek yerine sqlFragment ile yazın.`,\n );\n }\n const sub = `r${depth + 1}`;\n const innerSql = compileWhereBare(\n rel.to,\n schemaColumns(rel.to),\n (inner ?? {}) as Record<string, unknown>,\n add,\n caller,\n sub,\n depth + 1,\n );\n parts.push(\n `${alias}.${quoteIdent(ourCol)} IN (SELECT ${sub}.${quoteIdent(theirCol)} ` +\n `FROM ${quoteTable(rel.to)} ${sub}${innerSql === \"\" ? \"\" : ` WHERE ${innerSql}`})`,\n );\n }\n continue;\n }\n if (col === \"NOT\") {\n parts.push(\n `NOT (${compileWhereBare(table, colSet, cond as Record<string, unknown>, add, caller, alias, depth)})`,\n );\n continue;\n }\n // A null colSet means \"no schema to check against\" — the case `findMany`\n // reaches when a table is addressed by name alone. Identifiers still go\n // through quoteIdent, so an unknown name is a Postgres error, never syntax.\n if (colSet !== null && !colSet.has(col)) {\n throw new Error(`${caller}(${table}): where kolonu \"${col}\" tabloda yok (FR-016)`);\n }\n const q = `${alias}.${quoteIdent(col)}`;\n const bind = bindFor(col);\n // Çıplak `col()` bir DEĞER'dir: `{ title: col(\"owner\") }` → eşitlik. Bu\n // kontrol operatör dalından ÖNCE gelmeli, yoksa `{ $col: … }` bir operatör\n // haritası sanılırdı.\n if (isColRef(cond)) {\n parts.push(`${q} = ${colRefSql(table, colSet, cond, caller, alias)}`);\n continue;\n }\n // Çıplak `now()` — `{ expires_at: now() }` eşitlik. `col()` ile aynı yerde,\n // aynı nedenle: operatör dalından ÖNCE, yoksa tutamak bir operatör haritası\n // sanılırdı (tutamak bir Proxy'dir ve bilinmeyen prop'ta undefined döner).\n if (isNowExpr(cond)) {\n parts.push(`${q} = now()`);\n continue;\n }\n if (cond !== null && typeof cond === \"object\" && !Array.isArray(cond)) {\n for (const [op, v] of Object.entries(cond as Record<string, unknown>)) {\n // K1 metin operatörleri (FR-005). Desen BOUND PARAMETRE olarak gider;\n // `%` derleyicide eklenir ve kullanıcı verisindeki `%`/`_` KAÇIRILIR —\n // aksi hâlde bir arama kutusuna yazılan \"%\" tüm tabloyu döndürürdü.\n if (op === \"contains\" || op === \"icontains\" || op === \"startsWith\" || op === \"endsWith\") {\n if (typeof v !== \"string\") {\n throw new Error(`${caller}(${table}): where.${col}.${op} bir string olmalı`);\n }\n const lit = v.replace(/([\\\\%_])/g, \"\\\\$1\");\n const pattern =\n op === \"startsWith\" ? `${lit}%` : op === \"endsWith\" ? `%${lit}` : `%${lit}%`;\n parts.push(`${q} ${op === \"icontains\" ? \"ILIKE\" : \"LIKE\"} ${bind(pattern)}`);\n continue;\n }\n // NULL testi (FR-006): `= NULL` SQL'de her zaman UNKNOWN'dır, bu yüzden\n // niyet ayrı bir operatörle yazılır ve parametre ALMAZ.\n if (op === \"isNull\") {\n if (typeof v !== \"boolean\") {\n throw new Error(`${caller}(${table}): where.${col}.isNull bir boolean olmalı`);\n }\n parts.push(`${q} IS ${v ? \"NULL\" : \"NOT NULL\"}`);\n continue;\n }\n if (op === \"in\") {\n if (!Array.isArray(v)) throw new Error(`${caller}(${table}): where.${col}.in bir dizi olmalı`);\n // `in` listesinin ELEMANLARI değerdir. Bir `col()` buraya düşerse\n // parametre olarak bağlanır ve karşılaştırma sessizce yanlış olur —\n // `eq` aynı reddi adıyla veriyor, `in` sessiz kalıyordu (T010/I1).\n if (v.some(isColRef)) {\n throw new Error(`${caller}(${table}): where.${col}.in col() ile kullanılamaz — kolon karşılaştırması için çıplak biçimi ({ ${col}: col(\"…\") }) ya da gt/gte/lt/lte/neq kullanın`);\n }\n if (v.length === 0) {\n // Boş in-listesi \"hiçbir satır\" demektir — sessiz tam-tarama yerine\n // anlamı SQL'e açıkça yaz (review I5).\n parts.push(\"false\");\n continue;\n }\n // Placeholder genişletmesi: her eleman AYRI parametre. `= ANY($n)`\n // dizi bind'i sürücüde Postgres array literal'ine çevrilmiyor ve\n // canlıda `malformed array literal: \"ops,general\"` 500'ü veriyordu\n // (verify 19-3b, 2026-08-28). IN listesi tip-agnostik ve sürücüden\n // bağımsız; boş liste yukarıda açık `false`.\n parts.push(`${q} IN (${v.map((x) => bind(x)).join(\", \")})`);\n } else if (isNowExpr(v)) {\n // Sağ taraf SUNUCU SAATİ: parametre YOK, saat veritabanında okunuyor.\n // JS'ten `new Date()` göndermek istemci saatine geçmek olurdu.\n if (!(op in WHERE_OPS)) {\n throw new Error(`${caller}(${table}): where.${col}.${op} now() ile kullanılamaz — eşitlik için çıplak biçimi kullanın: { ${col}: now() }`);\n }\n parts.push(`${q} ${WHERE_OPS[op]} now()`);\n } else if (isColumnExpr(v)) {\n // `increment()`/`decrement()` bir YAZMA ifadesi. `now()` yukarıda\n // ayrı dal; buraya düşen her şey filtrede anlamsız ve ADIYLA\n // reddediliyor, çünkü sessizce bağlanırsa karşılaştırma `[object\n // Object]` ile yapılır ve hiçbir satır dönmez — hatasız.\n throw new Error(\n `${caller}(${table}): where.${col}.${op} bir YAZMA ifadesi aldı (increment/decrement) — ` +\n `karşılaştırma değeri değil. Sunucu saati için now() kullanın; sayısal bir eşik için değeri yazın.`,\n );\n } else if (isColRef(v)) {\n // Sağ taraf kolon (FR-011): parametre YOK. `in` yukarıda ayrı dal,\n // metin operatörleri desen ister — ikisi de buraya düşmez.\n if (!(op in WHERE_OPS)) {\n throw new Error(`${caller}(${table}): where.${col}.${op} col() ile kullanılamaz — eşitlik için çıplak biçimi kullanın: { ${col}: col(\"…\") }`);\n }\n parts.push(`${q} ${WHERE_OPS[op]} ${colRefSql(table, colSet, v, caller, alias)}`);\n } else if (looksLikeUnbrandedRef(v) !== null) {\n // MARKASIZ TAKLİT. Üst düzeyde \"bilinmeyen operatör\" diye\n // reddediliyor; burada sessizce PARAMETRE olarak bağlanıyordu ve\n // jsonb/text kolonunda sonuç HİÇBİR SATIR oluyordu, hatasız.\n const kind = looksLikeUnbrandedRef(v);\n const made = kind === \"col\" ? \"col()\" : kind === \"sql\" ? \"sqlFragment\" : \"now()\";\n const how = kind === \"col\" ? 'col(\"kolon_adı\")' : kind === \"sql\" ? \"sqlFragment`…`\" : \"now()\";\n throw new Error(\n `${caller}(${table}): where.${col}.${op} bir ${made} TAKLİDİ aldı — ` +\n `bu nesne bu süreçte ${made} ile üretilmemiş. ` +\n `İstek gövdesinden gelen bir filtre işaretçi TAŞIYAMAZ; koşulu kendi kodunuzda ` +\n `${how} ile kurun.`,\n );\n } else if (op in WHERE_OPS) {\n // NULL'a eşitlik SQL'de hiçbir zaman doğru değildir — `= NULL` ve\n // `<> NULL` ikisi de UNKNOWN, yani hiçbir satır. Yazarın YAZDIĞI bir\n // null'ı sessizce boş sonuca çevirmek, undefined'ın az önce kapatılan\n // hatasının aynısı. Soru IS NULL / IS NOT NULL ile sorulur.\n if (v === null && op === \"neq\") {\n parts.push(`${q} IS NOT NULL`);\n continue;\n }\n parts.push(`${q} ${WHERE_OPS[op]} ${bind(v)}`);\n } else {\n throw new Error(`${caller}(${table}): where.${col} bilinmeyen operatör \"${op}\" (gt/gte/lt/lte/neq/in)`);\n }\n }\n } else if (cond === null) {\n // Aynı gerekçe, kısa yazılış: `{ deleted_at: null }` — \"silinmemiş\n // satırlar\" demenin en doğal yolu — `= $1` derlenip hiçbir satır\n // döndürüyordu.\n parts.push(`${q} IS NULL`);\n } else {\n parts.push(`${q} = ${bind(cond)}`);\n }\n }\n return parts.join(\" AND \");\n}\n\n/** {@link compileWhereBare}, çağıranların beklediği ` AND …` önekiyle. */\nfunction compileWhere(\n table: string,\n colSet: Set<string> | null,\n where: Record<string, unknown>,\n add: (v: unknown) => string,\n caller = \"search\",\n): string {\n const bare = compileWhereBare(table, colSet, where, add, caller);\n return bare === \"\" ? \"\" : ` AND ${bare}`;\n}\n\n/** The `ON CONFLICT …` tail shared by `upsert` and `insertMany`.\n *\n * ONE writer, deliberately: two hand-written ON CONFLICT clauses is how the\n * single-row and the many-row spellings come to disagree about what a collision\n * does — and a disagreement there is silent, because both statements succeed.\n *\n * `DO UPDATE` sets every column that is NOT part of the conflict key; those are\n * what matched, so assigning them to themselves is the no-op Postgres needs when\n * there is nothing else to set. */\nfunction onConflictTail(\n cols: string[],\n conflict: readonly string[],\n action: \"ignore\" | \"update\",\n): string {\n const target = `ON CONFLICT (${conflict.map(quoteIdent).join(\", \")})`;\n if (action === \"ignore\") return `${target} DO NOTHING`;\n const conflictSet = new Set(conflict);\n const sets = cols\n .filter((c) => !conflictSet.has(c))\n .map((c) => `${quoteIdent(c)} = EXCLUDED.${quoteIdent(c)}`);\n return sets.length\n ? `${target} DO UPDATE SET ${sets.join(\", \")}`\n : `${target} DO UPDATE SET ${quoteIdent(conflict[0]!)} = EXCLUDED.${quoteIdent(conflict[0]!)}`;\n}\n\n/** vector extension'ının yaşadığı şema (C-10): canlı stack'te public, taze\n * stack'te extensions — operatör bununla nitelenir, search_path'e GÜVENİLMEZ\n * (M-1 ölçümü; veri düzlemi search_path=public kurar, handler.go:101). */\nlet cachedVectorSchema: string | null = null;\n\n/** pg_trgm'in kurulu olduğu şema — typo-fallback operatörü bununla nitelenir\n * (search_path'e GÜVENİLMEZ, M-1 ile aynı gerekçe). Bağlanma başına bir kez. */\nlet cachedTrgmSchema: string | null = null;\nasync function trgmSchemaOf(live: { unsafe: (sql: string, params?: unknown[]) => Promise<unknown> }): Promise<string> {\n if (cachedTrgmSchema !== null) return cachedTrgmSchema;\n const rows = (await live.unsafe(\n \"select n.nspname from pg_extension e join pg_namespace n on n.oid = e.extnamespace where e.extname = 'pg_trgm'\",\n )) as { nspname?: string }[];\n cachedTrgmSchema = rows?.[0]?.nspname ?? \"public\";\n return cachedTrgmSchema;\n}\n/** GUC + (soğukken) extension-şema çözümü TEK statement'ta (review I4). */\nasync function vectorSchemaWithGuc(runner: { unsafe(sql: string, params?: unknown[]): Promise<unknown> }): Promise<string> {\n if (cachedVectorSchema !== null) {\n // NFR-005 kapanışı, ÖLÇÜMLE (40K×384, %1 filtre, exact referans):\n // relaxed (vars. 20K tavan) → recall@20 0.62\n // relaxed + max_scan_tuples=200K → 0.64 (tavan tek başına YETMEZ:\n // iterative scan LIMIT dolunca durur, bulduğu ilk N \"en yakın N\" değil)\n // relaxed + 200K + ef_search=200 → 0.95 (asıl düğme aday genişliği)\n // ef_search=200 normal sorguya ms-mertebesi maliyet ekler; karşılığı\n // seçici filtrede doğru sonuç. strict_order ölçümde ek kazanç vermedi.\n await runner.unsafe(\n \"select set_config('hnsw.iterative_scan','relaxed_order',true), set_config('hnsw.max_scan_tuples','200000',true), set_config('hnsw.ef_search','200',true)\",\n );\n return cachedVectorSchema;\n }\n const rows = (await runner.unsafe(\n \"select set_config('hnsw.iterative_scan','relaxed_order',true), set_config('hnsw.max_scan_tuples','200000',true), set_config('hnsw.ef_search','200',true), \" +\n \"(select n.nspname from pg_extension e join pg_namespace n on n.oid = e.extnamespace where e.extname = 'vector') as nspname\",\n )) as { nspname?: string }[];\n const name = rows?.[0]?.nspname;\n if (typeof name !== \"string\" || name === \"\") {\n throw new Error(\"pgvector extension kurulu değil — vector araması çalışamaz (extensions beyanı deploy'dan geçti mi?)\");\n }\n cachedVectorSchema = name;\n return name;\n}\n\n/** Test edilebilirlik: setSchema gibi, cache'i sıfırlar. */\nexport function resetVectorSchemaCache(): void {\n cachedVectorSchema = null;\n}\n\n// ---------------------------------------------------------------------------\n// Sorgu-anı embed (T024, FR-025) — CLAIM-N1: POST /v1/embeddings.\n// ---------------------------------------------------------------------------\n\ntype SecretReader = (name: string) => Promise<string | null>;\nlet secretReader: SecretReader | null = null;\n/** Runtime boot'ta bağlanır (setSchema ile AYNI kanal deseni): vault'tan\n * secret okuma. Engine anahtarın yalnız ADINI bilir, değeri buradan akar. */\nexport function setSecretReader(fn: SecretReader | null): void {\n secretReader = fn;\n}\n\ntype EmbedFetch = (url: string, init?: RequestInit) => Promise<Response>;\nlet embedFetch: EmbedFetch = (url, init) => fetch(url, init);\n/** Test dikişi: sağlayıcı çağrısının fetch'i. Üretimde global fetch. */\nexport function setEmbedFetch(fn: EmbedFetch | null): void {\n embedFetch = fn ?? ((url, init) => fetch(url, init));\n}\n\n/** Sorgu metnini beyan edilen modelle vektörler (CLAIM-N1). Tek deneme, 10s\n * timeout — retry worker'ın işidir, sorgu yolunun değil. Hata apiKeyName'i\n * ADLANDIRIR; anahtar yoksa sağlayıcı hiç aranmaz. */\nasync function embedQuery(\n embed: NonNullable<SearchLeg[\"embed\"]>,\n text: string,\n): Promise<number[]> {\n if (secretReader === null) {\n throw new Error(`query embed: secret reader bağlanmamış — ${embed.apiKeyName} okunamıyor`);\n }\n const key = await secretReader(embed.apiKeyName);\n if (key === null || key === \"\") {\n throw new Error(`query embed: vault'ta ${embed.apiKeyName} yok (FR-021/FR-025)`);\n }\n const url = (embed.baseURL ?? \"https://api.openai.com/v1\").replace(/\\/$/, \"\") + \"/embeddings\";\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), 10_000);\n try {\n const res = await embedFetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", Authorization: `Bearer ${key}` },\n body: JSON.stringify({\n model: embed.model,\n input: [text],\n ...(embed.dimensions !== undefined ? { dimensions: embed.dimensions } : {}),\n }),\n signal: controller.signal,\n });\n if (!res.ok) {\n throw new Error(`query embed: sağlayıcı ${res.status} döndü (${embed.apiKeyName} ile) — anahtar/model doğru mu?`);\n }\n const data = (await res.json()) as { data?: { embedding?: number[] }[] };\n const vec = data.data?.[0]?.embedding;\n if (!Array.isArray(vec)) {\n throw new Error(\"query embed: sağlayıcı yanıtında data[0].embedding yok (CLAIM-N1 şekli)\");\n }\n return vec;\n } finally {\n clearTimeout(timer);\n }\n}\n\n/** The six string-keyed operations, plus an interactive `transaction`. */\n/**\n * SET atamalarını kuran TEK yer — `update` ve `updateMany` aynı dili konuşsun diye.\n *\n * Ayrı olduklarında `update(id, …)` düz `SET col = $n` kuruyordu: yani\n * `updated_at: now()` ve `hits: increment(1)` `updateMany`'de çalışıp `update`'te\n * çalışmıyordu — hem de EN ÇOK kullanılan yazma yolunda. Çağıranın göreceği bir\n * gerekçesi yoktu; \"aynı çağrı, tek düzlem\" (P1) tam olarak bunu yasaklıyor.\n */\nfunction buildSetAssignments(\n table: string,\n cols: readonly string[],\n set: Record<string, unknown>,\n add: (v: unknown) => string,\n caller: string,\n): string {\n return cols\n .map((c) => {\n // increment()/decrement() (FR-012, N-4): `SET col = col ± $n` TEK\n // statement'tır ve READ COMMITTED'te lost update üretmez — çakışan\n // ikinci UPDATE satırın GÜNCELLENMİŞ hâliyle devam eder. Oku-hesapla-yaz\n // yoluna düşmek o garantiyi yok ederdi, bu yüzden ifade burada,\n // sorgunun İÇİNDE derlenir; değeri okumak için ekstra tur YOK.\n const expr = columnExprOf(set[c]);\n // `now()` PLAN yolunda `SET col = now()` diye derleniyordu, doğrudan\n // yolda ise bind'e düşüp Proxy'yi sürücüye veriyordu. Aynı çağrı, iki\n // düzlem — P1'in kapattığı şeyin ta kendisi.\n if (expr !== null && expr.fn === \"now\") {\n return `${quoteIdent(c)} = now()`;\n }\n if (expr !== null) {\n const operator = expr.fn === \"inc\" ? \"+\" : \"-\";\n // MİKTAR da kolonun `toDb`'sinden geçer. Geçmeseydi, `.transform()`\n // bildiren bir kolonda `increment(5)` ham JS değeriyle bind edilir\n // ve toplama ya patlar ya da sessizce farklı bir sayıya çözülürdü —\n // dönüşümün yarısı bağlı, yarısı değil.\n const t = transformsOf(currentSchema, table).get(c);\n const amount = t?.toDb === undefined || expr.by === null || expr.by === undefined\n ? expr.by\n : t.toDb(expr.by);\n // Kolon tanımlayıcı, miktar BOUND — kiracının rakamları SQL metnine\n // hiç girmez (renderValue'daki tx yolunun aynı kuralı).\n return `${quoteIdent(c)} = ${quoteIdent(c)} ${operator} ${add(amount)}`;\n }\n return `${quoteIdent(c)} = ${add(asBindParams(table, [c], set, caller)[0])}`; })\n .join(\", \");\n}\n\n/**\n * `INSERT … VALUES` tuple'ı — ifade farkındalı, `buildSetAssignments`'ın ikizi.\n *\n * Beş kurucu (`insert`, `insertMany`, `put`, `claim`, `supersede`) düz\n * `$1..$n` üretiyordu, yani `now()` ekleme yolunda İFADE EDİLEMEZDİ. Verilen\n * gerekçe \"kolonun `defaultNow()`'ı daha iyi cevap\"tı ve GERÇEK bir şemada\n * ölçünce yanlış çıktı: introspect edilmiş bir şemada zaman kolonlarının çoğu\n * `timestamp()` — varsayılansız. O projede 12 yerde İSTEMCİ saati yazılıyordu,\n * ve aynı sütunu okuyan sorgular Postgres'in saatini kullanıyordu.\n *\n * `increment()`/`decrement()` burada ADIYLA reddediliyor: satır henüz yokken\n * \"kolonun şu anki değeri\" diye bir şey yok.\n */\nfunction buildValueTuple(\n table: string,\n cols: readonly string[],\n data: Record<string, unknown>,\n add: (v: unknown) => string,\n caller: string,\n): string {\n return cols\n .map((c) => {\n const expr = columnExprOf(data[c]);\n if (expr !== null && expr.fn === \"now\") return \"now()\";\n if (expr !== null) {\n throw new Error(\n `${caller}(${table}): \"${c}\" ${expr.fn === \"inc\" ? \"increment()\" : \"decrement()\"} aldı — ` +\n `satır HENÜZ YOK, yani \"kolonun şu anki değeri\" diye bir şey yok. Başlangıç ` +\n `değerini yazın; artırmak için satır oluştuktan sonra ` +\n `updateMany({ where, set: { ${c}: ${expr.fn === \"inc\" ? \"increment\" : \"decrement\"}(n) } }).`,\n );\n }\n return add(asBindParams(table, [c], data, caller)[0]);\n })\n .join(\", \");\n}\n\n/** Bir kolonun BİLDİRİLMİŞ Postgres tipi — `vectorColumnsOf` ile aynı okuma. */\nfunction computeColumnType(table: string, col: string): string | null {\n const def = tableDefOf(table);\n const c = def?.columns?.[col];\n if (c === undefined || c === null) return null;\n const d = (typeof c === \"object\" && \"_def\" in c ? (c as { _def: unknown })._def : c) as\n | { type?: unknown }\n | null;\n return d !== null && typeof d === \"object\" && typeof d.type === \"string\" ? d.type : null;\n}\n\nconst NUMERIC_PG_TYPES = new Set([\"integer\", \"bigint\", \"numeric\"]);\n\n/**\n * Toplama sonucunun SQL ifadesi.\n *\n * `::text` PARA GÜVENLİĞİDİR, süs değil. `sum()`/`avg()` HESAPLANMIŞ bir kolon\n * üretir; tablo kolonu olmadığı için şemanın `fromDb` dönüşümü ona uygulanmaz\n * ve sürücü onu JS `number`'ına çevirebilir. Bu tam olarak D-007'nin kapattığı\n * hata: 41.00821234567890123 canlıda 41.0082123456789 olarak dönüyordu.\n * `sum(numeric)` Postgres'te `numeric`, `sum(integer)` `bigint` — ikisi de bu\n * SDK'da `string`, ve öyle KALMALI.\n */\nfunction aggregateExpr(table: string, fn: \"sum\" | \"avg\" | \"min\" | \"max\", col: string, alias: string): string {\n const q = `t.${quoteIdent(col)}`;\n const t = columnTypeOf(table, col);\n // sum/avg her zaman metin: sonuç tipi numeric ya da bigint, ikisi de kesin\n // ve ikisi de JS number'da kayıplı.\n if (fn === \"sum\" || fn === \"avg\") return `${fn}(${q})::text AS ${quoteIdent(alias)}`;\n if (t === \"timestamp\") return `${timestampResult(`${fn}(${q})`)} AS ${quoteIdent(alias)}`;\n // min/max kolonun KENDİ tipini döndürür — yalnız sayısal olanlar metne\n // çevrilir; `timestamp`/`text` zaten string, `integer` JS number olarak\n // güvenli (tam sayı, 2^31).\n return t !== null && NUMERIC_PG_TYPES.has(t) && t !== \"integer\"\n ? `${fn}(${q})::text AS ${quoteIdent(alias)}`\n : `${fn}(${q}) AS ${quoteIdent(alias)}`;\n}\n\n/**\n * İLİŞKİLİ SATIRLARI GETİRME (`with`) — tek sorguda, LATERAL ile.\n *\n * `has` ilişki üzerinden SÜZÜYORDU ama GETİRMİYORDU: \"şu kullanıcıları ve\n * gönderilerini ver\" ya iki sorgu ya `$query` demekti — yani bu koşunun\n * kaldırmak için var olduğu N+1 sınıfının ta kendisi.\n *\n * PARA GÜVENLİĞİ BURADA KRİTİK, ve ölçülmüş bir rakip hatasından öğrenildi:\n * Drizzle'ın ilişkisel sorgusu satırları `json_build_array` ile taşıyor ve\n * kolonları metne DÖKMÜYOR; `numeric` JSON sayısına dönüşüp kesinliğini\n * kaybediyor — tip `string` derken runtime yuvarlanmış sayı veriyor\n * (ölçüldü: 100000000000000000000000000 → 100000000000000004764729344).\n * Burada her `numeric`/`bigint` kolonu `::text` ile dökülüyor, tıpkı Go\n * proxy'sinin düz satırlarda yaptığı gibi.\n */\nfunction jsonObjectFor(table: string, cols: readonly string[], alias: string, extra: string[] = []): string {\n const pairs = cols.map((c) => {\n const t = columnTypeOf(table, c);\n // `integer` JS number'da tam sayı olarak güvenli; `numeric`/`bigint` değil.\n const expr =\n t !== null && (t === \"numeric\" || t === \"bigint\")\n ? `${alias}.${quoteIdent(c)}::text`\n : t === \"timestamp\" ? timestampResult(`${alias}.${quoteIdent(c)}`) : `${alias}.${quoteIdent(c)}`;\n return `${quoteLiteral(c)}, ${expr}`;\n });\n return `json_build_object(${[...pairs, ...extra].join(\", \")})`;\n}\n\n/** A foreign key can reference any declared unique column, including on a\n * table whose primary key is composite. Read its actual referenced column. */\nfunction relationColumns(table: string, relation: Relation): [string | null, string | null] {\n const child = relation.kind === \"many\" ? relation.to : table;\n const value = tableDefOf(child)?.columns?.[relation.via];\n const column = (value && typeof value === \"object\" && \"_def\" in value ? value._def : value) as\n { references?: { column?: string } } | undefined;\n const target = column?.references?.column ?? primaryKeyOf(relation.kind === \"many\" ? table : relation.to);\n return relation.kind === \"many\" ? [target, relation.via] : [relation.via, target];\n}\n\n/** `with` dalları — her biri bir LATERAL ya da skaler alt sorgu. */\nfunction withClauses(\n table: string,\n spec: Record<string, unknown>,\n add: (v: unknown) => string,\n caller: string,\n parentAlias = \"t\", depth = 0, counter = { value: 0 },\n): { select: string[]; joins: string[]; jsonPairs: string[] } {\n if (depth >= 3 && Object.values(spec).some(Boolean)) throw new Error(`${caller}(${table}): with supports at most three relation levels`);\n const rels = currentRelations.get(table) ?? [];\n const select: string[] = [];\n const joins: string[] = [];\n const jsonPairs: string[] = [];\n for (const [name, opt] of Object.entries(spec)) {\n if (opt === false || opt === undefined) continue;\n const rel = rels.find((r) => r.name === name);\n if (rel === undefined) {\n const known = rels.map((r) => r.name).sort();\n throw new Error(\n `${caller}(${table}): with.${name} diye bir ilişki yok` +\n (known.length > 0\n ? ` (bilinenler: ${known.join(\", \")})`\n : `. Bu tablo hiç yabancı anahtar bildirmiyor ve ilişkiler onlardan TÜRETİLİR`) +\n `. İlişkiler references(() => <tablo>.<kolon>) ile bildirilir.`,\n );\n }\n const [ourCol, theirCol] = relationColumns(table, rel);\n if (ourCol === null || theirCol === null) {\n throw new Error(\n `${caller}(${table}): with.${name} birincil anahtar bilmeden kurulamaz — ` +\n `ilişkinin bir ucu tablonun PK'sı ve bu tablo tek kolonlu bir PK bildirmiyor.`,\n );\n }\n const o = typeof opt === \"object\" && opt !== null ? (opt as Record<string, unknown>) : {};\n const i = ++counter.value;\n const childAlias = `w${i}`;\n const childKnown = schemaColumns(rel.to);\n if (o['select'] !== undefined && (!Array.isArray(o['select']) || o['select'].length === 0)) {\n throw new Error(`${caller}(${table}): with.${name}.select must be a non-empty array of columns`);\n }\n const childCols =\n Array.isArray(o[\"select\"]) && o[\"select\"].length > 0\n ? (o[\"select\"] as string[])\n : childKnown !== null\n ? [...childKnown]\n : [];\n if (childCols.length === 0) {\n throw new Error(\n `${caller}(${table}): with.${name} için \"${rel.to}\" tablosunun kolonları bilinmiyor — ` +\n `select ile hangi kolonları istediğinizi yazın.`,\n );\n }\n for (const c of childCols) {\n if (childKnown !== null && !childKnown.has(c)) {\n throw new Error(`${caller}(${table}): with.${name}.select kolonu \"${c}\" \"${rel.to}\" tablosunda yok`);\n }\n }\n const nestedSpec = o[\"with\"];\n if (nestedSpec !== undefined && (nestedSpec === null || typeof nestedSpec !== \"object\" || Array.isArray(nestedSpec))) {\n throw new Error(`${caller}(${table}): with.${name}.with must be a relation object`);\n }\n const nested = nestedSpec === undefined ? { joins: [], jsonPairs: [] } :\n withClauses(rel.to, nestedSpec as Record<string, unknown>, add, caller, childAlias, depth + 1, counter);\n const nestedJoins = nested.joins.length ? ` ${nested.joins.join(\" \")}` : \"\";\n const obj = jsonObjectFor(rel.to, childCols, childAlias, [...nested.jsonPairs, ...canJsonPairs(rel.to, childAlias)]);\n const innerWhere =\n o[\"where\"] !== undefined && o[\"where\"] !== null\n ? compileWhereBare(rel.to, childKnown, o[\"where\"] as Record<string, unknown>, add, caller, childAlias, i)\n : \"\";\n const link = `${childAlias}.${quoteIdent(theirCol)} = ${parentAlias}.${quoteIdent(ourCol)}`;\n const cond = innerWhere === \"\" ? link : `${link} AND ${innerWhere}`;\n const requestedLimit = o[\"limit\"] as number | undefined;\n // Validate the supplied value even for a to-one relation, then clamp its\n // cardinality. A second LIMIT after the requested one is invalid SQL.\n limitClause(requestedLimit);\n const relationLimit = rel.kind === \"many\" ? requestedLimit : Math.min(1, requestedLimit ?? 1);\n const inner = orderClauseFor(rel.to, childKnown, o[\"orderBy\"], childAlias) + limitClause(relationLimit);\n const outAlias = `wj${i}`;\n if (rel.kind === \"many\") {\n // Boş küme `[]` — `null` DEĞİL. Çağıran `rows.posts.map(...)` yazabilsin\n // diye; `null` her erişimde bir guard isterdi.\n joins.push(\n `LEFT JOIN LATERAL (SELECT coalesce(json_agg(x.o), '[]'::json) AS d FROM ` +\n `(SELECT ${obj} AS o FROM ${quoteTable(rel.to)} ${childAlias}${nestedJoins} WHERE ${cond}${inner}) x) ` +\n `${quoteIdent(outAlias)} ON true`,\n );\n } else {\n // `one`: tek satır ya da `null` — dizi değil, çünkü ilişki tekil.\n joins.push(\n `LEFT JOIN LATERAL (SELECT ${obj} AS d FROM ${quoteTable(rel.to)} ${childAlias}${nestedJoins} ` +\n `WHERE ${cond}${inner}) ${quoteIdent(outAlias)} ON true`,\n );\n }\n select.push(`${quoteIdent(outAlias)}.\"d\" AS ${quoteIdent(name)}`);\n jsonPairs.push(`${quoteLiteral(name)}, ${quoteIdent(outAlias)}.\"d\"`);\n }\n return { select, joins, jsonPairs };\n}\n\nfunction compileFindMany(table: string, query: Row = {}, opts: FindManyOptions = {}): { sql: string; params: unknown[] } {\n const params: unknown[] = [];\n const add = (v: unknown): string => {\n params.push(v);\n return `$${params.length}`;\n };\n // The SAME compiler `search` uses. Two builders for one filter language is\n // how the two spellings drift; the operator set (gt/gte/lt/lte/neq/in) was\n // already written and already tested, it was just never reachable from here.\n const known = schemaColumns(table);\n const whereSql = compileWhere(table, known, query, add, \"findMany\");\n const order = orderClause(table, known, opts.orderBy);\n const limit = limitClause(opts.limit);\n const offset = offsetClause(opts.offset, opts.limit);\n const cols = selectClause(table, known, opts.select);\n // `with` — ilişkili satırlar, TEK sorguda. Boşsa üretilen SQL bayt-aynı\n // kalıyor: var olan her çağrının planı değişmesin.\n const w =\n opts.with !== undefined && Object.keys(opts.with).length > 0\n ? withClauses(table, opts.with, add, \"findMany\")\n : { select: [], joins: [] };\n const selectList = w.select.length > 0 ? `${cols === \"*\" ? \"t.*\" : cols}, ${w.select.join(\", \")}` : cols;\n const joinSql = w.joins.length > 0 ? ` ${w.joins.join(\" \")}` : \"\";\n const sql =\n `SELECT ${selectList} FROM ${quoteTable(table)} t${joinSql} WHERE true${whereSql}${order}${limit}${offset}`;\n return { sql, params };\n}\n\ninterface OpsContext { readonly cursorScope?: string; readonly commands?: boolean; readonly trace?: DatabaseTrace }\nconst uniqueKeysCache: SchemaMetadataCache<string[][]> = new WeakMap();\nconst pageSchemaCache: SchemaMetadataCache<{ columns: Record<string, PageColumn>; primaryKey: string[]; stamp: string }> = new WeakMap();\n\nfunction pageSchema(table: string) {\n return memoTable(pageSchemaCache, currentSchema, table, () => {\n const def = tableDefOf(table) as { columns?: Record<string, unknown>; primaryKey?: string[] } | null;\n if (!def?.columns) throw new Error(`page(${table}) requires an installed table declaration`);\n const columns: Record<string, PageColumn> = Object.create(null);\n const inlineKeys: string[] = [];\n for (const [name, column] of Object.entries(def.columns)) {\n const c = column as { _def?: PageColumn & { primaryKey?: boolean } } & PageColumn & { primaryKey?: boolean };\n const d = c._def ?? c;\n columns[name] = { type: d.type, nullable: d.nullable };\n if (d.primaryKey) inlineKeys.push(name);\n }\n const primaryKey = def.primaryKey ?? inlineKeys;\n for (const name of primaryKey) if (columns[name]) columns[name]!.nullable = false;\n return { columns, primaryKey, stamp: fingerprint({ columns, primaryKey }) };\n });\n}\n\nexport function createOps(tx: TxLike | (() => TxLike | Promise<TxLike>), context: OpsContext = {}) {\n const at = () => {\n const target = typeof tx === \"function\" ? tx() : tx;\n return target instanceof Promise ? target.then(resolveTx) : resolveTx(target);\n };\n\n const ops = {\n diagnostics() { return context.trace?.snapshot ?? null; },\n // Generic dönüş, çağıranın İDDİASIDIR (FR-021). Motor her zaman satır objeleri\n // üretir; `T` onlara bir ad vermekten ibarettir ve verilmezse `unknown` kalır —\n // yani \"bilmiyorum\", ki ham SQL için doğru cevap odur.\n async query<T = unknown>(sql: string, params: unknown[] = []): Promise<T[]> {\n // Arrays become Postgres array literals; everything else is bound as-is.\n // See encodePgArray for what the driver does without this.\n const bound = params.map((p) => (Array.isArray(p) ? encodePgArray(p) : p));\n return asWireRows((await (await at()).unsafe(sql, bound)) as Row[]) as T[];\n },\n\n async insert(table: string, data: Row): Promise<Row> {\n const cols = Object.keys(data);\n if (cols.length === 0) throw new Error(`insert into ${table}: no columns given`);\n const params: unknown[] = [];\n const add = (v: unknown): string => `$${params.push(v)}`;\n const tuple = buildValueTuple(table, cols, data, add, \"insert\");\n const sql =\n `INSERT INTO ${quoteTable(table)} (${cols.map(quoteIdent).join(\", \")}) ` +\n `VALUES (${tuple}) RETURNING ${rowProjection(table)}`;\n const rows = (await (await at()).unsafe(sql, params)) as Row[];\n const inserted = rows[0];\n if (!inserted) {\n // RETURNING * with no row back means the write was filtered away — an\n // RLS WITH CHECK that rejected it, most often. Silence here would hand\n // the author `undefined` and a 500 three lines later.\n throw new Error(\n `insert into ${table} returned no row — the write was rejected (an RLS policy, most likely).`,\n );\n }\n return asTableRow(table, inserted);\n },\n\n /**\n * Çok satırı TEK statement'la ekle.\n *\n * Motor bunu zaten yapıyordu ve yalnız PLAN yolundan erişilebiliyordu\n * (`tx.public.x.insertMany`). Dışarıda tek kapı `insert(row)` olduğu için\n * \"şu 200 satırı yaz\" ya 200 gidiş-dönüş ya da ham SQL oluyordu — ölçüldü:\n * bir müşteri projesinde bir seed rutini satırları tek tek siliyor\n * (`deleteMany` VARKEN) ve tek tek ekliyor.\n *\n * SATIRLARIN ANAHTAR KÜMESİ AYNI OLMAK ZORUNDA. Kolon listesi tek bir\n * statement'ta paylaşıldığı için ilk satırdan türer; farklı anahtar taşıyan\n * bir satırın fazla kolonu SESSİZCE YAZILMAZDI. Eksik kolon için `null`\n * yazın ya da varsayılanı istiyorsanız o satırları ayrı çağrıda ekleyin.\n */\n insertMany: (async function(\n table: string,\n rows: readonly Row[],\n opts?: InsertManyOptions,\n ): Promise<Row[] | number> {\n validateInsertManyOptions(opts);\n if (rows.length === 0) return opts?.returning === false ? 0 : [];\n const first = rows[0]!;\n const cols = Object.keys(first);\n if (cols.length === 0) throw new Error(`insertMany into ${table}: no columns given`);\n for (let i = 1; i < rows.length; i++) {\n const keys = Object.keys(rows[i]!);\n const missing = cols.filter((c) => !(c in rows[i]!));\n const extra = keys.filter((k) => !cols.includes(k));\n if (missing.length > 0 || extra.length > 0) {\n throw new Error(\n `insertMany(${table}): ${i}. satırın kolonları ilk satırla aynı değil` +\n (missing.length > 0 ? ` (eksik: ${missing.join(\", \")})` : \"\") +\n (extra.length > 0 ? ` (fazla: ${extra.join(\", \")})` : \"\") +\n `. Tek statement kolon listesini PAYLAŞIR, yani fazla kolon sessizce ` +\n `yazılmaz ve eksik kolon yanlış sütuna kayar. Eksikler için null yazın, ` +\n `ya da farklı şekilli satırları ayrı çağrılarda ekleyin.`,\n );\n }\n }\n const params: unknown[] = [];\n const add = (v: unknown): string => `$${params.push(v)}`;\n const tuples = rows.map((r) => `(${buildValueTuple(table, cols, r, add, \"insertMany\")})`);\n // ÇAKIŞMA KURALI — plan yolunun `insertMany`'si bunu 11.0.0'dan beri\n // alıyordu ve düz yüzeye eklerken atlamıştım: \"şu 200 satırı yaz, zaten\n // olanları geç\" toplu içe aktarmanın en sıradan hâli ve onsuz tek çare\n // yine ham SQL.\n //\n // DO NOTHING + RETURNING: Postgres yalnız YAZDIĞI satırları döndürür,\n // yani çakışan satır sonuçta YOKTUR. Sözleşme bu, pürüz değil.\n const tail =\n opts?.onConflict !== undefined && opts.onConflict.length > 0\n // VARSAYILAN `\"ignore\"` — plan yolunun 11.0.0'dan beri kullandığı\n // varsayılanın AYNISI. Bir süre `\"update\"` yazmıştım: aynı seçenek\n // adı, iki düzlemde ZIT davranış, ve fark ancak veri ezildikten sonra\n // görülürdü.\n ? ` ${onConflictTail(cols, opts.onConflict, opts.action ?? \"ignore\")}`\n : \"\";\n const sql =\n `INSERT INTO ${quoteTable(table)} (${cols.map(quoteIdent).join(\", \")}) ` +\n `VALUES ${tuples.join(\", \")}${tail}${opts?.returning === false ? \"\" : ` RETURNING ${rowProjection(table)}`}`;\n const out = (await (await at()).unsafe(sql, params)) as Row[] & { count?: number };\n if (opts?.returning === false) {\n if (!Number.isSafeInteger(out.count) || out.count! < 0) throw new Error(\"insertMany returning:false requires a driver with an affected row count\");\n return out.count!;\n }\n return out.map((r) => asTableRow(table, r));\n }) as DBOps[\"insertMany\"],\n\n /**\n * Bir ADI kilitle — satırı değil (FR-054).\n *\n * \"Aynı anda tek bir fatura kapanışı koşsun\" gibi, kilitlenecek satırı\n * OLMAYAN işler için. Anahtar bir metin; Postgres 64-bit tamsayı istediği\n * için `hashtextextended` ile hash'leniyor ve metin SQL'e hiç GİRMİYOR.\n *\n * YALNIZ transaction kapsamlı aile (`pg_advisory_xact_lock`). Oturum\n * kapsamlı sürüm bırakıldığı yerde KALIR: bağlantı havuza döner, kilit\n * üstünde kalır ve bir sonraki isteği — hiç bitmeyecek şekilde — bekletir.\n * Transaction kapsamlısı commit/rollback'te Postgres tarafından bırakılır,\n * yani unutulması imkânsız.\n */\n async advisoryXactLock(key: string): Promise<void> {\n await (await at()).unsafe(\"select pg_advisory_xact_lock(hashtextextended($1, 0))\", [key]);\n },\n\n /**\n * Bu satırları KİLİTLE, ve sırayı KATMAN koysun (FR-035).\n *\n * D-017: katman sıralamayı değil, **sıralamayı mümkün kılan primitifi**\n * verir. Uygulama dokunacağı kümeyi önden bildirir; sırayı burası koyar.\n * Çağıranın verdiği sıraya güvenmek, iki çağıranın aynı iki satıra ters\n * sırayla girmesi demektir — ve deadlock'un bedeli ucuz değil:\n * `deadlock_timeout` varsayılanı **1 saniye**, yani kaybeden işlem bir\n * saniye bekledikten sonra hata alır.\n *\n * `FOR NO KEY UPDATE`, `updateMany`'nin CTE'siyle AYNI kilit modu: iki\n * yazma yolunun tek bir sırası ve tek bir modu olmak zorunda, yoksa biri\n * diğerini bekletir.\n */\n async lockRows(table: string, ids: readonly string[]): Promise<void> {\n // Sıralama VE tekilleştirme burada: aynı id'yi iki kez kilitlemek bir\n // no-op ama listeyi uzatır, ve sıralanmamış bir liste bu fonksiyonun tek\n // işini yapmamış olurdu.\n const unique = [...new Set(ids)].sort();\n if (unique.length === 0) {\n // Boş liste sessizce \"hiçbir şeyi kilitleme\" OLMAMALI mı? Olmalı — ama\n // sessizce değil: burada erken dönüyoruz çünkü kilitlenecek satır\n // gerçekten yok. Çağıranın kilit aldığını sanması ancak boş olmayan bir\n // liste verip satırların bulunamamasıyla olur; onu Postgres söyler.\n return;\n }\n const pk = primaryKeyOf(table);\n if (pk === null) {\n throw new Error(\n `lockRows(${table}): tek-kolon primary key bulunamadı — kilit sırası bir anahtar ister (FR-035).`,\n );\n }\n const params: unknown[] = [];\n const add = (v: unknown): string => {\n params.push(v);\n return `$${params.length}`;\n };\n // Placeholder genişletmesi, `= ANY($1)` DEĞİL: dizi bind'i sürücüde\n // Postgres array literal'ine çevrilmiyor ve canlıda\n // `malformed array literal` 500'ü veriyordu (verify 19-3b, 2026-08-28).\n const list = unique.map((id) => add(id)).join(\", \");\n await (await at()).unsafe(\n `SELECT t.${quoteIdent(pk)} FROM ${quoteTable(table)} t ` +\n `WHERE t.${quoteIdent(pk)} IN (${list}) ORDER BY t.${quoteIdent(pk)} FOR NO KEY UPDATE`,\n params,\n );\n },\n\n /**\n * Bir idempotency anahtarını SAHİPLEN (FR-033).\n *\n * `{ inserted: true, row }` → bu çağrı yazdı.\n * `{ inserted: false, row }` → başkası önce yazdı; dönen satır ONUN satırı.\n *\n * ÖLÇÜLDÜ (pg16, spec Research Appendix) — üç dalın üçü de farklı davranıyor:\n *\n * plain INSERT ikinci oturum 2121 ms BLOKLANIR, sonra 23505 alır;\n * birincinin satırı korunur ← istenen\n * ON CONFLICT DO UPDATE ikincinin verisi birincininkini EZER\n * ON CONFLICT DO NOTHING `INSERT 0 0` — sessiz; çağıran ne olduğunu bilemez\n *\n * Bu yüzden `ON CONFLICT` KULLANILMIYOR. Ödeme yolunda \"ikinci çağrı\n * birincinin sonucunu görsün\" idempotency'nin tanımıdır; ezmek ya da\n * susmak ikisi de yanlış cevap.\n *\n * INSERT bir SAVEPOINT içinde koşuyor: başarısız bir INSERT transaction'ı\n * ABORT eder (25P02) ve savepoint olmadan yakalama işe yaramaz — hata\n * yakalanır ama sonraki SELECT de \"current transaction is aborted\" alır.\n */\n async claim(table: string, unique: Row, extra: Row = {}): Promise<{ inserted: boolean; row: Row }> {\n const keyCols = Object.keys(unique);\n if (keyCols.length === 0) {\n throw new Error(\n `claim(${table}): benzersiz alan verilmedi. claim, bir anahtarı sahiplenmektir; ` +\n `anahtar yoksa sahiplenecek bir şey de yok — insert(${table}, …) kullanın.`,\n );\n }\n assertUsableWriteValues(\"claim\", table, keyCols, unique);\n const data = { ...unique, ...extra };\n const cols = Object.keys(data);\n const live = await at();\n try {\n return await live.savepoint(async (sp) => {\n const params: unknown[] = [];\n const add = (v: unknown): string => `$${params.push(v)}`;\n const tuple = buildValueTuple(table, cols, data, add, \"claim\");\n const rows = (await sp.unsafe(\n `INSERT INTO ${quoteTable(table)} (${cols.map(quoteIdent).join(\", \")}) ` +\n `VALUES (${tuple}) RETURNING ${rowProjection(table)}`,\n params,\n )) as Row[];\n if (!rows[0]) {\n throw new Error(\n `claim(${table}): INSERT satır döndürmedi — yazma reddedildi (büyük olasılıkla bir RLS policy'si).`,\n );\n }\n return { inserted: true, row: asTableRow(table, rows[0]) };\n });\n } catch (e) {\n if (!isUniqueViolation(e)) throw e;\n // YALNIZ benzersiz alanlarla arıyoruz. Tüm alanlarla aramak, ikinci\n // çağrı farklı bir yük gönderdiğinde satırı BULAMAZDI ve hata\n // \"duplicate\" yerine \"kayıp satır\" olarak görünürdü.\n const params: unknown[] = [];\n const add = (v: unknown): string => {\n params.push(v);\n return `$${params.length}`;\n };\n const where = keyCols.map((c) => `t.${quoteIdent(c)} = ${add(unique[c])}`).join(\" AND \");\n const found = (await (await at()).unsafe(\n `SELECT ${rowProjection(table, \"t\", \"*\")} FROM ${quoteTable(table)} t WHERE ${where} LIMIT 1`,\n params,\n )) as Row[];\n if (!found[0]) {\n // Anahtar çakıştı ama satır görünmüyor. İKİ sebebi olabilir ve\n // ikisini de SÖYLÜYORUZ: (a) ihlal edilen kısıt bu çağrının `unique`\n // alanları DEĞİL — tabloda ikinci bir UNIQUE var ve onu çiğnedik;\n // (b) satır var ama bir RLS policy'si bu çağırandan gizliyor.\n // Tek sebebi ilan etmek, ikincisini yaşayan çağıranı yanlış yere\n // baktırırdı (inceleme I-5).\n const named = constraintOf(e);\n throw new Error(\n `claim(${table}): benzersizlik ihlali${named ? ` (${named})` : \"\"} yakalandı ama ` +\n `${keyCols.join(\", \")} ile satır bulunamadı. Ya ihlal BAŞKA bir unique kısıttan ` +\n `geliyor — o zaman claim() bu çağrı için yanlış araç — ya da satır var ve bir RLS ` +\n `policy'si onu bu çağırandan gizliyor.`,\n );\n }\n return { inserted: false, row: asTableRow(table, found[0]) };\n }\n },\n\n /**\n * INSERT the row, or UPDATE it when it collides on `onConflict`.\n *\n * WHY IT IS AN OPERATION rather than a recipe. \"Try the insert, catch the\n * unique violation, update instead\" does not work here: a request runs in ONE\n * Postgres transaction, so the failed insert aborts it and every later\n * statement answers `current transaction is aborted`. A tenant measured that\n * as 7 of 8 concurrent requests returning 500, gave up on upsert, and had a\n * trigger create the row instead — a workaround that needs a new trigger for\n * every table with a unique row.\n *\n * The conflict columns are excluded from the SET list: they are what MATCHED,\n * so writing them back is at best a no-op and at worst a surprise.\n */\n async put(table: string, data: Row, opts: { onConflict: readonly string[] }): Promise<Row> {\n assertNotAppendOnly(\"put\", table);\n const conflict = opts.onConflict;\n if (conflict.length === 0) {\n // A silent fall-through to a plain INSERT would be an upsert that is not\n // one: it would work until two callers raced, which is the only time it\n // matters.\n throw new Error(`upsert into ${table}: onConflict en az bir kolon adı ister`);\n }\n const cols = Object.keys(data);\n if (cols.length === 0) throw new Error(`upsert into ${table}: no columns given`);\n // D-020 eki (FR-020): validity'li tabloda \"aynı anahtarın yeni değeri\"\n // EZME değil SUPERSEDE'dir — geçmiş silinmez. Düz DO UPDATE burada iki\n // kez yanlıştır: geçerli satırı ezer VE partial arbiter'la (UNIQUE ...\n // WHERE valid_to IS NULL) düz ON CONFLICT eşleşmez (42P10). Desen:\n // partial-arbiter'lı DO NOTHING insert (abort'suz), çakışmada\n // kapat→ekle→bağla (worker writeMemoryFacts ile aynı sıra).\n if (searchConfigFor(table)?.validity) {\n const bindData: unknown[] = [];\n const addPut = (v: unknown): string => `$${bindData.push(v)}`;\n const ph = buildValueTuple(table, cols, data, addPut, \"put\");\n const insertSql =\n `INSERT INTO ${quoteTable(table)} (${cols.map(quoteIdent).join(\", \")}) VALUES (${ph}) ` +\n `ON CONFLICT (${conflict.map(quoteIdent).join(\", \")}) WHERE \"valid_to\" IS NULL DO NOTHING RETURNING ${rowProjection(table)}`;\n const live = await at();\n const first = (await live.unsafe(insertSql, bindData)) as Row[];\n if (first[0]) return asTableRow(table, first[0]);\n const condSql = conflict.map((c, i) => `${quoteIdent(c)} = $${i + 1}`).join(\" AND \");\n const condBind = conflict.map((c) => (data as Record<string, unknown>)[c]);\n const cur = (await live.unsafe(\n `SELECT ${rowProjection(table)} FROM ${quoteTable(table)} WHERE ${condSql} AND \"valid_to\" IS NULL`, condBind)) as Row[];\n const old = cur[0] as Record<string, unknown> | undefined;\n if (old === undefined) {\n throw new Error(`upsert into ${table}: eşzamanlı supersede yarışı — geçerli satır bulunamadı, isteği yineleyin (D-020)`);\n }\n const pk = Object.keys(old).includes(\"id\") ? \"id\" : Object.keys(old)[0]!;\n await live.unsafe(\n `UPDATE ${quoteTable(table)} SET \"valid_to\" = now() WHERE ${quoteIdent(pk)} = $1 AND \"valid_to\" IS NULL`,\n [old[pk]]);\n const second = (await live.unsafe(insertSql, bindData)) as Row[];\n if (!second[0]) {\n throw new Error(`upsert into ${table}: eşzamanlı supersede yarışı — yeni satır açılamadı, isteği yineleyin (D-020)`);\n }\n const fresh = second[0] as Record<string, unknown>;\n await live.unsafe(\n `UPDATE ${quoteTable(table)} SET \"superseded_by\" = $2 WHERE ${quoteIdent(pk)} = $1`,\n [old[pk], fresh[pk]]);\n return asTableRow(table, second[0]);\n }\n const params: unknown[] = [];\n const add = (v: unknown): string => `$${params.push(v)}`;\n const placeholders = buildValueTuple(table, cols, data, add, \"put\");\n const conflictSet = new Set(conflict);\n const assignments = cols\n .filter((c) => !conflictSet.has(c))\n .map((c) => `${quoteIdent(c)} = EXCLUDED.${quoteIdent(c)}`);\n // Nothing to update means the row's identity IS the row: keep it and hand\n // the existing one back rather than answering zero rows.\n const action = assignments.length\n ? `DO UPDATE SET ${assignments.join(\", \")}`\n : `DO UPDATE SET ${quoteIdent(conflict[0]!)} = EXCLUDED.${quoteIdent(conflict[0]!)}`;\n const sql =\n `INSERT INTO ${quoteTable(table)} (${cols.map(quoteIdent).join(\", \")}) ` +\n `VALUES (${placeholders}) ` +\n `ON CONFLICT (${conflict.map(quoteIdent).join(\", \")}) ${action} RETURNING ${rowProjection(table)}`;\n const rows = (await (await at()).unsafe(sql, params)) as Row[];\n const row = rows[0];\n if (!row) {\n throw new Error(\n `upsert into ${table} returned no row — the write was rejected (an RLS policy, most likely).`,\n );\n }\n return asTableRow(table, row);\n },\n\n async update(table: string, id: string, data: Row): Promise<Row | null> {\n assertNotAppendOnly(\"update\", table);\n const cols = Object.keys(data);\n if (cols.length === 0) return ops.findById(table, id);\n // AYNI SET kurucusu `updateMany` ile. Ayrı olduğunda bu yol düz\n // `SET col = $n` kuruyordu, yani `now()` ve `increment()` en çok\n // kullanılan yazmada çalışmıyor, çoklu yazmada çalışıyordu.\n const params: unknown[] = [];\n const add = (v: unknown): string => {\n params.push(v);\n return `$${params.length}`;\n };\n const assignments = buildSetAssignments(table, cols, data, add, \"update\");\n const sql = `UPDATE ${quoteTable(table)} SET ${assignments} WHERE id = ${add(id)} RETURNING ${rowProjection(table)}`;\n const rows = (await (await at()).unsafe(sql, params)) as Row[];\n return rows[0] ? asTableRow(table, rows[0]) : null;\n },\n\n async delete(table: string, id: string): Promise<void> {\n assertNotAppendOnly(\"delete\", table);\n await (await at()).unsafe(`DELETE FROM ${quoteTable(table)} WHERE id = $1`, [id]);\n },\n\n /**\n * Update every row the filter matches, in ONE statement.\n *\n * The capability was already here and only reachable from inside a\n * transaction plan (`tx.tables.x.updateWhere`, since 11.0.0). Outside it the\n * only door was `update(id, …)`, so \"mark every unapproved row in this\n * household\" was an N+1 loop or hand-written SQL — and hand-written SQL is\n * where the typed surface and RLS both stop helping.\n *\n * The filter language is `findMany`'s, compiled by the same `compileWhere`:\n * one filter language, or the two spellings drift.\n *\n * AN EMPTY FILTER IS REFUSED. `UPDATE … WHERE true` is a whole-table write,\n * and the shape that produces it by accident — a filter object built from\n * request input that happened to come back empty — is exactly the shape that\n * should not silently succeed. Callers who mean every row say so with a\n * predicate that is true for every row.\n */\n async updateMany(\n table: string,\n where: Row,\n set: Row,\n opts?: { returning?: boolean },\n ): Promise<Row[] | number> {\n assertNotAppendOnly(\"updateMany\", table);\n const cols = Object.keys(set);\n if (cols.length === 0) {\n // A silent `[]` here is indistinguishable from \"nothing matched\", and a\n // caller that turns an empty result into a 404 answers the wrong thing.\n throw new Error(\n `updateMany(${table}): nothing to set. An update with no columns is ` +\n `not a no-op worth pretending happened — pass the columns to write.`,\n );\n }\n // SET kolonları da WHERE kolonları gibi şemadan doğrulanır. Doğrulanmayan\n // yarı, bir yazım hatasını Postgres'e kadar taşıyordu: çağıran ham\n // `column \"dome\" of relation \"todos\" does not exist` görüyordu, SDK'nın\n // kendi diliyle değil. Null şema \"kontrol edemem\" demektir, \"serbest\"\n // değil — identifier yine quoteIdent'ten geçer (D-21).\n const known = schemaColumns(table);\n if (known !== null) {\n for (const c of cols) {\n if (!known.has(c)) {\n throw new Error(`updateMany(${table}): set kolonu \"${c}\" tabloda yok (FR-016)`);\n }\n }\n }\n const params: unknown[] = [];\n const add = (v: unknown): string => {\n params.push(v);\n return `$${params.length}`;\n };\n const assignments = buildSetAssignments(table, cols, set, add, \"updateMany\");\n const whereSql = compileWhere(table, known, where, add, \"updateMany\");\n assertHasPredicate(whereSql, \"updateMany\", table);\n // `AS t`, because compileWhere qualifies every column with the `t.` alias —\n // the same compiler findMany uses, and it must stay the same one. Without\n // the alias the predicate names a relation this statement never declared.\n //\n // Çok satır: kilit sırası CTE'de SABİTLENİR (FR-015). Postgres'in UPDATE'i\n // satırları KEYFİ sırada kilitler (\"There is no ORDER BY in an SQL UPDATE\n // command\") — aynı iki satıra dokunan iki oturum farklı plan seçerse ters\n // sırada kilitleyip deadlock üretir. ORDER BY'ı UPDATE'e yazamayız; bu\n // yüzden sıra, kilidi ALAN SELECT'e yazılıyor.\n const pk = primaryKeyOf(table);\n // `returning: false` — SATIR DEĞİL SAYI. Ölçüldü (200 bin satır, canlı\n // pg16): `RETURNING *` sunucuda %55 daha pahalı (7,2 sn → 11,1 sn) ve\n // JS'te 45 MB yığın, satır başına 236 bayt. Bir milyon satırda 225 MB.\n // `updateMany`'nin sözleşmesi dönen diziyi okumaktır ve çoğu çağrı için\n // doğrudur — ama toplu bir iş için çıkış yolu OLMALIYDI, ve `deleteMany`\n // zaten sayı döndürüyor.\n const wantRows = opts?.returning !== false;\n const tail = wantRows ? `RETURNING ${rowProjection(table, \"t\", \"*\")}` : \"RETURNING 1\";\n const simple = isSinglePkEquality(where, pk) || pk === null;\n // Kilit CTE'si (FR-015) ZATEN bir WITH listesi; sayım onun ARDINA\n // ekleniyor, İÇİNE değil — `WITH upd AS (WITH locked AS …)` iç içe bir\n // CTE olurdu ve okunması da doğrulaması da zor.\n const body = simple\n ? `UPDATE ${quoteTable(table)} AS t SET ${assignments} WHERE true${whereSql} ${tail}`\n : `UPDATE ${quoteTable(table)} AS t SET ${assignments} FROM locked ` +\n `WHERE t.${quoteIdent(pk)} = locked.\"__pb_lock\" ` +\n (wantRows ? `RETURNING ${rowProjection(table, \"t\")}` : \"RETURNING 1\");\n const lockedCte = simple\n ? \"\"\n : `WITH locked AS (SELECT t.${quoteIdent(pk)} AS \"__pb_lock\" FROM ${quoteTable(table)} t WHERE true${whereSql} ` +\n `ORDER BY t.${quoteIdent(pk)} FOR NO KEY UPDATE) `;\n const sql = wantRows\n ? `${lockedCte}${body}`\n : simple\n ? `WITH upd AS (${body}) SELECT count(*)::int AS n FROM upd`\n : `${lockedCte.replace(/ $/, \"\")}, upd AS (${body}) SELECT count(*)::int AS n FROM upd`;\n const out = (await (await at()).unsafe(sql, params)) as Row[];\n // `returning: false` SAYI döndürür — `deleteMany` ile aynı şekil, aynı\n // gerekçe.\n if (!wantRows) return Number((out[0] as Record<string, unknown> | undefined)?.[\"n\"] ?? 0);\n return asTableRows(table, out);\n },\n\n /**\n * Delete every row the filter matches, in ONE statement; resolves to how\n * many went. Same filter language, same empty-filter refusal as\n * {@link updateMany} — and here the accident is worse.\n */\n async deleteMany(table: string, where: Row): Promise<number> {\n assertNotAppendOnly(\"deleteMany\", table);\n const params: unknown[] = [];\n const add = (v: unknown): string => {\n params.push(v);\n return `$${params.length}`;\n };\n const known = schemaColumns(table);\n const whereSql = compileWhere(table, known, where, add, \"deleteMany\");\n assertHasPredicate(whereSql, \"deleteMany\", table);\n // DÜZ DELETE — kilit-sırası CTE'si BURADA YOK, ve yokluğu bir eksiklik\n // değil ölçülmüş bir düzeltme (T013 gözcüsü, canlı pg16; spec Changelog\n // 2026-09-02'de FR-015 buna göre daraltıldı).\n //\n // İki bağımsız sebep, ikisi de kilitleyen SELECT'in kendisinden geliyor:\n //\n // 1. YETKİ. `FOR NO KEY UPDATE` bir UPDATE kilididir ve Postgres\n // kilitleyen SELECT'e UPDATE POLİTİKASINI uygular (CREATE POLICY,\n // Table 292: \"Using UPDATE for a policy means that it will apply to\n // UPDATE, SELECT FOR UPDATE, and SELECT FOR SHARE\"). Yapılan iş ise\n // DELETE ve DELETE politikasıyla yönetilir. SELECT+DELETE politikası\n // olan ama UPDATE politikası OLMAYAN bir tabloda ölçüm: düz DELETE 1\n // satır sildi, CTE'li form 0 sildi — hatasız. Çağıran o sıfırı\n // \"hiçbir şey eşleşmedi\" diye okur. `FOR UPDATE` de kurtarmıyor.\n // 2. KİLİT YÜKSELTMESİ. DELETE zaten `FOR UPDATE` gücünde kilit alır\n // (doküman 13.3.2), yani `FOR NO KEY UPDATE` ile başlamak 13.3.4'ün\n // \"ilk alınan kilit gereken en kısıtlayıcı mod olsun\" kuralını\n // çiğner. NOT: bu gerekçenin FK'li kurulumdaki deadlock ölçümü ikinci\n // bir gözcü tarafından YENİDEN ÜRETİLEMEDİ — o kurguda her iki form\n // da deadlock veriyor. Yükseltmenin kendisi dokümanla sabit; ondan\n // doğan somut zarar iddiası ölçülmüş SAYILMAMALI.\n //\n // KABUL EDİLEN BEDEL, adıyla: düz form satırları pk sırasında DEĞİL,\n // planın seçtiği sırada kilitler. Aynı satır kümesine giren eşzamanlı bir\n // `updateMany` (o pk sırasında kilitliyor) ile deadlock ALINABİLİR —\n // ölçüldü, üretildi. Takas bilinçli: deadlock 40P01 ile GÜRÜLTÜLÜDÜR ve\n // çağıran onu görüp yeniden dener; alternatifi RLS altında SESSİZ 0\n // satırdı, ve sessiz yanlış cevap gürültülü hatadan her zaman kötüdür.\n //\n // `updateMany` tarafında bu ikilem yok (iş zaten UPDATE), orada CTE\n // duruyor.\n // `RETURNING 1` SATIR BAŞINA bir satır döndürüyor ve yalnız uzunluğu\n // okunuyor. Bir CTE ile tek satıra indirmeyi denedim ve GERİ ALDIM:\n // ölçüldü, 200 bin silmede bu biçim 8,1 MB — `RETURNING *`'ın 45 MB'ına\n // karşı 5,5 kat ucuz. Kazanç, kilit ve RLS gerekçesi özenle yazılmış bir\n // testin çivilediği bir statement şeklini değiştirmeyi hak etmiyor.\n // Bedel BİLİNİYOR ve ölçülü (D-034).\n const sql = `DELETE FROM ${quoteTable(table)} AS t WHERE true${whereSql} RETURNING 1`;\n const rows = (await (await at()).unsafe(sql, params)) as Row[];\n return rows.length;\n },\n\n /**\n * How many rows match — the half of pagination `limit`/`offset` cannot\n * supply. Without it a page count is either a guess or \"fetch everything and\n * read .length\", and the second one is the scale risk this surface exists to\n * remove.\n *\n * An empty filter is legitimate HERE: counting a whole table is a read, and\n * reads do not destroy anything.\n */\n /**\n * Toplama — `count`'un yanına `sum`/`avg`/`min`/`max` ve `groupBy`.\n *\n * Var olma nedeni: bunlar olmadan \"bu hesabın toplamı\" ya `$query`'ye ya da\n * TÜM satırları çekip JS'te toplamaya düşüyor. İkincisi hem N+1 hem de para\n * için YANLIŞ — `numeric` JS `number`'ına uğradığı anda kesinliğini\n * kaybeder.\n *\n * `groupBy` verilirse SATIRLAR döner, verilmezse TEK sonuç. Boş kümede\n * Postgres NULL döndürür, 0 değil — ve bu SDK onu `null` olarak geçiriyor:\n * \"hiç satır yoktu\" ile \"toplam sıfırdı\" farklı şeyler.\n */\n async aggregate(\n table: string,\n q: {\n where?: Row;\n sum?: readonly string[];\n avg?: readonly string[];\n min?: readonly string[];\n max?: readonly string[];\n count?: boolean;\n groupBy?: readonly string[];\n } = {},\n ): Promise<Record<string, unknown> | Record<string, unknown>[]> {\n const known = schemaColumns(table);\n const check = (col: string, where: string): void => {\n if (known !== null && !known.has(col)) {\n throw new Error(`aggregate(${table}): ${where} kolonu \"${col}\" tabloda yok (FR-016)`);\n }\n };\n const parts: string[] = [];\n const wants: { fn: \"sum\" | \"avg\" | \"min\" | \"max\"; col: string; alias: string }[] = [];\n for (const fn of [\"sum\", \"avg\", \"min\", \"max\"] as const) {\n for (const col of q[fn] ?? []) {\n check(col, fn);\n // `sum`/`avg` SAYISAL OLMAYAN bir kolonda anlamsız ve Postgres onu\n // `function sum(text) does not exist` diye reddeder — tip de\n // reddediyor, ama tipin atlandığı yolda motor susmamalı.\n if (fn === \"sum\" || fn === \"avg\") {\n const t = columnTypeOf(table, col);\n if (t !== null && !NUMERIC_PG_TYPES.has(t)) {\n throw new Error(\n `aggregate(${table}): ${fn}(\"${col}\") sayısal olmayan bir kolonda — \"${col}\" bir ` +\n `${t} kolonu. Toplama yalnız integer/bigint/numeric kolonlarda anlamlı; ` +\n `kaç satır olduğunu saymak için count: true kullanın.`,\n );\n }\n }\n const alias = `${fn}__${col}`;\n wants.push({ fn, col, alias });\n parts.push(aggregateExpr(table, fn, col, alias));\n }\n }\n if (q.count === true) parts.push('count(*) AS \"_count\"');\n if (parts.length === 0) {\n throw new Error(\n `aggregate(${table}): hiçbir toplama istenmedi — sonuç boş bir nesne olurdu. ` +\n `sum/avg/min/max kolonlarını ya da count: true'yu verin.`,\n );\n }\n const groups = q.groupBy ?? [];\n for (const col of groups) check(col, \"groupBy\");\n const groupSel = groups.map((c) => `${columnTypeOf(table, c) === \"timestamp\" ? columnResult(table, c, \"t\") : `t.${quoteIdent(c)}`} AS ${quoteIdent(`g__${c}`)}`);\n\n const params: unknown[] = [];\n const add = (v: unknown): string => `$${params.push(v)}`;\n const whereSql = compileWhere(table, known, q.where ?? {}, add, \"aggregate\");\n const groupSql = groups.length > 0 ? ` GROUP BY ${groups.map((c) => `t.${quoteIdent(c)}`).join(\", \")}` : \"\";\n const sql =\n `SELECT ${[...groupSel, ...parts].join(\", \")} FROM ${quoteTable(table)} t ` +\n `WHERE true${whereSql}${groupSql}`;\n const rows = (await (await at()).unsafe(sql, params)) as Record<string, unknown>[];\n\n const shape = (r: Record<string, unknown>): Record<string, unknown> => {\n const out: Record<string, unknown> = {};\n for (const c of groups) out[c] = r[`g__${c}`];\n for (const w of wants) {\n const bucket = (out[w.fn] ??= {}) as Record<string, unknown>;\n bucket[w.col] = r[w.alias] ?? null;\n }\n // count TEK sayı, çünkü tek bir şeyi sayıyor. Postgres bigint döndürür,\n // sürücü string verir — `count()` op'unun aynı dönüşümü.\n if (q.count === true) out[\"count\"] = Number(r[\"_count\"] ?? 0);\n return out;\n };\n // `groupBy` yoksa Postgres HER ZAMAN tek satır döndürür (boş tabloda bile,\n // NULL'larla) — o yüzden burada `rows[0]` boş olamaz, ama olsa bile\n // şekli koruyoruz ki çağıran `undefined` görmesin.\n return groups.length > 0 ? rows.map(shape) : shape(rows[0] ?? {});\n },\n\n async count(table: string, where: Row = {}): Promise<number> {\n const params: unknown[] = [];\n const add = (v: unknown): string => {\n params.push(v);\n return `$${params.length}`;\n };\n const known = schemaColumns(table);\n const whereSql = compileWhere(table, known, where, add, \"count\");\n const sql = `SELECT count(*) AS n FROM ${quoteTable(table)} t WHERE true${whereSql}`;\n const rows = (await (await at()).unsafe(sql, params)) as Row[];\n // Postgres answers count() as bigint, which the driver hands over as a\n // STRING. Returning it unconverted would put the report's own A4 defect\n // into a brand-new surface: a \"number\" the caller cannot add to.\n return Number((rows[0] as Record<string, unknown> | undefined)?.n ?? 0);\n },\n\n async findUnique(table: string, where: Row, opts: { select?: readonly string[]; with?: Record<string, unknown> } = {}): Promise<Row | null> {\n const keys = memoTable(uniqueKeysCache, currentSchema, table, () => uniqueKeysOf(tableDefOf(table) ?? {}));\n assertUniqueLookup(table, keys, where);\n const rows = await ops.findMany(table, where, { ...opts, select: opts.select === undefined ? undefined : [...opts.select], limit: 2 });\n if (rows.length > 1) throw new Error(`findUnique(${table}): deployed constraints disagree with the schema; multiple rows matched`);\n return rows[0] ?? null;\n },\n\n async findById(table: string, id: string): Promise<Row | null> {\n const rows = (await (await at()).unsafe(\n `SELECT ${rowProjection(table)} FROM ${quoteTable(table)} WHERE id = $1`,\n [id],\n )) as Row[];\n return rows[0] ? asTableRow(table, rows[0]) : null;\n },\n\n async findMany(table: string, query: Row = {}, opts: FindManyOptions = {}): Promise<Row[]> {\n const compiled = compileFindMany(table, query, opts);\n return asTableRows(table, await (await at()).unsafe(compiled.sql, compiled.params) as Row[], opts.with, opts.select !== undefined);\n },\n\n async page(table: string, query: Row = {}, opts: RawPageOptions = {}): Promise<Page<Row>> {\n const secret = cursorKey();\n const schema = pageSchema(table);\n const { order, size, backward, token } = pageOrder(schema.columns, schema.primaryKey, opts);\n const params: unknown[] = [];\n const add = (v: unknown) => `$${params.push(v)}`;\n const known = schemaColumns(table);\n const where = compileWhere(table, known, query, add, \"page\");\n const cols = selectClause(table, known, opts.select === undefined ? undefined : [...opts.select]);\n const scope = fingerprint({ table, schema: schema.stamp, order, where, params,\n select: opts.select, with: opts.with, identity: context.cursorScope ?? \"direct\" });\n const values = token === undefined ? undefined : decodeCursor(secret, scope, token, order.length);\n const column = (name: string) => `t.${quoteIdent(name)}`;\n const boundary = values ? ` AND ${pageBoundary(order, values, backward, add, column)}` : \"\";\n const opposite = values\n ? `EXISTS (SELECT 1 FROM ${quoteTable(table)} t WHERE true${where} AND ${pageBoundary(order, values, !backward, add, column, true)})`\n : \"false\";\n // Each hidden name is chosen outside both the projection and relation map.\n let prefix = \"__pb_page_\";\n const names = [...Object.keys(schema.columns), ...Object.keys(opts.with ?? {})];\n while (names.some(n => n.startsWith(prefix))) prefix += \"_\";\n const ordinal = `${prefix}ordinal`, other = `${prefix}opposite`;\n const hidden = order.map((o, i) => `${prefix}${i}`);\n const cursorCols = order.map((o, i) => `${columnTypeOf(table, o.column) === \"timestamp\" ? timestampResult(column(o.column)) : `${column(o.column)}::text`} AS ${quoteIdent(hidden[i]!)}`);\n const w = opts.with && Object.keys(opts.with).length ? withClauses(table, opts.with, add, \"page\") : { select: [], joins: [] };\n const nativeOrder = order.map(o => `${column(o.column)} ${(o.direction === \"asc\") !== backward ? \"ASC\" : \"DESC\"} NULLS ${(o.nulls === \"first\") !== backward ? \"FIRST\" : \"LAST\"}`).join(\", \");\n const visible = cols === \"*\" ? \"t.*\" : cols;\n const inner = `SELECT ${[visible, ...w.select, ...cursorCols, `row_number() OVER (ORDER BY ${nativeOrder}) AS ${quoteIdent(ordinal)}`].join(\", \")} ` +\n `FROM ${quoteTable(table)} t ${w.joins.join(\" \")} WHERE true${where}${boundary} ORDER BY ${nativeOrder} LIMIT ${size + 1}`;\n // The outer row exists even for an empty page. Both flags and the page\n // observe one statement snapshot, including under READ COMMITTED.\n const sql = `SELECT p.*, b.${quoteIdent(other)} FROM (SELECT ${opposite} AS ${quoteIdent(other)}) b ` +\n `LEFT JOIN LATERAL (${inner}) p ON true ORDER BY p.${quoteIdent(ordinal)}`;\n const result = await (await at()).unsafe(sql, params) as Row[];\n const hasOpposite = result[0]?.[other] === true;\n let rows = result.filter(row => row[ordinal] !== null && row[ordinal] !== undefined);\n const hasMore = rows.length > size;\n rows = rows.slice(0, size);\n if (backward) rows.reverse();\n const cursor = (row: Row | undefined) => row ? encodeCursor(secret, scope, hidden.map(name => row[name] === null ? null : String(row[name]))) : null;\n const pageInfo = { startCursor: cursor(rows[0]), endCursor: cursor(rows.at(-1)),\n hasNextPage: backward ? hasOpposite : hasMore, hasPreviousPage: backward ? hasMore : hasOpposite };\n for (const row of rows) for (const name of [...hidden, ordinal, other]) delete row[name];\n return { rows: asTableRows(table, rows, opts.with, opts.select !== undefined), pageInfo };\n },\n\n /**\n * Tek-SQL hibrit arama (FR-014): iki kol CTE + FULL OUTER JOIN + RRF\n * (1/(50+rank), CLAIM-N4). Operatör şema-nitelikli (C-10, M-1); GUC\n * hnsw.iterative_scan=relaxed_order aynı tx'te set_config ile (CLAIM-N3 —\n * RLS/filtre altında LIMIT-altı dönüş açığını kapatır). Sorgu-anı embed\n * T024'te gelir; o zamana dek vector kolu yalnız params.vector ile koşar.\n */\n async search(\n table: string,\n params: {\n query?: string;\n vector?: number[];\n where?: Record<string, unknown>;\n limit?: number;\n using?: string;\n mode?: \"hybrid\" | \"text\" | \"vector\";\n /** Nihai (RRF-sonrası) skor alt eşiği — süzme LIMIT'ten ÖNCE (FR-001). */\n minScore?: number;\n /** RRF-sonrası üstel tazelik çürümesi: _score * exp(-ln(2)*yaş/halfLife) (FR-004). */\n recency?: { field: string; halfLife: string };\n /** Chunk-modunda satır başına dönen en iyi blok sayısı (1..10, vars. 3; FR-015). */\n blocksPerRow?: number;\n /** Satır-modunda FTS eşleşme vurgusu: ts_headline ile `_highlight`\n * alanı; chunk-modda no-op — bloklar zaten eşleşen kesittir (FR-025). */\n highlight?: boolean;\n /** Validity'li tabloda zaman penceresi: varsayılan yalnız güncel;\n * \"all\" tüm versiyonlar; {asOf} o andaki geçerli versiyon (FR-029). */\n validity?: \"all\" | { asOf: string };\n /** Alan-boost (FR-030): skor * (1 + w·x/(1+x)) — sınırlı, dış servissiz. */\n boost?: { field: string; weight: number };\n } = {},\n ): Promise<Row[]> {\n const cfg = searchConfigFor(table);\n if (!cfg) {\n throw new Error(`search(${table}): tablo aranabilir değil — ne vector kolonu ne search beyanı var (FR-013)`);\n }\n const excl = (params as InternalSearchParams).__excludeIds ?? [];\n // FR-058: `facets` search'ün PARAMETRESİ DEĞİL. Sayaçlar dizi ÜSTÜNDE bir\n // özellik olarak taşınıyordu ve `JSON.stringify(rows)` onu SESSİZCE\n // düşürüyor — bir kontrolcü onu döndürmeye çalıştığında yanıt gövdesinde\n // hiç görünmüyordu. Bağımsız dönüş veren `facets()` ciddi sözleşme.\n if ((params as { facets?: unknown }).facets !== undefined) {\n throw new Error(\n `search(${table}): facets artık search'ün parametresi değil — sayaçlar dizi üstünde ` +\n `taşınınca JSON.stringify onları düşürüyordu (FR-058). Bağımsız çağırın: ` +\n `facets({ facets: [...], where })`,\n );\n }\n if (params.validity !== undefined && cfg.validity !== true) {\n throw new Error(\n `search(${table}): validity parametresi verildi ama tablo validity beyanı taşımıyor (FR-029)`,\n );\n }\n // FR-029: validity filtresi where'lerle aynı bileşime girer — sem/kw/probe\n // ve chunk parent'ı; facets sayaçları da aynı pencereyi görür.\n const validityFor = (adder: (x: unknown) => string): string =>\n cfg.validity === true ? validitySql(params.validity, adder) : \"\";\n const rawLimit = params.limit ?? 20;\n if (typeof rawLimit !== \"number\" || !Number.isFinite(rawLimit)) {\n throw new Error(`search(${table}): limit sonlu bir sayı olmalı, ${String(rawLimit)} verildi (FR-013)`);\n }\n const limit = Math.min(Math.max(1, Math.trunc(rawLimit)), 100);\n const pool = Math.max(limit * 3, 30);\n if (params.minScore !== undefined && (typeof params.minScore !== \"number\" || !Number.isFinite(params.minScore))) {\n throw new Error(`search(${table}): minScore sonlu bir sayı olmalı, ${String(params.minScore)} verildi (FR-001)`);\n }\n // recency.field yalnız kolon-üyeliğiyle doğrulanır — cfg kolon TİPİ\n // taşımaz; timestamp olmayan kolon SQL'de kendi adıyla düşer (C-6).\n let recencyMul = \"\";\n if (params.recency !== undefined) {\n const { field, halfLife } = params.recency;\n if (!cfg.colSet.has(field)) {\n throw new Error(`search(${table}): recency.field \"${field}\" tabloda yok (FR-004)`);\n }\n recencyMul = ` * exp(-ln(2) * extract(epoch from (now() - t.${quoteIdent(field)})) / ${parseHalfLife(halfLife)})`;\n }\n // FR-030/D-017: alan-boost dış servissiz SINIRLI çarpandır — x/(1+x)\n // 0..1'e doyar, 1 + w·(...) hiçbir satırı sıfırlamaz; weight doğrulanmış\n // SONLU sayı olarak SQL'e literal iner (recency'nin halfLife'ı gibi).\n // Bileşim sırası FR-030: RRF → boost → recency → minScore.\n let boostMul = \"\";\n if (params.boost !== undefined) {\n const { field, weight } = params.boost;\n if (!cfg.colSet.has(field)) {\n throw new Error(`search(${table}): boost.field \"${field}\" tabloda yok (FR-030)`);\n }\n if (typeof weight !== \"number\" || !Number.isFinite(weight)) {\n throw new Error(`search(${table}): boost.weight sonlu bir sayı olmalı, ${String(weight)} verildi (FR-030)`);\n }\n const g = `greatest(t.${quoteIdent(field)},0)`;\n boostMul = ` * (1 + ${weight} * ${g}/(1+${g}))`;\n }\n const scoreMul = boostMul + recencyMul;\n if (cfg.chunk !== undefined) {\n // CHUNK-MODU (FR-015, D-010): arama türev tabloda koşar; RRF chunk\n // düzeyinde, sonra parent'a MAX-skor toplaması + en iyi blokların\n // json_agg'ı. minScore/recency GRUPLAMA-SONRASI parent skoruna\n // uygulanır (FR-018). `where` filtreleri parent satırına uygulanır;\n // RLS'i chunk tablosunun parent-mirror policy'si zaten süzer.\n const ck = cfg.chunk;\n const pidQ = quoteIdent(`parent_${cfg.pk}`);\n const bpr = Math.min(Math.max(1, Math.trunc(params.blocksPerRow ?? 3)), 10);\n const wantTextC =\n params.mode !== \"vector\" && ck.fts && typeof params.query === \"string\" && params.query !== \"\";\n let qvC: number[] | null = Array.isArray(params.vector) ? params.vector : null;\n if (qvC === null && ck.embed !== undefined && params.mode !== \"text\" &&\n typeof params.query === \"string\" && params.query !== \"\") {\n try {\n qvC = await embedQuery(ck.embed, params.query);\n } catch (e) {\n if (!wantTextC) throw e;\n qvC = null;\n }\n }\n if (!wantTextC && qvC === null) {\n throw new Error(\n `search(${table}): koşulabilir kol yok — metin için 'query' (FTS beyanı gerekir), semantik için 'vector' verin (FR-015)`,\n );\n }\n const bindC: unknown[] = [];\n const addC = (v: unknown): string => { bindC.push(v); return `$${bindC.length}`; };\n // where/validity/exclude ADAY ÜRETİMİNE gömülür (final-review C1):\n // küresel top-K chunk havuzu filtreli kümeden seçilmezse seçici bir\n // where'de eşleşen sayfa havuza hiç giremez ve arama sessizce boş\n // döner. Satır-modunun kanıtlı deseniyle simetri: filtrenin tek\n // yazarı aday CTE'leridir (sem/kw/trgm-retry); dış katman tekrarlamaz.\n const userWhereC = compileWhere(table, cfg.colSet, params.where ?? {}, addC);\n const whereC = userWhereC + excludeSql(cfg.pk, excl, addC) + validityFor(addC);\n const parentJoinC = ` JOIN ${quoteTable(table)} t ON t.${quoteIdent(cfg.pk)} = c.${pidQ} WHERE true${whereC} AND `;\n const liveC = await at();\n const K2 = 50;\n const cpool = Math.max(limit * 9, 90); // blok başına aday: parent-limit × blocksPerRow payı\n let semC = \"\";\n let kwC = \"\";\n if (qvC !== null) {\n const sch = await vectorSchemaWithGuc(liveC);\n const op = METRIC_OPERATOR[ck.metric] ?? METRIC_OPERATOR.cosine;\n // NFR-B4 kapanışı: satır-modu probe'unun chunk ikizi — filtreli chunk\n // kümesi ≤ eşikse HNSW yerine exact tarama (+ 0.0 sıralama ifadesini\n // index-eşleşmesinden düşürür); recall=1.0, ms'ler. Probe RLS'li aynı\n // tx'te, C1'in parent-JOIN'li filtresiyle aynı kümeyi sayar.\n let exactOrderC = \"\";\n if (userWhereC !== \"\") {\n const probeRows = (await liveC.unsafe(\n `SELECT count(*)::int AS n FROM (SELECT 1 FROM ${quoteTable(ck.table)} c${parentJoinC}c.embedding IS NOT NULL LIMIT ${SELECTIVITY_EXACT_THRESHOLD + 1}) s`,\n bindC.slice(),\n )) as { n?: number }[];\n const n = probeRows?.[0]?.n;\n if (typeof n === \"number\" && n <= SELECTIVITY_EXACT_THRESHOLD) {\n exactOrderC = \" + 0.0\";\n }\n }\n const vp = addC(toVectorLiteral(qvC));\n semC =\n `SELECT c.${pidQ} AS pid, c.chunk_seq, ROW_NUMBER() OVER (ORDER BY (c.embedding OPERATOR(${quoteIdent(sch)}.${op}) ${vp}::${quoteIdent(sch)}.vector)${exactOrderC}) AS r ` +\n `FROM ${quoteTable(ck.table)} c${parentJoinC}c.embedding IS NOT NULL ORDER BY r LIMIT ${cpool}`;\n }\n let qpC = \"\";\n let qpCIdx = -1;\n if (wantTextC) {\n // FR-026: genişletme yalnız websearch BIND değerine — SQL metni değişmez.\n const qTextC =\n cfg.synonyms !== undefined ? expandSynonyms(params.query!, cfg.synonyms) : params.query;\n qpC = addC(qTextC);\n qpCIdx = bindC.length - 1;\n kwC =\n `SELECT c.${pidQ} AS pid, c.chunk_seq, ROW_NUMBER() OVER (ORDER BY ts_rank_cd(c.palbase_fts, websearch_to_tsquery('simple', ${qpC})) DESC) AS r ` +\n `FROM ${quoteTable(ck.table)} c${parentJoinC}c.palbase_fts @@ websearch_to_tsquery('simple', ${qpC}) ORDER BY r LIMIT ${cpool}`;\n }\n const msC = params.minScore === undefined ? \"\" : addC(params.minScore);\n const colListC = [...cfg.cols.map((c) => columnTypeOf(table, c) === \"timestamp\" ? projectedColumn(table, c, \"t\") : `t.${quoteIdent(c)}`)].join(\", \");\n const scoreC = scoreMul === \"\" ? \"g._score\" : `(g._score)${scoreMul}`;\n const assembleC = (kwIn: string, withKwn: boolean): string => {\n const kwnCol = withKwn ? `, (SELECT count(*) FROM kw)::int AS _kwn` : \"\";\n let fusedSrc: string;\n if (semC !== \"\" && kwIn !== \"\") {\n fusedSrc =\n `WITH sem AS (${semC}), kw AS (${kwIn}), fused AS (` +\n `SELECT COALESCE(sem.pid, kw.pid) AS pid, COALESCE(sem.chunk_seq, kw.chunk_seq) AS chunk_seq, ` +\n `(COALESCE(1.0/(${K2} + sem.r), 0) + COALESCE(1.0/(${K2} + kw.r), 0))::float8 AS cscore ` +\n `FROM sem FULL OUTER JOIN kw ON sem.pid = kw.pid AND sem.chunk_seq = kw.chunk_seq)`;\n } else if (semC !== \"\") {\n fusedSrc = `WITH sem AS (${semC}), fused AS (SELECT sem.pid, sem.chunk_seq, (1.0/(${K2} + sem.r))::float8 AS cscore FROM sem)`;\n } else {\n fusedSrc = `WITH kw AS (${kwIn}), fused AS (SELECT kw.pid, kw.chunk_seq, (1.0/(${K2} + kw.r))::float8 AS cscore FROM kw)`;\n }\n const inner =\n `${fusedSrc}, ranked AS (` +\n `SELECT f.pid, f.chunk_seq, f.cscore, ROW_NUMBER() OVER (PARTITION BY f.pid ORDER BY f.cscore DESC, f.chunk_seq) AS rn FROM fused f), ` +\n `grouped AS (` +\n `SELECT r.pid, MAX(r.cscore) AS _score, ` +\n `json_agg(json_build_object('content', c.content, 'score', r.cscore, 'chunkSeq', r.chunk_seq, 'charStart', c.char_start) ORDER BY r.cscore DESC, r.chunk_seq) FILTER (WHERE r.rn <= ${bpr}) AS blocks ` +\n `FROM ranked r JOIN ${quoteTable(ck.table)} c ON c.${pidQ} = r.pid AND c.chunk_seq = r.chunk_seq ` +\n `GROUP BY r.pid) ` +\n `SELECT ${colListC}, ${scoreC}::float8 AS _score, g.blocks AS blocks${kwnCol} ` +\n `FROM grouped g JOIN ${quoteTable(table)} t ON t.${quoteIdent(cfg.pk)} = g.pid`;\n return msC === \"\"\n ? `SELECT q.*${canOuter(table)} FROM (${inner}) q ORDER BY q._score DESC, q.${quoteIdent(cfg.pk)} LIMIT ${limit}`\n : `SELECT q.*${canOuter(table)} FROM (${inner}) q WHERE q._score >= ${msC} ORDER BY q._score DESC, q.${quoteIdent(cfg.pk)} LIMIT ${limit}`;\n };\n let rowsC = (await liveC.unsafe(assembleC(kwC, kwC !== \"\"), bindC)) as Row[];\n if (wantTextC && kwC !== \"\" && (rowsC.length === 0 || (rowsC[0] as Record<string, unknown>)._kwn === 0)) {\n // FR-002 chunk-modunda da geçerli: kelime kolu 0 adaysa trgm retry —\n // ifade chunk İÇERİĞİ üstünde (türev index'in kaynağı da o).\n const tsch = await trgmSchemaOf(liveC);\n const trgmKwC =\n `SELECT c.${pidQ} AS pid, c.chunk_seq, ROW_NUMBER() OVER (ORDER BY ${quoteIdent(tsch)}.word_similarity(${qpC}, coalesce(c.content,'')) DESC) AS r ` +\n `FROM ${quoteTable(ck.table)} c${parentJoinC}${quoteIdent(tsch)}.word_similarity(${qpC}, coalesce(c.content,'')) > 0.3 ORDER BY r LIMIT ${cpool}`;\n // trgm kelime-benzerliği OR-sözdizimi tanımaz: retry aynı placeholder'ı\n // HAM query ile koşar (bind kopyası — kayıtlı ilk çağrı değişmez).\n const retryBindC = bindC.slice();\n if (qpCIdx >= 0) retryBindC[qpCIdx] = params.query;\n rowsC = (await liveC.unsafe(assembleC(trgmKwC, false), retryBindC)) as Row[];\n }\n for (const r of rowsC) delete (r as Record<string, unknown>)._kwn;\n const outC = asTableRows(table, rowsC).map((r) => ({ ...r, blocks: (r as { blocks?: unknown }).blocks ?? [] }));\n logNoResults(table, params.query, params.mode, outC.length);\n return outC;\n }\n const wantText =\n params.mode !== \"vector\" && cfg.ftsCols.length > 0 && typeof params.query === \"string\" && params.query !== \"\";\n // Vektör kolu ancak GERÇEKTEN istenecekse çözülür (FR-015, review C1):\n // çok kollu tabloda salt-text arama 'using' zorunluluğuna TAKILMAZ.\n const anyEmbed = cfg.legs.some((l) => l.embed !== undefined);\n const vectorAsked =\n params.mode !== \"text\" &&\n (Array.isArray(params.vector) || params.using !== undefined || params.mode === \"vector\" ||\n (anyEmbed && typeof params.query === \"string\" && params.query !== \"\"));\n const leg = vectorAsked ? pickLeg(table, cfg.legs, params.using) : null;\n let qv: number[] | null = Array.isArray(params.vector) ? params.vector : null;\n if (qv === null && leg?.embed !== undefined && typeof params.query === \"string\" && params.query !== \"\") {\n // FR-025: beyan edilen modelle TEK sağlayıcı çağrısı. Başarısızlıkta\n // FR-015 düşüşü: text kolu koşulabiliyorsa arama ONUNLA döner; yoksa\n // adlandırılmış hata (sessiz boş dönüş asla).\n try {\n qv = await embedQuery(leg.embed, params.query);\n } catch (e) {\n if (!wantText) throw e;\n qv = null;\n }\n }\n const wantVector = leg !== null && qv !== null;\n if (!wantText && !wantVector) {\n throw new Error(\n `search(${table}): koşulabilir kol yok — metin için 'query' (FTS beyanı gerekir), semantik için 'vector' verin (FR-015)`,\n );\n }\n const bind: unknown[] = [];\n const add = (v: unknown): string => {\n bind.push(v);\n return `$${bind.length}`;\n };\n // Probe kararı (aşağıda) kullanıcı where'ine bakar: exclude tek başına\n // neredeyse hiç seçici değildir, exact-yol probe'unu tetiklememeli.\n const userWhere = compileWhere(table, cfg.colSet, params.where ?? {}, add);\n const whereSql = userWhere + excludeSql(cfg.pk, excl, add) + validityFor(add);\n const live = await at();\n const K = 50;\n let semSql = \"\";\n let kwSql = \"\";\n if (wantVector && leg) {\n // GUC yalnız hnsw taramasını etkiler — salt-text arama onu hiç koşmaz\n // (review I4). Soğuk yolda extension-şema lookup'ı AYNI statement'a\n // biner: sıcak yol +1, soğuk yol +1 (eskiden +2) round-trip; kalan tek\n // ekstra tur NFR-002'de karar kaydıyla kabul edildi.\n const sch = await vectorSchemaWithGuc(live);\n const op = METRIC_OPERATOR[leg.metric] ?? METRIC_OPERATOR.cosine;\n // SEÇİCİ FİLTREDE EXACT YOL (NFR-005 kapanışı, ölçümle): HNSW iterative\n // scan %1 seçicilikte 100K ölçeğinde hedefe ULAŞAMIYOR — GUC gridi\n // (relaxed/strict × max_scan_tuples 200K × ef_search 200..1000) en iyi\n // 0.38 recall verdi. Filtreli küme küçükse doğru cevap index'i HİÇ\n // kullanmamak: ≤10K satırda exact mesafe taraması ms'ler sürer ve\n // recall=1.0. Seçicilik bir probe ile ölçülür (RLS aynı tx'te — sayım\n // tenant'ın görebildiği satırlarla); index'i devre dışı bırakmak için\n // sıralama ifadesine + 0.0 eklenir (planner ifade-eşleşmesini kaybeder;\n // EXPLAIN'le doğrulandı — GUC'suz, tx yan etkisiz).\n let exactOrder = \"\";\n if (userWhere !== \"\") {\n const probeRows = (await live.unsafe(\n `SELECT count(*)::int AS n FROM (SELECT 1 FROM ${quoteTable(table)} t WHERE t.${quoteIdent(leg.column)} IS NOT NULL${whereSql} LIMIT ${SELECTIVITY_EXACT_THRESHOLD + 1}) s`,\n bind.slice(),\n )) as { n?: number }[];\n const n = probeRows?.[0]?.n;\n if (typeof n === \"number\" && n <= SELECTIVITY_EXACT_THRESHOLD) {\n exactOrder = \" + 0.0\";\n }\n }\n const vp = add(toVectorLiteral(qv!));\n semSql =\n `SELECT t.${quoteIdent(cfg.pk)} AS id, ROW_NUMBER() OVER (ORDER BY (t.${quoteIdent(leg.column)} OPERATOR(${quoteIdent(sch)}.${op}) ${vp}::${quoteIdent(sch)}.vector)${exactOrder}) AS r ` +\n `FROM ${quoteTable(table)} t WHERE t.${quoteIdent(leg.column)} IS NOT NULL${whereSql} ORDER BY r LIMIT ${pool}`;\n }\n let qpRef = \"\";\n let qpIdx = -1;\n if (wantText) {\n // FR-026: genişletme yalnız websearch BIND değerine — SQL metni değişmez.\n const qText =\n cfg.synonyms !== undefined ? expandSynonyms(params.query!, cfg.synonyms) : params.query;\n const qp = add(qText);\n qpIdx = bind.length - 1;\n qpRef = qp;\n kwSql =\n `SELECT t.${quoteIdent(cfg.pk)} AS id, ROW_NUMBER() OVER (ORDER BY ts_rank_cd(t.palbase_fts, websearch_to_tsquery('simple', ${qp})) DESC) AS r ` +\n `FROM ${quoteTable(table)} t WHERE t.palbase_fts @@ websearch_to_tsquery('simple', ${qp})${whereSql} ORDER BY r LIMIT ${pool}`;\n }\n const colList = [...cfg.cols.map((c) => columnTypeOf(table, c) === \"timestamp\" ? projectedColumn(table, c, \"t\") : `t.${quoteIdent(c)}`)].join(\", \");\n // minScore parametresi BİR kez bind'lenir — assemble iki kez çağrılabilir\n // (typo-fallback retry'ı) ve her çağrıda add() bind'i şişirirdi.\n const msP = params.minScore === undefined ? \"\" : add(params.minScore);\n // FR-025: vurgu yalnız satır-modu + metinli aramada; ifade typo-fallback'in\n // sorted-kolon birleşimiyle aynı. qp placeholder'ı yeniden kullanılır.\n const hlCol =\n params.highlight === true && wantText\n ? `, ts_headline('simple', ${ftsExprOf(cfg.ftsCols)}, websearch_to_tsquery('simple', ${qpRef})) AS _highlight`\n : \"\";\n // Recency çarpanı RRF-SONRASI nihai skora biner (FR-004); recency/\n // minScore yokken SQL'in tek farkı metinli aramadaki `_kwn` scalar'ıdır:\n // kelime kolunun kaç aday bulduğunu nihai SELECT taşır — typo-fallback\n // kararı (FR-002) sonuç satırından okunur, karar için ek tur yoktur.\n const assemble = (kwIn: string, withKwn: boolean): string => {\n const kwnCol = withKwn ? `, (SELECT count(*) FROM kw)::int AS _kwn` : \"\";\n let inner: string;\n if (semSql !== \"\" && kwIn !== \"\") {\n const score = scoreMul === \"\" ? \"fused._score\" : `(fused._score)${scoreMul}`;\n inner =\n `WITH sem AS (${semSql}), kw AS (${kwIn}), fused AS (` +\n `SELECT COALESCE(sem.id, kw.id) AS id, ` +\n `(COALESCE(1.0/(${K} + sem.r), 0) + COALESCE(1.0/(${K} + kw.r), 0))::float8 AS _score ` +\n `FROM sem FULL OUTER JOIN kw ON sem.id = kw.id) ` +\n `SELECT ${colList}, ${score} AS _score${hlCol}${kwnCol} FROM fused ` +\n `JOIN ${quoteTable(table)} t ON t.${quoteIdent(cfg.pk)} = fused.id`;\n } else {\n const single = semSql !== \"\" ? `sem AS (${semSql})` : `kw AS (${kwIn})`;\n const alias = semSql !== \"\" ? \"sem\" : \"kw\";\n const base = `(1.0/(${K} + ${alias}.r))::float8`;\n const score = scoreMul === \"\" ? base : `(${base})${scoreMul}`;\n inner =\n `WITH ${single} ` +\n `SELECT ${colList}, ${score} AS _score${hlCol}${semSql !== \"\" ? \"\" : kwnCol} FROM ${alias} ` +\n `JOIN ${quoteTable(table)} t ON t.${quoteIdent(cfg.pk)} = ${alias}.id`;\n }\n // Satır modu HER ZAMAN dış sorguyla sarılır: `can` yalnız burada, `q`\n // üzerinden seçilebilir (iç FROM'da pk taşıyan CTE'ler var — ham `using`\n // belirsizleşir); minScore'suz kısayol satırı can'siz bırakıyordu ve\n // foldCan `[]` uyduruyordu (W1 r1-r3). minScore süzmesi LIMIT'ten ÖNCE\n // (FR-001): süzülen satırın yeri alttakiyle dolar.\n const ms = msP === \"\" ? \"\" : ` WHERE q._score >= ${msP}`;\n return (\n `SELECT q.*${canOuter(table)} FROM (${inner}) q${ms} ` +\n `ORDER BY q._score DESC, q.${quoteIdent(cfg.pk)} LIMIT ${limit}`\n );\n };\n let rows = (await live.unsafe(assemble(kwSql, kwSql !== \"\"), bind)) as Row[];\n if (wantText && kwSql !== \"\" && (rows.length === 0 || (rows[0] as Record<string, unknown>)._kwn === 0)) {\n // FR-002: kelime kolu HİÇ aday bulamadı — aynı sorgu pg_trgm\n // word_similarity ile BİR kez daha denenir (yalnız bu 0-sonuç yolunda\n // +1 tur, NFR-A2). Exact-önce korunur: eşleşme varken trgm hiç koşmaz.\n // İfade, Go tarafının türev trgm index'iyle BİREBİR aynı (sorted\n // kolonlar) — index'i o ifade yakalar.\n const tsch = await trgmSchemaOf(live);\n const expr = ftsExprOf(cfg.ftsCols);\n const trgmKw =\n `SELECT t.${quoteIdent(cfg.pk)} AS id, ROW_NUMBER() OVER (ORDER BY ${quoteIdent(tsch)}.word_similarity(${qpRef}, ${expr}) DESC) AS r ` +\n `FROM ${quoteTable(table)} t WHERE ${quoteIdent(tsch)}.word_similarity(${qpRef}, ${expr}) > 0.3${whereSql} ORDER BY r LIMIT ${pool}`;\n // trgm kelime-benzerliği OR-sözdizimi tanımaz: retry aynı placeholder'ı\n // HAM query ile koşar (bind kopyası — kayıtlı ilk çağrı değişmez).\n const retryBind = bind.slice();\n if (qpIdx >= 0) retryBind[qpIdx] = params.query;\n rows = (await live.unsafe(assemble(trgmKw, false), retryBind)) as Row[];\n }\n for (const r of rows) delete (r as Record<string, unknown>)._kwn;\n // FR-015: dönüş tipi iki modda aynı şekildedir — satır-modunda blok\n // kavramı yoktur, tip uyumu boş diziyle sağlanır (spec kararı).\n const out = asTableRows(table, rows).map((r) => ({ ...r, blocks: [] as unknown[] }));\n logNoResults(table, params.query, params.mode, out.length);\n return out;\n },\n\n /**\n * similar (T018, FR-022): \"bu satıra benzeyenler\". Hedef vektör DB'den\n * okunur — satır-modu satırın kendi kolonu, chunk-modu parent chunk'larının\n * şema-nitelikli avg'ı — ve ana arama search'ün vector yoluyla koşar;\n * kaynak satır sonuçtan düşer. İKİ tur BİLİNÇLİ (plan T018): target-CTE'li\n * tek SQL'de \"id yok\" ile \"0 komşu\" ayrılamazdı; +1 küçük turla id-yokluğu\n * adlandırılmış hataya çevrilir. Sonuç şekli search ile aynı (FR-015).\n */\n /** D-021 (FR-027 DX): sayaçlar BAĞIMSIZ op'la — search'ün dizi-üstü\n * `_facets` özelliği JSON.stringify'da kaybolur (dizi özelliği), tenant\n * yanıtına koyunca sessizce yok olurdu. Ayrı dönüş ciddi bir sözleşmedir;\n * search'teki alan geriye-uyum için DURUR. where + validity default'u\n * sayaçlara da uygulanır (sayaç, kullanıcının gördüğü kümeyi anlatır). */\n async facets(\n table: string,\n params: { facets: string[]; where?: Record<string, unknown>; validity?: \"all\" | { asOf: string } },\n ): Promise<Record<string, { value: string | null; count: number }[]>> {\n const cfg = searchConfigFor(table);\n if (!cfg) {\n throw new Error(`facets(${table}): tablo aranabilir değil — search beyanı yok (FR-027)`);\n }\n for (const col of params.facets) {\n if (!cfg.colSet.has(col)) {\n throw new Error(`facets(${table}): facets kolonu \"${col}\" tabloda yok (FR-027)`);\n }\n }\n const live = await at();\n const extra = cfg.validity ? (add: (v: unknown) => string) => validitySql(params.validity, add) : () => \"\";\n return fetchFacets(live, table, cfg.colSet, params.facets, params.where ?? {}, extra);\n },\n\n async similar(\n table: string,\n id: string,\n opts: {\n where?: Record<string, unknown>;\n limit?: number;\n using?: string;\n minScore?: number;\n recency?: { field: string; halfLife: string };\n blocksPerRow?: number;\n validity?: \"all\" | { asOf: string };\n boost?: { field: string; weight: number };\n } = {},\n ): Promise<Row[]> {\n const cfg = searchConfigFor(table);\n if (!cfg) {\n throw new Error(`similar(${table}): tablo aranabilir değil — ne vector kolonu ne search beyanı var (FR-013)`);\n }\n const live = await at();\n let v: unknown;\n if (cfg.chunk !== undefined) {\n const sch = await vectorSchemaWithGuc(live);\n const rows = (await live.unsafe(\n `SELECT ${quoteIdent(sch)}.avg(c.embedding) AS v FROM ${quoteTable(cfg.chunk.table)} c ` +\n `WHERE c.${quoteIdent(`parent_${cfg.pk}`)} = $1 AND c.embedding IS NOT NULL`,\n [id],\n )) as { v?: unknown }[];\n v = rows?.[0]?.v;\n } else {\n const leg = pickLeg(table, cfg.legs, opts.using);\n if (leg === null) {\n throw new Error(`similar(${table}): tabloda vektör kolonu yok — benzerlik semantik vektör ister (FR-022)`);\n }\n const rows = (await live.unsafe(\n `SELECT t.${quoteIdent(leg.column)} AS v FROM ${quoteTable(table)} t WHERE t.${quoteIdent(cfg.pk)} = $1`,\n [id],\n )) as { v?: unknown }[];\n v = rows?.[0]?.v;\n }\n // Sürücü vector'ü text literal'i olarak verir (C-9); yokluk = satır yok\n // YA DA embedding NULL — ikisi de aynı adlandırılmış hata.\n if (typeof v !== \"string\") {\n throw new Error(`similar(${table}): id \"${String(id)}\" bulunamadı ya da embedding'i yok (FR-022)`);\n }\n const p = {\n vector: JSON.parse(v) as number[],\n mode: \"vector\" as const,\n where: opts.where,\n limit: opts.limit,\n using: opts.using,\n minScore: opts.minScore,\n recency: opts.recency,\n blocksPerRow: opts.blocksPerRow,\n validity: opts.validity,\n boost: opts.boost,\n __excludeIds: [id],\n };\n return ops.search(table, p);\n },\n\n /**\n * recommend (T018, FR-023): positive/negative id kümelerinden öneri.\n * Hedef vektör DB-İÇİ CTE'lerle türer: pos = avg(embedding of positives),\n * negative varsa hedef = pos.v + (pos.v - neg.v) — pgvector avg agregası\n * ve +/- operatörleri ŞEMA-NİTELİKLİ (M-1: search_path'e güvenilmez).\n * Vektör matematiği istemciye inmez; bulunamayan positive/negative\n * adlandırılmış hatadır ve kaynak id'ler sonuçtan düşer.\n */\n async recommend(\n table: string,\n opts: {\n positive: unknown[];\n negative?: unknown[];\n where?: Record<string, unknown>;\n limit?: number;\n using?: string;\n minScore?: number;\n recency?: { field: string; halfLife: string };\n blocksPerRow?: number;\n validity?: \"all\" | { asOf: string };\n boost?: { field: string; weight: number };\n },\n ): Promise<Row[]> {\n const positive = opts?.positive;\n if (!Array.isArray(positive) || positive.length === 0) {\n throw new Error(`recommend(${table}): positive boş olamaz — en az bir kaynak id gerekir (FR-023)`);\n }\n const negative = Array.isArray(opts.negative) ? opts.negative : [];\n const cfg = searchConfigFor(table);\n if (!cfg) {\n throw new Error(`recommend(${table}): tablo aranabilir değil — ne vector kolonu ne search beyanı var (FR-013)`);\n }\n let leg: SearchLeg | null = null;\n if (cfg.chunk === undefined) {\n leg = pickLeg(table, cfg.legs, opts.using);\n if (leg === null) {\n throw new Error(`recommend(${table}): tabloda vektör kolonu yok — öneri semantik vektör ister (FR-023)`);\n }\n }\n const live = await at();\n const sch = await vectorSchemaWithGuc(live);\n const bind: unknown[] = [];\n const add = (x: unknown): string => {\n bind.push(x);\n return `$${bind.length}`;\n };\n // id listesi AYRI placeholder'larla (where.in ile aynı gerekçe).\n const avgSel = (ids: unknown[]): string => {\n const inList = ids.map((x) => add(x)).join(\", \");\n return cfg.chunk !== undefined\n ? `SELECT ${quoteIdent(sch)}.avg(c.embedding) AS v FROM ${quoteTable(cfg.chunk.table)} c ` +\n `WHERE c.${quoteIdent(`parent_${cfg.pk}`)} IN (${inList}) AND c.embedding IS NOT NULL`\n : `SELECT ${quoteIdent(sch)}.avg(t.${quoteIdent(leg!.column)}) AS v FROM ${quoteTable(table)} t ` +\n `WHERE t.${quoteIdent(cfg.pk)} IN (${inList}) AND t.${quoteIdent(leg!.column)} IS NOT NULL`;\n };\n // pos/neg yokluğu bayrak olarak AYNI sorgudan döner: aritmetik DB'de\n // kalır, hata ayrımı için ek tur gerekmez.\n const targetSql =\n negative.length === 0\n ? `WITH pos AS (${avgSel(positive)}) SELECT pos.v AS v, (pos.v IS NULL) AS pos_missing FROM pos`\n : `WITH pos AS (${avgSel(positive)}), neg AS (${avgSel(negative)}) ` +\n `SELECT (pos.v OPERATOR(${quoteIdent(sch)}.+) (pos.v OPERATOR(${quoteIdent(sch)}.-) neg.v)) AS v, ` +\n `(pos.v IS NULL) AS pos_missing, (neg.v IS NULL) AS neg_missing FROM pos, neg`;\n const rows = (await live.unsafe(targetSql, bind)) as\n { v?: unknown; pos_missing?: unknown; neg_missing?: unknown }[];\n const r0 = rows?.[0];\n if (r0 === undefined || r0.pos_missing === true) {\n throw new Error(`recommend(${table}): positive id'lerin hiçbiri bulunamadı ya da embedding'i yok (FR-023)`);\n }\n if (negative.length > 0 && r0.neg_missing === true) {\n throw new Error(`recommend(${table}): negative id'leri bulunamadı ya da embedding'i yok (FR-023)`);\n }\n if (typeof r0.v !== \"string\") {\n throw new Error(`recommend(${table}): hedef vektör hesaplanamadı (FR-023)`);\n }\n const p = {\n vector: JSON.parse(r0.v) as number[],\n mode: \"vector\" as const,\n where: opts.where,\n limit: opts.limit,\n using: opts.using,\n minScore: opts.minScore,\n recency: opts.recency,\n blocksPerRow: opts.blocksPerRow,\n validity: opts.validity,\n boost: opts.boost,\n __excludeIds: [...positive, ...negative],\n };\n return ops.search(table, p);\n },\n\n /**\n * supersede (T021, FR-029, C-9): validity'li tabloda satırın YENİ\n * versiyonunu TEK savepoint'te yazar — eski satır kapatılır\n * (valid_to = now(), superseded_by = yeni pk), yeni satır eklenir, dönüş\n * yeni satırdır. Yeni pk CLIENT'ta üretilir (row'da verilmemişse\n * randomUUID — declared şemaların uuid().defaultRandom() standardı) ki\n * kapatma UPDATE'i INSERT'ten ÖNCE koşabilsin: 0 satır = zaten superseded\n * ya da yok → INSERT hiç denenmez; INSERT hatası ise savepoint'le\n * kapatmayı da geri sarar — yarım supersede diye bir durum yoktur.\n */\n async supersede(table: string, id: string, row: Row): Promise<Row> {\n // `supersede` eski satırın `valid_to`/`superseded_by` alanlarını YAZAR —\n // yani append-only bir tabloda yasak olan şeyin ta kendisi.\n assertNotAppendOnly(\"supersede\", table);\n const cfg = searchConfigFor(table);\n if (cfg === null || cfg.validity !== true) {\n throw new Error(`supersede(${table}): tablo validity beyanı taşımıyor (FR-029)`);\n }\n const live = await at();\n return live.savepoint(async (sp) => {\n const newId = row[cfg.pk] ?? crypto.randomUUID();\n const closed = (await sp.unsafe(\n `UPDATE ${quoteTable(table)} SET \"valid_to\" = now(), \"superseded_by\" = $1 ` +\n `WHERE ${quoteIdent(cfg.pk)} = $2 AND \"valid_to\" IS NULL RETURNING ${quoteIdent(cfg.pk)}`,\n [newId, id],\n )) as Row[];\n if (closed.length === 0) {\n throw new Error(`supersede(${table}): id \"${String(id)}\" zaten superseded ya da yok (FR-029)`);\n }\n const data = { ...row, [cfg.pk]: newId };\n const cols = Object.keys(data);\n const params: unknown[] = [];\n const add = (v: unknown): string => `$${params.push(v)}`;\n const tuple = buildValueTuple(table, cols, data, add, \"supersede\");\n const rows = (await sp.unsafe(\n `INSERT INTO ${quoteTable(table)} (${cols.map(quoteIdent).join(\", \")}) ` +\n `VALUES (${tuple}) RETURNING ${rowProjection(table)}`,\n params,\n )) as Row[];\n if (!rows[0]) {\n throw new Error(\n `supersede(${table}): INSERT satır döndürmedi — yazma reddedildi (büyük olasılıkla bir RLS policy'si)`,\n );\n }\n return asTableRow(table, rows[0]);\n });\n },\n\n /** A real SAVEPOINT inside the request's transaction. */\n async transaction<T>(cb: (t: unknown) => Promise<T>): Promise<T> {\n const live = await at();\n return live.savepoint(async (sp) => cb(withTables(createOps(sp, context), currentSchema)));\n },\n\n /**\n * Run `fn` against a handle bound to a SAVEPOINT, so a failure inside it\n * rolls back only what that handle wrote and the request can keep writing.\n *\n * WHY THE HANDLE IS AN ARGUMENT. The obvious shape — `attempt(async () => {\n * ... Database.$insert(...) ... })`, with no parameter — would have to point\n * the ambient `Database` at the savepoint for the duration, and a request is\n * concurrent with itself: `Promise.all([Database.$insert(a),\n * Database.$attempt(...)])` would put `a` inside the savepoint and roll it\n * back with it. Silent data loss, and the same interleaving this file already\n * refuses for `asService()`. Passing the handle makes the boundary something\n * you can see in the code that crosses it.\n *\n * Postgres, not us: the savepoint is released on success and rolled back on\n * failure by the driver, so an aborted statement inside `fn` does not poison\n * the surrounding transaction.\n */\n async attempt<T>(fn: (tx: DBOps) => Promise<T>): Promise<T> {\n const live = await at();\n return live.savepoint(async (sp) => fn(withTables(createOps(sp, context), currentSchema) as DBOps));\n },\n\n /**\n * Execute a whole transaction plan — what `Database.$transaction(fn)` builds.\n *\n * WHY IT RUNS HERE. The platform used to carry a complete implementation\n * of this at `/internal-api/db/tx`, for tenant code that ran in an isolate\n * with no connection of its own. Running the plan there means running it on\n * a DIFFERENT connection: a transaction would not see the uncommitted\n * writes of the request that started it, and the two would hold separate\n * RLS bindings of the same identity. In this stack the tenant's code and\n * the connection share a process, so the plan runs on the request's own\n * transaction inside one SAVEPOINT — and that surface was removed on\n * 2026-08-15, once this was the last thing that could have called it.\n *\n * Until 2026-08-15 it ran NOWHERE: `runTxPlan` called `transport.txPlan` and\n * nothing here implemented it, so a live handler answered\n * \"transport.txPlan is not a function\" while every test that covered\n * transactions passed against a mock that did implement it.\n */\n async command(plan: TxPlanBody, options: CommandOptions = {}): Promise<TxPlanResponse> {\n if (options.mode !== undefined && ![\"auto\", \"compiled\", \"sequential\"].includes(options.mode)) throw new Error(\"command mode must be auto, compiled or sequential\");\n if (options.mode === \"sequential\") return ops.txPlan(plan);\n const compiled = context.commands ? compileCommand(plan) : { reason: \"the PostgreSQL command executor is not installed\" };\n if (\"reason\" in compiled) {\n if (options.mode === \"compiled\") throw new Error(`Command cannot compile: ${compiled.reason}. Use auto/sequential mode or installCommandExecutor at boot.`);\n return ops.txPlan(plan);\n }\n if (compiled.steps.length === 0 && !compiled.pipeline?.length) return { results: [] };\n if (compiled.pipeline) {\n return (await at()).savepoint(async sp => {\n // One connection preserves statement order and fresh statement\n // snapshots. A SQL guard aborts PostgreSQL before queued writes can\n // run. Drain EVERY query before ROLLBACK TO / connection reuse.\n const settled = await Promise.allSettled(compiled.pipeline!.map(statement => sp.unsafe(statement.sql, statement.params)));\n const failed = settled.find(result => result.status === \"rejected\");\n if (failed?.status === \"rejected\") {\n const error = failed.reason as { detail?: string };\n if (sqlstateOf(error) === SQLSTATE.commandGuardFailed && typeof error.detail === \"string\") {\n const detail = JSON.parse(error.detail) as { error_code?: string; slot?: number };\n if (detail.error_code === \"tx_guard_failed\" && Number.isInteger(detail.slot)) {\n throw Object.assign(new Error(\"Command expectation failed\"), detail);\n }\n }\n throw error;\n }\n return { results: settled.map((result, i) => {\n const rows = (result as PromiseFulfilledResult<{ rows: Row[] }[]>).value[0]!.rows;\n return { rows: asTableRows(plan.ops[i]!.table, rows), rows_affected: rows.length };\n }) };\n });\n }\n // Keep the request usable after a constraint error or timeout, just as\n // txPlan does. PostgreSQL errors retain the driver's diagnostics.\n const rows = await (await at()).savepoint(sp => sp.unsafe(\"SELECT palbase_runtime.command_v1($1::jsonb -> 'steps') AS result\", [{ steps: compiled.steps }])) as { result: TxPlanResponse & { error?: Record<string, unknown> } }[];\n const response = rows[0]!.result;\n if (response.error) throw Object.assign(new Error(response.error.error_code === \"tx_ref_unresolved\"\n ? \"Command reference has no source row/column; use expectOne before reading it\" : \"Command expectation failed\"), response.error);\n return { results: response.results.map((result, i) => ({ ...result, rows: asTableRows(plan.ops[i]!.table, result.rows) })) };\n },\n\n async txPlan(plan: TxPlanBody): Promise<TxPlanResponse> {\n const live = await at();\n // ONE savepoint for the whole plan: a failed expectation must undo the\n // transaction the author wrote, and nothing outside it.\n return live.savepoint(async (sp) => {\n const results: TxPlanOpResult[] = [];\n for (const op of plan.ops) {\n const rows = asTableRows(op.table, await runPlanOp(sp, op, results)) as typeof results[number][\"rows\"];\n const result: TxPlanOpResult = { rows, rows_affected: rows.length };\n results.push(result);\n assertGuard(op, result);\n }\n return { results };\n });\n },\n } satisfies DBOps & Record<string, unknown>;\n\n return ops;\n}\n\n/** The schema whose table names the typed `.tables` surface is built from —\n * and, per table, whose columns the vector transform reads. */\nlet currentSchema: {\n tables?: Record<string, { name?: string; columns?: Record<string, unknown>; policies?: PolicyDef[] }>;\n} = {};\n\nconst columnsMemo: SchemaMetadataCache<Set<string> | null> = new WeakMap();\nconst primaryMemo: SchemaMetadataCache<string | null> = new WeakMap();\nconst vectorMemo: SchemaMetadataCache<Set<string>> = new WeakMap();\nconst transformMemo: SchemaMetadataCache<ReturnType<typeof computeTransforms>> = new WeakMap();\nconst typeMemo: SchemaMetadataCache<Map<string, string | null>> = new WeakMap();\nconst timestampMemo: SchemaMetadataCache<boolean> = new WeakMap();\nconst projectionMemo: SchemaMetadataCache<Map<string, string>> = new WeakMap();\n\nfunction schemaColumns(table: string): Set<string> | null {\n return memoTable(columnsMemo, currentSchema, table, () => computeSchemaColumns(table));\n}\nfunction primaryKeyOf(table: string): string | null {\n return memoTable(primaryMemo, currentSchema, table, () => computePrimaryKey(table));\n}\nfunction vectorColumnsOf(schema: typeof currentSchema, table: string): Set<string> {\n return memoTable(vectorMemo, schema, table, () => computeVectorColumns(schema, table));\n}\nfunction transformsOf(schema: typeof currentSchema, table: string): ReturnType<typeof computeTransforms> {\n return memoTable(transformMemo, schema, table, () => computeTransforms(schema, table));\n}\nfunction columnTypeOf(table: string, col: string): string | null {\n const types = memoTable(typeMemo, currentSchema, table, () => new Map(\n [...schemaColumns(table) ?? []].map(c => [c, computeColumnType(table, c)]),\n ));\n return types.get(col) ?? null;\n}\n\n/**\n * Install the project's declarations. Called once at boot.\n *\n * It takes the SET, because a project declares one schema PER FILE. The tables\n * are flattened under this system's one key convention — `public` bare,\n * anything else `schema.table` — so the key the wire carries and the key the\n * runtime looks up are the same string. A second convention here would be a\n * second answer to \"which table is this\", and the answers would diverge on the\n * day one of them learned something.\n */\n/**\n * İlişki grafiği — `buildRelations`'ın TEK çıktısı, burada yeniden türetilmiyor.\n *\n * `buildRelations`'ın kendi yorumu tüketicilerini adlandırıyor: *\"the query\n * builder, the seed engine, the cross-boundary lock\"*. Sorgu derleyicisi o\n * listedeydi ve hiç bağlanmamıştı — yani her projenin `palbase-env.d.ts`'i\n * \"bu tablo şununla ilişkili\" diye bir vaat basıyor ve hiçbir okuma onu\n * kullanmıyordu. `has` o vaadi karşılıyor.\n *\n * Grafiği BURADA yeniden hesaplamak ikinci bir yorumcu olurdu ve aynı yorum onu\n * adıyla yasaklıyor; o yüzden `setSchema` `buildRelations`'ı çağırıp sonucu\n * saklıyor.\n */\nlet currentRelations: Map<string, Relation[]> = new Map();\n\nexport function setSchema(schemas: readonly unknown[]): void {\n // Yeni şema kurulumu yeni bir bağlanma demektir: vector extension'ının\n // şeması da yeniden çözülür (review I3 — iki DB'li süreçte bayat cache,\n // public↔extensions ikiliğini sessizce yanlış tarafa kilitlerdi).\n const tables: NonNullable<typeof currentSchema.tables> = Object.create(null);\n for (const entry of schemas) {\n const mod = entry as { default?: unknown } | undefined;\n const def = ((mod && \"default\" in mod ? mod.default : mod) ?? {}) as {\n name?: string;\n tables?: Record<string, { name?: string; columns?: Record<string, unknown> }>;\n };\n const schemaName = def.name ?? \"public\";\n for (const [key, table] of Object.entries(def.tables ?? {})) {\n tables[qualifiedTableKey(schemaName, table.name ?? key)] = table;\n }\n }\n // İlişki grafiği AYNI bildirimlerden, AYNI yazıcıyla. Bir bildirim hatalıysa\n // (iki `ownedByUser`, çakışan ilişki adı) `buildRelations` ADIYLA fırlatıyor;\n // şema kurulumunu o hatayla düşürmek doğru — yarım bir grafik, `has`'in\n // sessizce hiçbir satır döndürmesi demek olurdu.\n //\n // GİRDİ NORMALLEŞTİRİLİYOR ama HATA YUTULMUYOR. `setSchema` elle kurulmuş,\n // yarım şema nesneleriyle de çağrılabiliyor (testler, ve tablo adıyla\n // erişilen bildirilmemiş tablolar) — `tables`/`columns` eksik olabilir.\n // Eksik alanı boşa çevirmek \"ilişki yok\" demek, doğru. Ama bildirimin KENDİ\n // hatasını (iki `ownedByUser`, çakışan ilişki adı) yakalayıp yutmak yarım bir\n // grafik bırakırdı ve `has` sessizce hiçbir satır döndürürdü — o yüzden\n // try/catch YOK.\n const relations = buildRelations(\n schemas.map((entry) => {\n const mod = entry as { default?: unknown } | undefined;\n const def = ((mod && \"default\" in mod ? mod.default : mod) ?? {}) as Partial<SchemaDef>;\n const tables: Record<string, unknown> = Object.create(null);\n for (const [key, t] of Object.entries(def.tables ?? {})) {\n const table = (t ?? {}) as { name?: string; columns?: Record<string, unknown> };\n // Kolonlar da normalleştiriliyor: elle kurulmuş bir şemada bir kolon\n // düz `{}` olabiliyor ve `buildRelations` her kolonda `_def` bekliyor.\n // Boş bir `_def` \"bu kolonun yabancı anahtarı yok\" demek — doğru cevap.\n const columns: Record<string, unknown> = {};\n for (const [cname, c] of Object.entries(table.columns ?? {})) {\n const cd = (c ?? {}) as { _def?: unknown };\n columns[cname] = \"_def\" in cd ? cd : { ...cd, _def: cd };\n }\n tables[key] = { ...table, name: table.name ?? key, columns };\n }\n return { name: def.name ?? \"public\", tables } as unknown as SchemaDef;\n }),\n );\n // Install only after the complete declaration/relationship graph validates.\n for (const key of Object.keys(tables)) tables[key] = snapshotDeclaration(tables[key]!);\n currentSchema = Object.freeze({ tables: Object.freeze(tables) });\n currentRelations = relations;\n cachedVectorSchema = null;\n cachedTrgmSchema = null;\n}\n\n\n\n/**\n * Merge the typed `.tables` accessor onto a raw op surface.\n *\n * Mirrors what the pod runtime does, including the recursive application to the\n * transaction callback: without it `tx.tables.rooms.insert(...)` throws\n * \"Cannot read properties of undefined\".\n */\nconst tableNamespaces = new WeakMap<object, Map<string, Map<string, string>>>();\n\nexport function withTables<T extends ReturnType<typeof createOps>>(\n ops: T,\n schema: { tables?: Record<string, { name?: string }> } = currentSchema,\n): T & { tables: Record<string, unknown>; schema: (name: string) => { tables: Record<string, unknown> } } {\n let namespaces = tableNamespaces.get(schema);\n if (!namespaces) {\n namespaces = new Map();\n for (const key of Object.keys(schema.tables ?? {})) {\n const dot = key.indexOf(\".\");\n const name = dot === -1 ? \"public\" : key.slice(0, dot);\n const short = dot === -1 ? key : key.slice(dot + 1);\n if (!namespaces.has(name)) namespaces.set(name, new Map());\n namespaces.get(name)!.set(short, key);\n }\n if (Object.isFrozen(schema) && Object.isFrozen(schema.tables)) tableNamespaces.set(schema, namespaces);\n }\n // THE KEY IS WHAT TRAVELS, not `def.name`. A bare name cannot say which\n // schema it lives in, and two schemas may declare the same table name —\n // `public.invoices` and `billing.invoices` are different tables.\n const bind = (key: string): Record<string, unknown> => ({\n insert: (data: Row) => ops.insert(key, data),\n update: (id: string, data: Row) => ops.update(key, id, data),\n delete: (id: string) => ops.delete(key, id),\n findById: (id: string) => ops.findById(key, id),\n findUnique: (where: Row, opts?: { select?: readonly string[]; with?: Record<string, unknown> }) => ops.findUnique(key, where, opts),\n findMany: (query?: Row, opts?: FindManyOptions) => ops.findMany(key, query ?? {}, opts),\n page: (query?: Row, opts?: RawPageOptions) => ops.page(key, query ?? {}, opts),\n put: (q: { data: Row; onConflict: readonly string[] }) => ops.put(key, q.data, { onConflict: q.onConflict }),\n });\n\n // `Database.tables` is PUBLIC's, and only public's. One flat namespace would\n // make `tables.invoices` resolve by declaration order; the bare name is\n // always public's and everything else is asked for by schema.\n const surfaces = new Map<string, { tables: Record<string, unknown> }>();\n const schemaOf = (name: string): { tables: Record<string, unknown> } => {\n const cached = surfaces.get(name);\n if (cached) return cached;\n const names = namespaces!.get(name) ?? new Map<string, string>();\n const target: Record<string, unknown> = Object.create(null);\n const get = (key: string): unknown => {\n if (!Object.hasOwn(target, key) && names.has(key)) {\n Object.defineProperty(target, key, { value: bind(names.get(key)!), configurable: true, enumerable: true, writable: true });\n }\n return Reflect.get(target, key);\n };\n const tables = new Proxy(target, {\n get: (t, key, receiver) => typeof key === \"string\" ? get(key) : Reflect.get(t, key, receiver),\n has: (t, key) => (typeof key === \"string\" && names.has(key)) || Reflect.has(t, key),\n ownKeys: t => [...new Set([...names.keys(), ...Reflect.ownKeys(t)])],\n getOwnPropertyDescriptor: (t, key) => Reflect.getOwnPropertyDescriptor(t, key) ??\n (typeof key === \"string\" && names.has(key) ? { configurable: true, enumerable: true, get: () => get(key) } : undefined),\n preventExtensions: t => {\n for (const key of names.keys()) get(key);\n return Reflect.preventExtensions(t);\n },\n });\n const surface = { tables };\n // Arbitrary unknown schema names must not accumulate per request.\n if (namespaces!.has(name) || name === \"public\") surfaces.set(name, surface);\n return surface;\n };\n\n const base: Record<string, unknown> = Object.create(null);\n return Object.assign(base, ops, { tables: schemaOf(\"public\").tables, schema: schemaOf });\n}\n\n// ── the two identities one request may speak with ──────────────────────────\n\n/**\n * How long a statement on the SERVICE transaction may wait for a row lock.\n *\n * The bound exists because `asService()` runs in a SECOND transaction on a\n * SECOND connection (see {@link createRequestDatabase} for why it must). A\n * handler that writes a row through `Database.*` and then touches the same row\n * through `Database.$asService()` is waiting on a lock held by a transaction\n * that cannot commit until the handler returns — a wait that can never end.\n * Unbounded, that hangs the request AND holds two pool connections for as long\n * as the process lives; a few of those and the runtime stops answering at all.\n *\n * 5s, from the two numbers around it: a healthy contended write resolves in\n * milliseconds, and the edge cuts a tenant request at 60s\n * (v2/deploy/envoy/routes.yaml, the catch-all route).\n * So the failure arrives as a legible error at the caller instead of a 504 with\n * both connections still held.\n */\nconst SERVICE_LOCK_TIMEOUT = \"5s\";\n\n/** Postgres raises 25P02 for every statement after one failed inside the same\n * transaction: `current transaction is aborted, commands ignored until end of\n * transaction block`. True, and useless on its own — it names the SYMPTOM and\n * never the write that caused it, nor the fact that a request is one\n * transaction. */\nfunction isAbortedTransaction(e: unknown): boolean {\n const message = String((e as { message?: unknown } | null)?.message ?? \"\");\n return sqlstateOf(e) === \"25P02\" || /current transaction is aborted/i.test(message);\n}\n\n/**\n * The five-character SQLSTATE, wherever this driver put it.\n *\n * MEASURED, not assumed (local stack, real Postgres, 2026-08-30): Bun's\n * `PostgresError` puts its OWN code in `.code` — the string\n * `\"ERR_POSTGRES_SERVER_ERROR\"` — and the SQLSTATE in `.errno`. node-postgres\n * puts the SQLSTATE in `.code`. Every check below was written against `.code`\n * alone, and its unit test built an object shaped like node-postgres, so the\n * tests were green and NONE of these diagnostics ever fired in production.\n *\n * The shape decides: a SQLSTATE is five characters of [0-9A-Z]. Anything else\n * in `.code` is the driver naming its own error, and the answer is in `.errno`.\n */\n/**\n * A bulk write must carry an actual predicate.\n *\n * COUNTING THE FILTER'S KEYS IS NOT ENOUGH, and the gap was measured: an\n * operator object with no operators in it — `{ created_at: {} }` — has one key\n * and compiles to NOTHING, so `WHERE true` reached Postgres and the statement\n * became a whole-table write. The shape that produces it is ordinary:\n *\n * const where = { created_at: {} };\n * if (from) where.created_at.gte = from; // neither set on this request\n * if (to) where.created_at.lte = to;\n *\n * So the check reads what the COMPILER produced, not what the caller passed.\n */\nfunction assertHasPredicate(whereSql: string, op: string, table: string): void {\n if (whereSql.trim().length > 0) return;\n throw new Error(\n `${op}(${table}): the filter compiled to no condition, so this would have ` +\n `written EVERY row. An empty filter — or an operator object with no ` +\n `operators in it, like { col: {} } — is refused. Name a condition.`,\n );\n}\n\nfunction sqlstateOf(e: unknown): string | undefined {\n const err = e as { code?: unknown; errno?: unknown } | null;\n const isState = (v: unknown): v is string => typeof v === \"string\" && /^[0-9A-Z]{5}$/.test(v);\n if (isState(err?.code)) return err.code;\n if (isState(err?.errno)) return err.errno;\n if (typeof err?.errno === \"number\") {\n const asText = String(err.errno);\n if (isState(asText)) return asText;\n }\n return undefined;\n}\n\n/** Postgres raises 23503 when a foreign key has nothing to point at. */\nfunction isForeignKeyViolation(e: unknown): boolean {\n return sqlstateOf(e) === \"23503\";\n}\n\n/**\n * Postgres raises 23505 (unique_violation) when a write would duplicate a row.\n *\n * İKİ ŞEKLİ DE tanır, ve bu bir tercih değil zorunluluk: `wrapTx` her ifadeyi\n * `explain()`'den geçirip 23505'i `UniqueViolation`'a ÇEVİRİYOR (aşağıda), ve\n * `HttpError`'ın `code` alanı yok — dolayısıyla dönüşmüş hatada `sqlstateOf`\n * hiçbir zaman eşleşmiyordu. Ölçüldü (nihai inceleme C-1): üretim\n * kablolamasında `claim()`'in catch'i `{ inserted: false }` yerine 409\n * fırlatıyordu, yani FR-033'ün tamamı ölüydü. Testler kaçırdı çünkü ham bir\n * stand-in tx kurup `wrapTx`'i atlıyorlardı.\n */\nfunction isUniqueViolation(e: unknown): boolean {\n return sqlstateOf(e) === \"23505\" || UniqueViolation.is(e);\n}\n\n/**\n * The name of the unique constraint a 23505 names.\n *\n * The driver's own `constraint` field first — both pg and postgres.js copy it\n * straight out of the wire protocol's CONSTRAINT field, so it is the answer\n * whenever there is one. The message is the fallback, and the reason it is only\n * a fallback: it is prose, and prose is what this whole conversion exists to\n * stop anyone from matching on.\n *\n * \"\" when neither carries it. An empty name is the honest answer — the caller\n * sees it is not known — and it is still a typed 409, because whether the write\n * was a duplicate does not depend on knowing which constraint said so.\n */\nfunction constraintOf(e: unknown): string {\n const named = (e as { constraint?: unknown } | null)?.constraint;\n if (typeof named === \"string\" && named.length > 0) return named;\n const message = String((e as { message?: unknown } | null)?.message ?? \"\");\n return /violates unique constraint \"([^\"]+)\"/.exec(message)?.[1] ?? \"\";\n}\n\n/** Postgres raises 55P03 (lock_not_available) when `lock_timeout` fires. */\nfunction isLockTimeout(e: unknown): boolean {\n const message = String((e as { message?: unknown } | null)?.message ?? \"\");\n return sqlstateOf(e) === \"55P03\" || /lock timeout/i.test(message);\n}\n\n/**\n * Wrap a driver so a lock timeout says what actually happened.\n *\n * \"canceling statement due to lock timeout\" is true and useless: the author's\n * two surfaces are two transactions, which is the one thing the message cannot\n * tell them. Applied recursively through `savepoint`, so `transaction()` and\n * `txPlan` inside the service surface answer the same way.\n */\nfunction diagnosingDriver(sql: SqlDriver, surface: \"user\" | \"service\" = \"service\"): SqlDriver {\n const original = (e: unknown): string => String((e as { message?: unknown } | null)?.message ?? e);\n\n const explain = (e: unknown): unknown => {\n // A statement refused because an EARLIER one failed. The database names the\n // symptom; only this layer knows that a request is a single transaction and\n // that there is a way to keep writing.\n if (isAbortedTransaction(e)) {\n return new Error(\n \"This request cannot write any more: an earlier write in it failed, and a request runs in ONE \" +\n \"Postgres transaction, so every statement after the failure is refused. Nothing here is \" +\n \"retryable in place. Wrap a write you expect to fail in `Database.$attempt(async (tx) => …)` — \" +\n \"it takes a SAVEPOINT, so only that write rolls back — or use \" +\n \"`Database.public.<t>.upsert(data, { onConflict: [...] })` when the failure you were bracing \" +\n `for is a duplicate row. (${original(e)})`,\n );\n }\n // A duplicate row is the one database refusal an application ROUTINELY\n // expects, and until this branch existed the only way to act on it was to\n // match the driver's prose (\"duplicate key value violates unique\n // constraint …\") — a contract nobody signed, broken by a Postgres upgrade,\n // a locale, or a constraint rename, silently and in production. Typed here\n // instead: an HttpError, so an uncaught duplicate answers a generic 409\n // rather than 500 `internal_error`, and a caught one is branched on with\n // `e instanceof UniqueViolation && e.constraint === …`. The NAME rides the\n // object, not the response body — see `UniqueViolation` for whose it is.\n // Both surfaces convert: a duplicate is a duplicate whichever role wrote it.\n if (isUniqueViolation(e)) {\n return markEngineRaised(new UniqueViolation(constraintOf(e)));\n }\n // Eşzamanlılık hataları (FR-036). Aynı gerekçe: sürücünün düzyazısını\n // eşleştirmek imzalanmamış bir sözleşme. Buradaki fark, bu ikisinin\n // TEKRAR DENENEBİLİR olması — ve bunun tipte taşınması, retry sarmalayıcısının\n // neyi yeniden deneyeceğini TAHMİN etmemesini sağlıyor.\n const state = sqlstateOf(e);\n if (state === SQLSTATE.serializationFailure) return markEngineRaised(new SerializationFailure(state));\n if (state === SQLSTATE.deadlockDetected) return markEngineRaised(new DeadlockDetected(state));\n // PostgreSQL's statement timeout can beat the JS deadline timer. Both\n // races must remain an observable cancellation, never a generic 500 or an\n // automatic replay. SQLSTATE also covers operator-initiated cancellation.\n if (state === SQLSTATE.queryCancelled) return markEngineRaised(new HttpError(503, \"database_query_cancelled\", \"Database statement was cancelled\"));\n // A foreign key with nothing to point at, seen from the SERVICE surface, is\n // usually not a broken key: it is the row this request already wrote through\n // `Database.*`, which has not committed and which the service transaction\n // cannot see. On the user surface the same code is an ordinary data error and\n // is left exactly as Postgres wrote it.\n if (surface === \"service\" && isForeignKeyViolation(e)) {\n return new Error(\n \"Database.$asService() hit a foreign key with nothing to point at. It runs in its OWN \" +\n \"transaction on its OWN connection, so a row this request wrote through `Database.*` is not \" +\n \"visible to it until the request commits — and the request cannot commit until the handler \" +\n \"returns. If the row it needs is one this request just created, do both writes on ONE \" +\n `surface. (${original(e)})`,\n );\n }\n if (isLockTimeout(e)) {\n return new Error(\n \"Database.$asService() waited too long for a row lock. It runs in its OWN transaction, so a \" +\n \"row this request already wrote through Database.* is locked against it until the request \" +\n \"commits — a wait that cannot end. Do that row's work on one surface or the other. \" +\n `(${original(e)})`,\n );\n }\n return e;\n };\n\n const wrapTx = (tx: SqlTx): SqlTx => ({\n unsafe(text: string, params?: unknown[]) {\n try {\n const query = tx.unsafe(text, params) as CancellableQuery;\n const mapped = query.catch(e => { throw explain(e); }) as CancellableQuery;\n if (query.cancel) mapped.cancel = () => query.cancel!();\n return mapped;\n } catch (e) {\n return Promise.reject(explain(e));\n }\n },\n savepoint<T>(cb: (sp: SqlTx) => Promise<T>) {\n return tx.savepoint((sp) => cb(wrapTx(sp)));\n },\n });\n\n return {\n admission: sql.admission ?? databaseAdmission(sql),\n unsafe: (text: string, params?: unknown[]) => sql.unsafe(text, params),\n cancelBackend: sql.cancelBackend?.bind(sql),\n begin: <T>(cb: (tx: SqlTx) => Promise<T>) => sql.begin((tx) => cb(wrapTx(tx))).catch((e: unknown) => { throw explain(e); }),\n };\n}\n\n/** The two transactions a request may hold, and the single `Database` over them. */\nexport interface RequestDatabase {\n /** What the engine injects as the request's `Database` singleton. */\n readonly client: DBClient;\n /** @internal Core has finished its read-only authorization queries. */\n authorizationComplete?(): void;\n /** Commit whatever was opened. Called once, after the handler returns. */\n commit(): Promise<void>;\n /** Roll back whatever was opened. Called once, when the handler throws. */\n rollback(reason: unknown): Promise<void>;\n}\n\n/**\n * The `Database` one request sees: RLS-enforced by default, with the\n * service-role sibling behind `asService()`.\n *\n * # Why the sibling cannot ride the request's own transaction\n *\n * The role reaches Postgres ONCE, in the BEGIN's bind statement, and it is\n * transaction-scoped. So a sibling built on the same transaction runs as\n * `backend_authenticated` no matter what it is called — RLS still filters every\n * row and `asService()` silently means nothing. That is the failure mode worth\n * naming: it does not throw, it does not log, it simply returns the caller's own\n * rows where the author asked for everyone's, and a handler that trusts it\n * (`if (existing) throw new Conflict()`) makes the wrong decision on data it was\n * never shown.\n *\n * The obvious repair — re-issue `set_config('role', …)` around each service op\n * — is worse than the bug. Two statements are not one: `Promise.all([\n * Database.$query(…), Database.$asService().$query(…) ])` interleaves them on the\n * single connection, and the user's query can execute between the service's\n * set-role and its own statement. That is RLS silently OFF on the DEFAULT path,\n * which is precisely the direction a security seam must never fail.\n *\n * So the service surface gets its own transaction, on its own connection, bound\n * to the service role at BEGIN. The identity separation is physical: no\n * statement of either surface can change what the other runs as.\n *\n * # What that costs, stated plainly\n *\n * - **One extra connection per request that uses it**, and only then: the second\n * transaction is lazy exactly like the first, so `asService()` called and\n * never used opens nothing.\n * - **Called twice, it is the same surface** — one transaction per REQUEST, not\n * per call — so a handler cannot leak connections by reaching for it in a\n * loop.\n * - **The two are not atomic with each other.** Both settle with the request\n * (commit when the handler returns, roll back when it throws), but they settle\n * as two transactions: if the second COMMIT fails, the first has already\n * landed. The request's own work commits first, so the failure that survives\n * is never \"the audit row exists and the thing it audits does not\".\n * - **They can wait on each other's locks.** Bounded in the service direction by\n * {@link SERVICE_LOCK_TIMEOUT}; in the other direction — a `Database.*` write\n * to a row `asService()` has already written — the wait is the request's own,\n * and the answer is not to write one row from both surfaces.\n *\n * # Claims travel unchanged\n *\n * The service transaction carries the SAME `request.jwt.claims` as the user's.\n * `asService()` changes what the caller may TOUCH, not who they are, so\n * `auth.uid()` still resolves inside a trigger or a column default. It is also\n * the fail-closed direction: a service role provisioned WITHOUT `BYPASSRLS`\n * (measured live on 2026-08-13, created by hand during a diagnosis) is not named\n * by any policy, so it reads zero rows instead of quietly reading everyone's.\n */\nexport function createRequestDatabase(\n sql: SqlDriver,\n identity: { role: string; serviceRole: string; claimsJson: string },\n diagnostics?: DatabaseDiagnosticsOptions,\n signal?: AbortSignal,\n): RequestDatabase {\n const trace = diagnostics === undefined ? undefined : new DatabaseTrace(diagnostics);\n const requestControl = signal === undefined ? undefined : new TransactionControl(undefined, signal);\n let requestClosed = false;\n let authorized = false, applicationTouched = false;\n let authorizationRelease: Promise<void> | undefined;\n const contextFor = (role: string): OpsContext => {\n let scope: string | undefined;\n return { trace, get cursorScope() { return scope ??= cursorIdentity(role, identity.claimsJson); }, get commands() { return hasCommandExecutor(sql); } };\n };\n const userContext = contextFor(identity.role);\n const serviceContext = contextFor(identity.serviceRole);\n const atomic = (role: string, surface: \"user\" | \"service\") => async <T>(\n fn: (client: AtomicClient) => Promise<T>, options: AtomicOptions = {},\n ): Promise<T> => {\n validateAtomicOptions(options);\n if (requestClosed) throw new Error(\"Database request has settled; it cannot open another transaction\");\n if (atomicScope.getStore() !== undefined) throw new Error(\"Nested Database.$atomic is not supported; use tx.$attempt for a savepoint\");\n // @User/permission checks may have opened the implicit request transaction.\n // If no application SQL has run, release those read-only core checks before\n // waiting for an independent atomic connection. Otherwise a full pool can\n // consist entirely of requests waiting for a second connection.\n if (authorized && !applicationTouched && tx.opened) {\n authorizationRelease ??= (async () => { await tx.commit(); tx = requestTransaction(); })();\n }\n if (authorizationRelease) await authorizationRelease;\n const retries = retryBudget(options.retry);\n const atomicSignal = options.signal && signal ? AbortSignal.any([options.signal, signal]) : options.signal ?? signal;\n const control = options.timeoutMs !== undefined || atomicSignal !== undefined ? new TransactionControl(options.timeoutMs, atomicSignal) : undefined;\n try {\n control?.check();\n for (let attempt = 0; ; attempt++) {\n control?.check();\n const timeouts = [options.statementTimeoutMs, control?.remainingMs()].filter((n): n is number => n !== undefined);\n const scope = Symbol(\"atomic transaction\");\n const root = createLazyTransaction(diagnosingDriver(sql, surface), role, identity.claimsJson, {\n scope, isolation: options.isolation, readOnly: options.readOnly, control, trace,\n lockTimeout: `${options.lockTimeoutMs ?? 5000}ms`,\n statementTimeout: timeouts.length === 0 ? undefined : `${Math.min(...timeouts)}ms`,\n });\n try {\n const callback = atomicScope.run(scope, () => fn(withTables(createOps(root, surface === \"user\" ? userContext : serviceContext))));\n const value = await (control ? control.race(callback) : callback);\n control?.check();\n await root.commit();\n return value;\n } catch (error) {\n await root.rollback(error);\n if (attempt >= retries || !isRetryable(error)) throw error;\n trace?.retry();\n const delay = new Promise<void>((resolve) => setTimeout(resolve, Math.min(100, 2 ** attempt)));\n await (control ? control.race(delay) : delay);\n }\n }\n } finally {\n control?.dispose();\n }\n };\n const requestTransaction = () => createLazyTransaction(diagnosingDriver(sql, \"user\"), identity.role, identity.claimsJson, { trace, control: requestControl });\n let tx = requestTransaction();\n\n // Opened on FIRST use and shared by every later `asService()` call.\n let serviceTx: LazyTransaction | null = null;\n let serviceControl: TransactionControl | undefined;\n let serviceClient: Omit<DBClient, \"asService\"> | null = null;\n\n const asService = (): Omit<DBClient, \"asService\"> => {\n if (serviceClient === null) {\n serviceControl = signal === undefined ? undefined : new TransactionControl(undefined, signal);\n serviceTx = createLazyTransaction(\n diagnosingDriver(sql, \"service\"),\n identity.serviceRole,\n identity.claimsJson,\n { lockTimeout: SERVICE_LOCK_TIMEOUT, trace, control: serviceControl },\n );\n // No `asService` on it: the type says `Omit<DBClient, \"asService\">` and so\n // does the object, so a second bypass is neither typeable nor callable.\n serviceClient = Object.assign(withTables(createOps(serviceTx, serviceContext)), { atomic: atomic(identity.serviceRole, \"service\") });\n }\n return serviceClient;\n };\n\n return {\n client: Object.assign(withTables(createOps(() => {\n if (authorized) applicationTouched = true;\n return authorizationRelease ? authorizationRelease.then(() => tx) : tx;\n }, userContext)), { asService, atomic: atomic(identity.role, \"user\") }),\n authorizationComplete() { authorized = true; },\n async commit(): Promise<void> {\n requestClosed = true;\n // The request's declared work first; see \"not atomic with each other\".\n try { await tx.commit(); await serviceTx?.commit(); trace?.complete(\"committed\"); requestControl?.dispose(); serviceControl?.dispose(); }\n catch (error) { trace?.failed(); throw error; }\n },\n async rollback(reason: unknown): Promise<void> {\n requestClosed = true;\n await tx.rollback(reason);\n await serviceTx?.rollback(reason);\n requestControl?.dispose();\n serviceControl?.dispose();\n trace?.complete(\"failed\");\n },\n };\n}\n\n\n// ── the transaction plan executor ──────────────────────────────────────────\n//\n// The plan is a closed little language: five op kinds, equality-only filters,\n// and three value forms (a literal, a `$ref` to an earlier op's row, an\n// `$expr`). It is built by `TxPlanBuilder` in this same package, so the\n// executor's job is to run it faithfully rather than to defend against it —\n// with one exception that still matters: identifiers reach SQL as text, so\n// every table and column name goes through `quoteIdent`, exactly as the six\n// single-statement ops above do.\n\n/** Collects bound parameters so a value is never spliced into SQL text. */\nclass Args {\n readonly values: unknown[] = [];\n readonly columns: { column?: string; table?: string }[] = [];\n bind(value: unknown, column?: string, table?: string): string {\n this.values.push(value);\n this.columns.push({ column, table });\n return `$${this.values.length}`;\n }\n}\n\n/**\n * Plan referansı mı — ŞEKLE değil MARKAYA bakarak.\n *\n * `\"$ref\" in v` yeterliydi ve `$ref` bu dilin markasız kalan TEK işaretçisiydi.\n * Ölçüldü (gözcü): istek gövdesinden gelen `{\"id\":{\"$ref\":{\"op\":0,\"field\":\"id\"}}}`\n * filtreyi ÖNCEKİ bir işlemin satır değeriyle karşılaştırtıyordu — gövdenin hiç\n * görmediği bir değer. Enjeksiyon değil (değerler bound) ama bir ORACLE:\n * `op`/`field` seçip `rows_affected`'tan o değeri öğrenmek. `col()` ve\n * `sqlFragment` aynı sebeple markalanmıştı; bu üçüncüsü.\n */\nfunction isRef(v: unknown): v is TxWireRef {\n return isPlanRef(v);\n}\n\n/**\n * Çözülemeyen bir referansın mesajı — ve İKİ AYRI DURUMU ayırıyor.\n *\n * Eskiden ikisi de `op 7 has no column \"id\" to reference` diyordu, 7 numaralı\n * işlem HİÇ YOKKEN bile. Yazar var olmayan bir op'un kolonlarını aramaya\n * gidiyordu (gözcü M-2). Komşu mesajlar tabloyu adlandırırken bu adlandırmıyordu\n * da.\n */\nfunction refUnresolvedMessage(\n ref: { op: number; field: string },\n results: TxPlanOpResult[],\n): string {\n if (ref.op < 0 || ref.op >= results.length) {\n return (\n `transaction plan: referans ${ref.op} numaralı işleme bakıyor ama planda ` +\n `${results.length} işlem var (0…${results.length - 1}). Referans yalnız KENDİNDEN ` +\n `ÖNCEKİ bir işlemin satırına bakabilir.`\n );\n }\n const row = results[ref.op]?.rows[0];\n if (!row) {\n return (\n `transaction plan: ${ref.op} numaralı işlem HİÇ SATIR döndürmedi, o yüzden ` +\n `\"${ref.field}\" okunamıyor. Bir referans okunacak satırın var olduğunu garanti ` +\n `etmez — önce beklentiyi bildirin (\\`.expectOne(err)\\`).`\n );\n }\n return (\n `transaction plan: ${ref.op} numaralı işlemin satırında \"${ref.field}\" kolonu yok ` +\n `(dönen kolonlar: ${Object.keys(row).join(\", \")}).`\n );\n}\n\n/** Markasız bir `{ $ref: … }` taklidi ADIYLA reddedilir — sessizce DEĞER olarak\n * bağlanması, filtrenin sessizce yanlış olması demekti. */\nfunction refuseUnbrandedRef(v: unknown, where: string): void {\n if (looksLikeUnbrandedPlanRef(v)) {\n throw new Error(\n `${where}: bir plan referansı TAKLİDİ aldı ({ $ref: … }) — bu nesne bu planın ` +\n `builder'ı tarafından üretilmemiş. Referans yalnız kendi kodunuzda, önceki bir ` +\n `işlemin satırından okunarak kurulur (ör. insert(...).expectOne(err).id); ` +\n `istek gövdesinden gelen bir filtre referans TAŞIYAMAZ.`,\n );\n }\n}\nfunction isExpr(v: unknown): v is TxWireExpr {\n return typeof v === \"object\" && v !== null && \"$expr\" in v;\n}\n\n/**\n * Render one value into SQL, binding whatever is data.\n *\n * `column` is only used by `inc`/`dec`, which read the column they write.\n */\nfunction renderValue(\n value: TxWireValue,\n column: string,\n args: Args,\n results: TxPlanOpResult[],\n vectorCols?: Set<string>,\n transforms?: ReturnType<typeof transformsOf>,\n): string {\n // DEĞER tarafında da marka aranıyor, ve burada bahis daha yüksek: sahte bir\n // referans filtreyi yanıltmakla kalmaz, BAŞKA BİR SATIRIN değerini yazdırır.\n refuseUnbrandedRef(value, `transaction plan (${column})`);\n if (isRef(value)) {\n const source = results[value.$ref.op];\n const row = source?.rows[0];\n if (!row || !(value.$ref.field in row)) {\n throw Object.assign(new Error(refUnresolvedMessage(value.$ref, results)), {\n error_code: \"tx_ref_unresolved\",\n });\n }\n return bindMaybeVector(args, column, vectorCols, row[value.$ref.field], transforms);\n }\n if (isExpr(value)) {\n const fn = value.$expr;\n if (fn.fn === \"now\") return \"now()\";\n const operator = fn.fn === \"inc\" ? \"+\" : \"-\";\n // The column is an identifier; the operand is BOUND. This is the one place\n // the tenant's digits could otherwise have reached SQL text.\n return `${quoteIdent(column)} ${operator} ${bindMaybeVector(args, column, vectorCols, fn.by, transforms)}`;\n }\n return bindMaybeVector(args, column, vectorCols, value, transforms);\n}\n\n/**\n * Resolve every `$ref` handle inside a plan filter, in place-free fashion.\n *\n * Refs point at a column of an EARLIER operation's returned row. They have to\n * become ordinary values BEFORE the filter is compiled, because the compiler\n * below is the SAME one `findMany` uses and it knows nothing about plans — and\n * that sameness is the whole point (see {@link renderWhere}).\n *\n * Recursive, because the filter language has composition: a ref can sit inside\n * `OR`/`AND`/`NOT` or on the right of an operator.\n */\nfunction resolveRefsDeep(value: unknown, results: TxPlanOpResult[]): unknown {\n refuseUnbrandedRef(value, \"transaction plan filtresi\");\n if (isRef(value)) {\n const source = results[value.$ref.op];\n const row = source?.rows[0];\n if (!row || !(value.$ref.field in row)) {\n throw Object.assign(\n new Error(refUnresolvedMessage(value.$ref, results)),\n { error_code: \"tx_ref_unresolved\" },\n );\n }\n return row[value.$ref.field];\n }\n if (Array.isArray(value)) return value.map((v) => resolveRefsDeep(v, results));\n // İşaretçiler ve ifade tutamakları OLDUĞU GİBİ geçer: `col()` bir kolon\n // referansı, `sqlFragment` bir parça, ve derleyici ikisini de kendi tanıyor.\n if (value !== null && typeof value === \"object\" && !isColRef(value) && !isSqlFragment(value) && !isExpr(value) && !(value instanceof Date)) {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n out[k] = resolveRefsDeep(v, results);\n }\n return out;\n }\n return value;\n}\n\n/**\n * Render a plan operation's WHERE clause — with `findMany`'s COMPILER.\n *\n * BU FONKSİYON BİR ZAMANLAR KENDİ DERLEYİCİSİYDİ, ve ayrı olması iki şeye mal\n * oluyordu:\n *\n * 1. SESSİZ YANLIŞ SORGU. `{ balance: { gte: \"5.00\" } }` nesnenin KENDİSİNİ\n * parametre olarak bağlıyordu — `WHERE \"balance\" = $1`, `$1={\"gte\":…}` —\n * yani hiçbir satır, hatasız (gözcü ölçtü).\n * 2. İKİ FİLTRE DİLİ. FR-014'ün amiral deseni `$transaction` İÇİNDE\n * yazılamıyordu: koşullu bir yazmayı plana koyamayan yazar `$query`'ye\n * düşüyordu — tam olarak bu yüzeyin kapatmak için var olduğu düşüş.\n *\n * Artık TEK derleyici var. Plan ifadeleri `t` takma adını taşıyor (aşağıdaki\n * `AS t` / `FROM … t`), çünkü `compileWhereBare` her kolonu onunla niteliyor —\n * `findMany`'nin ürettiği SQL'le aynı şekli üretmek, aynı derleyiciyi\n * kullanmanın bedeli değil, ispatı.\n */\nfunction renderWhere(\n table: string,\n where: Record<string, TxWireValue> | undefined,\n args: Args,\n results: TxPlanOpResult[],\n): string {\n return planWhere(table, where, args, results).sql;\n}\n\n/** {@link renderWhere}'in ÇÖZÜLMÜŞ filtreyi de veren hâli — kilit sırası kararı\n * (FR-015) `$ref`'ler çözüldükten SONRAKİ şekle bakmak zorunda. */\nfunction planWhere(\n table: string,\n where: Record<string, TxWireValue> | undefined,\n args: Args,\n results: TxPlanOpResult[],\n): { sql: string; resolved: Record<string, unknown> } {\n if (where === undefined || Object.keys(where).length === 0) {\n return { sql: \"\", resolved: {} };\n }\n const resolved = resolveRefsDeep(where, results) as Record<string, unknown>;\n const known = schemaColumns(table);\n const bare = compileWhereBare(table, known, resolved, (v, column, from) => args.bind(v, column, from), \"transaction plan\");\n return { sql: bare === \"\" ? \"\" : ` AND ${bare}`, resolved };\n}\n\n/** tx-plan bind'i (FR-008, review C2): vektör kolonuna giden number[] literal'e\n * çevrilir — düz op'lardaki asBindParams'ın plan-yolu ikizi. */\nfunction bindMaybeVector(\n args: { bind(v: unknown, column?: string): string },\n column: string | undefined,\n vectorCols: Set<string> | undefined,\n value: unknown,\n transforms?: ReturnType<typeof transformsOf>,\n): string {\n if (column !== undefined && vectorCols?.has(column) && Array.isArray(value)) {\n return args.bind(toVectorLiteral(value as number[]), column);\n }\n // The column's `toDb`, exactly as `asBindParams` applies it on the direct\n // path. Without it the SAME value is stored differently depending on which\n // surface wrote it — `tables.x.insert({ amount: 12.5 })` writes \"12.5\" and\n // `tx.tables.x.insert({ amount: 12.5 })` writes 12.5 — and the caller cannot\n // tell them apart, because both take the transform's target type.\n const t = column !== undefined ? transforms?.get(column) : undefined;\n if (t?.toDb !== undefined && value !== null && value !== undefined) {\n return args.bind(t.toDb(value), column);\n }\n return args.bind(value, column);\n}\n\nfunction compilePlanOp(\n op: TxWireOp,\n results: TxPlanOpResult[],\n): { sql: string; params: unknown[]; columns: { column?: string; table?: string }[] } | null {\n const opVectorCols = vectorColumnsOf(currentSchema, op.table);\n const opTransforms = transformsOf(currentSchema, op.table);\n const args = new Args();\n // `quoteTable`, `quoteIdent` DEĞİL — ve fark bu yolda ÖLÇÜLDÜ:\n // `quoteIdent(\"billing.invoices\")` → `\"billing.invoices\"`, yani ADINDA NOKTA\n // OLAN bir public tablo. Postgres'in anladığı şey o değil. Sonuç: `billing`\n // şemasındaki iki tabloyu tek atomik planda yazmak imkânsızdı ve yazar\n // `$query`'ye düşüyordu — bu yüzeyin kapatmak için var olduğu düşüş.\n // Doğrudan yolun her operasyonu zaten `quoteTable` kullanıyor; plan yolu\n // ondan ayrışmıştı.\n const table = quoteTable(op.table);\n let sql: string;\n\n switch (op.op) {\n case \"insert\": {\n const cols = Object.keys(op.values ?? {});\n const rendered = cols.map((c) => renderValue((op.values as Record<string, TxWireValue>)[c], c, args, results, opVectorCols, opTransforms));\n sql = cols.length\n ? `INSERT INTO ${table} (${cols.map(quoteIdent).join(\", \")}) VALUES (${rendered.join(\", \")}) RETURNING ${rowProjection(op.table)}`\n : `INSERT INTO ${table} DEFAULT VALUES RETURNING ${rowProjection(op.table)}`;\n break;\n }\n case \"upsert\": {\n // `put` bir UPDATE dalı taşıyor — append-only tabloda yasak.\n assertNotAppendOnly(\"put\", op.table);\n const cols = Object.keys(op.values ?? {});\n const conflict = op.onConflict ?? [];\n if (cols.length === 0 || conflict.length === 0) {\n throw Object.assign(new Error(`upsert on ${op.table} needs columns and onConflict`), {\n error_code: \"tx_bad_upsert\",\n });\n }\n const rendered = cols.map((c) =>\n renderValue((op.values as Record<string, TxWireValue>)[c], c, args, results, opVectorCols, opTransforms),\n );\n sql =\n `INSERT INTO ${table} (${cols.map(quoteIdent).join(\", \")}) VALUES (${rendered.join(\", \")}) ` +\n `${onConflictTail(cols, conflict, \"update\")} RETURNING ${rowProjection(op.table)}`;\n break;\n }\n case \"insertMany\": {\n const rows = (op.rows ?? []) as Record<string, TxWireValue>[];\n if (rows.length === 0 || !rows[0]) return null;\n // The column list comes from the FIRST row and every row is rendered\n // against it, so a row with a stray extra key cannot shift the columns of\n // the statement it shares.\n const cols = Object.keys(rows[0]);\n const tuples = rows.map(\n (r) => `(${cols.map((c) => renderValue(r[c], c, args, results, opVectorCols, opTransforms)).join(\", \")})`,\n );\n // ON CONFLICT only when the plan asked for it: an insertMany with no\n // options must render byte-identically to what it rendered before the\n // option existed.\n //\n // DO NOTHING and RETURNING: Postgres returns only the rows it WROTE, so a\n // collided row is simply absent from the result. That is the contract the\n // caller is told about, not a rough edge.\n const conflictCols = op.onConflict ?? [];\n const tail =\n op.action !== undefined && conflictCols.length > 0\n ? ` ${onConflictTail(cols, conflictCols, op.action)}`\n : \"\";\n sql = `INSERT INTO ${table} (${cols.map(quoteIdent).join(\", \")}) VALUES ${tuples.join(\", \")}${tail} RETURNING ${rowProjection(op.table)}`;\n break;\n }\n case \"update\": {\n // Tip kapısı `TxTable`'a uygulanmıyor, motor da bu dalda susuyordu:\n // `tx.tables.entries.updateWhere({id}, {amount:\"0\"})` derleniyor VE\n // koşuyordu (inceleme C-4). Muhasebe kaydında \"TypeScript'ten\n // yazılamaz\" yeterli değil.\n assertNotAppendOnly(\"updateWhere\", op.table);\n const cols = Object.keys(op.set ?? {});\n if (cols.length === 0) throw new Error(`update ${op.table}: nothing to set`);\n const knownSet = schemaColumns(op.table);\n for (const c of cols) {\n if (knownSet !== null && !knownSet.has(c)) {\n throw new Error(`transaction plan (${op.table}): set kolonu \"${c}\" tabloda yok`);\n }\n }\n const assignments = cols.map(\n (c) => `${quoteIdent(c)} = ${renderValue((op.set as Record<string, TxWireValue>)[c], c, args, results, opVectorCols, opTransforms)}`,\n );\n // KİLİT SIRASI PLAN YOLUNDA DA (FR-015).\n //\n // `updateMany` çok satıra dokunduğunda kilitleri PK sırasında alsın diye\n // CTE'ye derleniyor; gerekçesi DOĞRUDAN yolda ölçülmüştü (T013: ters\n // sıralı iki oturumda düz form 12/12 deadlock, CTE 0/12). Plan yolu aynı\n // işi yapıyor ama düz UPDATE üretiyordu.\n //\n // BOŞLUK BU FİLTRE GENİŞLEMESİNDEN ÖNCE DE VARDI: eski `TxWhere` de\n // eşitliği HERHANGİ bir kolonda kabul ediyordu (`updateWhere({ done:\n // false }, …)` benzersiz olmayan bir kolon, yani çok satır) ve o günkü\n // `runPlanOp`'ta da CTE yoktu. Genişleme sınıfı YARATMADI, SIKLIĞINI\n // artırdı: FR-014'ün amiral deseni korumasız yolda idiomatik hâle geldi.\n //\n // VE BU YOLDA DEADLOCK ÜRETİLDİ — çıkarım değil (gözcü, canlı pg16,\n // 30 satırlık tablo, iki oturum ters plan sırasına zorlanmış, satır\n // başına 10 ms uyku ile kilit penceresi açılmış, deadlock_timeout 100ms):\n // (A) düz UPDATE … WHERE balance >= … → 7 deadlock / 100 transaction\n // (B) WITH locked … ORDER BY id FOR NO KEY UPDATE → 0 / 120\n // (B)'de tek bir hata bile yok; oturumlar deadlock yerine SIRAYA giriyor.\n // Bedeli bekleme, ve bu kabul edilmiş takas.\n //\n // Karar ÇÖZÜLMÜŞ filtreye bakıyor: `{ id: <ref> }` çözüldükten sonra tek\n // PK eşitliğidir ve CTE'ye gerek yoktur; çözülmeden bakılsaydı bir ref\n // \"nesne\" görünüp gereksiz CTE kurdururdu.\n const planned = planWhere(op.table, op.where, args, results);\n const planPk = primaryKeyOf(op.table);\n sql = isSinglePkEquality(planned.resolved, planPk) || planPk === null\n ? `UPDATE ${table} AS t SET ${assignments.join(\", \")} WHERE true${planned.sql} RETURNING ${rowProjection(op.table, \"t\")}`\n : `WITH locked AS (SELECT t.${quoteIdent(planPk)} AS \"__pb_lock\" FROM ${table} t WHERE true${planned.sql} ` +\n `ORDER BY t.${quoteIdent(planPk)} FOR NO KEY UPDATE) ` +\n `UPDATE ${table} AS t SET ${assignments.join(\", \")} FROM locked ` +\n `WHERE t.${quoteIdent(planPk)} = locked.\"__pb_lock\" RETURNING ${rowProjection(op.table, \"t\")}`;\n break;\n }\n case \"delete\": {\n assertNotAppendOnly(\"deleteWhere\", op.table);\n sql = `DELETE FROM ${table} AS t WHERE true${renderWhere(op.table, op.where, args, results)} RETURNING ${rowProjection(op.table, \"t\")}`;\n break;\n }\n case \"select\": {\n // `Number(op.limit)` NaN üretebiliyordu ve `LIMIT NaN` sözdizimi hatası.\n // Sayı değilse ADIYLA reddet.\n let limit = \"\";\n if (op.limit !== undefined) {\n const n = Number(op.limit);\n if (!Number.isInteger(n) || n < 0) {\n throw new Error(`transaction plan (${op.table}): limit bir tam sayı olmalı, \"${String(op.limit)}\" alındı`);\n }\n limit = ` LIMIT ${n}`;\n }\n const lock = op.lock === \"update\" ? \" FOR UPDATE\" : \"\";\n sql = `SELECT ${rowProjection(op.table, \"t\")} FROM ${table} t WHERE true${renderWhere(op.table, op.where, args, results)}${limit}${lock}`;\n break;\n }\n default:\n // Loudly, rather than rendering something for an op nobody wrote.\n throw new Error(`unknown operation \"${String((op as { op: string }).op)}\" in a transaction plan`);\n }\n\n return { sql, params: args.values, columns: args.columns };\n}\n\nasync function runPlanOp(sp: SqlTx, op: TxWireOp, results: TxPlanOpResult[]): Promise<Row[]> {\n const statement = compilePlanOp(op, results);\n return statement ? await sp.unsafe(statement.sql, statement.params) as Row[] : [];\n}\n\n/** Reuse the sequential plan's SQL compiler. Symbolic preceding rows let that\n * compiler resolve branded refs into parameter slots without touching the DB.\n * JavaScript codecs and raw SQL fragments deliberately use the existing path. */\nfunction compileCommand(plan: TxPlanBody): { steps: CompiledStep[]; pipeline?: { sql: string; params: unknown[] }[] } | { reason: string } {\n const symbols = new Map<string, CommandBinding>();\n const results: TxPlanOpResult[] = [];\n const steps: (CompiledStep & { sql?: string })[] = [];\n const pipeline: { sql: string; params: unknown[] }[] = [];\n let hasRefs = false;\n const prefix = `command:${crypto.randomUUID()}:`;\n const containsFragment = (v: unknown): boolean => isSqlFragment(v) ||\n (v !== null && typeof v === \"object\" && Object.values(v).some(containsFragment));\n const hasNullableFilterRef = (v: unknown): boolean => {\n if (isRef(v)) {\n const source = plan.ops[v.$ref.op];\n return source !== undefined && pageSchema(source.table).columns[v.$ref.field]?.nullable !== false;\n }\n return v !== null && typeof v === \"object\" && Object.values(v).some(hasNullableFilterRef);\n };\n // Eligibility is checked for the WHOLE plan before any statement executes.\n for (const op of plan.ops) {\n if (!schemaColumns(op.table)?.size) return { reason: `table ${op.table} has no installed declaration` };\n if (transformsOf(currentSchema, op.table).size || vectorColumnsOf(currentSchema, op.table).size) return { reason: `${op.table} uses JavaScript codecs/transforms or vector values` };\n if (containsFragment(op)) return { reason: \"SQL fragments require the sequential path\" };\n // Resolving a nullable ref can change '= $n' into 'IS NULL'. The sequential\n // compiler makes that choice after reading the row; this subset cannot.\n if (hasNullableFilterRef(op.where)) return { reason: \"nullable references in filters require the sequential path\" };\n }\n for (const [index, op] of plan.ops.entries()) {\n const statement = compilePlanOp(op, results);\n if (statement === null) {\n steps.push({ empty: true, guard: op.guard });\n pipeline.push({ sql: \"SELECT palbase_runtime.command_rows_v1('[]'::jsonb,$1::jsonb) AS rows\", params: [op.guard ?? null] });\n }\n else {\n if (statement.params.some(v => v === undefined || typeof v === \"symbol\" || typeof v === \"function\" ||\n (typeof v === \"number\" && (!Number.isInteger(v) || v < -2147483648 || v > 2147483647)))) {\n return { reason: \"non-integer/wide numeric or non-JSON parameters require the sequential driver path; use exact decimal strings\" };\n }\n // Bun binds numbers/booleans with scalar protocol types even when the\n // target is JSONB. Keep that driver behavior on the sequential path.\n // A JSONB ref can contain any scalar, so it is also outside this subset.\n for (const [i, value] of statement.params.entries()) {\n const target = statement.columns[i]!;\n if (target.column === undefined || columnTypeOf(target.table ?? op.table, target.column) !== \"jsonb\") continue;\n const source = typeof value === \"string\" ? symbols.get(value) : undefined;\n if (typeof value === \"number\" || typeof value === \"boolean\" || typeof value === \"bigint\" ||\n (source && \"ref\" in source && ![\"text\", \"uuid\", \"timestamp\", \"enum\"].includes(columnTypeOf(plan.ops[source.ref.op]!.table, source.ref.field) ?? \"\"))) {\n return { reason: \"JSONB scalar/ref binding requires the sequential driver path\" };\n }\n }\n const wide = [...schemaColumns(op.table)!].filter(c => [\"bigint\", \"numeric\"].includes(columnTypeOf(op.table, c) ?? \"\"));\n const exact = wide.length ? ` || jsonb_build_object(${wide.map(c => `${quoteLiteral(c)}, r.${quoteIdent(c)}::text`).join(\", \")})` : \"\";\n const sql = `WITH command_rows AS (${statement.sql}) SELECT coalesce(jsonb_agg(to_jsonb(r)${exact}), '[]'::jsonb) FROM command_rows r`;\n pipeline.push({\n sql: `WITH command_rows AS (${statement.sql}) SELECT palbase_runtime.command_rows_v1(coalesce(jsonb_agg(to_jsonb(r)${exact}), '[]'::jsonb),$${statement.params.length + 1}::jsonb) AS rows FROM command_rows r`,\n params: [...statement.params, op.guard ?? null],\n });\n const bindings: CommandBinding[] = statement.params.map((value, i) => {\n const target = statement.columns[i]!;\n const json = target.column !== undefined && columnTypeOf(target.table ?? op.table, target.column) === \"jsonb\";\n if (typeof value === \"string\" && symbols.has(value)) { hasRefs = true; return { ...symbols.get(value)!, json }; }\n if (typeof value === \"bigint\") return { value: value.toString(), json };\n if (value instanceof Date) return { value: value.toISOString(), json };\n return { value, json };\n });\n steps.push({ sql, bindings, guard: op.guard });\n }\n const row: Row = {};\n for (const field of schemaColumns(op.table)!) {\n const token = `${prefix}${index}:${field}`;\n symbols.set(token, { ref: { op: index, field } }); row[field] = token;\n }\n results.push({ rows: [row], rows_affected: 1 });\n }\n // Independent statements use the parameterized driver pipeline. Tokenizing\n // them for command_v1 built a second, unused representation on every call.\n // Only a plan whose statements reference preceding rows needs those chunks.\n if (!hasRefs) return { steps: [], pipeline };\n return { steps: steps.map(({ sql, ...step }) => sql === undefined\n ? step : { ...step, chunks: parameterChunks(sql) }) };\n}\n\n/**\n * Enforce the author's declared expectation.\n *\n * The Error the author passed never travels: the plan carries a SLOT index and\n * the SDK maps it back. So a failure here throws the shape `runTxPlan` knows —\n * `{error_code: \"tx_guard_failed\", slot}` — and the savepoint unwinds.\n */\nfunction assertGuard(op: TxWireOp, result: TxPlanOpResult): void {\n const guard = op.guard;\n if (!guard) return;\n const n = result.rows.length;\n const ok =\n guard.kind === \"one\"\n ? n === 1\n : guard.kind === \"none\"\n ? n === 0\n : guard.kind === \"atLeast\"\n ? n >= guard.n\n : n <= guard.n;\n if (ok) return;\n throw Object.assign(new Error(`transaction expectation failed: ${guard.kind} (${n} row(s))`), {\n error_code: \"tx_guard_failed\",\n slot: guard.slot,\n });\n}\n","/** Metadata is scoped to an installed schema snapshot, never to row values. */\nexport type SchemaMetadataCache<T> = WeakMap<object, Map<string, T>>;\n\nexport function memoTable<T>(\n cache: SchemaMetadataCache<T>, schema: { tables?: Record<string, unknown> },\n table: string, compute: () => T,\n): T {\n // Dynamic/unknown table names must not grow a process-wide cache.\n if (!schema.tables || !Object.hasOwn(schema.tables, table)) return compute();\n let tables = cache.get(schema);\n if (!tables) { tables = new Map(); cache.set(schema, tables); }\n if (!tables.has(table)) tables.set(table, compute());\n return tables.get(table) as T;\n}\n\n/** Clone before freezing: authors may reuse/extend their declarations and\n * reinstall them, while a live compiled schema remains stable. Functions retain\n * their identity so custom column codecs continue to execute normally. */\nexport function snapshotDeclaration<T>(value: T, seen = new WeakMap<object, object>()): T {\n if (value === null || typeof value !== \"object\") return value;\n const previous = seen.get(value);\n if (previous) return previous as T;\n if (value instanceof Date) return new Date(value.getTime()) as T;\n const result = Array.isArray(value) ? [] : Object.create(Object.getPrototypeOf(value));\n seen.set(value, result);\n for (const key of Reflect.ownKeys(value)) {\n if (Array.isArray(value) && key === \"length\") continue;\n const descriptor = Object.getOwnPropertyDescriptor(value, key)!;\n if (\"value\" in descriptor) descriptor.value = snapshotDeclaration(descriptor.value, seen);\n Object.defineProperty(result, key, descriptor);\n }\n return Object.freeze(result) as T;\n}\n","import { createCipheriv, createDecipheriv, createHash, randomBytes } from \"node:crypto\";\nimport { BadRequest } from \"../errors.js\";\nimport type { RawPageOptions } from \"../db/page.js\";\n\nlet key: Buffer | null = null;\nconst invalidPage = (message: string, field = \"page\") => new BadRequest({ fields: [{ field, message }] }, message);\n\n/** One application secret shared by replicas. Rotation invalidates old cursors.\n * Encryption also hides sort values omitted by the public projection. */\nexport function setCursorKey(secret: string | null): void {\n key = secret ? createHash(\"sha256\").update(\"palbase:cursor:v1\\0\").update(secret).digest() : null;\n}\n\nexport function cursorKey(): Buffer {\n if (!key) throw new Error(\"Database.page needs PALBASE_CURSOR_SECRET or PALBASE_SERVICE_ROLE_KEY shared by all replicas\");\n return key;\n}\n\n/** Stable across object property order, BigInt inputs and refreshed JWTs. */\nexport function fingerprint(value: unknown): string {\n const stable = (v: unknown): unknown => {\n if (typeof v === \"bigint\") return { $bigint: v.toString() };\n if (v instanceof Date) return { $date: v.toISOString() };\n if (Array.isArray(v)) return v.map(stable);\n if (v && typeof v === \"object\") {\n return Object.fromEntries(Object.keys(v).sort().map(k => [k, stable((v as Record<string, unknown>)[k])]));\n }\n return v;\n };\n return createHash(\"sha256\").update(JSON.stringify(stable(value))).digest(\"base64url\");\n}\n\nexport function cursorIdentity(role: string, claimsJson: string): string {\n const claims = JSON.parse(claimsJson) as Record<string, unknown>;\n const { iat, exp, nbf, jti, ...authorization } = claims;\n return fingerprint({ role, authorization });\n}\n\nexport function encodeCursor(secret: Buffer, scope: string, values: (string | null)[]): string {\n const nonce = randomBytes(12);\n const cipher = createCipheriv(\"aes-256-gcm\", secret, nonce);\n cipher.setAAD(Buffer.from(scope));\n const body = Buffer.concat([cipher.update(JSON.stringify(values), \"utf8\"), cipher.final()]);\n const token = `p1.${Buffer.concat([nonce, cipher.getAuthTag(), body]).toString(\"base64url\")}`;\n if (token.length > 16384) throw invalidPage(\"page cursor values are too large; choose shorter ordering columns\");\n return token;\n}\n\nexport function decodeCursor(secret: Buffer, scope: string, token: string, count: number): (string | null)[] {\n try {\n if (typeof token !== \"string\" || token.length > 16384 || !/^p1\\.[\\w-]+$/.test(token)) throw new Error();\n const data = Buffer.from(token.slice(3), \"base64url\");\n if (data.length < 30 || data.toString(\"base64url\") !== token.slice(3)) throw new Error();\n const cipher = createDecipheriv(\"aes-256-gcm\", secret, data.subarray(0, 12));\n cipher.setAAD(Buffer.from(scope));\n cipher.setAuthTag(data.subarray(12, 28));\n const values: unknown = JSON.parse(Buffer.concat([cipher.update(data.subarray(28)), cipher.final()]).toString(\"utf8\"));\n if (!Array.isArray(values) || values.length !== count || values.some(v => v !== null && typeof v !== \"string\")) throw new Error();\n return values;\n } catch {\n throw invalidPage(\"Invalid cursor for this query or identity; restart from the first page\", \"cursor\");\n }\n}\n\nexport interface PageColumn { type?: string; nullable?: boolean }\nexport interface PageOrder { column: string; direction: \"asc\" | \"desc\"; nulls: \"first\" | \"last\"; nullable: boolean }\n\nexport function pageOrder(columns: Record<string, PageColumn>, primaryKey: readonly string[], opts: RawPageOptions): {\n order: PageOrder[]; size: number; backward: boolean; token: string | undefined;\n} {\n const raw = opts as Record<string, unknown>;\n if (\"limit\" in raw || \"offset\" in raw) throw invalidPage(\"page uses first/after or last/before, not limit/offset\");\n const backward = opts.last !== undefined || opts.before !== undefined;\n if (backward && (opts.first !== undefined || opts.after !== undefined)) throw invalidPage(\"Use first/after or last/before in one page request\");\n const size = (backward ? opts.last : opts.first) ?? 50;\n if (!Number.isInteger(size) || size < 1 || size > 1000) throw invalidPage(\"page size must be an integer between 1 and 1000\");\n if (primaryKey.length === 0) throw new Error(\"page requires a declared primary key for a unique, stable ordering\");\n const input = opts.orderBy === undefined ? [] : Array.isArray(opts.orderBy) ? opts.orderBy : [opts.orderBy];\n if (input.length > 16) throw invalidPage(\"page supports at most 16 ordering columns\");\n const seen = new Set<string>();\n const order: PageOrder[] = [];\n const add = (o: { column: string; direction?: string; nulls?: string }) => {\n const def = columns[o?.column];\n if (!Object.hasOwn(columns, o?.column) || !def) throw invalidPage(`page order column ${o?.column} is not declared`);\n if (!new Set([\"uuid\", \"text\", \"integer\", \"bigint\", \"boolean\", \"timestamp\", \"numeric\", \"enum\"]).has(def.type ?? \"\")) {\n throw invalidPage(`page cannot order ${o.column}: ${def.type ?? \"unknown\"} is not a supported scalar column`);\n }\n if (seen.has(o.column)) throw invalidPage(`page order column ${o.column} is repeated`);\n if (o.direction !== undefined && o.direction !== \"asc\" && o.direction !== \"desc\") throw invalidPage(\"page direction must be asc or desc\");\n if (o.nulls !== undefined && o.nulls !== \"first\" && o.nulls !== \"last\") throw invalidPage(\"page nulls must be first or last\");\n const direction = o.direction ?? \"asc\";\n seen.add(o.column);\n order.push({ column: o.column, direction, nulls: o.nulls ?? (direction === \"asc\" ? \"last\" : \"first\"), nullable: def.nullable !== false });\n };\n for (const o of input) add(o);\n for (const column of primaryKey) if (!seen.has(column)) add({ column, direction: order.at(-1)?.direction ?? \"asc\" });\n return { order, size, backward, token: backward ? opts.before : opts.after };\n}\n\n/** Render a strict lexicographic boundary. NULLs follow the declared sort order,\n * independent of direction; every component of a composite PK participates. */\nexport function pageBoundary(order: readonly PageOrder[], values: readonly (string | null)[], backward: boolean,\n bind: (value: unknown) => string, column: (name: string) => string, inclusive = false): string {\n const refs = values.map(v => bind(v));\n // This form lets PostgreSQL start an index scan at the cursor, instead of\n // filtering the entire prefix for the common non-null, uniform ordering.\n if (order.every(o => !o.nullable && o.direction === order[0]!.direction) && values.every(v => v !== null)) {\n const greater = (order[0]!.direction === \"asc\") !== backward;\n return `(${order.map(o => column(o.column)).join(\", \")}) ${greater ? \">\" : \"<\"}${inclusive ? \"=\" : \"\"} (${refs.join(\", \")})`;\n }\n const parts: string[] = [];\n const prefix: string[] = [];\n for (let i = 0; i < order.length; i++) {\n const o = order[i]!, c = column(o.column), r = refs[i]!;\n const nullsLast = (o.nulls === \"last\") !== backward;\n const cmp = (o.direction === \"asc\") !== backward ? \">\" : \"<\";\n const tail = values[i] === null\n ? (nullsLast ? \"false\" : `${c} IS NOT NULL`)\n : `(${c} ${cmp} ${r}${nullsLast ? ` OR ${c} IS NULL` : \"\"})`;\n parts.push(`(${[...prefix, tail].join(\" AND \")})`);\n prefix.push(`${c} IS NOT DISTINCT FROM ${r}`);\n }\n if (inclusive) parts.push(`(${prefix.join(\" AND \")})`);\n return `(${parts.join(\" OR \")})`;\n}\n","export interface InsertManyOptions<Key extends string = string> {\n onConflict?: readonly Key[];\n /** Defaults to ignore when onConflict is supplied. */\n action?: \"ignore\" | \"update\";\n /** false returns the affected row count and skips row serialization. */\n returning?: boolean;\n}\n\nexport function validateInsertManyOptions(opts: InsertManyOptions | undefined): void {\n if (!opts) return;\n if (opts.returning !== undefined && typeof opts.returning !== \"boolean\") throw new Error(\"insertMany returning must be a boolean\");\n if (opts.action !== undefined && opts.action !== \"ignore\" && opts.action !== \"update\") throw new Error(\"insertMany action must be ignore or update\");\n if (opts.onConflict !== undefined && (!Array.isArray(opts.onConflict) || opts.onConflict.some(c => typeof c !== \"string\" || c.length === 0))) {\n throw new Error(\"insertMany onConflict must be an array of column names\");\n }\n if (opts.action !== undefined && !opts.onConflict?.length) throw new Error(\"insertMany action requires nonempty onConflict columns\");\n}\n","/** Column and table UNIQUE declarations, including composite primary keys. */\nexport function uniqueKeysOf(table: {\n columns?: Record<string, unknown>;\n primaryKey?: readonly string[];\n unique?: readonly { columns: readonly string[] }[];\n}): string[][] {\n const columns = table.columns ?? {};\n const inlinePrimary: string[] = [], keys: string[][] = [];\n for (const [name, value] of Object.entries(columns)) {\n const col = (value && typeof value === \"object\" && \"_def\" in value ? value._def : value) as\n { primaryKey?: boolean; unique?: boolean } | undefined;\n if (col?.primaryKey) inlinePrimary.push(name);\n if (col?.unique) keys.push([name]);\n }\n const primary = table.primaryKey ?? inlinePrimary;\n if (primary.length) keys.unshift([...primary]);\n for (const key of table.unique ?? []) keys.push([...key.columns]);\n const seen = new Set<string>();\n return keys.filter(key => {\n if (!key.length || new Set(key).size !== key.length || key.some(col => !Object.hasOwn(columns, col))) {\n throw new Error(\"Unique lookup requires a nonempty declared key of distinct, known columns\");\n }\n const identity = JSON.stringify([...key].sort());\n if (seen.has(identity)) return false;\n seen.add(identity); return true;\n });\n}\n\n/** Nulls in ordinary PostgreSQL UNIQUE constraints are not unique. */\nexport function assertUniqueLookup(table: string, keys: readonly (readonly string[])[], where: Record<string, unknown>): void {\n if (!where || typeof where !== \"object\" || Array.isArray(where)) throw new Error(`findUnique(${table}): where must contain one declared unique key`);\n const columns = Object.keys(where);\n if (!keys.some(key => key.length === columns.length && key.every(col => Object.hasOwn(where, col)))) {\n throw new Error(`findUnique(${table}): supply exactly one declared unique key (${keys.map(key => key.join(\" + \")).join(\"; \") || \"none declared\"}); use findMany for other filters`);\n }\n for (const [name, value] of Object.entries(where)) {\n if (value === null || value === undefined || (typeof value === \"object\" && !(value instanceof Date)) || typeof value === \"function\" || typeof value === \"symbol\") {\n throw new Error(`findUnique(${table}): ${name} requires a non-null scalar equality value`);\n }\n }\n}\n\n/** A union of exact keys, not a partial row that could match many records. */\nexport type UniqueWhere<Row, Keys> = Keys extends readonly (infer Key extends readonly string[])[]\n ? Key extends unknown\n ? { [K in Extract<Key[number], keyof Row>]-?: NonNullable<Row[K]> } &\n { [K in Exclude<keyof Row, Key[number]>]?: never }\n : never\n : never;\n","import type { SqlDriver } from \"./db.js\";\nimport type { TxWireGuard } from \"../db/tx-plan.js\";\n\nconst installed = new WeakSet<SqlDriver>();\nexport const hasCommandExecutor = (sql: SqlDriver): boolean => installed.has(sql);\n\n/** Statements remain sequential inside PostgreSQL. Each sees preceding writes,\n * including triggers, unlike sibling data-modifying CTEs in one SQL statement.\n * The exception block is a subtransaction, matching a savepoint plan. */\nexport const COMMAND_EXECUTOR_DDL = `\nCREATE SCHEMA IF NOT EXISTS palbase_runtime;\nCREATE OR REPLACE FUNCTION palbase_runtime.command_v1(steps jsonb) RETURNS jsonb\nLANGUAGE plpgsql VOLATILE SECURITY INVOKER SET search_path = pg_catalog, public AS $pb_command$\nDECLARE\n results jsonb := '[]'::jsonb;\n step jsonb; chunk jsonb; binding jsonb; source jsonb; rows jsonb;\n statement text; rendered text; detail text; guard jsonb;\n index integer := 0; affected integer; passed boolean;\nBEGIN\n FOR step IN SELECT value FROM jsonb_array_elements(steps) LOOP\n IF step->>'empty' = 'true' THEN rows := '[]'::jsonb;\n ELSE\n statement := '';\n FOR chunk IN SELECT value FROM jsonb_array_elements(step->'chunks') LOOP\n IF jsonb_typeof(chunk) = 'string' THEN statement := statement || (chunk #>> '{}');\n ELSE\n binding := step->'bindings'->((chunk->>'bind')::integer);\n IF binding ? 'ref' THEN\n source := results->((binding->'ref'->>'op')::integer)->'rows'->0;\n IF source IS NULL OR NOT source ? (binding->'ref'->>'field') THEN\n RAISE EXCEPTION 'Command reference has no source row/column; use expectOne before reading it'\n USING ERRCODE = 'PBC02', DETAIL = jsonb_build_object('error_code','tx_ref_unresolved','op',index)::text;\n END IF;\n source := source->(binding->'ref'->>'field');\n ELSE source := binding->'value'; END IF;\n rendered := CASE WHEN source IS NULL OR source = 'null'::jsonb THEN NULL\n WHEN binding->>'json' = 'true' THEN source::text\n WHEN jsonb_typeof(source) = 'string' THEN source #>> '{}' ELSE source::text END;\n -- PostgreSQL quotes the value itself. Values reach this function as\n -- one bound JSON parameter, never as application-generated SQL text.\n statement := statement || quote_nullable(rendered);\n END IF;\n END LOOP;\n EXECUTE statement INTO rows;\n END IF;\n affected := jsonb_array_length(rows);\n guard := step->'guard';\n IF guard IS NOT NULL AND guard <> 'null'::jsonb THEN\n passed := CASE guard->>'kind'\n WHEN 'one' THEN affected = 1 WHEN 'none' THEN affected = 0\n WHEN 'atLeast' THEN affected >= (guard->>'n')::integer\n WHEN 'atMost' THEN affected <= (guard->>'n')::integer ELSE false END;\n IF NOT passed THEN\n RAISE EXCEPTION 'Command expectation failed'\n USING ERRCODE = 'PBC01', DETAIL = jsonb_build_object('error_code','tx_guard_failed','slot',guard->'slot','op',index)::text;\n END IF;\n END IF;\n results := results || jsonb_build_array(jsonb_build_object('rows',rows,'rows_affected',affected));\n index := index + 1;\n END LOOP;\n RETURN jsonb_build_object('results',results);\nEXCEPTION WHEN SQLSTATE 'PBC01' OR SQLSTATE 'PBC02' THEN\n GET STACKED DIAGNOSTICS detail = PG_EXCEPTION_DETAIL;\n RETURN jsonb_build_object('error',detail::jsonb);\nEND\n$pb_command$;\nREVOKE ALL ON FUNCTION palbase_runtime.command_v1(jsonb) FROM PUBLIC;\nCREATE OR REPLACE FUNCTION palbase_runtime.command_rows_v1(rows jsonb, guard jsonb) RETURNS jsonb\nLANGUAGE plpgsql VOLATILE SECURITY INVOKER SET search_path = pg_catalog, public AS $pb_rows$\nDECLARE affected integer := jsonb_array_length(rows); passed boolean;\nBEGIN\n IF guard IS NOT NULL AND guard <> 'null'::jsonb THEN\n passed := CASE guard->>'kind'\n WHEN 'one' THEN affected = 1 WHEN 'none' THEN affected = 0\n WHEN 'atLeast' THEN affected >= (guard->>'n')::integer\n WHEN 'atMost' THEN affected <= (guard->>'n')::integer ELSE false END;\n IF NOT passed THEN\n RAISE EXCEPTION 'Command expectation failed'\n USING ERRCODE = 'PBC01', DETAIL = jsonb_build_object('error_code','tx_guard_failed','slot',guard->'slot')::text;\n END IF;\n END IF;\n RETURN rows;\nEND\n$pb_rows$;\nREVOKE ALL ON FUNCTION palbase_runtime.command_rows_v1(jsonb,jsonb) FROM PUBLIC;\n`;\n\n/** Run once with a migration/owner connection. Runtime execution retains each\n * caller's role and RLS; there is no SECURITY DEFINER capability. */\nexport async function installCommandExecutor(sql: SqlDriver, roles: readonly string[]): Promise<void> {\n const quote = (s: string) => `\"${s.replace(/\"/g, '\"\"')}\"`;\n if (roles.length === 0) throw new Error(\"Command executor needs explicit runtime roles\");\n await sql.begin(async tx => {\n // Serialize simultaneous boots installing the same version.\n await tx.unsafe(\"SELECT pg_advisory_xact_lock(196754721, 1)\");\n await tx.unsafe(COMMAND_EXECUTOR_DDL);\n const list = [...new Set(roles)].map(quote).join(\", \");\n await tx.unsafe(`GRANT USAGE ON SCHEMA palbase_runtime TO ${list}`);\n await tx.unsafe(`GRANT EXECUTE ON FUNCTION palbase_runtime.command_v1(jsonb) TO ${list}`);\n await tx.unsafe(`GRANT EXECUTE ON FUNCTION palbase_runtime.command_rows_v1(jsonb,jsonb) TO ${list}`);\n });\n installed.add(sql);\n}\n\nexport type CommandBinding = ({ value: unknown } | { ref: { op: number; field: string } }) & { json?: boolean };\nexport interface CompiledStep {\n chunks?: (string | { bind: number })[];\n bindings?: CommandBinding[];\n guard?: TxWireGuard;\n empty?: true;\n}\n\n/** Only unquoted placeholders are replaced. A declared identifier or a string\n * literal containing \"$1\" is data in the SQL grammar, not a parameter. */\nexport function parameterChunks(sql: string): (string | { bind: number })[] {\n const chunks: (string | { bind: number })[] = [];\n let start = 0, quote: \"'\" | '\"' | null = null;\n for (let i = 0; i < sql.length; i++) {\n const c = sql[i];\n if (quote) {\n if (c === quote) { if (sql[i + 1] === quote) i++; else quote = null; }\n continue;\n }\n if (c === \"'\" || c === '\"') { quote = c; continue; }\n if (c !== \"$\") continue;\n const parameter = /^\\$(\\d+)\\b/.exec(sql.slice(i));\n if (!parameter) continue;\n chunks.push(sql.slice(start, i), { bind: Number(parameter[1]) - 1 });\n i += parameter[0].length - 1; start = i + 1;\n }\n chunks.push(sql.slice(start));\n return chunks;\n}\n","import { TooManyRequests } from \"../errors.js\";\n\nexport interface AdmissionLease {\n queueMs: number;\n release(): void;\n}\n\n/** Deployment settings, never a query/workload declaration in application code. */\nexport interface DatabaseAdmissionOptions {\n concurrency: number;\n queueLimit?: number;\n queueTimeoutMs?: number;\n /** Optional signed, issuer-controlled top-level tenant claim. By default\n * fairness uses verified sub, not the installation-wide tenant_id. */\n tenantClaim?: string;\n onReject?: (event: { reason: \"full\" | \"timeout\" | \"cancelled\"; active: number; queued: number }) => void;\n}\n\ninterface DatabaseWaiter {\n grant: (lease: AdmissionLease) => void;\n reject: (error: unknown) => void;\n entered: number;\n cleanup(): void;\n}\n\nexport class DatabaseAdmission {\n private active = 0;\n private queued = 0;\n private tenants = new Map<string, number>();\n // Map insertion order is the round-robin ring; each Set is FIFO. Grant and\n // cancellation remove nodes directly, without scanning a 10,000-item queue.\n private pending = new Map<string, Set<DatabaseWaiter>>();\n private lastTenant?: string;\n private accepted = 0;\n private rejected = { full: 0, timeout: 0, cancelled: 0 };\n private readonly limit: number;\n private readonly timeout: number;\n constructor(readonly options: DatabaseAdmissionOptions) {\n this.limit = options.queueLimit ?? Math.min(512, Math.max(32, options.concurrency * 8));\n this.timeout = options.queueTimeoutMs ?? 1000;\n if (!Number.isSafeInteger(options.concurrency) || options.concurrency < 1 ||\n !Number.isSafeInteger(this.limit) || this.limit < 0 || this.limit > 10000 ||\n !Number.isSafeInteger(this.timeout) || this.timeout < 1 || this.timeout > 60000) {\n throw new Error('Invalid database pool or queue deployment settings');\n }\n }\n get snapshot() { return { active: this.active, queued: this.queued, tenants: this.tenants.size,\n accepted: this.accepted, rejected: { ...this.rejected } }; }\n private rejection(reason: 'full' | 'timeout' | 'cancelled') {\n this.rejected[reason]++;\n try { this.options.onReject?.({ reason, active: this.active, queued: this.queued }); } catch { /* telemetry cannot affect admission */ }\n }\n private take(tenant: string, entered: number): AdmissionLease {\n this.active++; this.accepted++; this.lastTenant = tenant;\n this.tenants.set(tenant, (this.tenants.get(tenant) ?? 0) + 1);\n let released = false;\n return { queueMs: performance.now() - entered, release: () => {\n if (released) return;\n released = true; this.active--;\n const count = this.tenants.get(tenant)! - 1;\n if (count) this.tenants.set(tenant, count); else this.tenants.delete(tenant);\n this.drain();\n } };\n }\n private drain() {\n while (this.active < this.options.concurrency && this.queued) {\n let tenant = this.pending.keys().next().value!;\n if (this.pending.size > 1 && tenant === this.lastTenant) {\n const queue = this.pending.get(tenant)!;\n this.pending.delete(tenant); this.pending.set(tenant, queue);\n tenant = this.pending.keys().next().value!;\n }\n const queue = this.pending.get(tenant)!, waiter = queue.values().next().value!;\n queue.delete(waiter); this.pending.delete(tenant);\n if (queue.size) this.pending.set(tenant, queue);\n this.queued--; waiter.cleanup(); waiter.grant(this.take(tenant, waiter.entered));\n }\n }\n async acquire(claimsJson: string, signal?: AbortSignal): Promise<AdmissionLease> {\n if (signal?.aborted) { this.rejection('cancelled'); throw signal.reason ?? new Error('Database admission cancelled'); }\n const claims = JSON.parse(claimsJson) as Record<string, unknown>;\n const value = this.options.tenantClaim ? claims[this.options.tenantClaim] : claims.sub;\n const tenant = typeof value === 'string' && value.length ? value : '__anonymous__';\n const entered = performance.now();\n if (this.active < this.options.concurrency && !this.queued) return this.take(tenant, entered);\n if (this.queued >= this.limit) {\n this.rejection('full');\n throw new TooManyRequests({ retryAfter: 1 }, 'Database queue is full');\n }\n return new Promise<AdmissionLease>((grant, reject) => {\n const queue = this.pending.get(tenant) ?? new Set<DatabaseWaiter>();\n if (!this.pending.has(tenant)) this.pending.set(tenant, queue);\n const waiter: DatabaseWaiter = { grant, reject, entered, cleanup() {} };\n const remove = (reason: 'cancelled' | 'timeout', error: unknown) => {\n if (!queue.delete(waiter)) return;\n if (!queue.size) this.pending.delete(tenant);\n this.queued--; waiter.cleanup(); this.rejection(reason); reject(error); this.drain();\n };\n const abort = () => remove('cancelled', signal?.reason ?? new Error('Database admission cancelled'));\n const timer = setTimeout(() => remove('timeout', new TooManyRequests({ retryAfter: 1 }, 'Database queue deadline exceeded')), this.timeout);\n waiter.cleanup = () => { clearTimeout(timer); signal?.removeEventListener('abort', abort); };\n queue.add(waiter); this.queued++;\n signal?.addEventListener('abort', abort, { once: true });\n if (signal?.aborted) abort(); else this.drain();\n });\n }\n}\n\nconst databases = new WeakMap<object, DatabaseAdmission>();\nexport function databaseAdmission(owner: object, options?: DatabaseAdmissionOptions): DatabaseAdmission {\n let admission = databases.get(owner);\n if (!admission) {\n admission = new DatabaseAdmission(options ?? { concurrency: 10 });\n databases.set(owner, admission);\n } else if (options) {\n for (const key of [\"concurrency\", \"queueLimit\", \"queueTimeoutMs\", \"tenantClaim\"] as const) {\n if (options[key] !== admission.options[key]) throw new Error(\"Database admission cannot be reconfigured while its pool is shared\");\n }\n }\n return admission;\n}\n","import { HttpError } from \"../errors.js\";\n\nexport type CancellableQuery = Promise<unknown> & { cancel?: () => unknown };\n\n/** Abort callback work and active statements, then let the transaction owner\n * await rollback. COMMIT is never raced with a timer: its acknowledged result\n * or connection failure remains authoritative. */\nexport class TransactionControl {\n private controller = new AbortController();\n private active = new Set<CancellableQuery>();\n private cancelBackend?: () => Promise<void>;\n private cancellation: Promise<unknown> = Promise.resolve();\n private timer?: ReturnType<typeof setTimeout>;\n private unlink: () => void;\n private rejection: Promise<never>;\n readonly deadline: number | undefined;\n get signal(): AbortSignal { return this.controller.signal; }\n\n constructor(timeoutMs?: number, external?: AbortSignal) {\n this.deadline = timeoutMs === undefined ? undefined : performance.now() + timeoutMs;\n this.rejection = new Promise<never>((_, reject) => {\n this.signal.addEventListener(\"abort\", () => {\n reject(this.signal.reason);\n if (this.active.size && this.cancelBackend) {\n this.cancellation = this.cancelBackend().catch(() => undefined);\n } else {\n for (const query of this.active) {\n try { query.cancel?.(); } catch { /* rollback still owns settlement */ }\n }\n }\n }, { once: true });\n });\n void this.rejection.catch(() => undefined);\n const abort = () => this.controller.abort(external?.reason ?? new DOMException(\"Database transaction cancelled\", \"AbortError\"));\n external?.addEventListener(\"abort\", abort, { once: true });\n this.unlink = () => external?.removeEventListener(\"abort\", abort);\n if (external?.aborted) abort();\n if (timeoutMs !== undefined) this.timer = setTimeout(() => this.controller.abort(\n new HttpError(503, \"database_deadline_exceeded\", \"Database transaction exceeded its deadline\")), timeoutMs);\n }\n\n check(): void {\n if (this.deadline !== undefined && performance.now() >= this.deadline && !this.signal.aborted) {\n this.controller.abort(new HttpError(503, \"database_deadline_exceeded\", \"Database transaction exceeded its deadline\"));\n }\n this.signal.throwIfAborted();\n }\n\n remainingMs(): number | undefined {\n this.check();\n return this.deadline === undefined ? undefined : Math.max(1, Math.ceil(this.deadline - performance.now()));\n }\n\n race<T>(work: Promise<T>): Promise<T> { return Promise.race([work, this.rejection]); }\n\n bindBackend(cancel: () => Promise<void>): void { this.cancelBackend = cancel; }\n\n /** Keep the application's connection parked until the cancellation request\n * and all statements settle; a late cancel must not hit its next borrower. */\n async drainCancellation(): Promise<void> {\n await this.cancellation;\n await Promise.allSettled([...this.active]);\n }\n\n async watch(query: CancellableQuery): Promise<unknown> {\n this.active.add(query);\n try {\n if (this.signal.aborted) query.cancel?.();\n return await query;\n } finally { this.active.delete(query); }\n }\n\n dispose(): void { if (this.timer !== undefined) clearTimeout(this.timer); this.unlink(); }\n}\n","import { createHash } from \"node:crypto\";\nimport { HttpError } from \"../errors.js\";\nimport type { DatabaseDiagnostics, DatabaseDiagnosticsOptions, DatabaseQueryEvent } from \"../db/diagnostics.js\";\n\ntype Timing = \"queueMs\" | \"poolMs\" | \"setupMs\" | \"sqlMs\" | \"commitMs\" | \"rollbackMs\" | \"connectionMs\";\n\n/** Allocated only when diagnostics or a budget is configured. One collector\n * follows the request's user/service handles and independent atomic attempts. */\nexport class DatabaseTrace {\n private readonly start = performance.now();\n private ended?: number;\n private failure?: HttpError;\n private readonly state: DatabaseDiagnostics;\n constructor(private readonly options: DatabaseDiagnosticsOptions) {\n for (const key of [\"maxQueries\", \"maxRows\", \"maxBytes\"] as const) {\n const value = options[key];\n if (value !== undefined && (!Number.isSafeInteger(value) || value < 0)) throw new Error(`database ${key} must be a nonnegative safe integer`);\n }\n this.state = { endpoint: options.endpoint, requestId: options.requestId, outcome: \"active\", elapsedMs: 0,\n queries: 0, rows: 0, bytes: 0, queueMs: 0, poolMs: 0, setupMs: 0, sqlMs: 0, commitMs: 0, rollbackMs: 0,\n connectionMs: 0, commits: 0, commitFailures: 0, rollbackRequests: 0, retries: 0, statements: [] };\n }\n check(): void { if (this.failure) throw this.failure; }\n time(key: Timing, started: number): void { this.state[key] = (this.state[key] ?? 0) + performance.now() - started; }\n retry(): void { this.state.retries++; }\n committed(): void { this.state.commits++; }\n commitFailed(): void { this.state.commitFailures++; }\n failed(): void { this.state.outcome = \"failed\"; }\n rolledBack(): void { this.state.rollbackRequests++; }\n private refuse(kind: string): never {\n this.failure ??= new HttpError(500, \"database_budget_exceeded\", `Database ${kind} budget exceeded${this.options.endpoint ? ` in ${this.options.endpoint}` : \"\"}`);\n throw this.failure;\n }\n private emit<T>(callback: ((event: T) => void | Promise<void>) | undefined, event: T): void {\n // A telemetry sink cannot turn an acknowledged COMMIT into a reported failure.\n try { const result = callback?.(event); if (result) void Promise.resolve(result).catch(() => undefined); } catch { /* isolated sink */ }\n }\n async query(sql: string, name: string | undefined, run: () => Promise<unknown>): Promise<unknown> {\n this.check();\n if (this.options.maxQueries !== undefined && this.state.queries >= this.options.maxQueries) this.refuse(\"query count\");\n const ordinal = ++this.state.queries;\n const event: DatabaseQueryEvent = { ordinal, fingerprint: createHash(\"sha256\").update(sql).digest(\"hex\").slice(0, 24),\n ...(name === undefined ? {} : { name: name.slice(0, 128) }),\n ...(this.options.includeSql ? { sql: sql.slice(0, 4096) } : {}), durationMs: 0, rows: 0, bytes: 0 };\n if (this.options.captureSource) event.source = new Error().stack?.split(\"\\n\").slice(1, 9).join(\"\\n\").slice(0, 2500);\n const started = performance.now();\n let measured = false;\n try {\n const result = await run();\n event.durationMs = performance.now() - started; measured = true;\n if (Array.isArray(result)) {\n event.rows = result.length;\n event.bytes = Buffer.byteLength(JSON.stringify(result, (_, value) => typeof value === \"bigint\" ? value.toString() : value));\n }\n this.state.rows += event.rows; this.state.bytes += event.bytes;\n if (this.options.maxRows !== undefined && this.state.rows > this.options.maxRows) this.refuse(\"returned rows\");\n if (this.options.maxBytes !== undefined && this.state.bytes > this.options.maxBytes) this.refuse(\"result bytes\");\n return result;\n } catch (error) {\n const e = error as { sqlstate?: string; errno?: string; code?: string } | null;\n event.errorCode = String(e?.sqlstate ?? e?.errno ?? e?.code ?? \"query_failed\").slice(0, 80);\n throw error;\n } finally {\n if (!measured) event.durationMs = performance.now() - started;\n this.state.sqlMs += event.durationMs;\n const frozen = Object.freeze(event);\n if (this.state.statements.length < 200) (this.state.statements as DatabaseQueryEvent[]).push(frozen);\n this.emit(this.options.onQuery, frozen);\n }\n }\n get snapshot(): DatabaseDiagnostics {\n return Object.freeze({ ...this.state, elapsedMs: (this.ended ?? performance.now()) - this.start,\n statements: Object.freeze([...this.state.statements].sort((a, b) => a.ordinal - b.ordinal)) });\n }\n complete(outcome: \"committed\" | \"failed\"): void {\n if (this.ended !== undefined) return;\n this.ended = performance.now(); this.state.outcome = outcome;\n this.emit(this.options.onComplete, this.snapshot);\n }\n}\n","/** On delete action for foreign key references. */\nexport type OnDeleteAction = 'cascade' | 'set null' | 'restrict' | 'no action';\n\n/**\n * The ON DELETE actions permitted on a foreign key to the built-in auth users\n * (`auth.users`). Both let a user's rows be removed (`cascade`) or detached\n * (`set null`) when the account is erased; `restrict` / `no action` would BLOCK\n * erasure and are therefore excluded. This is the CLIENT-SIDE mirror of the\n * server's auth-FK deletion policy — the server (validateAuthUserFK) is the real\n * boundary, this narrows the type so the common mistake is caught at compile time.\n */\nexport type AuthUserOnDelete = Extract<OnDeleteAction, 'cascade' | 'set null'>;\n\n/** Column type identifiers. */\nexport type ColumnType =\n | 'uuid'\n | 'text'\n | 'integer'\n | 'bigint'\n | 'numeric'\n | 'boolean'\n | 'timestamp'\n | 'jsonb'\n | 'enum'\n | 'vector';\n\n/** Base column definition shared by all column types. */\nexport interface ColumnDef {\n type: ColumnType;\n nullable: boolean;\n primaryKey: boolean;\n defaultValue?: unknown;\n defaultRandom?: boolean;\n defaultNow?: boolean;\n references?: { table: string; column: string };\n /** Pending FK target, resolved by `defineSchema` once every binding exists. */\n referencesThunk?: () => ColumnBuilder;\n /** FK onto THIS table — no thunk needed, the target is the declaring table. */\n selfRefColumn?: string;\n /** This column OWNS the row: erasure, RLS and the `owner` relation read it. */\n owns?: true;\n /** Explicit name for the FORWARD relation (child → parent), when the one\n * derived from the column would be ambiguous or unclear. */\n refAs?: string;\n /**\n * Explicit name for the REVERSE relation (parent → children).\n *\n * Separate from {@link refAs} because the two directions are different facts:\n * the forward name describes the parent this row points at (`author`), the\n * reverse one describes the rows hanging off the parent (`posts`). One option\n * naming both made an ordinary schema undeclarable — `posts.author_id` and\n * `comments.author_id` both named `{ as: \"author\" }` collided on `users`, and\n * the refusal asked for the `{ as }` they had both already written.\n */\n reverseAs?: string;\n /** The table this column belongs to; set by `defineTable`. */\n ownerTable?: { name: string; columns: Record<string, ColumnBuilder> };\n /**\n * The name this column used to have. A diff cannot tell a rename from a drop and\n * an add — both leave one name gone and another present — so the intent has to be\n * declared. Without it, renaming a column loses its data.\n */\n renamedFrom?: string;\n /**\n * This release's PROMISE that it does not reference this column — neither\n * reads it nor writes it, and never names it in a filter, a sort or a SET.\n *\n * The contraction gate reads it and nothing else does: dropping a column is\n * refused while the RUNNING release's declaration still lacks this mark, so\n * removing a column is two deploys — mark it, ship, then drop it.\n *\n * The word is `ignored` and not `deprecated` deliberately: RFC 9745 defines\n * deprecation as changing NO behaviour, and this changes what a deploy will\n * accept. Rails calls the same thing `ignored_columns`.\n */\n ignored?: boolean;\n onDeleteAction?: OnDeleteAction;\n /** FR-044: yalnız AÇIKÇA `false` bildirilince var. Türev FK index'ini kapatır. */\n index?: boolean;\n /** FR-049: kolon `increment()` ile güncelleniyor. Plan HOT çakışmasını uyarır. */\n counter?: boolean;\n enumName?: string;\n enumValues?: string[];\n unique?: boolean;\n /**\n * The value is written by the DATABASE — a trigger, a rule, an identity — not by\n * the author and not by a DEFAULT this schema declares. It makes the column\n * optional on INSERT without putting a DEFAULT in the DDL.\n *\n * Before this existed the only way to keep a trigger-filled column off the\n * INSERT type was to give it a fake `default()`: a value the schema claimed to\n * write and the trigger immediately overwrote. That made the schema lie about\n * its own data.\n */\n dbAssigned?: boolean;\n /** vector(n): the declared dimension count — part of the TYPE (typmod), read\n * by the wire serializer and the deploy's auto-index (FR-001). */\n dimensions?: number;\n /**\n * How the stored value is projected in and out of this process (FR-009).\n *\n * NOT part of the DDL: the column's Postgres type is unchanged and this pair\n * is never serialized into a migration. It exists so the row surface can hand\n * back the type the application actually works with.\n */\n /**\n * The named codec this column declares (FR-001). Unlike `transform`, the NAME\n * survives into the runtime object, so `makeEnvDts` can emit the matching\n * TypeScript type instead of falling back to the storage type. Not part of\n * the DDL: the column's Postgres type is unchanged.\n */\n codec?: CodecName;\n transform?: ColumnTransform;\n}\n\n/**\n * The read/write pair a column may declare (FR-009).\n *\n * `fromDb` takes whatever the driver produced for this column and returns the\n * value the application sees; `toDb` is its inverse on the way out. Kept\n * deliberately unexported — a column declares one inline, nobody needs to name\n * the shape.\n */\ninterface ColumnTransform<T = unknown> {\n fromDb: (value: unknown) => T;\n toDb: (value: T) => unknown;\n}\n\n/**\n * The closed set of named column codecs (FR-001).\n *\n * WHY A CLOSED SET rather than `.transform<T>()`. A transform's target type is\n * a TYPE parameter — erased at runtime — so the generator that reads the\n * bundled schema object cannot learn it. `palbase-env.d.ts` therefore said\n * `string` while the engine handed the application a number, and a consumer\n * project wrote a hand-rolled codec module plus 141 call sites to compensate.\n *\n * A codec is NAMED instead of typed: the name lands in `_def.codec`, travels in\n * the runtime object to every reader, and BOTH the conversion and the emitted\n * TypeScript type are derived from it. One declaration, one truth, and no way\n * for the two to disagree.\n */\nexport type CodecName = 'number' | 'decimal';\n\nexport const CODECS: Record<\n CodecName,\n { fromDb: (value: unknown) => unknown; toDb: (value: unknown) => unknown; tsType: 'number' | 'string' }\n> = {\n // Exact-precision column → JS number. Safe below 2^53; a value above it is\n // not representable and the author wants `asDecimal()` instead.\n number: {\n fromDb: (v) => Number(v),\n // YAZMA YOLUNDA SESSİZ BOZULMA YOK. `toDb(9007199254740993)` bir zamanlar\n // \"9007199254740992\" yazıyordu: uygulamanın tuttuğundan BAŞKA bir sayı\n // kolona gidiyordu ve hiçbir şey söylemiyordu. `asNumber()`'ın JSDoc'u\n // \"2^53'ün altında güvenli\" diyordu ama bunu uygulayan bir şey yoktu.\n toDb: (v) => {\n if (typeof v === 'number' && !Number.isSafeInteger(v)) {\n throw new Error(\n `asNumber() cannot write ${v}: it is outside the safe integer range and would be stored as a different number. Declare .asDecimal() and hand this column a string.`,\n );\n }\n return String(v);\n },\n tsType: 'number',\n },\n // Exact-precision column → the string Postgres sent. It exists so the\n // DECLARATION is explicit: \"this column is a decimal I handle as text\",\n // rather than the ABSENCE of a declaration meaning the same thing by default.\n // NULL güvencesi ÇİFTİN KENDİSİNDE. Motor NULL'ı zaten atlıyor (üç ayrı\n // yerde), ama bir değişmez, onu koruyan üç `if`'in DIŞINDA yazılmalı: biri\n // düşerse `String(null)` kolonu \"null\" dizesine çevirirdi.\n decimal: {\n fromDb: (v) => (v === null || v === undefined ? v : String(v)),\n toDb: (v) => (v === null || v === undefined ? v : String(v)),\n tsType: 'string',\n },\n};\n\n/** FR-002: a vector column cannot carry keys/defaults/references — the modifier\n * is named in the error so the author fixes the right line. */\nfunction refuseOnVector(def: ColumnDef, modifier: string): void {\n if (def.type === 'vector') {\n throw new Error(`vector column: .${modifier}() is not supported (FR-002 — allowed: nullable()/notNull())`);\n }\n}\n\n// Phantom brand symbols — never have runtime values; exist only to force\n// TypeScript's structural type system to distinguish ColumnBuilder instances\n// with different type-param combinations. Without these, TS sees all\n// ColumnBuilder<K,...> as structurally identical and the first branch of\n// ColValue matches everything.\ndeclare const __colKind: unique symbol;\ndeclare const __colNullable: unique symbol;\ndeclare const __colHasDefault: unique symbol;\ndeclare const __colEnumValues: unique symbol;\ndeclare const __colPayload: unique symbol;\ndeclare const __colTransform: unique symbol;\n\n/**\n * Fluent column builder with phantom type params:\n * K — ColumnType literal (e.g. \"text\", \"integer\")\n * N — boolean: true when nullable() has been called last (false = NOT NULL)\n * D — boolean: true when a default has been set\n * E — enum value union (never for non-enum columns)\n * P — jsonb payload shape (unknown unless jsonb<T>() supplied one)\n * T — transform target type (`never` when the column declares no transform;\n * `never` is the sentinel because it is the only type that survives\n * `[T] extends [never]` and never collides with a real target type)\n *\n * All six params have defaults so bare `ColumnBuilder` (no args) still\n * satisfies `Record<string, ColumnBuilder>` in schema.ts without modification.\n *\n * The six `declare readonly` brand fields carry the phantom types into the\n * structural shape so that conditional types like ColValue<C> can discriminate\n * on K without requiring runtime values on those fields.\n */\nexport class ColumnBuilder<\n K extends ColumnType = ColumnType,\n N extends boolean = boolean,\n D extends boolean = boolean,\n E = unknown,\n P = unknown,\n // `unknown`, not `never`: the schema's own constraint is a BARE\n // `ColumnBuilder`, whose T lands on this default. With `never` there, a\n // column that declares `.transform<number>()` is not assignable to the\n // constraint at all — `number` does not extend `never` — so a transform\n // could not appear in a schema and the whole table's `RowShape` collapsed.\n // Measured: TS2322 on `defineSchema`.\n T = unknown,\n> {\n // These fields exist only in the type layer (declared, never initialised at\n // runtime — TypeScript allows declared class members without an initializer\n // in strict mode as long as they're never read at runtime).\n declare readonly [__colKind]: K;\n declare readonly [__colNullable]: N;\n declare readonly [__colHasDefault]: D;\n declare readonly [__colEnumValues]: E;\n declare readonly [__colPayload]: P;\n declare readonly [__colTransform]: T;\n\n readonly _def: ColumnDef;\n\n constructor(type: K, existingDef?: ColumnDef) {\n this._def = existingDef ?? {\n type,\n nullable: false,\n primaryKey: false,\n };\n }\n\n /** Mark this column as the primary key. */\n primaryKey(): ColumnBuilder<K, N, D, E, P, T> {\n refuseOnVector(this._def, 'primaryKey');\n this._def.primaryKey = true;\n return new ColumnBuilder<K, N, D, E, P, T>(this._def.type as K, this._def);\n }\n\n /** Mark this column as NOT NULL (default). */\n notNull(): ColumnBuilder<K, false, D, E, P, T> {\n this._def.nullable = false;\n return new ColumnBuilder<K, false, D, E, P, T>(this._def.type as K, this._def);\n }\n\n /** Allow NULL values. */\n nullable(): ColumnBuilder<K, true, D, E, P, T> {\n this._def.nullable = true;\n return new ColumnBuilder<K, true, D, E, P, T>(this._def.type as K, this._def);\n }\n\n /** Set a default value. */\n default(value: unknown): ColumnBuilder<K, N, true, E, P, T> {\n refuseOnVector(this._def, 'default');\n this._def.defaultValue = value;\n return new ColumnBuilder<K, N, true, E, P, T>(this._def.type as K, this._def);\n }\n\n /** UUID: generate a random default (gen_random_uuid()). */\n defaultRandom(): ColumnBuilder<K, N, true, E, P, T> {\n refuseOnVector(this._def, 'defaultRandom');\n this._def.defaultRandom = true;\n return new ColumnBuilder<K, N, true, E, P, T>(this._def.type as K, this._def);\n }\n\n /** Timestamp: default to now(). */\n defaultNow(): ColumnBuilder<K, N, true, E, P, T> {\n refuseOnVector(this._def, 'defaultNow');\n this._def.defaultNow = true;\n return new ColumnBuilder<K, N, true, E, P, T>(this._def.type as K, this._def);\n }\n\n /**\n * The DATABASE assigns this column's value — a trigger, a rule, an identity.\n *\n * The column becomes optional on INSERT (the author has nothing to send) while\n * the DDL stays free of a DEFAULT this schema would not honour. It is NOT\n * `default()`: that declares a value the schema promises to write.\n *\n * Naming: deliberately not `generated()`. Postgres has GENERATED columns and\n * they are a different thing; borrowing the word would send a reader — or a\n * model writing a schema — to the wrong feature.\n */\n dbAssigned(): ColumnBuilder<K, N, true, E, P, T> {\n this._def.dbAssigned = true;\n return new ColumnBuilder<K, N, true, E, P, T>(this._def.type as K, this._def);\n }\n\n /** Add a foreign key reference. */\n /**\n * Declares that this column used to be called `previous`.\n *\n * A schema diff sees one name gone and another present; it cannot know whether\n * you renamed a column or dropped one and added another, and the two are very\n * different — the second loses every value. Saying so here turns the plan into\n * `ALTER TABLE … RENAME COLUMN` instead.\n *\n * Once the rename has been applied the annotation is inert (the old name is no\n * longer there to rename), so it can be deleted at your leisure.\n */\n renamedFrom(previous: string): ColumnBuilder<K, N, D, E, P, T> {\n this._def.renamedFrom = previous;\n return this as unknown as ColumnBuilder<K, N, D, E, P, T>;\n }\n\n /**\n * See {@link ColumnDef.ignored}.\n *\n * COPIES the def rather than mutating it. The constructor takes an existing\n * def BY REFERENCE, so every builder derived from another shares one object —\n * `const a = slug.unique()` leaves `a._def === slug._def`. An in-place\n * `ignored = true` therefore marks every column sharing that def, including\n * one another table actively reads, and the gate would let THAT column be\n * dropped. Measured before this copy existed.\n *\n * The aliasing is older than this method and other fields leak through it too.\n * The reason this one cannot wait: every other leak produces a VISIBLE schema\n * difference — the plan shows it, the DDL shows it. This one is invisible by\n * design (no DDL, no diff, no plan line), so its only effect is to disarm a\n * safety gate in silence.\n */\n ignored(): ColumnBuilder<K, N, D, E, P, T> {\n return new ColumnBuilder<K, N, D, E, P, T>(this._def.type as K, {\n ...this._def,\n ignored: true,\n });\n }\n\n /**\n * Foreign key onto another table's column.\n *\n * The target is a THUNK, not a direct reference. In a cycle (`x → y`, `y → x`)\n * the second table does not exist yet when the first is built; a direct\n * reference makes TypeScript chase its own tail (TS7022 — measured, and making\n * the return type independent of the target does NOT help). The thunk is\n * invoked in `defineSchema`, where every binding exists and every table\n * already knows its name.\n *\n * In a cycle, ONE side needs an explicit return type:\n * `references((): AnyColumn => y.id)`. One side is enough — measured.\n * For a self-reference use `selfReferences(column)`: no thunk, no annotation.\n *\n * `as` names the FORWARD relation (`author_id` → `author` by default);\n * `reverseAs` names the REVERSE one on the parent, whose default is this\n * table's own name (`users.posts`). Two foreign keys from one table onto one\n * parent therefore need a `reverseAs` on at least one of them — the reverse\n * names would otherwise both be this table's name.\n */\n references(\n target: () => AnyColumn,\n opts?: {\n as?: string;\n reverseAs?: string;\n onDelete?: OnDeleteAction;\n /**\n * Bu FK kolonu için TÜREVİ index üretilsin mi (FR-044). Varsayılan açık.\n *\n * Postgres bir foreign key'i otomatik indekslemez — yalnız hedef\n * taraftaki unique kısıt vardır. Bedeli FK üzerinden her JOIN'de ve her\n * `ON DELETE CASCADE`'de ödenir: bir parent silinirken child tablo tam\n * taranır.\n *\n * `false` demek gerçek bir ihtiyaç, nezaket değil (D-028): FK kolonu aynı\n * zamanda SIK GÜNCELLENEN bir kolonsa index HOT güncellemeyi kırar — ve\n * HOT, DEĞİŞEN kolon indeksliyse kırılır, tablo indeksli diye değil.\n */\n index?: boolean;\n },\n ): ColumnBuilder<K, N, D, E, P, T> {\n refuseOnVector(this._def, 'references');\n if (typeof target !== 'function') {\n // Fail where the mistake is. Storing a non-thunk here surfaces three\n // layers later as \"def.referencesThunk is not a function\", inside\n // defineSchema, naming neither the column nor the call that was wrong.\n throw new Error(\n `references(...) takes a callback: write references(() => otherTable.column). ` +\n `The two-string form references(\"table\", \"column\") is gone — a string cannot be type-checked ` +\n `and cannot point at a table that does not exist yet.`,\n );\n }\n this._def.referencesThunk = target;\n if (opts?.as !== undefined) this._def.refAs = opts.as;\n if (opts?.reverseAs !== undefined) this._def.reverseAs = opts.reverseAs;\n if (opts?.onDelete !== undefined) this._def.onDeleteAction = opts.onDelete;\n // Yalnız AÇIKÇA false bildirilince taşınıyor: `undefined` \"bildirilmedi,\n // türet\" demek ve wire'da hiç görünmemeli (bayt-aynılık).\n if (opts?.index === false) this._def.index = false;\n return new ColumnBuilder<K, N, D, E, P, T>(this._def.type as K, this._def);\n }\n\n /**\n * Bu kolon `increment()` / `decrement()` ile güncelleniyor (FR-049).\n *\n * Deploy kontrolcü kodunu OKUMAZ, o yüzden bildirimin söylemesi gerekiyor —\n * ve söylediği anda plan bir şeyi görebiliyor: aynı kolon hem sayaç hem\n * indeksliyse her güncelleme HOT'u kaybeder.\n *\n * ZİNCİR (D-028+D-030): HOT kaybı → ölü tuple → autovacuum yükü → ve\n * autovacuum worker'ları KÜME GENELİNDE bir kaynak, yani bedeli başka\n * kiracıların tabloları da öder.\n *\n * Sektörde çare \"dokümana uyarı yaz\"dır, çünkü index'i ekleyen kişi\n * `increment()`'i yazan kişi değildir. Bu bildirimde ikisi de YAN YANA\n * duruyor.\n *\n * Uyarı, HATA DEĞİL: sayaç kolonunu indekslemek bazen doğru karardır.\n */\n counter(): ColumnBuilder<K, N, D, E, P, T> {\n this._def.counter = true;\n return new ColumnBuilder<K, N, D, E, P, T>(this._def.type as K, this._def);\n }\n\n /**\n * Foreign key onto THIS table (`parent_id → id`) — category trees, comment\n * replies, org charts.\n *\n * No thunk and no type annotation: the target table is the one being declared,\n * so there is nothing to defer and nothing for TypeScript to chase in a circle.\n * Drizzle forces an explicit `(): AnyPgColumn =>` here because its reference\n * always goes through a callback; measured, we do not need one.\n */\n selfReferences(\n column: string,\n opts?: { as?: string; onDelete?: OnDeleteAction },\n ): ColumnBuilder<K, N, D, E, P, T> {\n refuseOnVector(this._def, 'selfReferences');\n this._def.selfRefColumn = column;\n if (opts?.as !== undefined) this._def.refAs = opts.as;\n if (opts?.onDelete !== undefined) this._def.onDeleteAction = opts.onDelete;\n return new ColumnBuilder<K, N, D, E, P, T>(this._def.type as K, this._def);\n }\n\n\n\n /** Set the ON DELETE action for a foreign key reference. */\n onDelete(action: OnDeleteAction): ColumnBuilder<K, N, D, E, P, T> {\n this._def.onDeleteAction = action;\n return new ColumnBuilder<K, N, D, E, P, T>(this._def.type as K, this._def);\n }\n\n /** Add a single-column UNIQUE constraint. */\n unique(): ColumnBuilder<K, N, D, E, P, T> {\n refuseOnVector(this._def, 'unique');\n this._def.unique = true;\n return new ColumnBuilder<K, N, D, E, P, T>(this._def.type as K, this._def);\n }\n\n /**\n * Declare how this column's value is projected in and out of the process.\n *\n * The DDL does not move: `numeric` stays `numeric`, and the driver still hands\n * back what Postgres sent. What changes is the type the row surface exposes —\n * it becomes `Target`:\n *\n * amount: numeric().transform<number>({ fromDb: Number, toDb: String })\n *\n * `numeric` surfacing as `string` is CORRECT (a JS number cannot hold\n * arbitrary precision), and that is exactly why this exists: application code\n * that does arithmetic on the column otherwise rewrites the same\n * `Number(row.amount)` / `String(x)` pair in every controller that touches it,\n * and each rewrite is a place the two directions can drift apart.\n *\n * A transform is a PROJECTION, never a constraint: it lives only in this\n * process, so it can neither validate nor migrate what is stored.\n */\n /**\n * Surface this exact-precision column as a JS `number` (FR-001).\n *\n * `numeric`/`bigint` arrive as strings because a JS number cannot hold their\n * full range — correct, and exactly why this exists: application code that\n * does arithmetic on the column otherwise rewrites the same `Number(row.x)` /\n * `String(v)` pair in every caller, and each rewrite is a place the two\n * directions can drift apart.\n */\n asNumber(): ColumnBuilder<K, N, D, E, P, number> {\n return this.withCodec<number>('number', 'asNumber');\n }\n\n /**\n * Surface this exact-precision column as a `string` — the value Postgres\n * sent, DECLARED rather than defaulted (FR-001).\n */\n asDecimal(): ColumnBuilder<K, N, D, E, P, string> {\n return this.withCodec<string>('decimal', 'asDecimal');\n }\n\n private withCodec<Target>(codec: CodecName, method: string): ColumnBuilder<K, N, D, E, P, Target> {\n if (this._def.type !== 'bigint' && this._def.type !== 'numeric') {\n throw new Error(\n `${this._def.type} column: .${method}() is only available on bigint()/numeric() — ` +\n `those are the exact-precision types that surface as string.`,\n );\n }\n if (this._def.transform !== undefined) {\n throw new Error(\n `.${method}() and .transform() are two ways to say the same thing on one column — keep .${method}().`,\n );\n }\n if (this._def.codec !== undefined) {\n throw new Error(\n `column already declares .as${this._def.codec === 'number' ? 'Number' : 'Decimal'}(); a column has ONE codec.`,\n );\n }\n // KOPYA, MUTASYON DEĞİL — `ignored()` gibi.\n //\n // `this._def.codec = codec` yazmak, ORTAK bir temelden çatallanan iki\n // kolonun ikisine de SON codec'i verirdi. Ölçüldü:\n // const money = numeric().notNull();\n // money.asNumber(); money.asDecimal();\n // → ikisinin de _def.codec === 'decimal', ve AYNI nesne.\n // Birincinin TİPİ `number`, üretecin bastığı tip `string` olurdu — yani bu\n // özelliğin kapatmak için var olduğu ayrışmanın ta kendisi.\n return new ColumnBuilder<K, N, D, E, P, Target>(this._def.type as K, {\n ...this._def,\n codec,\n });\n }\n\n transform<Target>(fns: ColumnTransform<Target>): ColumnBuilder<K, N, D, E, P, Target> {\n // AYNA KONTROLÜ. `asNumber()` mevcut bir transform'u reddediyor; burası da\n // mevcut bir codec'i reddetmeli, yoksa kapı TEK YÖNLÜ olur:\n // `numeric().asNumber().transform<Date>(…)` üç ayrı cevap üretirdi —\n // builder tipi `Date`, üretilen tip `number`, motor `Number()` uygular —\n // ve hiçbir şey adını söyleyerek reddetmezdi.\n if (this._def.codec !== undefined) {\n throw new Error(\n `column already declares a named codec; .transform() and .as*() are two ways to say the same thing — keep the codec.`,\n );\n }\n // The cast is the variance, not a shortcut: `toDb` takes `Target`, and a\n // `ColumnTransform<unknown>` would have to accept anything. The stored pair\n // is only ever called with this column's own values.\n return new ColumnBuilder<K, N, D, E, P, Target>(this._def.type as K, {\n ...this._def,\n transform: fns as ColumnTransform,\n });\n }\n}\n\n// ---------------------------------------------------------------------------\n// Type extractors — imported by Task 2 to derive insert/row shapes.\n// ---------------------------------------------------------------------------\n\n/**\n * Extracts the TypeScript value type for a column, respecting nullability.\n * - \"uuid\" | \"text\" | \"timestamp\" | \"bigint\" | \"numeric\" → string (or string | null when N = true)\n * Note: bigint/numeric surface as string — JS number loses precision past 2^53,\n * and pgx/PostgREST serialize int8/numeric as strings. App code uses\n * BigInt(row.amount) for bigint, or a decimal lib for numeric.\n * - \"integer\" → number\n * - \"boolean\" → boolean\n * - \"jsonb\" → P (the dev-supplied payload shape from jsonb<T>(), else unknown)\n * - \"enum\" → E (the union of literal values)\n *\n * A declared `.transform<T>()` OVERRIDES the table above: the column then\n * surfaces as T (or T | null when nullable), because that is the value the\n * application is handed. Nullability is still the column's, not the\n * transform's — `fromDb` is not called for a NULL.\n */\nexport type ColValue<C> =\n C extends ColumnBuilder<ColumnType, infer N, boolean, unknown, unknown, infer T>\n ? [unknown] extends [T]\n ? ColStoredValue<C>\n : N extends true\n ? T | null\n : T\n : never;\n\n/** The value as the DATABASE hands it over — the branch table above, before any\n * transform. This is what a column's `fromDb` receives. */\ntype ColStoredValue<C> =\n C extends ColumnBuilder<'uuid' | 'text' | 'timestamp' | 'bigint' | 'numeric', infer N, infer _D, infer _E, infer _P>\n ? N extends true\n ? string | null\n : string\n : C extends ColumnBuilder<'integer', infer N, infer _D, infer _E, infer _P>\n ? N extends true\n ? number | null\n : number\n : C extends ColumnBuilder<'boolean', infer N, infer _D, infer _E, infer _P>\n ? N extends true\n ? boolean | null\n : boolean\n : C extends ColumnBuilder<'jsonb', infer N, infer _D, infer _E, infer P>\n ? N extends true\n ? P | null\n : P\n : C extends ColumnBuilder<'vector', infer N, infer _D, infer _E, infer _P>\n ? N extends true\n ? number[] | null\n : number[]\n : C extends ColumnBuilder<'enum', infer N, infer _D, infer E, infer _P>\n ? N extends true\n ? E | null\n : E\n : never;\n\n/**\n * True when a column is optional on INSERT:\n * - nullable columns (N = true) — the DB allows NULL so the field may be omitted\n * - columns with a default (D = true) — the DB fills in the value when absent\n */\nexport type ColIsOptionalOnInsert<C> =\n C extends ColumnBuilder<ColumnType, true, boolean, unknown, unknown, unknown>\n ? true\n : C extends ColumnBuilder<ColumnType, boolean, true, unknown, unknown, unknown>\n ? true\n : false;\n\n// ---------------------------------------------------------------------------\n// Factory functions\n// ---------------------------------------------------------------------------\n\n/** Create a UUID column. */\nexport function uuid(): ColumnBuilder<'uuid', false, false, never> {\n return new ColumnBuilder('uuid');\n}\n\n/** Create a TEXT column. */\nexport function text(): ColumnBuilder<'text', false, false, never> {\n return new ColumnBuilder('text');\n}\n\n/** Create an INTEGER column. Emits int4 (max ~2.1B). */\nexport function integer(): ColumnBuilder<'integer', false, false, never> {\n return new ColumnBuilder('integer');\n}\n\n/**\n * Create a BIGINT column (Postgres int8, max ~9.2×10^18).\n * Surfaces as `string` in row/insert types — JS number loses precision past 2^53\n * and pgx/PostgREST serialize int8 as a JSON string. Use BigInt(row.column) in app code.\n */\nexport function bigint(): ColumnBuilder<'bigint', false, false, never> {\n return new ColumnBuilder('bigint');\n}\n\n/**\n * Create a NUMERIC column (Postgres `numeric`/`decimal`, arbitrary precision).\n * For exact fractional values (money with cents as a decimal, rates, weights)\n * where int4/int8 don't fit. Surfaces as `string` in row/insert types — JS\n * number can't hold arbitrary-precision decimals without rounding, and\n * pgx/PostgREST serialize numeric as a JSON string. Parse with a decimal lib\n * (or BigInt for scaled integers) in app code.\n */\nexport function numeric(): ColumnBuilder<'numeric', false, false, never> {\n return new ColumnBuilder('numeric');\n}\n\n/** Create a BOOLEAN column. */\nexport function boolean(): ColumnBuilder<'boolean', false, false, never> {\n return new ColumnBuilder('boolean');\n}\n\n/** Create a TIMESTAMP column. */\nexport function timestamp(): ColumnBuilder<'timestamp', false, false, never> {\n return new ColumnBuilder('timestamp');\n}\n\n/**\n * Create a JSONB column. Pass a payload type to make the generated row/insert\n * type concrete instead of `unknown`:\n *\n * tags: jsonb<string[]>() // row.tags: string[]\n * meta: jsonb<{ tier: string }>() // row.meta: { tier: string }\n * raw: jsonb() // row.raw: unknown (back-compat)\n *\n * The runtime accepts a plain JS object/array directly (no JSON.stringify); the\n * generic only refines the TYPE the env codegen emits.\n */\nexport function jsonb<T = unknown>(): ColumnBuilder<'jsonb', false, false, never, T> {\n return new ColumnBuilder('jsonb');\n}\n\n/**\n * Create an ENUM column.\n * @param name The PostgreSQL enum type name (used in DDL).\n * @param values A readonly tuple of valid string values — kept `const` so the\n * union `V[number]` is as narrow as possible.\n */\nexport function enumType<const V extends readonly string[]>(\n name: string,\n values: V,\n): ColumnBuilder<'enum', false, false, V[number]> {\n const builder = new ColumnBuilder<'enum', false, false, V[number]>('enum');\n builder._def.enumName = name;\n builder._def.enumValues = [...values];\n return builder;\n}\n\n/** vector(n) — pgvector kolonu. n TİPİN parçasıdır (typmod) ve [1, 2000] —\n * 2000 = pgvector'ün HNSW-indekslenebilir tavanı; auto-index bu beyanla bağlı\n * (spec FR-001, D-3). */\nexport function vector(dimensions: number): ColumnBuilder<'vector', false, false, unknown, number[]> {\n if (!Number.isInteger(dimensions) || dimensions < 1 || dimensions > 2000) {\n throw new Error(`vector(): dimensions must be an integer in [1, 2000], got ${String(dimensions)}`);\n }\n const b = new ColumnBuilder('vector') as ColumnBuilder<'vector', false, false, unknown, number[]>;\n (b._def as { dimensions?: number }).dimensions = dimensions;\n return b;\n}\n\n/**\n * Any column, whatever its type parameters.\n *\n * Exported so a cycle can be broken from ONE side:\n * `references((): AnyColumn => y.id)`.\n */\nexport type AnyColumn = ColumnBuilder;\n\n/**\n * The column that OWNS this row: a `text` FK onto `auth.users(id)`, NOT NULL,\n * ON DELETE CASCADE.\n *\n * Ownership drives account erasure, so cascade is the only correct action and\n * takes no argument. The referencing column must be `text` (palauth ids are\n * `usr_<uuid>`) and NOT NULL — both are implied here rather than left to the\n * caller, so three rules the type could not express before become UNWRITABLE.\n *\n * At most ONE per table. The old shape let several columns reference\n * `auth.users` and picked the FIRST IN DECLARATION ORDER as the owner — moving a\n * `created_by` above a `user_id` silently changed which rows an account deletion\n * took with it. A second one is now rejected at push.\n *\n * For a column that merely POINTS at a user without owning the row\n * (`created_by`, `edited_by`), use `userRef({ onDelete })`.\n */\nexport function ownedByUser(): ColumnBuilder<'text', false, false, never> {\n const b = new ColumnBuilder<'text', false, false, never>('text');\n b._def.nullable = false;\n b._def.references = { table: 'auth.users', column: 'id' };\n b._def.onDeleteAction = 'cascade';\n b._def.owns = true;\n return b;\n}\n\n/**\n * A plain FK onto `auth.users(id)` that does NOT own the row.\n *\n * `created_by` / `edited_by`: deleting that user must not delete the row. ON\n * DELETE is required and limited to `cascade | set null` so an erasure request\n * is never blocked by a lingering FK; `set null` needs a nullable column.\n */\nexport function userRef(opts: { onDelete: AuthUserOnDelete; as?: string }): ColumnBuilder<'text', boolean, false, never> {\n const b = new ColumnBuilder<'text', boolean, false, never>('text');\n b._def.references = { table: 'auth.users', column: 'id' };\n b._def.onDeleteAction = opts.onDelete;\n if (opts.as !== undefined) b._def.refAs = opts.as;\n return b;\n}\n\n/**\n * A plain FK onto `auth.installations(id)` — the app-scoped verified-device\n * anchor.\n *\n * An installation is an APP INSTALL, not a user: this is NOT ownership. A\n * user-owned row still needs its own `ownedByUser()` so account erasure removes\n * it; an installation reference alone does not tie a row to a user's deletion.\n */\nexport function installationRef(opts: { onDelete: AuthUserOnDelete; as?: string }): ColumnBuilder<'text', boolean, false, never> {\n const b = new ColumnBuilder<'text', boolean, false, never>('text');\n b._def.references = { table: 'auth.installations', column: 'id' };\n b._def.onDeleteAction = opts.onDelete;\n if (opts.as !== undefined) b._def.refAs = opts.as;\n return b;\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.public.<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 */\nimport { DeclarationRefused } from \"../refusals.js\";\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\";\nimport { uniqueKeysOf } from \"./unique.js\";\nimport { CODECS } from \"./columns.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 // A NAMED CODEC DECIDES THE SURFACED TYPE, and it is read BEFORE the switch\n // because the codec is exactly the declaration that overrides the storage\n // type. `numeric` surfacing as `string` is correct by default; `asNumber()`\n // is the author saying \"in this process it is a number\", and the engine\n // already makes that true (FR-003).\n if (def.codec !== undefined && def.codec in CODECS) {\n return CODECS[def.codec].tsType;\n }\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 // `unknown` DEĞİL: `unknown` taşıyan bir kolonda filtre birleşimi\n // (`V | ColRef | …`) tamamen `unknown`'a çöker, yani HİÇBİR kural\n // tutunamaz — `col()` o kolonu her şeyle karşılaştırabiliyordu\n // (D-021'in açık bıraktığı son delik). `Json` gerçek kısıtı söylüyor ve\n // markalanabiliyor.\n return \"Json\";\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 // TÜKETİCİLİK KAPISI. `ColumnType`'a yeni bir değer eklenip burası\n // güncellenmezse BU SATIR DERLEME HATASI verir.\n //\n // Eskiden burası sessizce `unknown` döndürüyordu ve `unknown` taşıyan bir\n // kolonda filtre birleşimi tamamen `unknown`'a çöker — yani `col()`,\n // `now()`, toplama, hepsi o kolonda kuralsız kalırdı. `numeric` bir\n // zamanlar tam olarak buraya düşmüştü (\"numeric had no case at all\"),\n // ve `jsonb` aynı çöküşü 28.0.0'a kadar yaşadı. Üçüncüsü olmasın.\n const unhandled: never = def.type;\n throw new Error(\n `env-gen: \"${String(unhandled)}\" kolon tipinin TypeScript karşılığı ` +\n `bildirilmemiş. baseTsType'a bir case ekleyin — sessizce \\`unknown\\` ` +\n `dönmek o kolonu her kuralın dışına çıkarır.`,\n );\n }\n }\n}\n\n/** The full row type for a column: base type, `| null` when nullable. */\n/**\n * Kolonun POSTGRES tipi, tipin İÇİNDE taşınan bir marka olarak.\n *\n * TypeScript `numeric`, `bigint`, `text`, `uuid` ve `timestamp`'i tek bir\n * `string`'e düşürüyor. Yani `integer ↔ numeric` (Postgres'te geçerli) ile\n * `integer ↔ text` (geçersiz) tipte AYNI görünüyordu ve `col()` hangi kuralı\n * koyarsa koysun bir tarafta yanılıyordu (D-021: yanlış ret mi yanlış kabul mü\n * seçilecekti — ikisi de yanlıştı).\n *\n * Marka o bilgiyi geri getiriyor. `& { readonly __pg?: \"…\" }` seçilmesinin\n * nedeni ÖLÇÜLDÜ: isteğe bağlı bir alanla kesişim, satırı hâlâ düz `string`\n * olarak okunabilir ve düz bir değerle YAZILABİLİR bırakıyor — yani marka\n * yalnız karşılaştırma kurallarının gördüğü, kullanıcının hiç görmediği bir\n * bilgi. Zorunlu bir alan olsaydı `{ balance: \"10.00\" }` derlenmezdi.\n *\n * `enum` KİMLİĞİYLE markalanıyor: iki FARKLI enum'u Postgres de karşılaştırmaz,\n * ve düz `\"enum\"` markası onları aynı sayardı.\n */\nfunction pgBrand(def: ColumnDef): string {\n if (def.type === \"enum\") {\n const values = [...(def.enumValues ?? [])].sort();\n return values.length === 0 ? \"enum\" : `enum:${values.join(\"|\")}`;\n }\n return def.type;\n}\n\nfunction rowType(def: ColumnDef): string {\n const base = baseTsType(def);\n // `unknown` MARKALANAMAZ: marka bir kesişim ve `unknown & X` doğrudan `X`'e\n // çöker. `jsonb` kolonu `Pg<unknown, \"jsonb\">` yazılınca tipi\n // `{ readonly __pg?: \"jsonb\" }` oluyordu — yani kolon DARALDI ve meşru bir\n // nesne yazılamaz hâle geldi. GERÇEK bir projede ölçüldü: 33 tablolu bir\n // şemada `user_preferences`'ın jsonb kolonlarına yazan iki çağrı kırıldı.\n //\n // Markasız kalan kolon eski (gevşek) kurala düşer — jsonb için bu zaten\n // bugünkü davranış, yani hiçbir şey kötüleşmiyor.\n\n // Takma ad, ham kesişim yerine: bu dosyayı GELİŞTİRİCİ de açıyor ve\n // `(string) & { readonly __pg?: \"uuid\" }` satırları okunmaz kılıyordu.\n // `Pg<string, \"uuid\">` hem kısa hem kolonun Postgres tipini SÖYLÜYOR.\n // Takma ad ayrıca `enum` birleşimlerini tip argümanı olarak sarmalıyor —\n // ham kesişimde `A | B & C`, `A | (B & C)` diye ayrışıp bir dalı markasız\n // bırakırdı.\n const branded = `Pg<${base}, ${JSON.stringify(pgBrand(def))}>`;\n return def.nullable ? `${branded} | null` : branded;\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 DeclarationRefused(\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 DeclarationRefused(\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 // FR-004: `can` — adlandırılmış UPDATE policy adlarının literal union'ı.\n // Policy'siz tabloda `never[]`: alan hep var (motor `[]` yazar), eleman yok.\n // Gerçek bir `can` kolonu varsa yankı yoktur (motor da kolonu korur): ikinci\n // bir `can:` satırı `skipLibCheck` altında sessizce İLK bildirime çözülürdü.\n // İlişki de aynı rezervasyon (defineTable reddeder; ham TableDef için kemer).\n const hasCanColumn =\n Object.prototype.hasOwnProperty.call(table.columns, \"can\") || relations.some((r) => r.name === \"can\");\n // Motorla aynı süzgeç: 59 baytı aşan ad (`can:` + ad > NAMEDATALEN 63) telde asla gelmez.\n const canNames = (table.policies ?? []).filter((p) => p.command === \"update\" && p.permissive !== false && Buffer.byteLength(`can:${p.name}`, \"utf8\") <= 63).map((p) => JSON.stringify(p.name));\n // The contract travels with the type (final review M-2): a reader of the .d.ts\n // sees what `can` is for without opening the docs.\n const canDoc = `${indent} /** Names of this table's UPDATE policies whose \\`using\\` is true for THIS row and caller — an AFFORDANCE for the interface (draw or hide a control); never an authorization decision, may be incomplete, the server decides again on every request. */`;\n const canLine = hasCanColumn ? null : `${canDoc}\\n${indent} can: ${canNames.length === 0 ? \"never[]\" : `(${canNames.join(\" | \")})[]`};`;\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 ...(canLine === null ? [] : [canLine]),\n `${indent} };`,\n `${indent} insert: {`,\n ...insertLines,\n `${indent} };`,\n `${indent} relations: {${relEntries === \"\" ? \"\" : ` ${relEntries} `}};`,\n `${indent} uniqueKeys: ${JSON.stringify(uniqueKeysOf(table))};`,\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 // appendOnly (FR-031): EnvTypedTable'ın altı yazma üyesini KALDIRAN yapısal\n // bayrak. `searchable` ile aynı desen ve aynı OMIT disiplini — bayrak yokken\n // satır hiç üretilmez ki mevcut şemaların d.ts'i bayt-aynı kalsın.\n ...(table.appendOnly === true ? [`${indent} appendOnly: true;`] : []),\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 */\n/**\n * A free-form `.transform<T>()` CANNOT be typed here, and must not be typed\n * WRONG (FR-004).\n *\n * The target type is a TYPE PARAMETER — erased at runtime. This generator reads\n * the bundled runtime object, so it only ever saw `{ fromDb, toDb }` and fell\n * through to the storage type: it emitted `string` for a column the engine hands\n * back as a number. A consumer project measured exactly this and wrote a\n * hand-rolled codec module plus 141 call sites rather than trust the types.\n *\n * Refusing is the fix, not a limitation: the remedy is named in the message and\n * produces BOTH the conversion and the type from one declaration.\n */\nfunction refuseFreeFormTransforms(schemas: readonly SchemaDef[]): void {\n for (const schema of schemas) {\n for (const table of Object.values(schema.tables)) {\n for (const [col, builder] of Object.entries(table.columns)) {\n const def = builder._def;\n if (def.transform === undefined || def.codec !== undefined) continue;\n const where = qualifiedTableKey(schema.name, table.name);\n // `DeclarationRefused`, NOT a bare Error. `refusals.ts` carries the\n // measured reason: a bare Error from this layer is treated as FATAL by\n // the runtime, the supervisor takes the pod down and palsvc with it —\n // and palsvc is THE PROCESS THAT ACCEPTS THE PUSH this message asks\n // for. The cure must not kill the thing that delivers it.\n throw new DeclarationRefused(\n `table \"${where}\" column \"${col}\" declares .transform<T>(): its target type does not exist at ` +\n `runtime, so the generated types would say something the engine contradicts. Declare a named ` +\n `codec instead — .asNumber() for a JS number, .asDecimal() for the exact string.`,\n );\n }\n }\n }\n}\n\nexport function makeEnvDts(schemas: readonly SchemaDef[]): string {\n refuseFreeFormTransforms(schemas);\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.public.*\\`\n// is typed with no import and no generic. Schemas other than \\`public\\` land\n// under \\`Schemas\\`, reached with \\`Database.schema(\"<name>\").tables.*\\`.\n\n/**\n * Kolonun POSTGRES tipini tipte tasiyan marka.\n *\n * __pg ISTEGE BAGLI oldugu icin satir hala duz string/number gibi okunur ve duz\n * bir degerle yazilir — marka yalniz col() ve now() karsilastirma kurallarinin\n * gordugu bir bilgidir. TypeScript numeric, bigint, text, uuid ve timestamp'i\n * tek string'e dusurdugu icin bu bilgi olmadan integer<->numeric (gecerli) ile\n * integer<->text (gecersiz) ayirt edilemiyordu.\n */\ntype Pg<T, N extends string> = T & { readonly __pg?: N };\n\n/**\n * Bir jsonb kolonunun tasiyabilecegi deger.\n *\n * undefined DAHIL, cunku JSON.stringify undefined alanlari duserur ve\n * { a: undefined } yazan kod her yerde var — reddetmek dogru olmazdi.\n */\ntype Json = string | number | boolean | null | undefined | Json[] | { [k: string]: Json };\n\ndeclare module \"@palbase/backend/env\" {\n interface Tables {${body}}\n interface Schemas {${schemasBody}}\n}\n\nexport {};\n`;\n}\n","import type { SqlDriver } from \"./db.js\";\n\n/** The control pool must be separate from the application pool, connect as the\n * same session user and to the same PostgreSQL server. Cancellation must still\n * have a connection when every application connection is occupied. */\nexport function withQueryCancellation(application: SqlDriver, control: SqlDriver): SqlDriver & { close(): Promise<void> } {\n if (application === control) throw new Error(\"Query cancellation requires a separate control pool\");\n const close = async (driver: SqlDriver) => {\n const d = driver as SqlDriver & { close?: () => unknown; end?: () => unknown };\n if (d.close) await d.close(); else if (d.end) await d.end();\n };\n return {\n unsafe: (sql, params) => application.unsafe(sql, params),\n begin: fn => application.begin(fn),\n async cancelBackend(pid, startedAt) {\n // A PID alone is insufficient after a backend exits and the OS reuses\n // it. Match its start time and original login, using a bound PID.\n await control.unsafe(`SELECT pg_cancel_backend(pid) FROM pg_stat_activity\n WHERE pid=$1::integer AND backend_start=$2::timestamptz\n AND usename=session_user AND datname=current_database() AND backend_type='client backend'`, [pid, startedAt]);\n },\n async close() { await close(application); await close(control); },\n };\n}\n","// The decorator registry — the single plain-data store the method + parameter\n// decorators write into, and the deploy/dispatch pipeline reads back. No\n// `reflect-metadata`, no `emitDecoratorMetadata`: the registry is built from the\n// decorator arguments + the parameter INDEX that esbuild/tsc preserve for legacy\n// parameter decorators (verified — see the design spec §0/§4.1).\n//\n// A controller class carries its route metadata on a symbol-keyed static\n// property (`ROUTES`). `@Get`/`@Post`/… append a {@link RouteMeta} entry;\n// `@Body`/`@User`/… append a {@link ParamMeta} entry onto the route for the\n// method they decorate. Because parameter decorators run BEFORE the method\n// decorator for the same member (TS evaluates innermost-first, params before the\n// method), the route entry may not exist yet when a param decorator fires — so\n// param metadata is buffered per method name and merged when the method\n// decorator creates the route entry.\nimport type { AuthSpec, RateLimitConfig } from \"../endpoint.js\";\nimport type { UploadConfig } from \"./upload.js\";\nimport type { SseConfig } from \"./sse.js\";\nimport type { ZodTypeAny } from \"zod\";\n\n/** The HTTP verbs a route may declare, upper-cased (the runtime router +\n * OpenAPI lower-case on their own). */\nexport type HttpMethodUpper = \"GET\" | \"POST\" | \"PUT\" | \"PATCH\" | \"DELETE\" | \"QUERY\";\n\n/** Route-level options accepted by the method decorators (`@Get`/`@Post`/…). */\nexport interface RouteOptions {\n /** Enforced before statements and COMMIT; include retries and service queries. */\n databaseBudget?: import(\"../db/diagnostics.js\").DatabaseBudget;\n /** OVERRIDES the controller-level default auth for this one route. */\n auth?: AuthSpec;\n /** Per-route rate limit. */\n rateLimit?: RateLimitConfig;\n /** Direct-storage upload config — present ONLY on `@Upload` routes (the\n * `@Get`/`@Post`/… decorators never set it). Its presence is what MARKS a\n * route as an upload route through the whole pipeline (registry → flatten →\n * openapi → codegen). The bytes go client→storage directly; the method body\n * runs as the completion handler. See {@link UploadConfig} (decorators/upload.ts). */\n uploadConfig?: UploadConfig;\n /** Streaming config — present ONLY on `@Sse` routes (the `@Get`/`@Post`/…\n * decorators never set it). Its presence is what MARKS a route as a streaming\n * route through the whole pipeline (registry → flatten → openapi → codegen),\n * exactly as `uploadConfig` does for uploads — never a special HTTP verb. An\n * `@Sse` route registers POST like any input-bearing route, so the verb cannot\n * carry the distinction. See {@link SseConfig} (decorators/sse.ts). */\n sseConfig?: SseConfig;\n}\n\n/** The kind of value a parameter decorator injects. Drives both dispatch\n * (which request slice to inject) and codegen (which OpenAPI parameter source a\n * schema-bearing kind maps to). */\nexport type ParamKind =\n | \"body\"\n | \"query\"\n | \"param\"\n | \"headers\"\n | \"user\"\n | \"optionalUser\"\n | \"client\"\n | \"requestId\"\n | \"traceId\"\n | \"req\"\n // `@UploadedObject()` — injects the uploaded object (completion input) on an\n // `@Upload` route. No schema (the shape is the fixed UploadedObject type).\n | \"uploadedObject\"\n // `@SseOut()` — injects the frame writer on an `@Sse` route. No schema (the\n // shape is the fixed SseWriter type).\n | \"sseOut\"\n // `@Signal()` — injects the request's AbortSignal, which aborts when the\n // client disconnects. No schema. NOT derivable from `@Req()`: PBRequest\n // carries only request-scoped data and has no signal (endpoint.ts:358-363).\n | \"signal\";\n\n/** One parameter decorator's recorded metadata. `index` is the parameter\n * position esbuild/tsc preserve; `schema` is present for the schema-bearing\n * kinds (`body`/`query`/`headers`); `name` is the path-param name for `param`. */\nexport interface ParamMeta {\n index: number;\n kind: ParamKind;\n /** Zod schema for `body`/`query`/`headers` (validation + codegen source). */\n schema?: ZodTypeAny;\n /** Path-param name for `@Param(\"id\")`. */\n name?: string;\n}\n\n/** One inferred throw site: the error CLASS name (e.g. \"TodoLocked\") and its\n * wire code (e.g. \"todo_locked\"). `status`, `hasData`, and the data JSON schema\n * are NOT carried here — they resolve from the error registry by `code` at\n * extract/openapi time (single source of truth). */\nexport interface ThrowDescriptor {\n name: string;\n code: string;\n}\n\n/** One route's recorded metadata: the verb + subpath + method name + options,\n * the ordered parameter metas, and the resolved return schema (injected by the\n * codegen step — see `returnSchema`). */\nexport interface RouteMeta {\n method: HttpMethodUpper;\n subpath: string;\n fnName: string;\n options: RouteOptions;\n params: ParamMeta[];\n /** Response schema for the route, if any. Derived from the method's RETURN\n * TYPE by codegen and written here via `recordReturn` (a generated top-level\n * IIFE injected per controller), not by an author-written decorator. */\n returnSchema?: ZodTypeAny;\n /** Error classes this route can throw, if inferred. Derived from the method\n * body + service call graph by the deploy stager's throw analysis and written\n * here via `recordThrows` (a generated top-level IIFE injected per controller,\n * the `recordReturn` twin), not by an author-written decorator. */\n throws?: ThrowDescriptor[];\n}\n\n/** Symbol the route metadata list is stored under on a controller class. Using\n * a symbol (not a string key) keeps it off the public structural surface and\n * avoids any chance of an authored property collision. */\nexport const ROUTES: unique symbol = Symbol.for(\"palbase.backend.routes\");\n\n/** Symbol the per-method buffered parameter metas are stored under while a class\n * is being decorated. Parameter decorators fire before the method decorator, so\n * they buffer here keyed by method name; the method decorator drains the buffer\n * into the route entry it creates. */\nconst PARAM_BUFFER: unique symbol = Symbol.for(\"palbase.backend.paramBuffer\");\n\n/** A room's own slots. Rooms are NOT routes — no verb, no path, no params — so\n * they get their own carrier slots instead of being squeezed into RouteMeta. */\nconst ROOM: unique symbol = Symbol.for(\"palbase.backend.room\");\nconst ROOM_HOOKS: unique symbol = Symbol.for(\"palbase.backend.roomHooks\");\n\n/** Symbol the per-method buffered return-type schemas are stored under while a\n * class's registry is being populated. The codegen-injected `recordReturn` call\n * can fire before OR after the method decorator; it buffers here keyed by method\n * name and `recordRoute` drains it into the route entry (and `recordReturn`\n * writes through if the route already exists). Buffering on BOTH sides means a\n * fully-formed route entry always carries its return schema — a raw-symbol\n * reader (the runtime) never has to re-merge. */\nconst RETURN_BUFFER: unique symbol = Symbol.for(\"palbase.backend.returnBuffer\");\n\n/** Symbol the per-method buffered throw descriptors are stored under while a\n * class's registry is being populated. The stager-injected `recordThrows` call\n * can fire before OR after the method decorator; it buffers here keyed by method\n * name and `recordRoute` drains it into the route entry (and `recordThrows`\n * writes through if the route already exists). Buffering on BOTH sides means a\n * fully-formed route entry always carries its throw descriptors — a raw-symbol\n * reader (the runtime) never has to re-merge. */\nconst THROWS_BUFFER: unique symbol = Symbol.for(\"palbase.backend.throwsBuffer\");\n\n/** A class constructor carrying the symbol-keyed registry slots. We type the\n * registry-bearing class as this so the decorators can read/write the slots\n * without `any` — a plain `Function` does not carry index signatures. */\ninterface RegistryCarrier {\n [ROUTES]?: RouteMeta[];\n [PARAM_BUFFER]?: Record<string, ParamMeta[]>;\n [ROOM]?: RoomMeta;\n [ROOM_HOOKS]?: RoomBuffer;\n [RETURN_BUFFER]?: Record<string, ZodTypeAny>;\n [THROWS_BUFFER]?: Record<string, ThrowDescriptor[]>;\n}\n\n/** Coerce a decorated target (class constructor or its prototype) into the\n * registry carrier that owns the slots. Method/param decorators receive the\n * PROTOTYPE as their target; the class decorator receives the constructor. We\n * always anchor the registry on the CONSTRUCTOR so `getRoutes(ctor)` finds it. */\nfunction carrierOf(target: object): RegistryCarrier {\n // For instance-member decorators, `target` is the prototype; its `.constructor`\n // is the class. For a static member or the class decorator, `target` is the\n // constructor already. Resolve to the constructor either way.\n const ctor =\n typeof target === \"function\"\n ? (target as unknown as RegistryCarrier)\n : (((target as { constructor?: unknown }).constructor ??\n target) as unknown as RegistryCarrier);\n return ctor;\n}\n\n/** Get (creating if absent) the own route list for a class constructor. Own —\n * not inherited — so a subclass does not mutate its base's routes. */\nfunction ownRoutes(carrier: RegistryCarrier): RouteMeta[] {\n if (!Object.prototype.hasOwnProperty.call(carrier, ROUTES)) {\n carrier[ROUTES] = [];\n }\n return carrier[ROUTES] as RouteMeta[];\n}\n\n/** Get (creating if absent) the own per-method param buffer for a class. */\nfunction ownParamBuffer(carrier: RegistryCarrier): Record<string, ParamMeta[]> {\n if (!Object.prototype.hasOwnProperty.call(carrier, PARAM_BUFFER)) {\n carrier[PARAM_BUFFER] = {};\n }\n return carrier[PARAM_BUFFER] as Record<string, ParamMeta[]>;\n}\n\n/** Record a route (called by the method decorators). Drains any parameter\n * metas already buffered for `fnName` into the new route entry, then sorts them\n * by parameter index so dispatch can inject positionally. */\nexport function recordRoute(\n target: object,\n fnName: string,\n method: HttpMethodUpper,\n subpath: string,\n options: RouteOptions,\n): void {\n const carrier = carrierOf(target);\n const routes = ownRoutes(carrier);\n const buffer = ownParamBuffer(carrier);\n const params = (buffer[fnName] ?? []).slice().sort((a, b) => a.index - b.index);\n const route: RouteMeta = { method, subpath, fnName, options, params };\n // Drain a buffered return schema (the recordReturn-ran-first ordering) so the\n // route entry is complete the moment it's created — a raw-symbol consumer\n // (the runtime extractor/worker) sees the return schema without re-merging.\n const returnBuffer = carrier[RETURN_BUFFER];\n if (returnBuffer && returnBuffer[fnName] !== undefined) {\n route.returnSchema = returnBuffer[fnName];\n }\n // Same drain for buffered throw descriptors (the recordThrows-ran-first\n // ordering) — the route entry is complete the moment it's created.\n const throwsBuffer = carrier[THROWS_BUFFER];\n if (throwsBuffer && throwsBuffer[fnName] !== undefined) {\n route.throws = throwsBuffer[fnName];\n }\n routes.push(route);\n}\n\n/** Record one parameter decorator (called by `@Body`/`@User`/…). Buffers per\n * method name; the method decorator merges the buffer into the route entry. If\n * the route already exists (method decorator ran first — TS does evaluate the\n * method decorator AFTER its parameter decorators, but we stay order-robust),\n * the meta is also appended directly so neither ordering loses it. */\nexport function recordParam(target: object, fnName: string, meta: ParamMeta): void {\n const carrier = carrierOf(target);\n const buffer = ownParamBuffer(carrier);\n (buffer[fnName] ??= []).push(meta);\n\n // Order-robust: if the route already exists, merge in place + keep sorted.\n const routes = carrier[ROUTES];\n if (routes) {\n const route = routes.find((r) => r.fnName === fnName);\n if (route) {\n route.params.push(meta);\n route.params.sort((a, b) => a.index - b.index);\n }\n }\n}\n\n/** Attach a return schema to the route for `fnName` (called by the codegen\n * injection that reads the method's return type). If the route does not exist\n * yet, the schema is buffered (RETURN_BUFFER) and drained into the route by\n * `recordRoute` when the method decorator runs. */\nexport function recordReturn(target: object, fnName: string, schema: ZodTypeAny): void {\n const carrier = carrierOf(target);\n const routes = carrier[ROUTES];\n const route = routes?.find((r) => r.fnName === fnName);\n if (route) {\n route.returnSchema = schema;\n return;\n }\n if (!Object.prototype.hasOwnProperty.call(carrier, RETURN_BUFFER)) {\n carrier[RETURN_BUFFER] = {};\n }\n const returnBuffer = carrier[RETURN_BUFFER];\n if (returnBuffer) returnBuffer[fnName] = schema;\n}\n\n/** Attach the inferred throw descriptors to the route for `fnName` (called by\n * the stager-injected IIFE that carries the throw analysis result — the\n * `recordReturn` twin). If the route does not exist yet, the descriptors are\n * buffered (THROWS_BUFFER) and drained into the route by `recordRoute` when the\n * method decorator runs. */\nexport function recordThrows(target: object, fnName: string, throws: ThrowDescriptor[]): void {\n const carrier = carrierOf(target);\n const routes = carrier[ROUTES];\n const route = routes?.find((r) => r.fnName === fnName);\n if (route) {\n route.throws = throws;\n return;\n }\n if (!Object.prototype.hasOwnProperty.call(carrier, THROWS_BUFFER)) {\n carrier[THROWS_BUFFER] = {};\n }\n const throwsBuffer = carrier[THROWS_BUFFER];\n if (throwsBuffer) throwsBuffer[fnName] = throws;\n}\n\n/** Read the route metadata for a controller class (the deploy/dispatch entry\n * point). Applies any buffered return schemas + throw descriptors (for the\n * recordReturn/recordThrows-runs-before orderings) and returns a defensive copy\n * so callers cannot mutate the registry.\n */\nexport function getRoutes(ctor: object): RouteMeta[] {\n const carrier = carrierOf(ctor);\n const routes = carrier[ROUTES] ?? [];\n const returnBuffer = carrier[RETURN_BUFFER];\n if (returnBuffer) {\n for (const route of routes) {\n const buffered = returnBuffer[route.fnName];\n if (buffered && route.returnSchema === undefined) {\n route.returnSchema = buffered;\n }\n }\n }\n const throwsBuffer = carrier[THROWS_BUFFER];\n if (throwsBuffer) {\n for (const route of routes) {\n const buffered = throwsBuffer[route.fnName];\n if (buffered && route.throws === undefined) {\n route.throws = buffered;\n }\n }\n }\n return routes.map((r) => ({\n ...r,\n params: r.params.slice(),\n ...(r.throws !== undefined ? { throws: r.throws.slice() } : {}),\n }));\n}\n\n// ── rooms ───────────────────────────────────────────────────────────────────\n\n/** Which lifecycle hook a method is bound to. */\nexport type RoomHook = \"authorize\" | \"first\" | \"join\" | \"leave\" | \"empty\";\n\nexport interface RoomMessageMeta {\n fnName: string;\n schema: ZodTypeAny;\n}\n\nexport interface RoomMeta {\n pattern: string;\n events: Record<string, ZodTypeAny>;\n graceMs: number;\n /** hook → the method name that implements it. */\n hooks: Partial<Record<RoomHook, string>>;\n /** inbound message name → its method and payload schema. */\n messages: Record<string, RoomMessageMeta>;\n}\n\ninterface RoomBuffer {\n hooks: Partial<Record<RoomHook, string>>;\n messages: Record<string, RoomMessageMeta>;\n}\n\n/** Get (creating if absent) the own hook buffer. Own — not inherited — so a\n * subclass never mutates its base's hooks. Member decorators fill this BEFORE\n * the class decorator runs; controller.ts:203 depends on the same ordering. */\nfunction ownRoomBuffer(carrier: RegistryCarrier): RoomBuffer {\n if (!Object.prototype.hasOwnProperty.call(carrier, ROOM_HOOKS)) {\n carrier[ROOM_HOOKS] = { hooks: {}, messages: {} };\n }\n return carrier[ROOM_HOOKS] as RoomBuffer;\n}\n\n/** Record a lifecycle hook. A second method for the same hook is refused: two\n * answers to \"who handles this\" cannot be resolved at dispatch, and silently\n * keeping one is how a hook stops running without anyone being told. */\nexport function recordRoomHook(target: object, hook: RoomHook, fnName: string): void {\n const buffer = ownRoomBuffer(carrierOf(target));\n const existing = buffer.hooks[hook];\n if (existing !== undefined && existing !== fnName) {\n const label = `On${hook.charAt(0).toUpperCase()}${hook.slice(1)}`;\n throw new Error(\n `@${label} is declared twice in one room (${existing} and ${fnName}). ` +\n `A room has one of each hook.`,\n );\n }\n buffer.hooks[hook] = fnName;\n}\n\n/** Record an inbound message handler. */\nexport function recordRoomMessage(\n target: object,\n name: string,\n fnName: string,\n schema: ZodTypeAny,\n): void {\n const buffer = ownRoomBuffer(carrierOf(target));\n const existing = buffer.messages[name];\n if (existing !== undefined && existing.fnName !== fnName) {\n throw new Error(\n `@OnMessage(\"${name}\") is declared twice in one room (${existing.fnName} and ${fnName}).`,\n );\n }\n buffer.messages[name] = { fnName, schema };\n}\n\n/** Record the room itself (called by the class decorator), draining the buffer\n * the member decorators already filled. */\nexport function recordRoom(\n ctor: object,\n meta: Omit<RoomMeta, \"hooks\" | \"messages\">,\n): void {\n const carrier = carrierOf(ctor);\n const buffer = ownRoomBuffer(carrier);\n carrier[ROOM] = { ...meta, hooks: buffer.hooks, messages: buffer.messages };\n // AND into the shared class registry, the same slot @Controller pushes to.\n //\n // Without this line a room compiles, bundles and deploys, and is never called:\n // the bundler's entry exports `SDK.getRegisteredControllers()` and the runtime\n // reads its rooms out of THAT list (server.ts's `collectRooms`). A room that\n // only marks its own constructor is a room nobody can find — measured, on the\n // fixture, at the last gate before it would have worked.\n //\n // Rooms and controllers share one list because they are one thing to the\n // loader: classes a bundle declared. What each IS is decided by the marker it\n // carries, never by which list it arrived in.\n const g = globalThis as unknown as Record<symbol, unknown[] | undefined>;\n const REGISTRY = Symbol.for(\"palbase.backend.allControllers\");\n const all = (g[REGISTRY] ??= []);\n if (!all.includes(ctor)) all.push(ctor);\n}\n\n/** The room a class declares, or undefined. A class with no `@Room` is not a\n * room — the marker is the CONFIG's presence, never a name or a base class\n * (the rule upload.ts:13-16 states for uploads). */\nexport function getRoom(ctor: object): RoomMeta | undefined {\n const carrier = carrierOf(ctor);\n if (!Object.prototype.hasOwnProperty.call(carrier, ROOM)) return undefined;\n return carrier[ROOM] as RoomMeta;\n}\n","// `@Controller(basePath, options?)` — the class decorator that marks a class as\n// a Palbase backend controller. It stamps a non-enumerable `__palbase`\n// discriminant + the resolved controller metadata onto the class so the\n// deploy/dispatch pipeline (and `isController`/`resolveController`) can detect\n// and read it without `reflect-metadata`.\nimport type { AuthSpec } from \"../endpoint.js\";\nimport { getRoutes } from \"./registry.js\";\n\n/** The controller metadata stamped onto a `@Controller`-decorated class. The\n * default export of a `controllers/*.controller.ts` file resolves to this via\n * {@link resolveController}. */\nexport interface ControllerMeta {\n /** Discriminant the runtime + tooling read. */\n readonly __palbase: \"controller\";\n /** The base path every route in this controller mounts under (e.g. \"/todos\"). */\n basePath: string;\n /** Controller-level default auth, applied to routes that don't set their own\n * (`@Get(\"/x\", { auth })` overrides this). `undefined` ⇒ the application\n * default ({@link defineDefaultAuth}), and secure-by-default below that —\n * see {@link resolveEffectiveAuth} for the whole cascade. */\n defaultAuth?: AuthSpec;\n}\n\n/** Options accepted by `@Controller`. */\nexport interface ControllerOptions {\n /** Default auth for ALL routes in this controller (route-level overrides;\n * omitting it falls through to the application default declared with\n * {@link defineDefaultAuth}). */\n auth?: AuthSpec;\n}\n\n/** Symbol the controller metadata is stamped under. Symbol-keyed (not a string\n * property) so it never collides with an authored member and stays off the\n * structural surface. */\nexport const CONTROLLER_META: unique symbol = Symbol.for(\"palbase.backend.controllerMeta\");\n\n/**\n * Every class `@Controller` has decorated, in decoration order.\n *\n * This is what lets a controller file need no export at all: importing the file\n * runs the decorator, the decorator records the class here, and the runtime\n * reads the list. Without it the only handle on a class is its export name, so\n * every controller had to be exported AND named in a generated entry — the\n * ceremony NestJS still charges (`export class` PLUS\n * `@Module({controllers:[…]})`).\n *\n * Keyed on a well-known Symbol against globalThis rather than held in a module\n * variable, because a deployed bundle inlines its own copy of this package: two\n * copies would keep two lists, and the runtime would read the empty one. The\n * same hazard `runtimeHooks` exists for, closed the same way — one shared slot.\n */\nconst REGISTRY: unique symbol = Symbol.for(\"palbase.backend.allControllers\") as never;\n\nfunction registry(): unknown[] {\n const g = globalThis as unknown as Record<symbol, unknown[] | undefined>;\n const existing = g[REGISTRY];\n if (existing) return existing;\n const fresh: unknown[] = [];\n g[REGISTRY] = fresh;\n return fresh;\n}\n\n/**\n * The controller classes this process has loaded, in decoration order.\n *\n * Decoration order is import order, which the bundler fixes by sorting the\n * files it emits imports for — so two builds of one tree produce the same\n * route table, and route precedence is not a function of module-resolution\n * accidents.\n */\nexport function getRegisteredControllers(): readonly unknown[] {\n return registry().slice();\n}\n\n/** Empty the registry. For tests, which load controllers repeatedly. */\nexport function __resetRegisteredControllers(): void {\n registry().length = 0;\n}\n\n/**\n * The APPLICATION-level default auth.\n *\n * Held on globalThis under a well-known Symbol for exactly the reason\n * {@link REGISTRY} is: a deployed bundle inlines its own copy of this package,\n * and two copies keeping two defaults is how a security setting silently\n * becomes two different settings.\n */\nconst APP_DEFAULT_AUTH: unique symbol = Symbol.for(\"palbase.backend.appDefaultAuth\") as never;\n\nfunction appAuthSlot(): Record<symbol, AuthSpec | undefined> {\n return globalThis as unknown as Record<symbol, AuthSpec | undefined>;\n}\n\n/**\n * Declare the default auth for EVERY route in the application — the ring the\n * cascade consults when neither the route nor its controller says anything.\n *\n * The measured problem it removes: `auth: { verifiedEmail: true }` repeated by\n * hand on ten `@Controller`s. A security setting that must be repeated is a\n * security setting that will be forgotten — the eleventh controller opens the\n * door and nothing says so.\n *\n * Call it at MODULE SCOPE in a file the application imports (the controllers'\n * own barrel, or a module a controller imports). The cascade reads this slot\n * when the route table is built and when the spec is emitted — both of which\n * run after module loading — so declaration order does not matter, but being\n * imported at all does.\n *\n * @example\n * defineDefaultAuth({ verifiedEmail: true }); // every route, unless it says otherwise\n */\nexport function defineDefaultAuth(auth: AuthSpec): void {\n appAuthSlot()[APP_DEFAULT_AUTH] = auth;\n}\n\n/** The declared application default, or `undefined` when none was declared. */\nexport function getDefaultAuth(): AuthSpec | undefined {\n return appAuthSlot()[APP_DEFAULT_AUTH];\n}\n\n/** Clear the application default. For tests, which declare it repeatedly. */\nexport function __resetDefaultAuth(): void {\n delete appAuthSlot()[APP_DEFAULT_AUTH];\n}\n\n/**\n * THE auth cascade: route → controller → application → `true`.\n *\n * One function, every caller — the route table (`engine/router.ts`) and the\n * spec emitter (`openapi/controllers.ts`) ASK for the answer instead of\n * spelling the chain themselves. Two hand-written copies of a cascade is how\n * the build-time answer and the runtime answer come to disagree about who may\n * call an endpoint, and the disagreement shows up as an open door.\n *\n * The terminal `true` is secure-by-default and is load-bearing: a route that\n * declared nothing, under a controller that declared nothing, in an\n * application that declared nothing, is CLOSED.\n */\nexport function resolveEffectiveAuth(\n routeAuth: AuthSpec | undefined,\n controllerAuth: AuthSpec | undefined,\n): AuthSpec {\n return routeAuth ?? controllerAuth ?? getDefaultAuth() ?? true;\n}\n\n/** A class carrying the stamped controller metadata + discriminant. */\ninterface ControllerCarrier {\n __palbase?: \"controller\";\n [CONTROLLER_META]?: ControllerMeta;\n}\n\n/** The one path segment the platform owns. The isolate matches\n * `^/webhooks/([^/]+)$` on the raw request path BEFORE controller dispatch, so\n * anything a controller resolves to under it answers `404 webhook_not_found`\n * and never runs. */\nconst RESERVED_FIRST_SEGMENT = \"webhooks\";\n\n/**\n * Throw if `path` resolves under the reserved segment. Segments are compared the\n * way the isolate compares them — `split(\"/\").filter(Boolean)` — NOT by string\n * prefix, because empty segments collapse there: `@Controller(\"/\")` +\n * `@Post(\"/webhooks/x\")` composes to `//webhooks/x`, which the isolate serves as\n * `/webhooks/x`. A prefix check reads that as safe; the segment check does not.\n * `/webhooksy` stays allowed for the same reason — it is a different segment.\n *\n * Every verb is refused, not just the POST the isolate currently intercepts: the\n * reservation is of the URL namespace, so a `@Get(\"/webhooks/x\")` that happens\n * to work today would be silently shadowed the moment the isolate's method gate\n * widens. Refusing at build is recoverable; discovering it as a 404 is not.\n */\nfunction assertNotReserved(path: string, subject: string): void {\n const [first] = path.split(\"/\").filter(Boolean);\n if (first === RESERVED_FIRST_SEGMENT) {\n throw new Error(\n `${subject} resolves under the reserved /${RESERVED_FIRST_SEGMENT} path — ` +\n \"inbound webhooks are served there and would shadow this route\",\n );\n }\n}\n\n/**\n * Mark a class as a Palbase backend controller. `basePath` is the mount path\n * for every route the class declares; `options.auth` sets the controller-level\n * default auth (a route's own `auth` overrides it; absent ⇒ secure-by-default).\n *\n * @example\n * \\@Controller(\"/todos\", { auth: false })\n * export class TodosController {\n * \\@Get(\"\") list(\\@QueryParams(ListTodosQuery) q: ListTodosQuery): TodoSchema[] { … }\n * }\n */\nexport function Controller(basePath: string, options: ControllerOptions = {}) {\n return function <T extends abstract new (...args: never[]) => object>(ctor: T): T {\n // /webhooks/* belongs to the platform: the isolate matches the inbound\n // webhook route before controller dispatch, so a controller mounted here\n // would never receive a request. Silent shadowing is the failure mode this\n // whole change exists to remove, so refuse it at build.\n //\n // The COMPOSED path is what gets shadowed, not the base path. `@Controller(\"\")`\n // and `@Controller(\"/\")` both pass a base-path-only check while a\n // `@Post(\"/webhooks/stripe\")` inside them resolves to exactly the path the\n // isolate intercepts. Method decorators run BEFORE the class decorator (TS\n // evaluates members first), so every route this class declares is already in\n // the registry here — which is why the composed check can live at this one\n // seam instead of on the dispatch read path. The `@Controller(\"\") +\n // @Post(\"/webhooks/stripe\")` test is the lock on that ordering: if it ever\n // stopped holding, that test goes red.\n assertNotReserved(basePath, `@Controller(\"${basePath}\")`);\n for (const route of getRoutes(ctor)) {\n assertNotReserved(\n `${basePath}${route.subpath}`,\n `@${route.method}(\"${route.subpath}\") in @Controller(\"${basePath}\")`,\n );\n }\n\n const carrier = ctor as unknown as ControllerCarrier;\n const meta: ControllerMeta = {\n __palbase: \"controller\",\n basePath,\n ...(options.auth !== undefined ? { defaultAuth: options.auth } : {}),\n };\n // Non-enumerable so it doesn't leak onto instances / structural checks.\n Object.defineProperty(carrier, CONTROLLER_META, {\n value: meta,\n enumerable: false,\n configurable: true,\n writable: false,\n });\n // The bare `__palbase` discriminant is the cheap detection marker the\n // runtime/extractor checks; keep it readable but non-enumerable.\n Object.defineProperty(carrier, \"__palbase\", {\n value: \"controller\",\n enumerable: false,\n configurable: true,\n writable: false,\n });\n // Record it, so importing the file is enough and exporting is optional.\n // Guarded against a double-decoration re-entering the same class twice.\n const all = registry();\n if (!all.includes(ctor)) all.push(ctor);\n return ctor;\n };\n}\n\n/** True when `value` is a `@Controller`-decorated class (cheap discriminant\n * check). Accepts the class constructor (the default export of a controller\n * file). */\nexport function isController(value: unknown): boolean {\n if (typeof value !== \"function\" && (typeof value !== \"object\" || value === null)) {\n return false;\n }\n const carrier = value as ControllerCarrier;\n return carrier.__palbase === \"controller\" && carrier[CONTROLLER_META] !== undefined;\n}\n\n/** Read the resolved controller metadata off a `@Controller`-decorated class.\n * Throws if the class was not decorated — callers should gate with\n * {@link isController} first (the loader does). */\nexport function resolveController(ctor: unknown): ControllerMeta {\n if (typeof ctor !== \"function\" && (typeof ctor !== \"object\" || ctor === null)) {\n throw new TypeError(\"resolveController: value is not a class\");\n }\n const meta = (ctor as ControllerCarrier)[CONTROLLER_META];\n if (!meta) {\n throw new TypeError(\n \"resolveController: class is not a @Controller — decorate it with `@Controller(path)` and list it in a module's `controllers`\",\n );\n }\n return meta;\n}\n\n/**\n * A class the runtime constructs takes NO constructor parameters.\n *\n * ONE writer, four callers (controller, hook, job, webhook) and the build's own\n * check. Four hand-written copies of this message is how the four come to\n * disagree about what is refused — and the disagreement is silent, because a\n * class that slips past one of them still ends up with `undefined` fields.\n *\n * Why it is refused rather than injected: there is no container. The parameter\n * would arrive `undefined`, the code would compile, deploy, and fail at the\n * first request that touches the field — the most expensive place to learn it.\n */\nexport function assertZeroArgConstructor(Ctrl: unknown, kind: string): void {\n const arity = (Ctrl as { length?: number }).length ?? 0;\n if (arity === 0) return;\n\n // This function's NAME is a promise: whatever reaches it will be constructed\n // with a zero-argument constructor. Letting a class with parameters through\n // would make the name a lie — worse than the rename FR-029 guards against.\n //\n // An earlier design made it \"declaration-aware\": pass when metadata matches\n // arity. Measured, that re-opens the exact silence this exists to close.\n // ANY decorator triggers metadata emission, not just `@Injectable`:\n //\n // @Job(...) class J { constructor(repo: unknown) {} }\n // → design:paramtypes = [Object] ← matches arity\n //\n // so J would pass, then be built with `new J()`, and `repo` would be\n // `undefined` at the first scheduled run. Four tests in this repo asserted\n // that refusal and all four went red; the tests were right.\n //\n // What changed instead is the MESSAGE, and who calls this. Callers holding a\n // container resolve from it and never come here (router.ts, job/hook/webhook);\n // this stays the guard for the container-less path, and keeps its promise.\n const name = (Ctrl as { name?: string }).name ?? \"<anonymous>\";\n throw new Error(\n `${kind} ${name} declares a constructor with ${arity} parameter(s), and this path ` +\n `builds it with a zero-argument constructor — every parameter would arrive as ` +\n `undefined. If you meant to inject them, add @Injectable() to ${name} and list it ` +\n `in a module's providers, so the container builds it instead.`,\n );\n}\n","/**\n * engine/router.ts — the route table, built from the SDK's own registry.\n *\n * No third-party router. The table is known at boot (the decorators wrote it),\n * so matching is a segment walk over a small array rather than a compiled\n * pattern engine. Both authoring forms for a path parameter are accepted:\n * `{id}` (what the decorators are written with) and `:id`.\n */\nimport { getRoutes } from \"../decorators/registry.js\";\nimport type { Container } from \"../container.js\";\nimport type { RouteMeta } from \"../decorators/registry.js\";\nimport { resolveEffectiveAuth } from \"../decorators/controller.js\";\nimport type { AuthSpec } from \"../endpoint.js\";\n\nconst ROOM_META: unique symbol = Symbol.for(\"palbase.backend.room\") as never;\nconst CONTROLLER_META = Symbol.for(\"palbase.backend.controllerMeta\");\n\nexport interface RouteEntry {\n method: string;\n /** Path segments; a parameter segment is stored as `:name`. */\n segments: string[];\n meta: RouteMeta;\n /** The controller instance the method is invoked on. */\n instance: Record<string, (...args: unknown[]) => unknown>;\n /** `GET /todos/{id}` — stable, human-readable, used as the rate-limit key. */\n id: string;\n /** The auth spec that applies when the route itself declares none —\n * controller default ?? application default ?? `true`, resolved once at boot\n * by `resolveEffectiveAuth`. `engine/index.ts` reconciles the route's own\n * spec against it per request. */\n controllerAuth: AuthSpec;\n}\n\nfunction toSegments(path: string): string[] {\n return path\n .split(\"/\")\n .filter(Boolean)\n .map((s) => (s.startsWith(\"{\") && s.endsWith(\"}\") ? `:${s.slice(1, -1)}` : s));\n}\n\n/**\n * Build the table from controller classes.\n *\n * @throws when a class carries no routes — a controller that collected zero\n * endpoints is the silent failure this whole runtime is built to refuse, and\n * it must be loud at boot rather than a 404 in production.\n * @throws when a class declares constructor parameters — the same class of\n * silence one level down (FR-010): nothing here has an argument to pass, so\n * the field would simply be `undefined` in production.\n */\nexport function buildRouteTable(\n controllers: readonly unknown[],\n container: Container,\n): RouteEntry[] {\n const table: RouteEntry[] = [];\n for (const Ctrl of controllers) {\n // A ROOM is not a routeless controller, it is a class with no HTTP surface\n // at all — server code a device reaches over the socket. It arrives here\n // because rooms and controllers share ONE registry slot (the loader's\n // `controllersOf` hands over everything a bundle declared), and the zero-route\n // refusal below is correct for a controller and wrong for a room.\n //\n // Measured on the live stack: the fixture's `@Room` reached this line and the\n // runtime refused to boot with \"controller ProbeRoom collected zero routes\" —\n // a message naming a class that was perfectly correct.\n if ((Ctrl as Record<symbol, unknown>)[ROOM_META] !== undefined) continue;\n // No `new ()` claim any more: the container builds this, and it has already\n // refused anything it could not build honestly. The cast below is only for\n // reading the decorator metadata off the class.\n const ctor = Ctrl as Record<\n symbol,\n { basePath?: string; defaultAuth?: AuthSpec } | undefined\n >;\n const meta = ctor[CONTROLLER_META];\n const basePath = meta?.basePath ?? \"\";\n const routes = getRoutes(Ctrl as never) as RouteMeta[];\n if (routes.length === 0) {\n const name = (Ctrl as { name?: string }).name ?? \"<anonymous>\";\n throw new Error(\n `controller ${name} collected zero routes. Either it declares no @Get/@Post/… , ` +\n `or its decorator metadata was erased at build time — check that the bundle was ` +\n `compiled with experimentalDecorators enabled.`,\n );\n }\n // Resolved, not constructed. `assertZeroArgConstructor` is deliberately NOT\n // called here: it keeps its promise that a class reaching it takes zero\n // arguments, and every controller on this path is built by the container —\n // which is where a dependency it cannot supply is refused, by name.\n const instance = container.get(Ctrl as never) as Record<\n string,\n (...a: unknown[]) => unknown\n >;\n for (const r of routes) {\n const full = `${basePath}${r.subpath ?? \"\"}` || \"/\";\n table.push({\n method: r.method,\n segments: toSegments(full),\n meta: r,\n instance,\n id: `${r.method} ${full}`,\n // The route's OWN spec is deliberately not folded in here: this field\n // is what applies when the route is silent, and `effectiveAuth` puts\n // the route level back on top per request.\n controllerAuth: resolveEffectiveAuth(undefined, meta?.defaultAuth),\n });\n }\n }\n return table;\n}\n\nexport interface RouteMatch {\n entry: RouteEntry;\n params: Record<string, string>;\n}\n\n/** First match wins; the table is small and declaration order is the tiebreak. */\nexport function matchRoute(\n table: readonly RouteEntry[],\n method: string,\n pathname: string,\n): RouteMatch | null {\n const parts = pathname.split(\"/\").filter(Boolean);\n for (const entry of table) {\n if (entry.method !== method || entry.segments.length !== parts.length) continue;\n const params: Record<string, string> = {};\n let ok = true;\n for (let i = 0; i < entry.segments.length; i++) {\n const seg = entry.segments[i];\n const got = parts[i];\n if (seg === undefined || got === undefined) { ok = false; break; }\n if (seg.charCodeAt(0) === 58 /* ':' */) {\n params[seg.slice(1)] = decodeURIComponent(got);\n } else if (seg !== got) {\n ok = false;\n break;\n }\n }\n if (ok) return { entry, params };\n }\n return null;\n}\n","/**\n * engine/attest.ts — the App Attest gate, and the counter that watches it.\n *\n * # Where this sits, and why here\n *\n * The tenant edge splits traffic in two: the platform's own prefixes (`/auth`,\n * `/v1`, `/admin`, `/realtime`, `/.well-known`) go to palsvc, and EVERYTHING\n * ELSE goes to the customer's runtime — this process. That split is already\n * exactly the surface App Attest is supposed to cover, and exactly the set it\n * is supposed to exempt (auth bootstrap, module routes, Storage's own byte\n * write, analytics ingestion). So the gate does not draw a boundary; it stands\n * on one that was already drawn.\n *\n * # What it does NOT do\n *\n * It does not verify anything itself. The device record, its public key and its\n * signature counter live in palauth, and a counter has to have exactly one\n * writer. So the gate asks — `POST /admin/attest/devices/assert` — and palauth\n * answers.\n *\n * The path lives under /admin, not /auth, and that is deliberate: /auth is the\n * TENANT surface — a customer's own code reaches it — while /admin carries the\n * service_role gate. A caller who could POST to the assert endpoint could ask\n * for a challenge on any anchor.\n *\n * The credential is the `apikey` header, not a bearer token, and that is what\n * every other module client here sends: palsvc's own door turns a stack API key\n * into the iJWT its gates read. A bearer token would have to be an iJWT already\n * — which only the edge mints, and this call does not go through the edge.\n * Measured against the running stack: `apikey` → 200, bearer → refused.\n *\n * That call is the only reason the gate is async.\n *\n * The fresh challenge comes back WITH the verdict. That is deliberate: minting\n * it here would mean a second implementation of the same HMAC in a second\n * language, and two implementations of one construction drift silently. It also\n * costs nothing, because when there is evidence to verify the call happens\n * anyway.\n *\n * # The three modes\n *\n * off — nothing. No call, no observation, no header.\n * monitor — COUNTS ONLY. Never rejects, never even verifies. A request\n * carrying a broken assertion passes exactly like one carrying\n * none, because monitoring that can fail is not monitoring.\n * enforce — demands a valid assertion.\n *\n * Monitoring is passive on purpose and the reason is in the client: when the\n * SDK is told to attest on a device that cannot (Simulator, macOS, an older\n * iPhone), it throws and does NOT retry. So \"sample a few requests to see who\n * can attest\" would break the exact developer that monitoring exists to\n * protect. What we count instead is what the SDK already volunteers.\n *\n * # Failure directions are opposite, on purpose\n *\n * If the POLICY cannot be read, the gate falls back to `off`: a gate that\n * cannot reach palauth must not take the customer's traffic down with it.\n * If a VERDICT cannot be obtained while enforcing, the request is REJECTED:\n * under enforcement, \"I could not check\" is not \"it is fine\".\n */\n\nimport type { VerifiedDevice } from \"../types.js\";\n\nexport type AttestMode = \"off\" | \"monitor\" | \"enforce\";\n\n/** What one request contributed to the monitoring counts. */\nexport interface AttestObservation {\n /** The SDK's own answer to \"can this device attest at all\". CLIENT-DECLARED:\n * it counts, it never gates. */\n capable: \"yes\" | \"no\" | \"unknown\";\n attested: boolean;\n /** The client-minted installation id (`X-Palbase-Installation`), so the panel\n * can join these counts with the app-version distribution. NOT the server\n * anchor (`ins_…`) — that one is a security anchor and never a counter key. */\n installationId: string | null;\n}\n\nexport interface AttestOutcome {\n outcome: \"pass\" | \"reject\";\n reason: \"\" | \"app_attest_required\" | \"assertion_invalid\" | \"assertion_stale\";\n device: VerifiedDevice | null;\n /** null in `off` — nothing is counted there. */\n observation: AttestObservation | null;\n /** Handed to the client so its NEXT assertion needs no extra round trip. */\n nextChallenge: string | null;\n}\n\nexport interface AttestGateDeps {\n moduleBaseUrl: string;\n serviceRoleKey: string;\n /** How long a read policy is trusted. Default 30s — the flag must take effect\n * without a redeploy, and 30s is short enough that flipping it feels like a\n * switch rather than a deployment. */\n policyTtlMs?: number;\n /** Per-call ceiling on palauth. Default 2s — see DEFAULT_REQUEST_TIMEOUT_MS. */\n requestTimeoutMs?: number;\n fetchImpl?: typeof fetch;\n}\n\nexport const HEADER_DEVICE_ID = \"x-palbase-device-id\";\nexport const HEADER_PAYLOAD = \"x-palbase-attest-payload\";\nexport const HEADER_SIGNATURE = \"x-palbase-attest-signature\";\nexport const HEADER_CHALLENGE = \"x-palbase-attest-challenge\";\nexport const HEADER_CAPABLE = \"x-palbase-attest-capable\";\nexport const HEADER_INSTALLATION = \"x-palbase-installation\";\n/** The SERVER-minted installation anchor (`ins_…`) the device enrolled against.\n * Distinct from HEADER_INSTALLATION, which is the client's own counting id:\n * this one is what the assertion challenge is bound to, so it has to travel\n * with the evidence or palauth cannot verify the challenge at all. */\nexport const HEADER_ANCHOR = \"x-palbase-installation-anchor\";\n\nconst DEFAULT_POLICY_TTL_MS = 30_000;\n\n/** How long the gate waits on palauth before giving up. Loopback in the same\n * pod: a healthy answer is single-digit milliseconds, so two seconds is\n * generous and still far below any client's patience. */\nconst DEFAULT_REQUEST_TIMEOUT_MS = 2_000;\n\ninterface AssertVerdict {\n ok: boolean;\n reason: string;\n sign_count: number;\n next_challenge: string;\n}\n\n/** Base64 of the SHA-256 of the body, or \"\" when the request carried none. */\nasync function bodyDigest(body: Uint8Array | null): Promise<string> {\n if (!body || body.byteLength === 0) return \"\";\n // Copied into a buffer of its own, for two reasons: a view over a LARGER\n // ArrayBuffer would otherwise hash its neighbours, and a body backed by a\n // SharedArrayBuffer is not a valid digest input at all.\n const bytes = new Uint8Array(new ArrayBuffer(body.byteLength));\n bytes.set(body);\n const buf = await crypto.subtle.digest(\"SHA-256\", bytes);\n return btoa(String.fromCharCode(...new Uint8Array(buf)));\n}\n\nfunction readCapable(req: Request): \"yes\" | \"no\" | \"unknown\" {\n const v = req.headers.get(HEADER_CAPABLE);\n return v === \"yes\" || v === \"no\" ? v : \"unknown\";\n}\n\n/**\n * The gate. One call per request, from the engine's `handle()`, after auth and\n * before the rate limiter.\n */\nexport function createAttestGate(deps: AttestGateDeps) {\n const doFetch = deps.fetchImpl ?? fetch;\n const ttl = deps.policyTtlMs ?? DEFAULT_POLICY_TTL_MS;\n const policyTimeoutMs = deps.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;\n let cachedMode: AttestMode = \"off\";\n let cachedAt = -Infinity;\n\n async function mode(): Promise<AttestMode> {\n if (Date.now() - cachedAt < ttl) return cachedMode;\n try {\n const res = await doFetch(`${deps.moduleBaseUrl}/admin/attest/devices/attest-policy`, {\n headers: { apikey: deps.serviceRoleKey },\n signal: AbortSignal.timeout(policyTimeoutMs),\n });\n if (!res.ok) throw new Error(`attest-policy ${res.status}`);\n const body = (await res.json()) as { mode?: string };\n cachedMode = body.mode === \"monitor\" || body.mode === \"enforce\" ? body.mode : \"off\";\n cachedAt = Date.now();\n } catch {\n // A failed read KEEPS THE LAST KNOWN MODE and does not extend the cache.\n //\n // Falling to `off` here — and remembering that for thirty seconds — would\n // hand an attacker a way to switch the gate off: make the policy read\n // fail and every request for the next window skips verification\n // entirely. Keeping the last good answer means a stack that was\n // enforcing keeps enforcing, and a stack that was off stays off.\n //\n // `cachedAt` is deliberately NOT advanced, so the next request retries\n // rather than waiting out a window on stale information.\n //\n // A stack that has NEVER read the policy starts at `off`, which is the\n // only honest starting point: nothing has said otherwise yet.\n }\n return cachedMode;\n }\n\n return async function gate(\n req: Request,\n body: Uint8Array | null,\n _ctx: { userId?: string },\n ): Promise<AttestOutcome> {\n const m = await mode();\n if (m === \"off\") {\n return { outcome: \"pass\", reason: \"\", device: null, observation: null, nextChallenge: null };\n }\n\n const deviceId = req.headers.get(HEADER_DEVICE_ID) ?? \"\";\n const payload = req.headers.get(HEADER_PAYLOAD) ?? \"\";\n const signature = req.headers.get(HEADER_SIGNATURE) ?? \"\";\n const hasEvidence = deviceId !== \"\" && payload !== \"\" && signature !== \"\";\n\n const observation: AttestObservation = {\n capable: readCapable(req),\n attested: false,\n installationId: req.headers.get(HEADER_INSTALLATION) || null,\n };\n\n if (m === \"monitor\") {\n // No verification call at all. Monitoring costs one buffered counter per\n // request and nothing else — see NFR-002.\n observation.attested = hasEvidence;\n return { outcome: \"pass\", reason: \"\", device: null, observation, nextChallenge: null };\n }\n\n const url = new URL(req.url);\n let verdict: AssertVerdict;\n try {\n const res = await doFetch(`${deps.moduleBaseUrl}/admin/attest/devices/assert`, {\n method: \"POST\",\n headers: { apikey: deps.serviceRoleKey, \"content-type\": \"application/json\" },\n // A HUNG palauth must not become a hung tenant. Without this, a\n // process that accepts the connection and never answers holds every\n // request open until the client gives up — the gate would take the\n // whole stack down while claiming to protect it.\n signal: AbortSignal.timeout(policyTimeoutMs),\n body: JSON.stringify({\n installation_id: req.headers.get(HEADER_ANCHOR) ?? \"\",\n device_id: deviceId,\n challenge: req.headers.get(HEADER_CHALLENGE) ?? \"\",\n payload,\n signature,\n method: req.method,\n // pathname + search, NOT pathname alone.\n //\n // The client signs the path string it was given, and that string can\n // carry a query — the transport splits and reattaches one on purpose.\n // Recomputing from pathname alone would drop the query from the\n // signed definition, which breaks it BOTH ways: an attested call\n // carrying a query would fail to verify, and a captured assertion\n // could be replayed against the same route with different query\n // parameters, which is exactly the substitution the binding exists to\n // prevent.\n path: url.pathname + url.search,\n body_sha256: await bodyDigest(body),\n }),\n });\n if (!res.ok) throw new Error(`assert ${res.status}`);\n verdict = (await res.json()) as AssertVerdict;\n } catch {\n // Enforcing and unable to check: refuse. The client re-enrols and retries,\n // which is recoverable; letting an unverified call through is not.\n return {\n outcome: \"reject\",\n reason: \"app_attest_required\",\n device: null,\n observation,\n nextChallenge: null,\n };\n }\n\n if (!verdict.ok) {\n const reason =\n verdict.reason === \"assertion_invalid\" || verdict.reason === \"assertion_stale\"\n ? verdict.reason\n : \"app_attest_required\";\n return {\n outcome: \"reject\",\n reason,\n device: null,\n observation,\n nextChallenge: verdict.next_challenge || null,\n };\n }\n\n observation.attested = true;\n return {\n outcome: \"pass\",\n reason: \"\",\n device: {\n installationId: \"\",\n authDeviceId: deviceId,\n platform: \"ios\",\n assurance: \"attested\",\n },\n observation,\n nextChallenge: verdict.next_challenge || null,\n };\n };\n}\n\nexport interface ObservationSink {\n record(o: AttestObservation): void;\n flush(): Promise<void>;\n stop(): void;\n}\n\nexport interface ObservationSinkDeps {\n moduleBaseUrl: string;\n serviceRoleKey: string;\n intervalMs?: number;\n maxBatch?: number;\n fetchImpl?: typeof fetch;\n}\n\n/**\n * Buffers observations and ships them in batches.\n *\n * Per-request writes would double a tenant's internal request count for a\n * number that changes no decision. Batching makes the cost independent of\n * traffic: at most one call per interval, plus one per full batch.\n *\n * A failed batch is DROPPED and the sink keeps going. These are counters\n * feeding a forecast, not billing — losing the last few seconds on a crash is\n * cheaper than any machinery that would prevent it.\n */\nexport function createObservationSink(deps: ObservationSinkDeps): ObservationSink {\n const doFetch = deps.fetchImpl ?? fetch;\n const maxBatch = deps.maxBatch ?? 1000;\n const intervalMs = deps.intervalMs ?? 10_000;\n\n let buffer: AttestObservation[] = [];\n let inFlight: Promise<void> = Promise.resolve();\n\n const timer = setInterval(() => {\n void flush();\n }, intervalMs);\n // Never hold the process open for a counter.\n (timer as unknown as { unref?: () => void }).unref?.();\n\n function bucketsOf(batch: AttestObservation[]) {\n const counts = { capable: 0, incapable: 0, unknown: 0, no_sdk: 0 };\n for (const o of batch) {\n if (o.attested || o.capable === \"yes\") counts.capable += 1;\n else if (o.capable === \"no\") counts.incapable += 1;\n else if (o.installationId) counts.unknown += 1;\n else counts.no_sdk += 1;\n }\n return counts;\n }\n\n async function flush(): Promise<void> {\n if (buffer.length === 0) return;\n const batch = buffer;\n buffer = [];\n inFlight = (async () => {\n try {\n await doFetch(`${deps.moduleBaseUrl}/admin/attest/devices/observations`, {\n method: \"POST\",\n headers: { apikey: deps.serviceRoleKey, \"content-type\": \"application/json\" },\n body: JSON.stringify(bucketsOf(batch)),\n });\n } catch {\n // Dropped on purpose — see the doc comment.\n }\n })();\n await inFlight;\n }\n\n return {\n record(o) {\n buffer.push(o);\n if (buffer.length >= maxBatch) void flush();\n },\n flush,\n stop() {\n clearInterval(timer);\n },\n };\n}\n","/**\n * upload.ts — the engine's half of `@Upload`.\n *\n * THE SHAPE, because it is unusual and the reason matters:\n *\n * client ──[ multipart: file + request body ]──► storage\n * storage ──[ authorize: which bucket, which path? ]──► THIS process\n * storage ── writes the bytes, renders the variants\n * storage ──[ signed: uploadedObject + request body ]──► THIS process\n * THIS process ── the handler runs, returns its typed result\n * storage ──[ that result ]──► client\n *\n * The tenant's code NEVER sees the bytes. It sees the metadata and the request\n * body, and it answers — which is what a completion handler is for. A 1 GB\n * video would otherwise stream through this process to reach the same place.\n *\n * Two calls arrive here, both from storage and neither from a browser:\n *\n * - AUTHORIZE asks which bucket and path a route writes to. Storage cannot\n * know: the answer lives in `@Upload({bucket, pathTemplate})`, which is\n * TypeScript, in the deployed bundle. Asking the process that HAS the\n * routes is what stops the client from naming its own bucket.\n * - COMPLETION runs the handler.\n *\n * Both are signed. An unsigned completion would let anyone with the route path\n * invent an upload that never happened.\n */\n\nimport type { RouteEntry } from \"./router.js\";\n\n/** What authorize answers: where this route's bytes go, and what they may be. */\nexport interface UploadGrant {\n bucket: string;\n path: string;\n maxBytes: number | null;\n mimeTypes: string[] | null;\n /**\n * Who is uploading, or null when nobody is signed in.\n *\n * Storage records this on the object row so deleting the user takes their\n * files with them. It is reported rather than DECIDED here — this process\n * already resolved the caller to render `{userId}` in a path template, and\n * storage has no identity of its own to derive one from. Authorization stays\n * exactly where it was (the route's own `auth` declaration); this is\n * attribution, which is a different question with the same answer already in\n * hand.\n *\n * null is the anonymous upload, and it stays null: a file uploaded by nobody\n * belongs to nobody, and attributing it to whoever signs in next on that\n * device would file one person's upload under another's name.\n */\n ownerUid: string | null;\n}\n\n/** The completion input storage sends after the bytes have landed. */\nexport interface CompletionEnvelope {\n uploadedObject: {\n uploadId: string;\n path: string;\n bucket: string;\n size: number;\n contentType: string;\n checksum: string;\n width?: number;\n height?: number;\n thumbhash?: string;\n variants: Record<string, string>;\n };\n /** The request body the client sent alongside the file. */\n body: unknown;\n}\n\n/** The internal path storage calls to ask where a route's bytes go. */\nexport const AUTHORIZE_PATH = \"/__palbase/upload/authorize\";\n\n/** Header carrying the shared-secret signature on both internal calls. */\nexport const SIGNATURE_HEADER = \"x-palbase-upload-signature\";\n\n/**\n * renderPath fills a `pathTemplate` on the SERVER.\n *\n * The client never chooses where its bytes land. `{filename}` is the one token\n * that comes from the caller, and it is sanitised to a single path segment:\n * without that, `../../../etc/passwd` is a filename, and a template that looks\n * like a folder structure becomes a way to write anywhere in the bucket.\n */\nexport function renderPath(template: string, tokens: {\n userId?: string | null;\n uploadId: string;\n filename?: string;\n}): string {\n return template\n .replaceAll(\"{userId}\", sanitizeSegment(tokens.userId ?? \"anonymous\"))\n .replaceAll(\"{uploadId}\", sanitizeSegment(tokens.uploadId))\n .replaceAll(\"{filename}\", sanitizeSegment(tokens.filename ?? \"file\"));\n}\n\n/**\n * sanitizeSegment reduces a value to something safe inside one path segment.\n *\n * Slashes, dots and control characters go. Keeping dots would allow `..`;\n * keeping slashes would allow a client to climb out of the prefix the template\n * put it in, which is the whole point of having a template.\n */\nexport function sanitizeSegment(raw: string): string {\n const cleaned = raw\n .replace(/[\\x00-\\x1F\\x7F]/g, \"\")\n .replace(/[/\\\\]/g, \"-\")\n .replace(/\\.{2,}/g, \".\")\n .replace(/^\\.+/, \"\")\n .trim();\n return cleaned === \"\" ? \"file\" : cleaned.slice(0, 200);\n}\n\n/**\n * grantFor resolves a route's upload configuration into a concrete grant.\n *\n * Returns null when the route is not an upload route — which is a refusal, not\n * an oversight: storage asking about a route with no `@Upload` means somebody\n * is trying to write through an endpoint that never offered to accept a file.\n */\nexport function grantFor(\n entry: RouteEntry | undefined,\n ctx: { userId: string | null; uploadId: string; filename?: string },\n bucketLimits?: { maxBytes: number | null; mimeTypes: string[] | null },\n): UploadGrant | null {\n const cfg = entry?.meta?.options?.uploadConfig;\n if (!cfg) return null;\n return {\n bucket: cfg.bucket,\n path: renderPath(cfg.pathTemplate, {\n userId: ctx.userId,\n uploadId: ctx.uploadId,\n filename: ctx.filename,\n }),\n maxBytes: bucketLimits?.maxBytes ?? null,\n mimeTypes: bucketLimits?.mimeTypes ?? null,\n ownerUid: ctx.userId ?? null,\n };\n}\n\n/**\n * CompletionLedger makes a completion run its handler EXACTLY ONCE per upload.\n *\n * The completion is a mutation — it writes the row that makes the uploaded\n * bytes mean something — and it is delivered over a network by a caller that\n * retries. A retried completion must not create a second post for one photo, so\n * the second call is answered with the FIRST call's response rather than being\n * refused: to storage, and therefore to the client waiting on it, a retry that\n * succeeds is indistinguishable from the original, which is the point.\n *\n * Bounded, and oldest-first: an upload id is interesting for as long as a retry\n * could still arrive, not forever. The cap is what keeps a long-lived process\n * from turning this into a leak — a ledger that remembered every upload would\n * be a slow way to run out of memory.\n */\nexport class CompletionLedger {\n private readonly seen = new Map<string, CompletedResponse>();\n\n constructor(private readonly capacity = 1024) {}\n\n recall(uploadId: string): CompletedResponse | undefined {\n return this.seen.get(uploadId);\n }\n\n remember(uploadId: string, response: CompletedResponse): void {\n // Delete-then-set so a repeat moves to the back: Map iterates in insertion\n // order, and the eviction below takes the front.\n this.seen.delete(uploadId);\n this.seen.set(uploadId, response);\n while (this.seen.size > this.capacity) {\n const oldest = this.seen.keys().next();\n if (oldest.done) break;\n this.seen.delete(oldest.value);\n }\n }\n\n get size(): number {\n return this.seen.size;\n }\n}\n\n/** A completion's answer, kept verbatim so a retry receives what the first call did. */\nexport interface CompletedResponse {\n status: number;\n body: string | null;\n contentType: string | null;\n}\n\n/**\n * verifySignature compares a presented signature against the expected one in\n * constant time.\n *\n * Constant time because a leaky comparison on a shared secret is recoverable\n * byte by byte, and this secret authorises running a tenant's handler with an\n * upload the caller describes.\n */\nexport function verifySignature(presented: string, expected: string): boolean {\n if (presented.length !== expected.length) return false;\n let diff = 0;\n for (let i = 0; i < presented.length; i++) {\n diff |= presented.charCodeAt(i) ^ expected.charCodeAt(i);\n }\n return diff === 0;\n}\n","// engine/sse.ts — the Server-Sent Events mechanics, extracted from the request\n// pipeline so they can be tested without driving a whole request.\n//\n// This mirrors engine/upload.ts, which extracts renderPath / grantFor /\n// verifySignature and is consumed from engine/index.ts. Keeping the mechanics\n// here means the frame format, the ordering guarantee and the first-write hook\n// each have a test that names them, rather than being reachable only through a\n// full request.\n//\n// The problem being served: a provider on the server streams from a session;\n// while a client is connected its frames reach that client, and when the client\n// disconnects the provider must stop being pulled. This file owns the first\n// half — turning handler writes into wire frames, in order, without letting\n// anything escape before the request phase has been settled.\n\nimport type { SseWriter } from \"../decorators/sse.js\";\n\n/** The response content type for every `@Sse` route. */\nexport const SSE_CONTENT_TYPE = \"text/event-stream\";\n\n/**\n * Encode one value as an SSE `data:` frame.\n *\n * The payload is JSON, and that is load-bearing rather than merely convenient:\n * a raw newline inside a frame ends it and the remainder is parsed as a new\n * field, so a handler streaming user-influenced text could otherwise forge\n * events. JSON encoding escapes the newline, which makes the frame boundary\n * something only this function decides.\n */\nexport function encodeFrame(value: unknown): string {\n return `data: ${JSON.stringify(value)}\\n\\n`;\n}\n\n/**\n * Encode the terminal frame for a handler that threw AFTER it had already\n * written. The status line is long gone by then — 200 and the stream headers\n * were committed with the first frame — so the only honest way to report the\n * failure is in-band, and named, so a client can tell \"the stream ended\" from\n * \"the stream broke\".\n */\nexport function encodeErrorFrame(requestId: string): string {\n return `event: error\\ndata: ${JSON.stringify({ requestId })}\\n\\n`;\n}\n\n/** What `makeSseWriter` returns: the handler-facing writer plus the two members\n * the engine needs. `SseWriter` itself stays minimal — a handler author sees\n * only `write`. */\nexport interface EngineSseWriter extends SseWriter {\n /** Whether anything has been written yet. The engine chooses between an\n * ordinary error envelope (nothing written — the status line is still ours)\n * and a terminal error frame (already streaming) on this answer. */\n started(): boolean;\n /** Resolves when every queued frame has been enqueued. The engine awaits it\n * before closing the stream, so a handler that returns immediately after its\n * last write does not truncate it. */\n drained(): Promise<void>;\n}\n\nexport interface SseWriterOptions {\n /** Hand one encoded frame to the transport. */\n enqueue(chunk: string): void;\n /**\n * Runs ONCE, before the first frame is enqueued, and nothing is emitted until\n * it resolves. This is the seam where the request's database transaction is\n * settled: the handler runs inside that transaction, and a stream that lives\n * for minutes must not hold one open.\n */\n onFirstWrite(): Promise<void>;\n}\n\n/**\n * Build the writer handed to an `@Sse` handler.\n *\n * `write` is SYNCHRONOUS on purpose: a handler relaying a provider writes inside\n * a `for await` loop, and making every chunk awaitable would put a promise in\n * the hot path of every token for no benefit the caller can act on. The cost is\n * that the asynchronous first-write hook has to be absorbed here — so frames are\n * queued on a promise chain and emitted in exactly the order they were written.\n *\n * Values are encoded EAGERLY, inside `write`, not when the queue drains: a\n * handler that writes a mutable object and then keeps mutating it should see the\n * value as it was at the moment it wrote, which is also the only reading that\n * survives being queued.\n */\nexport function makeSseWriter(opts: SseWriterOptions): EngineSseWriter {\n let begun = false;\n let chain: Promise<void> = Promise.resolve();\n\n return {\n write(value: unknown): void {\n const frame = encodeFrame(value);\n if (!begun) {\n begun = true;\n chain = chain.then(() => opts.onFirstWrite()).then(() => opts.enqueue(frame));\n void chain.catch(() => undefined); // drained() retains the authoritative rejection\n return;\n }\n chain = chain.then(() => opts.enqueue(frame));\n void chain.catch(() => undefined);\n },\n started(): boolean {\n return begun;\n },\n drained(): Promise<void> {\n return chain;\n },\n };\n}\n","import \"reflect-metadata\";\n\nimport { DECLARATION_REFUSAL } from \"./refusals.js\";\n\nimport { __claimInjectables, isInjectable } from \"./decorators/injectable.js\";\nimport { isEntryPointClass } from \"./decorators/kinds.js\";\nimport { __claimModules, type ModuleDef, type Token } from \"./decorators/module.js\";\n\n/**\n * `Token` is born in `decorators/module.ts` — the atom of a module's lists — and\n * re-exported here so a reader meets it on the container's surface too. ONE\n * definition: two would be two `abstract new (...)` signatures free to drift.\n */\nexport type { Token };\n\n/**\n * How a container refuses.\n *\n * Every refusal is one of these, and every one names the class involved. There\n * is deliberately no \"unknown\" member: a failure this list cannot classify is a\n * failure the error surface has not been taught to explain, and that is a defect\n * rather than a category.\n */\nexport type DiKind =\n | \"unresolvable dependency\"\n | \"private dependency\"\n | \"missing import\"\n | \"unowned class\"\n | \"dependency cycle\"\n | \"metadata missing\"\n | \"generic dependency\"\n | \"duplicate ownership\"\n | \"unknown export\"\n | \"unknown import\"\n | \"undeclared provider\";\n\n/**\n * A refusal carries four parts: what kind, the full resolution path, where\n * exactly, and what to do about it.\n *\n * The shape is borrowed on purpose — Angular's path, Awilix's failure kind, and\n * Nest's list of potential solutions — because each of the three answers a\n * question the other two leave open: what broke, where in the graph, and what\n * the author should type next.\n */\nexport class DiError extends Error {\n /**\n * EVERY `DiKind` IS A FACT ABOUT THE AUTHOR'S DECLARATIONS — an unresolvable\n * dependency, a cycle, a class no module owns. Not one of them is something\n * the environment could change, so restarting re-reads the same bytes and\n * fails identically. The cure is a new artifact, and the tag is how the\n * runtime learns that without matching on wording.\n */\n readonly [DECLARATION_REFUSAL] = true as const;\n\n constructor(\n readonly kind: DiKind,\n readonly path: string[],\n readonly at: string,\n detail: string,\n readonly fixes: string[],\n ) {\n super(\n `\\nKind: ${kind}\\n` +\n `Path: ${path.length > 0 ? path.join(\" -> \") : \"(none)\"}\\n` +\n `At: ${at}\\n` +\n `${detail}\\n\\n` +\n `Potential solutions:\\n${fixes.map((f) => ` - ${f}`).join(\"\\n\")}\\n`,\n );\n this.name = \"DiError\";\n }\n}\n\n/** How often a module appears in the OTHERS' `imports`. */\nexport interface ModulePressure {\n module: string;\n pct: number;\n /**\n * How many OTHER modules there were — the denominator.\n *\n * Without it the percentage cannot be read. Measured 2026-09-02: a project\n * with two modules, one importing the other, reports 100% — which is true and\n * says nothing, because \"all of the others\" is one module. A reader deciding\n * whether a module has become ambient needs to know whether 80% was four\n * modules or one.\n */\n of: number;\n}\n\nexport interface Container {\n get<T>(t: Token<T>): T;\n /** Every class a module claimed — the set an entry point must be in. */\n readonly owned: ReadonlySet<Token>;\n /**\n * Where `@Global()` pressure is accumulating.\n *\n * A module that appears in more than ~80% of the others' `imports` is one the\n * design is asking to be ambient. That is a JUDGEMENT — how much sharing is\n * too much depends on the domain — so this is reported as a number and never\n * enforced as a gate. Lives on the container rather than in a module-level\n * variable: the runtime builds a candidate's container beside the live app's,\n * and a shared variable would have one overwrite the other's report.\n */\n readonly pressure: readonly ModulePressure[];\n}\n\nconst nameOf = (c: unknown): string => (c as { name?: string } | null)?.name ?? String(c);\n\n/**\n * Values a transpiler emits when a parameter's type has no runtime class.\n *\n * `Object` is the sentinel — an interface, a type alias and a union all collapse\n * to it — and that it is DISTINGUISHABLE from a real class is what lets the\n * container refuse loudly instead of injecting something arbitrary. The\n * primitives are here for the same reason: they are runtime values, so a naive\n * check would happily try to `new` them.\n */\nconst UNRESOLVABLE = new Set<unknown>([\n Object,\n Function,\n String,\n Number,\n Boolean,\n Array,\n Symbol,\n Promise,\n Date,\n undefined,\n null,\n]);\n\n/** The subset worth naming separately: these say \"you passed DATA\" (FR-036). */\nconst DATA = new Set<unknown>([String, Number, Boolean, Date, Symbol]);\n\n/**\n * Does this class SAY what its constructor asks for?\n *\n * The one predicate for the metadata-against-arity cross-check.\n * `assertZeroArgConstructor` calls this rather than re-deriving it: two copies\n * of the rule are two rules, free to drift the moment one is edited.\n */\nexport function declaresDependencies(ctor: unknown): boolean {\n const arity = (ctor as { length?: number } | null)?.length ?? 0;\n if (arity === 0) return true;\n const meta = Reflect.getMetadata(\"design:paramtypes\", ctor as object) as unknown[] | undefined;\n return meta !== undefined && meta.length === arity;\n}\n\n/**\n * Validates the declared modules and returns a container over them.\n *\n * Validation runs in a fixed order, and the order is the point: each stage may\n * assume the previous one held, so a message never has to hedge. Ownership\n * before exports, exports before dependencies, dependencies before cycles,\n * cycles before construction.\n *\n * Stages 3-5 (dependencies and visibility, cycles, resolution) are added by the\n * tasks that follow; this file grows, it is not replaced.\n */\nexport function buildContainer(): Container {\n // CLAIMS the declarations rather than reading them — see `__claimModules`.\n const entries = __claimModules();\n // Claimed HERE even when the graph is about to be refused below, so a failed\n // build cannot leave a previous import's classes for the next one to inherit.\n const declared = __claimInjectables();\n\n // 0 · a project declares at least one module.\n //\n // There is no implicit module. An implicit one would be a SECOND way for a\n // class to become owned, and the whole design rests on there being one: read\n // the module, know the answer.\n if (entries.length === 0) {\n throw new DiError(\n \"unowned class\",\n [],\n \"project\",\n \"no module was declared — every project declares at least one @Module.\",\n [\n \"create `<domain>.module.ts` with @Module({ controllers: [...], providers: [...] })\",\n \"`palbase init` scaffolds one for you\",\n ],\n );\n }\n\n // 1 · ownership — a class belongs to at most one module.\n //\n // `providers` and `controllers` share ONE namespace: a class is owned or it is\n // not, and being listed as both would make \"which module owns it\" a question\n // with two answers.\n const declaredModules = new Set<Token>(entries.map((e) => e.mod));\n\n const owner = new Map<Token, string>();\n for (const { mod, def } of entries) {\n const m = nameOf(mod);\n for (const c of [...(def.providers ?? []), ...(def.controllers ?? [])]) {\n const prev = owner.get(c);\n if (prev !== undefined) {\n throw new DiError(\n \"duplicate ownership\",\n [nameOf(c)],\n `${prev} & ${m}`,\n `${nameOf(c)} is listed by two modules, so which one owns it has two answers.`,\n [\n `remove ${nameOf(c)} from ${prev}`,\n `or remove it from ${m}`,\n `if both modules need it, keep ONE owner and export it, then import that module`,\n ],\n );\n }\n owner.set(c, m);\n }\n }\n\n // 1a · every provider is a class the container can actually BUILD.\n //\n // Measured 02.09.2026: a module that listed an `abstract class` in its\n // `providers` got `new Clock()` — which succeeds in JavaScript and returns an\n // object missing every abstract member — injected into everything that asked\n // for it, and the failure surfaced mid-request as `c.now is not a function`.\n // FR-055 already refuses that shape when the abstraction is named as a\n // DEPENDENCY; this is the same defect coming in through the other door, and\n // the SDK's own test asserted the broken shape was legal.\n //\n // The signal is the decorator. An abstraction in this design is an UNDECORATED\n // `abstract class` (the scaffold's `NoteRepo`), and an implementation carries\n // `@Injectable()`; surfaces carry `@Job`/`@Hook`/`@Webhook`/`@Room`. So a\n // provider carrying none of them is either an abstraction listed in the wrong\n // place or a class somebody forgot to decorate — and the second is not benign\n // either: without a decorator TypeScript emits no `design:paramtypes`, so\n // every constructor parameter it asks for would arrive `undefined`.\n {\n for (const { mod, def } of entries) {\n for (const p of def.providers ?? []) {\n if (isInjectable(p) || isEntryPointClass(p)) continue;\n // A class whose constructor ASKS for something but carries no emitted\n // types is a different fault with a better message — `metadata missing`\n // in stage 3, which explains `emitDecoratorMetadata` and the bundler.\n // Leaving it to that stage keeps each refusal pointed at one cause. The\n // abstract seam this rule is for has a zero-argument constructor\n // (`abstract class NoteRepo { abstract findMany(…) }`), so it lands\n // here.\n if (!declaresDependencies(p)) continue;\n throw new DiError(\n \"undeclared provider\",\n [nameOf(mod), nameOf(p)],\n `${nameOf(mod)}.providers`,\n `${nameOf(p)} is listed in ${nameOf(mod)}.providers but carries no decorator, ` +\n `so the container cannot know it is constructible or what its constructor asks for.`,\n [\n `mark ${nameOf(p)} \\`@Injectable()\\` if it is a concrete class`,\n `if ${nameOf(p)} is an \\`abstract class\\`, list the class that \\`extends\\` it instead — ` +\n `name the abstraction as the DEPENDENCY and the container resolves it`,\n ],\n );\n }\n }\n }\n\n // 1b · every declared class is OWNED by a module (FR-010).\n //\n // `@Injectable()` decides nothing — ownership is read from a module and from\n // nowhere else — but it makes the class COUNTABLE, and this is the question\n // that needs counting: a service written, imported, and listed in no module.\n // It has no entry point, so `assertNoOrphanEntryPoints` never sees it; it has\n // no dependent, so the resolution stages never reach it. It simply does not\n // exist, silently, which is the one outcome this design refuses everywhere\n // else. Measured through the CLI on 2026-09-02: the build said \"build OK\".\n //\n // Not in `isolated()`: that builds a graph without consulting this file at\n // all, deliberately, because a unit test is not a second opinion about the\n // architecture.\n {\n const orphans = declared.filter((c) => !owner.has(c));\n if (orphans.length > 0) {\n const names = orphans.map(nameOf);\n throw new DiError(\n \"unowned class\",\n names,\n \"module declarations\",\n `${names.join(\", \")} ${orphans.length === 1 ? \"is\" : \"are\"} marked @Injectable() ` +\n `but listed in no module's providers, so nothing can reach ${orphans.length === 1 ? \"it\" : \"them\"}.`,\n [\n `add ${names.length === 1 ? names[0] : \"each of them\"} to a module's \\`providers\\``,\n \"or delete the class — one no module lists is never built\",\n ],\n );\n }\n }\n\n // 2 · exports — a module may only open up what it OWNS.\n //\n // Re-exporting someone else's class would be a hole in the boundary the\n // module system exists to draw: the owner's decision about who may reach it\n // would stop being the owner's.\n const exported = new Map<string, Set<Token>>();\n const importsOf = new Map<string, Set<string>>();\n for (const { mod, def } of entries) {\n const m = nameOf(mod);\n for (const e of def.exports ?? []) {\n if (owner.get(e) !== m) {\n const holder = owner.get(e);\n throw new DiError(\n \"unknown export\",\n [m],\n `${m}.exports`,\n holder === undefined\n ? `${m} exports ${nameOf(e)}, but no module owns it.`\n : `${m} exports ${nameOf(e)}, but ${holder} owns it — a module cannot re-export another's class.`,\n holder === undefined\n ? [`add ${nameOf(e)} to ${m}.providers`, `or remove it from ${m}.exports`]\n : [\n `remove ${nameOf(e)} from ${m}.exports`,\n `and have ${holder} export it instead, then add ${holder} to the importing module's imports`,\n ],\n );\n }\n }\n // An `imports` entry must BE a module. Measured before this check existed:\n // `@Module({ imports: [NotAModule] })` built cleanly and did nothing — the\n // name simply never matched an owner, so every dependency it was meant to\n // unlock kept being refused for a reason that pointed elsewhere.\n for (const i of def.imports ?? []) {\n // Self-import is expressible — legacy decorators run after the class\n // binding exists, so `@Module({ imports: [M] }) class M {}` compiles and\n // ran silently before this check. It grants a module access to its own\n // exports, which it already has, so it is always a typo for another name.\n if (i === mod) {\n throw new DiError(\n \"unknown import\",\n [m],\n `${m}.imports`,\n `${m} imports itself, which grants nothing it does not already have.`,\n [`remove ${m} from its own imports`, \"or name the module you meant instead\"],\n );\n }\n if (!declaredModules.has(i)) {\n throw new DiError(\n \"unknown import\",\n [m],\n `${m}.imports`,\n `${m} imports ${nameOf(i)}, which is not a module.`,\n [\n `add @Module({ ... }) to ${nameOf(i)}`,\n `or remove ${nameOf(i)} from ${m}.imports — to reach a class, import the module that OWNS it`,\n ],\n );\n }\n }\n\n exported.set(m, new Set(def.exports ?? []));\n importsOf.set(m, new Set((def.imports ?? []).map(nameOf)));\n }\n\n // 3 · dependencies — metadata against arity, then type validity, then module\n // visibility. In that order, because each answer makes the next question\n // meaningful.\n const deps = new Map<Token, Token[]>();\n\n /**\n * The owned classes that EXTEND `t`.\n *\n * `abstract` does not exist at runtime — JavaScript happily runs `new Clock()`\n * and returns an object missing every abstract member. Measured before this\n * existed: the container injected exactly that, the build was green, and the\n * failure surfaced mid-request as `c.now is not a function`.\n *\n * So an abstraction is resolved through its implementation, and the\n * relationship is read from the prototype chain — which is what `extends`\n * builds. That is a DECLARATION the class makes about itself, not an\n * inference from where its file sits.\n *\n * Only consulted for a token NOTHING owns. A class that IS owned is the\n * answer to its own name, so an unrelated `extends` elsewhere can never\n * change what an existing dependency resolves to.\n */\n const implementorsOf = (t: Token): Token[] =>\n [...owner.keys()].filter(\n (c) => c !== t && Object.prototype.isPrototypeOf.call(t as object, c as object),\n );\n\n // Is missing metadata GLOBAL or local? Decided BEFORE any per-class message,\n // because the two faults look identical one class at a time and lead to\n // opposite fixes: all of them missing means the build ran without\n // `emitDecoratorMetadata` (or without `reflect-metadata`, whose absence makes\n // the emitted helper a silent no-op); some of them missing means the author\n // forgot `@Injectable()` on those. Telling someone to decorate a class when\n // the flag is off sends them to edit a file that is not the problem.\n //\n // NOT a synthetic canary. An earlier design embedded a probe class in the SDK\n // and asked whether IT carried metadata — but the SDK is built with tsup, and\n // esbuild emits zero `__metadata` (measured), so that probe would report a\n // global fault on every healthy boot. The tenant's OWN classes are the only\n // honest sample of the tenant's build.\n const withArity = [...owner.keys()].filter(\n (c) => (c as unknown as { length: number }).length > 0,\n );\n const missingMeta = withArity.filter(\n (c) => Reflect.getMetadata(\"design:paramtypes\", c) === undefined,\n );\n // TWO is the smallest sample this inference is honest on. With ONE class,\n // \"all of them are missing\" is also what a single forgotten `@Injectable()`\n // looks like, and telling that author their build is broken sends them to the\n // wrong file. Below the threshold the per-class message runs, which names the\n // class and the decorator.\n if (withArity.length >= 2 && missingMeta.length === withArity.length) {\n throw new DiError(\n \"metadata missing\",\n withArity.map(nameOf),\n \"the whole build\",\n `no class carries constructor metadata — every one of the ${withArity.length} ` +\n `class(es) that asks for a dependency is missing it, so this is the build, ` +\n `not the classes.`,\n [\n \"set `emitDecoratorMetadata: true` in the project's tsconfig.json\",\n \"and import `reflect-metadata` before any decorated class evaluates — without it the emitted helper is a silent no-op\",\n \"if the build is fine, then none of these classes carries @Injectable()\",\n ],\n );\n }\n\n for (const [cls, m] of owner) {\n const arity = (cls as unknown as { length: number }).length;\n\n // ARITY IS THE GROUND TRUTH. It survives every transpile; metadata does not.\n // Measured: a decorated class with no constructor carries `undefined`\n // metadata and a decorated one with an empty constructor carries `[]` —\n // both ask for nothing, and only arity says so. Treating absent metadata as\n // a fault would refuse every dependency-free class that never wrote a\n // constructor, which is most of them.\n if (arity === 0) {\n deps.set(cls, []);\n continue;\n }\n\n // Asked through the shared predicate, so \"does this class say what it needs\"\n // has ONE definition — the same one `assertZeroArgConstructor` answers with.\n if (!declaresDependencies(cls)) {\n const meta = Reflect.getMetadata(\"design:paramtypes\", cls) as unknown[] | undefined;\n throw new DiError(\n \"metadata missing\",\n [nameOf(cls)],\n `${nameOf(cls)} constructor`,\n `${nameOf(cls)} declares ${arity} parameter(s) but carries ` +\n `${meta === undefined ? \"no\" : String(meta.length)} metadata entries, ` +\n `so every parameter would arrive as undefined.`,\n [\n `add @Injectable() to ${nameOf(cls)} — metadata is emitted for DECORATED classes only`,\n \"or the build ran without emitDecoratorMetadata: check tsconfig.json\",\n ],\n );\n }\n\n const meta = Reflect.getMetadata(\"design:paramtypes\", cls) as unknown[];\n const list: Token[] = [];\n meta.forEach((t, i) => {\n const at = `${nameOf(cls)} constructor, parameter ${i}`;\n\n if (typeof t !== \"function\" || UNRESOLVABLE.has(t)) {\n throw new DiError(\n \"unresolvable dependency\",\n [nameOf(cls)],\n at,\n `parameter ${i} has no runtime class — an interface, a type alias, a ` +\n `union, or a data type. The container has nothing to construct.`,\n DATA.has(t)\n ? [\n \"an injectable's constructor takes dependencies, not data\",\n \"move the value to a method argument instead\",\n \"or make this a plain value class (no @Injectable, in no module) and `new` it yourself\",\n ]\n : [\n \"depend on a concrete class or an abstract class\",\n \"a TypeScript interface does not exist at runtime — there is nothing to inject\",\n ],\n );\n }\n\n const dep = t as Token;\n\n {\n let dm = owner.get(dep);\n if (dm === undefined) {\n // An ABSTRACTION, resolved to its one implementation (FR-055).\n //\n // Read from `extends`, not from a second syntax: `class SystemClock\n // extends Clock` is the class declaring \"I am a Clock\", and that is a\n // declaration — not an inference from where a file sits.\n const impls = implementorsOf(dep);\n if (impls.length === 1) {\n const impl = impls[0] as Token;\n list.push(impl);\n dm = owner.get(impl) as string;\n if (dm !== m) {\n if (!importsOf.get(m)?.has(dm)) {\n throw new DiError(\n \"missing import\",\n [nameOf(cls), nameOf(impl)],\n at,\n `${nameOf(impl)} implements ${nameOf(dep)} and is owned by ${dm}, which ${m} does not import.`,\n [`add ${dm} to ${m}.imports`],\n );\n }\n if (!exported.get(dm)?.has(impl)) {\n throw new DiError(\n \"private dependency\",\n [nameOf(cls), nameOf(impl)],\n at,\n `${nameOf(impl)} implements ${nameOf(dep)} but is internal to ${dm}.`,\n [`add ${nameOf(impl)} to ${dm}.exports (and say why)`],\n );\n }\n }\n return;\n }\n if (impls.length > 1) {\n const names = impls.map(nameOf).sort();\n throw new DiError(\n \"duplicate ownership\",\n [nameOf(cls), nameOf(dep)],\n at,\n `${names.join(\" and \")} both extend ${nameOf(dep)}, so which one ` +\n `${nameOf(cls)} should receive has two answers.`,\n [\n `keep ONE class extending ${nameOf(dep)} in this graph`,\n `or depend on ${names[0]} or ${names[1]} directly, by name`,\n ],\n );\n }\n throw new DiError(\n \"unowned class\",\n [nameOf(cls), nameOf(dep)],\n at,\n `${nameOf(dep)} belongs to no module, and nothing in this graph extends it — ` +\n `so there is nothing to construct. (An abstract class cannot be built: ` +\n `\\`abstract\\` is a type-level claim, and \\`new\\` on one returns an object ` +\n `missing every abstract member.)`,\n [\n `add ${nameOf(dep)} to a module's providers if it is concrete`,\n `or add a class that \\`extends ${nameOf(dep)}\\` to a module's providers`,\n ],\n );\n }\n if (dm !== m) {\n if (!importsOf.get(m)?.has(dm)) {\n throw new DiError(\n \"missing import\",\n [nameOf(cls), nameOf(dep)],\n at,\n `${nameOf(dep)} is owned by ${dm}, which ${m} does not import.`,\n [`add ${dm} to ${m}.imports`],\n );\n }\n if (!exported.get(dm)?.has(dep)) {\n throw new DiError(\n \"private dependency\",\n [nameOf(cls), nameOf(dep)],\n at,\n `${nameOf(dep)} is internal to ${dm} — it is not exported.`,\n [\n `use one of ${dm}'s exported classes`,\n `or add ${nameOf(dep)} to ${dm}.exports (and say why it should be public)`,\n ],\n );\n }\n }\n }\n\n list.push(dep);\n });\n\n deps.set(cls, list);\n }\n\n // 4 · cycles — refused, with the path written out by name.\n //\n // There is NO `forwardRef`-style escape, and the reason is that the shape one\n // exists to rescue cannot be built: a real ESM cycle dies at import. Measured\n // in the spike — Bun throws `Cannot access 'CB' before initialization` before\n // the container is ever consulted. What CAN still be assembled is a cycle\n // inside one file, so the detector earns its place; what it never has to do is\n // offer a way to keep one.\n const state = new Map<Token, 0 | 1 | 2>();\n const stack: Token[] = [];\n const walk = (c: Token): void => {\n if (state.get(c) === 1) {\n // Slice from where this class first entered the stack, so the message is\n // the CYCLE and not the path that happened to reach it.\n const cyc = [...stack.slice(stack.indexOf(c)), c].map(nameOf);\n throw new DiError(\n \"dependency cycle\",\n cyc,\n `${cyc[0]} constructor`,\n `the dependency graph contains a cycle: ${cyc.join(\" -> \")}.`,\n [\n \"extract the shared part into a third class both can depend on\",\n \"or invert one direction — have the callee raise an event the caller listens for\",\n ],\n );\n }\n if (state.get(c) === 2) return;\n state.set(c, 1);\n stack.push(c);\n // A platform token needs no special case: it has no `deps` entry, so the\n // walk reaches it, finds nothing to follow, and marks it done. A guard here\n // would be an inert check — it was written, measured against a mutation, and\n // removed when removing it changed nothing.\n for (const d of deps.get(c) ?? []) walk(d);\n stack.pop();\n state.set(c, 2);\n };\n for (const c of owner.keys()) walk(c);\n\n // 5 · resolution — ONE lifetime, singleton.\n //\n // No `transient`, no `request`. Request scope already exists and it is an\n // AsyncLocalStorage, not an object lifetime: what varies per request is the\n // database handle and the claims, and the engine opens that scope around the\n // handler. Making the OBJECTS per-request would duplicate that mechanism and\n // then have to keep the two in agreement.\n //\n // The consequence is a rule about constructors: they stay synchronous and do\n // nothing but wiring. Real I/O belongs in `onStart`, where it can fail loudly\n // at boot instead of halfway through the first request.\n const cache = new Map<Token, unknown>();\n const make = (c: Token): unknown => {\n // A token this container never validated is NOT built. Measured before this\n // check existed: `get(Stranger)` found no `deps` entry, fell through to\n // `new Stranger()` with zero arguments, and returned it — so a class in no\n // module could still be constructed through the container's own front door,\n // which is the hole the module system exists to close (FR-053).\n //\n // There is no platform escape hatch here: platform services (Database, Log,\n // …) are AMBIENT — imported, not injected — because they are request-scoped\n // and a boot-time singleton holding one would capture the first request's\n // client forever (FR-005). Nothing supplies a platform map, so having one\n // would be an inert extension point.\n if (!owner.has(c)) {\n throw new DiError(\n \"unowned class\",\n [nameOf(c)],\n \"container.get\",\n `${nameOf(c)} belongs to no module, so this container never validated it ` +\n `and will not build it.`,\n [\n `add ${nameOf(c)} to a module's providers`,\n \"or, if it is a plain value class, construct it yourself with `new`\",\n ],\n );\n }\n const hit = cache.get(c);\n if (hit !== undefined) return hit;\n const args = (deps.get(c) ?? []).map(make);\n const inst = new (c as unknown as new (...a: unknown[]) => unknown)(...args);\n cache.set(c, inst);\n return inst;\n };\n\n return {\n get: <T,>(t: Token<T>): T => make(t) as T,\n owned: new Set(owner.keys()),\n pressure: computePressure(entries),\n };\n}\n\n/**\n * What fraction of the OTHER modules import each module.\n *\n * `total - 1` is the denominator because a module never imports itself, so the\n * most any module can reach is everyone else. Under two modules there is nothing\n * to compare and the answer is an empty list rather than a misleading 100%.\n */\nfunction computePressure(entries: { mod: Token; def: ModuleDef }[]): ModulePressure[] {\n // No `total < 2` guard, and none is needed: a single module cannot import\n // anything (there is no other module, and both self-import and non-module\n // imports are refused above), so `count` is empty and the division below never\n // runs. The guard was written, measured against a mutation, and removed when\n // removing it changed nothing — an inert check still draws a number.\n const total = entries.length;\n const count = new Map<string, number>();\n for (const { def } of entries) {\n for (const i of def.imports ?? []) {\n const n = nameOf(i);\n count.set(n, (count.get(n) ?? 0) + 1);\n }\n }\n return [...count]\n .map(([module, c]) => ({ module, pct: Math.round((c / (total - 1)) * 100), of: total - 1 }))\n .sort((a, b) => b.pct - a.pct);\n}\n\n/** Kept so the module surface is stable while stages 3-5 land. */\nexport type { ModuleDef };\n\n/**\n * Refuses an entry point that no module lists (FR-035).\n *\n * A decorated class registers itself — `@Controller` pushes into a globalThis\n * slot the moment its file is imported — so before this check a class listed in\n * no module still reached the route table, the dispatcher and the OpenAPI\n * document. It worked, which is the problem: nothing said the module system had\n * been bypassed.\n *\n * After this, a successful boot means the two sets are EQUAL: what decorated\n * itself and what a module claimed. That equality is what lets `src/openapi/`\n * stay untouched — it renders the list it is handed, and the list is now the\n * module's.\n */\nexport function assertNoOrphanEntryPoints(\n registered: readonly unknown[],\n owned: ReadonlySet<Token>,\n): void {\n const orphans = registered.filter((c) => !owned.has(c as Token));\n if (orphans.length === 0) return;\n const names = orphans.map((c) => (c as { name?: string }).name ?? \"<anonymous>\");\n throw new DiError(\n \"unowned class\",\n names,\n \"module declarations\",\n `${names.join(\", \")} ${orphans.length === 1 ? \"is\" : \"are\"} decorated as an entry ` +\n `point but listed in no module, so nothing decides whether it should be served.`,\n [\n \"add it to a module's `controllers` (for @Controller) or `providers` (for @Room/@Job/@Hook/@Webhook)\",\n \"an entry point no module lists is never mounted and never reaches the OpenAPI document\",\n ],\n );\n}\n","import { type Token } from \"./module.js\";\n\n/**\n * The slot injectable declarations accumulate in.\n *\n * On `globalThis` under a well-known Symbol for the same reason `DI_MODULES` is\n * (see `module.ts`): a tenant bundle inlines its OWN copy of `@palbase/backend`\n * and the engine that loads it carries another, so a module-local array would\n * have the decorators push into one and the container read the other.\n */\nexport const DI_INJECTABLES: unique symbol = Symbol.for(\n \"palbase.backend.diInjectables\",\n) as never;\n\n/**\n * The marker `@Injectable()` leaves ON the class.\n *\n * Two signals, because two questions are being asked and only one of them can be\n * answered by a list. \"WHICH classes were declared in this build\" needs an\n * enumeration and gets the claimable slot below. \"IS this class decorated\" needs\n * an answer that survives Bun's module cache: a rollback re-imports an artifact\n * whose body does not run again, so the slot comes back empty while the modules\n * still list the same classes. Reading the slot for that question refused a\n * correct app — measured in `engine.test.ts`, where the second `createApp` in\n * one process saw an emptied slot and called every provider undecorated.\n */\nexport const INJECTABLE: unique symbol = Symbol.for(\"palbase.backend.injectable\") as never;\n\n/** Does this class carry `@Injectable()`? Reads the class, not a registry. */\nexport const isInjectable = (c: unknown): boolean =>\n (c as Record<symbol, unknown> | null)?.[INJECTABLE] === true;\n\nfunction slot(): Token[] {\n const g = globalThis as unknown as Record<symbol, Token[] | undefined>;\n return (g[DI_INJECTABLES] ??= []);\n}\n\n/**\n * Marks a class the container can resolve.\n *\n * TWO JOBS, and the first one is why the decorator has to exist at all:\n * TypeScript under `emitDecoratorMetadata` emits `design:paramtypes` for\n * DECORATED classes only. Measured — an undecorated class with the same\n * constructor carries no metadata, and `Reflect.getMetadata` answers\n * `undefined`.\n *\n * The second is being COUNTABLE. Ownership, visibility and permission are still\n * read from a single `@Module` and never from this decorator — recording the\n * class here decides nothing. It only makes \"carries `@Injectable()` and\n * appears in no module\" a question the build can ask, which FR-010 requires it\n * to answer by name. The body was empty until 2026-09-02, and the consequence\n * was measured through the CLI: an `@Injectable()` service in no module built\n * clean, while this file's own comment claimed the build named it.\n */\nexport function Injectable(): ClassDecorator {\n return (target) => {\n (target as unknown as Record<symbol, unknown>)[INJECTABLE] = true;\n slot().push(target as unknown as Token);\n };\n}\n\n/**\n * TAKES the accumulated declarations — it does not read them.\n *\n * Same claim semantics as `__claimModules`, and for the same reason: a\n * candidate bundle is imported into the SAME process as the live app it might\n * replace, so reading would let a candidate be judged against the live app's\n * classes and a discarded candidate would leave its own behind.\n */\nexport function __claimInjectables(): Token[] {\n return slot().splice(0);\n}\n","import type { Container, Token } from \"../container.js\";\n\n/**\n * Which of a container's classes are entry points of each kind.\n *\n * Discovery used to be a DIRECTORY: `jobs/*.ts` was the list of jobs, and\n * `@Job` recorded metadata but registered nothing. That made the file system a\n * second declaration — a class could carry `@Job`, sit outside `jobs/`, and\n * never run; or sit inside it, be listed in no module, and run anyway.\n *\n * Now a module lists it and the decorator says what it is. One declaration\n * answers ownership, and the metadata answers kind. These four predicates are\n * the only place that mapping lives.\n */\nconst JOB = Symbol.for(\"palbase.backend.jobMeta\");\nconst WEBHOOK = Symbol.for(\"palbase.backend.webhookMeta\");\nconst HOOK_BLOCKING = Symbol.for(\"palbase.backend.hookBlocking\");\nconst HOOK_LISTENERS = Symbol.for(\"palbase.backend.webhookEvents\");\nconst ROOM = Symbol.for(\"palbase.backend.room\");\nconst CONTROLLER = Symbol.for(\"palbase.backend.controllerMeta\");\n\nconst has = (c: unknown, s: symbol): boolean =>\n (c as Record<symbol, unknown>)[s] !== undefined;\n\n/**\n * Does this class carry one of the surface decorators?\n *\n * The container asks, because `providers` legitimately holds `@Job`, `@Hook`,\n * `@Webhook` and `@Room` classes alongside `@Injectable()` ones, and the rule it\n * enforces there — a provider must be DECORATED, so it is constructible and its\n * constructor's types were emitted — has to know that. The predicate lives here\n * because this file is the one place the marker symbols are named.\n */\nexport const isEntryPointClass = (c: unknown): boolean =>\n has(c, JOB) || has(c, WEBHOOK) || has(c, ROOM) || has(c, CONTROLLER) ||\n has(c, HOOK_BLOCKING) || has(c, HOOK_LISTENERS);\n\nconst owned = (container: Container): Token[] => [...container.owned];\n\nexport const jobsOf = (container: Container): Token[] => owned(container).filter((c) => has(c, JOB));\n\nexport const webhooksOf = (container: Container): Token[] =>\n owned(container).filter((c) => has(c, WEBHOOK));\n\n/**\n * A hook class carries handler entries and NO class-level marker, so it is\n * recognised by having handlers while being neither a webhook nor a controller.\n * `@On` is shared with `@Webhook`, which is why the webhook marker is what\n * separates them.\n */\nexport const hooksOf = (container: Container): Token[] =>\n owned(container).filter(\n (c) =>\n !has(c, WEBHOOK) &&\n !has(c, CONTROLLER) &&\n (has(c, HOOK_BLOCKING) || has(c, HOOK_LISTENERS)),\n );\n\nexport const roomsOf = (container: Container): Token[] =>\n owned(container).filter((c) => has(c, ROOM));\n\nexport const controllersOf = (container: Container): Token[] =>\n owned(container).filter((c) => has(c, CONTROLLER));\n","/**\n * A class the container can resolve, named by its own constructor.\n *\n * There is NO separate token concept — no strings, no symbols, no `@Inject`.\n * An abstraction is an `abstract class`, which is still a runtime value and so\n * is still a token. `never[]` on the parameters makes a token something you can\n * NAME but not call: `Token` is an identity, not a factory.\n */\nexport type Token<T = unknown> = abstract new (...args: never[]) => T;\n\n/**\n * The four lists a module declares.\n *\n * `providers` is OWNERSHIP — a class belongs to exactly one module and this is\n * where that is said. `exports` is VISIBILITY — what other modules may reach.\n * `imports` is PERMISSION — whose exports this module may reach. `controllers`\n * are the entry points the module owns.\n *\n * Position in a list means nothing; ownership is read from this declaration and\n * from nowhere else — not from a directory, not from a file name, not from the\n * class's own decorator (spec FR-009).\n */\nexport interface ModuleDef {\n imports?: Token[];\n controllers?: Token[];\n providers?: Token[];\n exports?: Token[];\n}\n\n/**\n * The slot module declarations accumulate in.\n *\n * On `globalThis` under a well-known Symbol, for the same reason\n * `lifecycleHooks` is (runtime.ts:210): a tenant bundle inlines its OWN copy of\n * `@palbase/backend`, and the engine that loads it carries another. Two\n * module-local arrays would mean the engine reads the empty one — decorators\n * push into the bundle's copy, `createApp` claims from the engine's, and every\n * module silently disappears.\n */\nexport const DI_MODULES: unique symbol = Symbol.for(\"palbase.backend.diModules\") as never;\n\n/** One `@Module` declaration: the class that carried it, and what it declared. */\nexport interface ModuleEntry {\n mod: Token;\n def: ModuleDef;\n}\n\nfunction slot(): ModuleEntry[] {\n const g = globalThis as unknown as Record<symbol, ModuleEntry[] | undefined>;\n return (g[DI_MODULES] ??= []);\n}\n\n/**\n * Declares a module.\n *\n * There is no root module and nothing to mount it into: registration IS the\n * decorator running, which happens when the file is imported. A project with no\n * module file at all is not an error — it simply owns nothing, and every entry\n * point it declares is refused by name (FR-035) rather than quietly served.\n */\nexport function Module(def: ModuleDef): ClassDecorator {\n return (target) => {\n slot().push({ mod: target as unknown as Token, def });\n };\n}\n\n/**\n * TAKES the accumulated declarations — it does not read them.\n *\n * Same reason `__runStartHooks` splices (runtime.ts:297): a candidate bundle is\n * imported into the SAME process as the live app it might replace. Reading\n * would let the candidate build a container out of the live app's modules, and\n * a discarded candidate would leave its own behind for the next release to\n * adopt. Claiming makes each `createApp` see exactly the modules imported since\n * the last one, and a rollback leave nothing behind.\n */\nexport function __claimModules(): ModuleEntry[] {\n return slot().splice(0);\n}\n","/**\n * engine/fence.ts — what the tenant's own code may reach.\n *\n * The isolate used to answer this by construction: tenant code ran in a realm\n * with no ambient network and an environment scrubbed of every secret, and each\n * privileged call hopped to a host that held the credentials. Running the\n * backend as one process removes that wall, so the two guarantees it carried\n * have to be re-made here — deliberately, and with the honest note that a\n * same-process fence is a SPEED BUMP against the tenant's own code, not a\n * sandbox. The real boundary is the machine: each tenant has its own.\n *\n * That is not a hole, it is a scope. The tenant owns this database and this\n * network namespace; the thing worth preventing is an ACCIDENT — a dependency\n * that reads `process.env` and posts it somewhere, a handler that opens its own\n * unscoped connection and quietly serves every user's rows — not a determined\n * operator attacking their own stack.\n */\n\n/** Names the engine holds and the tenant's code must not find lying around. */\nconst SECRET_ENV = [\n \"DATABASE_URL\",\n \"PALBASE_SERVICE_ROLE_KEY\",\n \"REALTIME_INGESTION_SECRET\",\n \"INTERNAL_API_SECRET\",\n \"STACK_ROOT_KEY\",\n \"PEPPER\",\n \"LOCAL_JWT_PEM\",\n] as const;\n\nexport interface ScrubResult {\n removed: string[];\n kept: string[];\n}\n\n/**\n * Delete the engine's own credentials from `process.env`.\n *\n * MUST run AFTER the config is read and BEFORE the tenant bundle is imported —\n * a bundle's module-level code runs at import, so a scrub that comes later has\n * already lost the race.\n *\n * The tenant's OWN variables (`PALBASE_VAR_*` and anything else) are untouched:\n * this removes what the platform put there, not what the operator did.\n *\n * Why RLS makes this matter: the engine binds every request to the caller with\n * `set_config('role', …)` so Postgres does the row filtering. Code that finds\n * `DATABASE_URL` can open its own connection as the owner and read every user's\n * rows — not by attacking anything, just by using a driver.\n */\nexport function scrubSecrets(env: Record<string, string | undefined>): ScrubResult {\n const removed: string[] = [];\n const kept: string[] = [];\n for (const name of SECRET_ENV) {\n if (env[name] === undefined) continue;\n delete env[name];\n removed.push(name);\n }\n for (const name of Object.keys(env)) if (name.startsWith(\"PALBASE_VAR_\")) kept.push(name);\n return { removed, kept };\n}\n\nexport interface EgressPolicy {\n /** Hostnames the tenant declared. Empty ⇒ no declaration was made. */\n allow: readonly string[];\n /** Per-call ceiling in ms. 0 ⇒ no ceiling declared. */\n timeoutMs: number;\n /** What to do when nothing was declared. */\n whenUndeclared: \"allow\" | \"deny\";\n /**\n * Hosts the BACKEND ITSELF needs: its module surface, the JWKS it verifies\n * tokens against, the artifact store it reloads from.\n *\n * These are not egress. `config/egress.ts` declares where the tenant's own\n * code may reach; a call to the platform this backend is part of is internal\n * traffic, and fencing it means the first deploy with an allowlist takes the\n * backend down — which is exactly what happened when this list did not exist:\n * every request 500'd with \"egress denied: palsvc is not in this backend's\n * declared allowlist\", and the artifact reload loop stopped with it.\n */\n alwaysAllow?: readonly string[];\n}\n\n/** `api.stripe.com` matches itself; `*.stripe.com` matches any subdomain. */\nexport function hostAllowed(host: string, allow: readonly string[]): boolean {\n const h = host.toLowerCase();\n for (const raw of allow) {\n const pattern = raw.trim().toLowerCase();\n if (!pattern) continue;\n if (pattern === h) return true;\n if (pattern.startsWith(\"*.\") && h.endsWith(pattern.slice(1)) && h.length > pattern.length - 1) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Install the tenant's declared outbound allowlist over `globalThis.fetch`.\n *\n * The engine's own traffic is exempted by HOST (`alwaysAllow`), not by holding\n * a captured reference: the module clients and the verifier resolve\n * `globalThis.fetch` at CALL time, so a captured original never reaches them.\n * That distinction is not academic — the first version of this file claimed the\n * capture worked, and every request 500'd on the first deploy that declared an\n * allowlist.\n *\n * @returns the original fetch, for the engine's own use.\n */\nexport function installEgressFence(policy: EgressPolicy): typeof fetch {\n const original = globalThis.fetch.bind(globalThis);\n const declared = policy.allow.length > 0;\n const platform = (policy.alwaysAllow ?? []).map((h) => h.toLowerCase()).filter(Boolean);\n\n if (!declared && policy.whenUndeclared === \"allow\") return original;\n\n const fenced: typeof fetch = async (input, init) => {\n const url =\n typeof input === \"string\"\n ? new URL(input)\n : input instanceof URL\n ? input\n : new URL((input as Request).url);\n\n // The backend's own platform first — internal traffic is not egress.\n if (platform.includes(url.hostname.toLowerCase())) return original(input, init);\n\n if (!declared || !hostAllowed(url.hostname, policy.allow)) {\n throw new Error(\n `egress denied: ${url.hostname} is not in this backend's declared allowlist. ` +\n `Add it to config/egress.ts and deploy.`,\n );\n }\n if (policy.timeoutMs > 0) {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), policy.timeoutMs);\n try {\n return await original(input, { ...init, signal: init?.signal ?? controller.signal });\n } finally {\n clearTimeout(timer);\n }\n }\n return original(input, init);\n };\n\n globalThis.fetch = fenced;\n return original;\n}\n"],"mappings":"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","names":["REF_BRAND","Symbol","for","brandRef","v","kind","Object","defineProperty","value","enumerable","brandOf","undefined","hasOwn","looksLikeUnbrandedRef","isColumnExpr","o","$col","$sql","$expr","isColRef","isPlanRef","r","$ref","op","field","looksLikeUnbrandedPlanRef","isSqlFragment","f","Array","isArray","text","values","TX_EXPR","isNowExpr","e","fn","assertNoExpressionHandles","caller","table","cols","data","c","Error","KNOWN_OPS","Set","REFUSED_OPS","eq","assertUsableFilter","where","COMPOSITES","col","cond","entries","has","branches","b","rel","inner","length","some","x","assertUsableWriteValues","TxRefError","Error","message","name","TxPlanError","EXPR","Symbol","for","REF","ROW","ROWS","TRAPPED_PROPS","toPrimitive","trap","prop","what","hint","description","String","columnExprOf","v","exprOf","makeRef","op","field","target","REF","Proxy","get","t","prop","TRAPPED_PROPS","includes","trap","undefined","makeRowHandle","ROW","refDescriptor","v","d","isRefDescriptor","rowOpIndex","exprOf","e","EXPR","isRowsHandle","ROWS","encodeValue","value","column","allowColumnExpr","ref","brandRef","$ref","isNowExpr","$expr","fn","expr","TxPlanError","assertNoNestedHandles","encodeFilterValue","Array","isArray","map","Date","isColRef","isSqlFragment","out","k","Object","entries","encodeFilterMap","key","keys","sort","item","values","encodeMap","SKIPPED_OP","TxRowsImpl","guarded","builder","opIndex","what","then","TxRefError","expectOne","error","declareGuard","expectNone","expectAtLeast","n","assertGuardCount","expectAtMost","kind","Error","attachGuard","Number","isInteger","String","MAX_OPS","MAX_ROWS","TxPlanBuilder","ops","slots","table","name","insert","encoded","length","push","put","options","onConflict","insertMany","rows","opts","row","assertUniformRows","action","updateWhere","where","set","encodedWhere","encodedSet","deleteWhere","select","limit","lock","index","slot","guard","body","errorForSlot","first","want","wantKey","join","i","got","materializeResult","results","rowOf","rowOp","isPlainObject","result","proto","getPrototypeOf","prototype","runTxPlan","transport","handle","returned","response","txPlan","err","translateRejection","rejection","error_code","retryBudget","value","n","Number","isInteger","Error","validateAtomicOptions","options","retry","isolation","undefined","includes","readOnly","name","signal","aborted","addEventListener","assertPlanRetry","qualifiedTableKey","schemaName","tableName","REQUEST_ALS","Symbol","for","__requestALS","g","globalThis","AsyncLocalStorage","runtime","__runWithRuntime","services","fn","__requestALS","run","runtime","REQUIRED_SERVICES","refuseIncompleteBox","missing","filter","k","undefined","length","Error","join","__getRuntime","scoped","getStore","LIFECYCLE","Symbol","for","declaredLifecycle","g","globalThis","start","shutdown","reason","err","Error","message","String","drain","hooks","h","reverse","run","console","error","name","__runStartHooks","slot","declaredLifecycle","start","splice","shutdown","cause","drained","makeServiceProxy","key","handler","get","_target","prop","receiver","client","__getRuntime","value","Reflect","bind","Proxy","makeTableProxy","ops","prefix","_t","undefined","name","insert","data","aggregate","q","insertMany","rows","opts","update","where","id","set","delete","findById","findUnique","select","with","page","findMany","put","onConflict","updateMany","returning","deleteMany","count","search","params","similar","recommend","facets","supersede","row","claim","unique","extra","rawDatabase","makeTypedSurface","raw","reco","$query","sql","query","$diagnostics","diagnostics","$insert","table","$update","$delete","$findById","$findUnique","$page","$findMany","$put","$updateMany","$deleteMany","$count","$search","$similar","$recommend","$facets","$claim","$lockRows","ids","lockRows","$advisoryXactLock","advisoryXactLock","$aggregate","$insertMany","$supersede","base","Object","assign","$atomic","fn","options","atomic","Error","parent","__requestALS","getStore","runtime","tx","typed","invoke","refuse","ambient","asService","run","Database","$attempt","attempt","$transaction","assertPlanRetry","builder","TxPlanBuilder","runTxPlan","makeTxPlanHandle","$command","txPlan","plan","command","target","startsWith","qualifiedTableKey","makeTxTablesAccessor","tablesProxy","publicTables","$asService","Documents","makeBucketsAccessor","storage","bucket","rawStorage","Storage","buckets","Cache","Secrets","Auth","Log","Notifications","rawFlags","Flags","isEnabled","flagName","context","getVariant","getAll","defaultOrContext","maybeContext","setOverride","Realtime","SQLSTATE","Object","freeze","serializationFailure","deadlockDetected","queryCancelled","commandGuardFailed","isTransactionRollbackState","state","HTTP_ERROR_BRAND","Symbol","for","ENGINE_RAISED","markEngineRaised","e","isEngineRaised","isHttpError","err","status","error","errorDescription","HttpError","Error","data","name","undefined","toJSON","requestId","result","error_description","request_id","NamedHttpError","HttpError","status","defaultCode","name","message","code","data","defaultMessage","spaced","replace","charAt","toUpperCase","slice","toLowerCase","BadRequest","undefined","Conflict","NamedHttpError","message","code","data","UniqueViolation","is","e","name","constraint","isRetryable","retryable","isTransactionRollbackState","sqlstate","SerializationFailure","SQLSTATE","serializationFailure","DeadlockDetected","deadlockDetected","TooManyRequests","undefined","BootRefused","Error","missing","message","name","MANDATORY","key","what","loadConfig","env","filter","m","trim","map","length","detail","includes","padEnd","join","port","Number","PORT","isInteger","poolMax","DB_POOL_MAX","capacityNumber","minimum","maximum","undefined","value","isSafeInteger","queueLimit","queueTimeoutMs","tenantClaim","PALBASE_DB_TENANT_CLAIM","test","databaseUrl","DATABASE_URL","authJwksUrl","AUTH_JWKS_URL","authIssuer","AUTH_ISSUER","moduleBaseUrl","MODULE_BASE_URL","replace","publicOrigin","PALBASE_PUBLIC_ORIGIN","uploadSecret","PALBASE_UPLOAD_SECRET","anonKey","PALBASE_ANON_KEY","serviceRoleKey","PALBASE_SERVICE_ROLE_KEY","cursorSecret","PALBASE_CURSOR_SECRET","enableCommands","PALBASE_DB_COMMANDS","realtimeSecret","REALTIME_INGESTION_SECRET","dbRole","DB_ROLE","dbServiceRole","DB_SERVICE_ROLE","databaseAdmission","PALBASE_DB_DIAGNOSTICS","databaseDiagnostics","onComplete","diagnostics","console","log","JSON","stringify","DECLARATION_REFUSAL","Symbol","for","DeclarationRefused","Error","message","name","isDeclarationRefused","e","b64urlToBytes","s","pad","replace","full","padEnd","Math","ceil","length","bin","atob","out","Uint8Array","ArrayBuffer","i","charCodeAt","AuthVerifier","keys","Map","fetchedAt","inflight","jwksUrl","issuer","fetchImpl","ttl","opts","a","fetch","keysetTtlMs","refresh","res","ok","body","json","next","jwk","kty","crv","set","kid","crypto","subtle","importKey","x","y","ext","name","namedCurve","size","Date","now","key","stale","has","get","verify","authorization","startsWith","parts","slice","trim","split","h","p","sig","undefined","header","claims","JSON","parse","TextDecoder","decode","alg","hash","TextEncoder","encode","exp","iss","effectiveAuth","routeAuth","controllerAuth","spec","required","verifiedEmail","o","role","permission","RateLimiter","buckets","Map","maxKeys","key","routeId","userId","headers","fwd","get","addr","split","trim","check","rule","now","max","window","bucket","resetAt","size","evict","set","count","Math","ceil","dropped","k","b","delete","byReset","entries","sort","a","i","length","victim","makeMemoryCache","opts","maxEntries","now","Date","store","Map","inflight","live","key","e","get","undefined","expiresAt","delete","evict","t","dropped","k","order","entries","sort","a","b","Infinity","i","Math","ceil","length","victim","set","value","ttl","size","has","del","incr","next","getOrSet","fn","hit","running","fill","import_node_async_hooks","memoTable","cache","schema","table","compute","tables","Object","hasOwn","get","Map","set","has","snapshotDeclaration","value","seen","WeakMap","previous","Date","getTime","result","Array","isArray","create","getPrototypeOf","key","Reflect","ownKeys","descriptor","getOwnPropertyDescriptor","defineProperty","freeze","key","invalidPage","message","field","BadRequest","fields","setCursorKey","secret","createHash","update","digest","cursorKey","Error","fingerprint","value","stable","v","$bigint","toString","Date","$date","toISOString","Array","isArray","map","Object","fromEntries","keys","sort","k","JSON","stringify","cursorIdentity","role","claimsJson","claims","parse","iat","exp","nbf","jti","authorization","encodeCursor","scope","values","nonce","randomBytes","cipher","createCipheriv","setAAD","Buffer","from","body","concat","final","token","getAuthTag","length","decodeCursor","count","test","data","slice","createDecipheriv","subarray","setAuthTag","some","pageOrder","columns","primaryKey","opts","raw","backward","last","undefined","before","first","after","size","Number","isInteger","input","orderBy","seen","Set","order","add","o","def","column","hasOwn","has","type","direction","nulls","push","nullable","at","pageBoundary","bind","inclusive","refs","every","greater","join","parts","prefix","i","c","r","nullsLast","cmp","tail","validateInsertManyOptions","opts","returning","undefined","Error","action","onConflict","Array","isArray","some","c","length","uniqueKeysOf","table","columns","inlinePrimary","keys","name","value","Object","entries","col","_def","primaryKey","push","unique","primary","length","unshift","key","seen","Set","filter","size","some","hasOwn","Error","identity","JSON","stringify","sort","has","add","assertUniqueLookup","where","Array","isArray","every","map","join","undefined","Date","installed","WeakSet","hasCommandExecutor","sql","has","COMMAND_EXECUTOR_DDL","installCommandExecutor","roles","quote","s","replace","length","Error","begin","tx","unsafe","list","Set","map","join","add","parameterChunks","chunks","start","i","c","parameter","exec","slice","push","bind","Number","DatabaseAdmission","active","queued","tenants","Map","pending","lastTenant","accepted","rejected","full","timeout","cancelled","limit","options","queueLimit","Math","min","max","concurrency","queueTimeoutMs","Number","isSafeInteger","Error","snapshot","size","rejection","reason","onReject","take","tenant","entered","set","get","released","queueMs","performance","now","release","count","delete","drain","keys","next","value","queue","waiter","values","cleanup","grant","acquire","claimsJson","signal","aborted","claims","JSON","parse","tenantClaim","sub","length","TooManyRequests","retryAfter","Promise","reject","Set","has","remove","error","abort","timer","setTimeout","clearTimeout","removeEventListener","add","addEventListener","once","databases","WeakMap","databaseAdmission","owner","admission","key","TransactionControl","controller","AbortController","active","Set","cancelBackend","cancellation","Promise","resolve","timer","unlink","rejection","deadline","signal","timeoutMs","external","undefined","performance","now","_","reject","addEventListener","reason","size","catch","query","cancel","once","abort","DOMException","removeEventListener","aborted","setTimeout","HttpError","check","throwIfAborted","remainingMs","Math","max","ceil","race","work","bindBackend","drainCancellation","allSettled","watch","add","delete","dispose","clearTimeout","import_node_crypto","DatabaseTrace","start","performance","now","ended","failure","state","options","key","value","undefined","Number","isSafeInteger","Error","endpoint","requestId","outcome","elapsedMs","queries","rows","bytes","queueMs","poolMs","setupMs","sqlMs","commitMs","rollbackMs","connectionMs","commits","commitFailures","rollbackRequests","retries","statements","check","time","started","retry","committed","commitFailed","failed","rolledBack","refuse","kind","HttpError","emit","callback","event","result","Promise","resolve","catch","query","sql","name","run","maxQueries","ordinal","fingerprint","createHash","update","digest","slice","includeSql","durationMs","captureSource","source","stack","split","join","measured","Array","isArray","length","Buffer","byteLength","JSON","stringify","_","toString","maxRows","maxBytes","error","e","errorCode","String","sqlstate","errno","code","frozen","Object","freeze","push","onQuery","snapshot","sort","a","b","complete","onComplete","CODECS","number","fromDb","v","Number","toDb","isSafeInteger","Error","String","tsType","decimal","undefined","forwardName","column","endsWith","slice","describeOrigin","o","direction","table","renameCall","def","owns","target","references","selfRefColumn","undefined","buildRelations","schemas","out","Map","taken","schema","t","Object","values","tables","key","qualifiedTableKey","name","set","claim","tableKey","origin","edge","names","get","held","DeclarationRefused","heldFix","originFix","remedy","push","childKey","has","col","builder","entries","columns","_def","targetKey","refAs","to","kind","via","reverse","reverseAs","quoteIdent","name","replace","quoteTable","key","dot","indexOf","slice","encodePgArray","value","element","x","undefined","Array","isArray","String","map","join","BIND_SQL","atomicScope","AsyncLocalStorage","createLazyTransaction","sql","role","claimsJson","options","lockTimeout","bindSql","bindParams","statementTimeout","push","length","opening","release","fail","settled","closed","assertAccess","Error","control","check","trace","getStore","scope","savepointALS","activeSavepoint","pendingSavepoints","Set","scoped","tx","checkParent","owner","children","access","unsafe","text","params","metadata","run","query","watch","savepoint","fn","token","Symbol","descendants","work","sp","ended","callback","race","size","Promise","allSettled","add","delete","ensure","resolveTx","rejectTx","parked","res","rej","catch","queuedAt","performance","now","lease","admission","databaseAdmission","acquire","signal","time","openingAt","connectedAt","begin","setupAt","isolation","readOnly","validateAtomicOptions","toUpperCase","cancelBackend","ticket","Number","isInteger","pid","started","bindBackend","binding","e","opened","commit","committed","error","commitFailed","rollback","reason","drainCancellation","rolledBack","asWireValue","Date","toISOString","asWireRow","row","out","Object","entries","asWireRows","rows","toVectorLiteral","v","computeVectorColumns","schema","table","def","tableDefOf","col","c","columns","d","_def","type","currentSchema","tables","reviveVectors","vectorCols","JSON","parse","computeTransforms","Map","codec","CODECS","c2","set","fromDb","toDb","t","transform","applyFromDb","transforms","asTableRow","revived","vectorColumnsOf","foldCan","transformsOf","asTableRows","withSpec","partial","result","rel","currentRelations","get","spec","nested","with","selected","select","to","asBindParams","cols","data","caller","assertUsableWriteValues","assertNoExpressionHandles","has","SELECTIVITY_EXACT_THRESHOLD","METRIC_OPERATOR","cosine","euclidean","inner_product","searchConfigFor","defOf","keys","filter","defOfFull","pkCols","primaryKey","pk","includes","search","synonyms","validity","from","model","m","embed","apiKeyName","baseURL","dimensions","metric","ftsOn","ftsColsNew","colSet","ftsCols","legs","column","chunk","fts","rawLegs","vector","leg","l","pickLeg","using","hit","find","HALF_LIFE_UNIT_SECONDS","s","h","parseHalfLife","exec","sec","isFinite","WHERE_OPS","gt","gte","lt","lte","neq","ftsExprOf","sort","expandSynonyms","lower","word","alts","toLowerCase","split","seg","startsWith","tok","test","searchLogger","evt","fields","console","log","stringify","logNoResults","table","query","mode","n","searchLogger","slice","fetchFacets","live","colSet","facets","where","extraWhere","bind","add","v","push","length","whereSql","compileWhere","parts","map","col","replace","quoteIdent","quoteTable","rows","unsafe","join","out","r","f","undefined","value","count","Number","validitySql","p","asOf","excludeSql","pk","ids","x","computePrimaryKey","t","tableDefOf","columns","cols","Object","keys","declared","primaryKey","Array","isArray","only","includes","pkOf","c","rec","def","_def","pks","filter","isSinglePkEquality","assertNotAppendOnly","caller","appendOnly","Error","computeSchemaColumns","Set","timestampResult","expr","columnResult","column","alias","columnTypeOf","projectedColumn","CAN_PREFIX","canMemo","WeakMap","canRoleGate","roles","length","names","flatMap","r","map","replace","join","canEntries","def","alias","policies","dropped","restrictive","p","permissive","command","renderCanUsing","name","entries","filter","q","reason","rGate","push","Buffer","byteLength","CAN_PREFIX","using","gate","parts","CanRenderError","Error","ENGINE_ALIASES","qualifier","tableName","undefined","withoutLiterals","test","includes","depth","ch","tbl","qualified","RegExp","calls","match","wrapped","rendered","canExprSql","selfParenthesized","kind","err","CAN_BINOPS","eq","neq","gt","gte","lt","lte","canLiteral","v","Number","isFinite","String","e","quoteIdent","value","op","left","right","expr","negated","quoteTable","table","predicate","canEntriesOf","byAlias","memoTable","canMemo","currentSchema","Map","hit","get","tableDefOf","warnOnce","msg","has","set","console","warn","hasCanColumn","d","canOuter","cols","canProjection","canJsonPairs","quoteLiteral","foldCan","row","partial","can","key","Object","keys","startsWith","slice","flags","columns","prototype","hasOwnProperty","call","currentRelations","some","rel","rowProjection","wildcard","schemaColumns","base","timestampMemo","c","columnTypeOf","projections","projectionMemo","sql","projectedColumn","rows","colRefSql","known","ref","caller","$col","shapeOK","selectClause","select","col","orderClauseFor","orderBy","items","Array","isArray","o","column","dir","direction","nulls","orderClause","limitClause","limit","isInteger","offsetClause","offset","compileWhereBare","colSet","where","add","transforms","transformsOf","bindFor","t","toDb","assertUsableFilter","isSqlFragment","text","values","$sql","out","i","cond","branches","compiled","b","rels","relName","inner","find","sort","ourCol","theirCol","relationColumns","missing","to","sub","innerSql","bind","isColRef","isNowExpr","lit","pattern","x","WHERE_OPS","isColumnExpr","looksLikeUnbrandedRef","made","how","compileWhere","bare","onConflictTail","conflict","action","target","conflictSet","Set","sets","cachedVectorSchema","cachedTrgmSchema","trgmSchemaOf","live","unsafe","nspname","vectorSchemaWithGuc","runner","secretReader","setSecretReader","fn","embedFetch","url","init","fetch","embedQuery","embed","text","secretReader","Error","apiKeyName","key","url","baseURL","replace","controller","AbortController","timer","setTimeout","abort","res","embedFetch","method","headers","Authorization","body","JSON","stringify","model","input","dimensions","undefined","signal","ok","status","data","json","vec","embedding","Array","isArray","clearTimeout","buildSetAssignments","table","cols","set","add","caller","map","c","expr","columnExprOf","fn","quoteIdent","operator","t","transformsOf","currentSchema","get","amount","toDb","by","asBindParams","join","buildValueTuple","computeColumnType","col","def","tableDefOf","columns","d","_def","type","NUMERIC_PG_TYPES","Set","aggregateExpr","alias","q","columnTypeOf","timestampResult","has","jsonObjectFor","extra","pairs","quoteLiteral","relationColumns","relation","child","kind","to","value","via","column","target","references","primaryKeyOf","withClauses","spec","parentAlias","depth","counter","Object","values","some","Boolean","rels","currentRelations","select","joins","jsonPairs","name","opt","entries","rel","find","r","known","sort","length","ourCol","theirCol","o","i","childAlias","childKnown","schemaColumns","childCols","nestedSpec","nested","nestedJoins","obj","canJsonPairs","innerWhere","compileWhereBare","link","cond","requestedLimit","limitClause","relationLimit","Math","min","inner","orderClauseFor","outAlias","push","quoteTable","compileFindMany","query","opts","params","v","whereSql","compileWhere","order","orderClause","orderBy","limit","offset","offsetClause","selectClause","w","with","keys","selectList","joinSql","sql","uniqueKeysCache","WeakMap","pageSchemaCache","pageSchema","memoTable","create","inlineKeys","nullable","primaryKey","stamp","fingerprint","createOps","tx","context","at","Promise","then","resolveTx","ops","diagnostics","trace","snapshot","bound","p","encodePgArray","asWireRows","unsafe","insert","tuple","rowProjection","rows","inserted","asTableRow","insertMany","validateInsertManyOptions","returning","first","missing","filter","k","includes","tuples","tail","onConflict","onConflictTail","action","out","Number","isSafeInteger","count","advisoryXactLock","lockRows","ids","unique","pk","list","id","claim","keyCols","assertUsableWriteValues","live","savepoint","sp","row","e","isUniqueViolation","where","found","named","constraintOf","put","assertNotAppendOnly","conflict","searchConfigFor","validity","bindData","addPut","ph","insertSql","condSql","condBind","cur","old","second","fresh","placeholders","conflictSet","assignments","update","findById","delete","updateMany","assertHasPredicate","wantRows","simple","isSinglePkEquality","lockedCte","asTableRows","deleteMany","aggregate","check","parts","wants","groups","groupBy","groupSel","columnResult","groupSql","shape","bucket","n","findUnique","uniqueKeysOf","assertUniqueLookup","findMany","compiled","page","secret","cursorKey","schema","size","backward","token","pageOrder","scope","identity","cursorScope","decodeCursor","boundary","pageBoundary","opposite","prefix","names","startsWith","ordinal","other","hidden","cursorCols","nativeOrder","direction","nulls","visible","result","hasOpposite","hasMore","slice","reverse","cursor","encodeCursor","String","pageInfo","startCursor","endCursor","hasNextPage","hasPreviousPage","search","cfg","excl","__excludeIds","facets","validityFor","adder","validitySql","rawLimit","isFinite","max","trunc","pool","minScore","recencyMul","recency","field","halfLife","colSet","parseHalfLife","boostMul","boost","weight","g","scoreMul","chunk","ck","pidQ","bpr","blocksPerRow","wantTextC","mode","fts","qvC","vector","bindC","addC","userWhereC","whereC","excludeSql","parentJoinC","liveC","K2","cpool","semC","kwC","sch","vectorSchemaWithGuc","op","METRIC_OPERATOR","metric","cosine","exactOrderC","probeRows","SELECTIVITY_EXACT_THRESHOLD","vp","toVectorLiteral","qpC","qpCIdx","qTextC","synonyms","expandSynonyms","msC","colListC","projectedColumn","scoreC","assembleC","kwIn","withKwn","kwnCol","fusedSrc","canOuter","rowsC","_kwn","tsch","trgmSchemaOf","trgmKwC","retryBindC","outC","blocks","logNoResults","wantText","ftsCols","anyEmbed","legs","l","vectorAsked","using","leg","pickLeg","qv","wantVector","bind","userWhere","K","semSql","kwSql","exactOrder","qpRef","qpIdx","qText","qp","colList","msP","hlCol","highlight","ftsExprOf","assemble","score","single","base","ms","trgmKw","retryBind","fetchFacets","similar","parse","recommend","positive","negative","x","avgSel","inList","targetSql","r0","pos_missing","neg_missing","supersede","newId","crypto","randomUUID","closed","transaction","cb","withTables","attempt","command","plan","options","txPlan","commands","compileCommand","reason","steps","pipeline","results","settled","allSettled","statement","failed","error","sqlstateOf","SQLSTATE","commandGuardFailed","detail","error_code","isInteger","slot","assign","rows_affected","response","runPlanOp","assertGuard","columnsMemo","primaryMemo","vectorMemo","transformMemo","typeMemo","timestampMemo","projectionMemo","computeSchemaColumns","computePrimaryKey","vectorColumnsOf","computeVectorColumns","computeTransforms","types","Map","setSchema","schemas","tables","entry","mod","default","schemaName","qualifiedTableKey","relations","buildRelations","cname","cd","snapshotDeclaration","freeze","cachedVectorSchema","cachedTrgmSchema","tableNamespaces","namespaces","dot","indexOf","short","isFrozen","surfaces","schemaOf","cached","hasOwn","defineProperty","configurable","enumerable","writable","Reflect","Proxy","receiver","ownKeys","getOwnPropertyDescriptor","preventExtensions","surface","SERVICE_LOCK_TIMEOUT","isAbortedTransaction","message","test","trim","err","isState","code","errno","asText","isForeignKeyViolation","UniqueViolation","is","constraint","exec","isLockTimeout","diagnosingDriver","original","explain","markEngineRaised","state","serializationFailure","SerializationFailure","deadlockDetected","DeadlockDetected","queryCancelled","HttpError","wrapTx","mapped","catch","cancel","reject","admission","databaseAdmission","cancelBackend","begin","createRequestDatabase","DatabaseTrace","requestControl","TransactionControl","requestClosed","authorized","applicationTouched","authorizationRelease","contextFor","role","cursorIdentity","claimsJson","hasCommandExecutor","userContext","serviceContext","serviceRole","atomic","validateAtomicOptions","atomicScope","getStore","opened","commit","requestTransaction","retries","retryBudget","retry","atomicSignal","AbortSignal","any","control","timeoutMs","timeouts","statementTimeoutMs","remainingMs","Symbol","root","createLazyTransaction","isolation","readOnly","lockTimeout","lockTimeoutMs","statementTimeout","callback","run","race","rollback","isRetryable","delay","resolve","dispose","serviceTx","serviceControl","serviceClient","asService","client","authorizationComplete","complete","Args","isRef","isPlanRef","refUnresolvedMessage","ref","refuseUnbrandedRef","looksLikeUnbrandedPlanRef","isExpr","renderValue","args","vectorCols","transforms","source","$ref","bindMaybeVector","$expr","resolveRefsDeep","isColRef","isSqlFragment","Date","renderWhere","planWhere","resolved","bare","from","compilePlanOp","opVectorCols","opTransforms","rendered","conflictCols","knownSet","planned","planPk","lock","symbols","hasRefs","containsFragment","hasNullableFilterRef","index","empty","guard","wide","exact","bindings","toString","toISOString","step","chunks","parameterChunks","withQueryCancellation","application","control","Error","close","driver","d","end","unsafe","sql","params","begin","fn","cancelBackend","pid","startedAt","ROUTES","Symbol","for","RETURN_BUFFER","Symbol","for","THROWS_BUFFER","carrierOf","target","ctor","getRoutes","ctor","carrier","carrierOf","routes","ROUTES","returnBuffer","RETURN_BUFFER","route","buffered","fnName","returnSchema","undefined","throwsBuffer","THROWS_BUFFER","throws","map","r","params","slice","APP_DEFAULT_AUTH","Symbol","for","appAuthSlot","globalThis","getDefaultAuth","appAuthSlot","APP_DEFAULT_AUTH","resolveEffectiveAuth","routeAuth","controllerAuth","getDefaultAuth","ROOM_META","Symbol","for","CONTROLLER_META","toSegments","path","split","filter","Boolean","map","s","startsWith","endsWith","slice","buildRouteTable","controllers","container","table","Ctrl","undefined","ctor","meta","basePath","routes","getRoutes","length","name","Error","instance","get","r","full","subpath","push","method","segments","id","controllerAuth","resolveEffectiveAuth","defaultAuth","matchRoute","pathname","parts","entry","params","ok","i","seg","got","charCodeAt","decodeURIComponent","HEADER_DEVICE_ID","HEADER_PAYLOAD","HEADER_SIGNATURE","HEADER_CHALLENGE","HEADER_CAPABLE","HEADER_INSTALLATION","HEADER_ANCHOR","DEFAULT_POLICY_TTL_MS","DEFAULT_REQUEST_TIMEOUT_MS","bodyDigest","body","byteLength","bytes","Uint8Array","ArrayBuffer","set","buf","crypto","subtle","digest","btoa","String","fromCharCode","readCapable","req","v","headers","get","createAttestGate","deps","doFetch","fetchImpl","fetch","ttl","policyTtlMs","policyTimeoutMs","requestTimeoutMs","cachedMode","cachedAt","mode","Date","now","res","moduleBaseUrl","apikey","serviceRoleKey","signal","AbortSignal","timeout","ok","Error","status","json","gate","_ctx","m","outcome","reason","device","observation","nextChallenge","deviceId","payload","signature","hasEvidence","capable","attested","installationId","url","URL","verdict","method","JSON","stringify","installation_id","device_id","challenge","path","pathname","search","body_sha256","next_challenge","authDeviceId","platform","assurance","createObservationSink","maxBatch","intervalMs","buffer","inFlight","Promise","resolve","timer","setInterval","flush","unref","bucketsOf","batch","counts","incapable","unknown","no_sdk","o","length","record","push","stop","clearInterval","AUTHORIZE_PATH","SIGNATURE_HEADER","renderPath","template","tokens","replaceAll","sanitizeSegment","userId","uploadId","filename","raw","cleaned","replace","trim","slice","grantFor","entry","ctx","bucketLimits","cfg","meta","options","uploadConfig","bucket","path","pathTemplate","maxBytes","mimeTypes","ownerUid","CompletionLedger","seen","Map","capacity","recall","get","remember","response","delete","set","size","oldest","keys","next","done","value","verifySignature","presented","expected","length","diff","i","charCodeAt","SSE_CONTENT_TYPE","encodeFrame","value","JSON","stringify","encodeErrorFrame","requestId","makeSseWriter","opts","begun","chain","Promise","resolve","write","frame","then","onFirstWrite","enqueue","catch","undefined","started","drained","DI_INJECTABLES","Symbol","for","INJECTABLE","isInjectable","c","slot","g","globalThis","__claimInjectables","slot","splice","JOB","Symbol","for","WEBHOOK","HOOK_BLOCKING","HOOK_LISTENERS","ROOM","CONTROLLER","has","c","s","undefined","isEntryPointClass","DI_MODULES","Symbol","for","slot","g","globalThis","__claimModules","slot","splice","DiError","Error","DECLARATION_REFUSAL","kind","path","at","detail","fixes","length","join","map","f","name","nameOf","c","String","UNRESOLVABLE","Set","Object","Function","Number","Boolean","Array","Symbol","Promise","Date","undefined","DATA","declaresDependencies","ctor","arity","meta","Reflect","getMetadata","buildContainer","entries","__claimModules","declared","__claimInjectables","declaredModules","e","mod","owner","Map","def","m","providers","controllers","prev","get","set","p","isInjectable","isEntryPointClass","orphans","filter","has","names","exported","importsOf","exports","holder","i","imports","deps","implementorsOf","t","keys","prototype","isPrototypeOf","call","withArity","missingMeta","cls","list","forEach","dep","dm","impls","impl","push","sort","state","stack","walk","cyc","slice","indexOf","d","pop","cache","make","hit","args","inst","owned","pressure","computePressure","total","count","n","module","pct","Math","round","of","a","b","assertNoOrphanEntryPoints","registered","SECRET_ENV","scrubSecrets","env","removed","kept","name","undefined","push","Object","keys","startsWith","hostAllowed","host","allow","h","toLowerCase","raw","pattern","trim","endsWith","slice","length","installEgressFence","policy","original","globalThis","fetch","bind","declared","platform","alwaysAllow","map","filter","Boolean","whenUndeclared","fenced","input","init","url","URL","includes","hostname","Error","timeoutMs","controller","AbortController","timer","setTimeout","abort","signal","clearTimeout","MAX_BODY_BYTES","JSON_HEADERS","fieldErrors","err","issues","map","i","field","path","join","message","headersFor","raw","schema","shape","aliased","declared","Object","keys","lower","toLowerCase","value","undefined","envelope","error","description","status","requestId","extra","Response","JSON","stringify","error_description","request_id","headers","unavailable","name","Error","stubModule","Proxy","get","apply","defaultSqlDriver","config","g","globalThis","Bun","SQL","BootRefused","withQueryCancellation","url","databaseUrl","max","poolMax","AUTHOR_ANSWERED","Set","refuseUnlessAuthorized","client","spec","rolesOfCaller","permission","row","query","ok","required","role","held","includes","required_role","makeRoleResolver","pending","then","rows","r","createApp","opts","controllers","container","buildContainer","released","liveContainer","t","owned","pressure","assertNoOrphanEntryPoints","routes","buildRouteTable","length","DeclarationRefused","sql","admission","databaseAdmission","concurrency","inFlight","shuttingDown","accepting","serving","run","work","add","delete","unsafe","setSchema","schemas","setCursorKey","cursorSecret","serviceRoleKey","enableCommands","installCommandExecutor","dbRole","dbServiceRole","setSecretReader","secretReader","auth","AuthVerifier","jwksUrl","authJwksUrl","issuer","authIssuer","attestGate","createAttestGate","moduleBaseUrl","observations","createObservationSink","limiter","RateLimiter","cache","makeMemoryCache","log","logger","console","modules","runWithRuntime","runtimeHooks","__runWithRuntime","requestALS","__requestALS","uploadSecret","completions","CompletionLedger","buildServices","db","Database","Cache","Log","Auth","Documents","Storage","Notifications","Flags","Realtime","Secrets","runInServiceScope","fn","createRequestDatabase","serviceRole","claimsJson","databaseDiagnostics","endpoint","out","commit","rollback","errorResponse","isHttpError","isEngineRaised","has","errorDescription","data","handleAuthorize","req","verifySignature","SIGNATURE_HEADER","body","json","catch","uploadId","target","matchRoute","method","effectiveAuth","entry","meta","options","controllerAuth","callerClaims","verify","uploadDb","signal","refusal","grant","grantFor","userId","sub","filename","handle","crypto","randomUUID","URL","pathname","AUTHORIZE_PATH","hit","attestedDevice","attestChallengeOut","claims","databaseBudget","id","dispatched","settleBeforeRefusal","verifiedEmail","email_verified","parsedBody","bodyRead","rawBody","Number","isFinite","buf","arrayBuffer","byteLength","Uint8Array","readParsedBody","parse","TextDecoder","decode","attest","observation","record","outcome","nextChallenge","reason","device","retryAfter","check","rateLimit","key","Date","now","String","completionUploadId","args","sseEnqueue","sseSettle","sseWriter","makeSseWriter","enqueue","chunk","onFirstWrite","p","params","kind","safeParse","success","fields","index","fromEntries","searchParams","email","emailVerified","metadata","roles","envelopeIn","uploadedObject","already","recall","contentType","sdkVersion","appVersion","platform","osVersion","authorizationComplete","services","sseConfig","sseController","sseEncoder","TextEncoder","stream","ReadableStream","start","c","encode","sawFirstFrame","refuseFirstFrame","firstFrame","Promise","resolve","reject","guarded","prop","recv","started","Reflect","thrown","ran","box","getStore","idempotencyKey","instance","fnName","race","drained","encodeErrorFrame","close","SSE_CONTENT_TYPE","result","returnSchema","v","remember","payload","bootServices","runShutdownHooks","__runStartHooks","closeDriver","databasePressure","snapshot","shutdown","size","allSettled","closable","end"]}
1
+ {"version":3,"sources":["../../src/engine/index.ts","../../src/runtime.ts","../../src/db/input-guards.ts","../../src/db/tx-plan.ts","../../src/db/transaction-options.ts","../../src/db/schema-json.ts","../../src/db/sqlstate.ts","../../src/errors.ts","../../src/engine/config.ts","../../src/refusals.ts","../../src/engine/auth.ts","../../src/engine/ratelimit.ts","../../src/engine/cache.ts","../../src/engine/db.ts","../../src/engine/schema-cache.ts","../../src/engine/cursor.ts","../../src/db/bulk.ts","../../src/db/unique.ts","../../src/engine/commands.ts","../../src/engine/admission.ts","../../src/engine/transaction-control.ts","../../src/engine/diagnostics.ts","../../src/db/columns.ts","../../src/db/env-gen.ts","../../src/engine/cancellation.ts","../../src/decorators/registry.ts","../../src/decorators/controller.ts","../../src/engine/router.ts","../../src/engine/attest.ts","../../src/engine/upload.ts","../../src/engine/sse.ts","../../src/container.ts","../../src/decorators/injectable.ts","../../src/decorators/kinds.ts","../../src/decorators/module.ts","../../src/engine/fence.ts"],"sourcesContent":["/**\n * engine/index.ts — the engine: a backend that boots itself.\n *\n * `createApp` turns a set of `@Controller` classes into a `fetch(Request)`\n * handler. No V8 isolate, no capability hop: this process owns its database\n * pool, verifies its own tokens, applies its own rate limits, and calls the\n * modules directly.\n *\n * import { createApp, loadConfig } from \"@palbase/backend/engine\";\n *\n * const app = await createApp({\n * config: loadConfig(process.env),\n * controllers: [TodosController],\n * schema,\n * });\n * Bun.serve({ port: app.config.port, fetch: app.handle });\n *\n * The Web-standard `fetch` signature is the point: the same handler runs under\n * Bun, Deno and any host that speaks Request/Response, so \"works locally\" and\n * \"works in the cloud\" are the same code path rather than two.\n */\nimport type { ZodError, ZodTypeAny } from \"zod\";\n\nimport { __runWithRuntime, __requestALS, __runStartHooks } from \"../runtime.js\";\nimport type { RuntimeServices, ShutdownRunner } from \"../runtime.js\";\nimport { isHttpError, isEngineRaised } from \"../errors.js\";\nimport type { CacheClient, ClientInfo } from \"../endpoint.js\";\n\nimport { loadConfig, BootRefused } from \"./config.js\";\nimport { DeclarationRefused, isDeclarationRefused, DECLARATION_REFUSAL } from \"../refusals.js\";\nimport type { EngineConfig } from \"./config.js\";\nimport { AuthVerifier, effectiveAuth } from \"./auth.js\";\nimport type { VerifiedDevice } from \"../types.js\";\nimport type { EffectiveAuth, VerifiedClaims } from \"./auth.js\";\nimport { RateLimiter } from \"./ratelimit.js\";\nimport { makeMemoryCache } from \"./cache.js\";\nimport { createRequestDatabase, setSchema, setSecretReader } from \"./db.js\";\nimport { setCursorKey } from \"./cursor.js\";\nimport { installCommandExecutor } from \"./commands.js\";\nimport { withQueryCancellation } from \"./cancellation.js\";\nimport { databaseAdmission } from \"./admission.js\";\nimport type { SqlDriver } from \"./db.js\";\nimport { buildRouteTable, matchRoute } from \"./router.js\";\nimport { createAttestGate, createObservationSink } from \"./attest.js\";\nimport {\n AUTHORIZE_PATH,\n SIGNATURE_HEADER,\n grantFor,\n verifySignature,\n CompletionLedger,\n type CompletionEnvelope,\n} from \"./upload.js\";\nimport {\n SSE_CONTENT_TYPE,\n encodeErrorFrame,\n makeSseWriter,\n type EngineSseWriter,\n} from \"./sse.js\";\nimport type { RouteEntry } from \"./router.js\";\nimport { assertNoOrphanEntryPoints, buildContainer, type Container } from \"../container.js\";\n\nexport { loadConfig, BootRefused } from \"./config.js\";\nexport { DeclarationRefused, isDeclarationRefused, DECLARATION_REFUSAL } from \"../refusals.js\";\nexport type { EngineConfig } from \"./config.js\";\nexport { AuthVerifier, effectiveAuth } from \"./auth.js\";\nexport { RateLimiter } from \"./ratelimit.js\";\nexport { makeMemoryCache } from \"./cache.js\";\nexport { createLazyTransaction, createOps, withTables, createRequestDatabase, quoteIdent } from \"./db.js\";\nexport type { SqlDriver, SqlTx, RequestDatabase } from \"./db.js\";\nexport { setCursorKey } from \"./cursor.js\";\nexport { installCommandExecutor, COMMAND_EXECUTOR_DDL } from \"./commands.js\";\nexport { withQueryCancellation } from \"./cancellation.js\";\nexport { buildRouteTable, matchRoute } from \"./router.js\";\nexport type { RouteEntry } from \"./router.js\";\nexport { scrubSecrets, installEgressFence, hostAllowed } from \"./fence.js\";\nexport type { EgressPolicy, ScrubResult } from \"./fence.js\";\n\n/** The `__`-prefixed request-scope seam, as re-exported by a deployed bundle. */\nexport interface RuntimeHooks {\n __runWithRuntime: typeof __runWithRuntime;\n __requestALS: typeof __requestALS;\n}\n\n/** The module singletons the engine injects, minus the two it owns itself. */\nexport type ModuleClients = Partial<\n Pick<\n RuntimeServices,\n \"Auth\" | \"Documents\" | \"Storage\" | \"Notifications\" | \"Flags\" | \"Realtime\" | \"Secrets\"\n >\n>;\n\nexport interface CreateAppOptions {\n /**\n * Vault'tan TEK secret okuma (FR-025): sorgu-anı embedding'in anahtarı\n * buradan akar. Verilmezse auto-embed'li search({query}) adlandırılmış\n * hatayla düşer — sessiz boş sonuç asla (FR-015).\n */\n secretReader?: (name: string) => Promise<string | null>;\n config: EngineConfig;\n /** `@Controller` classes. A class that collected zero routes is fatal. */\n controllers: readonly unknown[];\n /** The project's `defineSchema()` result, for the typed `.tables` surface. */\n schemas?: readonly unknown[];\n /** The SQL driver. Omitted ⇒ built from `Bun.sql` when running under Bun. */\n sql?: SqlDriver;\n /** Module clients. Omitted ⇒ each corresponding singleton throws when used. */\n modules?: ModuleClients;\n /** Cache. Omitted ⇒ this process's own memory. */\n cache?: CacheClient;\n /**\n * The request-scope hooks to run handlers inside.\n *\n * MUST come from the SAME `@palbase/backend` module instance the loaded\n * controllers were bundled against. A deployed bundle inlines its own copy of\n * the SDK and re-exports these two; the engine here has its own. Two copies\n * mean two AsyncLocalStorage instances, and the store this engine sets is not\n * the store the handler's `Database` proxy reads — every service would be\n * undefined at the first call, with nothing in the logs to say why. So the\n * host passes the BUNDLE's hooks and the seam closes.\n *\n * Omitted ⇒ this module's own, which is correct only when the controllers\n * were built against this same instance (tests, a single-package project).\n */\n runtimeHooks?: RuntimeHooks;\n logger?: Pick<Console, \"info\" | \"warn\" | \"error\" | \"debug\">;\n}\n\nexport interface App {\n /** Core/operator observation of the shared physical pool's admission queue. */\n readonly databasePressure?: ReturnType<typeof databaseAdmission>[\"snapshot\"];\n handle: (req: Request) => Promise<Response>;\n routes: readonly RouteEntry[];\n config: EngineConfig;\n /**\n * Run work that has no request behind it — a scheduled job — inside the same\n * request scope a handler gets, with its own transaction.\n */\n runInServiceScope: <T>(fn: () => T | Promise<T>) => Promise<T>;\n /** Close the pool and release resources. */\n shutdown: () => Promise<void>;\n /**\n * The container this app resolved its classes from.\n *\n * Exposed because entry points the ENGINE does not own are built elsewhere:\n * the runtime constructs rooms, jobs and hooks, and they must come from THIS\n * app's graph rather than a second one built beside it (FR-037, FR-042).\n */\n readonly container: Container;\n}\n\n/** Ceiling on a buffered request body.\n *\n * Ten megabytes: comfortably above any JSON payload a controller takes, and\n * far below what a handful of concurrent requests could use to exhaust a\n * runtime. It exists because the App Attest gate needs the bytes, so the body\n * is now read before the rate limiter — earlier than the limiter that used to\n * bound how many could arrive at once. */\nconst MAX_BODY_BYTES = 10 * 1024 * 1024;\n\nconst JSON_HEADERS = { \"content-type\": \"application/json\" } as const;\n\n/** Flatten a zod failure into the `{ field, message }[]` the SDK's own\n * `BadRequest` payload declares — one shape for the engine's automatic\n * refusals and for `throw new BadRequest({ fields })` alike. */\nfunction fieldErrors(err: ZodError): Array<{ field: string; message: string }> {\n return err.issues.map((i) => ({ field: i.path.join(\".\"), message: i.message }));\n}\n\n/** Re-key the header map onto the names an `@Headers` schema declares.\n *\n * HTTP HEADER NAMES ARE CASE-INSENSITIVE (RFC 9110 §5.1); a zod key is a\n * literal. `Headers` iteration lowercases, so `Object.fromEntries(req.headers)`\n * only ever carries `x-tenant` — while the deploy gate lowercases a declared\n * name only for its RESERVED check (`extract_meta.js` validateHeadersSchema),\n * so `z.object({ \"X-Tenant\": … })` ships. That is also the spelling every HTTP\n * document uses and the one the iOS/Android generators emit into the generated\n * call's signature, so the caller really does send it.\n *\n * Comparing case-sensitively would answer 400 on a header the caller DID send,\n * on every request, forever — the schema was inert before it was enforced, so\n * the refusal would arrive with the SDK upgrade and name a header the client\n * can see itself sending. The lowercase twin stays in the map (zod strips\n * unknown keys), so the parsed value carries exactly the declared spelling.\n */\nfunction headersFor(raw: Record<string, string>, schema: ZodTypeAny): Record<string, string> {\n const shape = (schema as { shape?: Record<string, unknown> }).shape;\n if (typeof shape !== \"object\" || shape === null) return raw;\n let aliased: Record<string, string> | null = null;\n for (const declared of Object.keys(shape)) {\n const lower = declared.toLowerCase();\n if (lower === declared) continue;\n const value = raw[lower];\n if (value === undefined) continue;\n aliased ??= { ...raw };\n aliased[declared] = value;\n }\n return aliased ?? raw;\n}\n\nfunction envelope(\n error: string,\n description: string,\n status: number,\n requestId: string,\n extra?: Record<string, unknown>,\n): Response {\n return new Response(\n JSON.stringify({ error, error_description: description, status, request_id: requestId, ...extra }),\n { status, headers: JSON_HEADERS },\n );\n}\n\n/** A module that was never configured must say so by name on first use, not\n * fail with \"Cannot read properties of undefined\". */\n/**\n * A module singleton nobody injected.\n *\n * The message names TWO causes because there are two, and pointing at only one\n * sends an operator to check a setting that is already correct. Measured on\n * 2026-08-15: a handler reaching for `Purchases` was told to set\n * MODULE_BASE_URL — which was set. Purchases is simply not part of this\n * backend, and an error that hides that costs the reader the afternoon.\n */\nfunction unavailable(name: string): never {\n throw new Error(\n `${name} is unavailable. Either this backend was started without module clients ` +\n `(set MODULE_BASE_URL and the API keys so the engine can reach the module surface), ` +\n `or ${name} is not one of the modules this backend provides.`,\n );\n}\n\nfunction stubModule(name: string): unknown {\n return new Proxy(\n {},\n {\n get: () => unavailable(name),\n apply: () => unavailable(name),\n },\n );\n}\n\nasync function defaultSqlDriver(config: EngineConfig): Promise<SqlDriver> {\n const g = globalThis as { Bun?: { SQL: new (o: { url: string; max: number }) => SqlDriver } };\n if (!g.Bun?.SQL) {\n throw new BootRefused(\n [],\n \"boot refused: no SQL driver. Running outside Bun means the driver must be supplied — \" +\n \"pass `sql` to createApp().\",\n );\n }\n return withQueryCancellation(new g.Bun.SQL({ url: config.databaseUrl, max: config.poolMax }),\n new g.Bun.SQL({ url: config.databaseUrl, max: 2 }));\n}\n\n/** The statuses an author THROWS to answer a request. Everything else that\n * reaches the catch is unplanned and gets logged — see the branch that reads\n * this. Kept beside nothing else so there is one list, not a condition spread\n * across two files.\n *\n * 409 IS IN THIS LIST, and the reason is the whole shape of the check. The\n * scaffold teaches `throw new Conflict(\"title already taken\")` as the way to\n * answer with a 409 (template/AGENTS.md), and the engine raises\n * `UniqueViolation` — also a 409 — from a duplicate write. The status cannot\n * tell them apart, so intent is read from ORIGIN instead: the engine MARKS what\n * it built (`markEngineRaised`), and the branch below logs on that mark\n * regardless of status. Splitting on the status alone wrote an \"unhandled\" line\n * every time an author took the documented path — measured. */\nconst AUTHOR_ANSWERED: ReadonlySet<number> = new Set([400, 401, 403, 404, 409, 429]);\n\n/**\n * Build the app. Fails fast: the database is reached here, at boot, rather than\n * on the first request that needs it.\n */\n\n/**\n * Refuse a caller the route's declared role/permission does not cover.\n *\n * Authority is read from `auth.user_roles` through the two SECURITY DEFINER\n * helpers, inside the transaction the handler is going to use anyway — never\n * off a JWT claim. That is what makes a revoked role take effect on the very\n * next request rather than whenever the token expires.\n *\n * It lives here, called from BOTH gates, because the alternative is two copies\n * of an authorization rule: the request path and storage's upload-authorize\n * path read the SAME `auth: { … }` declaration, and a decorator that means one\n * thing on one path and another thing on the other is a trap nobody reads twice.\n *\n * Returns the refusal to send, or null when the caller may proceed.\n */\nasync function refuseUnlessAuthorized(\n client: AuthorityClient,\n spec: EffectiveAuth,\n requestId: string,\n rolesOfCaller: () => Promise<string[]>,\n): Promise<Response | null> {\n if (spec.permission !== undefined) {\n const [row] = await client.query<{ ok: boolean }>(\n \"select auth.has_permission($1) as ok\",\n [spec.permission],\n );\n if (row?.ok !== true) {\n return envelope(\n \"forbidden\",\n `This endpoint requires the \"${spec.permission}\" permission`,\n 403,\n requestId,\n // FR-008 / D-7: reddin ÇARESİ gövdede — istemci `required`'ı görünce ilgili\n // nesneyi yeniden çeker (Entra CAE deseni); cümle değişmez.\n { required: spec.permission },\n );\n }\n }\n if (spec.role !== undefined) {\n const held = await rolesOfCaller();\n if (!held.includes(spec.role)) {\n return envelope(\"forbidden\", `This endpoint requires the \"${spec.role}\" role`, 403, requestId, {\n required_role: spec.role,\n });\n }\n }\n return null;\n}\n\n/** What both gates and the `@User()` branch need out of a request database. */\ntype AuthorityClient = { query<T = unknown>(sql: string, params?: unknown[]): Promise<T[]> };\n\n/**\n * The caller's application roles, resolved ONCE per request.\n *\n * The gate asks \"does this caller hold R\" and `@User()` asks \"what does this\n * caller hold\" — two questions with one answer, and asking twice would cost a\n * second round trip AND let the gate admit on one snapshot while the handler\n * reads another. So the LIST is what gets fetched, memoised on the promise so\n * two concurrent readers share the one query, and the gate's membership test\n * becomes an `includes` on it.\n *\n * `auth.app_roles()` returns `text[]` (sorted, `{}` when empty) and is unnested\n * here rather than parsed as an array: a row per role is what every driver in\n * front of this agrees on without a codec.\n *\n * Nothing runs until somebody asks. A route that declares no role and never\n * injects a user opens no transaction at all — the request database is lazy and\n * this is the only thing that would have touched it.\n */\nfunction makeRoleResolver(client: AuthorityClient): () => Promise<string[]> {\n let pending: Promise<string[]> | null = null;\n return () => {\n pending ??= client\n .query<{ role: string }>(\"select unnest(auth.app_roles()) as role\")\n .then((rows) => rows.map((r) => r.role));\n return pending;\n };\n}\n\nexport async function createApp(opts: CreateAppOptions): Promise<App> {\n const { config, controllers } = opts;\n\n // NOTHING PROCESS-WIDE IS WRITTEN UNTIL THIS APP IS GOING TO EXIST.\n //\n // `setSchema` and `setSecretReader` used to be the first two lines, and they\n // write MODULE state that the whole process shares. A candidate bundle is\n // built beside the live app in the same process, so a candidate that was then\n // REFUSED — for any reason, and this file has several — had already replaced\n // the serving release's schema and never put it back.\n //\n // Measured 2026-09-02:\n // live app → schema [\"notes\"]\n // candidate refused → \"Kind: unowned class\"\n // live app now → schema [\"candidate_only\"]\n //\n // Every request the still-serving release went on answering would resolve its\n // tables against a schema that no longer had them. The fix is ordering, not a\n // second mechanism: VALIDATE FIRST, take over the process afterwards. The\n // writes now sit below the last thing that can refuse.\n\n // The container is built HERE and lives exactly as long as this app.\n //\n // `buildContainer` CLAIMS the module declarations rather than reading them, so\n // a candidate bundle loaded beside a live app builds from its OWN modules and\n // leaves nothing behind if it is discarded. Keeping the graph on globalThis\n // instead would be the same defect one layer up.\n const container = buildContainer();\n // Set by `shutdown`; read by the guard below so a resolve after shutdown says\n // WHY rather than handing back an instance whose pool is closed.\n let released = false;\n const liveContainer: Container = {\n get<T>(t: never): T {\n if (released) {\n throw new Error(\n \"this app has shut down — its container no longer resolves. \" +\n \"A class resolved here would hold a closed database pool.\",\n );\n }\n return container.get(t) as T;\n },\n owned: container.owned,\n pressure: container.pressure,\n };\n\n // Nothing that decorated itself may be served unless a module claimed it.\n // Before this, a @Controller in no module still reached the route table and\n // the OpenAPI document — it worked, and that was the problem.\n assertNoOrphanEntryPoints(controllers, container.owned);\n\n const routes = buildRouteTable(controllers, liveContainer);\n if (routes.length === 0) {\n // A DECLARATION FACT, and it used to be filed under `BootRefused` beside\n // \"no DATABASE_URL\" — two refusals with opposite cures under one name. This\n // one is cured by a push and nothing else, so the runtime must be able to\n // wait on it instead of taking the pod (and palsvc) down.\n throw new DeclarationRefused(\"boot refused: zero endpoints collected — nothing would answer.\");\n }\n\n const sql = opts.sql ?? (await defaultSqlDriver(config));\n const admission = sql.admission ?? databaseAdmission(sql, { concurrency: config.poolMax, ...config.databaseAdmission });\n const inFlight = new Set<Promise<unknown>>();\n let shuttingDown: Promise<void> | undefined;\n let accepting = true;\n async function serving<T>(run: () => Promise<T>): Promise<T> {\n const work = run();\n inFlight.add(work);\n try { return await work; } finally { inFlight.delete(work); }\n }\n await sql.unsafe(\"select 1\");\n\n // Past every refusal above — including the database being unreachable, which\n // is the last thing that stops a boot. This app IS going to exist, so the\n // process-wide state is now its to hold. See the note at the top of this\n // function. Neither line above needs the schema: one builds a driver from\n // config, the other sends a literal.\n setSchema(opts.schemas ?? []);\n setCursorKey(config.cursorSecret || config.serviceRoleKey || null);\n if (config.enableCommands) await installCommandExecutor(sql, [config.dbRole, config.dbServiceRole]);\n setSecretReader(opts.secretReader ?? null);\n\n const auth = new AuthVerifier({ jwksUrl: config.authJwksUrl, issuer: config.authIssuer });\n\n // The App Attest gate and its counter, built once at boot.\n //\n // Both talk to palauth over the SAME internal base url the module clients\n // use, with the service-role key — these endpoints are the seam between two\n // processes in one pod, not a client surface.\n //\n // The gate resolves the mode itself on a 30-second cache, which is what lets\n // an operator flip the flag in Studio and see it take effect without a\n // redeploy. Unreachable palauth ⇒ \"off\", because a gate that cannot reach its\n // policy must not take the tenant's traffic down with it.\n const attestGate = createAttestGate({\n moduleBaseUrl: config.moduleBaseUrl,\n serviceRoleKey: config.serviceRoleKey,\n });\n const observations = createObservationSink({\n moduleBaseUrl: config.moduleBaseUrl,\n serviceRoleKey: config.serviceRoleKey,\n });\n const limiter = new RateLimiter();\n const cache = opts.cache ?? makeMemoryCache();\n const log = opts.logger ?? console;\n const modules = opts.modules ?? {};\n const runWithRuntime = opts.runtimeHooks?.__runWithRuntime ?? __runWithRuntime;\n const requestALS = opts.runtimeHooks?.__requestALS ?? __requestALS;\n\n // The secret storage signs its internal calls with. Absent means uploads are\n // not wired, and authorize REFUSES rather than answering with a grant anybody\n // could have asked for.\n const uploadSecret = config.uploadSecret ?? \"\";\n\n /**\n * Answer \"which bucket and path does this route write to?\".\n *\n * Storage cannot know: the answer is `@Upload({bucket, pathTemplate})`, which\n * lives in the deployed bundle. Asking the process that HAS the routes is\n * what keeps the client from naming its own bucket — the request carries the\n * route it wants to use, and this decides what that means.\n */\n // One ledger per app: a completion retried against this process must find\n // its own first answer, and a process restart legitimately forgets — the\n // window a retry lives in is far shorter than an uptime.\n const completions = new CompletionLedger();\n\n /**\n * The service bundle a scope binds, built around ONE request-scoped database.\n *\n * Extracted so the request path and the job path cannot drift: a second copy\n * of this object is a second definition of what a handler can reach, and the\n * one that goes stale is always the one nobody is looking at.\n */\n /** `db === null` is the BOOT scope: everything else is available, and\n * `Database` refuses by name because a start hook runs before any request and\n * there is no transaction for a query to belong to. One writer, so the boot\n * scope cannot drift from the request one. */\n function buildServices(db: ReturnType<typeof createRequestDatabase> | null): RuntimeServices {\n return {\n Database:\n db?.client ??\n stubModule(\"Database (a start hook runs before any request — open your own connection here)\"),\n Cache: cache,\n Log: log,\n Auth: modules.Auth ?? stubModule(\"Auth\"),\n Documents: modules.Documents ?? stubModule(\"Documents\"),\n Storage: modules.Storage ?? stubModule(\"Storage\"),\n Notifications: modules.Notifications ?? stubModule(\"Notifications\"),\n Flags: modules.Flags ?? stubModule(\"Flags\"),\n Realtime: modules.Realtime ?? stubModule(\"Realtime\"),\n // Named, never undefined. A backend started without a secrets client\n // that returned `undefined` here would fail inside the handler as\n // \"Cannot read properties of undefined\", which says nothing about what\n // to configure — the stub says the name and the variable.\n Secrets: modules.Secrets ?? stubModule(\"Secrets\"),\n } as unknown as RuntimeServices;\n }\n\n /**\n * Run `fn` as the system, with no request behind it.\n *\n * Scheduled jobs need exactly what a handler needs — Database, Log,\n * Notifications, resolved out of the request scope — but there is no request\n * to take an identity from. So the claims are EMPTY: a job is nobody, and\n * `Database` here satisfies no owner-scoped RLS policy. That is why a job\n * reaches for `Database.$asService()`, and why this does not quietly hand it\n * service_role by default.\n *\n * The transaction settles the same way a request's does: commit on return,\n * rollback on throw. A job that fails halfway leaves nothing behind that the\n * next run has to reason about.\n */\n async function runInServiceScope<T>(fn: () => T | Promise<T>): Promise<T> {\n const db = createRequestDatabase(sql, {\n role: config.dbRole,\n serviceRole: config.dbServiceRole,\n claimsJson: \"{}\",\n }, config.databaseDiagnostics === undefined ? undefined : { ...config.databaseDiagnostics, endpoint: \"scheduled job\" });\n try {\n const out = await runWithRuntime(buildServices(db), fn as () => Promise<T>);\n await db.commit();\n return out;\n } catch (err) {\n await db.rollback(err);\n throw err;\n }\n }\n\n function errorResponse(err: unknown, endpoint: string, requestId: string): Response {\n // The same branded envelope applies before dispatch, in a handler and in\n // storage authorization. A queue rejection must never escape as Bun's 500.\n if (isHttpError(err)) {\n if (isEngineRaised(err) || !AUTHOR_ANSWERED.has(err.status)) {\n log.error(`[engine] unhandled ${err.error} in ${endpoint}`, err);\n }\n return envelope(err.error, err.errorDescription, err.status, requestId,\n err.data !== undefined ? { data: err.data } : undefined);\n }\n log.error(`[engine] unhandled error in ${endpoint}`, err);\n return envelope(\"internal_error\", \"The request could not be completed\", 500, requestId);\n }\n\n async function handleAuthorize(req: Request, requestId: string): Promise<Response> {\n if (uploadSecret === \"\" ||\n !verifySignature(req.headers.get(SIGNATURE_HEADER) ?? \"\", uploadSecret)) {\n return envelope(\"unauthorized\", \"This endpoint is not callable directly\", 401, requestId);\n }\n const body = (await req.json().catch(() => null)) as {\n method?: string;\n path?: string;\n userId?: string | null;\n uploadId?: string;\n filename?: string;\n } | null;\n if (!body?.path || !body.uploadId) {\n return envelope(\"bad_request\", \"authorize needs a path and an uploadId\", 400, requestId);\n }\n const target = matchRoute(routes, body.method ?? \"POST\", body.path);\n\n // THE AUTH DECISION HAPPENS HERE, BEFORE A SINGLE BYTE IS ACCEPTED.\n //\n // Storage asks this question precisely so it can refuse early: without it,\n // an anonymous caller could push a file at a route that requires a user,\n // have it written and its variants rendered, and only then be turned away\n // by the completion — the bytes were still accepted, and the work still\n // done, once per attempt.\n //\n // The credential is the caller's own, forwarded by storage, and it is\n // verified HERE rather than trusted: the userId that ends up in the path\n // template comes from these claims and from nothing else, so neither the\n // client nor storage can name a folder that belongs to somebody else.\n const spec = effectiveAuth(target?.entry.meta.options?.auth, target?.entry.controllerAuth);\n const callerClaims = await auth.verify(req.headers.get(\"authorization\"));\n if (spec.required && !callerClaims) {\n return envelope(\"unauthorized\", \"A valid access token is required\", 401, requestId);\n }\n // Storage'ın yetkilendirme hoppası da AYNI kapıdan geçer — ve ana istek\n // yolunda olduğu gibi, `claims` olsun olmasın. Bu blok bir\n // `if (callerClaims)` guard'ının içindeydi: `{ required: false, permission }`\n // bildiren bir upload rotasında imzasız çağıran hiç sorulmadan geçiyordu.\n // Kimliksiz çağıranda `auth.uid()` null olduğu için `has_permission` false\n // döner ve ret 403 olur.\n //\n // Transaction lazy: rol/izin sorulmayan bir upload rotasında hiçbir şey\n // açılmaz, yani bildirmeyen rotaya maliyeti yoktur.\n const uploadDb = createRequestDatabase(sql, {\n role: config.dbRole,\n serviceRole: config.dbServiceRole,\n claimsJson: JSON.stringify(callerClaims ?? {}),\n }, config.databaseDiagnostics === undefined ? undefined : { ...config.databaseDiagnostics, endpoint: \"upload authorization\", requestId }, req.signal);\n try {\n const refusal = await refuseUnlessAuthorized(\n uploadDb.client,\n spec,\n requestId,\n makeRoleResolver(uploadDb.client),\n );\n if (refusal) {\n await uploadDb.commit();\n return refusal;\n }\n await uploadDb.commit();\n } catch (err) {\n await uploadDb.rollback(err);\n return errorResponse(err, \"upload authorization\", requestId);\n }\n\n const grant = grantFor(target?.entry, {\n userId: typeof callerClaims?.sub === \"string\" ? callerClaims.sub : null,\n uploadId: body.uploadId,\n filename: body.filename,\n });\n if (!grant) {\n // A route with no @Upload never offered to accept a file. Refusing by\n // NAME rather than 404 so an operator reading storage's log learns which\n // route was asked for.\n return envelope(\"not_an_upload_route\",\n `${body.method ?? \"POST\"} ${body.path} does not declare @Upload`, 400, requestId);\n }\n return new Response(JSON.stringify(grant), { status: 200, headers: JSON_HEADERS });\n }\n\n async function handle(req: Request): Promise<Response> {\n const requestId = `req_${crypto.randomUUID()}`;\n const url = new URL(req.url);\n\n // ── storage's two internal calls, before ordinary routing ───────────────\n //\n // They are not the tenant's routes and must not be reachable as one: an\n // app that declared `POST /__palbase/upload/authorize` would otherwise\n // shadow the mechanism that decides where uploads land.\n if (url.pathname === AUTHORIZE_PATH) {\n return handleAuthorize(req, requestId);\n }\n\n const hit = matchRoute(routes, req.method, url.pathname);\n if (!hit) return envelope(\"not_found\", \"No route matches this method and path\", 404, requestId);\n const { meta } = hit.entry;\n\n let attestedDevice: VerifiedDevice | null = null;\n let attestChallengeOut: string | null = null;\n\n // ── auth ────────────────────────────────────────────────────────────────\n const spec = effectiveAuth(meta.options?.auth, hit.entry.controllerAuth);\n const claims: VerifiedClaims | null = await auth.verify(req.headers.get(\"authorization\"));\n if (spec.required && !claims) {\n return envelope(\"unauthorized\", \"A valid access token is required\", 401, requestId);\n }\n const userId = typeof claims?.sub === \"string\" ? claims.sub : undefined;\n\n // Transaction'ı kapıdan ÖNCE kuruyoruz ve kapı da onu kullanıyor: yetki\n // sorgusu ilk request transaction'ını kullansın diye. Lazy olduğu için rol\n // sormayan bir rotada burada hiçbir şey açılmaz. İlk iş bağımsız $atomic\n // ise yalnız bu core okumaları erken kapanır; uygulamanın SQL'i kapanmaz.\n const db = createRequestDatabase(sql, {\n role: config.dbRole,\n serviceRole: config.dbServiceRole,\n claimsJson: JSON.stringify(claims ?? {}),\n }, config.databaseDiagnostics === undefined && meta.options.databaseBudget === undefined ? undefined : {\n ...config.databaseDiagnostics, ...meta.options.databaseBudget, endpoint: hit.entry.id, requestId,\n }, req.signal);\n\n // Authority reads and parameter injection also acquire database capacity.\n // Their failures must settle the request transaction and preserve HTTP\n // status just as failures in the handler do.\n try {\n // Yetki TOKEN'DAN değil TABLODAN okunur (FR-014/FR-015). Bir claim yalnız\n // mint edildiği anda doğrudur; bir rol geri alındığında etkisinin token\n // süresini beklemesi güvenlik açığıdır. Sorgu, handler'ın zaten kullanacağı\n // transaction içinde koşar (FR-017), yani ek bağlantı maliyeti yoktur.\n //\n // `role` claim'i burada KASTEN okunmuyor: o Postgres rolüdür (\"authenticated\")\n // ve uygulama rolüyle aynı ada sahip olması bir tesadüftür.\n // Bir kez çözülür, iki yerden okunur: kapı (aşağıda) ve `@User()`ın\n // `roles` alanı (FR-016). İkinci bir sorgu ikinci bir snapshot demekti.\n const rolesOfCaller = makeRoleResolver(db.client);\n\n // DISPATCH'TEN ÖNCEKİ HER RET, AÇILMIŞ OLABİLECEK TRANSACTION'I KAPATIR.\n //\n // `createRequestDatabase` artık kapıdan ÖNCE kuruluyor, ve kapı sorgu\n // koşturduğu an `createLazyTransaction` `sql.begin(...)` callback'ine girip\n // `await parked` üzerinde park ediyor. O park yalnız `commit()` (resolve)\n // ya da `rollback()` (reject) ile kalkar — ve ikisi de aşağıdaki `try`\n // bloğunun İÇİNDE çağrılıyor. Aradaki bir `return`, havuz bağlantısını\n // süreç ömrü boyunca `idle in transaction` bırakırdı.\n //\n // Ölçüldü: izin kapısının 403'ünde `{ begun: 1, settled: 0 }`. Yetkisiz bir\n // çağıranın aynı uca N kez vurması havuzdan N bağlantı düşürüyordu — yani\n // kapının kendisi bir DoS koluydu.\n //\n // Hiç açılmamışsa da, zaten commit edilmişse de bu çağrı işlemsizdir\n // (`createLazyTransaction`: `if (!opening) return`), bu yüzden ret yollarına\n // koşulsuz konabilir.\n let dispatched = false;\n const settleBeforeRefusal = async (): Promise<void> => {\n if (dispatched) return;\n await db.rollback(new Error(\"request refused before dispatch\"));\n };\n\n // Kapı `claims` olsun olmasın koşar.\n //\n // `{ required: false, permission: \"p\" }` bildiren bir rotada bu çağrı bir\n // `if (claims)` guard'ının içindeydi: token yoksa `required:false` 401'i de\n // engelliyordu ve kapı HİÇ sorulmuyordu, yani imzasız çağıran handler'a\n // giriyordu. Ölçüldü — Authorization başlığı olmayan istek 200 aldı.\n // İzin isteyen bir uç kimliksiz çağıranı reddetmek ZORUNDA; `auth.uid()`\n // null olduğu için `has_permission` false döner ve ret 403 olur.\n //\n // Bildirmeyen rotaya maliyeti yok: `refuseUnlessAuthorized` ne izin ne rol\n // bildirilmişse hiçbir sorgu açmadan null döner.\n const refusal = await refuseUnlessAuthorized(db.client, spec, requestId, rolesOfCaller);\n if (refusal) {\n await settleBeforeRefusal();\n return refusal;\n }\n if (claims && spec.verifiedEmail && claims.email_verified !== true) {\n await settleBeforeRefusal();\n return envelope(\"email_not_verified\", \"A verified email address is required\", 403, requestId);\n }\n\n let parsedBody: unknown;\n let bodyRead = false;\n\n // The raw body, read ONCE.\n //\n // The App Attest gate binds the assertion to a hash of the body, so it has\n // to see the bytes — and a Request body is a stream that can only be\n // consumed once. Reading it here and handing the same buffer to both the\n // gate and the parameter loop is what keeps the gate from silently\n // draining the body out from under the handler.\n //\n // `rawBody` stays null for methods that cannot carry one, so a GET pays\n // nothing for a feature it never uses.\n let rawBody: Uint8Array | null = null;\n if (req.method !== \"GET\" && req.method !== \"HEAD\") {\n // A DECLARED length over the ceiling is refused BEFORE the body is read.\n //\n // The gate needs the bytes, so the body is now buffered earlier than it\n // used to be — before the rate limiter rather than after, and for every\n // method that can carry one rather than only @Body routes. That moves a\n // memory cost in front of the thing that used to bound it, so the ceiling\n // has to live here instead.\n const declared = Number(req.headers.get(\"content-length\") ?? \"\");\n if (Number.isFinite(declared) && declared > MAX_BODY_BYTES) {\n await settleBeforeRefusal();\n return new Response(\n JSON.stringify({\n error: \"payload_too_large\",\n error_description: `Request body exceeds ${MAX_BODY_BYTES} bytes`,\n status: 413,\n request_id: requestId,\n }),\n { status: 413, headers: JSON_HEADERS },\n );\n }\n const buf = await req.arrayBuffer().catch(() => null);\n // And again on what ACTUALLY arrived: a chunked request declares nothing.\n if (buf && buf.byteLength > MAX_BODY_BYTES) {\n await settleBeforeRefusal();\n return new Response(\n JSON.stringify({\n error: \"payload_too_large\",\n error_description: `Request body exceeds ${MAX_BODY_BYTES} bytes`,\n status: 413,\n request_id: requestId,\n }),\n { status: 413, headers: JSON_HEADERS },\n );\n }\n if (buf && buf.byteLength > 0) rawBody = new Uint8Array(buf);\n }\n const readParsedBody = (): unknown => {\n if (bodyRead) return parsedBody;\n bodyRead = true;\n if (!rawBody) {\n parsedBody = {};\n return parsedBody;\n }\n try {\n parsedBody = JSON.parse(new TextDecoder().decode(rawBody));\n } catch {\n parsedBody = {};\n }\n return parsedBody;\n };\n\n // ── App Attest ──────────────────────────────────────────────────────────\n //\n // After auth (a caller with no session must hear \"unauthorized\", not\n // \"attest first\" — the first is actionable, the second is confusing) and\n // before the rate limiter (a refused request must not spend the caller's\n // budget on a call that never reached a handler).\n const attest = await attestGate(req, rawBody, { userId });\n if (attest.observation) observations.record(attest.observation);\n if (attest.outcome === \"reject\") {\n const headers: Record<string, string> = { ...JSON_HEADERS };\n if (attest.nextChallenge) headers[\"x-palbase-attest-challenge\"] = attest.nextChallenge;\n await settleBeforeRefusal();\n return new Response(\n JSON.stringify({\n error: attest.reason,\n error_description: \"This endpoint requires a verified app instance\",\n status: 401,\n request_id: requestId,\n }),\n { status: 401, headers },\n );\n }\n if (attest.device && claims) attestedDevice = attest.device;\n // The next challenge rides EVERY answer, not just the refusals.\n //\n // Dropping it on the success path is what would keep an attested client\n // paying a 401-then-retry pair for every single call: it would have no\n // fresh nonce for its next assertion and would have to be told to attest\n // all over again. Handing it back here is the entire reason the challenge\n // travels with the verdict.\n attestChallengeOut = attest.nextChallenge;\n\n // ── rate limit ──────────────────────────────────────────────────────────\n const retryAfter = limiter.check(\n meta.options?.rateLimit,\n RateLimiter.key(hit.entry.id, userId, req.headers),\n Date.now(),\n );\n if (retryAfter !== null) {\n // THE HINT GOES IN THE BODY TOO, under the name this SDK already\n // publishes for it. `error-registry.ts` declares\n // `too_many_requests: { retryAfter: number }`, so codegen types\n // `error.data.retryAfter` on every generated client and a thrown\n // `new TooManyRequests({ retryAfter })` already answers in that shape.\n // This limiter answered with the header ALONE, so the one 429 the engine\n // itself produces was the one shape no generated client could read — and\n // a browser behind a CORS gateway cannot see `Retry-After` at all unless\n // it is explicitly exposed. The header stays: it is the HTTP-correct\n // signal, and `@palbase/core`'s retry loop reads it.\n await settleBeforeRefusal();\n return new Response(\n JSON.stringify({\n error: \"too_many_requests\",\n error_description: \"Rate limit exceeded for this endpoint\",\n status: 429,\n request_id: requestId,\n data: { retryAfter },\n }),\n { status: 429, headers: { ...JSON_HEADERS, \"retry-after\": String(retryAfter) } },\n );\n }\n\n // ── arguments ───────────────────────────────────────────────────────────\n // Set when this request IS a completion, so its answer can be remembered.\n let completionUploadId: string | null = null;\n\n const args: unknown[] = [];\n\n\n\n\n\n // The SSE writer has to exist BEFORE the parameter loop (that is where it is\n // injected) but its two collaborators only exist later: the transport queue\n // is created when the ReadableStream starts, and the transaction it settles\n // is opened further down. So both are reached through holders the SSE branch\n // fills in — the writer itself stays ignorant of either.\n let sseEnqueue: ((chunk: string) => void) | null = null;\n let sseSettle: () => Promise<void> = async () => {};\n const sseWriter: EngineSseWriter = makeSseWriter({\n enqueue: (chunk) => sseEnqueue?.(chunk),\n onFirstWrite: () => sseSettle(),\n });\n for (const p of meta.params ?? []) {\n switch (p.kind) {\n case \"body\": {\n readParsedBody();\n const r = p.schema!.safeParse(parsedBody);\n if (!r.success) {\n await settleBeforeRefusal();\n return envelope(\"bad_request\", \"Request body failed validation\", 400, requestId, {\n data: { fields: fieldErrors(r.error) },\n });\n }\n args[p.index] = r.data;\n break;\n }\n case \"query\": {\n const r = p.schema!.safeParse(Object.fromEntries(url.searchParams));\n if (!r.success) {\n await settleBeforeRefusal();\n return envelope(\"bad_request\", \"Query parameters failed validation\", 400, requestId, {\n data: { fields: fieldErrors(r.error) },\n });\n }\n args[p.index] = r.data;\n break;\n }\n case \"param\":\n args[p.index] = hit.params[p.name!];\n break;\n case \"headers\": {\n // A DECLARED HEADER SCHEMA IS A CONTRACT, and three other systems\n // already treat it as one: the deploy gate REFUSES a build whose\n // schema names a reserved or non-string header\n // (cli/internal/backend/devjs/extract_meta.js), the OpenAPI document\n // lists it as an `in: header` parameter, and the iOS/Android\n // generators put it in the generated call's signature. The runtime\n // was the only one that read the schema and did nothing with it, so a\n // request with the header missing or malformed answered 200 and the\n // handler read `undefined` off a value whose type says `string`.\n //\n // Keys arrive LOWERCASE — `Headers` iteration lowercases them — so\n // the declared names are matched case-insensitively (`headersFor`)\n // and `x-tenant` and `X-Tenant` both work, as HTTP says they must.\n const raw = Object.fromEntries(req.headers);\n if (!p.schema) {\n args[p.index] = raw;\n break;\n }\n const r = p.schema.safeParse(headersFor(raw, p.schema));\n if (!r.success) {\n await settleBeforeRefusal();\n return envelope(\"bad_request\", \"Request headers failed validation\", 400, requestId, {\n data: { fields: fieldErrors(r.error) },\n });\n }\n // The PARSED value, matching @Body/@QueryParams: the parameter's type\n // is `z.infer<Schema>`, and injecting the whole header map made the\n // value wider than its own declared type. An author who wants every\n // header still writes `@Headers()` with no schema.\n args[p.index] = r.data;\n break;\n }\n case \"user\":\n case \"optionalUser\":\n args[p.index] = claims\n ? {\n id: userId,\n email: claims.email,\n role: claims.role,\n emailVerified: claims.email_verified === true,\n metadata: (claims.metadata as Record<string, unknown>) ?? {},\n // The caller's APPLICATION roles, from `auth.user_roles` — the\n // same resolution the gate used, so the handler cannot read a\n // different set than the one it was admitted on. Never from a\n // claim: a revoked role has to bite on the next request, and a\n // token says only what was true when it was minted.\n roles: await rolesOfCaller(),\n // Server-owned and only ever filled from a verdict palauth\n // returned. Never from a raw header, never from JWT metadata —\n // the type has said so since it was written and this is the\n // first writer.\n device: attestedDevice,\n }\n : null;\n break;\n case \"uploadedObject\": {\n // An @Upload route runs as a COMPLETION handler: the bytes went to\n // storage, and what arrives here is what storage recorded about them.\n // The call must be signed, or anyone who knows the route path could\n // invent an upload that never happened and make the handler write a\n // row for it.\n if (uploadSecret === \"\" ||\n !verifySignature(req.headers.get(SIGNATURE_HEADER) ?? \"\", uploadSecret)) {\n await settleBeforeRefusal();\n return envelope(\"unauthorized\",\n \"This endpoint accepts uploads through storage, not directly\", 401, requestId);\n }\n readParsedBody();\n const envelopeIn = parsedBody as CompletionEnvelope | null;\n if (!envelopeIn?.uploadedObject) {\n await settleBeforeRefusal();\n return envelope(\"bad_request\", \"the completion call carried no uploaded object\", 400, requestId);\n }\n // A RETRY MUST NOT RUN THE HANDLER AGAIN.\n //\n // Storage retries a completion it did not hear back from, and the\n // handler is a mutation: run twice, one uploaded photo becomes two\n // posts. The first answer is replayed instead, which is what makes\n // the retry invisible to the client waiting on the other end.\n const uploadId = envelopeIn.uploadedObject.uploadId;\n if (typeof uploadId === \"string\" && uploadId !== \"\") {\n const already = completions.recall(uploadId);\n if (already) {\n await settleBeforeRefusal();\n return new Response(already.body, {\n status: already.status,\n headers: already.contentType ? { \"content-type\": already.contentType } : undefined,\n });\n }\n completionUploadId = uploadId;\n }\n args[p.index] = envelopeIn.uploadedObject;\n // The author's @Body sees THEIR payload, not the envelope around it.\n parsedBody = envelopeIn.body ?? {};\n break;\n }\n case \"requestId\":\n args[p.index] = requestId;\n break;\n case \"traceId\":\n args[p.index] = requestId;\n break;\n case \"client\":\n // The data was always on the wire; nothing read it. Every shipped\n // client SDK stamps these four on every request (iOS\n // Palbe/Core/ClientInfo.swift, web core/src/http.ts), and the\n // platform already reads the same names in Go\n // (user-flags/internal/middleware/clientcontext.go). Header names are\n // canonical here, not invented: the deploy gate REFUSES an\n // `@Headers` schema that names an `x-palbase-*` key, which makes\n // `@Client()` the only sanctioned reader of them.\n //\n // `Headers.get()` answers `string | null`, which is exactly what\n // `ClientInfo` declares — a non-SDK caller (curl, server-to-server)\n // sends none of these and gets four nulls rather than a throw.\n args[p.index] = {\n sdkVersion: req.headers.get(\"x-palbase-sdk-version\"),\n appVersion: req.headers.get(\"x-palbase-client-version\"),\n platform: req.headers.get(\"x-platform\"),\n osVersion: req.headers.get(\"x-os-version\"),\n } satisfies ClientInfo;\n break;\n case \"req\":\n args[p.index] = req;\n break;\n // `@Signal()` — the raw request's AbortSignal, which enters the aborted\n // state when the client disconnects. Measured on Bun: an infinite\n // producer guarded by it stops within a few frames of the client dying.\n // It is deliberately NOT reachable through `@Req()`: PBRequest carries\n // request-scoped data and no signal.\n case \"signal\":\n args[p.index] = req.signal;\n break;\n // `@SseOut()` — the frame writer. Meaningful only on an `@Sse` route;\n // on any other route it is an inert writer whose frames go nowhere,\n // which is the same shape `@UploadedObject()` has off an `@Upload`\n // route.\n case \"sseOut\":\n args[p.index] = sseWriter;\n break;\n default:\n args[p.index] = undefined;\n }\n }\n\n // ── dispatch, inside the request's transaction(s) ───────────────────────\n //\n // One for the caller's identity, and — only if the handler asks for it —\n // one more for `Database.$asService()`. Both were built above, at the\n // authorization gate, and both settle here, together.\n db.authorizationComplete?.();\n dispatched = true;\n const services = buildServices(db);\n\n // ── the streaming branch ────────────────────────────────────────────────\n //\n // An `@Sse` route answers with `text/event-stream` and a body that stays\n // open; its return value is discarded. What makes this more than \"return a\n // stream\" is the moment of commitment: once ONE frame has gone out, the\n // 200 and the headers are spent, so a later throw can only be reported\n // in-band (FR-011). Before that first frame the status line is still ours\n // and an ordinary error envelope is both possible and much more useful\n // (FR-010). So the handler is started, and the decision waits for whichever\n // comes first — its first write, or its own completion.\n if (meta.options?.sseConfig !== undefined) {\n // The transport is built BEFORE the handler starts, so there is never a\n // window in which a written frame has nowhere to go. An unused stream\n // costs nothing: if the handler turns out never to write, the response\n // below is an ordinary envelope and this object is simply dropped.\n // (An earlier version created the stream only after the first frame and\n // held frames in a buffer meanwhile. That buffer's correctness depended\n // on microtask timing, so no test could pin it — mutation-checked: the\n // flush could be deleted with the suite still green. Untestable\n // defensive code is worse than no window at all.)\n let sseController!: ReadableStreamDefaultController<Uint8Array>;\n const sseEncoder = new TextEncoder();\n const stream = new ReadableStream<Uint8Array>({\n start(c) {\n sseController = c;\n },\n });\n sseEnqueue = (chunk) => {\n // Same exposure as the close below: a frame written after the client\n // left has nowhere to go, and saying so by throwing would kill the\n // process rather than the request.\n try {\n sseController.enqueue(sseEncoder.encode(chunk));\n } catch {\n // The reader is gone. The handler's own signal is what stops it.\n }\n };\n\n let sawFirstFrame!: () => void, refuseFirstFrame!: (error: unknown) => void;\n const firstFrame = new Promise<void>((resolve, reject) => { sawFirstFrame = resolve; refuseFirstFrame = reject; });\n\n // THE FIRST FRAME ENDS THE REQUEST PHASE.\n //\n // The handler runs inside the request's transaction, and a stream may\n // live for minutes. Holding a transaction that long exhausts the\n // connection pool — a failure no unit test sees, that appears only under\n // load, and that looks like \"the database is slow\" when it arrives. So\n // the transaction settles HERE, in the hook the writer awaits before it\n // emits anything: the ordering is structural, not a happy accident of\n // microtask scheduling.\n sseSettle = async () => {\n try { await db.commit(); sawFirstFrame(); }\n catch (error) { refuseFirstFrame(error); throw error; }\n };\n\n // …and afterwards the database is refused BY NAME. The alternative is a\n // settled transaction quietly answering a query, which is a correctness\n // bug the author would never find. The message says what happened and\n // what to do instead.\n const guarded: RuntimeServices = {\n ...services,\n Database: new Proxy(services.Database as object, {\n get(target, prop, recv) {\n // `started()` flips SYNCHRONOUSLY inside `write()`, which is the\n // only reading that works: `write` returns immediately, so a\n // handler's next line runs before the commit has finished. The\n // author's own call is the boundary, not the commit's completion.\n if (sseWriter.started()) {\n throw new Error(\n `sse_db_after_write: ${hit.entry.id} touched the database after its ` +\n `first write(). A streaming response settles its transaction with the ` +\n `first frame — do the database work before the first write.`,\n );\n }\n return Reflect.get(target, prop, recv);\n },\n }) as RuntimeServices[\"Database\"],\n };\n\n let thrown: unknown = null;\n const ran = Promise.resolve(runWithRuntime(guarded, () => {\n const box = requestALS.getStore();\n if (box) {\n box.userId = userId ?? null;\n box.requestId = requestId;\n box.idempotencyKey = req.headers.get(\"idempotency-key\");\n }\n const method = hit.entry.instance[meta.fnName];\n if (typeof method !== \"function\") {\n throw new Error(\n `route ${hit.entry.id} names method ${meta.fnName}, which the controller does not define`,\n );\n }\n return method.apply(hit.entry.instance, args);\n })).then(\n () => undefined,\n (err: unknown) => {\n thrown = err;\n },\n );\n\n await Promise.race([firstFrame, ran]);\n\n if (!sseWriter.started()) {\n // Nothing was ever written. The handler either finished silently or\n // threw before its first frame — either way the response shape is\n // still a free choice, so it gets the ordinary one.\n await ran;\n await db.commit();\n if (thrown !== null) throw thrown;\n return new Response(null, { status: 204 });\n }\n\n // A synchronous handler can finish before its queued first write.\n // Do not send HTTP 200 until that write's COMMIT has actually settled.\n await firstFrame;\n void (async () => {\n await ran;\n await sseWriter.drained();\n // THE CLIENT LEAVING IS A NORMAL ENDING, NOT AN ERROR.\n //\n // When the client disconnects the runtime closes this controller\n // itself, so the terminal write and close below arrive at a stream\n // that is already gone. Left unguarded they throw\n // `ERR_INVALID_STATE: Controller is already closed` from inside a\n // detached async task — which is an unhandled rejection, and under Bun\n // that KILLS THE SERVER PROCESS. One user closing a tab would take the\n // backend down with them.\n //\n // Measured 2026-08-29 against real OpenAI: curl was killed mid-stream\n // and the process exited with code 1 at this line. No unit test could\n // have caught it — in a test the client never disconnects at the\n // transport layer, so the controller is always still open here.\n try {\n if (thrown !== null) {\n log.error(`[engine] ${hit.entry.id} threw mid-stream`, thrown);\n sseController.enqueue(sseEncoder.encode(encodeErrorFrame(requestId)));\n }\n sseController.close();\n } catch {\n // Already closed: the client is gone and there is nobody to tell.\n }\n })();\n return new Response(stream, {\n status: 200,\n headers: { \"content-type\": SSE_CONTENT_TYPE, \"cache-control\": \"no-cache\" },\n });\n }\n\n const result = await runWithRuntime(services, () => {\n // The ALS box carries the caller's identity beside the services; Flags'\n // auto-bind reads it, and so does anything else that needs a\n // server-owned user id rather than one the caller supplied.\n const box = requestALS.getStore();\n if (box) {\n box.userId = userId ?? null;\n box.requestId = requestId;\n box.idempotencyKey = req.headers.get(\"idempotency-key\");\n }\n const method = hit.entry.instance[meta.fnName];\n if (typeof method !== \"function\") {\n throw new Error(\n `route ${hit.entry.id} names method ${meta.fnName}, which the controller does not define`,\n );\n }\n return method.apply(hit.entry.instance, args);\n });\n if (meta.returnSchema) {\n const v = meta.returnSchema.safeParse(result);\n if (!v.success) {\n log.error(`[engine] ${hit.entry.id} returned a value its declared type rejects`, v.error.issues);\n await db.rollback(new Error(\"output_invalid\"));\n return envelope(\n \"output_invalid\",\n \"The handler returned a value its declared return type rejects\",\n 500,\n requestId,\n );\n }\n }\n if (result === undefined || result === null && !meta.returnSchema) {\n await db.commit();\n if (completionUploadId) {\n completions.remember(completionUploadId, { status: 204, body: null, contentType: null });\n }\n return new Response(null, { status: 204 });\n }\n const payload = JSON.stringify(result);\n await db.commit();\n if (completionUploadId) {\n completions.remember(completionUploadId, {\n status: 200,\n body: payload,\n contentType: JSON_HEADERS[\"content-type\"] ?? \"application/json\",\n });\n }\n return new Response(payload, {\n status: 200,\n headers: attestChallengeOut\n ? { ...JSON_HEADERS, \"x-palbase-attest-challenge\": attestChallengeOut }\n : JSON_HEADERS,\n });\n } catch (err) {\n // This includes errors in authorization and parameter injection.\n await db.rollback(err);\n // Branded, not `instanceof`: the tenant's bundle carries its own copy of\n // this SDK, so class identity does not survive the hop from the handler\n // to this catch. See HTTP_ERROR_BRAND.\n return errorResponse(err, hit.entry.id, requestId);\n }\n }\n\n // The author's own long-lived resources come up HERE: after the pool has been\n // proven (`select 1` above) and before anything can be served. A hook that\n // throws REFUSES THE BOOT — an app that answers with a half-open resource\n // behind it is the silence `onStart` exists to replace — and the pool this\n // function opened is closed on the way out, because nobody will ever get the\n // `shutdown` below to close it.\n // START HOOKS RUN IN A SCOPE — a BOOT one, not a request one.\n //\n // A start hook is where a long-lived resource comes up, and the credential\n // that resource needs lives in the vault. `Secrets.get()` threw \"outside a\n // request scope\" here, so the one place an author is TOLD to open a pool could\n // not read the password for it (D-19).\n //\n // Everything that is genuinely boot-level — Secrets, Cache, Log, the module\n // clients — is handed over. `Database` is NOT, and refuses BY NAME: a start\n // hook runs before anything is served, so there is no request and no\n // transaction for a query to belong to. Handing out a real one would open a\n // transaction on the boot path that nobody closes; saying so is the honest\n // answer and the one an author can act on.\n const bootServices = buildServices(null);\n\n let runShutdownHooks: ShutdownRunner;\n try {\n runShutdownHooks = await runWithRuntime(bootServices, () => __runStartHooks());\n } catch (err) {\n await closeDriver(sql);\n throw err;\n }\n\n return {\n handle: req => !accepting\n ? Promise.resolve(envelope(\"runtime_draining\", \"This application is shutting down\", 503, `req_${crypto.randomUUID()}`))\n : serving(() => handle(req)),\n get databasePressure() { return admission.snapshot; },\n routes,\n config,\n container: liveContainer,\n runInServiceScope: fn => !accepting\n ? Promise.reject(new Error(\"This application is shutting down; no new database scope can start\"))\n : serving(() => runInServiceScope(fn)),\n shutdown() {\n accepting = false;\n return shuttingDown ??= (async () => {\n // A release may share its physical pool with its successor. Wait for\n // this app's HTTP/jobs (including COMMIT/ROLLBACK) before closing its\n // resources; closing the shared pool is no longer a drain mechanism.\n while (inFlight.size) await Promise.allSettled([...inFlight]);\n // The author's resource is released BEFORE the pool: a driver standing on\n // this pool cannot close after the pool is gone.\n await runShutdownHooks();\n await closeDriver(sql);\n // The container goes with the app. It holds one instance of every class\n // this app owns, and those instances hold whatever their constructors\n // captured — an app that shut down must not keep them reachable through\n // a handle someone still has.\n released = true;\n })();\n },\n };\n}\n\n/** Let go of the driver — `close` or `end`, whichever it carries. */\nasync function closeDriver(sql: SqlDriver): Promise<void> {\n const closable = sql as { close?: () => Promise<void> | void; end?: () => Promise<void> | void };\n await closable.close?.();\n await closable.end?.();\n}\n","/**\n * runtime.ts — request-scoped service singletons.\n *\n * The backend SDK no longer threads a `ctx` god-object through every handler.\n * Instead, controller methods import PascalCase service singletons directly:\n *\n * import { Controller, Post, Body, Database } from \"@palbase/backend\";\n *\n * \\@Controller(\"/todos\")\n * export default class TodosController {\n * \\@Post(\"\") create(\\@Body(CreateTodoBody) body: CreateTodoBody): unknown {\n * return Database.public.todos.insert({ title: body.title });\n * }\n * }\n *\n * The singletons are thin Proxies. Every property access forwards to the live\n * client for the CURRENT request scope, resolved through {@link __getRuntime}.\n *\n * # Request-scope resolution (persistent app-server)\n *\n * The runtime is a long-running Node process that serves many concurrent\n * requests on one event loop (NOT a fresh subprocess per request). A single\n * module-global slot would let one in-flight request's services bleed into\n * another's. So the services are carried in an {@link AsyncLocalStorage} store\n * ({@link __requestALS}) that the runtime sets per request with\n * {@link __runWithRuntime}; every async continuation of that request reads its\n * own store. `__getRuntime` reads the ALS store first; the module-global slot\n * (set by {@link __setRuntime}) is only a fallback for callers that run OUTSIDE\n * an ALS scope (dev-server, unit tests, the legacy single-shot path). Because\n * each `br-<ref>` pod is single-tenant, there is no cross-tenant leakage; the\n * ALS store is what prevents cross-REQUEST leakage within the shared process.\n *\n * The seam that makes `import { Database } from \"@palbase/backend\"` resolve to\n * the runtime-injected client: `@palbase/backend` is marked esbuild-EXTERNAL\n * when the tenant bundle is built, and the package is installed globally in the\n * pod (NODE_PATH=/usr/local/lib/node_modules). So worker.js's\n * `require('@palbase/backend')` and the bundle's `import` resolve to ONE shared\n * module instance — the ALS store and `__setRuntime` slot on that instance are\n * visible to the singletons the bundle imported.\n */\n\nimport type { PalbaseFlagKey } from \"./stack.js\";\nimport type { Buckets, BucketTypes, Schemas } from \"./db/env.js\";\nimport { AsyncLocalStorage } from \"node:async_hooks\";\n\nimport type {\n DBClient,\n AtomicClient,\n DBOps,\n CacheClient,\n Logger,\n PalbaseDocsClient,\n SecretsService,\n} from \"./endpoint.js\";\nimport type {\n PalbaseAuthAdminClient,\n PalbaseStorageClient,\n PalbaseBucketClient,\n PalbaseNotificationsClient,\n PalbaseFlagsClient,\n PalbaseFlagsServiceClient,\n PalbaseFlagContext,\n PalbaseFlagVariant,\n PalbaseFlag,\n PalbaseFlagValue,\n PalbaseSetOverrideResult,\n PalbaseRealtimeClient,\n} from \"./clients.js\";\nimport type { PalbaseResult } from \"./endpoint.js\";\nimport type {\n EnvTypedDatabase,\n EnvServiceDatabase,\n AtomicDatabase,\n EnvTables,\n TxPlan,\n TxTables,\n} from \"./db/typed-db.js\";\nimport type { Materialized } from \"./db/tx-plan.js\";\nimport { TxPlanBuilder, runTxPlan } from \"./db/tx-plan.js\";\nimport { assertPlanRetry, type AtomicOptions } from \"./db/transaction-options.js\";\nimport { qualifiedTableKey } from \"./db/schema-json.js\";\nimport type { DollarOps } from \"./db/typed-db.js\";\n\n/** The set of live clients the runtime injects per request scope.\n *\n * Realtime is BROADCAST-ONLY here (a stateless handler can push an event but\n * cannot hold a subscription socket — `subscribe()` lives on the client SDK).\n *\n * EXCLUDED on purpose: Functions, Links, Analytics. They are not exposed as\n * backend handler singletons — out of scope for backend endpoints. `Auth` is\n * here in its ROLE-ASSIGNMENT shape only: signing in is the client SDK's job,\n * but granting a role is an operator verb the tenant's own handler needs\n * (FR-009). */\nexport interface RuntimeServices {\n Database: DBClient;\n Auth: PalbaseAuthAdminClient;\n Secrets: SecretsService;\n Documents: PalbaseDocsClient;\n Storage: PalbaseStorageClient;\n Cache: CacheClient;\n Log: Logger;\n Notifications: PalbaseNotificationsClient;\n Flags: PalbaseFlagsClient;\n Realtime: PalbaseRealtimeClient;\n}\n\n/**\n * The per-request ALS box.\n *\n * `runtime` is the service bundle. `userId` is the request's authenticated user\n * id, written by the runtime immediately after it assembles the request object\n * (worker.js: `requestALS.getStore().userId = pbReq.user?.id || null`) and\n * `null` on an anonymous request. It was already being written there for the\n * Flags client's auto-bind; declaring it here makes the existing contract typed\n * instead of implicit, which is what lets `currentSubjectId()` read a\n * server-owned identity rather than trusting anything the caller sent.\n */\nexport interface RequestStore {\n runtime: RuntimeServices;\n userId?: string | null;\n /** This request's id (`req_…`), written by the runtime. Used as the spend\n * idempotency scope when the caller supplied no `Idempotency-Key`. */\n requestId?: string;\n /** The caller's `Idempotency-Key` header, or `null` when absent. What makes a\n * client's retry replay its first result instead of charging twice. */\n idempotencyKey?: string | null;\n}\n\n/**\n * Per-request store. The persistent runtime runs each request inside\n * {@link __runWithRuntime}, so every async continuation of that request reads\n * its OWN `runtime` (and any other request-scoped fields the runtime adds).\n *\n * Exported with a `__` prefix so the runtime (worker.js) shares the SAME ALS\n * instance across the one module instance — two ALS instances would silently\n * not see each other's stores. NOT part of the public author-facing API.\n */\n/**\n * The per-request store — ON globalThis under a well-known Symbol, for the same\n * reason `lifecycleHooks` and the controller registry are.\n *\n * MEASURED, through the production package gate: `tsup` emits `dist/index.cjs`\n * and `dist/test/index.cjs` as SEPARATE bundles and each inlines this module.\n * With a module-local `AsyncLocalStorage`, `withServices` (which ships from the\n * `/test` subpath) opened a scope in ITS copy while the `Database` singleton\n * (which ships from the root) read the OTHER copy's — and the ambient service a\n * test had just installed was invisible:\n *\n * Error: Palbase services accessed outside a request scope.\n *\n * The unit tests could not see it: inside the package there is only ever one\n * copy. It took calling the built artifact the way a consumer does. Same class\n * as the defect `@Module`'s slot comment describes — two module-local values\n * where the two halves of one contract must agree.\n *\n * SÜRÜMSÜZ, VE BU BİLİNÇLİ. Anahtar `…requestALS@32` gibi sürümlenseydi iki\n * major aynı süreçte ALS'i paylaşmayı BIRAKIRDI — yani yukarıda anlatılan kusur\n * sürüm sınırında geri gelirdi. Bedeli de gerçek ve burada yazılı:\n * `RequestStore.runtime` zorunlu bir `RuntimeServices` ve o küme büyüyor\n * (30.0.0 `Auth` ile 9→10). Eski bir majorün yazdığı kutuyu yeni bir major\n * okursa yeni alan `undefined` gelir.\n *\n * Bu pakette YEDİ well-known Symbol var ve hepsi sürümsüz (`httpError`,\n * `engineRaised`, `channels`, `errorRegistry`, `declarationRefusal`,\n * `lifecycleHooks`, ve bu). Yalnız BİRİNİ sürümlemek tutarsızlıktan başka bir\n * şey üretmez: karar paket geneli olmalı ve `RequestStore`'un şekil\n * sözleşmesiyle birlikte alınmalı (sapma defteri D-05).\n */\nconst REQUEST_ALS: unique symbol = Symbol.for(\"palbase.backend.requestALS\") as never;\n\nexport const __requestALS: AsyncLocalStorage<RequestStore> = ((): AsyncLocalStorage<RequestStore> => {\n const g = globalThis as unknown as Record<symbol, AsyncLocalStorage<RequestStore> | undefined>;\n return (g[REQUEST_ALS] ??= new AsyncLocalStorage<RequestStore>());\n})();\n\n/** Process-global fallback slot. Used only OUTSIDE an ALS scope (dev-server,\n * unit tests, legacy single-shot worker). Inside the persistent server every\n * request runs in {@link __requestALS}, which takes precedence. */\nlet runtime: RuntimeServices | null = null;\n\n/** Install the live clients in the process-global fallback slot.\n *\n * Persistent-server requests should use {@link __runWithRuntime} instead; this\n * remains for dev-server / tests / the legacy single-shot path that run without\n * an ALS scope. NOT part of the public author-facing API. */\nexport function __setRuntime(services: RuntimeServices): void {\n runtime = services;\n}\n\n/** Run `fn` with `services` bound as the request-scoped runtime.\n *\n * The persistent worker calls this once per request so concurrent requests\n * never share a services slot. NOT part of the public author-facing API. */\nexport function __runWithRuntime<T>(services: RuntimeServices, fn: () => T): T {\n return __requestALS.run({ runtime: services }, fn);\n}\n\n/** Read the live clients, throwing if accessed outside a request scope.\n *\n * Resolves the ALS store first (persistent server, per-request), then the\n * process-global fallback (dev-server / tests). NOT part of the public\n * author-facing API — used by the runtime and the singleton Proxies. */\n/**\n * Bir kutunun TAŞIMASI GEREKEN servisler.\n *\n * `withServices`'in listesiyle aynı gerçeği söylüyor ama BURADA yaşamak\n * zorunda: `test/` yalnız test yüzeyinde, bu kontrol ise her isteğin yolunda.\n * İkisi de `satisfies` ile `RuntimeServices`'a pinli, yani biri eksik kalırsa\n * derleme durur.\n */\nconst REQUIRED_SERVICES = [\n \"Database\",\n \"Auth\",\n \"Secrets\",\n \"Documents\",\n \"Storage\",\n \"Cache\",\n \"Log\",\n \"Notifications\",\n \"Flags\",\n \"Realtime\",\n] as const satisfies readonly (keyof RuntimeServices)[];\n\n/**\n * ÇAPRAZ-MAJOR KUTUYU ADIYLA REDDET (sapma defteri D-05).\n *\n * `__requestALS` sürümSÜZ bir `Symbol.for` altında ve bu bilinçli: iki bundle\n * (`dist/index.cjs` ve `dist/test/index.cjs`) ambient kapsamı ancak öyle\n * paylaşır. Bedeli de gerçek — tek süreçte iki major varsa ESKİ olanın yazdığı\n * kutuyu YENİ olan okur, ve servis kümesi büyümüşse (30.0.0'da 9→10, `Auth`)\n * yeni alan `undefined` gelir.\n *\n * `undefined` bir servis, erişildiğinde `Reflect.get called on non-object`\n * verir: ne eksik olanın adı, ne sebebi. Bu kontrol o sessizliği bir cümleye\n * çevirir. Maliyeti istek başına on `in` kontrolü.\n */\nfunction refuseIncompleteBox(services: RuntimeServices): RuntimeServices {\n const missing = REQUIRED_SERVICES.filter((k) => services[k] === undefined);\n if (missing.length > 0) {\n throw new Error(\n `the request scope is missing ${missing.join(\", \")} — this box was most likely written by a ` +\n `DIFFERENT @palbase/backend major sharing the same process (the request store is a ` +\n `process-wide well-known Symbol, deliberately, so two bundles of ONE version can share it). ` +\n `Align the versions, or pass every service when building the scope yourself.`,\n );\n }\n return services;\n}\n\nexport function __getRuntime(): RuntimeServices {\n const scoped = __requestALS.getStore();\n if (scoped) return refuseIncompleteBox(scoped.runtime);\n if (runtime === null) {\n throw new Error(\n \"Palbase services accessed outside a request scope. The Database/Documents/… \" +\n \"singletons are only available inside an endpoint handler (or after the \" +\n \"runtime has called __runWithRuntime / __setRuntime).\",\n );\n }\n return runtime;\n}\n\n// ─── lifecycle: where a long-lived resource lives (FR-013) ─────────────────\n//\n// `Resource` was removed in 23.0.0 and nothing replaced the LIFECYCLE half of\n// it. What that left behind is measurable: a connection pool (the driver in\n// `docs/resources.md`'s own example was Neo4j) had no documented place to be\n// opened and NO WAY AT ALL to be closed, so every deploy left the pool it\n// opened behind. These two hooks are that half — and only that half. The\n// secret-distribution half does not come back: a handler reads `Secrets.get`,\n// and a start hook, which runs before any request scope exists, reads the\n// `process.env` the runtime mirrors the vault into at boot.\n\n/** A lifecycle hook. Sync or async; the runtime awaits what it returns. */\nexport type LifecycleHook = () => void | Promise<void>;\n\n/** Runs one release's shutdown hooks. Handed back by {@link __runStartHooks}\n * and called by the engine's `app.shutdown()`. Idempotent. */\nexport type ShutdownRunner = () => Promise<void>;\n\ninterface DeclaredHook {\n name: string;\n run: LifecycleHook;\n}\n\ninterface DeclaredLifecycle {\n start: DeclaredHook[];\n shutdown: DeclaredHook[];\n}\n\n/**\n * What has been DECLARED and not yet claimed by an app.\n *\n * On globalThis under a well-known Symbol for the reason the controller\n * registry is (`decorators/controller.ts`): a deployed bundle inlines its own\n * copy of this package, and the engine that has to RUN these hooks holds the\n * other copy. Two module-local arrays would mean the engine reads the empty one\n * and every declared hook is silently never run — which is exactly how\n * `Resource`'s `init(env)` died.\n */\nconst LIFECYCLE: unique symbol = Symbol.for(\"palbase.backend.lifecycleHooks\") as never;\n\nfunction declaredLifecycle(): DeclaredLifecycle {\n const g = globalThis as unknown as Record<symbol, DeclaredLifecycle | undefined>;\n return (g[LIFECYCLE] ??= { start: [], shutdown: [] });\n}\n\n/**\n * Run `hook` ONCE while the application comes up, before it serves anything.\n *\n * Call it at MODULE SCOPE in a file the application imports — the same rule\n * `defineDefaultAuth` and `@Controller` follow, and for the same reason: the\n * declaration is claimed when the app boots, which is after module loading and\n * before the first request. `name` is not decoration: a hook that throws is\n * reported by that name and the boot is REFUSED, so it is what tells an\n * operator which resource did not come up.\n *\n * There is no request scope yet, so the `Database`/`Secrets`/… singletons are\n * NOT available inside a start hook. A secret is read from `process.env` here\n * (the runtime mirrors the vault into it at boot).\n *\n * @example\n * // resources/graph.ts\n * import neo4j from \"neo4j-driver\";\n * import { onStart, onShutdown } from \"@palbase/backend\";\n *\n * export let graph: Driver;\n * onStart(\"graph\", () => {\n * graph = neo4j.driver(process.env.NEO4J_URL!, neo4j.auth.basic(\"neo4j\", process.env.NEO4J_PASSWORD!));\n * });\n * onShutdown(\"graph\", () => graph.close());\n */\nexport function onStart(name: string, hook: LifecycleHook): void {\n declaredLifecycle().start.push({ name, run: hook });\n}\n\n/**\n * Run `hook` while the application shuts down — the place a pool opened in\n * {@link onStart} is closed.\n *\n * Shutdown is BEST-EFFORT by design: a hook that throws is reported by name and\n * the rest still run. A drain that abandoned the remaining hooks on the first\n * failure would leak exactly what this exists to release, and the process is\n * leaving anyway.\n *\n * Hooks run in REVERSE declaration order, so a resource is released before what\n * it was built on.\n */\nexport function onShutdown(name: string, hook: LifecycleHook): void {\n declaredLifecycle().shutdown.push({ name, run: hook });\n}\n\nfunction reason(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n\n/** Best-effort drain: every hook runs, a failure is reported, none is silent. */\nasync function drain(hooks: DeclaredHook[]): Promise<void> {\n for (const h of [...hooks].reverse()) {\n try {\n await h.run();\n } catch (err) {\n console.error(`[palbase] shutdown hook \"${h.name}\" failed: ${reason(err)}`, err);\n }\n }\n}\n\n/**\n * CLAIM what has been declared, run the start hooks, and hand back the runner\n * for this release's shutdown hooks. Called by the engine's `createApp`; the\n * `App.shutdown()` it builds calls what comes back. NOT part of the public\n * author-facing API.\n *\n * IT CLAIMS RATHER THAN READS, which is what makes it correct in this runtime:\n * a candidate release is loaded BESIDE the live one in one process\n * (`v2/runtime/src/registry-scope.ts`), and both bundles append to the one\n * shared slot above. If each app read the whole list, the live app's shutdown\n * would close the candidate's pool and the candidate's would close the live\n * app's. Taking the declarations leaves each app holding exactly its own.\n *\n * A start hook that throws REFUSES THE BOOT — with the hook's name in the\n * message — after releasing whatever the earlier hooks already opened. Serving\n * from a half-initialised app is the silence this whole surface replaces, and a\n * boot that dies holding an open pool is the leak it replaces.\n */\nexport async function __runStartHooks(): Promise<ShutdownRunner> {\n const slot = declaredLifecycle();\n const start = slot.start.splice(0);\n const shutdown = slot.shutdown.splice(0);\n\n for (const h of start) {\n try {\n await h.run();\n } catch (err) {\n await drain(shutdown);\n throw new Error(`[palbase] start hook \"${h.name}\" failed: ${reason(err)}`, { cause: err });\n }\n }\n\n let drained = false;\n return async () => {\n // SIGTERM racing a redeploy asks twice; a pool is closed once.\n if (drained) return;\n drained = true;\n await drain(shutdown);\n };\n}\n\n/** Drop every declaration. For tests, which declare repeatedly in one process.\n * NOT part of the public author-facing API. */\nexport function __resetLifecycleHooks(): void {\n const g = globalThis as unknown as Record<symbol, DeclaredLifecycle | undefined>;\n delete g[LIFECYCLE];\n}\n\n/**\n * Build a Proxy singleton that forwards every property access to the live\n * client named `key` on the current runtime.\n *\n * The single `as RuntimeServices[K]` is the only contained cast in the surface:\n * `Reflect.get` on a typed object returns `unknown` for a `string | symbol`\n * key, but `prop` is constrained to keys of the client interface at the call\n * sites (the exported singletons are typed below), so the forward is sound.\n */\nfunction makeServiceProxy<K extends keyof RuntimeServices>(key: K): RuntimeServices[K] {\n const handler: ProxyHandler<RuntimeServices[K]> = {\n get(_target, prop, receiver) {\n const client = __getRuntime()[key];\n const value = Reflect.get(client as object, prop, receiver) as unknown;\n // Bind methods to their owning client so `this` stays correct when the\n // author destructures or calls `Database.query(...)`.\n return typeof value === \"function\" ? value.bind(client) : value;\n },\n };\n // The Proxy target is irrelevant (all access goes through `get`); the cast\n // names the surface type the singleton presents to authors.\n return new Proxy({} as RuntimeServices[K], handler);\n}\n\n/**\n * Build the `.tables` accessor for the top-level `Database`. Each\n * `tables.<name>` access returns a small object that forwards the five CRUD ops\n * to the underlying client using `name` as the string table identifier. The\n * shapes are typed against the generated `palbase-env.d.ts` (`EnvTables`); at\n * runtime they are plain string-keyed calls, so no schema value is needed here.\n *\n * Returns `EnvTables` — TS cannot infer the mapped type through the Proxy, so\n * a single structural narrowing names the surface (the proxy returns a\n * correctly-shaped accessor for whatever string member is read).\n */\n/** T018 (C-8): similar/recommend'in string-keyed yüzü. DBOps'a (endpoint.ts)\n * BİLEREK eklenmedi — search-param imza üçlüsü (engine/db + typed-db +\n * endpoint) büyümesin: proxy dispatch runtime'da engine ops'una zaten ulaşır,\n * derleme güvenliğini typed yüzey (EnvTypedTable) verir. */\nexport interface RecoOps {\n similar(table: string, id: string, params?: Record<string, unknown>): Promise<Record<string, unknown>[]>;\n recommend(table: string, params: Record<string, unknown>): Promise<Record<string, unknown>[]>;\n}\n\n/**\n * The Proxy behind EVERY `.tables` map — public's and every other schema's.\n *\n * `prefix` is what the wire name is built from: `\"\"` for `public`, so its tables\n * stay BARE, and `\"<schema>.\"` for any other, so `schema(\"billing\").tables\n * .invoices` reaches the broker as `billing.invoices` (D-10 — the same\n * schema-qualified key `toSchemaJSON` and the generated `relations` use).\n *\n * One trap for both surfaces: two copies would be two op lists that can drift,\n * and the one that forgets an op does not complain — it answers `undefined`.\n */\nfunction makeTableProxy(ops: () => DBOps & RecoOps, prefix: string): object {\n return new Proxy(\n {},\n {\n get(_t, prop: string | symbol) {\n if (typeof prop !== \"string\") return undefined;\n const name = `${prefix}${prop}`;\n return {\n insert: (data: Record<string, unknown>) => ops().insert(name, data),\n // DÖRDÜNCÜ FİİL, aynı gerekçeyle: tip söz veriyor, ops katmanı\n // uyguluyor, ve bir handler'ın gerçekten dokunduğu yer BURASI.\n // `runtime-table-verbs` kapısı bunu adıyla saydı.\n aggregate: (q: Parameters<DBOps[\"aggregate\"]>[1]) => ops().aggregate(name, q),\n insertMany: (\n rows: readonly Record<string, unknown>[],\n opts?: import(\"./db/bulk.js\").InsertManyOptions,\n ) => ops().insertMany(name, rows, opts),\n update: (q: { where: { id: string }; set: Record<string, unknown> }) =>\n ops().update(name, q.where.id, q.set),\n delete: (id: string) => ops().delete(name, id),\n findById: (id: string) => ops().findById(name, id),\n findUnique: (q: { where: Record<string, unknown>; select?: readonly string[]; with?: Record<string, unknown> }) =>\n ops().findUnique(name, q.where, { select: q.select, with: q.with }),\n page: (q?: Record<string, unknown>) => {\n const { where, ...opts } = q ?? {};\n return ops().page(name, where as Record<string, unknown> | undefined, opts as import(\"./db/page.js\").RawPageOptions);\n },\n findMany: (q?: Record<string, unknown>) => {\n // `where` AYIKLANIR; kalan alanlar (orderBy/limit/offset) ham op'un\n // ikinci parametresine gider. Tümünü geçirmek `where`'i tel üstünde\n // ikinci kez gönderirdi — `typed-db.test.ts` bunu yakalıyor.\n const { where, ...opts } = q ?? {};\n return ops().findMany(\n name,\n where as Record<string, unknown> | undefined,\n opts as Parameters<DBOps[\"findMany\"]>[2],\n );\n },\n put: (q: { data: Record<string, unknown>; onConflict: readonly string[] }) =>\n ops().put(name, q.data, { onConflict: q.onConflict }),\n // THREE VERBS THE TYPE PROMISED AND THIS PROXY DID NOT EMIT.\n //\n // `EnvTypedTableBase` declares `updateMany`, `deleteMany` and `count`\n // (typed-db.ts) and the ops layer implements all three — only this\n // proxy, which is what a handler actually touches, left them out. So\n // the type said the verb exists, autocomplete offered it, and the call\n // answered `undefined is not a function`.\n //\n // Older than this run, but the run rewrote this proxy for\n // `Database.schema(name).tables.*` and would have carried the gap onto\n // the new surface too.\n updateMany: (q: { where: Record<string, unknown>; set: Record<string, unknown>; returning?: boolean }) =>\n ops().updateMany(name, q.where, q.set, q.returning === undefined ? undefined : { returning: q.returning }),\n deleteMany: (q: { where: Record<string, unknown> }) => ops().deleteMany(name, q.where),\n count: (q?: { where?: Record<string, unknown> }) => ops().count(name, q?.where),\n search: (params?: Record<string, unknown>) => ops().search(name, params),\n similar: (id: string, params?: Record<string, unknown>) => ops().similar(name, id, params),\n recommend: (params: Record<string, unknown>) => ops().recommend(name, params),\n facets: (params: { facets: string[] } & Record<string, unknown>) => ops().facets(name, params),\n supersede: (id: string, row: Record<string, unknown>) => ops().supersede(name, id, row),\n claim: (unique: Record<string, unknown>, extra?: Record<string, unknown>) =>\n ops().claim(name, unique, extra),\n };\n },\n },\n );\n}\n\n\n/** The raw string-keyed `DBClient` for the current request scope. */\nconst rawDatabase: DBClient = makeServiceProxy(\"Database\");\n\n/**\n * Wrap a raw `DBClient` into the typed `{ ...ops, tables, transaction }`\n * surface. The five string ops forward straight through; `tables` is the\n * env-typed accessor; `transaction` yields typed tables. Reused for both the\n * default (RLS-enforced) `Database` and the `asService()` sibling — each is\n * fed its own raw client (the default proxy vs `rawDatabase.asService()`).\n *\n * The `satisfies` pins the op surface so a missing/renamed op is a compile\n * error; the assembled object carries `tables`/`transaction` alongside.\n */\n/**\n * PACKAGE-INTERNAL, and deliberately NOT re-exported from `index.ts`.\n *\n * `test/fake-db.ts` builds the fake's surface with the SAME constructor\n * production uses, so the two cannot drift: the day a `$op` is added here, the\n * fake grows it in the same commit. Exporting it from the public index instead\n * would put a runtime-assembly detail on the author-facing API (FR-006).\n */\nexport function makeTypedSurface(raw: AtomicClient & Partial<Pick<DBClient, \"atomic\">>): EnvServiceDatabase {\n // Proxy dispatch her üyeyi taşır; RecoOps tipi DBClient'a eklenmediğinden\n // (yukarıdaki karar) similar/recommend erişimi bu daraltmadan geçer.\n const reco = raw as Omit<DBClient, \"asService\"> & RecoOps;\n // `$` ÖNEKİ AÇIKÇA YAZILIR, dinamik üretilmez.\n //\n // Bir tur `Object.fromEntries(Object.entries(ops).map(…))` ile üretilmişti ve\n // `database.test.ts`'in sayımı onu göremedi: sayım DEKLARASYONLARI okuyor,\n // string literal'leri değil. Görünmeyen bir yüzey denetlenemez — ve o testin\n // varlık sebebi tam olarak budur (FR-044: yüzeyde bağlantı bilgisi olmadığını\n // kanıtlamak, ama önce yüzeye gerçekten ULAŞTIĞINI kanıtlamak).\n const ops = {\n $query: (sql: string, params?: unknown[]) => raw.query(sql, params),\n $diagnostics: () => raw.diagnostics(),\n $insert: (table: string, data: Record<string, unknown>) => raw.insert(table, data),\n $update: (table: string, id: string, data: Record<string, unknown>) =>\n raw.update(table, id, data),\n $delete: (table: string, id: string) => raw.delete(table, id),\n $findById: (table: string, id: string) => raw.findById(table, id),\n $findUnique: (table: string, where: Record<string, unknown>, opts?: Parameters<DBOps[\"findUnique\"]>[2]) => raw.findUnique(table, where, opts),\n $page: (table: string, query?: Record<string, unknown>, opts?: import(\"./db/page.js\").RawPageOptions) => raw.page(table, query, opts),\n $findMany: (table: string, query?: Record<string, unknown>, opts?: Parameters<DBOps[\"findMany\"]>[2]) =>\n raw.findMany(table, query, opts),\n $put: (table: string, data: Record<string, unknown>, opts: { onConflict: readonly string[] }) =>\n raw.put(table, data, opts),\n // `opts` İLETİLİR. Düşürüldüğü sürece `Database.$updateMany(t, w, s,\n // { returning: false })` sessizce SATIRLARI döndürüyordu, sayıyı değil —\n // ve `if (n === 0) throw new Conflict(...)` guard'ı HİÇ çalışmıyordu,\n // çünkü `[] === 0` yanlıştır. Komşu forwarder'lar (`$findMany`, `$put`)\n // kendi opsiyonlarını zaten iletiyordu; bu biri unutulmuştu.\n $updateMany: (\n table: string,\n where: Record<string, unknown>,\n set: Record<string, unknown>,\n opts?: Parameters<DBOps[\"updateMany\"]>[3],\n ) => raw.updateMany(table, where, set, opts),\n $deleteMany: (table: string, where: Record<string, unknown>) => raw.deleteMany(table, where),\n $count: (table: string, where?: Record<string, unknown>) => raw.count(table, where),\n $search: (table: string, params?: Record<string, unknown>) => raw.search(table, params),\n $similar: (table: string, id: string, params?: Record<string, unknown>) =>\n reco.similar(table, id, params),\n $recommend: (table: string, params: Record<string, unknown>) => reco.recommend(table, params),\n $facets: (table: string, params: { facets: string[] } & Record<string, unknown>) => reco.facets(table, params),\n $claim: (table: string, unique: Record<string, unknown>, extra?: Record<string, unknown>) =>\n reco.claim(table, unique, extra),\n $lockRows: (table: string, ids: readonly string[]) => reco.lockRows(table, ids),\n $lockRowsWhere: (\n table: string,\n where: Record<string, unknown>,\n opts?: Parameters<DBOps[\"lockRowsWhere\"]>[2],\n ) => reco.lockRowsWhere(table, where, opts),\n $advisoryXactLock: (key: string) => reco.advisoryXactLock(key),\n $aggregate: (table: string, q: Parameters<DBOps[\"aggregate\"]>[1]) => raw.aggregate(table, q),\n $insertMany: ((\n table: string,\n rows: readonly Record<string, unknown>[],\n opts?: import(\"./db/bulk.js\").InsertManyOptions,\n ) => raw.insertMany(table, rows, opts)) as DBOps[\"insertMany\"],\n $supersede: (table: string, id: string, row: Record<string, unknown>) =>\n raw.supersede(table, id, row),\n } satisfies DollarOps<Omit<DBOps & RecoOps, \"attempt\">>;\n // `ops` DOĞRUDAN verilir, spread edilmez: sayım (`database.test.ts`) nesneyi\n // deklarasyonundan takip ediyor ve bir spread onu kaybettiriyor. Görünmeyen\n // yüzey denetlenemez.\n const base = Object.assign(ops as unknown as Record<string, unknown>, {\n $atomic<T>(fn: (tx: AtomicDatabase) => Promise<T>, options?: AtomicOptions): Promise<T> {\n if (typeof raw.atomic !== \"function\") {\n throw new Error(\"This Database handle cannot open a root transaction; nested $atomic is not supported\");\n }\n // ALS.run scopes only this callback and its continuations, never another\n // Promise.all branch. Calls made by ordinary services through Database\n // therefore share the callback's physical transaction and identity.\n const parent = __requestALS.getStore();\n let runtime: RuntimeServices | undefined;\n try { runtime = __getRuntime(); } catch { /* Direct typed engine handles need no ambient runtime. */ }\n return raw.atomic(async (tx) => {\n const typed = makeTypedSurface(tx);\n const invoke = () => fn(typed);\n if (!runtime) return invoke();\n const refuse = (): never => { throw new Error(\"Database.$atomic owns one transaction and identity; nested roots and $asService are not allowed\"); };\n const ambient = Object.assign({}, tx, { atomic: refuse, asService: refuse });\n return __requestALS.run({ ...parent, runtime: { ...runtime, Database: ambient } }, invoke);\n }, options);\n },\n // Both surfaces get it: a savepoint on the service transaction is as useful\n // as one on the request's, and each is bound to its own connection.\n $attempt: <T,>(fn: (tx: DBOps) => Promise<T>) => raw.attempt(fn),\n $transaction<T>(\n fn: (tx: TxPlan) => T extends Promise<unknown> ? never : T,\n opts?: { retry?: number },\n ): Promise<Materialized<T>> {\n // A FRESH builder per call: it holds this transaction's ops and its error\n // slot table, and the runtime serves concurrent requests on one event loop.\n // A shared builder would splice one request's writes into another's plan.\n //\n assertPlanRetry(opts);\n const builder = new TxPlanBuilder();\n return runTxPlan(raw, makeTxPlanHandle(builder), builder, fn) as Promise<Materialized<T>>;\n },\n $command<T>(fn: (tx: TxPlan) => T extends Promise<unknown> ? never : T, options?: import(\"./db/command.js\").CommandOptions): Promise<Materialized<T>> {\n const builder = new TxPlanBuilder();\n return runTxPlan({ txPlan: plan => raw.command(plan, options) }, makeTxPlanHandle(builder), builder, fn) as Promise<Materialized<T>>;\n },\n });\n // ŞEMA ERİŞİMİ BİR PROXY'DİR, çünkü hangi şemaların bildirildiğini yalnız TİP\n // bilir — runtime'da `Database.billing` diye bir üye yoktur, o ada dokunulduğu\n // anda üretilir. `$`'la başlamayan her ad bir ŞEMA adıdır; ayrım tam olarak\n // budur ve tip tarafındaki DollarOps ile aynı kuralı uygular.\n return new Proxy(base, {\n get(target, prop, receiver) {\n // `tables` DOĞRUDAN YÜZEYDE DE public'in takma adı.\n //\n // Plan tutamağı `tx.tables.todos`'u öğretiyor (göç notu da öyle), ama\n // `Database.public.todos` aynı kelimeyi ADI `tables` OLAN BİR ŞEMA sanıp\n // tele `tables.todos` yazıyordu. Tip onu reddettiği için derlenen kodda\n // erişilemezdi — ama `as any` ya da düz JS ile geçen biri sessizce\n // olmayan bir şemaya gidiyordu, ve iki yüzeyin aynı kelimeye zıt cevap\n // vermesi bu run'ın kapattığı sınıfın kendisi (gözcü M-6).\n if (prop === \"tables\") return makeTableProxy(() => reco, \"\");\n if (typeof prop === \"string\" && !prop.startsWith(\"$\") && !(prop in target)) {\n // Nitelikli tablo anahtarının kuralı BURADA TEKRARLANMAZ (FR-058): tek\n // yazıcı `qualifiedTableKey` ve `table-key-single-source.test.ts` ikinci\n // bir yazıcıyı reddediyor. Prefix ondan türetilir — boş tablo adıyla\n // çağrıldığında geriye ya \"\" (public) ya \"<şema>.\" kalır.\n return makeTableProxy(() => reco, qualifiedTableKey(prop, \"\"));\n }\n return Reflect.get(target, prop, receiver);\n },\n }) as unknown as EnvServiceDatabase;\n}\n\n/**\n * `makeTableProxy`'nin plan ikizi: `tables.<name>` yields the\n * table's PLAN operations, recorded into `builder` instead of sent one by one.\n *\n * Same Proxy shape and same reason for the single narrowing — TS cannot infer a\n * mapped type through a Proxy, so the cast names what the trap returns.\n */\nfunction makeTxTablesAccessor(builder: TxPlanBuilder, prefix = \"\"): TxTables {\n const tablesProxy = new Proxy(\n {},\n {\n get(_t, prop: string | symbol) {\n if (typeof prop !== \"string\") return undefined;\n return builder.table(prefix + prop);\n },\n },\n );\n return tablesProxy as TxTables;\n}\n\n/**\n * Plan tutamağı — `Database` ile AYNI şekil: `tx.public.x`, `tx.<şema>.x`, ve\n * geriye dönük `tx.tables.x`.\n *\n * Şema adı tablo adının ÖNÜNE geçiyor (`billing.invoices`), tıpkı doğrudan\n * yüzeyin `makeTypedSurface` proxy'sinin yaptığı gibi — ve motor artık onu\n * `quoteTable` ile İKİ parça hâlinde tırnaklıyor. Bu ikisi olmadan `billing`\n * şemasındaki iki tabloyu tek atomik planda yazmak imkânsızdı.\n *\n * `tables` ve `public` DIŞINDAKİ HER ad şema kabul edilir ve altındaki tablolar\n * `<ad>.<tablo>` diye adlanır. Yanlış bir şema adı TİPTE yakalanıyor\n * (`keyof Schemas`) — `tx.constructor.x` ve `tx.toString.x` dahil, ölçüldü.\n *\n * TİPTEN KAÇAN bir ad için savunma `quoteTable`'ın KAÇIŞIDIR, başka bir şey\n * değil: `runPlanOp` `op.table`'ı doğrulamadan ona veriyor ve `quoteTable`\n * tırnak ikizleyerek tek bir tanımlayıcı üretiyor. Ölçüldü: `a\"; DROP TABLE t; --`\n * → `\"a\"\"; DROP TABLE t; --\"`, yani enjeksiyon değil, `relation does not exist`.\n * (Bu yorum bir zamanlar `validateSchemaIdentifier`'a atıf yapıyordu — o\n * fonksiyon Go tarafında yaşıyor ve BU yolu hiç görmüyor; gözcü yakaladı.)\n */\nfunction makeTxPlanHandle(builder: TxPlanBuilder): TxPlan {\n const publicTables = makeTxTablesAccessor(builder);\n return new Proxy(\n {},\n {\n get(_t, prop: string | symbol) {\n if (typeof prop !== \"string\") return undefined;\n if (prop === \"tables\") return publicTables;\n // ÖNEK TEK YAZICIDAN (FR-058): `qualifiedTableKey`. Bu kuralı burada\n // elle yazmıştım — public'i çıplak bırakıp diğerine nokta ekleyen bir\n // if/return çifti — ve FR-058 kapısı onu GÖRMEDİ, çünkü kapı yalnız\n // ternary arıyordu. (Kural burada KELİMEYLE anlatılıyor, kod biçiminde\n // DEĞİL: kapı metni tarıyor ve bir yorumdaki kopya da onu tetikler.)\n // İkinci bir yazıcı, kapının var olma sebebi olan sınıfın kendisi:\n // `env-gen.ts`'in kendi kopyası bir public FK'yi başka bir şemanın\n // tablosuna etiketlemişti ve hiçbir şey bunu söylememişti.\n // Boş tablo adıyla çağrılınca geriye ya \"\" (public) ya \"<şema>.\" kalır.\n return makeTxTablesAccessor(builder, qualifiedTableKey(prop, \"\"));\n },\n },\n ) as TxPlan;\n}\n\n/**\n * The project's own Postgres (pgx, schema `env_<envId>`).\n *\n * Typed by default: `Database.public.<name>.insert({...})` is typed against\n * the project's generated `palbase-env.d.ts` with NO import and NO generic.\n * The raw string ops (`Database.$query`/`$insert`/`$update`/`$delete`/\n * `$findById`/`$findMany`) are also available for read-only SQL and for a table\n * name only known at runtime — which the typed surface cannot express past\n * seven tables (see `db/tx-union-key.test-d.ts`).\n *\n * RLS is enforced by default (the runtime runs each op as `authenticated` with\n * the verified user's claims). To bypass RLS, call `Database.$asService()` —\n * explicit and greppable — which runs as the `service_role` (BYPASSRLS).\n *\n * @example\n * import { Database } from \"@palbase/backend\";\n *\n * const todo = await Database.public.todos.insert({ title: req.input.title });\n * todo.id; // string ✓\n * const rows = await Database.$query(\"SELECT id FROM todos WHERE done = $1\", [false]);\n * const all = await Database.$asService().public.todos.findMany({}); // RLS bypass\n */\nexport const Database: EnvTypedDatabase = Object.assign(makeTypedSurface(rawDatabase), {\n /**\n * Lazily resolve the runtime's service-role sibling on each call. We do NOT\n * cache it: `rawDatabase.asService()` reads the CURRENT request scope through\n * the runtime proxy, and the per-request runtime injects a service client\n * bound to that request's identity headers — caching would leak one request's\n * sibling into another concurrent request.\n */\n $asService(): EnvServiceDatabase {\n return makeTypedSurface(rawDatabase.asService());\n },\n}) as unknown as EnvTypedDatabase;\n\n/** Firestore-like document client (PalDocs). */\nexport const Documents: PalbaseDocsClient = makeServiceProxy(\"Documents\");\n\n/**\n * `buckets.<name>` — the storage twin of `Database.public.<name>`, and the same\n * mechanism: `config/storage.ts` generates a `Buckets` augmentation into\n * `palbase-env.d.ts`, so a bucket name is a property with no import and no\n * generic, and a typo is a compile error.\n *\n * The intermediate `.buckets` is there for the reason `.tables` is: bucket\n * names must not share a namespace with the client's own methods, or the day\n * somebody declares a bucket called `bucket` the surface breaks.\n */\nexport type EnvBuckets = {\n [K in keyof Buckets]: TypedBucketClient<Buckets[K] extends BucketTypes ? Buckets[K] : BucketTypes>;\n};\n\n/** One bucket, with its declared variant names in the type. */\nexport interface TypedBucketClient<B extends BucketTypes> extends Omit<PalbaseBucketClient, \"getPublicUrl\"> {\n /** The public URL for the object, or for one of THIS bucket's declared\n * renditions. A name the bucket does not declare is a compile error. */\n getPublicUrl(path: string, options?: { variant?: B[\"variants\"] }): string;\n}\n\nfunction makeBucketsAccessor(storage: () => PalbaseStorageClient): EnvBuckets {\n return new Proxy(\n {},\n {\n get(_t, prop: string | symbol) {\n if (typeof prop !== \"string\") return undefined;\n return storage().bucket(prop);\n },\n },\n ) as EnvBuckets;\n}\n\nconst rawStorage: PalbaseStorageClient = makeServiceProxy(\"Storage\");\n\n/**\n * Object storage: buckets, objects, renditions and signed URLs.\n *\n * `Storage.buckets.posts.upload(...)` is the typed path. `Storage.bucket(name)`\n * remains for a name computed at runtime — rare, and it gives up the typing,\n * which is the honest trade rather than a second blessed way to do it.\n */\nexport const Storage: PalbaseStorageClient & { buckets: EnvBuckets } = Object.assign(\n {\n // FORWARDED explicitly, not assigned onto the service proxy.\n //\n // `Object.assign(rawStorage, {buckets})` writes onto the proxy's TARGET, and\n // the proxy's only trap is `get`, which forwards every read to the module\n // client — so the property landed somewhere nothing reads and\n // `Storage.buckets.docs` was `undefined` in a deployed handler. It\n // typechecked, every test passed, and the live call answered\n // \"TypeError: undefined is not an object\". `Database` never had the bug\n // because it builds a plain surface the same way this now does.\n bucket: (name: string) => rawStorage.bucket(name),\n },\n { buckets: makeBucketsAccessor(() => rawStorage) },\n);\n\n/** JSON-typed cache (get/set/incr/getOrSet). */\nexport const Cache: CacheClient = makeServiceProxy(\"Cache\");\n\n\n/**\n * This tenant's secrets — API keys, provider credentials, signing material the\n * BACKEND owns.\n *\n * `await Secrets.get(\"STRIPE_KEY\")` in a handler. There is no `.env` to read\n * and no file to mount: a secret is written through the vault's authenticated\n * API (or the CLI/MCP that calls it), and this is how the deployed code reads\n * it back. A name this tenant has not set answers null — as does every name\n * the STACK holds, because no route returns a platform secret's value at all.\n */\nexport const Secrets: SecretsService = makeServiceProxy(\"Secrets\");\n\n/**\n * Role assignment, as an operator — `Auth.assignRole(userId, \"agent\")`.\n *\n * The half of auth a SERVER owns. Signing in, MFA and device attestation are a\n * person acting on their own account and live on the client SDK; granting a\n * role is the tenant's product doing something to somebody else, which is\n * exactly what a handler is for. It writes with the service-role credential,\n * because an end user who could write their own assignment would make every\n * permission underneath it meaningless.\n *\n * The write is visible to the very next request: authority is read from the\n * table on each call, never carried on a token.\n */\nexport const Auth: PalbaseAuthAdminClient = makeServiceProxy(\"Auth\");\n\n/** Structured logger. */\nexport const Log: Logger = makeServiceProxy(\"Log\");\n\n/** Push / email / SMS / in-app notifications. */\nexport const Notifications: PalbaseNotificationsClient = makeServiceProxy(\"Notifications\");\n\n\n/**\n * The raw runtime Flags client for the current request scope. Carries the\n * default-surface reads + `setOverride` AND the runtime's `asService()` sibling\n * (the br-pod's `buildFlagsClient` returns both). The default `Flags` singleton\n * below forwards reads + `setOverride` through here; `Flags.$asService()`\n * forwards to this client's own `asService()`.\n */\nconst rawFlags: PalbaseFlagsClient = makeServiceProxy(\"Flags\");\n\n/**\n * Feature flags.\n *\n * Mirrors the `Database` / `Database.$asService()` model. The default surface is\n * RLS-equivalent for flags: reads resolve against the CURRENT request user and\n * `Flags.setOverride(key, value)` writes an override for that same signed-in\n * user (no userId argument, no admin power). Cross-user admin writes\n * (`setOverrideForUser`, …) live behind `Flags.$asService()` — explicit and\n * greppable, just like `Database.$asService()`.\n *\n * @example\n * import { Flags } from \"@palbase/backend\";\n *\n * if (await Flags.isEnabled(\"new_checkout\")) { ... } // current user\n * await Flags.setOverride(\"new_checkout\", true); // current user\n * await Flags.$asService().setOverrideForUser(\"u_9\", \"x\", true); // cross-user\n */\n/**\n * The ambient `Flags` singleton's own surface — NOT the raw client's.\n *\n * MEASURED, as a consumer, against the built tarball: annotating the singleton\n * as `PalbaseFlagsClient` ERASED the `$asService` that `Object.assign` adds, so\n * `Flags.$asService()` did not exist for anyone outside this package —\n *\n * TS2551: Property '$asService' does not exist on type 'PalbaseFlagsClient'.\n * Did you mean 'asService'?\n *\n * — while the only path that DID compile (`asService()`) throws by design. The\n * feature was written and unreachable, which is the defect class this surface\n * exists to remove.\n *\n * `Database` never had the problem because its singleton carries its OWN type\n * (`EnvTypedDatabase`) rather than the raw client's (`DBClient`). This is that,\n * for `Flags`. The raw `PalbaseFlagsClient.asService()` is untouched (FR-023) —\n * it is the seam this forwards to.\n */\nexport type PalbaseFlagsAmbient = Omit<PalbaseFlagsClient, \"asService\"> & {\n /** RLS'i aşan, kullanıcılar arası yazma yüzeyi. */\n $asService(): PalbaseFlagsServiceClient;\n /** 31.0.0 öncesinin adı — SESSİZCE çalışmaz, yerini söyleyerek fırlatır. */\n asService(): never;\n};\n\nexport const Flags: PalbaseFlagsAmbient = Object.assign(\n {\n isEnabled(\n flagName: PalbaseFlagKey,\n context?: PalbaseFlagContext,\n ): Promise<PalbaseResult<boolean>> {\n return rawFlags.isEnabled(flagName, context);\n },\n getVariant(\n flagName: PalbaseFlagKey,\n context?: PalbaseFlagContext,\n ): Promise<PalbaseResult<PalbaseFlagVariant>> {\n return rawFlags.getVariant(flagName, context);\n },\n getAll(context?: PalbaseFlagContext): Promise<PalbaseResult<PalbaseFlag[]>> {\n return rawFlags.getAll(context);\n },\n /**\n * Resolve a flag's value, with an optional fallback.\n *\n * FORWARDED as of 2026-08-15. This surface is written out by hand, method\n * by method, and `get` was missing from it — so the client implemented it,\n * thirty assertions covered it, and `Flags.get(\"x\")` was `undefined` in a\n * deployed handler. Exactly the shape of the `Storage.buckets` defect found\n * the same day: a hand-maintained forwarding list is a list somebody has to\n * remember to update.\n */\n get(\n flagName: PalbaseFlagKey,\n defaultOrContext?: PalbaseFlagValue | PalbaseFlagContext,\n maybeContext?: PalbaseFlagContext,\n ): Promise<PalbaseResult<PalbaseFlagValue>> {\n return rawFlags.get(flagName, defaultOrContext, maybeContext);\n },\n setOverride(\n key: PalbaseFlagKey,\n value: PalbaseFlagValue,\n ): Promise<PalbaseResult<PalbaseSetOverrideResult>> {\n return rawFlags.setOverride(key, value);\n },\n },\n {\n /**\n * Lazily resolve the runtime's cross-user sibling on each call. We do NOT\n * cache it: `rawFlags.asService()` reads the CURRENT request scope through\n * the runtime proxy, so caching would leak one request's sibling into\n * another concurrent request. Mirrors `Database.$asService()`.\n */\n $asService(): PalbaseFlagsServiceClient {\n return rawFlags.asService();\n },\n /**\n * The name this member carried before 32.0.0.\n *\n * It does NOT work silently. A retired member that quietly keeps returning\n * is how a rename becomes a mystery: the old call site goes on compiling,\n * the new name never spreads, and the two live side by side until somebody\n * greps for one and misses half the codebase. `Database` made this split\n * first (`$asService`), and this JSDoc promised \"exactly like\n * Database.$asService()\" while the promise went unkept.\n */\n asService(): never {\n throw new Error(\n \"Flags.asService() was renamed to Flags.$asService() in 32.0.0 — system members carry the `$` prefix, like Database.$asService().\",\n );\n },\n },\n);\n\n/**\n * The Realtime broadcast singleton for the current request scope. Backend-side\n * Realtime is BROADCAST-ONLY (a stateless handler can push but not subscribe —\n * `subscribe()` lives on the client SDK's `pb.realtime`). Fire-and-forget:\n * `broadcast` resolves once accepted (or with an `error`), never blocking the\n * handler on subscribers.\n *\n * @example\n * import { Realtime } from \"@palbase/backend\";\n *\n * await Realtime.broadcast(\"room:42\", \"message\", { text, from: user.id });\n */\nexport const Realtime: PalbaseRealtimeClient = makeServiceProxy(\"Realtime\");\n","/**\n * The refusals a Database call gets BEFORE any SQL exists — written once, so the\n * engine and the test double cannot disagree about them.\n *\n * WHY THIS FILE EXISTS. `fakeDatabase()` is a second implementation of the same\n * surface (`__tests__/helpers/mock-db.ts`), and it never touched `compileWhere`\n * or `asBindParams`. Measured against the published 24.1.0: all four of the\n * calls that release had just started refusing went through the fake SILENTLY —\n * `update{title:undefined}`, `insert{title:undefined}`, `findMany{done:{}}`,\n * `deleteMany{owner,created_at:{}}`.\n *\n * The scaffold tells authors to test the service layer against exactly that\n * fake. So a test went green on a call production would throw on, and the\n * author found out in production instead — the same \"the surface does not match\n * the engine\" shape these refusals exist to end, arriving through the door the\n * SDK hands people for testing.\n *\n * These are pure and SQL-free on purpose: an in-memory store can run them as\n * easily as the driver path can.\n */\n\n/**\n * İşaretçilerin MARKASI — `col()` ve `sqlFragment()` ürünlerini bu süreçte\n * üretilmiş olmakla tanımlar.\n *\n * NEDEN ŞEKİL DEĞİL DE MARKA (gözcü W2-A/C1 ve W2-B/C3, ikisi de ÖLÇTÜ):\n * şekil kontrolü, işaretçiyi güvenilmeyen bir istek gövdesinden UYDURULABİLİR\n * kılıyordu. Ölçülen iki sonuç:\n *\n * findMany(\"docs\", { owner_id: JSON.parse('{\"$col\":\"owner_id\"}') })\n * → WHERE true AND t.\"owner_id\" = t.\"owner_id\" ← kiracılık predikatı totoloji\n * findMany(\"todos\", JSON.parse('{\"$sql\":{\"text\":[\"1=1 -- pwned\"],\"values\":[]}}'))\n * → WHERE true AND 1=1 -- pwned ← saldırganın metni SQL'e HARFİYEN\n *\n * `{ where: { tenant_id: tid, ...req.body.filter } }` bu SDK'nın öğrettiği\n * desen; T010/T014 öncesinde aynı anahtarlar \"bilinmeyen operatör\" diye\n * REDDEDİLİYORDU. Marka o reddi geri getiriyor.\n *\n * Sembol GLOBAL kayıttan (`Symbol.for`) ve ENUMERABLE DEĞİL. İkisi de kasıtlı:\n * global kayıt paketin iki kopyası arasında da eşleşir; enumerable olmaması ise\n * `JSON.stringify` ve `{...ref, gt: 5}` yayılımının markayı DÜŞÜRMESİNİ sağlar —\n * yani telden geçen ya da elle karıştırılan hiçbir şey işaretçi sayılmaz.\n * Kardeş özellik (`increment`) zaten `Symbol.for(\"palbase.tx.expr\")` kullanıyor;\n * bu onun aynısı.\n */\nconst REF_BRAND = Symbol.for(\"palbase.db.ref\");\n\n/** İşaretçiyi markalar. Yalnız `col()` ve `sqlFragment()` çağırır. */\nexport function brandRef<T extends object>(v: T, kind: \"col\" | \"sql\" | \"ref\"): T {\n Object.defineProperty(v, REF_BRAND, { value: kind, enumerable: false });\n return v;\n}\n\nfunction brandOf(v: unknown): unknown {\n if (typeof v !== \"object\" || v === null) return undefined;\n // KENDİ özelliği olmalı, prototip zincirinden MİRAS ALINMIŞ değil:\n // `Object.create(col(\"x\"))` markayı zincirden okuyup işaretçi sayılıyordu\n // (gözcü ölçtü). Telden erişilemez — JSON `__proto__` üstünden sembol\n // yazamaz — ama daraltmak bedava ve \"işaretçi bu süreçte ÜRETİLDİ\"\n // iddiasının tam karşılığı budur.\n return Object.hasOwn(v, REF_BRAND) ? (v as Record<symbol, unknown>)[REF_BRAND] : undefined;\n}\n\n/**\n * Bir değer, MARKASIZ bir işaretçi taklidi mi? (`{$col:…}` / `{$sql:…}`)\n *\n * Üst düzeyde bunlar zaten \"bilinmeyen operatör\" diye reddediliyor. Ama\n * operatörün SAĞINDA — `{ amount: { gt: {\"$col\":\"other\"} } }` — sessizce\n * PARAMETRE olarak bağlanıyorlardı: sayısal kolonda sürücünün 22P02'si,\n * jsonb/text kolonunda ise HİÇBİR SATIR, hatasız (gözcü ölçtü).\n *\n * `in` listesindeki aynı kusur adıyla reddediliyor; bu onun bir seviye\n * yanındaki hâli ve aynı cevabı hak ediyor.\n */\nexport function looksLikeUnbrandedRef(v: unknown): \"col\" | \"sql\" | \"expr\" | null {\n if (typeof v !== \"object\" || v === null) return null;\n if (brandOf(v) !== undefined) return null; // gerçek işaretçi\n if (isColumnExpr(v)) return null; // gerçek ifade tutamağı (kendi markası var)\n const o = v as { $col?: unknown; $sql?: unknown; $expr?: unknown };\n if (typeof o.$col === \"string\") return \"col\";\n if (o.$sql !== undefined && typeof o.$sql === \"object\" && o.$sql !== null) return \"sql\";\n // `$expr` `now()`/`increment()`'in TEL BİÇİMİ. `now()` filtrede geçerli bir\n // değer olduğu andan itibaren bu şekil de uydurulabilir hâle geldi: ÖLÇÜLDÜ,\n // gövdeden gelen `{\"$expr\":{\"fn\":\"now\"}}` sessizce PARAMETRE olarak bağlanıp\n // sorguyu hatasız biçimde boş sonuca çeviriyordu. `$col`/`$sql`/`$ref` ile\n // aynı kapı, aynı gerekçe.\n if (o.$expr !== undefined && typeof o.$expr === \"object\" && o.$expr !== null) return \"expr\";\n return null;\n}\n\n/**\n * `col()` ürünü mü? (FR-011)\n *\n * Burada, çünkü bu dosya \"iki uygulamanın da okuduğu kurallar\" dosyası: motor,\n * `fakeDatabase` ve guard AYNI cevabı vermek zorunda.\n */\nexport function isColRef(v: unknown): v is { readonly $col: string } {\n return brandOf(v) === \"col\" && typeof (v as { $col?: unknown }).$col === \"string\";\n}\n\n/**\n * `sqlFragment` ürünü mü? (FR-018)\n *\n * `isColRef` ile aynı gerekçeyle burada: motor, guard ve `fakeDatabase` üçü de\n * aynı cevabı vermek zorunda — biri fragment'i \"kolon haritası\" sanarsa filtre\n * sessizce düşer.\n */\n/**\n * Plan REFERANSI mı? (`{ $ref: { op, field } }`)\n *\n * `$ref` bu dilin MARKASIZ KALAN TEK işaretçisiydi — `engine/db.ts` onu\n * `\"$ref\" in v` diye tanıyordu — ve SDK'nın öğrettiği desen\n * `{ where: { tenant_id: tid, ...req.body.filter } }`. Ölçüldü (gözcü):\n * istek gövdesinden gelen `{\"id\":{\"$ref\":{\"op\":0,\"field\":\"id\"}}}` filtreyi\n * ÖNCEKİ bir işlemin satır değeriyle karşılaştırtıyor —\n * DELETE … WHERE t.\"tenant_id\" = $1 AND t.\"id\" = $2 PRM [\"t1\",\"SIZAN_DEGER\"]\n * gövdenin hiç görmediği bir değer. Enjeksiyon değil (değerler bound) ama bir\n * ORACLE: `op`/`field` seçip `rows_affected`'tan o değeri öğrenmek.\n *\n * Marka `Symbol.for` olduğu için SDK'nın İKİ KOPYASI arasında da eşleşiyor —\n * kontrolcü bundle'ı kendi kopyasını inline ediyor, planı çalıştıran ise\n * runtime'ınki. Ve plan gövdesi JSON'lanmıyor: tek üretim `txPlan` uygulaması\n * süreç içi (`engine/db.ts`), doğrulandı.\n */\nexport function isPlanRef(v: unknown): v is { readonly $ref: { op: number; field: string } } {\n if (brandOf(v) !== \"ref\") return false;\n const r = (v as { $ref?: { op?: unknown; field?: unknown } }).$ref;\n return r !== undefined && typeof r.op === \"number\" && typeof r.field === \"string\";\n}\n\n/** Markasız bir `{ $ref: … }` taklidi mi? Adıyla reddedilmesi için. */\nexport function looksLikeUnbrandedPlanRef(v: unknown): boolean {\n if (typeof v !== \"object\" || v === null || brandOf(v) !== undefined) return false;\n const r = (v as { $ref?: unknown }).$ref;\n return r !== undefined && typeof r === \"object\" && r !== null;\n}\n\nexport function isSqlFragment(v: unknown): v is { readonly $sql: { text: string[]; values: unknown[] } } {\n if (brandOf(v) !== \"sql\") return false;\n const f = (v as { $sql?: { text?: unknown; values?: unknown } }).$sql;\n return f !== undefined && Array.isArray(f.text) && Array.isArray(f.values);\n}\n\n/**\n * İFADE TUTAMAĞI DEĞER DEĞİLDİR — değer bekleyen yollarda adıyla reddedilir.\n *\n * `increment()` / `decrement()` / `now()` bir Proxy döndürür ve yalnız\n * `updateMany` ile plan yolunun `updateWhere`'i onu SQL'e derler. `insert` /\n * `update` / `put` / `supersede` derlemez; oralarda tutamak bound parametre\n * olarak sürücüye gidiyordu ve reddi SÜRÜCÜ veriyordu (\"Unknown object is not\n * a valid PostgreSQL type\") — yazarın yazdığı hiçbir şeyi adlandırmayan bir\n * mesaj (inceleme I-2/I8, ölçüldü). Plan yolu aynı hatayı kendi diliyle\n * reddediyor; bu, doğrudan yolun karşılığı.\n *\n * Sembol `tx-plan.ts`'in markasıyla AYNI global kayıttan okunuyor; bu dosya\n * kural dosyası olduğu için oraya bağımlılık kurmuyor.\n */\nconst TX_EXPR = Symbol.for(\"palbase.tx.expr\");\n\n/**\n * `now()` — SUNUCU SAATİ, karşılaştırma değeri olarak.\n *\n * `increment()`/`decrement()` bir YAZMA ifadesidir ve filtrede anlamsızdır;\n * `now()` öyle değil: `expires_at > now()` sıradan bir karşılaştırma ve her\n * backend'in en sık yazdığı yüklemlerden biri. Filtrede TÜM ifade tutamaklarını\n * reddetmek, yazarı bunun için `sqlFragment`e düşürüyordu — yani sorgunun\n * içine giren parça, en sıradan koşul için gerekiyordu.\n *\n * Ayrım MARKAYLA: bir istek gövdesinden gelen `{\"$expr\":{\"fn\":\"now\"}}` bu\n * süreçte `now()` ile üretilmediği için marka taşımaz ve reddedilir.\n */\nexport function isNowExpr(v: unknown): boolean {\n if (!isColumnExpr(v)) return false;\n try {\n const e = (v as Record<symbol, unknown>)[TX_EXPR];\n return typeof e === \"object\" && e !== null && (e as { fn?: unknown }).fn === \"now\";\n } catch {\n return false;\n }\n}\n\nexport function isColumnExpr(v: unknown): boolean {\n if (typeof v !== \"object\" && typeof v !== \"function\") return false;\n if (v === null) return false;\n try {\n return (v as Record<symbol, unknown>)[TX_EXPR] !== undefined;\n } catch {\n // Tutamak bir Proxy; bilinmeyen bir prop'ta trap fırlatabilir.\n return false;\n }\n}\n\n/**\n * Değer bekleyen bir yazma yolunda ifade tutamağı ya da `col()` var mı?\n *\n * Motor ve `fakeDatabase` AYNI cevabı vermek zorunda: fake tutamağı satıra\n * YAZIYORDU (`row[k] = proxy`) ve satır artık JSON'a bile çevrilemiyordu, motor\n * ise sürücüde patlıyordu. İki farklı yanlış, tek doğru.\n */\nexport function assertNoExpressionHandles(\n caller: string,\n table: string,\n cols: readonly string[],\n data: Record<string, unknown>,\n): void {\n for (const c of cols) {\n const v = data[c];\n // `now()` ile sayaç ifadeleri AYRI cevaplar hak ediyor: ikisinin de\n // çalışan alternatifi var ama farklı (P6 — hata çalışan bir alternatifi\n // ADIYLA söyler). Tek bir \"ifade tutamağı\" mesajı, `now()` yazan kişiye\n // `increment()` öneriyordu.\n if (isNowExpr(v)) {\n throw new Error(\n `${caller}(${table}): \"${c}\" now() aldı — bu yolda değer beklenir. ` +\n `Satır EKLENİRKEN sunucu saatini yazmanın yolu kolonu defaultNow() ile ` +\n `bildirmek (varsayılan kolonun yanında durur, her çağrıda tekrarlanmaz); ` +\n `var olan bir satırı damgalamak için updateMany({ where, set: { ${c}: now() } }) ` +\n `ya da $transaction içinde tx.public.${table}.updateWhere(where, { ${c}: now() }).`,\n );\n }\n if (isColumnExpr(v)) {\n throw new Error(\n `${caller}(${table}): \"${c}\" bir ifade tutamağı aldı (increment()/decrement()). ` +\n `Bu yolda değer beklenir. Sayaç artışı için updateMany({ where, set: { ${c}: increment(n) } }) ` +\n `ya da $transaction içinde tx.public.${table}.updateWhere(where, { ${c}: increment(n) }) kullanın.`,\n );\n }\n if (isColRef(v)) {\n throw new Error(\n `${caller}(${table}): \"${c}\" bir col() aldı. Kolon referansı yalnız FİLTREDE durabilir; ` +\n `bir kolonun değerini başka bir kolona yazmak için $query kullanın.`,\n );\n }\n }\n}\n\n/** The comparison operators a filter value may carry. Kept here because the\n * guard has to tell an operator object from a plain value. */\nconst KNOWN_OPS = new Set([\n \"gt\", \"gte\", \"lt\", \"lte\", \"neq\", \"in\",\n // K1 metin operatörleri (FR-005) ve null testi (FR-006). Bu küme\n // `fakeDatabase()` ile ORTAK kaynaktır: fake bir çağrıyı motorun reddettiği\n // yerde kabul ederse, yazarın testi üretimde patlayan koda karşı yeşil verir.\n \"contains\", \"icontains\", \"startsWith\", \"endsWith\", \"isNull\",\n]);\n\n/**\n * `eq` ADIYLA reddedilir, ve reddi buradadır çünkü guard'ı motor da fake de\n * okuyor.\n *\n * Eşitliğin yazımı ÇIPLAK DEĞERDİR: `{ owner: \"u1\" }`. `eq`'i ikinci bir yazım\n * olarak eklemek, bu run'ın kapatmak için var olduğu şeyi — aynı iş için iki\n * uyumsuz yazım — filtre dilinin İÇİNDE yeniden açardı. Ve eskiden kabul eden\n * ile reddeden ayrışıyordu: guard `eq`'i geçiriyor, derleyici\n * `bilinmeyen operatör \"eq\"` diyordu (gözcü ölçtü).\n */\nconst REFUSED_OPS: Record<string, string> = {\n eq: 'eşitlik ÇIPLAK yazılır: { <kolon>: <değer> } (ya da kolon karşılaştırması için { <kolon>: col(\"…\") })',\n};\n\n/**\n * Refuse a filter that would compile to something other than what it reads like.\n *\n * Three shapes, each measured in production before it was closed:\n *\n * `{ col: undefined }` binds NULL; `= NULL` matches no row, so the query\n * answered \"no records\" and said nothing.\n * `{ col: {} }` produces no term at all — every row on the read\n * path, a dropped condition on the write path.\n * `{ col: { gte: undefined } }` and an `undefined` inside `in`: the same NULL,\n * one level down.\n */\nexport function assertUsableFilter(\n caller: string,\n table: string,\n where: Record<string, unknown> | undefined,\n): void {\n // Bileşim anahtarları (FR-007) bir KOLON adı değildir; kolon doğrulamasından\n // ve operatör kontrolünden muaftır, kendi dalları özyinelemeli olarak aynı\n // kurallardan geçer.\n const COMPOSITES = new Set([\"OR\", \"AND\", \"NOT\"]);\n\n if (!where) return;\n // Fragment bir kolon haritası DEĞİLDİR (FR-018): içeriği SQL'dir, kolon\n // doğrulaması ona uygulanamaz. Değerleri zaten bound gidiyor.\n if (isSqlFragment(where)) return;\n for (const [col, cond] of Object.entries(where)) {\n // Bileşim anahtarları (FR-007) kolon DEĞİLDİR: dalları aynı kurallardan\n // özyinelemeli geçer, ama kendileri operatör kontrolüne girmez.\n if (COMPOSITES.has(col)) {\n const branches = col === \"NOT\" ? [cond] : cond;\n if (!Array.isArray(branches) && col !== \"NOT\") {\n throw new Error(`${caller}(${table}): where.${col} bir dizi olmalı`);\n }\n for (const b of branches as unknown[]) {\n if (b === null || typeof b !== \"object\") {\n throw new Error(`${caller}(${table}): where.${col} dalları filtre nesnesi olmalı`);\n }\n assertUsableFilter(caller, table, b as Record<string, unknown>);\n }\n continue;\n }\n // `has` de kolon DEĞİLDİR: anahtarları İLİŞKİ adları, değerleri BİR TABLO\n // ÖTESİNİN filtresi. İç filtre aynı kurallardan geçiyor — `has` ikinci bir\n // filtre dili değil, aynı dilin bir tablo ötesi.\n //\n // İlişki ADI burada doğrulanMIYOR: grafiği yalnız motor tanıyor (ve tip,\n // derleme anında). Guard'ın onu bilmesi ilişki grafiğinin İKİNCİ bir\n // yorumcusu demekti — `buildRelations`'ın yorumunun adıyla yasakladığı şey.\n if (col === \"has\") {\n if (cond === null || typeof cond !== \"object\" || Array.isArray(cond)) {\n throw new Error(`${caller}(${table}): where.has bir ilişki haritası olmalı ({ <ilişki>: { … } })`);\n }\n for (const [rel, inner] of Object.entries(cond as Record<string, unknown>)) {\n if (inner === null || typeof inner !== \"object\" || Array.isArray(inner)) {\n throw new Error(`${caller}(${table}): where.has.${rel} bir filtre nesnesi olmalı`);\n }\n assertUsableFilter(caller, table, inner as Record<string, unknown>);\n }\n continue;\n }\n if (cond === undefined) {\n throw new Error(\n `${caller}(${table}): where.${col} değeri undefined — bu bir filtre değeri değil. ` +\n `Bağlanınca NULL olur ve '= NULL' hiçbir satıra uymaz, yani sorgu sessizce ` +\n `boş sonuç dönerdi. Değer yoksa anahtarı filtreye hiç koymayın.`,\n );\n }\n if (cond === null || typeof cond !== \"object\" || Array.isArray(cond)) continue;\n // `col()` ürünü bir DEĞER'dir, operatör nesnesi değil (FR-011). Ayırt\n // edilmezse `{ $col: \"x\" }` bir operatör haritası sanılır ve \"bilinmeyen\n // operatör $col\" diye reddedilirdi.\n if (isColRef(cond)) continue;\n // `now()` de bir DEĞER'dir, aynı gerekçeyle — ve tutamak bir Proxy olduğu\n // için `Object.entries` BOŞ döner: ayırt edilmezse \"boş operatör nesnesi\"\n // diye reddedilirdi, yani doğru yazım yanlış bir hatayla karşılanırdı.\n if (isNowExpr(cond)) continue;\n\n const entries = Object.entries(cond as Record<string, unknown>);\n if (entries.length === 0) {\n throw new Error(\n `${caller}(${table}): where.${col} boş bir operatör nesnesi ({}) — hiçbir koşul ` +\n `üretmez, yani bu alan filtreden sessizce DÜŞERDİ. Koşul kurulmayacaksa ` +\n `anahtarı filtreye hiç koymayın (D-21).`,\n );\n }\n for (const [op, v] of entries) {\n if (op === \"in\") {\n if (!Array.isArray(v)) throw new Error(`${caller}(${table}): where.${col}.in bir dizi olmalı`);\n if (v.some((x) => x === undefined)) {\n throw new Error(\n `${caller}(${table}): where.${col}.in listesinde undefined var — sessizce NULL'a ` +\n `bağlanır ve o eleman hiçbir satırla eşleşmez. Listeyi kurarken eleyin.`,\n );\n }\n continue;\n }\n // Sağ tarafta kolon durabilir: `{ total: { gt: col(\"amount_paid\") } }`.\n // Değer kontrolleri (undefined) ona da uygulanır, ama `in` gibi şekil\n // kontrolleri değil — o dal aşağıda zaten ayrı.\n if (REFUSED_OPS[op] !== undefined) {\n // Bilinmeyen değil — BİLİNEREK reddedilen. Hata çalışan yazımı söylüyor.\n throw new Error(`${caller}(${table}): where.${col}.${op} bu filtre dilinde yok — ${REFUSED_OPS[op]}`);\n }\n if (!KNOWN_OPS.has(op)) {\n throw new Error(\n `${caller}(${table}): where.${col} bilinmeyen operatör \"${op}\" (gt/gte/lt/lte/neq/in/contains/icontains/startsWith/endsWith/isNull)`,\n );\n }\n if (v === undefined) {\n throw new Error(\n `${caller}(${table}): where.${col}.${op} değeri undefined — karşılaştırmanın ` +\n `sağ tarafı NULL olur ve sonuç hiçbir satıra uymaz. Koşulu kurmayın.`,\n );\n }\n }\n }\n}\n\n/**\n * Refuse a write whose value never arrived.\n *\n * `{ title: req.body.title }` with no `title` in the body bound NULL and\n * answered 200 — the column was ERASED. `null` is untouched, and the difference\n * is the whole point: null is an author SAYING \"empty this column\"; undefined is\n * nobody saying anything.\n */\nexport function assertUsableWriteValues(\n caller: string,\n table: string,\n cols: readonly string[],\n data: Record<string, unknown>,\n): void {\n for (const c of cols) {\n if (data[c] === undefined) {\n throw new Error(\n `${caller}(${table}): \"${c}\" değeri undefined — bu bir yazma değeri değil. ` +\n `Kolonu boşaltmak istiyorsan null yaz; kolonu değiştirmek istemiyorsan nesneye hiç koyma ` +\n `(bir eksik istek alanı sessizce NULL yazıyordu — FR-016).`,\n );\n }\n }\n}\n","/**\n * tx-plan.ts — `Database.$transaction()` as a PLAN, not a pinned session.\n *\n * A transaction used to be a conversation: BEGIN, then one network round trip\n * per operation, then COMMIT. Each of those round trips cost ~4 ms and, because\n * the pooler runs in transaction mode, an open transaction pinned a Postgres\n * backend for the whole conversation. A 121-operation statement upload pinned\n * one backend for ~490 ms.\n *\n * So the callback no longer TALKS to the database. It DESCRIBES what should\n * happen; the description is serialised and sent once; the broker runs the whole\n * thing inside one transaction and answers once. Committing on return and\n * rolling back on throw is unchanged — that is the only property tenant code\n * actually asked for.\n *\n * The consequences, stated plainly, because they are the whole design:\n *\n * - The callback is SYNCHRONOUS. There is nothing to await: no statement has\n * run yet when it returns. `async` on the callback and `await` inside it are\n * both compile errors (see {@link TxPlan} and {@link NotAwaitable}).\n * - `insert()` does not hand back a row, it hands back {@link TxRows}. Reading\n * a field requires `.expectOne(err)` first, which makes \"what if the row\n * isn't there\" a question you cannot route around: it is the argument.\n * - A field read from a row is a {@link Ref} — a PROMISE OF A VALUE THE SERVER\n * WILL PRODUCE, not the value. It can be written into a later operation and\n * it can be returned from the callback (it is substituted for the real value\n * before `transaction()` resolves). It cannot be branched on. See the\n * \"Truthiness\" note below — this is the sharp edge of the whole design.\n * - Control flow that needs a real value must move OUT of the callback: read\n * before the transaction, or express the condition as a guard\n * (`updateWhere({ id, accepted_at: null }, …).expectOne(new Conflict(…))`)\n * which the server evaluates and which rolls the whole plan back.\n *\n * # Truthiness — the hole this file CANNOT close\n *\n * JavaScript does not let a Proxy trap truthiness. `if (ref)` takes the true\n * branch, always, for every Ref, and no `get` handler ever runs. `tsc` is silent\n * because a Ref is a perfectly good object. So:\n *\n * const pot = tx.tables.pots.select({ id }, { limit: 1 }).expectOne(e);\n * if (!pot.balance) { … } // ← ALWAYS false. Silently wrong data.\n *\n * What this file does close: coercion (`Symbol.toPrimitive`/`valueOf`/\n * `toString`), awaiting (`then` is a callable member with a non-thenable\n * signature, which is a *compile* error), serialisation (`toJSON`), and nesting\n * a Ref inside a literal value where the server would store it as data. What it\n * cannot close is a bare truthiness test. The real defence is the build-time\n * static analysis (`tx_analysis.js`, phase P4); until that ships, this hole is\n * open and this comment is the only warning.\n *\n * # Wire contract\n *\n * The JSON this file emits is consumed by\n * the plan executor in `engine/db.ts`. That executor rejects\n * unknown fields at every level, so an op carries EXACTLY the fields its kind\n * takes. Everything here that looks like a needless restriction is one of the\n * server's rules made visible early:\n *\n * - `$ref` only points BACKWARDS, and only at an op statically known to yield\n * at most one row (insert, or a `one`/`atMost 1` guard, or `select limit 1`).\n * `.expectOne()` is what this file uses to satisfy that, always.\n * - `$expr` is a closed set: `inc`/`dec` (update only — they read the column's\n * current value) and `now()`.\n * - `update`/`delete` require a `where`; `insert` refuses one.\n * - `insertMany` rows must all set the same columns.\n * - ≤1000 ops, ≤5000 rows per insertMany, ≤8 MiB of JSON.\n *\n * Column keys are emitted SORTED, so the same callback always produces byte-\n * identical JSON. That is what lets the Go decoder be locked to golden files\n * this SDK emits (`testdata/tx_plan_golden/`).\n */\n\n// ---------------------------------------------------------------------------\n// Errors\n// ---------------------------------------------------------------------------\n\n/**\n * A plan handle was used as if it were a value: awaited, coerced to a string or\n * number, serialised, or nested inside another value.\n *\n * Thrown while the callback is still BUILDING the plan, so nothing has been sent\n * and nothing has been written.\n */\n// TİP-ONLY, ve döngü kasıtlı: `typed-db.ts` bu dosyadan tip alıyor, bu dosya\n// ondan `WhereOp` alıyor. Çalışma zamanında hiçbir şey ithal edilmiyor (import\n// type), yani modül döngüsü yok — paylaşılan olan şey TEK FİLTRE DİLİ, ve onu\n// iki yerde ayrı ayrı tanımlamak bu run'ın kapattığı \"iki yazım\"ın tipteki\n// hâli olurdu.\nimport type { WhereOpWith, ColRefOf, HasOnly, SqlFragment } from \"./typed-db.js\";\nimport { isColRef, isSqlFragment, brandRef, isNowExpr } from \"./input-guards.js\";\n\nexport class TxRefError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"TxRefError\";\n }\n}\n\n/**\n * The plan the callback described cannot be sent: it breaks a rule the server\n * would reject, and rejecting it here names the line that wrote it instead of\n * returning a 400 about an op index.\n */\nexport class TxPlanError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"TxPlanError\";\n }\n}\n\n// ---------------------------------------------------------------------------\n// Wire types — mirror the plan executor in `engine/db.ts` exactly.\n// ---------------------------------------------------------------------------\n\n/** A backwards reference to an earlier op's single-row result. */\nexport interface TxWireRef {\n $ref: { op: number; field: string };\n}\n\n/** A call from the server's closed function set. */\nexport interface TxWireExpr {\n $expr: { fn: \"inc\" | \"dec\"; by: number | string } | { fn: \"now\" };\n}\n\n/** One value in a `values`/`set`/`where` map: a literal, a `$ref` or a `$expr`. */\nexport type TxWireValue = TxWireRef | TxWireExpr | unknown;\n\n/** The tenant's declared expectation about an op's row count. `slot` indexes the\n * client-side error table — the error OBJECT never travels. */\nexport interface TxWireGuard {\n kind: \"one\" | \"none\" | \"atLeast\" | \"atMost\";\n n: number;\n slot: number;\n}\n\n/** One operation in the wire plan. Fields are omitted, never null: the decoder\n * rejects a field that does not belong to the op's kind. */\nexport interface TxWireOp {\n /** upsert and insertMany: the columns Postgres matches on. */\n onConflict?: readonly string[];\n /** insertMany only: what a collision does. Absent means no ON CONFLICT clause\n * at all, which is what every insertMany did before this option existed. */\n action?: \"ignore\" | \"update\";\n op: \"insert\" | \"insertMany\" | \"upsert\" | \"update\" | \"delete\" | \"select\";\n table: string;\n values?: Record<string, TxWireValue>;\n rows?: Record<string, TxWireValue>[];\n set?: Record<string, TxWireValue>;\n where?: Record<string, TxWireValue>;\n limit?: number;\n lock?: \"update\";\n guard?: TxWireGuard;\n}\n\n/** The plan the engine executes on the request's own transaction. */\nexport interface TxPlanBody {\n ops: TxWireOp[];\n}\n\n/** One op's outcome, positionally matched to the plan's ops. */\nexport interface TxPlanOpResult {\n rows: Record<string, unknown>[];\n rows_affected: number;\n}\n\n/** One result per op, in plan order. */\nexport interface TxPlanResponse {\n results: TxPlanOpResult[];\n}\n\n/**\n * The fields the runtime must copy from the broker's error envelope onto the\n * rejection it throws out of {@link DBClient.txPlan}.\n *\n * `slot` is the whole point: on a guard failure the server answers with the\n * INDEX of the expectation that did not hold, never with an error message of its\n * own, and this SDK maps that index back to the `Error` the callback handed to\n * `.expectOne(…)`. Without `slot` a guard failure degrades to a generic 409.\n */\nexport interface TxPlanRejection {\n status?: number;\n /** `tx_plan_invalid` | `tx_guard_failed` | `tx_ref_unresolved` | a pg class. */\n error_code?: string;\n /** Present only for `tx_guard_failed`: the client-side error table index. */\n slot?: number;\n /** Present on a database error: which op failed. */\n op?: number;\n}\n\n// ---------------------------------------------------------------------------\n// Handle types\n// ---------------------------------------------------------------------------\n\ndeclare const refBrand: unique symbol;\ndeclare const rowBrand: unique symbol;\ndeclare const rowsBrand: unique symbol;\n\n/**\n * Makes a handle a compile error to `await`.\n *\n * `then` is declared as a CALLABLE member whose signature is not `PromiseLike`,\n * which is precisely the shape TypeScript rejects: `await handle` is TS1320 and\n * `async () => handle` is TS1058. A non-callable `then` would not do it — the\n * compiler simply ignores those.\n */\nexport interface NotAwaitable {\n /** Not a promise. Nothing here has run yet; there is nothing to await. */\n then(doNotAwaitAPlanHandle: \"a transaction plan is built synchronously\"): never;\n}\n\n/**\n * A value the SERVER will produce, standing in for a column of a row this plan\n * writes or reads.\n *\n * Legal uses: write it into a later operation's `values`/`set`/`where`, or\n * return it from the callback (it is replaced by the real value before\n * `transaction()` resolves).\n *\n * Illegal, and caught: `await`, `String(ref)`, `` `${ref}` ``, `ref + 1`,\n * `JSON.stringify(ref)`, burying it inside a jsonb object.\n *\n * Illegal, and NOT caught: `if (ref)`. See the truthiness note at the top.\n */\nexport interface Ref<T> extends NotAwaitable {\n readonly [refBrand]: T;\n}\n\n/** The brand carried by a single-row handle, and the seam `Materialized` reads\n * to turn `return st` into the whole row. */\nexport interface TxRowHandle<Row> extends NotAwaitable {\n readonly [rowBrand]: Row;\n}\n\n/**\n * A row this plan is known to produce exactly one of. Every property is a\n * {@link Ref}; returning the handle itself yields the whole row.\n *\n * Only `.expectOne(err)` produces one — which is the design: a row you can read\n * fields from is a row whose absence you have already answered for.\n */\nexport type TxRow<Row> = { readonly [K in keyof Row]: Ref<Row[K]> } & TxRowHandle<Row>;\n\n/**\n * The result of one operation, before any expectation is declared about it.\n *\n * Deliberately not a row and not a list: an operation's row count is not known\n * until the server runs it, so the only thing that can be said about it here is\n * an EXPECTATION. Declaring one is also the only way to get a readable row.\n *\n * At most one expectation per operation — the wire carries one guard per op, and\n * a second call throws rather than silently dropping the first.\n */\nexport interface TxRows<Row> extends NotAwaitable {\n readonly [rowsBrand]: Row;\n /**\n * Require exactly one row, and read it. On any other count the server rolls\n * the whole transaction back and this `error` is thrown to the caller.\n *\n * This is the only way to reach a row's fields, and the only shape a `$ref`\n * may point at.\n */\n expectOne(error: Error): TxRow<Row>;\n /** Require zero rows (e.g. \"this membership must not already exist\"). */\n expectNone(error: Error): void;\n /** Require at least `n` rows. */\n expectAtLeast(n: number, error: Error): void;\n /** Require at most `n` rows. */\n expectAtMost(n: number, error: Error): void;\n}\n\n/** `now()` — the server's clock, usable wherever a value is. */\nexport interface TxNow extends NotAwaitable {\n readonly $expr: { fn: \"now\" };\n}\n\n/** `inc(n)` / `dec(n)` — read the column's CURRENT value and write it back\n * changed. Only meaningful in an update's `set`, which is where the types allow\n * it and where the server allows it. */\nexport interface TxColumnExpr extends NotAwaitable {\n readonly $expr: { fn: \"inc\" | \"dec\"; by: number | string };\n}\n\n/**\n * Resolve a callback's return type against what actually comes back: every\n * {@link Ref} becomes its value, every {@link TxRow} becomes its row, and\n * anything else keeps its shape.\n *\n * A {@link TxRows} resolves to an explanatory string type rather than a row\n * list: it has no single answer to give, and saying so in the type is louder\n * than a runtime throw.\n */\nexport type Materialized<T> = T extends Ref<infer U>\n ? U\n : T extends TxRowHandle<infer R>\n ? R\n : T extends TxRows<unknown>\n ? \"a TxRows cannot leave the transaction callback — read a row with .expectOne(err) first\"\n : T extends Date\n ? T\n : T extends object\n ? { [K in keyof T]: Materialized<T[K]> }\n : T;\n\n// ---------------------------------------------------------------------------\n// Author-facing value types\n// ---------------------------------------------------------------------------\n\n/** A value written by an INSERT: a literal, an earlier row's field, or `now()`.\n * `inc`/`dec` are absent on purpose — they read a current value, and an inserted\n * row has none. */\nexport type TxInsertValue<V> = V | Ref<V> | TxNow;\n\n/** A value written by an UPDATE's `set`: everything an insert takes, plus the\n * read-modify-write expressions. */\n/**\n * TEK KURAL: ifade tutamağı yalnız sayısal-benzeri kolonlarda.\n *\n * Bu tip KOŞULSUZDU ve doğrudan yolun `SetValue<V>`'si koşulluydu, yani aynı\n * nesne için İKİ tip kuralı vardı: `tx.tables.todos.updateWhere({id}, { done:\n * increment(1) })` (boolean kolon!) DERLENİYOR, `updateMany`'nin aynısı derleme\n * hatası veriyordu. Bu run'ın kapatmak için var olduğu şey \"aynı iş için iki\n * uyumsuz yazım\"dı; tip kuralı ikinci yazımın kendisi olmuştu (gözcü I6/I-1).\n */\nexport type TxSetValue<V> =\n | V\n | Ref<V>\n | TxNow\n | (NonNullable<V> extends number | string ? TxColumnExpr : never);\n\n/** An insert payload: the table's insert shape, with refs and `now()` allowed. */\nexport type TxInsertShape<Insert> = { [K in keyof Insert]: TxInsertValue<Insert[K]> };\n\n/** An update's `set`: any subset of the insert shape, with expressions allowed. */\nexport type TxSetShape<Insert> = { [K in keyof Insert]?: TxSetValue<Insert[K]> };\n\n/**\n * A filter. Every entry is an equality test and they are AND-ed; a `null`\n * becomes `IS NULL`, which is what makes `{ accepted_at: null }` a usable\n * \"not yet accepted\" guard rather than a clause that matches nothing.\n */\n/**\n * Plan filtresinin tipi — `WhereFilter<Row>` ile AYNI sözlük, artı `Ref`.\n *\n * Eskiden yalnız eşitlikti (`Row[K] | Ref<Row[K]>`), ve iki şeye mal oluyordu:\n * FR-014'ün amiral deseni (`{ balance: { gte: amount } }`) `$transaction`\n * İÇİNDE yazılamıyordu — koşullu bir yazmayı plana koyamayan yazar `$query`'ye\n * düşüyordu — ve motor tarafında tip atlandığında aynı nesne SESSİZCE parametre\n * olarak bağlanıyordu.\n *\n * `Ref` fazladan üye ve öyle kalmalı: bir plan filtresi ÖNCEKİ bir işlemin\n * döndürdüğü değere bakabilir, `findMany` bakamaz — plan dışında böyle bir\n * \"önceki işlem\" yok.\n */\ntype TxWhereField<Row, K extends keyof Row> = WhereOpWith<\n Row[K],\n // `Ref` KOLON REFERANSININ YANINDA duruyor, `V`'nin içinde DEĞİL: `V`'ye\n // eklenseydi `TextOps<V>`'nin `V extends string` sorusu HAYIR olur ve\n // `contains`/`startsWith` sessizce kaybolurdu (ölçüldü).\n ColRefOf<Row, Row[K]> | Ref<Row[K]>\n>;\n\nexport type TxWhere<Row, Rels = unknown> = {\n [K in keyof Row]?: TxWhereField<Row, K>;\n} & {\n // Düz op'lardaki `WhereFilter` ile AYNI: dal bir `sqlFragment` de olabilir.\n // İki filtre dilinin bir dalda ayrışması, \"tek dil\" iddiasını tam da bileşim\n // anında boşa çıkarırdı — ve motor plan yolunda da fragment'i derliyor\n // (ölçüldü: `SELECT t.* FROM \"crew\" t WHERE true AND (((a > 1)) AND (…))`).\n OR?: (TxWhere<Row, Rels> | SqlFragment)[];\n AND?: (TxWhere<Row, Rels> | SqlFragment)[];\n NOT?: TxWhere<Row, Rels> | SqlFragment;\n} & HasOnly<Rels>;\n\n/** Options for a plan `select`. */\nexport interface TxSelectOptions {\n /** Cap the rows read. */\n limit?: number;\n /** Take a real `FOR UPDATE` row lock for the rest of the transaction. */\n lock?: \"update\";\n}\n\n/** One table, as the plan sees it. */\nexport interface TxTable<Row, Insert, Rels = unknown> {\n /** Insert one row. Returns a handle — call `.expectOne(err)` to read fields. */\n insert(values: TxInsertShape<Insert>): TxRows<Row>;\n /**\n * Insert many rows in ONE statement. Every row must set the same columns\n * (a row that omits one would silently take the column's default).\n *\n * An empty list writes nothing and sends nothing.\n */\n /**\n * Insert many rows in ONE statement, optionally choosing what a collision does.\n *\n * Without `opts` this is a plain multi-row INSERT and a collision aborts the\n * transaction — the behaviour every call had before the option existed.\n *\n * `action: \"ignore\"` emits `ON CONFLICT DO NOTHING`, which is how \"insert the\n * ones that are new\" becomes one round-trip instead of one per row with a\n * 23505 caught around each. **The returned rows are the ones actually\n * INSERTED**: a row that collided is skipped, so it is absent from the result\n * — Postgres does not return what it did not write.\n *\n * `action: \"update\"` emits `ON CONFLICT DO UPDATE`, setting every non-conflict\n * column from the incoming row, and every row comes back.\n */\n insertMany(\n rows: readonly TxInsertShape<Insert>[],\n opts?: {\n onConflict: readonly Extract<keyof Row, string>[];\n action?: \"ignore\" | \"update\";\n },\n ): TxRows<Row>;\n /**\n * Satırı yaz, `onConflict` kolonlarında çakışırsa üzerine yaz — planın\n * savepoint'i içinde, `Database.<şema>.<tablo>.put()` ile AYNI anlamda.\n *\n * Adı bilerek aynı: aynı iş için transaction içinde ve dışında iki farklı\n * yazım, bu run'ın kapatmak için var olduğu şeydir (P1). TEL şekli\n * (`op: \"upsert\"`) değişmedi — o iç sözleşme, yazarın gördüğü ad değil.\n *\n * Bir operasyon olmasının sebebi: alternatifi burada yazılamaz — başarısız\n * bir insert tüm transaction'ı abort eder, yani \"dene, sonra geri düş\" iki\n * plan adımı olamaz.\n */\n put(\n values: TxInsertShape<Insert>,\n options: { onConflict: readonly Extract<keyof Row, string>[] },\n ): TxRows<Row>;\n /**\n * Update every row matching `where`. The filter comes first because it is the\n * dangerous half: an update whose `where` you got wrong rewrites rows you\n * never looked at. The server refuses an update with no `where` at all.\n */\n updateWhere(where: TxWhere<Row, Rels>, set: TxSetShape<Insert>): TxRows<Row>;\n /** Delete every row matching `where`. The server refuses an unfiltered delete. */\n deleteWhere(where: TxWhere<Row, Rels>): TxRows<Row>;\n /** Read rows, optionally locking them for the rest of the transaction. */\n select(where?: TxWhere<Row, Rels>, options?: TxSelectOptions): TxRows<Row>;\n}\n\n/**\n * The handle a transaction callback receives.\n *\n * It carries tables and nothing else: no `query`, no `findById`, no `asService`.\n * A read whose value the plan does not write belongs OUTSIDE the transaction,\n * where it costs one round trip and can be branched on like an ordinary value.\n */\nexport interface TxPlanHandle<TTables> {\n /**\n * @deprecated `tx.public` kullanın. Bu ad public'in takma adı olarak DURUYOR\n * (göç notu onu öğretiyor ve her mevcut çağrı onu kullanıyor), ama ARTIK\n * ÖĞRETİLMİYOR: doğrudan yüzeyde `Database.tables` FR-001 ile kaldırıldı, ve\n * plan yüzeyinin onu öğretmeye devam etmesi yazarı bir yüzeyde çalışıp\n * diğerinde derlenmeyen bir yazıma alıştırıyordu (gözcü M-6).\n */\n tables: TTables;\n}\n\n// ---------------------------------------------------------------------------\n// Runtime — expressions\n// ---------------------------------------------------------------------------\n\n/** Internal marker read by the serialiser. */\nconst EXPR = Symbol.for(\"palbase.tx.expr\");\nconst REF = Symbol.for(\"palbase.tx.ref\");\nconst ROW = Symbol.for(\"palbase.tx.row\");\nconst ROWS = Symbol.for(\"palbase.tx.rows\");\n\ninterface RefDescriptor {\n op: number;\n field: string;\n}\n\n/** Property reads that must not silently produce a value on a plan handle.\n * `then` is the one that matters for correctness (it makes `await` a compile\n * error AND stops a handle from being adopted by a promise); the rest turn a\n * silent wrong answer — `\"[object Object]\"`, `NaN`, `{}` — into a thrown one. */\nconst TRAPPED_PROPS: readonly (string | symbol)[] = [\n \"then\",\n \"valueOf\",\n \"toString\",\n \"toJSON\",\n Symbol.toPrimitive,\n];\n\nfunction trap(prop: string | symbol, what: string, hint: string): never {\n const name = typeof prop === \"symbol\" ? prop.description ?? String(prop) : prop;\n throw new TxRefError(\n `${what} was used as a value (via \\`${name}\\`). Nothing in a transaction ` +\n `callback has run yet, so there is no value to read. ${hint}`,\n );\n}\n\n/** The server's `now()`. */\nexport function now(): TxNow {\n return makeExpr({ fn: \"now\" }) as TxNow;\n}\n\n/** Add `by` to the column's current value. Only valid in an update's `set`. */\nexport function increment(by: number | string): TxColumnExpr {\n assertAmount(by, \"increment\");\n return makeExpr({ fn: \"inc\", by }) as TxColumnExpr;\n}\n\n/**\n * `increment`'in eski adı. AYNI fabrikadır — iki uygulama değil, iki ad.\n *\n * @deprecated `increment()` kullanın; bu ad geriye dönük uyumluluk için duruyor.\n */\nexport const inc = increment;\n\n/** Subtract `by` from the column's current value. Only valid in an update's `set`. */\nexport function decrement(by: number | string): TxColumnExpr {\n assertAmount(by, \"decrement\");\n return makeExpr({ fn: \"dec\", by }) as TxColumnExpr;\n}\n\n/**\n * `decrement`'in eski adı. AYNI fabrikadır.\n *\n * @deprecated `decrement()` kullanın.\n */\nexport const dec = decrement;\n\n/**\n * Miktarın taşınabilir olduğunu doğrular.\n *\n * String kabul edilir ve KASITLIDIR (D-007): `numeric` bir kolonda miktar JS\n * `number`'a uğrarsa 0.1 + 0.2 orada 0.30000000000000004'tür ve para hesabı\n * sessizce kayar. String hem burada hem `renderValue`'da bound parametre olarak\n * taşınır — Postgres onu tam ondalık olarak okur.\n */\nfunction assertAmount(by: number | string, fn: string): void {\n if (typeof by === \"string\") {\n // Metin SQL'e girmiyor (bound parametre), ama şekli yine de doğrulanır:\n // \"abc\" bind edilirse hata Postgres'ten gelir, çağıranın diliyle değil.\n if (!/^-?\\d+(\\.\\d+)?$/.test(by)) {\n throw new TxPlanError(\n `${fn}() ondalık bir sayı metni bekliyor, \"${by}\" aldı — kabul edilen biçim: \"12\", \"-12\", \"12.50\"`,\n );\n }\n } else if (typeof by !== \"number\" || !Number.isFinite(by)) {\n // JSON has no NaN/Infinity: they would serialise to `null` and the server\n // would reject the plan with an unhelpful decode error.\n throw new TxPlanError(`${fn}() needs a finite number, got ${String(by)}`);\n }\n // NEGATİF MİKTAR REDDEDİLİR — ve bu şekil kontrolünden çok daha fazlası.\n // `decrement(\"-5\")` `SET c = c - $1` derliyordu, `$1 = -5`, yani beş EKLİYORDU.\n // FR-014'ün amiral deseninde (`where: { balance: { gte: amount } }`) miktar\n // istek gövdesinden geliyorsa `balance >= -5` her zaman doğru: hesap\n // KREDİLENDİRİLİR ve çağrı bunu 1 satırla \"başarı\" diye raporlar. Guard\n // okunduğunda işaret kontrol edilmiş gibi duruyordu (gözcü I9, ölçüldü).\n const negative = typeof by === \"string\" ? by.trimStart().startsWith(\"-\") : by < 0;\n if (negative) {\n const other = fn === \"increment\" ? \"decrement\" : \"increment\";\n throw new TxPlanError(\n `${fn}() negatif miktar almaz (\"${String(by)}\"). Ters yön için ${other}() kullanın — ` +\n `işaretin miktarda saklanması, yönü okuyan hiçbir kod tarafından görülmezdi.`,\n );\n }\n}\n\n/**\n * Bir değer `increment()`/`decrement()` ürünü mü? Öyleyse tel şekli.\n *\n * DOĞRUDAN yol (`updateMany`) da bu ifadeyi anlamak zorunda: aynı nesnenin iki\n * yerde çalışması, \"kolona ekle\"nin tek yazımı olmasının şartı (P1).\n */\nexport function columnExprOf(v: unknown): TxWireExpr[\"$expr\"] | null {\n return exprOf(v);\n}\n\nfunction makeExpr(expr: TxWireExpr[\"$expr\"]): unknown {\n return new Proxy(\n { [EXPR]: expr } as Record<string | symbol, unknown>,\n {\n get(target, prop) {\n if (prop === EXPR) return target[EXPR];\n if (TRAPPED_PROPS.includes(prop)) {\n trap(prop, \"A plan expression\", \"Write it into an operation instead.\");\n }\n return undefined;\n },\n },\n );\n}\n\n// ---------------------------------------------------------------------------\n// Runtime — refs and row handles\n// ---------------------------------------------------------------------------\n\nfunction makeRef(op: number, field: string): unknown {\n const target: Record<string | symbol, unknown> = { [REF]: { op, field } satisfies RefDescriptor };\n return new Proxy(target, {\n get(t, prop) {\n if (prop === REF) return t[REF];\n if (TRAPPED_PROPS.includes(prop)) {\n trap(\n prop,\n `\\`${field}\\` of a row this transaction has not written yet`,\n \"Pass it to another operation in the same plan, or return it from the \" +\n \"callback and read it after `transaction()` resolves.\",\n );\n }\n return undefined;\n },\n });\n}\n\nfunction makeRowHandle(op: number): unknown {\n const target: Record<string | symbol, unknown> = { [ROW]: op };\n return new Proxy(target, {\n get(t, prop) {\n if (prop === ROW) return t[ROW];\n if (TRAPPED_PROPS.includes(prop)) {\n trap(\n prop,\n \"A row this transaction has not written yet\",\n \"Read one of its columns to reference it, or return the row from the \" +\n \"callback and read it after `transaction()` resolves.\",\n );\n }\n if (typeof prop === \"symbol\") return undefined;\n return makeRef(op, prop);\n },\n });\n}\n\nfunction refDescriptor(v: unknown): RefDescriptor | null {\n if (typeof v !== \"object\" || v === null) return null;\n const d = (v as Record<symbol, unknown>)[REF];\n return isRefDescriptor(d) ? d : null;\n}\n\nfunction isRefDescriptor(d: unknown): d is RefDescriptor {\n return (\n typeof d === \"object\" &&\n d !== null &&\n typeof (d as RefDescriptor).op === \"number\" &&\n typeof (d as RefDescriptor).field === \"string\"\n );\n}\n\nfunction rowOpIndex(v: unknown): number | null {\n if (typeof v !== \"object\" || v === null) return null;\n const op = (v as Record<symbol, unknown>)[ROW];\n return typeof op === \"number\" ? op : null;\n}\n\nfunction exprOf(v: unknown): TxWireExpr[\"$expr\"] | null {\n if (typeof v !== \"object\" || v === null) return null;\n const e = (v as Record<symbol, unknown>)[EXPR];\n return typeof e === \"object\" && e !== null ? (e as TxWireExpr[\"$expr\"]) : null;\n}\n\nfunction isRowsHandle(v: unknown): boolean {\n return typeof v === \"object\" && v !== null && (v as Record<symbol, unknown>)[ROWS] !== undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Runtime — value encoding\n// ---------------------------------------------------------------------------\n\n/**\n * Encode one value of a `values`/`set`/`where` map.\n *\n * The nesting check is not defensive tidiness. The server treats `$ref` as a\n * tagged value only at the TOP of a column's value; a ref buried inside a jsonb\n * payload is just data, and would be stored as the literal object\n * `{\"$ref\":{...}}` — a write that succeeds, commits, and is wrong. So a nested\n * handle is a hard error here, where the line that wrote it is still on the\n * stack.\n */\nfunction encodeValue(value: unknown, column: string, allowColumnExpr: boolean): TxWireValue {\n const ref = refDescriptor(value);\n if (ref) return brandRef({ $ref: { op: ref.op, field: ref.field } }, \"ref\") satisfies TxWireRef;\n\n // `now()` bir KARŞILAŞTIRMA değeri olarak geçer — sunucu saati. Diğer\n // ifadeler (increment/decrement) yazma ifadesidir ve aşağıda adıyla\n // reddediliyor. Düz op yolu ile aynı ayrım, aynı gerekçe.\n if (isNowExpr(value)) return { $expr: { fn: \"now\" } };\n const expr = exprOf(value);\n if (expr) {\n if (expr.fn !== \"now\" && !allowColumnExpr) {\n throw new TxPlanError(\n `\\`${column}\\`: ${expr.fn}() reads the column's current value, so it is ` +\n `only valid in updateWhere(where, set).`,\n );\n }\n return { $expr: expr } satisfies TxWireExpr;\n }\n\n if (rowOpIndex(value) !== null) {\n throw new TxPlanError(\n `\\`${column}\\`: a row handle is not a value. Read the column you meant ` +\n `(e.g. \\`row.id\\`).`,\n );\n }\n if (isRowsHandle(value)) {\n throw new TxPlanError(\n `\\`${column}\\`: an operation result is not a value. Declare an expectation ` +\n `first (\\`.expectOne(err)\\`) and read a column from the row.`,\n );\n }\n\n assertNoNestedHandles(value, column);\n return value;\n}\n\n/**\n * Encode a FİLTRE — `values`/`set` ile AYNI kodlayıcı değil, ve olmaması bir\n * düzeltme.\n *\n * `encodeValue` bir `$ref`'i yalnız kolonun EN ÜSTÜNDE kabul ediyor, çünkü bir\n * insert değerinin İÇİNE gömülü ref sunucuda çözülmez, literal JSON olarak\n * SAKLANIR — \"başarıyla commit olan ve yanlış olan bir yazma\". O kural DEĞER\n * yolu için doğru.\n *\n * FİLTREDE öyle değil: motorun `resolveRefsDeep`'i bir ref'i filtrenin HER\n * yerinde çözüyor — operatörün sağında, `OR`/`AND`/`NOT` dallarının içinde. Ama\n * kodlayıcı hâlâ değer kuralını uyguluyordu, yani üç katman üç farklı cevap\n * veriyordu (gözcü C-2): tip kabul, motor çözüyor, kodlayıcı REDDEDİYOR — ve\n * reddin metni değer-yuvalama vakasını anlatıyor, filtrede olmayan bir şeyi.\n *\n * İFADE TUTAMAĞI ve SATIR TUTAMAĞI filtrede HÂLÂ reddediliyor: onları motor\n * filtrede çözmüyor ve çözmemeli — `increment()` bir yazma ifadesi, bir\n * karşılaştırma değil.\n */\nfunction encodeFilterValue(value: unknown, column: string): unknown {\n const ref = refDescriptor(value);\n if (ref) return brandRef({ $ref: { op: ref.op, field: ref.field } }, \"ref\") satisfies TxWireRef;\n\n const expr = exprOf(value);\n if (expr) {\n throw new TxPlanError(\n `\\`${column}\\`: ${expr.fn}() bir YAZMA ifadesi, karşılaştırma değil — ` +\n `filtrede kullanılamaz. Kolonu bir değerle ya da col() ile karşılaştırın.`,\n );\n }\n if (rowOpIndex(value) !== null) {\n throw new TxPlanError(\n `\\`${column}\\`: a row handle is not a value. Read the column you meant (e.g. \\`row.id\\`).`,\n );\n }\n if (isRowsHandle(value)) {\n throw new TxPlanError(\n `\\`${column}\\`: an operation result is not a value. Declare an expectation ` +\n `first (\\`.expectOne(err)\\`) and read a column from the row.`,\n );\n }\n if (Array.isArray(value)) return value.map((v) => encodeFilterValue(v, column));\n // `col()` ve `sqlFragment` OLDUĞU GİBİ geçer: markaları süreç içinde korunur\n // ve derleyici ikisini de kendi tanıyor.\n if (value !== null && typeof value === \"object\" && !(value instanceof Date) && !isColRef(value) && !isSqlFragment(value)) {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n out[k] = encodeFilterValue(v, column);\n }\n return out;\n }\n return value;\n}\n\n/** Filtre haritası — anahtarlar SIRALI (aynı geri çağrı bayt-özdeş JSON üretsin). */\nfunction encodeFilterMap(map: Record<string, unknown>): Record<string, TxWireValue> {\n const out: Record<string, TxWireValue> = {};\n for (const key of Object.keys(map).sort()) {\n const value = map[key];\n if (value === undefined) continue;\n out[key] = encodeFilterValue(value, key) as TxWireValue;\n }\n return out;\n}\n\nfunction assertNoNestedHandles(value: unknown, column: string): void {\n if (typeof value !== \"object\" || value === null) return;\n if (value instanceof Date) return;\n if (refDescriptor(value) || exprOf(value) || rowOpIndex(value) !== null || isRowsHandle(value)) {\n throw new TxPlanError(\n `\\`${column}\\`: a plan handle is nested inside a value. The server would ` +\n `store it as literal JSON, not resolve it. Put the reference directly in ` +\n `the column.`,\n );\n }\n if (Array.isArray(value)) {\n for (const item of value) assertNoNestedHandles(item, column);\n return;\n }\n for (const item of Object.values(value as Record<string, unknown>)) {\n assertNoNestedHandles(item, column);\n }\n}\n\n/**\n * Encode a column map, dropping `undefined` and emitting keys SORTED.\n *\n * Sorting is what makes the same callback produce byte-identical JSON every\n * time, which is what lets the Go decoder be locked to goldens this SDK emits.\n * Dropping `undefined` mirrors what `JSON.stringify` would do anyway, but does\n * it where the resulting column list is still checkable.\n */\nfunction encodeMap(\n map: Record<string, unknown>,\n allowColumnExpr: boolean,\n): Record<string, TxWireValue> {\n const out: Record<string, TxWireValue> = {};\n for (const key of Object.keys(map).sort()) {\n const value = map[key];\n // AÇIK `undefined` REDDEDİLİR (D-017 kapandı).\n //\n // \"Kolon varsayılanını al\" demenin yolu anahtarı HİÇ KOYMAMAK; bu döngü\n // zaten yalnız var olan anahtarları geziyor, yani o niyet bozulmadan\n // çalışıyor. Ayırt edilen şey başka: anahtarın DURDUĞU ama değerinin\n // `undefined` olduğu hâl — yani `{ title: req.body.title }` gövdede\n // `title` yokken. O ölçülmüş bir olaydı: kolon sessizce yazılmadı ve\n // istek 200 döndü.\n //\n // Doğrudan yol bunu baştan beri adıyla reddediyordu; plan yolu sessizce\n // düşürüyordu. Aynı girdiye zıt iki cevap, \"tek filtre dili, tek cevap\"\n // iddiasını yazma tarafında boşa çıkarıyordu.\n if (value === undefined) {\n throw new TxPlanError(\n `${key} değeri undefined — bu bir yazma değeri değil. Anahtar duruyor ` +\n `ama değeri yok, yani kolon sessizce YAZILMAZDI (istek gövdesinden ` +\n `gelen bir alanın eksik olması bu şekilde görünür). Kolon ` +\n `varsayılanını istiyorsanız anahtarı hiç koymayın; NULL yazmak ` +\n `istiyorsanız açıkça null yazın.`,\n );\n }\n out[key] = encodeValue(value, key, allowColumnExpr);\n }\n return out;\n}\n\n// ---------------------------------------------------------------------------\n// Runtime — the builder\n// ---------------------------------------------------------------------------\n\n/** How many rows an op can produce, as far as the CLIENT can tell before it\n * runs. Only the empty `insertMany` is knowable, and knowing it is what lets a\n * doomed expectation fail on the line that declared it. */\nconst SKIPPED_OP = -1;\n\nclass TxRowsImpl<Row> implements TxRows<Row> {\n // Present so `isRowsHandle` recognises the object; never read for its value.\n readonly [ROWS] = true;\n // Phantom: the type brand that stops a bare object passing as a TxRows. Never\n // present at run time, which is what `declare` says.\n declare readonly [rowsBrand]: Row;\n private guarded = false;\n\n constructor(\n private readonly builder: TxPlanBuilder,\n private readonly opIndex: number,\n private readonly what: string,\n ) {}\n\n // The type-level `await` guard made real: TS rejects `await rows` at compile\n // time, and reaching this means someone called `.then(...)` by hand.\n then(): never {\n throw new TxRefError(\n `${this.what} cannot be awaited: a transaction callback builds a plan, it ` +\n `does not run statements. Remove the \\`await\\`.`,\n );\n }\n\n expectOne(error: Error): TxRow<Row> {\n this.declareGuard(\"one\", 1, error);\n if (this.opIndex === SKIPPED_OP) throw error;\n return makeRowHandle(this.opIndex) as TxRow<Row>;\n }\n\n expectNone(error: Error): void {\n this.declareGuard(\"none\", 0, error);\n }\n\n expectAtLeast(n: number, error: Error): void {\n assertGuardCount(n, \"expectAtLeast\");\n this.declareGuard(\"atLeast\", n, error);\n if (this.opIndex === SKIPPED_OP && n > 0) throw error;\n }\n\n expectAtMost(n: number, error: Error): void {\n assertGuardCount(n, \"expectAtMost\");\n this.declareGuard(\"atMost\", n, error);\n }\n\n private declareGuard(kind: TxWireGuard[\"kind\"], n: number, error: Error): void {\n if (!(error instanceof Error)) {\n // The error object is the ONLY thing that describes this failure to the\n // caller — the server sends back an index, never a message.\n throw new TxPlanError(\n `${this.what}: an expectation needs the Error to throw when it does not ` +\n `hold (e.g. \\`.expect…(new Conflict(\"already accepted\"))\\`).`,\n );\n }\n if (this.guarded) {\n throw new TxPlanError(\n `${this.what} already has an expectation. One operation carries one ` +\n `expectation; declare the second one on its own operation.`,\n );\n }\n this.guarded = true;\n if (this.opIndex === SKIPPED_OP) return;\n this.builder.attachGuard(this.opIndex, kind, n, error);\n }\n}\n\nfunction assertGuardCount(n: number, fn: string): void {\n if (!Number.isInteger(n) || n < 0) {\n throw new TxPlanError(`${fn}(n) needs a non-negative integer, got ${String(n)}`);\n }\n}\n\n/** Bounds mirrored from the plan executor so an over-sized plan is named here rather\n * than rejected as an opaque 400 after it has crossed the network. */\nconst MAX_OPS = 1000;\nconst MAX_ROWS = 5000;\n\n/**\n * Accumulates ops and the client-side error table while the callback runs.\n *\n * Exported for the runtime and for tests that need the serialised plan without\n * a server; author code never sees it.\n */\nexport class TxPlanBuilder {\n private readonly ops: TxWireOp[] = [];\n /** Errors handed to expectations, indexed by the `slot` the server echoes. */\n private readonly slots: Error[] = [];\n\n /** The table surface handed to the callback. Untyped here; the public\n * `transaction()` signatures put the schema types on top. */\n table(name: string): TxTable<Record<string, unknown>, Record<string, unknown>> {\n return {\n insert: (values) => {\n const encoded = encodeMap(values as Record<string, unknown>, false);\n if (Object.keys(encoded).length === 0) {\n throw new TxPlanError(`${name}.insert() needs at least one column`);\n }\n return this.push({ op: \"insert\", table: name, values: encoded }, `${name}.insert()`);\n },\n\n put: (values, options) => {\n const encoded = encodeMap(values as Record<string, unknown>, false);\n if (Object.keys(encoded).length === 0) {\n throw new TxPlanError(`${name}.put() needs at least one column`);\n }\n if (options.onConflict.length === 0) {\n throw new TxPlanError(`${name}.put() needs at least one onConflict column`);\n }\n return this.push(\n { op: \"upsert\", table: name, values: encoded, onConflict: options.onConflict },\n `${name}.upsert()`,\n );\n },\n\n insertMany: (rows, opts) => {\n if (rows.length === 0) {\n // Nothing to write. Emitting an op would be a guaranteed 400 (the\n // server requires rows), and refusing outright would punish the\n // ordinary \"filtered every candidate out\" case.\n return new TxRowsImpl(this, SKIPPED_OP, `${name}.insertMany()`);\n }\n if (rows.length > MAX_ROWS) {\n throw new TxPlanError(\n `${name}.insertMany() has ${rows.length} rows; the limit is ${MAX_ROWS}. ` +\n `Split the write across requests.`,\n );\n }\n const encoded = rows.map((row) => encodeMap(row as Record<string, unknown>, false));\n assertUniformRows(encoded, name);\n if (opts !== undefined && opts.onConflict.length === 0) {\n throw new TxPlanError(\n `${name}.insertMany() was given a conflict action with no onConflict ` +\n `columns. Postgres matches a collision on columns, so name them.`,\n );\n }\n return this.push(\n {\n op: \"insertMany\",\n table: name,\n rows: encoded,\n // Omitted entirely when no options were given, so the op a plain\n // insertMany produces is byte-identical to the one it produced\n // before this option existed.\n ...(opts !== undefined\n ? { onConflict: opts.onConflict, action: opts.action ?? \"ignore\" }\n : {}),\n },\n `${name}.insertMany()`,\n );\n },\n\n updateWhere: (where, set) => {\n const encodedWhere = encodeFilterMap(where as Record<string, unknown>);\n const encodedSet = encodeMap(set as Record<string, unknown>, true);\n if (Object.keys(encodedWhere).length === 0) {\n throw new TxPlanError(\n `${name}.updateWhere() needs a filter. An update with no filter ` +\n `rewrites the whole table.`,\n );\n }\n if (Object.keys(encodedSet).length === 0) {\n throw new TxPlanError(`${name}.updateWhere() needs at least one column to set`);\n }\n return this.push(\n { op: \"update\", table: name, set: encodedSet, where: encodedWhere },\n `${name}.updateWhere()`,\n );\n },\n\n deleteWhere: (where) => {\n const encodedWhere = encodeFilterMap(where as Record<string, unknown>);\n if (Object.keys(encodedWhere).length === 0) {\n throw new TxPlanError(\n `${name}.deleteWhere() needs a filter. A delete with no filter empties ` +\n `the table.`,\n );\n }\n return this.push(\n { op: \"delete\", table: name, where: encodedWhere },\n `${name}.deleteWhere()`,\n );\n },\n\n select: (where, options) => {\n const op: TxWireOp = { op: \"select\", table: name };\n const encodedWhere = encodeFilterMap((where ?? {}) as Record<string, unknown>);\n if (Object.keys(encodedWhere).length > 0) op.where = encodedWhere;\n if (options?.limit !== undefined) {\n if (!Number.isInteger(options.limit) || options.limit < 0) {\n throw new TxPlanError(\n `${name}.select(): limit needs a non-negative integer, got ${String(options.limit)}`,\n );\n }\n op.limit = options.limit;\n }\n if (options?.lock !== undefined) op.lock = options.lock;\n return this.push(op, `${name}.select()`);\n },\n };\n }\n\n private push(op: TxWireOp, what: string): TxRows<Record<string, unknown>> {\n if (this.ops.length >= MAX_OPS) {\n throw new TxPlanError(\n `this transaction has ${MAX_OPS} operations, which is the limit. Use ` +\n `insertMany() for bulk writes, or split the work across requests.`,\n );\n }\n const index = this.ops.length;\n this.ops.push(op);\n return new TxRowsImpl(this, index, what);\n }\n\n /** Attach an expectation to an op and record its error in the slot table. */\n attachGuard(opIndex: number, kind: TxWireGuard[\"kind\"], n: number, error: Error): void {\n const op = this.ops[opIndex];\n // Unreachable: the index came from `push`. A loud failure beats a silently\n // unguarded write if that ever stops being true.\n if (!op) throw new TxPlanError(`internal: expectation on unknown operation ${opIndex}`);\n const slot = this.slots.length;\n this.slots.push(error);\n op.guard = { kind, n, slot };\n }\n\n /** The serialisable plan. Empty when the callback described no writes. */\n body(): TxPlanBody {\n return { ops: this.ops };\n }\n\n /** The error the server's `slot` selects, or `null` when it names one this\n * plan never declared (a server/client disagreement, not a tenant error). */\n errorForSlot(slot: number): Error | null {\n return this.slots[slot] ?? null;\n }\n}\n\nfunction assertUniformRows(rows: Record<string, TxWireValue>[], table: string): void {\n const first = rows[0];\n if (!first) return;\n const want = Object.keys(first);\n const wantKey = want.join(\",\");\n for (let i = 1; i < rows.length; i++) {\n const got = Object.keys(rows[i] as Record<string, TxWireValue>);\n if (got.join(\",\") !== wantKey) {\n // One statement, one column list. A ragged row would take the DB default\n // for the column it omitted — a write that succeeds and is wrong.\n throw new TxPlanError(\n `${table}.insertMany(): every row must set the same columns. Row 0 sets ` +\n `[${want.join(\", \")}] but row ${i} sets [${got.join(\", \")}]. ` +\n `(A property set to \\`undefined\\` counts as absent — use \\`null\\`.)`,\n );\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Runtime — materialisation\n// ---------------------------------------------------------------------------\n\n/**\n * Replace every handle in the callback's return value with what the server\n * actually produced.\n *\n * Walks arrays and PLAIN objects only. Class instances (a Date, a Zod schema, a\n * domain object) are returned untouched — recursing into them would rebuild them\n * as bare objects, and nothing inside one can be a handle that this SDK created.\n */\nexport function materializeResult(value: unknown, results: TxPlanOpResult[]): unknown {\n const ref = refDescriptor(value);\n if (ref) {\n const row = rowOf(results, ref.op, `\\`${ref.field}\\``);\n if (!(ref.field in row)) {\n throw new TxPlanError(\n `the transaction's operation ${ref.op} returned no column \\`${ref.field}\\`.`,\n );\n }\n return row[ref.field];\n }\n\n const rowOp = rowOpIndex(value);\n if (rowOp !== null) return rowOf(results, rowOp, \"a row\");\n\n if (isRowsHandle(value)) {\n throw new TxPlanError(\n \"an operation result cannot be returned from a transaction callback: its \" +\n \"row count is not known until the plan runs. Declare an expectation \" +\n \"(`.expectOne(err)`) and return the row, or a column of it.\",\n );\n }\n\n if (Array.isArray(value)) return value.map((item) => materializeResult(item, results));\n\n if (isPlainObject(value)) {\n const out: Record<string, unknown> = {};\n for (const [key, item] of Object.entries(value)) out[key] = materializeResult(item, results);\n return out;\n }\n\n return value;\n}\n\nfunction rowOf(results: TxPlanOpResult[], opIndex: number, what: string): Record<string, unknown> {\n const result = results[opIndex];\n if (!result) {\n throw new TxPlanError(\n `the transaction returned no result for operation ${opIndex}, so ${what} ` +\n `cannot be read.`,\n );\n }\n const row = result.rows[0];\n if (!row) {\n // Unreachable through the public API: a handle only exists behind an\n // `expectOne`, and the server rolls back rather than answering 200 with a\n // guard unmet. Loud, because the alternative is `undefined` in tenant data.\n throw new TxPlanError(\n `the transaction's operation ${opIndex} returned no row, so ${what} cannot ` +\n `be read.`,\n );\n }\n return row;\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n if (typeof value !== \"object\" || value === null) return false;\n const proto: unknown = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n}\n\n// ---------------------------------------------------------------------------\n// Runtime — the driver\n// ---------------------------------------------------------------------------\n\n/** What {@link runTxPlan} needs from the runtime: one call, one transaction. */\nexport interface TxPlanTransport {\n txPlan(plan: TxPlanBody): Promise<TxPlanResponse>;\n}\n\n/**\n * Build the plan, send it, and resolve the callback's return value.\n *\n * A callback that throws never reaches the network: there is nothing to roll\n * back because nothing was sent. A callback that describes no writes also skips\n * the round trip entirely.\n *\n * The RETURN type is `unknown` here on purpose. `Materialized<T>` is a compile-\n * time rewrite of the callback's return type, and it belongs on the public\n * `transaction()` signatures where `T` is inferred from the author's callback;\n * threading it through this driver as well would mean inferring `T` twice, from\n * two different positions, and reconciling them. The public wrappers narrow\n * once, at the seam where the value types were erased anyway.\n */\nexport async function runTxPlan<THandle>(\n transport: TxPlanTransport,\n // TUTAMAĞIN TAMAMI, yalnız `tables` DEĞİL. Tutamak artık şema yüzeyini de\n // taşıyor (`tx.public.x`, `tx.<şema>.x`), ve onu BURADA `{ tables }` diye\n // yeniden kurmak o yüzeyi sessizce düşürürdü.\n handle: THandle,\n builder: TxPlanBuilder,\n fn: (tx: THandle) => unknown,\n): Promise<unknown> {\n const returned = fn(handle);\n const body = builder.body();\n if (body.ops.length === 0) {\n return materializeResult(returned, []);\n }\n\n let response: TxPlanResponse;\n try {\n response = await transport.txPlan(body);\n } catch (err) {\n throw translateRejection(err, builder);\n }\n return materializeResult(returned, response.results);\n}\n\n/**\n * Turn the broker's rejection back into the tenant's own error.\n *\n * The server never sees the `Error` an expectation was given — only its slot\n * index — so this is the only place the intended error can be produced. A\n * rejection this SDK does not recognise passes through untouched: inventing an\n * error for it would hide the real failure.\n */\nfunction translateRejection(err: unknown, builder: TxPlanBuilder): unknown {\n if (typeof err !== \"object\" || err === null) return err;\n const rejection = err as TxPlanRejection;\n if (rejection.error_code !== \"tx_guard_failed\" || typeof rejection.slot !== \"number\") {\n return err;\n }\n return builder.errorForSlot(rejection.slot) ?? err;\n}\n","/** A PostgreSQL isolation level supported by the explicit root transaction. */\nexport type TransactionIsolation = \"read committed\" | \"repeatable read\" | \"serializable\";\n\nexport interface AtomicOptions {\n /** Each retry opens a fresh transaction and reruns the complete callback.\n * Defaults to zero. Keep external effects outside it; persist an outbox instead. */\n retry?: number;\n isolation?: TransactionIsolation;\n readOnly?: boolean;\n /** Maximum wait for a PostgreSQL lock. Defaults to 5000 ms. */\n lockTimeoutMs?: number;\n /** PostgreSQL statement timeout; applies to every statement in this scope. */\n statementTimeoutMs?: number;\n /** Total work deadline including queueing and retries. Active Bun queries are\n * cancelled; rollback settles before release. An in-flight COMMIT is awaited. */\n timeoutMs?: number;\n signal?: AbortSignal;\n\n}\n\nexport function retryBudget(value: number | undefined): number {\n const n = value ?? 0;\n if (!Number.isInteger(n) || n < 0 || n > 10) {\n throw new Error(\"transaction retry must be an integer between 0 and 10\");\n }\n return n;\n}\n\nexport function validateAtomicOptions(options: AtomicOptions): void {\n retryBudget(options.retry);\n if (options.isolation !== undefined && ![\"read committed\", \"repeatable read\", \"serializable\"].includes(options.isolation)) {\n throw new Error(\"transaction isolation must be read committed, repeatable read or serializable\");\n }\n if (options.readOnly !== undefined && typeof options.readOnly !== \"boolean\") {\n throw new Error(\"transaction readOnly must be a boolean\");\n }\n for (const name of [\"lockTimeoutMs\", \"statementTimeoutMs\", \"timeoutMs\"] as const) {\n const n = options[name];\n if (n !== undefined && (!Number.isInteger(n) || n < 1 || n > 2_147_483_647)) {\n throw new Error(`transaction ${name} must be a positive integer in milliseconds`);\n }\n }\n if (options.signal !== undefined && (typeof options.signal.aborted !== \"boolean\" || typeof options.signal.addEventListener !== \"function\")) {\n throw new Error(\"transaction signal must be an AbortSignal\");\n }\n}\n\n/** A savepoint cannot replace the enclosing transaction's snapshot or retry COMMIT. */\nexport function assertPlanRetry(options: { retry?: number } | undefined): void {\n if (retryBudget(options?.retry) !== 0) {\n throw new Error(\n \"Database.$transaction is a savepoint plan on the request transaction and cannot retry its snapshot or COMMIT. \" +\n \"Use Database.$atomic(async tx => { ... }, { retry, isolation }) and put all decision reads and writes inside that callback.\",\n );\n }\n}\n","// The wire shape of a declared schema — what the deploy reads.\n//\n// `defineSchema(...)` produces a value full of builders and phantom types, which\n// is the right shape for authoring and the wrong shape for anything outside this\n// process. The deploy is Go: it introspects the live database, diffs it against\n// the declaration, and applies the difference. So the declaration has to leave\n// TypeScript as data, and this file is where that happens.\n//\n// It lives in the SDK because the SDK owns the DSL. The alternative — a script\n// beside the deploy that reaches into `._def` — is a second reading of a private\n// shape, and it drifts the moment a column gains a property: the DSL keeps\n// working, the emitter silently omits it, and the database is missing something\n// nobody can see in the source.\n//\n// The field names below are a CONTRACT with Go's `schema.SchemaJSON`. Renaming\n// one here without renaming it there produces a declaration that parses to\n// something emptier than it was — the failure mode being a column, a policy, or\n// a whole table that quietly never gets created.\n// Politika ifadesinin tel şekli `policy.ts`'te TEK kez bildiriliyor. İki kopya\n// olsaydı biri `exists` düğümünü alır, diğeri almaz ve fark ancak Go tarafı\n// bilmediği bir `kind` gördüğünde ortaya çıkardı.\nimport type { PolicyExpr as PolicyExprJSON } from \"./policy.js\";\nexport type { PolicyExpr as PolicyExprJSON } from \"./policy.js\";\nimport type { ColumnBuilder, ColumnDef } from \"./columns.js\";\nimport type { PolicyDef } from \"./policy.js\";\nimport type { MemoryDecl, SchemaDef, SearchDecl, TableDef } from \"./schema.js\";\n\n/** One column, flattened. Mirrors Go's `schema.ColumnJSON`. */\nexport interface ColumnJSON {\n type: string;\n nullable: boolean;\n primaryKey: boolean;\n defaultValue?: unknown;\n defaultRandom?: boolean;\n defaultNow?: boolean;\n renamedFrom?: string;\n /** See Go's `schema.ColumnJSON.Ignored` — the contraction gate's only signal. */\n ignored?: boolean;\n owns?: boolean;\n references?: { table: string; column: string };\n onDeleteAction?: string;\n /** FR-044: türev FK index'i kapatılmışsa `false`. Bildirilmemişse alan YOK. */\n index?: boolean;\n /** FR-049: kolon increment() ile güncelleniyorsa `true`. Aksi hâlde alan YOK. */\n counter?: boolean;\n enumName?: string;\n enumValues?: string[];\n unique?: boolean;\n dimensions?: number;\n}\n\n/** One RLS policy. Mirrors Go's `schema.PolicyJSON`. */\nexport interface PolicyJSON {\n name: string;\n command: string;\n roles: string[];\n /**\n * `USING (...)` — ham string (kaçış kapağı, FR-028) ya da YAPI (FR-022).\n *\n * Go tarafı ikisini de okur: string olan verbatim emit edilir, yapı olan\n * `generator.go`'da SQL'e çevrilir (C-6). Yapı hâli InitPlan sarmalamasını\n * ve `TO <rol>` daraltmasını GÜVENLE yapılabilir kılan şey — string üstünde\n * regex'le denemek yorum içindeki bir `auth.uid()`'yi de sarmalardı.\n */\n using: string | PolicyExprJSON | null;\n withCheck: string | PolicyExprJSON | null;\n permissive: boolean;\n}\n\n\n/** One table. Mirrors Go's `schema.TableJSON`. */\nexport interface TableJSON {\n /**\n * The schema this table lives in. `public` unless declared otherwise.\n *\n * The table carries it because the diff iterates over KEYS but passes the\n * VALUE around: a bare name inside a qualified key space writes the migration\n * into the wrong schema, silently.\n */\n schema: string;\n name: string;\n columns: Record<string, ColumnJSON>;\n rls: boolean;\n policies: PolicyJSON[];\n primaryKey?: string[];\n uniqueConstraints?: { name: string; columns: string[] }[];\n rawConstraints?: { name: string; up: string }[];\n checks?: { name: string; expr: string }[];\n indexes?: IndexJSON[];\n /** Canlıdan düşürülecek constraint adları (FR-008). Sıfır değerde OMIT. */\n dropConstraints?: string[];\n /** Tablo düzeyi çok sütunlu FOREIGN KEY'ler (FR-001). Sıfır değerde OMIT. */\n foreignKeys?: ForeignKeyJSON[];\n /** Koşullu FK'lar — donan demetler (FR-012). Sıfır değerde OMIT. */\n freeze?: FreezeJSON[];\n /** Guard'lar — bildirimsel kısıtın yetişemediği yazma redleri (FR-015). Sıfır değerde OMIT. */\n guards?: GuardJSON[];\n /** Bir kez koşacak veri düzeltmeleri (FR-033). Sıfır değerde OMIT. */\n backfills?: BackfillJSON[];\n /**\n * appendOnly (FR-030): tablo yalnız INSERT kabul eder. Sıfır değerde OMIT —\n * bildirmeyen tablolar wire'da bayt-aynı kalır.\n */\n appendOnly?: boolean;\n search?: SearchJSON;\n memory?: MemoryJSON;\n}\n\n/**\n * Bir index'in wire şekli — Go'nun `IndexJSON`'ıyla ALAN-ADI SÖZLEŞMESİ.\n *\n * `name` + `columns` bugünkü hâl; kalanı FR-041…043'ün taşıyıcısı. Hepsi sıfır\n * değerde OMIT edilir: bildirmeyen bir index wire'da eskisiyle bayt-aynı kalır,\n * yoksa dokunulmamış her şema diff'te değişmiş görünür ve her deploy churn üretir.\n */\nexport interface IndexJSON {\n name: string;\n /** `CREATE UNIQUE INDEX` (FR-007). Sıfır değerde OMIT. */\n unique?: boolean;\n columns: string[];\n /** Partial index koşulu (FR-042) — filtre şekli `WhereFilter` ile aynı. */\n where?: unknown;\n /** İfade index'i (FR-043), ör. `lower(email)`. `columns` ile birlikte kullanılmaz. */\n expression?: string;\n /** Kolon sırası (FR-043). */\n sort?: \"asc\" | \"desc\";\n /** NULL sırası (FR-043). */\n nulls?: \"first\" | \"last\";\n /** Covering index — `INCLUDE (...)` (FR-043). */\n include?: string[];\n}\n\n/**\n * Tablo düzeyi çok sütunlu FOREIGN KEY'in wire şekli — Go'nun `ForeignKeyJSON`'ı\n * ile ALAN-ADI SÖZLEŞMESİ (FR-001). Bir ad değişirse wire sessizce kopar.\n *\n * `onUpdate`/`onDelete`/`match` sıfır değerinde OMIT: bildirmeyen bir FK\n * Postgres'in varsayılanını (NO ACTION / MATCH SIMPLE) alır ve telde yer\n * kaplamaz (NFR-006).\n */\nexport interface ForeignKeyJSON {\n name: string;\n columns: string[];\n refTable: string;\n refColumns: string[];\n onUpdate?: string;\n onDelete?: string;\n match?: string;\n}\n\n/**\n * Koşullu FK'nın (\"donan demet\") wire şekli — Go'nun `FreezeJSON`'ı ile\n * ALAN-ADI SÖZLEŞMESİ (C-8, FR-012).\n *\n * `when` politika ifade yapısının ta kendisi — `IndexJSON.where` ile aynı\n * duruş: üçüncü bir yüklem lehçesi açmak, aynı sorunun iki yazımı demekti.\n * Alanların hiçbiri opsiyonel değil: bir freeze'in koşulu, donan sütunları ve\n * hedefi olmadan anlamı yok ve `toFreezeDef` bunları bildirim anında şart\n * koşuyor. Sıfır değerde OMIT edilen şey DİZİNİN KENDİSİ (`TableJSON.freeze`).\n */\nexport interface FreezeJSON {\n name: string;\n when: unknown;\n columns: string[];\n refTable: string;\n refColumns: string[];\n}\n\n/**\n * Bir guard'ın wire şekli — Go'nun `GuardJSON`'ı ile ALAN-ADI SÖZLEŞMESİ\n * (C-4/C-8, FR-015).\n *\n * `when` ile `exists` AYRI alanlar: Postgres bir trigger'ın `WHEN` yan\n * tümcesinde alt sorguya izin vermiyor (`cannot use subquery in trigger WHEN\n * condition`), yani çapraz satır yüklemi gövdedeki `EXISTS` bloğuna inmek\n * zorunda (FR-019). Ayrımı emitter'ın yükleme bakıp tahmin etmesi yerine wire'da\n * taşımak, o kuralı bildirimin kendi şekline yazar.\n *\n * `detail`/`hint`/`column` sıfır değerde OMIT — bildirmeyen bir guard telde yer\n * kaplamaz (NFR-006). `message` her zaman var: reddin kullanıcıya ulaşan tek\n * çıktısı o.\n */\nexport interface GuardJSON {\n name: string;\n event: string;\n when?: unknown;\n exists?: unknown;\n message: string;\n detail?: string;\n hint?: string;\n column?: string;\n}\n\n/**\n * Bir backfill'in wire şekli — Go'nun `BackfillJSON`'ı ile ALAN-ADI SÖZLEŞMESİ\n * (C-8, FR-033).\n *\n * `name` kimliğin TAMAMI: \"koştu mu\" sorusu ona göre cevaplanıyor, `sql`'e göre\n * değil. Aynı adın altında değişen bir gövde ikinci bir koşu üretmez.\n */\nexport interface BackfillJSON {\n name: string;\n sql: string;\n}\n\n/** C-11 wire şekli — Go'nun MemoryJSON'ıyla alan-adı sözleşmesi (D-019).\n * Beyansız tablolarda alan OMIT — eski şemalar bayt-aynı (NFR-B1). */\nexport interface MemoryJSON {\n from: string[];\n into: string;\n subject?: string;\n extract: { provider: string; model: string };\n}\n\n/** A whole declaration. Mirrors Go's `schema.SchemaJSON`. */\nexport interface SchemaJSON {\n tables: Record<string, TableJSON>;\n extensions: string[];\n /**\n * Every declared schema, with its HTTP reachability.\n *\n * The flag has nowhere else to live: `/v1/db` must know which schemas are\n * reachable, and introspection must know which schemas the project DECLARED —\n * a live database also contains internal module schemas that are none of the\n * diff's business.\n */\n schemas: SchemaMetaJSON[];\n}\n\nexport interface SchemaMetaJSON {\n name: string;\n exposed: boolean;\n}\n\n/** The definition behind a column, whichever side of the builder it arrives on. */\nfunction defOf(column: ColumnBuilder | ColumnDef): ColumnDef {\n return \"_def\" in column ? column._def : column;\n}\n\nfunction columnToJSON(column: ColumnBuilder | ColumnDef): ColumnJSON {\n const def = defOf(column);\n const out: ColumnJSON = {\n type: def.type,\n nullable: def.nullable,\n primaryKey: def.primaryKey,\n };\n // Every optional field is omitted rather than emitted as undefined: Go\n // distinguishes \"absent\" from \"present and empty\" on several of these, and a\n // `defaultValue: null` is a real default that says NULL.\n if (def.defaultValue !== undefined) out.defaultValue = def.defaultValue;\n if (def.defaultRandom === true) out.defaultRandom = true;\n if (def.defaultNow === true) out.defaultNow = true;\n if (def.renamedFrom !== undefined) out.renamedFrom = def.renamedFrom;\n // Go'daki schema.ColumnJSON'un aynası. `omitempty` karşılığı: yalnız TRUE ise yazılır,\n // böylece işaretsiz bir şemanın JSON'u bu alandan önceki hâliyle byte-eş kalır.\n if (def.ignored === true) out.ignored = true;\n // OWNERSHIP HAS TO CROSS THE WIRE, because the gate that enforces it is on the\n // other side. `ownedByUser()` sets `owns` on the column, and Go's\n // `validateOwnership` reads `ColumnJSON.Owns` to refuse a table that declares\n // two owners — but nothing was carrying the flag between them.\n //\n // Measured on the live cluster: a table with TWO `ownedByUser()` columns\n // pushed clean and both foreign keys landed on `auth.users` ON DELETE CASCADE.\n // The rule existed in the DSL and in the generator; the wire in between said\n // nothing, so the generator saw ZERO ownership columns and had nothing to\n // refuse. A flag with a reader and no writer is a dead wire.\n if (def.owns === true) out.owns = true;\n if (def.references !== undefined) {\n out.references = { table: def.references.table, column: def.references.column };\n }\n if (def.onDeleteAction !== undefined) out.onDeleteAction = def.onDeleteAction;\n // Yalnız `false` taşınıyor: \"bildirilmedi\" ile \"açık\" aynı şey ve wire'a\n // yazmak bildirmeyen her kolonu diff'te değişmiş gösterirdi.\n if (def.index === false) out.index = false;\n if (def.counter === true) out.counter = true;\n if (def.enumName !== undefined) out.enumName = def.enumName;\n if (def.enumValues !== undefined) out.enumValues = [...def.enumValues];\n if (def.unique === true) out.unique = true;\n if (def.dimensions !== undefined) out.dimensions = def.dimensions;\n return out;\n}\n\nfunction policyToJSON(policy: PolicyDef): PolicyJSON {\n return {\n name: policy.name,\n command: policy.command ?? \"all\",\n roles: policy.roles ? [...policy.roles] : [],\n // null rather than omitted: a policy with no USING clause is a different\n // thing from one whose clause the emitter forgot, and Go reads the\n // difference.\n using: policy.using ?? null,\n withCheck: policy.withCheck ?? null,\n permissive: policy.permissive !== false,\n };\n}\n\n/** C-4 wire şekli — Go'nun SearchJSON'ıyla ALAN ADI sözleşmesi (C-5).\n * `mode`/`chunks` yalnız yeni-biçim chunk-modunda emit edilir (D-010);\n * satır-modu ve eski biçim bayt-aynı kalır (NFR-B1). */\nexport interface SearchJSON {\n text?: { columns: string[] };\n vector?: {\n column?: string;\n metric: string;\n embed?: { provider: string; model: string; from: string[]; apiKeyName?: string; dimensions?: number; baseURL?: string };\n staleness?: \"null\" | \"keep\";\n mode?: \"row\" | \"chunks\";\n chunks?: { sizeChars?: number; overlapChars?: number };\n }[];\n /** FR-026: sorgu-yeniden-yazımı haritası — beyan yoksa OMIT (NFR-B1). */\n synonyms?: Record<string, string[]>;\n /** C-1: sonuç yeniden-sıralama beyanı — beyan yoksa OMIT. */\n /** FR-029: geçerlilik türevleri — beyan yoksa OMIT. */\n validity?: boolean;\n}\n\n/** T020 (C-1): iki biçimin de üst-düzey ortak alanları — beyan yoksa OMIT,\n * boş synonyms haritası da OMIT (NFR-B1 baytları kımıldamaz). */\nfunction commonSearchFields(search: SearchDecl, out: SearchJSON): void {\n if (search.synonyms !== undefined && Object.keys(search.synonyms).length > 0) {\n out.synonyms = Object.fromEntries(\n Object.entries(search.synonyms).map(([word, alts]) => [word, [...alts]]),\n );\n }\n if (search.validity === true) out.validity = true;\n}\n\n/** Beyanı normalize eder: vector her zaman DİZİ, metric her zaman dolu (vars. cosine),\n * authoring'deki `from`/`model` wire'da `embed` altında toplanır. Alan yoksa OMIT —\n * search'süz şema bayt-aynı kalır (NFR-006). */\nfunction searchToJSON(search: SearchDecl, vectorColumn: string | undefined): SearchJSON {\n if (search.from !== undefined && search.model !== undefined) {\n // YENİ biçim (D-007): from tek listedir — FTS'i de embed'i de besler.\n // Mod ŞEMADAN türer (D-010): tabloda vector kolonu varsa satır-modu\n // (column yazılır, mode OMIT — eski davranışla aynı wire), yoksa\n // chunk-modu (mode:\"chunks\", column yok — vektörler türev tabloda).\n const out: SearchJSON = {};\n const textCols =\n search.text === false ? undefined : Array.isArray(search.text) && search.text.length > 0 ? search.text : search.from;\n if (textCols !== undefined) out.text = { columns: [...textCols] };\n const v: NonNullable<SearchJSON[\"vector\"]>[number] = { metric: search.metric ?? \"cosine\" };\n if (vectorColumn !== undefined) v.column = vectorColumn;\n v.embed = {\n provider: search.model.provider,\n model: search.model.model,\n from: [...search.from],\n ...(search.model.apiKeyName !== undefined ? { apiKeyName: search.model.apiKeyName } : {}),\n ...(search.model.dimensions !== undefined ? { dimensions: search.model.dimensions } : {}),\n ...(search.model.baseURL !== undefined ? { baseURL: search.model.baseURL } : {}),\n };\n if (search.staleness !== undefined) v.staleness = search.staleness;\n if (vectorColumn === undefined) {\n v.mode = \"chunks\";\n if (search.chunks !== undefined) {\n const c: NonNullable<typeof v.chunks> = {};\n if (search.chunks.size !== undefined && search.chunks.size > 0) c.sizeChars = search.chunks.size;\n if (search.chunks.overlap !== undefined && search.chunks.overlap > 0) c.overlapChars = search.chunks.overlap;\n if (Object.keys(c).length > 0) v.chunks = c;\n }\n }\n out.vector = [v];\n commonSearchFields(search, out);\n return out;\n }\n const out: SearchJSON = {};\n // Eski biçimde text yalnız dizi olabilir (boolean'ı defineSchema zaten\n // reddediyor); Array.isArray hem tipi daraltır hem o sözleşmeyi belgeler.\n if (Array.isArray(search.text) && search.text.length > 0) out.text = { columns: [...search.text] };\n const legs = search.vector === undefined ? []\n : Array.isArray(search.vector) ? search.vector : [search.vector];\n if (legs.length > 0) {\n out.vector = legs.map((leg) => {\n const v: NonNullable<SearchJSON[\"vector\"]>[number] = { metric: leg.metric ?? \"cosine\" };\n if (leg.column !== undefined) v.column = leg.column;\n if (leg.staleness !== undefined) v.staleness = leg.staleness;\n if (leg.model !== undefined) {\n v.embed = {\n provider: leg.model.provider,\n model: leg.model.model,\n from: [...(leg.from ?? [])],\n ...(leg.model.apiKeyName !== undefined ? { apiKeyName: leg.model.apiKeyName } : {}),\n ...(leg.model.dimensions !== undefined ? { dimensions: leg.model.dimensions } : {}),\n ...(leg.model.baseURL !== undefined ? { baseURL: leg.model.baseURL } : {}),\n };\n }\n return v;\n });\n }\n commonSearchFields(search, out);\n return out;\n}\n\nfunction memoryToJSON(m: MemoryDecl): MemoryJSON {\n return {\n from: [...m.from],\n into: m.into,\n ...(m.subject !== undefined ? { subject: m.subject } : {}),\n extract: { provider: m.extract.provider, model: m.extract.model },\n };\n}\n\nfunction tableToJSON(table: TableDef, schemaName: string): TableJSON {\n const columns: Record<string, ColumnJSON> = {};\n for (const [name, column] of Object.entries(table.columns)) {\n columns[name] = columnToJSON(column);\n }\n\n const out: TableJSON = {\n name: table.name,\n schema: schemaName,\n columns,\n // Read, not re-derived. `defineSchema` already resolves the fail-closed\n // default (RLS on unless the author wrote `rls: false`, and forced on by any\n // policy), and a second copy of a SECURITY default is exactly the thing that\n // drifts — the direction it drifted last time was \"expose everything\", and\n // the live proof was one user reading another's rows.\n rls: table.rls,\n // KOŞAN SÜRÜMÜN SÖZÜ TELE ÇIKAR — yoksa daralma kapısı onu göremez.\n // `ColumnJSON.ignored` ile aynı sözleşme: işaretlenmemişse alan YOK.\n ...(table.ignored === true ? { ignored: true } : {}),\n policies: (table.policies ?? []).map(policyToJSON),\n };\n\n if (table.primaryKey !== undefined && table.primaryKey.length > 0) {\n out.primaryKey = [...table.primaryKey];\n }\n if (table.unique !== undefined && table.unique.length > 0) {\n out.uniqueConstraints = table.unique.map((u) => ({ name: u.name, columns: [...u.columns] }));\n }\n if (table.raw !== undefined && table.raw.length > 0) {\n out.rawConstraints = table.raw.map((r) => ({ name: r.name, up: r.up }));\n }\n if (table.checks !== undefined && table.checks.length > 0) {\n out.checks = table.checks.map((c) => ({ name: c.name, expr: c.expr }));\n }\n if (table.indexes !== undefined && table.indexes.length > 0) {\n out.indexes = table.indexes.map((i) => {\n // `columns` expression-index'te YOKTUR (ikisi birbirinin alternatifi).\n // Boş dizi ile taşınır: Go tarafı `expression` doluysa onu kullanır.\n const ix: IndexJSON = { name: i.name, columns: i.columns ? [...i.columns] : [] };\n if (i.unique === true) ix.unique = true;\n if (i.where !== undefined) ix.where = i.where;\n if (i.expression !== undefined) ix.expression = i.expression;\n if (i.sort !== undefined) ix.sort = i.sort;\n if (i.nulls !== undefined) ix.nulls = i.nulls;\n if (i.include !== undefined) ix.include = [...i.include];\n return ix;\n });\n }\n if (table.dropConstraints !== undefined && table.dropConstraints.length > 0) {\n out.dropConstraints = [...table.dropConstraints];\n }\n if (table.foreignKeys !== undefined && table.foreignKeys.length > 0) {\n out.foreignKeys = table.foreignKeys.map((fk) => {\n const j: ForeignKeyJSON = {\n name: fk.name,\n columns: [...fk.columns],\n refTable: fk.refTable,\n refColumns: [...fk.refColumns],\n };\n if (fk.onUpdate !== undefined) j.onUpdate = fk.onUpdate;\n if (fk.onDelete !== undefined) j.onDelete = fk.onDelete;\n if (fk.match !== undefined) j.match = fk.match;\n return j;\n });\n }\n if (table.freeze !== undefined && table.freeze.length > 0) {\n out.freeze = table.freeze.map((f) => ({\n name: f.name,\n when: f.when,\n columns: [...f.columns],\n refTable: f.refTable,\n refColumns: [...f.refColumns],\n }));\n }\n if (table.guards !== undefined && table.guards.length > 0) {\n out.guards = table.guards.map((g) => ({\n name: g.name,\n event: g.event,\n ...(g.when !== undefined ? { when: g.when } : {}),\n ...(g.exists !== undefined ? { exists: g.exists } : {}),\n message: g.message,\n ...(g.detail !== undefined ? { detail: g.detail } : {}),\n ...(g.hint !== undefined ? { hint: g.hint } : {}),\n ...(g.column !== undefined ? { column: g.column } : {}),\n }));\n }\n if (table.backfills !== undefined && table.backfills.length > 0) {\n out.backfills = table.backfills.map((b) => ({ name: b.name, sql: b.sql }));\n }\n // Sıfır değerde YAZILMAZ: `appendOnly: false` ile \"bildirilmemiş\" wire'da\n // ayırt edilemez olmalı, yoksa her eski şema diff'te değişmiş görünür.\n if (table.appendOnly === true) out.appendOnly = true;\n if (table.search !== undefined) {\n // D-010 mod kararının tek girdisi: tabloda dimensions'lı (vector) kolon\n // adı. Birden çoksa ilkini yazmak YANLIŞ olurdu — o durum eski biçimin\n // işidir ve yeni biçim + çoklu vector kolonu apply'da reddedilir.\n const vectorColumn = Object.entries(columns).find(([, c]) => c.dimensions !== undefined)?.[0];\n const sj = searchToJSON(table.search, vectorColumn);\n if (sj.text !== undefined || sj.vector !== undefined) out.search = sj;\n }\n if (table.memory !== undefined) {\n out.memory = memoryToJSON(table.memory);\n }\n return out;\n}\n\n/**\n * The key a table answers to in `SchemaJSON.tables`.\n *\n * A public table is BARE, anything else is schema-qualified. This is not a new\n * convention: `RefJSON.Table` already carries `auth.users`, and introspection\n * already returns a public referent bare and a non-public one qualified. Adding\n * a second key space would make two interpreters of the same database.\n */\nexport function qualifiedTableKey(schemaName: string, tableName: string): string {\n // An ABSENT schema means public, exactly as Go's `isPublicSchema` says. This\n // branch used to be missing here and present in the engine's private copy, so\n // the two writers of one rule answered DIFFERENTLY for `\"\"`: one qualified it\n // into a schema literally named the empty string, the other left it bare.\n return schemaName === \"\" || schemaName === \"public\" ? tableName : `${schemaName}.${tableName}`;\n}\n\n/**\n * Serialize declared schemas into the JSON the deploy applies.\n *\n * Takes every schema the project declares — one file per schema — because a\n * cross-schema foreign key can only be checked when both ends are in hand.\n */\nexport function toSchemaJSON(schemas: readonly SchemaDef[]): SchemaJSON {\n const tables: Record<string, TableJSON> = {};\n const extensions: string[] = [];\n const meta: SchemaMetaJSON[] = [];\n const seen = new Set<string>();\n for (const schema of schemas) {\n if (seen.has(schema.name)) {\n throw new Error(`two schemas declare the name \"${schema.name}\" — schema names must be unique`);\n }\n seen.add(schema.name);\n for (const table of Object.values(schema.tables)) {\n const json = tableToJSON(table, schema.name);\n tables[qualifiedTableKey(schema.name, json.name)] = json;\n }\n extensions.push(...(schema.extensions ?? []));\n // The schema list travels because the flag has nowhere else to live: without\n // it /v1/db cannot know which schemas are reachable over HTTP, and nothing\n // downstream can read the DECLARED schema set that introspection needs.\n meta.push({ name: schema.name, exposed: schema.exposed });\n }\n return { tables, extensions: [...new Set(extensions)], schemas: meta };\n}\n","/** PostgreSQL protocol identifiers, shared by error mapping and retry policy. */\nexport const SQLSTATE = Object.freeze({\n serializationFailure: \"40001\",\n deadlockDetected: \"40P01\",\n queryCancelled: \"57014\",\n commandGuardFailed: \"PBC01\",\n} as const);\n\n/** These errors confirm that PostgreSQL aborted the transaction. A connection\n * failure does not: the COMMIT may already have succeeded. */\nexport function isTransactionRollbackState(state: unknown): boolean {\n return state === SQLSTATE.serializationFailure || state === SQLSTATE.deadlockDetected;\n}\n","import { SQLSTATE, isTransactionRollbackState } from \"./db/sqlstate.js\";\n\n/**\n * The brand that identifies an HttpError ACROSS SDK instances.\n *\n * A process legitimately holds more than one copy of this SDK — the runtime\n * loads the engine from its own node_modules while the tenant's bundle carries\n * an inlined copy, which is why the controller registry and the error registry\n * are both anchored on `Symbol.for`. The one place that did not follow the\n * pattern was the engine's catch: `err instanceof HttpError` compares CLASS\n * IDENTITY, so a `throw new NotFound()` from the bundle's copy did not match\n * the engine's copy and every typed error in every deployed backend degraded to\n * `500 internal_error`. Measured through the edge on a real deploy: a route\n * throwing `NotFound` answered 500 while the runtime's own log printed the\n * error object with `status: 404` right beside it.\n *\n * `Symbol.for` puts this in the cross-realm registry, so every copy of the SDK\n * agrees on it by VALUE rather than by identity.\n */\nexport const HTTP_ERROR_BRAND: unique symbol = Symbol.for(\"palbase.backend.httpError\");\n\n/**\n * Set on an `HttpError` the ENGINE built out of a driver failure, as opposed to\n * one the author constructed to ANSWER a request.\n *\n * The distinction cannot be read off the status, and 409 is why. The scaffold\n * teaches `throw new Conflict(\"title already taken\")` as the way to answer\n * (template/AGENTS.md), and the engine raises `UniqueViolation` — also a 409 —\n * when a write hits a unique index. Logging by status therefore either loses the\n * engine's event or writes an \"unhandled\" line every time an author takes the\n * documented path. Measured: it did the second.\n *\n * `Symbol.for` so the mark survives the bundle/runtime SDK split, the same way\n * {@link HTTP_ERROR_BRAND} does.\n */\nexport const ENGINE_RAISED: unique symbol = Symbol.for(\"palbase.backend.engineRaised\") as never;\n\n/** Mark `e` as engine-raised and return it, so a conversion site reads as one expression. */\nexport function markEngineRaised<E extends object>(e: E): E {\n (e as Record<symbol, unknown>)[ENGINE_RAISED] = true;\n return e;\n}\n\n/** Whether the engine built this error, rather than the author throwing it to answer. */\nexport function isEngineRaised(e: unknown): boolean {\n return typeof e === \"object\" && e !== null && (e as Record<symbol, unknown>)[ENGINE_RAISED] === true;\n}\n\n/**\n * Whether a thrown value is an HttpError from ANY copy of this SDK.\n *\n * The shape is checked as well as the brand: the brand says \"this claims to be\n * one of ours\", the fields say the envelope can actually be built from it, and\n * a half-formed object must fall through to the 500 path rather than produce a\n * malformed response.\n */\nexport function isHttpError(err: unknown): err is HttpError {\n if (typeof err !== \"object\" || err === null) return false;\n const e = err as Record<PropertyKey, unknown>;\n return (\n e[HTTP_ERROR_BRAND] === true &&\n typeof e.status === \"number\" &&\n typeof e.error === \"string\" &&\n typeof e.errorDescription === \"string\"\n );\n}\n\n/** HTTP error with structured error response format.\n *\n * The base class for the throwable error classes (`PalError`, `Conflict`,\n * `NotFound`, …). Construct one directly with `throw new HttpError(404,\n * \"todo_not_found\", \"No such todo\")`, or throw a named subclass\n * (`throw new NotFound(\"todo not found\")`). The runtime catches any `HttpError`\n * and emits the standard envelope; on the wire (and to iOS) it surfaces as\n * `BackendError.server(code, status, message, requestId)`.\n *\n * The optional `data` field carries a structured payload alongside the\n * standard envelope — for errors that need to ship extra context\n * (e.g. `new Conflict(\"locked\", \"title_locked\", { retryAfter: 30 })`). It rides\n * through to the iOS typed enum's associated value.\n */\nexport class HttpError extends Error {\n public readonly status: number;\n public readonly error: string;\n public readonly errorDescription: string;\n public readonly data?: unknown;\n /** See {@link HTTP_ERROR_BRAND} — how the engine recognises this across SDK copies. */\n public readonly [HTTP_ERROR_BRAND] = true;\n\n constructor(status: number, error: string, errorDescription: string, data?: unknown) {\n super(errorDescription);\n this.name = \"HttpError\";\n this.status = status;\n this.error = error;\n this.errorDescription = errorDescription;\n if (data !== undefined) {\n this.data = data;\n }\n }\n\n /**\n * Serialize to the standard Palbase error response format.\n * The `requestId` is injected by the runtime layer from the request context.\n * When called without arguments (e.g. JSON.stringify), request_id is omitted.\n * When `data` is set, it is appended as a strict-superset field.\n */\n toJSON(requestId?: string): {\n error: string;\n error_description: string;\n status: number;\n request_id?: string;\n data?: unknown;\n } {\n const result: {\n error: string;\n error_description: string;\n status: number;\n request_id?: string;\n data?: unknown;\n } = {\n error: this.error,\n error_description: this.errorDescription,\n status: this.status,\n };\n if (requestId) {\n result.request_id = requestId;\n }\n if (this.data !== undefined) {\n result.data = this.data;\n }\n return result;\n }\n}\n\n/**\n * Throw with a custom HTTP status + wire code. The general-purpose escape hatch\n * when none of the named classes (`Conflict`/`NotFound`/…) fits.\n *\n * @example\n * throw new PalError(418, \"teapot\", \"I'm a teapot\");\n */\nexport class PalError extends HttpError {\n constructor(status: number, code: string, description: string, data?: unknown) {\n super(status, code, description, data);\n this.name = \"PalError\";\n }\n}\n\n/** Base for the named status classes. Each subclass fixes its HTTP status; the\n * `code` defaults to the class's canonical wire code (overridable), and the\n * `message` defaults to a human-readable label (overridable). */\nabstract class NamedHttpError extends HttpError {\n protected constructor(\n status: number,\n defaultCode: string,\n name: string,\n message?: string,\n code?: string,\n data?: unknown,\n ) {\n super(status, code ?? defaultCode, message ?? defaultMessage(name), data);\n this.name = name;\n }\n}\n\n/** Derive a default human-readable message from a class name\n * (\"NotFound\" → \"Not found\", \"TooManyRequests\" → \"Too many requests\"). */\nfunction defaultMessage(name: string): string {\n const spaced = name.replace(/([a-z0-9])([A-Z])/g, \"$1 $2\");\n return spaced.charAt(0).toUpperCase() + spaced.slice(1).toLowerCase();\n}\n\n/**\n * 400 — the request was malformed or failed validation. Carries a fixed typed\n * payload: `new BadRequest({ fields: [{ field: \"email\", message: \"invalid\" }] })`.\n * The shape is declared once in the SDK so codegen surfaces `error.data.fields`\n * typed on the client.\n */\nexport class BadRequest extends NamedHttpError {\n public declare readonly data: BadRequestData;\n constructor(data: BadRequestData, message?: string) {\n super(400, \"bad_request\", \"BadRequest\", message, undefined, data);\n }\n}\n\n/** 401 — the caller is not authenticated. */\nexport class Unauthorized extends NamedHttpError {\n constructor(message?: string, code?: string, data?: unknown) {\n super(401, \"unauthorized\", \"Unauthorized\", message, code, data);\n }\n}\n\n/** 403 — the caller is authenticated but not allowed. */\nexport class Forbidden extends NamedHttpError {\n constructor(message?: string, code?: string, data?: unknown) {\n super(403, \"forbidden\", \"Forbidden\", message, code, data);\n }\n}\n\n/** 404 — the requested resource does not exist. */\nexport class NotFound extends NamedHttpError {\n constructor(message?: string, code?: string, data?: unknown) {\n super(404, \"not_found\", \"NotFound\", message, code, data);\n }\n}\n\n/** 409 — the request conflicts with the current state. */\nexport class Conflict extends NamedHttpError {\n constructor(message?: string, code?: string, data?: unknown) {\n super(409, \"conflict\", \"Conflict\", message, code, data);\n }\n}\n\n/**\n * 409 — a write was refused because it would duplicate an existing row.\n * Carries the NAME of the unique constraint Postgres named (`users_email_key`).\n *\n * The engine produces it: a statement rejected with SQLSTATE `23505` is\n * converted here rather than surfacing as an opaque driver error (see\n * `engine/db.ts`, `diagnosingDriver`). What that removes is the string match —\n * before this, the only way to act on a duplicate was to test the driver\n * message for \"duplicate key value violates unique constraint\", a contract\n * nobody signed that breaks on a Postgres upgrade, a locale, or a constraint\n * rename, silently and in production.\n *\n * THE NAME IS A FIELD AND STAYS OUT OF THE DEFAULT MESSAGE. The two are not\n * the same audience. `constraint` is read by the code that catches this — the\n * developer, who already knows the schema. `errorDescription` is the HTTP\n * response body, and an UNCAUGHT duplicate puts it in front of the\n * application's end user: `users_email_key` there discloses how the schema is\n * built to whoever sent the request. The platform's own data API took the same\n * decision one surface over and wrote down why —\n * `v2/internal/modules/database/internal/handler/pgerror.go:83-87` collapses\n * every 23xxx to a generic conflict, \"never disclose the constraint/column\n * name\". A thrower who WANTS the name on the wire passes it deliberately\n * (`new UniqueViolation(c, \\`\\${c} already exists\\`)`, or through `data`).\n *\n * @example\n * try {\n * await Database.public.users.insert({ email });\n * } catch (e) {\n * if (UniqueViolation.is(e) && e.constraint === \"users_email_key\") {\n * throw new Conflict(\"That email is taken\", \"email_taken\");\n * }\n * throw e;\n * }\n */\nexport class UniqueViolation extends Conflict {\n /**\n * Whether `e` is a unique violation — REGARDLESS of which copy of this SDK\n * constructed it.\n *\n * Use this instead of `instanceof`. Measured on a live stack: a controller\n * bundle INLINES its own copy of `@palbase/backend`, and the engine that\n * raises this error is the runtime's copy. Two copies, two class identities,\n * and `e instanceof UniqueViolation` is false in the one place a caller\n * writes it — a check that reads as correct and silently never matches.\n */\n static is(e: unknown): e is UniqueViolation {\n return (\n typeof e === \"object\" &&\n e !== null &&\n (e as { name?: unknown }).name === \"UniqueViolation\" &&\n typeof (e as { constraint?: unknown }).constraint === \"string\"\n );\n }\n\n /** The unique constraint the statement violated, as Postgres named it.\n * `\"\"` when the driver did not say which — see `engine/db.ts`. */\n public readonly constraint: string;\n\n constructor(constraint: string, message?: string, code?: string, data?: unknown) {\n super(message ?? \"Unique constraint violated\", code ?? \"unique_violation\", data);\n this.name = \"UniqueViolation\";\n this.constraint = constraint;\n }\n}\n\n/**\n * Eşzamanlılık yüzünden BAŞARISIZ OLAN, ama TEKRAR DENENİRSE başarılı olabilecek\n * hataların ortak yüzeyi (FR-036).\n *\n * `retryable: true` bir tahmin değil, Postgres'in söylediği şey: `40001` ve\n * `40P01` \"bu işlemi baştan çalıştır\" anlamına gelir. Kümenin DAR tutulması\n * kasıtlı — `23505` buraya girseydi, tekrar denemek aynı cevabı verir ve\n * döngü sonsuza kadar dönerdi.\n */\nexport interface RetryableError extends Error {\n readonly retryable: true;\n /** Beş karakterlik SQLSTATE — hangi eşzamanlılık hatası olduğunu SÖYLER. */\n readonly sqlstate: string;\n}\n\n/**\n * `e` tekrar denenebilir mi?\n *\n * `instanceof` DEĞİL şekil kontrolü — ve sebebi ÖLÇÜLMÜŞ (bkz. {@link\n * UniqueViolation.is}): bir controller bundle'ı kendi `@palbase/backend`\n * kopyasını inline'lıyor, hatayı fırlatan motor ise runtime'ın kopyası. İki\n * sınıf kimliği, ve `e instanceof SerializationFailure` yazan tek yerde\n * sessizce hiç eşleşmiyor.\n */\nexport function isRetryable(e: unknown): e is RetryableError {\n return (\n typeof e === \"object\" &&\n e !== null &&\n (e as { retryable?: unknown }).retryable === true &&\n isTransactionRollbackState((e as { sqlstate?: unknown }).sqlstate)\n );\n}\n\n/**\n * `40001 serialization_failure` — SERIALIZABLE ya da REPEATABLE READ altında\n * eşzamanlı bir işlem bu işlemi geçersiz kıldı.\n *\n * D-016: bu hata BLOKLANMIYOR, FIRLATILIYOR. Retry'sız bir izolasyon\n * yükseltmesi sunmak defect'tir — kullanıcıya çalışmayan bir düğme vermektir:\n * SERIALIZABLE'a çıkıp `40001`'i yakalamayan kod, önceden çalışan işlemleri\n * rastgele kaybetmeye başlar.\n */\nexport class SerializationFailure extends Conflict implements RetryableError {\n public readonly retryable = true as const;\n public readonly sqlstate: string;\n\n static is(e: unknown): e is SerializationFailure {\n return (\n typeof e === \"object\" && e !== null &&\n (e as { name?: unknown }).name === \"SerializationFailure\"\n );\n }\n\n constructor(sqlstate: string = SQLSTATE.serializationFailure, message?: string, data?: unknown) {\n super(\n message ??\n \"işlem eşzamanlı bir işlemle serileştirilemedi — aynı işlemi baştan çalıştırın \" +\n \"(karar okumaları ve yazmaları $atomic içine alıp { retry: n } verin)\",\n \"serialization_failure\",\n data,\n );\n this.name = \"SerializationFailure\";\n this.sqlstate = sqlstate;\n }\n}\n\n/**\n * `40P01 deadlock_detected` — iki işlem birbirinin kilidini bekliyordu;\n * Postgres birini seçip iptal etti.\n *\n * Bu hatayı GÖRMEK bir tasarım sinyali: kilit sırası deterministik değilse\n * tekrar denemek yalnız maliyeti öteler. Sırayı sabitleyen üç şey var ve\n * hangisinin geçerli olduğunu ELİNDEKİ belirler: satırların id'leri elindeyse\n * `Database.$lockRows(tablo, id'ler)`, elinde bir FİLTRE varsa\n * `Database.$lockRowsWhere(tablo, filtre)` (FR-037 — birincil anahtara göre\n * sıralayarak kilitler, yani `updateMany` ile aynı sırayı paylaşır), ya da çok\n * satırlı yazmanın CTE'si (FR-015).\n */\nexport class DeadlockDetected extends Conflict implements RetryableError {\n public readonly retryable = true as const;\n public readonly sqlstate: string;\n\n static is(e: unknown): e is DeadlockDetected {\n return (\n typeof e === \"object\" && e !== null &&\n (e as { name?: unknown }).name === \"DeadlockDetected\"\n );\n }\n\n constructor(sqlstate: string = SQLSTATE.deadlockDetected, message?: string, data?: unknown) {\n super(\n message ??\n \"deadlock: iki işlem birbirinin kilidini bekledi ve bu işlem iptal edildi — \" +\n \"kilit sırasını sabitleyin: id'ler elinizdeyse Database.$lockRows(tablo, id'ler), \" +\n \"elinizde bir filtre varsa Database.$lockRowsWhere(tablo, filtre) kullanın\",\n \"deadlock_detected\",\n data,\n );\n this.name = \"DeadlockDetected\";\n this.sqlstate = sqlstate;\n }\n}\n\n/** A single field-level validation failure carried by {@link BadRequest}. */\nexport interface FieldError {\n /** The offending field's name (dotted path for nested fields). */\n field: string;\n /** Human-readable reason the field failed. */\n message: string;\n}\n\n/** The fixed, typed payload {@link BadRequest} ships. */\nexport interface BadRequestData {\n /** The fields that failed validation. */\n fields: FieldError[];\n}\n\n/** The fixed, typed payload {@link TooManyRequests} ships. */\nexport interface TooManyRequestsData {\n /** Seconds the caller should wait before retrying. */\n retryAfter: number;\n}\n\n/**\n * 429 — the caller has exceeded the rate limit. Carries a fixed typed payload:\n * `new TooManyRequests({ retryAfter: 30 })`. The shape is declared once in the\n * SDK (error-registry pre-seed) so codegen surfaces `error.data.retryAfter`\n * typed on the client — no per-project definition needed.\n */\nexport class TooManyRequests extends NamedHttpError {\n public declare readonly data: TooManyRequestsData;\n constructor(data: TooManyRequestsData, message?: string) {\n super(429, \"too_many_requests\", \"TooManyRequests\", message, undefined, data);\n }\n}\n","/**\n * engine/config.ts — settings from the environment, and the gate that refuses\n * to boot without them.\n *\n * A mandatory module that is not configured must stop the process, by name.\n * The failure this prevents is the expensive one: a stack that boots, passes\n * its probes, and answers 500 on first contact — where the missing value is\n * discovered by a customer rather than by the operator who could fix it.\n *\n * Database and Auth are mandatory. That is a product decision (2026-08-14), not\n * a technical necessity: a backend whose data layer or whose notion of \"who is\n * calling\" is undefined has nothing safe to do with a request.\n */\n\n/** Everything the engine needs to serve. Built once, at boot, never re-read. */\nexport interface EngineConfig {\n /** Postgres connection string. MANDATORY. */\n databaseUrl: string;\n /** Where this stack publishes its token signing keys. MANDATORY. */\n authJwksUrl: string;\n /** When set, a token whose `iss` differs is rejected. */\n authIssuer?: string;\n /** Base URL of the module surface (`/v1/*`, `/auth/*`). Empty ⇒ module\n * singletons throw a named error on first use rather than silently no-op. */\n moduleBaseUrl: string;\n /**\n * The address CLIENTS reach this stack at — `https://<ref>.palbase.studio` in\n * the cloud, whatever domain the certificate is for when self-hosted.\n *\n * NOT `moduleBaseUrl`, and the distinction is the whole point: that one is\n * this process's internal route to palsvc (`http://127.0.0.1:8080`), which\n * resolves nowhere outside the pod. A public object URL has to survive\n * leaving the response body, so it cannot be built from the internal one.\n *\n * Only the operator knows this value, so only the operator sets it\n * (`PALBASE_PUBLIC_ORIGIN`). Empty ⇒ `Storage…getPublicUrl()` throws a named\n * error, the same way an unconfigured module does.\n */\n publicOrigin: string;\n /** Shared secret storage signs its internal upload calls with. Empty means\n * uploads are not wired, and those calls are refused. */\n uploadSecret: string;\n /** Publishable key, sent as `apikey` on module calls. */\n anonKey: string;\n /** Secret key. Used for privileged module calls. */\n serviceRoleKey: string;\n /** Optional dedicated cursor encryption secret, shared by all replicas. */\n cursorSecret?: string;\n /** Install the invoker-only PostgreSQL command helper at boot. Requires DDL\n * rights on the connection role; execution retains each request's RLS role. */\n enableCommands?: boolean;\n /** HMAC the realtime broadcast token is signed with. Empty ⇒ broadcast\n * returns a clear `realtime_unconfigured` error instead of failing silently. */\n realtimeSecret: string;\n port: number;\n /** The Postgres role each request is bound to. RLS policies are written\n * against it, so changing it changes who the database thinks is asking. */\n dbRole: string;\n /**\n * The Postgres role `Database.$asService()` is bound to. It is the one that\n * carries BYPASSRLS, which is the whole of what \"as service\" means — a name\n * pointing at a role without it does not fail, it returns fewer rows.\n *\n * Configurable for the same reason `dbRole` is, and beside it on purpose: a\n * stack that renames one of the pair must rename both, or the request and its\n * service sibling stop being two identities of the same installation.\n */\n dbServiceRole: string;\n poolMax: number;\n /** Internal engine/core deployment policy; application CRUD has no capacity options. */\n databaseAdmission?: Omit<import(\"./admission.js\").DatabaseAdmissionOptions, \"concurrency\">;\n databaseDiagnostics?: import(\"../db/diagnostics.js\").DatabaseDiagnosticsOptions;\n}\n\n/**\n * THE ENVIRONMENT THIS STACK WAS HANDED IS UNUSABLE. Carries the missing names.\n *\n * ONLY the environment. A refusal about the author's own declarations is\n * `DeclarationRefused` (see `src/refusals.ts`) and the difference is not\n * severity, it is the CURE: no push fixes a missing DATABASE_URL, so the\n * runtime must keep treating this one as fatal rather than waiting for an\n * artifact that would change nothing.\n */\nexport class BootRefused extends Error {\n readonly missing: readonly string[];\n constructor(missing: readonly string[], message: string) {\n super(message);\n this.name = \"BootRefused\";\n this.missing = missing;\n }\n}\n\nconst MANDATORY: ReadonlyArray<{ key: string; what: string }> = [\n { key: \"DATABASE_URL\", what: \"the stack's Postgres (Database module)\" },\n { key: \"AUTH_JWKS_URL\", what: \"where this stack publishes its token signing keys (Auth module)\" },\n];\n\n/**\n * Read the engine's settings, or refuse.\n *\n * @throws {BootRefused} naming every missing mandatory value at once — one\n * restart per missing variable is a bad way to learn what a stack needs.\n */\nexport function loadConfig(env: Record<string, string | undefined>): EngineConfig {\n const missing = MANDATORY.filter((m) => !env[m.key]?.trim()).map((m) => m.key);\n if (missing.length > 0) {\n const detail = MANDATORY.filter((m) => missing.includes(m.key))\n .map((m) => ` ${m.key.padEnd(16)}${m.what}`)\n .join(\"\\n\");\n throw new BootRefused(\n missing,\n `boot refused: mandatory module not configured — missing ${missing.join(\", \")}.\\n${detail}`,\n );\n }\n\n const port = Number(env.PORT ?? 3000);\n if (!Number.isInteger(port) || port < 0 || port > 65535) {\n throw new BootRefused([], `boot refused: PORT is not a valid port number (got ${env.PORT}).`);\n }\n const poolMax = Number(env.DB_POOL_MAX ?? 10);\n if (!Number.isInteger(poolMax) || poolMax < 1) {\n throw new BootRefused([], `boot refused: DB_POOL_MAX must be a positive integer (got ${env.DB_POOL_MAX}).`);\n }\n const capacityNumber = (key: string, minimum: number, maximum: number): number | undefined => {\n if (env[key] === undefined) return undefined;\n const value = Number(env[key]);\n if (!Number.isSafeInteger(value) || value < minimum || value > maximum) throw new BootRefused([], `boot refused: ${key} must be between ${minimum} and ${maximum}.`);\n return value;\n };\n const queueLimit = capacityNumber(\"PALBASE_DB_QUEUE_LIMIT\", 0, 10000);\n const queueTimeoutMs = capacityNumber(\"PALBASE_DB_QUEUE_TIMEOUT_MS\", 1, 60000);\n const tenantClaim = env.PALBASE_DB_TENANT_CLAIM;\n if (tenantClaim !== undefined && !/^[a-zA-Z][a-zA-Z0-9_]{0,63}$/.test(tenantClaim)) throw new BootRefused([], \"boot refused: PALBASE_DB_TENANT_CLAIM must be a top-level trusted claim name.\");\n\n return {\n databaseUrl: env.DATABASE_URL!.trim(),\n authJwksUrl: env.AUTH_JWKS_URL!.trim(),\n authIssuer: env.AUTH_ISSUER?.trim() || undefined,\n moduleBaseUrl: (env.MODULE_BASE_URL ?? \"\").replace(/\\/+$/, \"\"),\n publicOrigin: (env.PALBASE_PUBLIC_ORIGIN ?? \"\").trim().replace(/\\/+$/, \"\"),\n // The secret storage signs its two internal calls with (authorize, and the\n // completion that runs an @Upload handler). Empty means uploads are not\n // wired, and both calls REFUSE — an unsigned completion would let anyone\n // who knows a route path invent an upload that never happened.\n uploadSecret: env.PALBASE_UPLOAD_SECRET ?? \"\",\n anonKey: env.PALBASE_ANON_KEY ?? \"\",\n serviceRoleKey: env.PALBASE_SERVICE_ROLE_KEY ?? \"\",\n cursorSecret: env.PALBASE_CURSOR_SECRET,\n enableCommands: env.PALBASE_DB_COMMANDS === \"true\",\n realtimeSecret: env.REALTIME_INGESTION_SECRET ?? \"\",\n port,\n dbRole: env.DB_ROLE ?? \"backend_authenticated\",\n // Verified against the stack that provisions them, not from memory: the six\n // roles and their attributes are declared in v2/internal/migrate/provision.go\n // (`roleBackendServiceRole = \"backend_service_role\"`, NOLOGIN BYPASSRLS),\n // and the live database agrees (pg_roles.rolbypassrls = true).\n dbServiceRole: env.DB_SERVICE_ROLE ?? \"backend_service_role\",\n poolMax,\n databaseAdmission: { ...(queueLimit === undefined ? {} : { queueLimit }),\n ...(queueTimeoutMs === undefined ? {} : { queueTimeoutMs }), ...(tenantClaim === undefined ? {} : { tenantClaim }) },\n ...(env.PALBASE_DB_DIAGNOSTICS === \"true\" ? { databaseDiagnostics: {\n onComplete: (diagnostics: import(\"../db/diagnostics.js\").DatabaseDiagnostics) => {\n console.log(\"palbase.database\", JSON.stringify(diagnostics));\n },\n } } : {}),\n };\n}\n","/**\n * The two ways a stack refuses to boot — and they are two because their CURES\n * are two.\n *\n * A LEAF MODULE ON PURPOSE. `db/` does not import from `engine/` and must not\n * start: the schema layer is below the engine, and a refusal both of them raise\n * cannot live in either. Anything imported here would invert that.\n *\n * WHY THE SPLIT EXISTS AT ALL — measured live on 2026-09-04.\n *\n * `8qitbtucm` ran for days on an image whose `setSchema` did not build\n * relations. Moved onto one that does, the same artifact hit\n * `buildRelations` at boot, threw a bare `Error`, and the runtime — which waits\n * only on its own `ArtifactRefused` — treated it as fatal. The supervisor took\n * the pod down, palsvc with it. CrashLoopBackOff, back-off 5m, and palsvc is\n * THE PROCESS THAT ACCEPTS THE PUSH the message asks for.\n *\n * That is verbatim the lesson `v2/runtime/src/loader.ts` already carries for\n * ABI refusals: *\"the cure was named in the error and made impossible by the\n * exit that carried it.\"* It cost a tenant a third time because the second\n * refusal had no type to be recognised by.\n *\n * SO THE RULE IS THE CURE, NOT THE SEVERITY:\n *\n * {@link DeclarationRefused} — what was PUSHED cannot be built. Restarting\n * re-reads the same bytes and fails identically; only a new artifact\n * changes the answer. The runtime WAITS on this, keeps palsvc alive, and\n * says the reason out loud.\n *\n * {@link BootRefused} — the ENVIRONMENT this stack was handed is unusable\n * (no DATABASE_URL, an unparseable PORT, no SQL driver). No push fixes it;\n * waiting for one would be a lie told in a log line forever. Stays fatal.\n *\n * NOT A MESSAGE PATTERN. The runtime's loader already says why: *\"The\n * distinction is the loader's TYPE, not a pattern over its wording.\"* A gate\n * that reads wording drifts from the thing it claims to measure the first time\n * someone improves an error message.\n */\n\n/**\n * The tag that survives a realm boundary.\n *\n * `instanceof` compares constructor identity, and identity is per module\n * instance. In the pod today the runtime and the bundle share one install\n * (measured: both frames resolve to `/app/node_modules/@palbase/backend`), so\n * `instanceof` would work — but it works by a coincidence of packaging, and a\n * bundle that ever carries its own copy would make every declaration refusal\n * silently fatal again. `Symbol.for` reads from the process-wide registry, so\n * the tag means the same thing in every copy.\n *\n * Exported so the runtime can recognise the refusal without importing the\n * class — see {@link isDeclarationRefused}.\n */\nexport const DECLARATION_REFUSAL = Symbol.for(\"palbase.backend.declarationRefusal\");\n\n/**\n * What was pushed cannot be built. The cure is a NEW ARTIFACT.\n *\n * Thrown by the declaration layer — relation naming, ownership, entry points —\n * wherever a fact about the author's code makes the app impossible to\n * construct. Never thrown for anything the environment could change.\n */\nexport class DeclarationRefused extends Error {\n /** @see DECLARATION_REFUSAL — realm-safe, unlike `instanceof`. */\n readonly [DECLARATION_REFUSAL] = true as const;\n\n constructor(message: string) {\n super(message);\n this.name = \"DeclarationRefused\";\n }\n}\n\n/**\n * True for a refusal whose only cure is a new artifact — across realms.\n *\n * Takes `unknown` because every caller is a `catch`. A non-object, a null, a\n * plain `Error`: all false, and false is the safe answer — it means \"keep\n * treating this as fatal\", which is what the code did before this type existed.\n */\nexport function isDeclarationRefused(e: unknown): e is DeclarationRefused {\n return typeof e === \"object\" && e !== null && (e as Record<symbol, unknown>)[DECLARATION_REFUSAL] === true;\n}\n","/**\n * engine/auth.ts — verifying the stack's own access tokens.\n *\n * The engine does this itself rather than trusting a header stamped upstream.\n * In the isolate architecture a gateway verified the token and the runtime read\n * the result; a backend that boots on its own has no such upstream, so the\n * verification lives here — against the keys the stack publishes.\n *\n * Deliberately narrow: ES256 over P-256, which is what palauth mints. An\n * unrecognised `alg` is refused rather than accommodated, because the classic\n * JWT break is a verifier that is helpful about algorithms.\n */\n\n/** A JSON Web Key, narrowed to the EC keys this verifier accepts. */\ninterface EcJwk {\n kid: string;\n kty: string;\n crv: string;\n x: string;\n y: string;\n}\n\n/** The claims the engine reads. Everything else rides along untyped. */\nexport interface VerifiedClaims extends Record<string, unknown> {\n sub?: string;\n role?: string;\n email?: string;\n email_verified?: boolean;\n exp?: number;\n iss?: string;\n}\n\nfunction b64urlToBytes(s: string): Uint8Array<ArrayBuffer> {\n const pad = s.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const full = pad.padEnd(Math.ceil(pad.length / 4) * 4, \"=\");\n const bin = atob(full);\n // Backed by a plain ArrayBuffer so the result satisfies BufferSource — a\n // Uint8Array over ArrayBufferLike could be shared memory, which the WebCrypto\n // signatures reject.\n const out = new Uint8Array(new ArrayBuffer(bin.length));\n for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);\n return out;\n}\n\nexport interface AuthVerifierOptions {\n jwksUrl: string;\n issuer?: string;\n /** Injectable for tests; defaults to global fetch. */\n fetchImpl?: typeof fetch;\n /** How long a fetched keyset is trusted before it is fetched again. A key\n * rotation must become visible without a restart, and an unknown `kid` must\n * not be able to force a fetch per request (that is a free DoS lever). */\n keysetTtlMs?: number;\n}\n\nexport class AuthVerifier {\n private keys = new Map<string, CryptoKey>();\n private fetchedAt = 0;\n private inflight: Promise<void> | null = null;\n private readonly jwksUrl: string;\n private readonly issuer?: string;\n private readonly fetchImpl: typeof fetch;\n private readonly ttl: number;\n\n constructor(opts: AuthVerifierOptions) {\n this.jwksUrl = opts.jwksUrl;\n this.issuer = opts.issuer;\n this.fetchImpl = opts.fetchImpl ?? ((...a: Parameters<typeof fetch>) => fetch(...a));\n this.ttl = opts.keysetTtlMs ?? 5 * 60_000;\n }\n\n /** Fetch the keyset at most once per TTL, and at most once concurrently. */\n private async refresh(): Promise<void> {\n if (this.inflight) return this.inflight;\n this.inflight = (async () => {\n try {\n const res = await this.fetchImpl(this.jwksUrl);\n if (!res.ok) return;\n const body = (await res.json()) as { keys?: EcJwk[] };\n const next = new Map<string, CryptoKey>();\n for (const jwk of body.keys ?? []) {\n if (jwk.kty !== \"EC\" || jwk.crv !== \"P-256\") continue;\n try {\n next.set(\n jwk.kid,\n await crypto.subtle.importKey(\n \"jwk\",\n { kty: \"EC\", crv: jwk.crv, x: jwk.x, y: jwk.y, ext: true },\n { name: \"ECDSA\", namedCurve: \"P-256\" },\n true,\n [\"verify\"],\n ),\n );\n } catch {\n // A single malformed key must not blind the verifier to the rest.\n }\n }\n if (next.size > 0) {\n this.keys = next;\n this.fetchedAt = Date.now();\n }\n } finally {\n this.inflight = null;\n }\n })();\n return this.inflight;\n }\n\n private async key(kid: string): Promise<CryptoKey | null> {\n const stale = Date.now() - this.fetchedAt > this.ttl;\n if (!this.keys.has(kid) || stale) await this.refresh();\n return this.keys.get(kid) ?? null;\n }\n\n /**\n * Verify an `Authorization` header value.\n *\n * @returns the verified claims, or `null` for absent / malformed / expired /\n * wrong-issuer / bad-signature. One `null` for every failure on purpose:\n * the caller answers 401 either way, and a detailed reason is an oracle.\n */\n async verify(authorization: string | null | undefined): Promise<VerifiedClaims | null> {\n if (!authorization || !authorization.startsWith(\"Bearer \")) return null;\n const parts = authorization.slice(7).trim().split(\".\");\n if (parts.length !== 3) return null;\n const h = parts[0];\n const p = parts[1];\n const sig = parts[2];\n if (h === undefined || p === undefined || sig === undefined) return null;\n\n let header: { alg?: string; kid?: string };\n let claims: VerifiedClaims;\n try {\n header = JSON.parse(new TextDecoder().decode(b64urlToBytes(h)));\n claims = JSON.parse(new TextDecoder().decode(b64urlToBytes(p)));\n } catch {\n return null;\n }\n // `none`, `HS256`-with-the-public-key, and friends all die here.\n if (header.alg !== \"ES256\" || !header.kid) return null;\n\n const key = await this.key(header.kid);\n if (!key) return null;\n\n let ok = false;\n try {\n ok = await crypto.subtle.verify(\n { name: \"ECDSA\", hash: \"SHA-256\" },\n key,\n b64urlToBytes(sig),\n new TextEncoder().encode(`${h}.${p}`),\n );\n } catch {\n return null;\n }\n if (!ok) return null;\n if (typeof claims.exp === \"number\" && claims.exp * 1000 <= Date.now()) return null;\n if (this.issuer && claims.iss !== this.issuer) return null;\n return claims;\n }\n}\n\n/** What a route demands, after the route's own spec and the controller's\n * default have been reconciled. */\nexport interface EffectiveAuth {\n required: boolean;\n role?: string;\n /** The permission the route demands, as `resource.action`. Resolved against\n * `auth.has_permission(...)` at the gate — see AuthConfig.permission. */\n permission?: string;\n verifiedEmail: boolean;\n}\n\n/**\n * Reconcile route-level and controller-level auth.\n *\n * The route's own spec wins when it says anything at all; otherwise the\n * controller's default applies; when NEITHER speaks, the answer is `required`.\n * That last clause is the whole point — a route that forgot to declare must be\n * closed, not open. (Measured: an engine that only read the route level served\n * a controller marked `auth: false` as 401, and would have served the reverse\n * mistake as an open endpoint.)\n */\nexport function effectiveAuth(routeAuth: unknown, controllerAuth: unknown): EffectiveAuth {\n const spec = routeAuth !== undefined ? routeAuth : controllerAuth;\n if (spec === false) return { required: false, verifiedEmail: false };\n if (spec === true || spec === undefined || spec === null) return { required: true, verifiedEmail: false };\n if (typeof spec !== \"object\") return { required: true, verifiedEmail: false };\n\n const o = spec as {\n required?: unknown;\n role?: unknown;\n permission?: unknown;\n verifiedEmail?: unknown;\n };\n const role = typeof o.role === \"string\" && o.role.trim() !== \"\" ? o.role.trim() : undefined;\n // Blank-trimmed like `role`, and for the same reason: a spec that carries\n // `permission: \"\"` is asking for nothing, and a gate that took it literally\n // would query for the empty permission and refuse everyone.\n const permission =\n typeof o.permission === \"string\" && o.permission.trim() !== \"\" ? o.permission.trim() : undefined;\n return {\n required: o.required !== false,\n role,\n permission,\n verifiedEmail: o.verifiedEmail === true,\n };\n}\n","/**\n * engine/ratelimit.ts — the customer's own per-route limit, enforced here.\n *\n * This is the PRODUCT feature (`@Get(\"/x\", { rateLimit: { max, window } })`),\n * not a quota the platform imposes. It runs in this process, on this pod,\n * because the route table lives here: the edge proxies by path and has never\n * seen a route's options, so teaching it would mean shipping the table twice\n * and keeping the copies in step.\n *\n * Fixed window, in memory. A single-tenant backend is the whole stack rather\n * than a shard of it, so \"in process\" is not an approximation. A restart\n * forgets the window, which for an endpoint guard fails in the right\n * direction: it forgives, it never invents a refusal.\n */\n\nexport interface RateLimitRule {\n max: number;\n /** Seconds. */\n window: number;\n}\n\ninterface Bucket {\n count: number;\n resetAt: number;\n}\n\nexport class RateLimiter {\n private buckets = new Map<string, Bucket>();\n /** Bound on distinct keys held, so an attacker cycling identities cannot\n * grow this map without limit. On overflow the oldest windows are dropped —\n * forgiving, consistent with the restart behaviour above. */\n constructor(private readonly maxKeys = 100_000) {}\n\n /**\n * Identify the caller: the signed-in user when the route resolved one,\n * otherwise the address the edge forwarded. Callers the edge did not\n * identify share one bucket — deliberately conservative, since the\n * alternative is a limit anyone resets by omitting a header.\n */\n static key(routeId: string, userId: string | undefined, headers: Headers): string {\n if (userId) return `${routeId}\\x00u:${userId}`;\n const fwd = headers.get(\"x-forwarded-for\");\n const addr = (fwd ? (fwd.split(\",\")[0] ?? \"\") : (headers.get(\"x-real-ip\") ?? \"\")).trim();\n return `${routeId}\\x00a:${addr || \"anonymous\"}`;\n }\n\n /**\n * @returns `null` when the request may proceed, or the number of seconds to\n * wait (never 0 — a caller told to wait 0 comes straight back to the same\n * refusal).\n */\n check(rule: RateLimitRule | undefined, key: string, now: number): number | null {\n if (!rule || !(rule.max > 0) || !(rule.window > 0)) return null;\n\n const bucket = this.buckets.get(key);\n if (!bucket || now >= bucket.resetAt) {\n if (this.buckets.size >= this.maxKeys) this.evict(now);\n this.buckets.set(key, { count: 1, resetAt: now + rule.window * 1000 });\n return null;\n }\n if (bucket.count < rule.max) {\n bucket.count++;\n return null;\n }\n return Math.max(1, Math.ceil((bucket.resetAt - now) / 1000));\n }\n\n /** Drop expired windows; if none are expired, drop the earliest-resetting\n * quarter so the map cannot wedge at the ceiling. */\n private evict(now: number): void {\n let dropped = 0;\n for (const [k, b] of this.buckets) {\n if (now >= b.resetAt) {\n this.buckets.delete(k);\n dropped++;\n }\n }\n if (dropped > 0) return;\n const byReset = [...this.buckets.entries()].sort((a, b) => a[1].resetAt - b[1].resetAt);\n for (let i = 0; i < Math.ceil(byReset.length / 4); i++) {\n const victim = byReset[i];\n if (victim) this.buckets.delete(victim[0]);\n }\n }\n\n /** Test seam. */\n get size(): number {\n return this.buckets.size;\n }\n}\n","/**\n * engine/cache.ts — the cache, in this process's own memory.\n *\n * A stack that serves one tenant has nobody to share a cache with; palsvc drew\n * exactly this conclusion for itself when it dropped Redis, and a backend that\n * reaches over a network for a hash map is paying a round trip for nothing.\n *\n * JSON-typed, matching `CacheClient`: values round-trip as whatever was stored.\n */\nimport type { CacheClient } from \"../endpoint.js\";\n\ninterface Entry {\n value: unknown;\n /** Epoch ms, or 0 for \"no expiry\". */\n expiresAt: number;\n}\n\nexport interface MemoryCacheOptions {\n /** Bound on entries held. On overflow the soonest-to-expire are dropped. */\n maxEntries?: number;\n /** Injectable clock, for tests. */\n now?: () => number;\n}\n\n/**\n * Build an in-process cache.\n *\n * `getOrSet` is single-flight: concurrent misses on one key share one fill, so\n * a cold key under load does not become N identical expensive calls.\n */\nexport function makeMemoryCache(opts: MemoryCacheOptions = {}): CacheClient {\n const maxEntries = opts.maxEntries ?? 50_000;\n const now = opts.now ?? (() => Date.now());\n const store = new Map<string, Entry>();\n const inflight = new Map<string, Promise<unknown>>();\n\n const live = (key: string): Entry | undefined => {\n const e = store.get(key);\n if (!e) return undefined;\n if (e.expiresAt !== 0 && e.expiresAt <= now()) {\n store.delete(key);\n return undefined;\n }\n return e;\n };\n\n const evict = () => {\n const t = now();\n let dropped = 0;\n for (const [k, e] of store) {\n if (e.expiresAt !== 0 && e.expiresAt <= t) {\n store.delete(k);\n dropped++;\n }\n }\n if (dropped > 0) return;\n // Nothing expired: drop the soonest-to-expire quarter (entries with no\n // expiry sort last, so an unbounded writer sheds its own oldest first).\n const order = [...store.entries()].sort(\n (a, b) => (a[1].expiresAt || Infinity) - (b[1].expiresAt || Infinity),\n );\n for (let i = 0; i < Math.ceil(order.length / 4); i++) {\n const victim = order[i];\n if (victim) store.delete(victim[0]);\n }\n };\n\n const set = async (key: string, value: unknown, ttl?: number): Promise<void> => {\n if (store.size >= maxEntries && !store.has(key)) evict();\n store.set(key, { value, expiresAt: ttl && ttl > 0 ? now() + ttl * 1000 : 0 });\n };\n\n return {\n async get<T = unknown>(key: string): Promise<T | null> {\n const e = live(key);\n return e ? (e.value as T) : null;\n },\n set,\n async del(key: string): Promise<void> {\n store.delete(key);\n },\n async incr(key: string): Promise<number> {\n const e = live(key);\n const next = (typeof e?.value === \"number\" ? e.value : 0) + 1;\n store.set(key, { value: next, expiresAt: e?.expiresAt ?? 0 });\n return next;\n },\n async getOrSet<T>(key: string, ttl: number, fn: () => Promise<T> | T): Promise<T> {\n const hit = live(key);\n if (hit) return hit.value as T;\n\n const running = inflight.get(key);\n if (running) return running as Promise<T>;\n\n const fill = (async () => {\n try {\n const value = await fn();\n await set(key, value, ttl);\n return value;\n } finally {\n inflight.delete(key);\n }\n })();\n inflight.set(key, fill);\n return fill as Promise<T>;\n },\n };\n}\n","/**\n * engine/db.ts — a real pooled connection, and the identity every request is\n * bound to inside it.\n *\n * # Why one transaction per request\n *\n * In the isolate architecture every `Database.*` call was its own HTTP hop to a\n * capability surface, so two writes in one handler could not be atomic — a\n * handler that wrote and then threw left the first write behind. Here the whole\n * request runs inside one transaction: it commits when the handler returns and\n * rolls back when it throws. Atomicity stops being something the author has to\n * ask for.\n *\n * # Why it opens lazily\n *\n * A handler that touches no table must cost no round trip. Opening eagerly cost\n * four (BEGIN + bind + … + COMMIT) on endpoints that never query — measured at\n * 1,243 rps against 31,579 for the same endpoint once the open became lazy.\n *\n * # How the caller's identity reaches RLS\n *\n * One statement, not three:\n *\n * select set_config('role',$1,true),\n * set_config('search_path','public',true),\n * set_config('request.jwt.claims',$2,true)\n *\n * `set_config(..., is_local => true)` is transaction-scoped exactly like\n * `SET LOCAL`, but takes BOUND PARAMETERS, which `SET LOCAL` cannot. So the\n * role and the caller's claims travel as parameters — user identity is never\n * spliced into SQL text — and `auth.uid()` resolves inside RLS policies, which\n * means the row filter is enforced by Postgres rather than by our code.\n */\nimport type { DBClient, DBOps, AtomicClient } from \"../endpoint.js\";\nimport { AsyncLocalStorage } from \"node:async_hooks\";\nimport { validateAtomicOptions, retryBudget, type AtomicOptions, type TransactionIsolation } from \"../db/transaction-options.js\";\nimport { memoTable, snapshotDeclaration, type SchemaMetadataCache } from \"./schema-cache.js\";\nimport { SQLSTATE } from \"../db/sqlstate.js\";\nimport { cursorKey, cursorIdentity, encodeCursor, decodeCursor, fingerprint, pageOrder, pageBoundary, type PageColumn } from \"./cursor.js\";\nimport type { Page, RawPageOptions } from \"../db/page.js\";\nimport { validateInsertManyOptions, type InsertManyOptions } from \"../db/bulk.js\";\nimport type { CommandOptions } from \"../db/command.js\";\nimport { uniqueKeysOf, assertUniqueLookup } from \"../db/unique.js\";\nimport { hasCommandExecutor, parameterChunks, type CompiledStep, type CommandBinding } from \"./commands.js\";\nimport { databaseAdmission, type AdmissionLease, type DatabaseAdmission } from \"./admission.js\";\nimport { TransactionControl, type CancellableQuery } from \"./transaction-control.js\";\nimport { DatabaseTrace } from \"./diagnostics.js\";\nimport type { DatabaseDiagnosticsOptions } from \"../db/diagnostics.js\";\n// A VALUE import, not a type: the engine constructs one (23505 → 409).\nimport { HttpError, UniqueViolation, SerializationFailure, DeadlockDetected, markEngineRaised, isRetryable,\n} from \"../errors.js\";\nimport { assertUsableFilter, assertUsableWriteValues, assertNoExpressionHandles, isColRef, isSqlFragment, isNowExpr, isColumnExpr, looksLikeUnbrandedRef, isPlanRef, looksLikeUnbrandedPlanRef } from \"../db/input-guards.js\";\nimport { CODECS, type CodecName } from \"../db/columns.js\";\nimport { columnExprOf } from \"../db/tx-plan.js\";\nimport type { PolicyDef, PolicyExpr } from \"../db/policy.js\";\nimport type { TableDef } from \"../db/schema.js\";\nimport { qualifiedTableKey } from \"../db/schema-json.js\";\nimport { buildRelations, type Relation } from \"../db/env-gen.js\";\nimport type { SchemaDef } from \"../db/schema.js\";\nimport type {\n TxPlanBody,\n TxPlanOpResult,\n TxPlanResponse,\n TxWireExpr,\n TxWireOp,\n TxWireRef,\n TxWireValue,\n} from \"../db/tx-plan.js\";\n\n/** The slice of a SQL driver the engine uses. `Bun.sql` satisfies it. */\nexport interface SqlDriver {\n /** Shared by every request and identity using this physical application pool. */\n admission?: DatabaseAdmission;\n /** Optional reliable cancellation through a separate control connection. */\n cancelBackend?(pid: number, startedAt: string): Promise<void>;\n /** Run a parameterised statement. */\n unsafe(sql: string, params?: unknown[]): Promise<unknown>;\n /** Open a transaction; the driver commits when `cb` resolves and rolls back\n * when it rejects. */\n begin<T>(cb: (tx: SqlTx) => Promise<T>): Promise<T>;\n}\n\nexport interface SqlTx {\n unsafe(sql: string, params?: unknown[], metadata?: { name?: string }): Promise<unknown>;\n savepoint<T>(cb: (sp: SqlTx) => Promise<T>): Promise<T>;\n}\n\ntype Row = Record<string, unknown>;\n\n/** Quote an identifier. Table and column names reach here from the schema and\n * from handler arguments; neither is allowed to become syntax. */\nexport function quoteIdent(name: string): string {\n return `\"${name.replace(/\"/g, '\"\"')}\"`;\n}\n\n/**\n * Quote a TABLE KEY, which is one identifier or two — never one that contains\n * a dot.\n *\n * A table travels under this system's one key convention: `public` bare,\n * anything else `schema.table` (the same rule `qualifiedTableKey` writes on the\n * Go side). Handing that key to `quoteIdent` produces `\"billing.invoices\"`,\n * which Postgres reads as a PUBLIC table whose NAME contains a dot — so every\n * call through `Database.billing.*` named a table that does\n * not exist, or, worse, a different one that does.\n *\n * The public half stays BYTE-IDENTICAL to the single-schema world, because\n * every existing query and golden asserts the bare form.\n */\nexport function quoteTable(key: string): string {\n const dot = key.indexOf(\".\");\n if (dot === -1) return quoteIdent(key);\n return `${quoteIdent(key.slice(0, dot))}.${quoteIdent(key.slice(dot + 1))}`;\n}\n\n/**\n * Render a JavaScript array as a Postgres array literal, so `= ANY($n::uuid[])`\n * works from `Database.query`.\n *\n * WHY THIS EXISTS. `Bun.SQL`'s `unsafe(text, params)` does NOT bind a JS array as\n * a Postgres array — it applies `Array.prototype.toString()`. `[\"a\",\"b\"]` arrives\n * as the text `a,b`, with no braces, and `$1::uuid[]` fails with \"malformed array\n * literal\" (measured 2026-08-29 against pgvector/pg16 + bun 1.3.9). Every fan-in\n * query a tenant writes therefore had to hand-build the literal; one of them did,\n * and reported it. node-postgres converts arrays for exactly this reason.\n *\n * Bun's own escape hatch, `sql.array()`, cannot be used here: it is a tagged-\n * template FRAGMENT that renders inline `ARRAY[...]` TEXT, and nothing that\n * travels in the `params` array can carry it.\n *\n * There is deliberately NO vector branch, and there cannot be one: this sees raw\n * SQL, so which column a parameter is destined for is unknowable. The single\n * uniform encoding is what makes a vector parameter writable at all —\n * `$n::float8[]::vector` round-trips (measured), where today nothing does.\n */\nexport function encodePgArray(value: readonly unknown[]): string {\n const element = (x: unknown): string => {\n // Unquoted NULL is the only spelling Postgres reads as the null element;\n // `\"NULL\"` would be the four-character string.\n if (x === null || x === undefined) return \"NULL\";\n if (Array.isArray(x)) return encodePgArray(x);\n return `\"${String(x).replace(/([\"\\\\])/g, \"\\\\$1\")}\"`;\n };\n return `{${value.map(element).join(\",\")}}`;\n}\n\nconst BIND_SQL =\n \"select set_config('role',$1,true), set_config('search_path','public',true), set_config('request.jwt.claims',$2,true)\";\n\n/** Per async branch: other requests and sibling Promise.all branches are unaffected. */\nconst atomicScope = new AsyncLocalStorage<symbol>();\n\n/**\n * A transaction that does not exist until somebody reads or writes.\n *\n * `begin(cb)` is callback-scoped, so to hold one open across a whole request\n * the callback parks on a promise this object controls: `commit()` resolves it\n * (the driver commits), `rollback()` rejects it (the driver rolls back). A\n * request that never touches the database never enters the callback at all.\n */\nexport function createLazyTransaction(\n sql: SqlDriver,\n role: string,\n claimsJson: string,\n options: { lockTimeout?: string; statementTimeout?: string; isolation?: TransactionIsolation; readOnly?: boolean; scope?: symbol; control?: TransactionControl; trace?: DatabaseTrace } = {},\n) {\n const { lockTimeout } = options;\n // `lock_timeout` travels as a BOUND parameter like the other two, so a value\n // from configuration can never become SQL text.\n let bindSql = lockTimeout ? `${BIND_SQL}, set_config('lock_timeout',$3,true)` : BIND_SQL;\n const bindParams = lockTimeout ? [role, claimsJson, lockTimeout] : [role, claimsJson];\n if (options.statementTimeout !== undefined) {\n bindParams.push(options.statementTimeout);\n bindSql += `, set_config('statement_timeout',$${bindParams.length},true)`;\n }\n\n let opening: Promise<SqlTx> | null = null;\n let release: (() => void) | null = null;\n let fail: ((e: unknown) => void) | null = null;\n let settled: Promise<unknown> | null = null;\n let closed = false;\n\n const assertAccess = (): void => {\n if (closed) throw new Error(\"Database transaction has settled; its handle cannot be used again\");\n options.control?.check();\n options.trace?.check();\n if (atomicScope.getStore() !== options.scope) {\n throw new Error(\"Database.$atomic cannot use a handle from another transaction or identity; use its tx argument\");\n }\n };\n let savepointALS: AsyncLocalStorage<symbol> | undefined;\n let activeSavepoint: symbol | undefined;\n const pendingSavepoints = new Set<Promise<unknown>>();\n const scoped = (tx: SqlTx, checkParent = assertAccess, owner?: symbol, children = new Set<Promise<unknown>>()): SqlTx => {\n const access = () => {\n checkParent();\n if (activeSavepoint !== owner || savepointALS?.getStore() !== owner) {\n throw new Error(\"Database connection belongs to another active savepoint; use its tx argument and await it before using the parent handle\");\n }\n };\n return {\n async unsafe(text, params, metadata) {\n access();\n const run = () => { const query = tx.unsafe(text, params); return options.control ? options.control.watch(query) : query; };\n return options.trace ? options.trace.query(text, metadata?.name, run) : run();\n },\n async savepoint(fn) {\n access();\n const token = Symbol(\"savepoint\"), descendants = new Set<Promise<unknown>>();\n savepointALS ??= new AsyncLocalStorage<symbol>();\n activeSavepoint = token;\n const work = (async () => {\n try {\n return await tx.savepoint(async sp => {\n let ended = false;\n const check = () => { checkParent(); if (ended) throw new Error(\"Database savepoint has settled; its handle cannot be used again\"); };\n try {\n const callback = savepointALS!.run(token, () => fn(scoped(sp, check, token, descendants)));\n return await (options.control ? options.control.race(callback) : callback);\n } finally {\n // Children finish their ROLLBACK TO / RELEASE before this\n // savepoint settles, including when the callback is cancelled.\n if (descendants.size) await Promise.allSettled([...descendants]);\n ended = true;\n }\n });\n } finally { activeSavepoint = owner; }\n })();\n pendingSavepoints.add(work); children.add(work);\n try { return await work; }\n finally { pendingSavepoints.delete(work); children.delete(work); }\n },\n };\n };\n const ensure = async (): Promise<SqlTx> => {\n assertAccess();\n if (opening) return opening;\n opening = new Promise<SqlTx>((resolveTx, rejectTx) => {\n const parked = new Promise<void>((res, rej) => {\n release = res;\n fail = rej;\n });\n // Opening can fail before the driver ever awaits parked. Rollback still\n // rejects it, so attach a handler at creation while retaining the original.\n void parked.catch(() => undefined);\n settled = (async () => {\n const queuedAt = performance.now();\n let lease: AdmissionLease;\n try { lease = await (sql.admission ?? databaseAdmission(sql)).acquire(claimsJson, options.control?.signal); }\n finally { options.trace?.time(\"queueMs\", queuedAt); }\n const openingAt = performance.now();\n let connectedAt: number | undefined;\n try {\n // Cancellation may win after admission and before the driver callback.\n // Never bind/cancel a backend that has not been acquired by this scope.\n options.control?.check();\n if (closed) throw new Error(\"Database transaction closed while waiting for admission\");\n return await sql.begin(async (tx) => {\n connectedAt = performance.now();\n options.trace?.time(\"poolMs\", openingAt);\n const setupAt = options.trace ? performance.now() : 0;\n options.control?.check();\n if (closed) throw new Error(\"Database transaction closed while waiting for its connection\");\n if (options.isolation !== undefined || options.readOnly !== undefined) {\n const isolation = options.isolation ?? \"read committed\";\n // Only enumerated values can become SQL; SET must precede the bind SELECT.\n validateAtomicOptions({ isolation, readOnly: options.readOnly });\n await tx.unsafe(`SET TRANSACTION ISOLATION LEVEL ${isolation.toUpperCase()}${options.readOnly === undefined ? \"\" : options.readOnly ? \" READ ONLY\" : \" READ WRITE\"}`);\n }\n if (options.control && sql.cancelBackend) {\n // The materialized input is evaluated before the outer SET ROLE\n // projection. Read only this backend, then bind RLS in the SAME\n // round trip. Scanning pg_stat_activity and binding separately\n // added an extra query to every cancellable CRUD transaction.\n // Await setup before binding cancellation: a cancellation during\n // setup may roll this transaction back, never its next borrower.\n const ticket = await tx.unsafe(`WITH backend AS MATERIALIZED (\n SELECT pid, backend_start::text AS started FROM pg_catalog.pg_stat_get_activity(pg_catalog.pg_backend_pid())\n ) ${bindSql}, backend.pid, backend.started FROM backend`, bindParams) as { pid: number; started: string }[];\n if (!Number.isInteger(ticket[0]?.pid) || typeof ticket[0]?.started !== \"string\") throw new Error(\"Database cancellation cannot identify its own backend\");\n options.control.bindBackend(() => sql.cancelBackend!(ticket[0]!.pid, ticket[0]!.started));\n options.control.check();\n } else {\n const binding = tx.unsafe(bindSql, bindParams);\n await (options.control ? options.control.watch(binding) : binding);\n }\n options.trace?.time(\"setupMs\", setupAt);\n resolveTx(scoped(tx));\n await parked;\n });\n } finally {\n if (connectedAt !== undefined) options.trace?.time(\"connectionMs\", connectedAt);\n lease.release();\n }\n })()\n .catch((e: unknown) => {\n // Both paths matter: a caller awaiting `ensure()` must see the\n // failure, and `commit()` must not hang waiting for a dead driver.\n rejectTx(e);\n throw e;\n });\n // A statement can fail before its caller reaches rollback(). The owner\n // still observes settled at COMMIT, without an unhandled rejection meanwhile.\n void settled.catch(() => undefined);\n });\n return opening;\n };\n\n return {\n ensure,\n get opened(): boolean {\n return opening !== null;\n },\n async commit(): Promise<void> {\n if (pendingSavepoints.size) await Promise.allSettled([...pendingSavepoints]);\n options.trace?.check();\n // No connection/transaction was opened. A cancelled HTTP stream may\n // still report its Signal state without a database COMMIT to cancel.\n if (!opening) { closed = true; return; }\n options.control?.check();\n closed = true;\n const started = options.trace ? performance.now() : 0;\n release!();\n try { await settled; options.trace?.committed(); }\n catch (error) { options.trace?.commitFailed(); throw error; }\n finally { options.trace?.time(\"commitMs\", started); }\n },\n async rollback(reason: unknown): Promise<void> {\n closed = true;\n if (!opening) return;\n await options.control?.drainCancellation();\n if (pendingSavepoints.size) await Promise.allSettled([...pendingSavepoints]);\n const started = options.trace ? performance.now() : 0;\n fail!(reason);\n // The rejection is the mechanism, not an error to report twice.\n await settled?.catch(() => undefined);\n options.trace?.time(\"rollbackMs\", started); options.trace?.rolledBack();\n },\n };\n}\n\nexport type LazyTransaction = ReturnType<typeof createLazyTransaction>;\n\n/** Either a live driver transaction or the lazy holder above. */\ntype TxLike = SqlTx | LazyTransaction;\n\nconst resolveTx = async (tx: TxLike): Promise<SqlTx> =>\n typeof (tx as LazyTransaction).ensure === \"function\"\n ? await (tx as LazyTransaction).ensure()\n : (tx as SqlTx);\n\n/**\n * What a row LOOKS like to the code that reads it.\n *\n * The driver hands back a `Date` for every timestamp column, while the typed\n * surface this SDK generates for the same table says `string` — and so does the\n * response schema derived from a handler's return type, and so does the JSON on\n * the wire. So a handler that returned a row straight from `Database.public.x`\n * failed its OWN declared type: measured on 2026-08-16, `POST /todos` answered\n * 500 `output_invalid` with \"expected string, received date\" for `created_at`,\n * from code that had done nothing wrong.\n *\n * ISO-8601, because that is what the schema, the generated client and every\n * JSON reader already agree on.\n */\nfunction asWireValue(value: unknown): unknown {\n if (value instanceof Date) return value.toISOString();\n if (Array.isArray(value)) return value.map(asWireValue);\n return value;\n}\n\n/** Every row a caller receives passes through here. */\nfunction asWireRow<T>(row: T): T {\n if (row === null || typeof row !== \"object\") return row;\n const out: Row = {};\n for (const [key, value] of Object.entries(row as Row)) out[key] = asWireValue(value);\n return out as T;\n}\n\nfunction asWireRows(rows: Row[]): Row[] {\n return rows.map((row) => asWireRow(row));\n}\n\n/** pgvector text literal: '[v1,v2,...]' — the driver would otherwise bind a\n * Postgres ARRAY, which vector's input function refuses. (FR-008) */\nfunction toVectorLiteral(v: number[]): string {\n return `[${v.join(\",\")}]`;\n}\n\n/**\n * The vector-typed column names of one table, read from the installed schema.\n *\n * Ops receive the PHYSICAL table name (`withTables` maps key → `def.name`), so\n * the lookup matches `def.name ?? key`. A column arrives either as a\n * ColumnBuilder (with `_def`) or as the plain def — the same double reading\n * schema-json does, for the same reason: both shapes exist in the wild.\n */\nfunction computeVectorColumns(schema: typeof currentSchema, table: string): Set<string> {\n const out = new Set<string>();\n const def = tableDefOf(table, schema);\n if (def) {\n for (const [col, c] of Object.entries(def.columns ?? {})) {\n const d = (c !== null && typeof c === \"object\" && \"_def\" in c\n ? (c as { _def: unknown })._def\n : c) as { type?: unknown } | null;\n if (d !== null && typeof d === \"object\" && d.type === \"vector\") out.add(col);\n }\n }\n return out;\n}\n\n/**\n * The one place that answers \"which declared table is this?\".\n *\n * Ops receive the table's WIRE KEY — public bare, anything else qualified —\n * and the installed schema is flattened under exactly those keys. There used to\n * be four separate scans here, each matching `def.name ?? key` against the\n * name, and every one of them missed a table outside public: the column\n * metadata (vectors, transforms, search config) came back EMPTY and the ops\n * fell through to their \"no schema to check against\" path without saying so.\n */\nfunction tableDefOf(\n key: string,\n schema: typeof currentSchema = currentSchema,\n): { name?: string; columns?: Record<string, unknown>; policies?: PolicyDef[] } | null {\n return schema.tables?.[key] ?? null;\n}\n\n/** The driver hands a vector back as its text literal; JSON.parse restores the\n * number[] the typed surface declares — the literal is valid JSON (C-9). A null\n * (row without an embedding yet) passes through untouched. */\nfunction reviveVectors<T>(row: T, vectorCols: Set<string>): T {\n if (row === null || typeof row !== \"object\" || vectorCols.size === 0) return row;\n const out = row as Row;\n for (const col of vectorCols) {\n const v = out[col];\n if (typeof v === \"string\") out[col] = JSON.parse(v);\n }\n return row;\n}\n\n/** The declared `{ fromDb, toDb }` per column of `table`, empty when none.\n *\n * Read the same way vector columns are: a column is either a ColumnBuilder\n * (with `_def`) or the flat generated shape, and both are accepted.\n *\n * WITHOUT THIS the hook is a type-level promise the runtime does not keep — the\n * declaration would say `number` and the driver would still hand over the\n * string, which is the defect class this whole surface exists to remove. */\nfunction computeTransforms(\n schema: typeof currentSchema,\n table: string,\n): Map<string, { fromDb?: (v: unknown) => unknown; toDb?: (v: unknown) => unknown }> {\n const out = new Map<string, { fromDb?: (v: unknown) => unknown; toDb?: (v: unknown) => unknown }>();\n const def = tableDefOf(table, schema);\n if (def) {\n for (const [col, c] of Object.entries(def.columns ?? {})) {\n const d = (c !== null && typeof c === \"object\" && \"_def\" in c\n ? (c as { _def: unknown })._def\n : c) as { transform?: unknown; codec?: unknown } | null;\n // A NAMED CODEC IS A TRANSFORM whose pair is looked up rather than\n // supplied. It goes through THIS map on purpose: two implementations of\n // \"how a numeric becomes a number\" would be two answers, and one day they\n // would disagree. The name is what the type generator can read; the pair\n // it resolves to is the same pair `.transform()` hands over (FR-002).\n const codec = d?.codec;\n if (typeof codec === \"string\" && codec in CODECS) {\n const c2 = CODECS[codec as CodecName];\n out.set(col, { fromDb: c2.fromDb, toDb: c2.toDb });\n continue;\n }\n const t = d?.transform;\n if (t !== null && typeof t === \"object\") {\n out.set(col, t as { fromDb?: (v: unknown) => unknown; toDb?: (v: unknown) => unknown });\n }\n }\n }\n return out;\n}\n\n/** Apply every declared `fromDb` to one row. NULL is passed through untouched:\n * \"no value\" is not a value to convert, and a `fromDb` written for a string\n * would answer `0` for it. */\nfunction applyFromDb(row: Row, transforms: ReturnType<typeof transformsOf>): Row {\n if (transforms.size === 0) return row;\n for (const [col, t] of transforms) {\n if (t.fromDb === undefined) continue;\n const v = row[col];\n if (v === null || v === undefined) continue;\n row[col] = t.fromDb(v);\n }\n return row;\n}\n\n/** `asWireRow`, made table-aware: what the table's schema calls a vector comes\n * back as number[]. Rows from tables the schema does not know pass unchanged. */\nfunction asTableRow<T>(table: string, row: T): T {\n const revived = reviveVectors(asWireRow(row), vectorColumnsOf(currentSchema, table));\n return foldCan(table, applyFromDb(revived as Row, transformsOf(currentSchema, table)) as Row, false) as T;\n}\n\n/** `partial`: `select` projeksiyonu — `can` alanı hiç yazılmaz. `with` ile gelen iç\n * içe satırlar `can:*` çiftlerini kendi JSON nesnesinde taşır (`canJsonPairs`), tam satırdır. */\nfunction asTableRows(table: string, rows: Row[], withSpec?: Record<string, unknown>, partial = false): Row[] {\n const vectorCols = vectorColumnsOf(currentSchema, table);\n const transforms = transformsOf(currentSchema, table);\n const result = rows.map((row) => applyFromDb(reviveVectors(asWireRow(row), vectorCols), transforms));\n if (withSpec) for (const rel of currentRelations.get(table) ?? []) {\n const spec = withSpec[rel.name];\n if (!spec) continue;\n const nested = typeof spec === \"object\" ? (spec as { with?: Record<string, unknown> }).with : undefined;\n for (const row of result) {\n const value = row[rel.name];\n const selected = typeof spec === \"object\" && \"select\" in spec && spec.select !== undefined;\n if (Array.isArray(value)) row[rel.name] = asTableRows(rel.to, value, nested, selected);\n else if (value && typeof value === \"object\") row[rel.name] = asTableRows(rel.to, [value as Row], nested, selected)[0];\n }\n }\n // Katlama ilişkilerden SONRA: `can` adlı bir ilişki varsa yankı zaten kapalı ve\n // `foldCan` o alana dokunmaz (hasCanColumn ilişkiyi de sayar).\n for (const row of result) foldCan(table, row, partial);\n return result;\n}\n\n/** Bind parameters for one write: a value headed for a vector column becomes\n * the pgvector text literal; everything else binds as-is. (FR-008) */\nfunction asBindParams(table: string, cols: string[], data: Row, caller: string): unknown[] {\n // AN `undefined` VALUE IS NOT A WRITE — it is a value that never arrived.\n //\n // The read path already refuses one (see compileWhere): a filter nobody filled\n // in returned an empty list and said nothing. The WRITE half is the same shape\n // and a far more expensive result: `{ title: req.body.title }` with no `title`\n // in the body bound NULL and answered 200 — the column was ERASED, silently.\n // Measured on the 24.0.x line across insert, update, updateMany, upsert and\n // supersede, all of which bind through here.\n //\n // `null` is untouched, and the difference is the whole point: null is an author\n // SAYING \"empty this column\". undefined is nobody saying anything.\n assertUsableWriteValues(caller, table, cols, data);\n // Bir ifade tutamağı ya da `col()` DEĞER değildir — ortak kural dosyasından\n // (db/input-guards.ts), böylece `fakeDatabase` de aynı cevabı veriyor.\n assertNoExpressionHandles(caller, table, cols, data);\n const vectorCols = vectorColumnsOf(currentSchema, table);\n const transforms = transformsOf(currentSchema, table);\n return cols.map((c) => {\n const v = data[c];\n if (Array.isArray(v) && vectorCols.has(c)) return toVectorLiteral(v);\n // `toDb` before the bind, and NULL straight through for the same reason\n // `fromDb` skips it.\n const t = transforms.get(c);\n if (t?.toDb !== undefined && v !== null && v !== undefined) return t.toDb(v);\n return v;\n });\n}\n\n// ---------------------------------------------------------------------------\n// search (T017, FR-013..016) — tek-SQL hibrit RRF.\n// ---------------------------------------------------------------------------\n\n/** Metrik → operatör. Tek kelimeden türetilir; opclass/operatör asla yüzeye\n * çıkmaz, uyumsuzluk yapısal olarak imkânsız (D-5, prod arıza #2). */\n// ≤ bu kadar satır eşleşiyorsa vektör kolu EXACT taranır (10K×1536d ≈ 10-20ms;\n// HNSW'nin seçici filtrede recall çöküşüne karşı — ölçüm: engine/db.ts NFR-005 yorumu).\nconst SELECTIVITY_EXACT_THRESHOLD = 10000;\n\nconst METRIC_OPERATOR: Record<string, string> = {\n cosine: \"<=>\",\n euclidean: \"<->\",\n inner_product: \"<#>\",\n};\n\ninterface SearchLeg {\n column: string;\n metric: string;\n /** Auto-embed beyanı (authoring EmbeddingModelRef — runtime şeması defineSchema çıktısıdır). */\n embed?: { model: string; apiKeyName: string; baseURL?: string; dimensions?: number };\n}\n\n/** Chunk-modu hedefi (D-010): arama bu türev tabloda koşar. */\ninterface ChunkTarget {\n table: string;\n metric: string;\n embed?: SearchLeg[\"embed\"];\n fts: boolean;\n}\n\ninterface SearchConfig {\n chunk?: ChunkTarget;\n pk: string;\n cols: string[];\n colSet: Set<string>;\n ftsCols: string[];\n legs: SearchLeg[];\n /** FR-026: beyandan gelen eş anlamlı haritası — websearch girdisi bununla genişler. */\n synonyms?: Record<string, string[]>;\n /** FR-029: beyanda validity:true — arama varsayılan yalnız günceli tarar,\n * supersede bu tabloda çalışır (T019 türev kolonları: valid_from/valid_to/superseded_by). */\n validity?: boolean;\n}\n\n/** Tablonun arama konfigürasyonu, runtime'ın kurduğu şemadan (setSchema — C-9).\n * `search` bloğu yoksa vector kolonlarının VARLIĞI yeter (D-3/FR-013): her\n * vector kolonu cosine metrikli bir leg olur. Tablo şemada yoksa null. */\nfunction searchConfigFor(table: string): SearchConfig | null {\n const t = tableDefOf(table);\n if (!t) return null;\n const columns = t.columns ?? {};\n const defOf = (c: unknown): { type?: string } =>\n c !== null && typeof c === \"object\" && \"_def\" in (c as Record<string, unknown>)\n ? ((c as { _def: { type?: string } })._def)\n : ((c ?? {}) as { type?: string });\n const cols = Object.keys(columns);\n const vectorCols = cols.filter((c) => defOf((columns as Record<string, unknown>)[c]).type === \"vector\");\n // PK adı ŞEMADAN (review I3): Go tarafı tek-kolon PK'nın adını bilinçli\n // serbest bırakır (FR-020 \"adı serbesttir\") — SQL'e 'id' gömmek, pk'sı\n // başka adla declare edilmiş searchable tabloyu runtime 500'üne çevirirdi.\n const defOfFull = (c: unknown): { type?: string; primaryKey?: boolean } =>\n c !== null && typeof c === \"object\" && \"_def\" in (c as Record<string, unknown>)\n ? ((c as { _def: { type?: string; primaryKey?: boolean } })._def)\n : ((c ?? {}) as { type?: string; primaryKey?: boolean });\n const pkCols = cols.filter((c) => defOfFull((columns as Record<string, unknown>)[c]).primaryKey === true);\n const pk = pkCols.length === 1 ? pkCols[0]! : cols.includes(\"id\") ? \"id\" : null;\n if (pk === null) {\n throw new Error(\n `search(${table}): tek-kolon primary key bulunamadı — arama sıralaması ve satır birleşimi PK ister (FR-020)`,\n );\n }\n const search = (t as {\n search?: { text?: string[] | boolean; vector?: unknown; from?: string[]; metric?: string;\n model?: { model: string; apiKeyName?: string; baseURL?: string; dimensions?: number };\n synonyms?: Record<string, string[]>; validity?: boolean };\n }).search;\n const synonyms =\n search?.synonyms !== undefined && Object.keys(search.synonyms).length > 0\n ? { synonyms: search.synonyms }\n : {};\n // T019 notu: validity beyanı wire'da SEARCH bloğunda yaşar (SearchJSON.Validity).\n const validity = search?.validity === true ? { validity: true } : {};\n // YENİ biçim (D-007/D-010): `from`+`model`. Vector kolonu varsa satır-modu\n // (tek leg, kolon o); yoksa CHUNK-modu — arama türev __palbase_chunks\n // tablosunda koşar, sonuç parent'a gruplanır (FR-015).\n if (search?.from !== undefined && search.model !== undefined) {\n const m = search.model;\n const embed = {\n model: m.model, apiKeyName: m.apiKeyName ?? \"OPENAI_API_KEY\",\n ...(m.baseURL !== undefined ? { baseURL: m.baseURL } : {}),\n ...(m.dimensions !== undefined ? { dimensions: m.dimensions } : {}),\n };\n const metric = search.metric ?? \"cosine\";\n const ftsOn = search.text !== false;\n const ftsColsNew = ftsOn\n ? (Array.isArray(search.text) && search.text.length > 0 ? search.text : search.from)\n : [];\n if (vectorCols.length > 0) {\n return { pk, cols, colSet: new Set(cols), ftsCols: ftsColsNew,\n legs: [{ column: vectorCols[0]!, metric, embed }], ...synonyms, ...validity };\n }\n return { pk, cols, colSet: new Set(cols), ftsCols: ftsColsNew, legs: [],\n chunk: { table: `${table}__palbase_chunks`, metric, embed, fts: ftsOn }, ...synonyms, ...validity };\n }\n const ftsCols = (Array.isArray(search?.text) ? search.text : undefined) ?? [];\n const rawLegs = search?.vector === undefined ? [] : Array.isArray(search.vector) ? search.vector : [search.vector];\n let legs: SearchLeg[];\n if (rawLegs.length > 0) {\n legs = rawLegs.map((leg) => {\n const l = leg as { column?: string; metric?: string };\n const column = l.column ?? (vectorCols.length === 1 ? vectorCols[0]! : undefined);\n if (column === undefined) {\n throw new Error(`search(${table}): birden çok vector kolonu var — beyanda 'column' zorunlu (FR-010)`);\n }\n const model = (l as { model?: { model: string; apiKeyName?: string; baseURL?: string; dimensions?: number } }).model;\n return {\n column,\n metric: l.metric ?? \"cosine\",\n ...(model !== undefined\n ? { embed: { model: model.model, apiKeyName: model.apiKeyName ?? \"OPENAI_API_KEY\",\n ...(model.baseURL !== undefined ? { baseURL: model.baseURL } : {}),\n ...(model.dimensions !== undefined ? { dimensions: model.dimensions } : {}) } }\n : {}),\n };\n });\n } else {\n legs = vectorCols.map((column) => ({ column, metric: \"cosine\" }));\n }\n if (ftsCols.length === 0 && legs.length === 0) return null;\n return { pk, cols, colSet: new Set(cols), ftsCols, legs, ...synonyms, ...validity };\n}\n\n/** using → hedef leg. using yok + tek leg → o; using yok + çok leg → adlandırılmış\n * hata (model geçişinde seçim bilinçli olmalı); using yanlış → adlandırılmış hata. */\nfunction pickLeg(table: string, legs: SearchLeg[], using: string | undefined): SearchLeg | null {\n if (legs.length === 0) return null;\n if (using !== undefined) {\n const hit = legs.find((l) => l.column === using);\n if (!hit) {\n throw new Error(\n `search(${table}): using \"${using}\" bir vektör kolunu adlamıyor — mevcut: ${legs.map((l) => l.column).join(\", \")}`,\n );\n }\n return hit;\n }\n if (legs.length === 1) return legs[0]!;\n throw new Error(`search(${table}): birden çok vektör kolu var — 'using' ile seçin (FR-013) — salt metin arıyorsan mode:\\\"text\\\" kullan`);\n}\n\nconst HALF_LIFE_UNIT_SECONDS: Record<string, number> = { s: 1, m: 60, h: 3600, d: 86400 };\n\n/** \"30d\" gibi bir yarı ömrü saniyeye çevirir (FR-004). Biçim <sayı>(s|m|h|d);\n * çözülemeyen YA DA sıfır süre adıyla reddedilir — SQL'e sıfır bölen gitmez. */\nfunction parseHalfLife(s: string): number {\n const m = /^(\\d+)(s|m|h|d)$/.exec(s);\n const sec = m === null ? 0 : Number(m[1]) * HALF_LIFE_UNIT_SECONDS[m[2]!]!;\n if (!Number.isFinite(sec) || sec <= 0) {\n throw new Error(`recency.halfLife \"${s}\" çözümlenemedi — beklenen: pozitif <sayı>+(s|m|h|d), örn. \"30d\" (FR-004)`);\n }\n return sec;\n}\n\n// `eq` BURADA YOK, ve bu bir eksik değil: ÇIPLAK DEĞER eşitliğin yazımı\n// (`{ owner: \"u1\" }`). İkinci bir yazım eklemek, bu run'ın kapatmak için var\n// olduğu şeyi — aynı iş için iki yazım — filtre dilinin içinde yeniden açardı.\n// Guard `eq`'i ADIYLA reddediyor ve çalışan yazımı söylüyor (P6).\nconst WHERE_OPS: Record<string, string> = { gt: \">\", gte: \">=\", lt: \"<\", lte: \"<=\", neq: \"<>\" };\n\n/**\n * `lockRowsWhere`'in kilit modları (FR-037).\n *\n * Serbest string DEĞİL, KAPALI bir küme: mod SQL'e cümle olarak iniyor ve\n * tanınmayan bir değeri sessizce varsayılana düşürmek çağıranın istediğinden\n * ZAYIF bir kilit almak olurdu. `FOR KEY SHARE` kasıtlı olarak yok — onun tek\n * işi FK doğrulaması ve bunu Postgres kendi yapıyor; yüzeye koymak, ne\n * yaptığını bilmeyen birinin \"en hafifi\" diye seçeceği bir seçenek eklerdi.\n */\nconst LOCK_MODES: Record<string, string> = {\n update: \"FOR UPDATE\",\n share: \"FOR SHARE\",\n noKeyUpdate: \"FOR NO KEY UPDATE\",\n};\n\n/** FTS kolonlarının sorted coalesce birleşimi — typo-fallback trgm ifadesi ve\n * ts_headline kaynağı (FR-028) AYNI ifadeyi kullanır (Go türev index'iyle birebir). */\nfunction ftsExprOf(ftsCols: string[]): string {\n return [...ftsCols]\n .sort()\n .map((c) => `coalesce(t.${quoteIdent(c)},'')`)\n .join(\" || ' ' || \");\n}\n\n/**\n * expandSynonyms (T020, FR-026): websearch girdisinde tek yönlü eş anlamlı\n * genişletmesi — haritadaki kelime `(kelime OR eş1 OR eş2)` olur\n * (websearch_to_tsquery OR'u tanır). Çift tırnaklı kesimler AYNEN korunur\n * (yazar tam-ifade istedi); eşleşme küçük-harf üzerinden, orijinal token\n * çıktıda kalır. Saf fonksiyon — SQL'e değil bind DEĞERİNE uygulanır.\n */\nexport function expandSynonyms(query: string, map: Record<string, string[]>): string {\n const lower: Record<string, string[]> = {};\n for (const [word, alts] of Object.entries(map)) lower[word.toLowerCase()] = alts;\n return query\n .split(/(\"[^\"]*\")/)\n .map((seg) => {\n if (seg.startsWith('\"')) return seg;\n return seg\n .split(/(\\s+)/)\n .map((tok) => {\n if (tok === \"\" || /^\\s+$/.test(tok)) return tok;\n const alts = lower[tok.toLowerCase()];\n return alts !== undefined && alts.length > 0 ? `(${tok} OR ${alts.join(\" OR \")})` : tok;\n })\n .join(\"\");\n })\n .join(\"\");\n}\n\ntype SearchLogFn = (event: string, fields: Record<string, unknown>) => void;\n// Varsayılan console'a düşer: dikiş kurulmamış runtime'da bile no-results\n// sinyali kaybolmasın (FR-025; bölüm 25-f canlıda sessiz kalmıştı).\nlet searchLogger: SearchLogFn | null = (evt, fields) => {\n console.log(evt, JSON.stringify(fields));\n};\n/** Runtime boot'ta bağlanır (setSecretReader ile aynı kanal deseni): yapısal\n * arama telemetrisi. Varsayılan console.log'tur (a8d5a03: 0-sonuç görünür kalsın); null ile susturulur\n * (FR-025; db.ts'de başka log yolu yok, grep 2026-08-29 boş döndü). */\nexport function setSearchLogger(fn: SearchLogFn | null): void {\n searchLogger = fn;\n}\n\n/** FR-025: nihai dönüş boşsa (typo-fallback DAHİL denendikten sonra) yapısal\n * satır — query HAM haliyle ve 200'e kırpılıp yazılır, sinonim genişletmesi\n * telemetriyi kirletmez. Anahtar/vektör değeri asla loglanmaz. */\nfunction logNoResults(table: string, query: string | undefined, mode: string | undefined, n: number): void {\n if (n === 0) {\n searchLogger?.(\"palbase.search.no_results\", {\n table,\n query: (query ?? \"\").slice(0, 200),\n mode: mode ?? \"hybrid\",\n });\n }\n}\n\n/**\n * fetchFacets (T020, FR-027): filtrelenmiş küme üzerinde kolon başına değer\n * sayaçları — kolon başına top-20, tek UNION ALL sorgusu (parçalar LIMIT/ORDER\n * taşıdığından parantezli). Kolon adları çağıran tarafından şemadan doğrulanmış\n * gelir; where filtreleri sayaçlara da uygulanır (sayaç, kullanıcının gördüğü\n * kümeyi anlatır). Kendi bind listesiyle koşar — ana sorgunun parametreleriyle\n * karışmaz (kullanılmayan bind Postgres'te hatadır).\n */\nasync function fetchFacets(\n live: { unsafe(sql: string, params?: unknown[]): Promise<unknown> },\n table: string,\n colSet: Set<string>,\n facets: string[],\n where: Record<string, unknown>,\n extraWhere: (add: (v: unknown) => string) => string = () => \"\",\n): Promise<Record<string, { value: string | null; count: number }[]>> {\n const bind: unknown[] = [];\n const add = (v: unknown): string => {\n bind.push(v);\n return `$${bind.length}`;\n };\n const whereSql = compileWhere(table, colSet, where, add) + extraWhere(add);\n const parts = facets.map(\n (col) =>\n `(SELECT '${col.replace(/'/g, \"''\")}' AS f, t.${quoteIdent(col)}::text AS v, count(*) AS n ` +\n `FROM ${quoteTable(table)} t WHERE true${whereSql} GROUP BY 2 ORDER BY 3 DESC LIMIT 20)`,\n );\n const rows = (await live.unsafe(parts.join(\" UNION ALL \"), bind)) as\n { f?: string; v?: string | null; n?: unknown }[];\n const out: Record<string, { value: string | null; count: number }[]> = {};\n for (const col of facets) out[col] = [];\n for (const r of rows) {\n if (typeof r.f === \"string\" && out[r.f] !== undefined) {\n out[r.f]!.push({ value: r.v ?? null, count: Number(r.n) });\n }\n }\n return out;\n}\n\n/** C-8 iç kanalı (T018): similar/recommend kaynak id'lerini sonuçtan düşürür.\n * Public search imzasında BİLEREK yok — search-param imza üçlüsü (engine/db +\n * typed-db + endpoint) büyümesin; yalnız bu dosyadaki similar/recommend yazar. */\ninterface InternalSearchParams {\n __excludeIds?: unknown[];\n}\n\n/** FR-029: validity'li tabloda zaman filtresi (T019 türev kolonları sabit:\n * valid_from/valid_to). Varsayılan yalnız güncel satır; \"all\" filtreyi\n * kaldırır; {asOf} o anda geçerli olan versiyonu seçer (tek bind, iki kullanım).\n * Çağıran yalnız cfg.validity === true iken çağırır. */\nfunction validitySql(\n v: \"all\" | { asOf: string } | undefined,\n add: (x: unknown) => string,\n): string {\n if (v === \"all\") return \"\";\n if (v !== undefined) {\n const p = add(v.asOf);\n return ` AND t.\"valid_from\" <= ${p} AND (t.\"valid_to\" IS NULL OR t.\"valid_to\" > ${p})`;\n }\n return ` AND t.\"valid_to\" IS NULL`;\n}\n\n/** Kaynak satır(lar)ı eleyen SQL parçası. Tek id düz `<>`; çoklu\n * `<> ALL(ARRAY[...])` — elemanlar AYRI placeholder: dizi bind'i sürücüde\n * Postgres array literal'ine çevrilmiyor (verify 19-3b dersi, where.in ile aynı). */\nfunction excludeSql(pk: string, ids: unknown[], add: (v: unknown) => string): string {\n if (ids.length === 0) return \"\";\n if (ids.length === 1) return ` AND t.${quoteIdent(pk)} <> ${add(ids[0])}`;\n // ::text — pk uuid'yken text bind'lerle karşılaştırma \"operator does not\n // exist: uuid <> text\" veriyordu (bölüm 25-b canlı ölçümü).\n return ` AND t.${quoteIdent(pk)}::text <> ALL(ARRAY[${ids.map((x) => add(x)).join(\", \")}])`;\n}\n\n/** What `findMany` accepts beside its filter: an ordering, a row ceiling and a\n * page offset. All three used to require dropping to raw SQL, and the docs said\n * so — which is how a tenant's controllers filled up with hand-written SELECTs. */\nexport interface FindManyOptions {\n /** Sıralama: tek obje ya da SIRALI liste (FR-008). `nulls` NULL'ların yerini\n * sabitler — Postgres varsayılanı yöne göre değişir (ASC'de son, DESC'te ilk). */\n orderBy?:\n | { column: string; direction?: \"asc\" | \"desc\"; nulls?: \"first\" | \"last\" }\n | { column: string; direction?: \"asc\" | \"desc\"; nulls?: \"first\" | \"last\" }[];\n /** Projeksiyon (FR-009): verilmezse `SELECT *`. Kolon adları ŞEMAYA karşı\n * doğrulanır — bilinmeyen ad SQL'e ulaşmadan, adıyla reddedilir. */\n select?: string[];\n /**\n * İLİŞKİLİ SATIRLARI da getir — TEK sorguda, LATERAL ile.\n *\n * `has` ilişki üzerinden SÜZER, `with` GETİRİR. İkisi aynı ilişki grafiğini\n * okuyor (yabancı anahtarlardan türetilmiş), yani ilişki adları aynı.\n */\n with?: Record<string, unknown>;\n limit?: number;\n /** Rows to skip before the page starts. Only meaningful with `limit`, and\n * refused without it — see `offsetClause`. */\n offset?: number;\n}\n\n/** The table's columns as the installed schema knows them, or null when this\n * process has no schema for it (unit tests, a table addressed by name alone).\n * Null means \"cannot validate\", never \"allow anything into SQL\": every\n * identifier still goes through quoteIdent. */\n/**\n * Tablonun tek-kolon primary key'i (FR-015). Bulunamazsa `null`.\n *\n * PK adı ŞEMADAN okunur; SQL'e \"id\" gömmek, pk'sı başka adla bildirilmiş bir\n * tabloyu çalışma zamanı hatasına çevirirdi. Çok kolonlu PK'da `null` dönüyor:\n * kilit sırası birden çok kolonla da kurulabilirdi ama bu run onu istemiyor ve\n * yanlış bir sıra, olmayan bir sıradan daha kötüdür.\n *\n * \"id\" TAHMİNİ YOK — ve bu bir sadelik tercihi değil, ÖLÇÜLMÜŞ bir veri\n * bozulmasının düzeltmesi (gözcü W2-B/C1 ve T013/C-1, ikisi de canlı pg16'da):\n * dış `UPDATE` artık orijinal yüklemi taşımıyor, tek bağı `t.pk = locked.pk`.\n * `primaryKey: [\"tenant_id\",\"id\"]` bildiren bir tabloda hiçbir kolona\n * `_def.primaryKey` yazılmıyor, eski kod `id`'yi anahtar sanıyordu, ve `id`\n * benzersiz olmadığı için filtreye UYMAYAN satırlar da içeri giriyordu —\n * ölçülen sonuç kiracılar arası yazma ve `deleteMany`'de tablonun boşalması.\n *\n * Tablo düzeyi `primaryKey` dizisi de OKUNUYOR: tek elemanlıysa anahtar odur.\n * İki şekli de tanımak `searchConfigFor`'un aynı dosyada kurduğu emsal\n * (\"both shapes exist in the wild\") — orada `_def`'siz düz kolon nesnesi de\n * kabul ediliyor, burada da edilmeli.\n */\nfunction computePrimaryKey(table: string): string | null {\n const t = tableDefOf(table) as\n | { columns?: Record<string, unknown>; primaryKey?: unknown }\n | undefined;\n const columns = (t?.columns ?? {}) as Record<string, unknown>;\n const cols = Object.keys(columns);\n if (cols.length === 0) return null;\n // Tablo düzeyi bildirim ÖNCE: composite PK burada yaşıyor ve tek doğru cevap\n // \"birden çoksa anahtar yok\"tur.\n const declared = t?.primaryKey;\n if (Array.isArray(declared)) {\n if (declared.length !== 1) return null;\n const only = declared[0];\n return typeof only === \"string\" && cols.includes(only) ? only : null;\n }\n const pkOf = (c: unknown): boolean => {\n if (c === null || typeof c !== \"object\") return false;\n const rec = c as Record<string, unknown>;\n // İki kolon şekli: `_def` taşıyan builder ve düz nesne (schema-json.ts'in\n // ürettiği şekil). `searchConfigFor` ile aynı gerekçe.\n const def = (\"_def\" in rec ? rec._def : rec) as { primaryKey?: unknown } | null;\n return def !== null && typeof def === \"object\" && def.primaryKey === true;\n };\n const pks = cols.filter((c) => pkOf(columns[c]));\n return pks.length === 1 ? pks[0]! : null;\n}\n\n/**\n * Filtre TEK bir satırı adıyla mı seçiyor? (`{ id: \"a1\" }`)\n *\n * Öyleyse kilit sırasının anlamı yok — sıra ancak birden çok satır varken\n * vardır. Tek satırlık yazmayı CTE'ye sokmak, en sık yolu bedava yavaşlatırdı.\n */\nfunction isSinglePkEquality(where: Record<string, unknown>, pk: string | null): boolean {\n if (pk === null) return false;\n const keys = Object.keys(where);\n if (keys.length !== 1 || keys[0] !== pk) return false;\n const v = where[pk];\n return v !== null && (typeof v !== \"object\" || Array.isArray(v));\n}\n\n/**\n * `appendOnly` tabloya yazma reddi (FR-032).\n *\n * Tip kapısı (`EnvTypedTable` altı üyeyi Omit ediyor) `Database.public.x` yolunu\n * kapatıyor. Ama motoru tipten geçmeden çağıran yollar var — `DBOps` doğrudan,\n * tablo adı string olarak. Bir muhasebe kaydında \"TypeScript'ten silinemez\"\n * yeterli değil.\n *\n * Hata ÇALIŞAN alternatifi adlandırıyor (P6): telafi kaydı eklemek gerçekten\n * çalışan yol, çünkü `insert` bu tabloda açık kalıyor.\n */\nfunction assertNotAppendOnly(caller: string, table: string): void {\n const def = tableDefOf(table) as { appendOnly?: boolean } | undefined;\n if (def?.appendOnly !== true) return;\n throw new Error(\n `${caller}(${table}): \"${table}\" append-only — satır güncellenemez ya da silinemez. ` +\n `Düzeltme için TELAFİ KAYDI ekleyin: insert(\"${table}\", { … }) ile ters işareti taşıyan ` +\n `yeni bir satır yazın; geçmiş olduğu gibi kalsın diye tablo böyle bildirilmiş (appendOnly: true).`,\n );\n}\n\nfunction computeSchemaColumns(table: string): Set<string> | null {\n const t = tableDefOf(table);\n const cols = t?.columns ? Object.keys(t.columns) : [];\n return cols.length > 0 ? new Set(cols) : null;\n}\n\n/** Keep PostgreSQL microseconds before a driver can reduce them to a JS Date.\n * All schema-aware result paths share this expression; predicates/order retain\n * the native timestamp column so indexes and comparison semantics stay intact. */\nfunction timestampResult(expr: string): string {\n return `CASE WHEN isfinite(${expr}) AND extract(year FROM ${expr} AT TIME ZONE 'UTC') BETWEEN 1 AND 9999 THEN to_char(${expr} AT TIME ZONE 'UTC', 'YYYY-MM-DD\"T\"HH24:MI:SS.US\"Z\"') ELSE ${expr}::text END`;\n}\n\nfunction columnResult(table: string, column: string, alias?: string): string {\n const expr = `${alias ? `${quoteIdent(alias)}.` : \"\"}${quoteIdent(column)}`;\n return columnTypeOf(table, column) === \"timestamp\" ? timestampResult(expr) : expr;\n}\n\nfunction projectedColumn(table: string, column: string, alias?: string): string {\n const expr = columnResult(table, column, alias);\n return columnTypeOf(table, column) === \"timestamp\" ? `${expr} AS ${quoteIdent(column)}` : expr;\n}\n\n/** Unknown schemas keep their raw wildcard behavior. Declared timestamps need\n * explicit expressions; the result then contains the declared row shape. */\n// ── can: policy'nin satır başına yankısı (FR-001…003 · D-15 · D-18) ────────────\n//\n// Tablonun adlandırılmış UPDATE policy'lerinin `using` ifadesi, satırı seçen\n// AYNI SELECT'te `(<using>) AS \"can:<name>\"` boolean sütunu olarak değerlendirilir;\n// `foldCan` true olanların adını `can: string[]`e katlar. Kural TEK kopya —\n// policy'de. Ham string (FR-028) BİREBİR girer; yapısal ifade `t` alias'ıyla\n// nitelenerek render edilir (Go `renderPolicyExpr`'in can-amaçlı ikizi). Render\n// edilemeyen (`using` yok, bilinmeyen kind, tablo adıyla nitelenmiş ham string)\n// DÜŞER ve warn yazar: sessiz `true` bir yetki yalanı olurdu, sessiz düşüş yalnız\n// bir düğmeyi saklar.\n//\n// Postgres'in kendi UPDATE kuralı da taşınır: `TO <rol>` listesi (policy o role\n// uygulanmıyorsa `can` da vaat etmez) ve AS RESTRICTIVE policy'ler (her izinli\n// policy'ye AND'lenir). `for(\"all\")` policy'leri `can`'e GİRMEZ — adlandırılmış\n// bir update policy'si değildir; kısıtlayıcı olanları yine AND'lenir.\nconst CAN_PREFIX = \"can:\";\ntype CanEntry = { name: string; using: string };\ntype CanDrop = { name: string; reason: string };\nconst canMemo: SchemaMetadataCache<Map<string, CanEntry[]>> = new WeakMap();\n\n/** C-1. `alias`: satır kaynağının SQL niteleyicisi — `t`, ya da alias'sız yolda tırnaklı tablo adı. */\nexport function canColumns(def: TableDef, alias: string): { sql: string[]; dropped: string[] } {\n const { entries, dropped } = canEntries(def, alias);\n return {\n sql: entries.map((e) => `${e.using} AS ${quoteIdent(CAN_PREFIX + e.name)}`),\n dropped: dropped.map((d) => d.name),\n };\n}\n\n/** Bildirilen rol üretimde `backend_<rol>` ikiziyle koşar (`config.ts` dbRole); ikisi de sayılır. Boş liste = PUBLIC. */\nfunction canRoleGate(roles: readonly string[]): string | null {\n if (roles.length === 0) return null;\n const names = roles.flatMap((r) => [r, `backend_${r}`]).map((r) => `'${r.replace(/'/g, \"''\")}'`);\n return `(current_user = ANY (ARRAY[${names.join(\", \")}]))`;\n}\n\nfunction canEntries(def: TableDef, alias: string): { entries: CanEntry[]; dropped: CanDrop[] } {\n const policies = def.policies ?? [];\n const dropped: CanDrop[] = [];\n const restrictive: string[] = [];\n for (const p of policies) {\n if (p.permissive !== false || (p.command !== \"update\" && p.command !== \"all\")) continue;\n const r = renderCanUsing(p, alias, def.name);\n if (r === null) {\n // Bir kısıtlayıcı policy değerlendirilemiyorsa HİÇBİR update policy'si vaat edilemez:\n // eksik bir AND, olmayan bir izni gösterirdi.\n return {\n entries: [],\n dropped: policies\n .filter((q) => q.command === \"update\" && q.permissive !== false)\n .map((q) => ({ name: q.name, reason: `restrictive policy \"${p.name}\" cannot be evaluated as a column` })),\n };\n }\n // Kısıtlayıcı da yalnız KENDİ `TO` rolüne uygulanır (Postgres): rol dışındaysa terim `true`.\n const rGate = canRoleGate(p.roles ?? []);\n restrictive.push(rGate === null ? r : `((NOT ${rGate}) OR ${r})`);\n }\n const entries: CanEntry[] = [];\n for (const p of policies) {\n if (p.command !== \"update\" || p.permissive === false) continue;\n // Postgres sonuç kolonunu 63 BAYTTA kırpar (NAMEDATALEN); `can:` 4 bayt yer.\n // Kırpılmış ad şemada olmayan bir değer olurdu — hiç vaat etme.\n if (Buffer.byteLength(CAN_PREFIX + p.name, \"utf8\") > 63) {\n dropped.push({ name: p.name, reason: \"its name is longer than 59 bytes and Postgres would truncate the column alias\" });\n continue;\n }\n const using = renderCanUsing(p, alias, def.name);\n if (using === null) {\n dropped.push({ name: p.name, reason: \"its using expression cannot be selected as a column (null; a raw string that is table-qualified, carries a comment or unbalanced parentheses, or calls auth.has_permission outside a (select …) wrapper; or a shape this engine does not render)\" });\n continue;\n }\n const gate = canRoleGate(p.roles ?? []);\n const parts = [...(gate === null ? [] : [gate]), using, ...restrictive];\n entries.push({ name: p.name, using: parts.length === 1 ? using : `(${parts.join(\" AND \")})` });\n }\n return { entries, dropped };\n}\n\n/** Ham string her zaman parantezlenir (içinde `a or b` olabilir); yapısal ifade\n * kendi parantezini taşıyorsa (binop/and/or/not/isNull/exists) ikinci kat açılmaz.\n * Tablo ADIYLA nitelenmiş ham string (`transfers.status`) alias altında çözülmez —\n * okuma anında 500 yerine burada düşer (fail-closed, warn). */\nclass CanRenderError extends Error {}\n\n/** Motorun kendi alias uzayı: `t` (satır), `w<n>`/`wj<n>` (with), `locked` (kilit CTE).\n * Bir `exists` alt-sorgusu bunlardan birini alsa korelasyon SESSİZCE `x = x`e çökerdi. */\nconst ENGINE_ALIASES = /^(t|locked|w\\d+|wj\\d+|x|q|g|p|upd)$/;\n\nfunction renderCanUsing(p: PolicyDef, qualifier: string, tableName: string): string | null {\n if (p.using === null || p.using === undefined) return null;\n if (typeof p.using === \"string\") {\n // String literalleri çıkar: `has_permission('transfers.approve')` içindeki\n // `transfers.` bir tablo niteleyicisi değildir.\n const withoutLiterals = p.using.replace(/'(?:[^']|'')*'/g, \"''\");\n // Yorum (`--`, `/*`) tek satırlık SELECT listesinde açık parantezi yutar ve\n // TABLOYU okunamaz yapardı; dengesiz parantez ve kapanmamış tırnak da öyle. Düşür, uyar.\n if (/--|\\/\\*/.test(withoutLiterals)) return null;\n if (withoutLiterals.replace(/''/g, \"\").includes(\"'\")) return null;\n let depth = 0;\n for (const ch of withoutLiterals) {\n if (ch === \"(\") depth++;\n else if (ch === \")\" && --depth < 0) return null;\n }\n if (depth !== 0) return null;\n // Tablo ADIYLA niteleme — çıplak (`transfers.status`), tırnaklı\n // (`\"transfers\".\"status\"`) ya da şema önekli (`public.transfers.status`) —\n // alias altında çözülmez; `CREATE POLICY` kabul eder, SELECT etmez (W1 h1 C-4 ×3).\n const tbl = tableName.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n const qualified = new RegExp(`(^|[^A-Za-z0-9_])(?:\"?[A-Za-z_][A-Za-z0-9_]*\"?\\\\s*\\\\.\\\\s*)?\"?${tbl}\"?\\\\s*\\\\.`);\n if (qualified.test(withoutLiterals)) return null;\n // FR-006: çıplak `auth.has_permission(...)` SATIR BAŞINA koşar; `(select …)`\n // sarmalı statement başına bir kez. HER çağrı sarmalı olmalı — bir sarmalı bir\n // çıplak çağrı da düşer. Noktanın çevresindeki boşluk SQL'de serbesttir (`auth . has_permission`).\n // Tanımlayıcı tırnaklı da yazılabilir (`auth.\"has_permission\"`), sarmalı biçim\n // `(select (auth.has_permission(…)))` de InitPlan'dır (W1 h1-r4 N-11/N-12).\n const calls = withoutLiterals.match(/auth\\s*\\.\\s*\"?has_permission\"?\\s*\\(/gi) ?? [];\n const wrapped = withoutLiterals.match(/\\(\\s*select\\s*[(\\s]*auth\\s*\\.\\s*\"?has_permission\"?\\s*\\(/gi) ?? [];\n if (calls.length !== wrapped.length) return null;\n return `(${p.using})`;\n }\n try {\n const rendered = canExprSql(p.using, qualifier);\n const selfParenthesized =\n p.using.kind === \"binop\" || p.using.kind === \"and\" || p.using.kind === \"or\" ||\n p.using.kind === \"not\" || p.using.kind === \"isNull\" || p.using.kind === \"exists\";\n return selfParenthesized ? rendered : `(${rendered})`;\n } catch (err) {\n if (err instanceof CanRenderError) return null;\n throw err;\n }\n}\n\nconst CAN_BINOPS: Record<string, string> = { eq: \"=\", neq: \"<>\", gt: \">\", gte: \">=\", lt: \"<\", lte: \"<=\" };\n\nfunction canLiteral(v: string | number | boolean | null): string {\n if (v === null) return \"NULL\";\n if (typeof v === \"boolean\") return v ? \"TRUE\" : \"FALSE\";\n if (typeof v === \"number\") {\n if (!Number.isFinite(v)) throw new CanRenderError(\"can: non-finite literal\");\n return String(v);\n }\n return `'${v.replace(/'/g, \"''\")}'`;\n}\n\n/** Yapısal policy ifadesini SQL'e çevirir. Alias'sız kolon = DIŞ (bizim) satır,\n * `exists` içinde de — Go emitter'ının kuralı (policy_expr.go:109-131). */\nfunction canExprSql(e: PolicyExpr, qualifier: string): string {\n switch (e.kind) {\n case \"col\":\n return e.alias !== undefined && e.alias !== \"\"\n ? `${quoteIdent(e.alias)}.${quoteIdent(e.name)}`\n : `${qualifier}.${quoteIdent(e.name)}`;\n case \"authUid\":\n return \"(SELECT auth.uid())\";\n case \"lit\":\n return canLiteral(e.value);\n case \"binop\": {\n const op = CAN_BINOPS[e.op];\n if (op === undefined) throw new CanRenderError(`can: unknown operator ${String(e.op)}`);\n return `(${canExprSql(e.left, qualifier)} ${op} ${canExprSql(e.right, qualifier)})`;\n }\n case \"and\":\n return e.parts.length === 0 ? \"(true)\" : `(${e.parts.map((p) => canExprSql(p, qualifier)).join(\" AND \")})`;\n case \"or\":\n return e.parts.length === 0 ? \"(false)\" : `(${e.parts.map((p) => canExprSql(p, qualifier)).join(\" OR \")})`;\n case \"not\":\n return `(NOT ${canExprSql(e.expr, qualifier)})`;\n case \"isNull\":\n return `(${canExprSql(e.expr, qualifier)} IS ${e.negated ? \"NOT \" : \"\"}NULL)`;\n case \"exists\":\n if (e.alias === \"\" || ENGINE_ALIASES.test(e.alias)) {\n throw new CanRenderError(`can: exists alias \"${e.alias}\" collides with the engine's own aliases — the correlation would silently collapse`);\n }\n return `EXISTS (SELECT 1 FROM ${quoteTable(e.table)} ${quoteIdent(e.alias)} WHERE ${canExprSql(e.predicate, qualifier)})`;\n default:\n throw new CanRenderError(`can: unknown policy expression kind ${String((e as { kind: unknown }).kind)}`);\n }\n}\n\n/** Şema kurulumu başına bir kez hesaplanır; uyarı tablo başına BİR kez (alias sayısı kadar değil). */\nfunction canEntriesOf(table: string, alias: string): CanEntry[] {\n const byAlias = memoTable(canMemo, currentSchema, table, () => new Map<string, CanEntry[]>());\n const hit = byAlias.get(alias);\n if (hit !== undefined) return hit;\n const def = tableDefOf(table);\n const warnOnce = (msg: string): void => {\n if (byAlias.has(\"__warned\")) return;\n byAlias.set(\"__warned\", []);\n console.warn(msg);\n };\n if (def === null || def.policies === undefined) {\n byAlias.set(alias, []);\n return [];\n }\n if (hasCanColumn(table)) {\n // Gerçek bir `can` kolonu/ilişkisi var: onu ezmek veri kaybı olurdu. Afordans bu tabloda kapalı.\n warnOnce(`can(${table}): the table declares a column or relation named \"can\", so the policy echo is disabled for it — rename it to get can`);\n byAlias.set(alias, []);\n return [];\n }\n const { entries, dropped } = canEntries(def as TableDef, alias === \"\" ? quoteTable(table) : alias);\n if (dropped.length > 0) {\n warnOnce(\n dropped\n .map((d) => `can(${table}): policy \"${d.name}\" is not exposed in can — ${d.reason}; the database still enforces it`)\n .join(\"\\n\"),\n );\n }\n byAlias.set(alias, entries);\n return entries;\n}\n\n/** Arama/sayfa gibi sarmalanmış sorgularda `can` DIŞ SELECT'te seçilir: iç\n * sorgunun FROM'u (`fused`, `sem`, `kw`) pk'yı da taşır ve niteliksiz ham `using`\n * orada \"ambiguous\" olurdu; dışta kapsamda yalnız `q` vardır (W1 r1). */\nfunction canOuter(table: string): string {\n const cols = canProjection(table, \"q\");\n return cols.length === 0 ? \"\" : `, ${cols.join(\", \")}`;\n}\n\nfunction canProjection(table: string, alias: string): string[] {\n return canEntriesOf(table, alias).map((e) => `${e.using} AS ${quoteIdent(CAN_PREFIX + e.name)}`);\n}\n\n/** `with` ile gelen iç içe satırın JSON nesnesine eklenen `'can:<name>', <expr>` çiftleri —\n * aynı statement, aynı kural (FR-002); satır tipi `can` taşıdığı için değeri de taşımalı. */\nfunction canJsonPairs(table: string, alias: string): string[] {\n return canEntriesOf(table, alias).map((e) => `${quoteLiteral(CAN_PREFIX + e.name)}, ${e.using}`);\n}\n\n/** \"can:*\" sütunlarını `can: string[]`e katlar ([PLAN-FREE] adı). `partial`: `select`\n * projeksiyonu — alan hiç yazılmaz. */\nfunction foldCan(table: string, row: Row, partial: boolean): Row {\n let can: string[] | null = null;\n for (const key of Object.keys(row)) {\n if (!key.startsWith(CAN_PREFIX)) continue;\n can ??= [];\n if (row[key] === true) can.push(key.slice(CAN_PREFIX.length));\n delete row[key];\n }\n if (hasCanColumn(table)) return row; // rezerve ad: kolon/ilişki neyse o kalır\n if (can !== null) row.can = can;\n else if (!partial && tableDefOf(table) !== null) {\n // Tam satır, sütun gelmedi: policy'si olan bir tabloda bu, sütun taşımayan\n // bir okuma yolu demektir — `[]` yazılır (fail-closed) ama SESSİZ değil\n // (W1 h1-r4 N-9: arama üç tur boyunca böyle `[]` uydurdu).\n if (canEntriesOf(table, \"\").length > 0) {\n const flags = memoTable(canMemo, currentSchema, table, () => new Map<string, CanEntry[]>());\n if (!flags.has(\"__missing_warned\")) {\n flags.set(\"__missing_warned\", []);\n console.warn(`can(${table}): a full-row read returned no \"can:*\" columns although the table declares update policies — this statement shape does not carry can; the row gets can: []`);\n }\n }\n row.can = [];\n }\n return row;\n}\n\n/** `can` adı REZERVE: gerçek bir kolon YA DA ilişki (`can_id` FK'sinden türeyen\n * `can`, ya da `refAs`/`reverseAs`) taşıyan tabloda yankı kapalı — ezmek veri\n * kaybı, `with` döngüsüyle çakışmak TypeError olurdu (W1 h1-r2 C-3). */\nfunction hasCanColumn(table: string): boolean {\n const cols = tableDefOf(table)?.columns;\n if (cols !== undefined && Object.prototype.hasOwnProperty.call(cols, \"can\")) return true;\n return (currentRelations.get(table) ?? []).some((rel) => rel.name === \"can\");\n}\n\nfunction rowProjection(table: string, alias?: string, wildcard = alias ? `${alias}.*` : \"*\"): string {\n const cols = schemaColumns(table);\n let base = wildcard;\n if (cols && memoTable(timestampMemo, currentSchema, table, () => [...cols].some(c => columnTypeOf(table, c) === \"timestamp\"))) {\n const projections = memoTable(projectionMemo, currentSchema, table, () => new Map<string, string>());\n const key = alias ?? \"\";\n let sql = projections.get(key);\n if (sql === undefined) { sql = [...cols].map(c => projectedColumn(table, c, alias)).join(\", \"); projections.set(key, sql); }\n base = sql;\n }\n const can = canProjection(table, alias ?? \"\");\n if (can.length === 0) return base;\n // `*` alias altında `t.*` olmak zorunda: `with` LATERAL join'leri kendi `d` sütununu da taşır.\n const rows = base === \"*\" && alias !== undefined ? `${alias}.*` : base;\n return `${rows}, ${can.join(\", \")}`;\n}\n\n/** ORDER BY, with the column checked BEFORE it can reach SQL. Against a known\n * schema the check is membership; without one it is a conservative identifier\n * shape. Either way an ordering column is never interpolated on trust. */\n/**\n * Projeksiyon listesi (FR-009). Verilmezse `*`.\n *\n * Her kolon `orderBy` ile AYNI kapıdan geçer: şema biliniyorsa üyelik, bilinmiyorsa\n * tanımlayıcı şekli. Listenin her öğesi ayrı doğrulanır — ilk öğe masumken\n * ikincisini atlamak, listeye bir öğe eklemeyi enjeksiyon yoluna çevirirdi.\n */\n/**\n * `col()` referansını SQL'e çevirir (FR-011).\n *\n * Kolon adı SQL METNİNE girer — parametre olarak bağlanamaz, çünkü bağlanan\n * şey bir değer olurdu ve `total > 'amount_paid'` string karşılaştırması\n * yapardı. Metne giren her ad `selectClause`/`orderClause` ile AYNI kapıdan\n * geçer: şema biliniyorsa üyelik, bilinmiyorsa tanımlayıcı şekli.\n */\nfunction colRefSql(table: string, known: Set<string> | null, ref: { $col: string }, caller: string, alias = \"t\"): string {\n const name = ref.$col;\n const shapeOK = /^[A-Za-z_][A-Za-z0-9_]*$/.test(name);\n if (known !== null ? !known.has(name) : !shapeOK) {\n throw new Error(`${caller}(${table}): col(\"${name}\") tabloda yok (FR-011)`);\n }\n return `${alias}.${quoteIdent(name)}`;\n}\n\nfunction selectClause(table: string, known: Set<string> | null, select: string[] | undefined): string {\n // BOŞ PROJEKSİYON `*` DEĞİLDİR — ve sessizce öyle davranıyordu.\n //\n // `select: []` ile `select: undefined` aynı dala düşüyor ve ikisi de HER\n // KOLONU çekiyordu. Ama anlamları zıt: birini YAZMAMAK \"projeksiyon yok,\n // hepsini ver\" demek; BOŞ BİR LİSTE yazmak \"şu kolonları ver\" deyip hiçbirini\n // saymamak demek — ve cevabı kesinlikle \"hepsi\" değil.\n //\n // Şekli üreten hâl de tam olarak sessiz kalmaması gereken hâl:\n // `select: cols.filter(isVisible)` her kolonu elediğinde çağıran, gizlemeye\n // çalıştığı kolonların TAMAMINI alıyordu. Aynı dosya boş `in` listesini\n // (`false` yazıyor) ve boş filtreyi (adıyla reddediyor) tam bu gerekçeyle\n // ele alıyor; `select` onlardan ayrışmıştı.\n if (select !== undefined && select.length === 0) {\n throw new Error(\n `findMany(${table}): select boş bir liste aldı — bu \"hepsini ver\" DEĞİL, ` +\n `\"hiçbirini saymadım\" demek. Projeksiyon istemiyorsanız anahtarı hiç koymayın; ` +\n `istiyorsanız en az bir kolon adı verin.`,\n );\n }\n if (select === undefined) return rowProjection(table, \"t\", \"*\");\n return select\n .map((col) => {\n const shapeOK = /^[A-Za-z_][A-Za-z0-9_]*$/.test(col);\n if (known !== null ? !known.has(col) : !shapeOK) {\n throw new Error(`findMany(${table}): select kolonu \"${col}\" tabloda yok`);\n }\n return columnTypeOf(table, col) === \"timestamp\" ? projectedColumn(table, col, \"t\") : `t.${quoteIdent(col)}`;\n })\n .join(\", \");\n}\n\n/** JSON anahtarı için SQL string literal'i. Kolon adı zaten şemaya karşı\n * doğrulanıyor, ama tek tırnak KAÇIRILMADAN bir literal kurmak, doğrulamanın\n * bir gün gevşediği anı enjeksiyona çevirirdi. */\nfunction quoteLiteral(v: string): string {\n return `'${v.replace(/'/g, \"''\")}'`;\n}\n\n/** {@link orderClause}'ın TAKMA ADLI ikizi — `with` alt sorgusu kendi adını\n * kullanır, dış sorgunun `t`'sini değil. */\nfunction orderClauseFor(\n table: string,\n known: Set<string> | null,\n orderBy: unknown,\n alias: string,\n): string {\n if (orderBy === undefined || orderBy === null) return \"\";\n const items = (Array.isArray(orderBy) ? orderBy : [orderBy]) as {\n column: string;\n direction?: \"asc\" | \"desc\";\n nulls?: \"first\" | \"last\";\n }[];\n if (items.length === 0) return \"\";\n const rendered = items.map((o) => {\n const col = o.column;\n const shapeOK = /^[A-Za-z_][A-Za-z0-9_]*$/.test(col);\n if (known !== null ? !known.has(col) : !shapeOK) {\n throw new Error(`with(${table}): orderBy kolonu \"${col}\" tabloda yok`);\n }\n const dir = o.direction === \"desc\" ? \"DESC\" : \"ASC\";\n const nulls = o.nulls === \"first\" ? \" NULLS FIRST\" : o.nulls === \"last\" ? \" NULLS LAST\" : \"\";\n return `${alias}.${quoteIdent(col)} ${dir}${nulls}`;\n });\n return ` ORDER BY ${rendered.join(\", \")}`;\n}\n\nfunction orderClause(\n table: string,\n known: Set<string> | null,\n orderBy: FindManyOptions[\"orderBy\"],\n): string {\n if (!orderBy) return \"\";\n // SIRA KORUNUR: `ORDER BY`ın anlamı sıralı bir listedir, küme değil. Tek obje\n // biçimi de kabul edilir — çağıranların hepsi aynı anda göç edemez ve tek\n // öğeli bir liste ile tek obje AYNI SQL'i üretir (FR-008).\n const items = Array.isArray(orderBy) ? orderBy : [orderBy];\n if (items.length === 0) return \"\";\n const rendered = items.map((o) => {\n const col = o.column;\n const shapeOK = /^[A-Za-z_][A-Za-z0-9_]*$/.test(col);\n if (known !== null ? !known.has(col) : !shapeOK) {\n throw new Error(`findMany(${table}): orderBy kolonu \"${col}\" tabloda yok`);\n }\n const dir = o.direction === \"desc\" ? \"DESC\" : \"ASC\";\n // NULL'ın YERİ ayrı bir karardır: Postgres varsayılanı ASC'de NULLS LAST,\n // DESC'te NULLS FIRST'tür ve bu, sıralama yönünü değiştirdiğinde NULL'ların\n // sessizce yer değiştirmesi demektir. Yazar isterse sabitler.\n const nulls = o.nulls === \"first\" ? \" NULLS FIRST\" : o.nulls === \"last\" ? \" NULLS LAST\" : \"\";\n return `${quoteIdent(col)} ${dir}${nulls}`;\n });\n return ` ORDER BY ${rendered.join(\", \")}`;\n}\n\n/** LIMIT, as a literal because it is a number this code produced — a bound must\n * not be bindable to something that is not one. */\nfunction limitClause(limit: number | undefined): string {\n if (limit === undefined) return \"\";\n if (!Number.isInteger(limit) || limit < 0) {\n throw new Error(`findMany: limit bir negatif olmayan tam sayı olmalı (geldi: ${String(limit)})`);\n }\n return ` LIMIT ${limit}`;\n}\n\n/** OFFSET, a literal for the same reason LIMIT is one.\n *\n * A bare `offset` — no `limit` — is refused BY NAME. Postgres accepts it, but\n * \"skip 10 rows of an unbounded result\" is not a page, and every caller that\n * writes `offset` means a page; letting it through would hand back the whole\n * tail and look like it worked. */\nfunction offsetClause(offset: number | undefined, limit: number | undefined): string {\n if (offset === undefined) return \"\";\n if (!Number.isInteger(offset) || offset < 0) {\n throw new Error(\n `findMany: offset bir negatif olmayan tam sayı olmalı (geldi: ${String(offset)})`,\n );\n }\n if (limit === undefined) {\n throw new Error(\n \"findMany: offset yalnız limit ile birlikte verilir — limitsiz offset bir sayfa değil, sınırsız bir kuyruğun kaydırılmışıdır\",\n );\n }\n return ` OFFSET ${offset}`;\n}\n\n/** where → SQL (FR-016): eşitlik + gt/gte/lt/lte/neq/in, AND'li. Kolon adı\n * şemadan doğrulanır — bilinmeyen ad SQL'e ulaşmadan, adıyla reddedilir. */\n/**\n * Filtrenin ÖNEKSİZ gövdesi: `a AND b`, baştaki `AND` olmadan.\n *\n * Ayrı duruyor çünkü {@link compileWhere} çağıranlarına ` AND …` önekiyle\n * dönüyor (`WHERE true` + dönüş deseni) ve bileşim dalları (OR/AND/NOT) o öneki\n * TAŞIYAMAZ — iç içe geçtiğinde `(( AND x) OR ( AND y))` üretirdi.\n */\nfunction compileWhereBare(\n table: string,\n colSet: Set<string> | null,\n where: Record<string, unknown>,\n add: (v: unknown, column?: string, table?: string) => string,\n caller = \"search\",\n /** Kolonların niteleneceği takma ad. `has` alt sorgusu KENDİ adını verir —\n * iç ve dış sorgu aynı `t`'yi paylaşsaydı korelasyon sessizce `x = x`'e\n * çökerdi; policy tarafında bu tam olarak ölçülmüş bir hataydı. */\n alias = \"t\",\n /** İç içe `has` derinliği — takma adları ayırmak için. */\n depth = 0,\n): string {\n const parts: string[] = [];\n // A column's `toDb` applies on the WHERE path too. Without it a transform is\n // half-wired: `insert` writes the converted value and `findMany({ at: date })`\n // binds the client-side shape, so the row that was just written does not come\n // back. The bind goes through `bind` below, never `add` directly.\n const transforms = transformsOf(currentSchema, table);\n const bindFor = (col: string) => {\n const t = transforms.get(col);\n return (v: unknown) => add(t?.toDb === undefined || v === null || v === undefined ? v : t.toDb(v), col, table);\n };\n // The refusals live in ONE place (db/input-guards.ts) because `fakeDatabase()`\n // is a second implementation of this surface and has to answer identically —\n // measured on 24.1.0: every call this function had just started refusing went\n // through the fake silently, so an author's test went green on code that\n // throws in production.\n assertUsableFilter(caller, table, where);\n // K3 (FR-018): fragment SORGUNUN İÇİNE girer. Metin parçaları SQL'e, değerler\n // BOUND parametreye — arada, birleştirilmeden. Birleştirilmiş tek string'in\n // içinden hangi kısmın kullanıcı verisi olduğu bir daha çıkarılamaz; enjeksiyon\n // tam orada doğar. Tanımlayıcı gömme kapağı yok (research B4: Drizzle\n // CVE-2026-39356, Knex CVE-2019-10757).\n if (isSqlFragment(where)) {\n const { text, values } = where.$sql;\n if (text.length !== values.length + 1) {\n throw new Error(\n `${caller}(${table}): sqlFragment parçaları bozuk (${text.length} metin, ${values.length} değer) — bunu üreten tek şey template tag'i, elle kurulmuş bir nesne değil`,\n );\n }\n let out = text[0] ?? \"\";\n for (let i = 0; i < values.length; i++) out += `${add(values[i])}${text[i + 1] ?? \"\"}`;\n // PARANTEZ: bu fonksiyonun kendi kuralı, fragment dalına da uygulanır.\n // `whereSql` üst düzeyde `WHERE true AND …` önekiyle şansa denk düşüyordu\n // ama `search`/`facets` onu BAŞKA koşullarla birleştiriyor (`… @@ … ${whereSql}`);\n // orada `hit AND a=1 OR b=2` ile `hit AND (a=1 OR b=2)` farklı sorgular ve\n // ölçüldü: 3 satır vs 1 satır (W2-B/C2).\n return `(${out})`;\n }\n for (const [col, cond] of Object.entries(where)) {\n // Boolean bileşimi (FR-007). Her dal PARANTEZLENİR: `a AND (b OR c)` ile\n // `(a AND b) OR c` farklı sorgulardır ve parantezsiz derleme ikincisini\n // SESSİZCE üretirdi. Dallar aynı derleyiciden geçer — iki filtre dili olmaz.\n if (col === \"OR\" || col === \"AND\") {\n const branches = cond as Record<string, unknown>[];\n if (branches.length === 0) {\n // Boş liste \"hiçbir satır\" demektir (OR) ya da \"koşulsuz\" (AND);\n // ikisini de AÇIKÇA yaz, sessiz tam-tarama bırakma.\n parts.push(col === \"OR\" ? \"false\" : \"true\");\n continue;\n }\n const compiled = branches.map(\n (b) => `(${compileWhereBare(table, colSet, b, add, caller, alias, depth)})`,\n );\n parts.push(`(${compiled.join(col === \"OR\" ? \" OR \" : \" AND \")})`);\n continue;\n }\n // İLİŞKİ ÜZERİNDEN SÜZME (`has`) — ve bu JOIN'in yerine geçen şey değil,\n // JOIN'in İHTİYAÇ DUYULMAYAN hâli.\n //\n // `{ has: { user_interests: { user_id: uid } } }` şuna derleniyor:\n // t.\"id\" IN (SELECT r1.\"interest_id\" FROM \"user_interests\" r1 WHERE r1.\"user_id\" = $1)\n //\n // Kolon adları ilişkinin KENDİSİNDEN geliyor (`buildRelations`), yazardan\n // değil: hangi kolonun hangi kolona baktığını bildirimden başkası bilemez,\n // ve onu elle yazdırmak \"iki yorumcu\" demekti.\n //\n // İç filtre AYNI derleyiciden geçiyor — `has` ikinci bir filtre dili DEĞİL,\n // aynı dilin bir tablo ötesi. İç sorgu KENDİ takma adını alıyor; paylaşsalardı\n // korelasyon sessizce `x = x`'e çökerdi (policy tarafında ölçülmüş hata).\n if (col === \"has\") {\n const rels = currentRelations.get(table) ?? [];\n for (const [relName, inner] of Object.entries(cond as Record<string, unknown>)) {\n const rel = rels.find((r) => r.name === relName);\n if (rel === undefined) {\n const known = rels.map((r) => r.name).sort();\n throw new Error(\n `${caller}(${table}): has.${relName} diye bir ilişki yok` +\n (known.length > 0\n ? ` (bilinenler: ${known.join(\", \")}). İlişkiler yabancı anahtarlardan TÜRETİLİR; ` +\n `adını değiştirmek için references(..., { as, reverseAs }).`\n : `. Bu tablo HİÇ yabancı anahtar bildirmiyor, ve ilişkiler onlardan TÜRETİLİR. ` +\n `Var olan bir veritabanından introspect edilmiş şemalarda bu sık olur: kolon ` +\n `\\`text()\\`/\\`uuid()\\` olarak durur, \\`references(() => <tablo>.<kolon>)\\` yoktur. ` +\n `Bildirdiğiniz anda ilişki iki tarafta da adlandırılır — ama bu CANLI veritabanına ` +\n `giden bir kısıttır ve mevcut yetim satırlar onu düşürür; önce onları sayın.`),\n );\n }\n // `many`: FK karşı tabloda, bizim tarafımız kendi PK'mız.\n // `one`: FK bizde, karşı taraf onların PK'sı.\n const [ourCol, theirCol] = relationColumns(table, rel);\n if (ourCol === null || theirCol === null) {\n const missing = ourCol === null ? table : rel.to;\n throw new Error(\n `${caller}(${table}): has.${relName} kurulamıyor — \"${missing}\" tablosunun tek kolonlu bir ` +\n `primary key'i yok. Korelasyon bir anahtar ister; çok kolonlu anahtarda ilişki üzerinden ` +\n `süzmek yerine sqlFragment ile yazın.`,\n );\n }\n const sub = `r${depth + 1}`;\n const innerSql = compileWhereBare(\n rel.to,\n schemaColumns(rel.to),\n (inner ?? {}) as Record<string, unknown>,\n add,\n caller,\n sub,\n depth + 1,\n );\n parts.push(\n `${alias}.${quoteIdent(ourCol)} IN (SELECT ${sub}.${quoteIdent(theirCol)} ` +\n `FROM ${quoteTable(rel.to)} ${sub}${innerSql === \"\" ? \"\" : ` WHERE ${innerSql}`})`,\n );\n }\n continue;\n }\n if (col === \"NOT\") {\n parts.push(\n `NOT (${compileWhereBare(table, colSet, cond as Record<string, unknown>, add, caller, alias, depth)})`,\n );\n continue;\n }\n // A null colSet means \"no schema to check against\" — the case `findMany`\n // reaches when a table is addressed by name alone. Identifiers still go\n // through quoteIdent, so an unknown name is a Postgres error, never syntax.\n if (colSet !== null && !colSet.has(col)) {\n throw new Error(`${caller}(${table}): where kolonu \"${col}\" tabloda yok (FR-016)`);\n }\n const q = `${alias}.${quoteIdent(col)}`;\n const bind = bindFor(col);\n // Çıplak `col()` bir DEĞER'dir: `{ title: col(\"owner\") }` → eşitlik. Bu\n // kontrol operatör dalından ÖNCE gelmeli, yoksa `{ $col: … }` bir operatör\n // haritası sanılırdı.\n if (isColRef(cond)) {\n parts.push(`${q} = ${colRefSql(table, colSet, cond, caller, alias)}`);\n continue;\n }\n // Çıplak `now()` — `{ expires_at: now() }` eşitlik. `col()` ile aynı yerde,\n // aynı nedenle: operatör dalından ÖNCE, yoksa tutamak bir operatör haritası\n // sanılırdı (tutamak bir Proxy'dir ve bilinmeyen prop'ta undefined döner).\n if (isNowExpr(cond)) {\n parts.push(`${q} = now()`);\n continue;\n }\n if (cond !== null && typeof cond === \"object\" && !Array.isArray(cond)) {\n for (const [op, v] of Object.entries(cond as Record<string, unknown>)) {\n // K1 metin operatörleri (FR-005). Desen BOUND PARAMETRE olarak gider;\n // `%` derleyicide eklenir ve kullanıcı verisindeki `%`/`_` KAÇIRILIR —\n // aksi hâlde bir arama kutusuna yazılan \"%\" tüm tabloyu döndürürdü.\n if (op === \"contains\" || op === \"icontains\" || op === \"startsWith\" || op === \"endsWith\") {\n if (typeof v !== \"string\") {\n throw new Error(`${caller}(${table}): where.${col}.${op} bir string olmalı`);\n }\n const lit = v.replace(/([\\\\%_])/g, \"\\\\$1\");\n const pattern =\n op === \"startsWith\" ? `${lit}%` : op === \"endsWith\" ? `%${lit}` : `%${lit}%`;\n parts.push(`${q} ${op === \"icontains\" ? \"ILIKE\" : \"LIKE\"} ${bind(pattern)}`);\n continue;\n }\n // NULL testi (FR-006): `= NULL` SQL'de her zaman UNKNOWN'dır, bu yüzden\n // niyet ayrı bir operatörle yazılır ve parametre ALMAZ.\n if (op === \"isNull\") {\n if (typeof v !== \"boolean\") {\n throw new Error(`${caller}(${table}): where.${col}.isNull bir boolean olmalı`);\n }\n parts.push(`${q} IS ${v ? \"NULL\" : \"NOT NULL\"}`);\n continue;\n }\n if (op === \"in\") {\n if (!Array.isArray(v)) throw new Error(`${caller}(${table}): where.${col}.in bir dizi olmalı`);\n // `in` listesinin ELEMANLARI değerdir. Bir `col()` buraya düşerse\n // parametre olarak bağlanır ve karşılaştırma sessizce yanlış olur —\n // `eq` aynı reddi adıyla veriyor, `in` sessiz kalıyordu (T010/I1).\n if (v.some(isColRef)) {\n throw new Error(`${caller}(${table}): where.${col}.in col() ile kullanılamaz — kolon karşılaştırması için çıplak biçimi ({ ${col}: col(\"…\") }) ya da gt/gte/lt/lte/neq kullanın`);\n }\n if (v.length === 0) {\n // Boş in-listesi \"hiçbir satır\" demektir — sessiz tam-tarama yerine\n // anlamı SQL'e açıkça yaz (review I5).\n parts.push(\"false\");\n continue;\n }\n // Placeholder genişletmesi: her eleman AYRI parametre. `= ANY($n)`\n // dizi bind'i sürücüde Postgres array literal'ine çevrilmiyor ve\n // canlıda `malformed array literal: \"ops,general\"` 500'ü veriyordu\n // (verify 19-3b, 2026-08-28). IN listesi tip-agnostik ve sürücüden\n // bağımsız; boş liste yukarıda açık `false`.\n parts.push(`${q} IN (${v.map((x) => bind(x)).join(\", \")})`);\n } else if (isNowExpr(v)) {\n // Sağ taraf SUNUCU SAATİ: parametre YOK, saat veritabanında okunuyor.\n // JS'ten `new Date()` göndermek istemci saatine geçmek olurdu.\n if (!(op in WHERE_OPS)) {\n throw new Error(`${caller}(${table}): where.${col}.${op} now() ile kullanılamaz — eşitlik için çıplak biçimi kullanın: { ${col}: now() }`);\n }\n parts.push(`${q} ${WHERE_OPS[op]} now()`);\n } else if (isColumnExpr(v)) {\n // `increment()`/`decrement()` bir YAZMA ifadesi. `now()` yukarıda\n // ayrı dal; buraya düşen her şey filtrede anlamsız ve ADIYLA\n // reddediliyor, çünkü sessizce bağlanırsa karşılaştırma `[object\n // Object]` ile yapılır ve hiçbir satır dönmez — hatasız.\n throw new Error(\n `${caller}(${table}): where.${col}.${op} bir YAZMA ifadesi aldı (increment/decrement) — ` +\n `karşılaştırma değeri değil. Sunucu saati için now() kullanın; sayısal bir eşik için değeri yazın.`,\n );\n } else if (isColRef(v)) {\n // Sağ taraf kolon (FR-011): parametre YOK. `in` yukarıda ayrı dal,\n // metin operatörleri desen ister — ikisi de buraya düşmez.\n if (!(op in WHERE_OPS)) {\n throw new Error(`${caller}(${table}): where.${col}.${op} col() ile kullanılamaz — eşitlik için çıplak biçimi kullanın: { ${col}: col(\"…\") }`);\n }\n parts.push(`${q} ${WHERE_OPS[op]} ${colRefSql(table, colSet, v, caller, alias)}`);\n } else if (looksLikeUnbrandedRef(v) !== null) {\n // MARKASIZ TAKLİT. Üst düzeyde \"bilinmeyen operatör\" diye\n // reddediliyor; burada sessizce PARAMETRE olarak bağlanıyordu ve\n // jsonb/text kolonunda sonuç HİÇBİR SATIR oluyordu, hatasız.\n const kind = looksLikeUnbrandedRef(v);\n const made = kind === \"col\" ? \"col()\" : kind === \"sql\" ? \"sqlFragment\" : \"now()\";\n const how = kind === \"col\" ? 'col(\"kolon_adı\")' : kind === \"sql\" ? \"sqlFragment`…`\" : \"now()\";\n throw new Error(\n `${caller}(${table}): where.${col}.${op} bir ${made} TAKLİDİ aldı — ` +\n `bu nesne bu süreçte ${made} ile üretilmemiş. ` +\n `İstek gövdesinden gelen bir filtre işaretçi TAŞIYAMAZ; koşulu kendi kodunuzda ` +\n `${how} ile kurun.`,\n );\n } else if (op in WHERE_OPS) {\n // NULL'a eşitlik SQL'de hiçbir zaman doğru değildir — `= NULL` ve\n // `<> NULL` ikisi de UNKNOWN, yani hiçbir satır. Yazarın YAZDIĞI bir\n // null'ı sessizce boş sonuca çevirmek, undefined'ın az önce kapatılan\n // hatasının aynısı. Soru IS NULL / IS NOT NULL ile sorulur.\n if (v === null && op === \"neq\") {\n parts.push(`${q} IS NOT NULL`);\n continue;\n }\n parts.push(`${q} ${WHERE_OPS[op]} ${bind(v)}`);\n } else {\n throw new Error(`${caller}(${table}): where.${col} bilinmeyen operatör \"${op}\" (gt/gte/lt/lte/neq/in)`);\n }\n }\n } else if (cond === null) {\n // Aynı gerekçe, kısa yazılış: `{ deleted_at: null }` — \"silinmemiş\n // satırlar\" demenin en doğal yolu — `= $1` derlenip hiçbir satır\n // döndürüyordu.\n parts.push(`${q} IS NULL`);\n } else {\n parts.push(`${q} = ${bind(cond)}`);\n }\n }\n return parts.join(\" AND \");\n}\n\n/** {@link compileWhereBare}, çağıranların beklediği ` AND …` önekiyle. */\nfunction compileWhere(\n table: string,\n colSet: Set<string> | null,\n where: Record<string, unknown>,\n add: (v: unknown) => string,\n caller = \"search\",\n): string {\n const bare = compileWhereBare(table, colSet, where, add, caller);\n return bare === \"\" ? \"\" : ` AND ${bare}`;\n}\n\n/** The `ON CONFLICT …` tail shared by `upsert` and `insertMany`.\n *\n * ONE writer, deliberately: two hand-written ON CONFLICT clauses is how the\n * single-row and the many-row spellings come to disagree about what a collision\n * does — and a disagreement there is silent, because both statements succeed.\n *\n * `DO UPDATE` sets every column that is NOT part of the conflict key; those are\n * what matched, so assigning them to themselves is the no-op Postgres needs when\n * there is nothing else to set. */\nfunction onConflictTail(\n cols: string[],\n conflict: readonly string[],\n action: \"ignore\" | \"update\",\n): string {\n const target = `ON CONFLICT (${conflict.map(quoteIdent).join(\", \")})`;\n if (action === \"ignore\") return `${target} DO NOTHING`;\n const conflictSet = new Set(conflict);\n const sets = cols\n .filter((c) => !conflictSet.has(c))\n .map((c) => `${quoteIdent(c)} = EXCLUDED.${quoteIdent(c)}`);\n return sets.length\n ? `${target} DO UPDATE SET ${sets.join(\", \")}`\n : `${target} DO UPDATE SET ${quoteIdent(conflict[0]!)} = EXCLUDED.${quoteIdent(conflict[0]!)}`;\n}\n\n/** vector extension'ının yaşadığı şema (C-10): canlı stack'te public, taze\n * stack'te extensions — operatör bununla nitelenir, search_path'e GÜVENİLMEZ\n * (M-1 ölçümü; veri düzlemi search_path=public kurar, handler.go:101). */\nlet cachedVectorSchema: string | null = null;\n\n/** pg_trgm'in kurulu olduğu şema — typo-fallback operatörü bununla nitelenir\n * (search_path'e GÜVENİLMEZ, M-1 ile aynı gerekçe). Bağlanma başına bir kez. */\nlet cachedTrgmSchema: string | null = null;\nasync function trgmSchemaOf(live: { unsafe: (sql: string, params?: unknown[]) => Promise<unknown> }): Promise<string> {\n if (cachedTrgmSchema !== null) return cachedTrgmSchema;\n const rows = (await live.unsafe(\n \"select n.nspname from pg_extension e join pg_namespace n on n.oid = e.extnamespace where e.extname = 'pg_trgm'\",\n )) as { nspname?: string }[];\n cachedTrgmSchema = rows?.[0]?.nspname ?? \"public\";\n return cachedTrgmSchema;\n}\n/** GUC + (soğukken) extension-şema çözümü TEK statement'ta (review I4). */\nasync function vectorSchemaWithGuc(runner: { unsafe(sql: string, params?: unknown[]): Promise<unknown> }): Promise<string> {\n if (cachedVectorSchema !== null) {\n // NFR-005 kapanışı, ÖLÇÜMLE (40K×384, %1 filtre, exact referans):\n // relaxed (vars. 20K tavan) → recall@20 0.62\n // relaxed + max_scan_tuples=200K → 0.64 (tavan tek başına YETMEZ:\n // iterative scan LIMIT dolunca durur, bulduğu ilk N \"en yakın N\" değil)\n // relaxed + 200K + ef_search=200 → 0.95 (asıl düğme aday genişliği)\n // ef_search=200 normal sorguya ms-mertebesi maliyet ekler; karşılığı\n // seçici filtrede doğru sonuç. strict_order ölçümde ek kazanç vermedi.\n await runner.unsafe(\n \"select set_config('hnsw.iterative_scan','relaxed_order',true), set_config('hnsw.max_scan_tuples','200000',true), set_config('hnsw.ef_search','200',true)\",\n );\n return cachedVectorSchema;\n }\n const rows = (await runner.unsafe(\n \"select set_config('hnsw.iterative_scan','relaxed_order',true), set_config('hnsw.max_scan_tuples','200000',true), set_config('hnsw.ef_search','200',true), \" +\n \"(select n.nspname from pg_extension e join pg_namespace n on n.oid = e.extnamespace where e.extname = 'vector') as nspname\",\n )) as { nspname?: string }[];\n const name = rows?.[0]?.nspname;\n if (typeof name !== \"string\" || name === \"\") {\n throw new Error(\"pgvector extension kurulu değil — vector araması çalışamaz (extensions beyanı deploy'dan geçti mi?)\");\n }\n cachedVectorSchema = name;\n return name;\n}\n\n/** Test edilebilirlik: setSchema gibi, cache'i sıfırlar. */\nexport function resetVectorSchemaCache(): void {\n cachedVectorSchema = null;\n}\n\n// ---------------------------------------------------------------------------\n// Sorgu-anı embed (T024, FR-025) — CLAIM-N1: POST /v1/embeddings.\n// ---------------------------------------------------------------------------\n\ntype SecretReader = (name: string) => Promise<string | null>;\nlet secretReader: SecretReader | null = null;\n/** Runtime boot'ta bağlanır (setSchema ile AYNI kanal deseni): vault'tan\n * secret okuma. Engine anahtarın yalnız ADINI bilir, değeri buradan akar. */\nexport function setSecretReader(fn: SecretReader | null): void {\n secretReader = fn;\n}\n\ntype EmbedFetch = (url: string, init?: RequestInit) => Promise<Response>;\nlet embedFetch: EmbedFetch = (url, init) => fetch(url, init);\n/** Test dikişi: sağlayıcı çağrısının fetch'i. Üretimde global fetch. */\nexport function setEmbedFetch(fn: EmbedFetch | null): void {\n embedFetch = fn ?? ((url, init) => fetch(url, init));\n}\n\n/** Sorgu metnini beyan edilen modelle vektörler (CLAIM-N1). Tek deneme, 10s\n * timeout — retry worker'ın işidir, sorgu yolunun değil. Hata apiKeyName'i\n * ADLANDIRIR; anahtar yoksa sağlayıcı hiç aranmaz. */\nasync function embedQuery(\n embed: NonNullable<SearchLeg[\"embed\"]>,\n text: string,\n): Promise<number[]> {\n if (secretReader === null) {\n throw new Error(`query embed: secret reader bağlanmamış — ${embed.apiKeyName} okunamıyor`);\n }\n const key = await secretReader(embed.apiKeyName);\n if (key === null || key === \"\") {\n throw new Error(`query embed: vault'ta ${embed.apiKeyName} yok (FR-021/FR-025)`);\n }\n const url = (embed.baseURL ?? \"https://api.openai.com/v1\").replace(/\\/$/, \"\") + \"/embeddings\";\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), 10_000);\n try {\n const res = await embedFetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", Authorization: `Bearer ${key}` },\n body: JSON.stringify({\n model: embed.model,\n input: [text],\n ...(embed.dimensions !== undefined ? { dimensions: embed.dimensions } : {}),\n }),\n signal: controller.signal,\n });\n if (!res.ok) {\n throw new Error(`query embed: sağlayıcı ${res.status} döndü (${embed.apiKeyName} ile) — anahtar/model doğru mu?`);\n }\n const data = (await res.json()) as { data?: { embedding?: number[] }[] };\n const vec = data.data?.[0]?.embedding;\n if (!Array.isArray(vec)) {\n throw new Error(\"query embed: sağlayıcı yanıtında data[0].embedding yok (CLAIM-N1 şekli)\");\n }\n return vec;\n } finally {\n clearTimeout(timer);\n }\n}\n\n/** The six string-keyed operations, plus an interactive `transaction`. */\n/**\n * SET atamalarını kuran TEK yer — `update` ve `updateMany` aynı dili konuşsun diye.\n *\n * Ayrı olduklarında `update(id, …)` düz `SET col = $n` kuruyordu: yani\n * `updated_at: now()` ve `hits: increment(1)` `updateMany`'de çalışıp `update`'te\n * çalışmıyordu — hem de EN ÇOK kullanılan yazma yolunda. Çağıranın göreceği bir\n * gerekçesi yoktu; \"aynı çağrı, tek düzlem\" (P1) tam olarak bunu yasaklıyor.\n */\nfunction buildSetAssignments(\n table: string,\n cols: readonly string[],\n set: Record<string, unknown>,\n add: (v: unknown) => string,\n caller: string,\n): string {\n return cols\n .map((c) => {\n // increment()/decrement() (FR-012, N-4): `SET col = col ± $n` TEK\n // statement'tır ve READ COMMITTED'te lost update üretmez — çakışan\n // ikinci UPDATE satırın GÜNCELLENMİŞ hâliyle devam eder. Oku-hesapla-yaz\n // yoluna düşmek o garantiyi yok ederdi, bu yüzden ifade burada,\n // sorgunun İÇİNDE derlenir; değeri okumak için ekstra tur YOK.\n const expr = columnExprOf(set[c]);\n // `now()` PLAN yolunda `SET col = now()` diye derleniyordu, doğrudan\n // yolda ise bind'e düşüp Proxy'yi sürücüye veriyordu. Aynı çağrı, iki\n // düzlem — P1'in kapattığı şeyin ta kendisi.\n if (expr !== null && expr.fn === \"now\") {\n return `${quoteIdent(c)} = now()`;\n }\n if (expr !== null) {\n const operator = expr.fn === \"inc\" ? \"+\" : \"-\";\n // MİKTAR da kolonun `toDb`'sinden geçer. Geçmeseydi, `.transform()`\n // bildiren bir kolonda `increment(5)` ham JS değeriyle bind edilir\n // ve toplama ya patlar ya da sessizce farklı bir sayıya çözülürdü —\n // dönüşümün yarısı bağlı, yarısı değil.\n const t = transformsOf(currentSchema, table).get(c);\n const amount = t?.toDb === undefined || expr.by === null || expr.by === undefined\n ? expr.by\n : t.toDb(expr.by);\n // Kolon tanımlayıcı, miktar BOUND — kiracının rakamları SQL metnine\n // hiç girmez (renderValue'daki tx yolunun aynı kuralı).\n return `${quoteIdent(c)} = ${quoteIdent(c)} ${operator} ${add(amount)}`;\n }\n return `${quoteIdent(c)} = ${add(asBindParams(table, [c], set, caller)[0])}`; })\n .join(\", \");\n}\n\n/**\n * `INSERT … VALUES` tuple'ı — ifade farkındalı, `buildSetAssignments`'ın ikizi.\n *\n * Beş kurucu (`insert`, `insertMany`, `put`, `claim`, `supersede`) düz\n * `$1..$n` üretiyordu, yani `now()` ekleme yolunda İFADE EDİLEMEZDİ. Verilen\n * gerekçe \"kolonun `defaultNow()`'ı daha iyi cevap\"tı ve GERÇEK bir şemada\n * ölçünce yanlış çıktı: introspect edilmiş bir şemada zaman kolonlarının çoğu\n * `timestamp()` — varsayılansız. O projede 12 yerde İSTEMCİ saati yazılıyordu,\n * ve aynı sütunu okuyan sorgular Postgres'in saatini kullanıyordu.\n *\n * `increment()`/`decrement()` burada ADIYLA reddediliyor: satır henüz yokken\n * \"kolonun şu anki değeri\" diye bir şey yok.\n */\nfunction buildValueTuple(\n table: string,\n cols: readonly string[],\n data: Record<string, unknown>,\n add: (v: unknown) => string,\n caller: string,\n): string {\n return cols\n .map((c) => {\n const expr = columnExprOf(data[c]);\n if (expr !== null && expr.fn === \"now\") return \"now()\";\n if (expr !== null) {\n throw new Error(\n `${caller}(${table}): \"${c}\" ${expr.fn === \"inc\" ? \"increment()\" : \"decrement()\"} aldı — ` +\n `satır HENÜZ YOK, yani \"kolonun şu anki değeri\" diye bir şey yok. Başlangıç ` +\n `değerini yazın; artırmak için satır oluştuktan sonra ` +\n `updateMany({ where, set: { ${c}: ${expr.fn === \"inc\" ? \"increment\" : \"decrement\"}(n) } }).`,\n );\n }\n return add(asBindParams(table, [c], data, caller)[0]);\n })\n .join(\", \");\n}\n\n/** Bir kolonun BİLDİRİLMİŞ Postgres tipi — `vectorColumnsOf` ile aynı okuma. */\nfunction computeColumnType(table: string, col: string): string | null {\n const def = tableDefOf(table);\n const c = def?.columns?.[col];\n if (c === undefined || c === null) return null;\n const d = (typeof c === \"object\" && \"_def\" in c ? (c as { _def: unknown })._def : c) as\n | { type?: unknown }\n | null;\n return d !== null && typeof d === \"object\" && typeof d.type === \"string\" ? d.type : null;\n}\n\nconst NUMERIC_PG_TYPES = new Set([\"integer\", \"bigint\", \"numeric\"]);\n\n/**\n * Toplama sonucunun SQL ifadesi.\n *\n * `::text` PARA GÜVENLİĞİDİR, süs değil. `sum()`/`avg()` HESAPLANMIŞ bir kolon\n * üretir; tablo kolonu olmadığı için şemanın `fromDb` dönüşümü ona uygulanmaz\n * ve sürücü onu JS `number`'ına çevirebilir. Bu tam olarak D-007'nin kapattığı\n * hata: 41.00821234567890123 canlıda 41.0082123456789 olarak dönüyordu.\n * `sum(numeric)` Postgres'te `numeric`, `sum(integer)` `bigint` — ikisi de bu\n * SDK'da `string`, ve öyle KALMALI.\n */\nfunction aggregateExpr(table: string, fn: \"sum\" | \"avg\" | \"min\" | \"max\", col: string, alias: string): string {\n const q = `t.${quoteIdent(col)}`;\n const t = columnTypeOf(table, col);\n // sum/avg her zaman metin: sonuç tipi numeric ya da bigint, ikisi de kesin\n // ve ikisi de JS number'da kayıplı.\n if (fn === \"sum\" || fn === \"avg\") return `${fn}(${q})::text AS ${quoteIdent(alias)}`;\n if (t === \"timestamp\") return `${timestampResult(`${fn}(${q})`)} AS ${quoteIdent(alias)}`;\n // min/max kolonun KENDİ tipini döndürür — yalnız sayısal olanlar metne\n // çevrilir; `timestamp`/`text` zaten string, `integer` JS number olarak\n // güvenli (tam sayı, 2^31).\n return t !== null && NUMERIC_PG_TYPES.has(t) && t !== \"integer\"\n ? `${fn}(${q})::text AS ${quoteIdent(alias)}`\n : `${fn}(${q}) AS ${quoteIdent(alias)}`;\n}\n\n/**\n * İLİŞKİLİ SATIRLARI GETİRME (`with`) — tek sorguda, LATERAL ile.\n *\n * `has` ilişki üzerinden SÜZÜYORDU ama GETİRMİYORDU: \"şu kullanıcıları ve\n * gönderilerini ver\" ya iki sorgu ya `$query` demekti — yani bu koşunun\n * kaldırmak için var olduğu N+1 sınıfının ta kendisi.\n *\n * PARA GÜVENLİĞİ BURADA KRİTİK, ve ölçülmüş bir rakip hatasından öğrenildi:\n * Drizzle'ın ilişkisel sorgusu satırları `json_build_array` ile taşıyor ve\n * kolonları metne DÖKMÜYOR; `numeric` JSON sayısına dönüşüp kesinliğini\n * kaybediyor — tip `string` derken runtime yuvarlanmış sayı veriyor\n * (ölçüldü: 100000000000000000000000000 → 100000000000000004764729344).\n * Burada her `numeric`/`bigint` kolonu `::text` ile dökülüyor, tıpkı Go\n * proxy'sinin düz satırlarda yaptığı gibi.\n */\nfunction jsonObjectFor(table: string, cols: readonly string[], alias: string, extra: string[] = []): string {\n const pairs = cols.map((c) => {\n const t = columnTypeOf(table, c);\n // `integer` JS number'da tam sayı olarak güvenli; `numeric`/`bigint` değil.\n const expr =\n t !== null && (t === \"numeric\" || t === \"bigint\")\n ? `${alias}.${quoteIdent(c)}::text`\n : t === \"timestamp\" ? timestampResult(`${alias}.${quoteIdent(c)}`) : `${alias}.${quoteIdent(c)}`;\n return `${quoteLiteral(c)}, ${expr}`;\n });\n return `json_build_object(${[...pairs, ...extra].join(\", \")})`;\n}\n\n/** A foreign key can reference any declared unique column, including on a\n * table whose primary key is composite. Read its actual referenced column. */\nfunction relationColumns(table: string, relation: Relation): [string | null, string | null] {\n const child = relation.kind === \"many\" ? relation.to : table;\n const value = tableDefOf(child)?.columns?.[relation.via];\n const column = (value && typeof value === \"object\" && \"_def\" in value ? value._def : value) as\n { references?: { column?: string } } | undefined;\n const target = column?.references?.column ?? primaryKeyOf(relation.kind === \"many\" ? table : relation.to);\n return relation.kind === \"many\" ? [target, relation.via] : [relation.via, target];\n}\n\n/** `with` dalları — her biri bir LATERAL ya da skaler alt sorgu. */\nfunction withClauses(\n table: string,\n spec: Record<string, unknown>,\n add: (v: unknown) => string,\n caller: string,\n parentAlias = \"t\", depth = 0, counter = { value: 0 },\n): { select: string[]; joins: string[]; jsonPairs: string[] } {\n if (depth >= 3 && Object.values(spec).some(Boolean)) throw new Error(`${caller}(${table}): with supports at most three relation levels`);\n const rels = currentRelations.get(table) ?? [];\n const select: string[] = [];\n const joins: string[] = [];\n const jsonPairs: string[] = [];\n for (const [name, opt] of Object.entries(spec)) {\n if (opt === false || opt === undefined) continue;\n const rel = rels.find((r) => r.name === name);\n if (rel === undefined) {\n const known = rels.map((r) => r.name).sort();\n throw new Error(\n `${caller}(${table}): with.${name} diye bir ilişki yok` +\n (known.length > 0\n ? ` (bilinenler: ${known.join(\", \")})`\n : `. Bu tablo hiç yabancı anahtar bildirmiyor ve ilişkiler onlardan TÜRETİLİR`) +\n `. İlişkiler references(() => <tablo>.<kolon>) ile bildirilir.`,\n );\n }\n const [ourCol, theirCol] = relationColumns(table, rel);\n if (ourCol === null || theirCol === null) {\n throw new Error(\n `${caller}(${table}): with.${name} birincil anahtar bilmeden kurulamaz — ` +\n `ilişkinin bir ucu tablonun PK'sı ve bu tablo tek kolonlu bir PK bildirmiyor.`,\n );\n }\n const o = typeof opt === \"object\" && opt !== null ? (opt as Record<string, unknown>) : {};\n const i = ++counter.value;\n const childAlias = `w${i}`;\n const childKnown = schemaColumns(rel.to);\n if (o['select'] !== undefined && (!Array.isArray(o['select']) || o['select'].length === 0)) {\n throw new Error(`${caller}(${table}): with.${name}.select must be a non-empty array of columns`);\n }\n const childCols =\n Array.isArray(o[\"select\"]) && o[\"select\"].length > 0\n ? (o[\"select\"] as string[])\n : childKnown !== null\n ? [...childKnown]\n : [];\n if (childCols.length === 0) {\n throw new Error(\n `${caller}(${table}): with.${name} için \"${rel.to}\" tablosunun kolonları bilinmiyor — ` +\n `select ile hangi kolonları istediğinizi yazın.`,\n );\n }\n for (const c of childCols) {\n if (childKnown !== null && !childKnown.has(c)) {\n throw new Error(`${caller}(${table}): with.${name}.select kolonu \"${c}\" \"${rel.to}\" tablosunda yok`);\n }\n }\n const nestedSpec = o[\"with\"];\n if (nestedSpec !== undefined && (nestedSpec === null || typeof nestedSpec !== \"object\" || Array.isArray(nestedSpec))) {\n throw new Error(`${caller}(${table}): with.${name}.with must be a relation object`);\n }\n const nested = nestedSpec === undefined ? { joins: [], jsonPairs: [] } :\n withClauses(rel.to, nestedSpec as Record<string, unknown>, add, caller, childAlias, depth + 1, counter);\n const nestedJoins = nested.joins.length ? ` ${nested.joins.join(\" \")}` : \"\";\n const obj = jsonObjectFor(rel.to, childCols, childAlias, [...nested.jsonPairs, ...canJsonPairs(rel.to, childAlias)]);\n const innerWhere =\n o[\"where\"] !== undefined && o[\"where\"] !== null\n ? compileWhereBare(rel.to, childKnown, o[\"where\"] as Record<string, unknown>, add, caller, childAlias, i)\n : \"\";\n const link = `${childAlias}.${quoteIdent(theirCol)} = ${parentAlias}.${quoteIdent(ourCol)}`;\n const cond = innerWhere === \"\" ? link : `${link} AND ${innerWhere}`;\n const requestedLimit = o[\"limit\"] as number | undefined;\n // Validate the supplied value even for a to-one relation, then clamp its\n // cardinality. A second LIMIT after the requested one is invalid SQL.\n limitClause(requestedLimit);\n const relationLimit = rel.kind === \"many\" ? requestedLimit : Math.min(1, requestedLimit ?? 1);\n const inner = orderClauseFor(rel.to, childKnown, o[\"orderBy\"], childAlias) + limitClause(relationLimit);\n const outAlias = `wj${i}`;\n if (rel.kind === \"many\") {\n // Boş küme `[]` — `null` DEĞİL. Çağıran `rows.posts.map(...)` yazabilsin\n // diye; `null` her erişimde bir guard isterdi.\n joins.push(\n `LEFT JOIN LATERAL (SELECT coalesce(json_agg(x.o), '[]'::json) AS d FROM ` +\n `(SELECT ${obj} AS o FROM ${quoteTable(rel.to)} ${childAlias}${nestedJoins} WHERE ${cond}${inner}) x) ` +\n `${quoteIdent(outAlias)} ON true`,\n );\n } else {\n // `one`: tek satır ya da `null` — dizi değil, çünkü ilişki tekil.\n joins.push(\n `LEFT JOIN LATERAL (SELECT ${obj} AS d FROM ${quoteTable(rel.to)} ${childAlias}${nestedJoins} ` +\n `WHERE ${cond}${inner}) ${quoteIdent(outAlias)} ON true`,\n );\n }\n select.push(`${quoteIdent(outAlias)}.\"d\" AS ${quoteIdent(name)}`);\n jsonPairs.push(`${quoteLiteral(name)}, ${quoteIdent(outAlias)}.\"d\"`);\n }\n return { select, joins, jsonPairs };\n}\n\nfunction compileFindMany(table: string, query: Row = {}, opts: FindManyOptions = {}): { sql: string; params: unknown[] } {\n const params: unknown[] = [];\n const add = (v: unknown): string => {\n params.push(v);\n return `$${params.length}`;\n };\n // The SAME compiler `search` uses. Two builders for one filter language is\n // how the two spellings drift; the operator set (gt/gte/lt/lte/neq/in) was\n // already written and already tested, it was just never reachable from here.\n const known = schemaColumns(table);\n const whereSql = compileWhere(table, known, query, add, \"findMany\");\n const order = orderClause(table, known, opts.orderBy);\n const limit = limitClause(opts.limit);\n const offset = offsetClause(opts.offset, opts.limit);\n const cols = selectClause(table, known, opts.select);\n // `with` — ilişkili satırlar, TEK sorguda. Boşsa üretilen SQL bayt-aynı\n // kalıyor: var olan her çağrının planı değişmesin.\n const w =\n opts.with !== undefined && Object.keys(opts.with).length > 0\n ? withClauses(table, opts.with, add, \"findMany\")\n : { select: [], joins: [] };\n const selectList = w.select.length > 0 ? `${cols === \"*\" ? \"t.*\" : cols}, ${w.select.join(\", \")}` : cols;\n const joinSql = w.joins.length > 0 ? ` ${w.joins.join(\" \")}` : \"\";\n const sql =\n `SELECT ${selectList} FROM ${quoteTable(table)} t${joinSql} WHERE true${whereSql}${order}${limit}${offset}`;\n return { sql, params };\n}\n\ninterface OpsContext { readonly cursorScope?: string; readonly commands?: boolean; readonly trace?: DatabaseTrace }\nconst uniqueKeysCache: SchemaMetadataCache<string[][]> = new WeakMap();\nconst pageSchemaCache: SchemaMetadataCache<{ columns: Record<string, PageColumn>; primaryKey: string[]; stamp: string }> = new WeakMap();\n\nfunction pageSchema(table: string) {\n return memoTable(pageSchemaCache, currentSchema, table, () => {\n const def = tableDefOf(table) as { columns?: Record<string, unknown>; primaryKey?: string[] } | null;\n if (!def?.columns) throw new Error(`page(${table}) requires an installed table declaration`);\n const columns: Record<string, PageColumn> = Object.create(null);\n const inlineKeys: string[] = [];\n for (const [name, column] of Object.entries(def.columns)) {\n const c = column as { _def?: PageColumn & { primaryKey?: boolean } } & PageColumn & { primaryKey?: boolean };\n const d = c._def ?? c;\n columns[name] = { type: d.type, nullable: d.nullable };\n if (d.primaryKey) inlineKeys.push(name);\n }\n const primaryKey = def.primaryKey ?? inlineKeys;\n for (const name of primaryKey) if (columns[name]) columns[name]!.nullable = false;\n return { columns, primaryKey, stamp: fingerprint({ columns, primaryKey }) };\n });\n}\n\nexport function createOps(tx: TxLike | (() => TxLike | Promise<TxLike>), context: OpsContext = {}) {\n const at = () => {\n const target = typeof tx === \"function\" ? tx() : tx;\n return target instanceof Promise ? target.then(resolveTx) : resolveTx(target);\n };\n\n const ops = {\n diagnostics() { return context.trace?.snapshot ?? null; },\n // Generic dönüş, çağıranın İDDİASIDIR (FR-021). Motor her zaman satır objeleri\n // üretir; `T` onlara bir ad vermekten ibarettir ve verilmezse `unknown` kalır —\n // yani \"bilmiyorum\", ki ham SQL için doğru cevap odur.\n async query<T = unknown>(sql: string, params: unknown[] = []): Promise<T[]> {\n // Arrays become Postgres array literals; everything else is bound as-is.\n // See encodePgArray for what the driver does without this.\n const bound = params.map((p) => (Array.isArray(p) ? encodePgArray(p) : p));\n return asWireRows((await (await at()).unsafe(sql, bound)) as Row[]) as T[];\n },\n\n async insert(table: string, data: Row): Promise<Row> {\n const cols = Object.keys(data);\n if (cols.length === 0) throw new Error(`insert into ${table}: no columns given`);\n const params: unknown[] = [];\n const add = (v: unknown): string => `$${params.push(v)}`;\n const tuple = buildValueTuple(table, cols, data, add, \"insert\");\n const sql =\n `INSERT INTO ${quoteTable(table)} (${cols.map(quoteIdent).join(\", \")}) ` +\n `VALUES (${tuple}) RETURNING ${rowProjection(table)}`;\n const rows = (await (await at()).unsafe(sql, params)) as Row[];\n const inserted = rows[0];\n if (!inserted) {\n // RETURNING * with no row back means the write was filtered away — an\n // RLS WITH CHECK that rejected it, most often. Silence here would hand\n // the author `undefined` and a 500 three lines later.\n throw new Error(\n `insert into ${table} returned no row — the write was rejected (an RLS policy, most likely).`,\n );\n }\n return asTableRow(table, inserted);\n },\n\n /**\n * Çok satırı TEK statement'la ekle.\n *\n * Motor bunu zaten yapıyordu ve yalnız PLAN yolundan erişilebiliyordu\n * (`tx.public.x.insertMany`). Dışarıda tek kapı `insert(row)` olduğu için\n * \"şu 200 satırı yaz\" ya 200 gidiş-dönüş ya da ham SQL oluyordu — ölçüldü:\n * bir müşteri projesinde bir seed rutini satırları tek tek siliyor\n * (`deleteMany` VARKEN) ve tek tek ekliyor.\n *\n * SATIRLARIN ANAHTAR KÜMESİ AYNI OLMAK ZORUNDA. Kolon listesi tek bir\n * statement'ta paylaşıldığı için ilk satırdan türer; farklı anahtar taşıyan\n * bir satırın fazla kolonu SESSİZCE YAZILMAZDI. Eksik kolon için `null`\n * yazın ya da varsayılanı istiyorsanız o satırları ayrı çağrıda ekleyin.\n */\n insertMany: (async function(\n table: string,\n rows: readonly Row[],\n opts?: InsertManyOptions,\n ): Promise<Row[] | number> {\n validateInsertManyOptions(opts);\n if (rows.length === 0) return opts?.returning === false ? 0 : [];\n const first = rows[0]!;\n const cols = Object.keys(first);\n if (cols.length === 0) throw new Error(`insertMany into ${table}: no columns given`);\n for (let i = 1; i < rows.length; i++) {\n const keys = Object.keys(rows[i]!);\n const missing = cols.filter((c) => !(c in rows[i]!));\n const extra = keys.filter((k) => !cols.includes(k));\n if (missing.length > 0 || extra.length > 0) {\n throw new Error(\n `insertMany(${table}): ${i}. satırın kolonları ilk satırla aynı değil` +\n (missing.length > 0 ? ` (eksik: ${missing.join(\", \")})` : \"\") +\n (extra.length > 0 ? ` (fazla: ${extra.join(\", \")})` : \"\") +\n `. Tek statement kolon listesini PAYLAŞIR, yani fazla kolon sessizce ` +\n `yazılmaz ve eksik kolon yanlış sütuna kayar. Eksikler için null yazın, ` +\n `ya da farklı şekilli satırları ayrı çağrılarda ekleyin.`,\n );\n }\n }\n const params: unknown[] = [];\n const add = (v: unknown): string => `$${params.push(v)}`;\n const tuples = rows.map((r) => `(${buildValueTuple(table, cols, r, add, \"insertMany\")})`);\n // ÇAKIŞMA KURALI — plan yolunun `insertMany`'si bunu 11.0.0'dan beri\n // alıyordu ve düz yüzeye eklerken atlamıştım: \"şu 200 satırı yaz, zaten\n // olanları geç\" toplu içe aktarmanın en sıradan hâli ve onsuz tek çare\n // yine ham SQL.\n //\n // DO NOTHING + RETURNING: Postgres yalnız YAZDIĞI satırları döndürür,\n // yani çakışan satır sonuçta YOKTUR. Sözleşme bu, pürüz değil.\n const tail =\n opts?.onConflict !== undefined && opts.onConflict.length > 0\n // VARSAYILAN `\"ignore\"` — plan yolunun 11.0.0'dan beri kullandığı\n // varsayılanın AYNISI. Bir süre `\"update\"` yazmıştım: aynı seçenek\n // adı, iki düzlemde ZIT davranış, ve fark ancak veri ezildikten sonra\n // görülürdü.\n ? ` ${onConflictTail(cols, opts.onConflict, opts.action ?? \"ignore\")}`\n : \"\";\n const sql =\n `INSERT INTO ${quoteTable(table)} (${cols.map(quoteIdent).join(\", \")}) ` +\n `VALUES ${tuples.join(\", \")}${tail}${opts?.returning === false ? \"\" : ` RETURNING ${rowProjection(table)}`}`;\n const out = (await (await at()).unsafe(sql, params)) as Row[] & { count?: number };\n if (opts?.returning === false) {\n if (!Number.isSafeInteger(out.count) || out.count! < 0) throw new Error(\"insertMany returning:false requires a driver with an affected row count\");\n return out.count!;\n }\n return out.map((r) => asTableRow(table, r));\n }) as DBOps[\"insertMany\"],\n\n /**\n * Bir ADI kilitle — satırı değil (FR-054).\n *\n * \"Aynı anda tek bir fatura kapanışı koşsun\" gibi, kilitlenecek satırı\n * OLMAYAN işler için. Anahtar bir metin; Postgres 64-bit tamsayı istediği\n * için `hashtextextended` ile hash'leniyor ve metin SQL'e hiç GİRMİYOR.\n *\n * YALNIZ transaction kapsamlı aile (`pg_advisory_xact_lock`). Oturum\n * kapsamlı sürüm bırakıldığı yerde KALIR: bağlantı havuza döner, kilit\n * üstünde kalır ve bir sonraki isteği — hiç bitmeyecek şekilde — bekletir.\n * Transaction kapsamlısı commit/rollback'te Postgres tarafından bırakılır,\n * yani unutulması imkânsız.\n */\n async advisoryXactLock(key: string): Promise<void> {\n await (await at()).unsafe(\"select pg_advisory_xact_lock(hashtextextended($1, 0))\", [key]);\n },\n\n /**\n * Bu satırları KİLİTLE, ve sırayı KATMAN koysun (FR-035).\n *\n * D-017: katman sıralamayı değil, **sıralamayı mümkün kılan primitifi**\n * verir. Uygulama dokunacağı kümeyi önden bildirir; sırayı burası koyar.\n * Çağıranın verdiği sıraya güvenmek, iki çağıranın aynı iki satıra ters\n * sırayla girmesi demektir — ve deadlock'un bedeli ucuz değil:\n * `deadlock_timeout` varsayılanı **1 saniye**, yani kaybeden işlem bir\n * saniye bekledikten sonra hata alır.\n *\n * `FOR NO KEY UPDATE`, `updateMany`'nin CTE'siyle AYNI kilit modu: iki\n * yazma yolunun tek bir sırası ve tek bir modu olmak zorunda, yoksa biri\n * diğerini bekletir.\n */\n async lockRows(table: string, ids: readonly string[]): Promise<void> {\n // Sıralama VE tekilleştirme burada: aynı id'yi iki kez kilitlemek bir\n // no-op ama listeyi uzatır, ve sıralanmamış bir liste bu fonksiyonun tek\n // işini yapmamış olurdu.\n const unique = [...new Set(ids)].sort();\n if (unique.length === 0) {\n // Boş liste sessizce \"hiçbir şeyi kilitleme\" OLMAMALI mı? Olmalı — ama\n // sessizce değil: burada erken dönüyoruz çünkü kilitlenecek satır\n // gerçekten yok. Çağıranın kilit aldığını sanması ancak boş olmayan bir\n // liste verip satırların bulunamamasıyla olur; onu Postgres söyler.\n return;\n }\n const pk = primaryKeyOf(table);\n if (pk === null) {\n throw new Error(\n `lockRows(${table}): tek-kolon primary key bulunamadı — kilit sırası bir anahtar ister (FR-035).`,\n );\n }\n const params: unknown[] = [];\n const add = (v: unknown): string => {\n params.push(v);\n return `$${params.length}`;\n };\n // Placeholder genişletmesi, `= ANY($1)` DEĞİL: dizi bind'i sürücüde\n // Postgres array literal'ine çevrilmiyor ve canlıda\n // `malformed array literal` 500'ü veriyordu (verify 19-3b, 2026-08-28).\n const list = unique.map((id) => add(id)).join(\", \");\n await (await at()).unsafe(\n `SELECT t.${quoteIdent(pk)} FROM ${quoteTable(table)} t ` +\n `WHERE t.${quoteIdent(pk)} IN (${list}) ORDER BY t.${quoteIdent(pk)} FOR NO KEY UPDATE`,\n params,\n );\n },\n\n /**\n * Bir FİLTRENİN eşleştiği satırları kilitle — sırayı yine KATMAN koyar\n * (FR-037).\n *\n * `lockRows` kilitlenecek kümeyi çağıranın SAYMASINI istiyor. \"Bu hesabın\n * bekleyen bütün hareketlerini kilitle\" bunu yapamaz: id listesi ancak bir\n * sorguyla çıkar, ve SORGU İLE KİLİT ARASINDAKİ BOŞLUK tam olarak kilidin\n * kapatması gereken yarıştır — araya giren bir INSERT o listede yoktur ve\n * kilitlenmez. Burada küme TEK statement'ta hem seçiliyor hem kilitleniyor.\n *\n * `ORDER BY <pk>`: `updateMany`'nin kilit CTE'siyle AYNI sıra (FR-037b).\n * Sırayı iki yolun da katmandan alması, aynı satır kümesine giren iki\n * transaction'ın ters sırada kilitlemesini imkânsız kılıyor — deadlock'un\n * bedeli ucuz değil, `deadlock_timeout` varsayılanı 1 SANİYE.\n *\n * KİLİT MODU EŞİTLENMEZ (FR-037b): `updateMany` işi UPDATE olduğu için\n * `FOR NO KEY UPDATE` kullanıyor, ama burada mod ÇAĞIRANIN seçimi. Herkesi\n * o moda zorlamak, yalnız okuma kilidi isteyeni ihtiyacından fazlasını\n * almaya zorlardı. Deadlock'u önleyen SIRADIR, mod değil.\n */\n async lockRowsWhere(\n table: string,\n where: Row,\n opts?: { mode?: \"update\" | \"share\" | \"noKeyUpdate\" },\n ): Promise<void> {\n // Mod SINIFLANDIRILAMAZSA REDDEDİLİR. Tanınmayan bir modu sessizce\n // varsayılana düşürmek, çağıranın istediğinden ZAYIF bir kilit almak\n // demekti — ve kilit yolunda sessiz zayıflama fail-open'dır.\n const mode = opts?.mode ?? \"update\";\n const clause = LOCK_MODES[mode];\n if (clause === undefined) {\n throw new Error(\n `lockRowsWhere(${table}): bilinmeyen mode \"${String(mode)}\" — ` +\n `\"update\" (FOR UPDATE), \"share\" (FOR SHARE) ya da \"noKeyUpdate\" (FOR NO KEY UPDATE).`,\n );\n }\n const pk = primaryKeyOf(table);\n if (pk === null) {\n throw new Error(\n `lockRowsWhere(${table}): tek-kolon primary key bulunamadı — kilit sırası bir anahtar ister (FR-037).`,\n );\n }\n const params: unknown[] = [];\n const add = (v: unknown): string => {\n params.push(v);\n return `$${params.length}`;\n };\n // Filtre `updateMany`/`findMany` ile AYNI derleyiciden geçiyor: ikinci\n // bir filtre lehçesi olmaz, ve placeholder genişletmesi (`= ANY($1)`\n // DEĞİL) oradan geliyor — dizi bind'i canlıda `malformed array literal`\n // veriyordu (verify 19-3b, 2026-08-28).\n const whereSql = compileWhere(table, schemaColumns(table), where, add, \"lockRowsWhere\");\n // Boş filtre = BÜTÜN TABLO. Kilit almak bir yazma değil ama bütün tabloyu\n // kilitlemek de kazayla ulaşılacak bir yer değil: her yazar bu\n // transaction bitene kadar bekler.\n assertHasPredicate(whereSql, \"lockRowsWhere\", table);\n await (await at()).unsafe(\n `SELECT t.${quoteIdent(pk)} FROM ${quoteTable(table)} t ` +\n `WHERE true${whereSql} ORDER BY t.${quoteIdent(pk)} ${clause}`,\n params,\n );\n },\n\n /**\n * Bir idempotency anahtarını SAHİPLEN (FR-033).\n *\n * `{ inserted: true, row }` → bu çağrı yazdı.\n * `{ inserted: false, row }` → başkası önce yazdı; dönen satır ONUN satırı.\n *\n * ÖLÇÜLDÜ (pg16, spec Research Appendix) — üç dalın üçü de farklı davranıyor:\n *\n * plain INSERT ikinci oturum 2121 ms BLOKLANIR, sonra 23505 alır;\n * birincinin satırı korunur ← istenen\n * ON CONFLICT DO UPDATE ikincinin verisi birincininkini EZER\n * ON CONFLICT DO NOTHING `INSERT 0 0` — sessiz; çağıran ne olduğunu bilemez\n *\n * Bu yüzden `ON CONFLICT` KULLANILMIYOR. Ödeme yolunda \"ikinci çağrı\n * birincinin sonucunu görsün\" idempotency'nin tanımıdır; ezmek ya da\n * susmak ikisi de yanlış cevap.\n *\n * INSERT bir SAVEPOINT içinde koşuyor: başarısız bir INSERT transaction'ı\n * ABORT eder (25P02) ve savepoint olmadan yakalama işe yaramaz — hata\n * yakalanır ama sonraki SELECT de \"current transaction is aborted\" alır.\n */\n async claim(table: string, unique: Row, extra: Row = {}): Promise<{ inserted: boolean; row: Row }> {\n const keyCols = Object.keys(unique);\n if (keyCols.length === 0) {\n throw new Error(\n `claim(${table}): benzersiz alan verilmedi. claim, bir anahtarı sahiplenmektir; ` +\n `anahtar yoksa sahiplenecek bir şey de yok — insert(${table}, …) kullanın.`,\n );\n }\n assertUsableWriteValues(\"claim\", table, keyCols, unique);\n const data = { ...unique, ...extra };\n const cols = Object.keys(data);\n const live = await at();\n try {\n return await live.savepoint(async (sp) => {\n const params: unknown[] = [];\n const add = (v: unknown): string => `$${params.push(v)}`;\n const tuple = buildValueTuple(table, cols, data, add, \"claim\");\n const rows = (await sp.unsafe(\n `INSERT INTO ${quoteTable(table)} (${cols.map(quoteIdent).join(\", \")}) ` +\n `VALUES (${tuple}) RETURNING ${rowProjection(table)}`,\n params,\n )) as Row[];\n if (!rows[0]) {\n throw new Error(\n `claim(${table}): INSERT satır döndürmedi — yazma reddedildi (büyük olasılıkla bir RLS policy'si).`,\n );\n }\n return { inserted: true, row: asTableRow(table, rows[0]) };\n });\n } catch (e) {\n if (!isUniqueViolation(e)) throw e;\n // YALNIZ benzersiz alanlarla arıyoruz. Tüm alanlarla aramak, ikinci\n // çağrı farklı bir yük gönderdiğinde satırı BULAMAZDI ve hata\n // \"duplicate\" yerine \"kayıp satır\" olarak görünürdü.\n const params: unknown[] = [];\n const add = (v: unknown): string => {\n params.push(v);\n return `$${params.length}`;\n };\n const where = keyCols.map((c) => `t.${quoteIdent(c)} = ${add(unique[c])}`).join(\" AND \");\n const found = (await (await at()).unsafe(\n `SELECT ${rowProjection(table, \"t\", \"*\")} FROM ${quoteTable(table)} t WHERE ${where} LIMIT 1`,\n params,\n )) as Row[];\n if (!found[0]) {\n // Anahtar çakıştı ama satır görünmüyor. İKİ sebebi olabilir ve\n // ikisini de SÖYLÜYORUZ: (a) ihlal edilen kısıt bu çağrının `unique`\n // alanları DEĞİL — tabloda ikinci bir UNIQUE var ve onu çiğnedik;\n // (b) satır var ama bir RLS policy'si bu çağırandan gizliyor.\n // Tek sebebi ilan etmek, ikincisini yaşayan çağıranı yanlış yere\n // baktırırdı (inceleme I-5).\n const named = constraintOf(e);\n throw new Error(\n `claim(${table}): benzersizlik ihlali${named ? ` (${named})` : \"\"} yakalandı ama ` +\n `${keyCols.join(\", \")} ile satır bulunamadı. Ya ihlal BAŞKA bir unique kısıttan ` +\n `geliyor — o zaman claim() bu çağrı için yanlış araç — ya da satır var ve bir RLS ` +\n `policy'si onu bu çağırandan gizliyor.`,\n );\n }\n return { inserted: false, row: asTableRow(table, found[0]) };\n }\n },\n\n /**\n * INSERT the row, or UPDATE it when it collides on `onConflict`.\n *\n * WHY IT IS AN OPERATION rather than a recipe. \"Try the insert, catch the\n * unique violation, update instead\" does not work here: a request runs in ONE\n * Postgres transaction, so the failed insert aborts it and every later\n * statement answers `current transaction is aborted`. A tenant measured that\n * as 7 of 8 concurrent requests returning 500, gave up on upsert, and had a\n * trigger create the row instead — a workaround that needs a new trigger for\n * every table with a unique row.\n *\n * The conflict columns are excluded from the SET list: they are what MATCHED,\n * so writing them back is at best a no-op and at worst a surprise.\n */\n async put(table: string, data: Row, opts: { onConflict: readonly string[] }): Promise<Row> {\n assertNotAppendOnly(\"put\", table);\n const conflict = opts.onConflict;\n if (conflict.length === 0) {\n // A silent fall-through to a plain INSERT would be an upsert that is not\n // one: it would work until two callers raced, which is the only time it\n // matters.\n throw new Error(`upsert into ${table}: onConflict en az bir kolon adı ister`);\n }\n const cols = Object.keys(data);\n if (cols.length === 0) throw new Error(`upsert into ${table}: no columns given`);\n // D-020 eki (FR-020): validity'li tabloda \"aynı anahtarın yeni değeri\"\n // EZME değil SUPERSEDE'dir — geçmiş silinmez. Düz DO UPDATE burada iki\n // kez yanlıştır: geçerli satırı ezer VE partial arbiter'la (UNIQUE ...\n // WHERE valid_to IS NULL) düz ON CONFLICT eşleşmez (42P10). Desen:\n // partial-arbiter'lı DO NOTHING insert (abort'suz), çakışmada\n // kapat→ekle→bağla (worker writeMemoryFacts ile aynı sıra).\n if (searchConfigFor(table)?.validity) {\n const bindData: unknown[] = [];\n const addPut = (v: unknown): string => `$${bindData.push(v)}`;\n const ph = buildValueTuple(table, cols, data, addPut, \"put\");\n const insertSql =\n `INSERT INTO ${quoteTable(table)} (${cols.map(quoteIdent).join(\", \")}) VALUES (${ph}) ` +\n `ON CONFLICT (${conflict.map(quoteIdent).join(\", \")}) WHERE \"valid_to\" IS NULL DO NOTHING RETURNING ${rowProjection(table)}`;\n const live = await at();\n const first = (await live.unsafe(insertSql, bindData)) as Row[];\n if (first[0]) return asTableRow(table, first[0]);\n const condSql = conflict.map((c, i) => `${quoteIdent(c)} = $${i + 1}`).join(\" AND \");\n const condBind = conflict.map((c) => (data as Record<string, unknown>)[c]);\n const cur = (await live.unsafe(\n `SELECT ${rowProjection(table)} FROM ${quoteTable(table)} WHERE ${condSql} AND \"valid_to\" IS NULL`, condBind)) as Row[];\n const old = cur[0] as Record<string, unknown> | undefined;\n if (old === undefined) {\n throw new Error(`upsert into ${table}: eşzamanlı supersede yarışı — geçerli satır bulunamadı, isteği yineleyin (D-020)`);\n }\n const pk = Object.keys(old).includes(\"id\") ? \"id\" : Object.keys(old)[0]!;\n await live.unsafe(\n `UPDATE ${quoteTable(table)} SET \"valid_to\" = now() WHERE ${quoteIdent(pk)} = $1 AND \"valid_to\" IS NULL`,\n [old[pk]]);\n const second = (await live.unsafe(insertSql, bindData)) as Row[];\n if (!second[0]) {\n throw new Error(`upsert into ${table}: eşzamanlı supersede yarışı — yeni satır açılamadı, isteği yineleyin (D-020)`);\n }\n const fresh = second[0] as Record<string, unknown>;\n await live.unsafe(\n `UPDATE ${quoteTable(table)} SET \"superseded_by\" = $2 WHERE ${quoteIdent(pk)} = $1`,\n [old[pk], fresh[pk]]);\n return asTableRow(table, second[0]);\n }\n const params: unknown[] = [];\n const add = (v: unknown): string => `$${params.push(v)}`;\n const placeholders = buildValueTuple(table, cols, data, add, \"put\");\n const conflictSet = new Set(conflict);\n const assignments = cols\n .filter((c) => !conflictSet.has(c))\n .map((c) => `${quoteIdent(c)} = EXCLUDED.${quoteIdent(c)}`);\n // Nothing to update means the row's identity IS the row: keep it and hand\n // the existing one back rather than answering zero rows.\n const action = assignments.length\n ? `DO UPDATE SET ${assignments.join(\", \")}`\n : `DO UPDATE SET ${quoteIdent(conflict[0]!)} = EXCLUDED.${quoteIdent(conflict[0]!)}`;\n const sql =\n `INSERT INTO ${quoteTable(table)} (${cols.map(quoteIdent).join(\", \")}) ` +\n `VALUES (${placeholders}) ` +\n `ON CONFLICT (${conflict.map(quoteIdent).join(\", \")}) ${action} RETURNING ${rowProjection(table)}`;\n const rows = (await (await at()).unsafe(sql, params)) as Row[];\n const row = rows[0];\n if (!row) {\n throw new Error(\n `upsert into ${table} returned no row — the write was rejected (an RLS policy, most likely).`,\n );\n }\n return asTableRow(table, row);\n },\n\n async update(table: string, id: string, data: Row): Promise<Row | null> {\n assertNotAppendOnly(\"update\", table);\n const cols = Object.keys(data);\n if (cols.length === 0) return ops.findById(table, id);\n // AYNI SET kurucusu `updateMany` ile. Ayrı olduğunda bu yol düz\n // `SET col = $n` kuruyordu, yani `now()` ve `increment()` en çok\n // kullanılan yazmada çalışmıyor, çoklu yazmada çalışıyordu.\n const params: unknown[] = [];\n const add = (v: unknown): string => {\n params.push(v);\n return `$${params.length}`;\n };\n const assignments = buildSetAssignments(table, cols, data, add, \"update\");\n const sql = `UPDATE ${quoteTable(table)} SET ${assignments} WHERE id = ${add(id)} RETURNING ${rowProjection(table)}`;\n const rows = (await (await at()).unsafe(sql, params)) as Row[];\n return rows[0] ? asTableRow(table, rows[0]) : null;\n },\n\n async delete(table: string, id: string): Promise<void> {\n assertNotAppendOnly(\"delete\", table);\n await (await at()).unsafe(`DELETE FROM ${quoteTable(table)} WHERE id = $1`, [id]);\n },\n\n /**\n * Update every row the filter matches, in ONE statement.\n *\n * The capability was already here and only reachable from inside a\n * transaction plan (`tx.tables.x.updateWhere`, since 11.0.0). Outside it the\n * only door was `update(id, …)`, so \"mark every unapproved row in this\n * household\" was an N+1 loop or hand-written SQL — and hand-written SQL is\n * where the typed surface and RLS both stop helping.\n *\n * The filter language is `findMany`'s, compiled by the same `compileWhere`:\n * one filter language, or the two spellings drift.\n *\n * AN EMPTY FILTER IS REFUSED. `UPDATE … WHERE true` is a whole-table write,\n * and the shape that produces it by accident — a filter object built from\n * request input that happened to come back empty — is exactly the shape that\n * should not silently succeed. Callers who mean every row say so with a\n * predicate that is true for every row.\n */\n async updateMany(\n table: string,\n where: Row,\n set: Row,\n opts?: { returning?: boolean },\n ): Promise<Row[] | number> {\n assertNotAppendOnly(\"updateMany\", table);\n const cols = Object.keys(set);\n if (cols.length === 0) {\n // A silent `[]` here is indistinguishable from \"nothing matched\", and a\n // caller that turns an empty result into a 404 answers the wrong thing.\n throw new Error(\n `updateMany(${table}): nothing to set. An update with no columns is ` +\n `not a no-op worth pretending happened — pass the columns to write.`,\n );\n }\n // SET kolonları da WHERE kolonları gibi şemadan doğrulanır. Doğrulanmayan\n // yarı, bir yazım hatasını Postgres'e kadar taşıyordu: çağıran ham\n // `column \"dome\" of relation \"todos\" does not exist` görüyordu, SDK'nın\n // kendi diliyle değil. Null şema \"kontrol edemem\" demektir, \"serbest\"\n // değil — identifier yine quoteIdent'ten geçer (D-21).\n const known = schemaColumns(table);\n if (known !== null) {\n for (const c of cols) {\n if (!known.has(c)) {\n throw new Error(`updateMany(${table}): set kolonu \"${c}\" tabloda yok (FR-016)`);\n }\n }\n }\n const params: unknown[] = [];\n const add = (v: unknown): string => {\n params.push(v);\n return `$${params.length}`;\n };\n const assignments = buildSetAssignments(table, cols, set, add, \"updateMany\");\n const whereSql = compileWhere(table, known, where, add, \"updateMany\");\n assertHasPredicate(whereSql, \"updateMany\", table);\n // `AS t`, because compileWhere qualifies every column with the `t.` alias —\n // the same compiler findMany uses, and it must stay the same one. Without\n // the alias the predicate names a relation this statement never declared.\n //\n // Çok satır: kilit sırası CTE'de SABİTLENİR (FR-015). Postgres'in UPDATE'i\n // satırları KEYFİ sırada kilitler (\"There is no ORDER BY in an SQL UPDATE\n // command\") — aynı iki satıra dokunan iki oturum farklı plan seçerse ters\n // sırada kilitleyip deadlock üretir. ORDER BY'ı UPDATE'e yazamayız; bu\n // yüzden sıra, kilidi ALAN SELECT'e yazılıyor.\n const pk = primaryKeyOf(table);\n // `returning: false` — SATIR DEĞİL SAYI. Ölçüldü (200 bin satır, canlı\n // pg16): `RETURNING *` sunucuda %55 daha pahalı (7,2 sn → 11,1 sn) ve\n // JS'te 45 MB yığın, satır başına 236 bayt. Bir milyon satırda 225 MB.\n // `updateMany`'nin sözleşmesi dönen diziyi okumaktır ve çoğu çağrı için\n // doğrudur — ama toplu bir iş için çıkış yolu OLMALIYDI, ve `deleteMany`\n // zaten sayı döndürüyor.\n const wantRows = opts?.returning !== false;\n const tail = wantRows ? `RETURNING ${rowProjection(table, \"t\", \"*\")}` : \"RETURNING 1\";\n const simple = isSinglePkEquality(where, pk) || pk === null;\n // Kilit CTE'si (FR-015) ZATEN bir WITH listesi; sayım onun ARDINA\n // ekleniyor, İÇİNE değil — `WITH upd AS (WITH locked AS …)` iç içe bir\n // CTE olurdu ve okunması da doğrulaması da zor.\n const body = simple\n ? `UPDATE ${quoteTable(table)} AS t SET ${assignments} WHERE true${whereSql} ${tail}`\n : `UPDATE ${quoteTable(table)} AS t SET ${assignments} FROM locked ` +\n `WHERE t.${quoteIdent(pk)} = locked.\"__pb_lock\" ` +\n (wantRows ? `RETURNING ${rowProjection(table, \"t\")}` : \"RETURNING 1\");\n const lockedCte = simple\n ? \"\"\n : `WITH locked AS (SELECT t.${quoteIdent(pk)} AS \"__pb_lock\" FROM ${quoteTable(table)} t WHERE true${whereSql} ` +\n `ORDER BY t.${quoteIdent(pk)} FOR NO KEY UPDATE) `;\n const sql = wantRows\n ? `${lockedCte}${body}`\n : simple\n ? `WITH upd AS (${body}) SELECT count(*)::int AS n FROM upd`\n : `${lockedCte.replace(/ $/, \"\")}, upd AS (${body}) SELECT count(*)::int AS n FROM upd`;\n const out = (await (await at()).unsafe(sql, params)) as Row[];\n // `returning: false` SAYI döndürür — `deleteMany` ile aynı şekil, aynı\n // gerekçe.\n if (!wantRows) return Number((out[0] as Record<string, unknown> | undefined)?.[\"n\"] ?? 0);\n return asTableRows(table, out);\n },\n\n /**\n * Delete every row the filter matches, in ONE statement; resolves to how\n * many went. Same filter language, same empty-filter refusal as\n * {@link updateMany} — and here the accident is worse.\n */\n async deleteMany(table: string, where: Row): Promise<number> {\n assertNotAppendOnly(\"deleteMany\", table);\n const params: unknown[] = [];\n const add = (v: unknown): string => {\n params.push(v);\n return `$${params.length}`;\n };\n const known = schemaColumns(table);\n const whereSql = compileWhere(table, known, where, add, \"deleteMany\");\n assertHasPredicate(whereSql, \"deleteMany\", table);\n // DÜZ DELETE — kilit-sırası CTE'si BURADA YOK, ve yokluğu bir eksiklik\n // değil ölçülmüş bir düzeltme (T013 gözcüsü, canlı pg16; spec Changelog\n // 2026-09-02'de FR-015 buna göre daraltıldı).\n //\n // İki bağımsız sebep, ikisi de kilitleyen SELECT'in kendisinden geliyor:\n //\n // 1. YETKİ. `FOR NO KEY UPDATE` bir UPDATE kilididir ve Postgres\n // kilitleyen SELECT'e UPDATE POLİTİKASINI uygular (CREATE POLICY,\n // Table 292: \"Using UPDATE for a policy means that it will apply to\n // UPDATE, SELECT FOR UPDATE, and SELECT FOR SHARE\"). Yapılan iş ise\n // DELETE ve DELETE politikasıyla yönetilir. SELECT+DELETE politikası\n // olan ama UPDATE politikası OLMAYAN bir tabloda ölçüm: düz DELETE 1\n // satır sildi, CTE'li form 0 sildi — hatasız. Çağıran o sıfırı\n // \"hiçbir şey eşleşmedi\" diye okur. `FOR UPDATE` de kurtarmıyor.\n // 2. KİLİT YÜKSELTMESİ. DELETE zaten `FOR UPDATE` gücünde kilit alır\n // (doküman 13.3.2), yani `FOR NO KEY UPDATE` ile başlamak 13.3.4'ün\n // \"ilk alınan kilit gereken en kısıtlayıcı mod olsun\" kuralını\n // çiğner. NOT: bu gerekçenin FK'li kurulumdaki deadlock ölçümü ikinci\n // bir gözcü tarafından YENİDEN ÜRETİLEMEDİ — o kurguda her iki form\n // da deadlock veriyor. Yükseltmenin kendisi dokümanla sabit; ondan\n // doğan somut zarar iddiası ölçülmüş SAYILMAMALI.\n //\n // KABUL EDİLEN BEDEL, adıyla: düz form satırları pk sırasında DEĞİL,\n // planın seçtiği sırada kilitler. Aynı satır kümesine giren eşzamanlı bir\n // `updateMany` (o pk sırasında kilitliyor) ile deadlock ALINABİLİR —\n // ölçüldü, üretildi. Takas bilinçli: deadlock 40P01 ile GÜRÜLTÜLÜDÜR ve\n // çağıran onu görüp yeniden dener; alternatifi RLS altında SESSİZ 0\n // satırdı, ve sessiz yanlış cevap gürültülü hatadan her zaman kötüdür.\n //\n // `updateMany` tarafında bu ikilem yok (iş zaten UPDATE), orada CTE\n // duruyor.\n // `RETURNING 1` SATIR BAŞINA bir satır döndürüyor ve yalnız uzunluğu\n // okunuyor. Bir CTE ile tek satıra indirmeyi denedim ve GERİ ALDIM:\n // ölçüldü, 200 bin silmede bu biçim 8,1 MB — `RETURNING *`'ın 45 MB'ına\n // karşı 5,5 kat ucuz. Kazanç, kilit ve RLS gerekçesi özenle yazılmış bir\n // testin çivilediği bir statement şeklini değiştirmeyi hak etmiyor.\n // Bedel BİLİNİYOR ve ölçülü (D-034).\n const sql = `DELETE FROM ${quoteTable(table)} AS t WHERE true${whereSql} RETURNING 1`;\n const rows = (await (await at()).unsafe(sql, params)) as Row[];\n return rows.length;\n },\n\n /**\n * How many rows match — the half of pagination `limit`/`offset` cannot\n * supply. Without it a page count is either a guess or \"fetch everything and\n * read .length\", and the second one is the scale risk this surface exists to\n * remove.\n *\n * An empty filter is legitimate HERE: counting a whole table is a read, and\n * reads do not destroy anything.\n */\n /**\n * Toplama — `count`'un yanına `sum`/`avg`/`min`/`max` ve `groupBy`.\n *\n * Var olma nedeni: bunlar olmadan \"bu hesabın toplamı\" ya `$query`'ye ya da\n * TÜM satırları çekip JS'te toplamaya düşüyor. İkincisi hem N+1 hem de para\n * için YANLIŞ — `numeric` JS `number`'ına uğradığı anda kesinliğini\n * kaybeder.\n *\n * `groupBy` verilirse SATIRLAR döner, verilmezse TEK sonuç. Boş kümede\n * Postgres NULL döndürür, 0 değil — ve bu SDK onu `null` olarak geçiriyor:\n * \"hiç satır yoktu\" ile \"toplam sıfırdı\" farklı şeyler.\n */\n async aggregate(\n table: string,\n q: {\n where?: Row;\n sum?: readonly string[];\n avg?: readonly string[];\n min?: readonly string[];\n max?: readonly string[];\n count?: boolean;\n groupBy?: readonly string[];\n } = {},\n ): Promise<Record<string, unknown> | Record<string, unknown>[]> {\n const known = schemaColumns(table);\n const check = (col: string, where: string): void => {\n if (known !== null && !known.has(col)) {\n throw new Error(`aggregate(${table}): ${where} kolonu \"${col}\" tabloda yok (FR-016)`);\n }\n };\n const parts: string[] = [];\n const wants: { fn: \"sum\" | \"avg\" | \"min\" | \"max\"; col: string; alias: string }[] = [];\n for (const fn of [\"sum\", \"avg\", \"min\", \"max\"] as const) {\n for (const col of q[fn] ?? []) {\n check(col, fn);\n // `sum`/`avg` SAYISAL OLMAYAN bir kolonda anlamsız ve Postgres onu\n // `function sum(text) does not exist` diye reddeder — tip de\n // reddediyor, ama tipin atlandığı yolda motor susmamalı.\n if (fn === \"sum\" || fn === \"avg\") {\n const t = columnTypeOf(table, col);\n if (t !== null && !NUMERIC_PG_TYPES.has(t)) {\n throw new Error(\n `aggregate(${table}): ${fn}(\"${col}\") sayısal olmayan bir kolonda — \"${col}\" bir ` +\n `${t} kolonu. Toplama yalnız integer/bigint/numeric kolonlarda anlamlı; ` +\n `kaç satır olduğunu saymak için count: true kullanın.`,\n );\n }\n }\n const alias = `${fn}__${col}`;\n wants.push({ fn, col, alias });\n parts.push(aggregateExpr(table, fn, col, alias));\n }\n }\n if (q.count === true) parts.push('count(*) AS \"_count\"');\n if (parts.length === 0) {\n throw new Error(\n `aggregate(${table}): hiçbir toplama istenmedi — sonuç boş bir nesne olurdu. ` +\n `sum/avg/min/max kolonlarını ya da count: true'yu verin.`,\n );\n }\n const groups = q.groupBy ?? [];\n for (const col of groups) check(col, \"groupBy\");\n const groupSel = groups.map((c) => `${columnTypeOf(table, c) === \"timestamp\" ? columnResult(table, c, \"t\") : `t.${quoteIdent(c)}`} AS ${quoteIdent(`g__${c}`)}`);\n\n const params: unknown[] = [];\n const add = (v: unknown): string => `$${params.push(v)}`;\n const whereSql = compileWhere(table, known, q.where ?? {}, add, \"aggregate\");\n const groupSql = groups.length > 0 ? ` GROUP BY ${groups.map((c) => `t.${quoteIdent(c)}`).join(\", \")}` : \"\";\n const sql =\n `SELECT ${[...groupSel, ...parts].join(\", \")} FROM ${quoteTable(table)} t ` +\n `WHERE true${whereSql}${groupSql}`;\n const rows = (await (await at()).unsafe(sql, params)) as Record<string, unknown>[];\n\n const shape = (r: Record<string, unknown>): Record<string, unknown> => {\n const out: Record<string, unknown> = {};\n for (const c of groups) out[c] = r[`g__${c}`];\n for (const w of wants) {\n const bucket = (out[w.fn] ??= {}) as Record<string, unknown>;\n bucket[w.col] = r[w.alias] ?? null;\n }\n // count TEK sayı, çünkü tek bir şeyi sayıyor. Postgres bigint döndürür,\n // sürücü string verir — `count()` op'unun aynı dönüşümü.\n if (q.count === true) out[\"count\"] = Number(r[\"_count\"] ?? 0);\n return out;\n };\n // `groupBy` yoksa Postgres HER ZAMAN tek satır döndürür (boş tabloda bile,\n // NULL'larla) — o yüzden burada `rows[0]` boş olamaz, ama olsa bile\n // şekli koruyoruz ki çağıran `undefined` görmesin.\n return groups.length > 0 ? rows.map(shape) : shape(rows[0] ?? {});\n },\n\n async count(table: string, where: Row = {}): Promise<number> {\n const params: unknown[] = [];\n const add = (v: unknown): string => {\n params.push(v);\n return `$${params.length}`;\n };\n const known = schemaColumns(table);\n const whereSql = compileWhere(table, known, where, add, \"count\");\n const sql = `SELECT count(*) AS n FROM ${quoteTable(table)} t WHERE true${whereSql}`;\n const rows = (await (await at()).unsafe(sql, params)) as Row[];\n // Postgres answers count() as bigint, which the driver hands over as a\n // STRING. Returning it unconverted would put the report's own A4 defect\n // into a brand-new surface: a \"number\" the caller cannot add to.\n return Number((rows[0] as Record<string, unknown> | undefined)?.n ?? 0);\n },\n\n async findUnique(table: string, where: Row, opts: { select?: readonly string[]; with?: Record<string, unknown> } = {}): Promise<Row | null> {\n const keys = memoTable(uniqueKeysCache, currentSchema, table, () => uniqueKeysOf(tableDefOf(table) ?? {}));\n assertUniqueLookup(table, keys, where);\n const rows = await ops.findMany(table, where, { ...opts, select: opts.select === undefined ? undefined : [...opts.select], limit: 2 });\n if (rows.length > 1) throw new Error(`findUnique(${table}): deployed constraints disagree with the schema; multiple rows matched`);\n return rows[0] ?? null;\n },\n\n async findById(table: string, id: string): Promise<Row | null> {\n const rows = (await (await at()).unsafe(\n `SELECT ${rowProjection(table)} FROM ${quoteTable(table)} WHERE id = $1`,\n [id],\n )) as Row[];\n return rows[0] ? asTableRow(table, rows[0]) : null;\n },\n\n async findMany(table: string, query: Row = {}, opts: FindManyOptions = {}): Promise<Row[]> {\n const compiled = compileFindMany(table, query, opts);\n return asTableRows(table, await (await at()).unsafe(compiled.sql, compiled.params) as Row[], opts.with, opts.select !== undefined);\n },\n\n async page(table: string, query: Row = {}, opts: RawPageOptions = {}): Promise<Page<Row>> {\n const secret = cursorKey();\n const schema = pageSchema(table);\n const { order, size, backward, token } = pageOrder(schema.columns, schema.primaryKey, opts);\n const params: unknown[] = [];\n const add = (v: unknown) => `$${params.push(v)}`;\n const known = schemaColumns(table);\n const where = compileWhere(table, known, query, add, \"page\");\n const cols = selectClause(table, known, opts.select === undefined ? undefined : [...opts.select]);\n const scope = fingerprint({ table, schema: schema.stamp, order, where, params,\n select: opts.select, with: opts.with, identity: context.cursorScope ?? \"direct\" });\n const values = token === undefined ? undefined : decodeCursor(secret, scope, token, order.length);\n const column = (name: string) => `t.${quoteIdent(name)}`;\n const boundary = values ? ` AND ${pageBoundary(order, values, backward, add, column)}` : \"\";\n const opposite = values\n ? `EXISTS (SELECT 1 FROM ${quoteTable(table)} t WHERE true${where} AND ${pageBoundary(order, values, !backward, add, column, true)})`\n : \"false\";\n // Each hidden name is chosen outside both the projection and relation map.\n let prefix = \"__pb_page_\";\n const names = [...Object.keys(schema.columns), ...Object.keys(opts.with ?? {})];\n while (names.some(n => n.startsWith(prefix))) prefix += \"_\";\n const ordinal = `${prefix}ordinal`, other = `${prefix}opposite`;\n const hidden = order.map((o, i) => `${prefix}${i}`);\n const cursorCols = order.map((o, i) => `${columnTypeOf(table, o.column) === \"timestamp\" ? timestampResult(column(o.column)) : `${column(o.column)}::text`} AS ${quoteIdent(hidden[i]!)}`);\n const w = opts.with && Object.keys(opts.with).length ? withClauses(table, opts.with, add, \"page\") : { select: [], joins: [] };\n const nativeOrder = order.map(o => `${column(o.column)} ${(o.direction === \"asc\") !== backward ? \"ASC\" : \"DESC\"} NULLS ${(o.nulls === \"first\") !== backward ? \"FIRST\" : \"LAST\"}`).join(\", \");\n const visible = cols === \"*\" ? \"t.*\" : cols;\n const inner = `SELECT ${[visible, ...w.select, ...cursorCols, `row_number() OVER (ORDER BY ${nativeOrder}) AS ${quoteIdent(ordinal)}`].join(\", \")} ` +\n `FROM ${quoteTable(table)} t ${w.joins.join(\" \")} WHERE true${where}${boundary} ORDER BY ${nativeOrder} LIMIT ${size + 1}`;\n // The outer row exists even for an empty page. Both flags and the page\n // observe one statement snapshot, including under READ COMMITTED.\n const sql = `SELECT p.*, b.${quoteIdent(other)} FROM (SELECT ${opposite} AS ${quoteIdent(other)}) b ` +\n `LEFT JOIN LATERAL (${inner}) p ON true ORDER BY p.${quoteIdent(ordinal)}`;\n const result = await (await at()).unsafe(sql, params) as Row[];\n const hasOpposite = result[0]?.[other] === true;\n let rows = result.filter(row => row[ordinal] !== null && row[ordinal] !== undefined);\n const hasMore = rows.length > size;\n rows = rows.slice(0, size);\n if (backward) rows.reverse();\n const cursor = (row: Row | undefined) => row ? encodeCursor(secret, scope, hidden.map(name => row[name] === null ? null : String(row[name]))) : null;\n const pageInfo = { startCursor: cursor(rows[0]), endCursor: cursor(rows.at(-1)),\n hasNextPage: backward ? hasOpposite : hasMore, hasPreviousPage: backward ? hasMore : hasOpposite };\n for (const row of rows) for (const name of [...hidden, ordinal, other]) delete row[name];\n return { rows: asTableRows(table, rows, opts.with, opts.select !== undefined), pageInfo };\n },\n\n /**\n * Tek-SQL hibrit arama (FR-014): iki kol CTE + FULL OUTER JOIN + RRF\n * (1/(50+rank), CLAIM-N4). Operatör şema-nitelikli (C-10, M-1); GUC\n * hnsw.iterative_scan=relaxed_order aynı tx'te set_config ile (CLAIM-N3 —\n * RLS/filtre altında LIMIT-altı dönüş açığını kapatır). Sorgu-anı embed\n * T024'te gelir; o zamana dek vector kolu yalnız params.vector ile koşar.\n */\n async search(\n table: string,\n params: {\n query?: string;\n vector?: number[];\n where?: Record<string, unknown>;\n limit?: number;\n using?: string;\n mode?: \"hybrid\" | \"text\" | \"vector\";\n /** Nihai (RRF-sonrası) skor alt eşiği — süzme LIMIT'ten ÖNCE (FR-001). */\n minScore?: number;\n /** RRF-sonrası üstel tazelik çürümesi: _score * exp(-ln(2)*yaş/halfLife) (FR-004). */\n recency?: { field: string; halfLife: string };\n /** Chunk-modunda satır başına dönen en iyi blok sayısı (1..10, vars. 3; FR-015). */\n blocksPerRow?: number;\n /** Satır-modunda FTS eşleşme vurgusu: ts_headline ile `_highlight`\n * alanı; chunk-modda no-op — bloklar zaten eşleşen kesittir (FR-025). */\n highlight?: boolean;\n /** Validity'li tabloda zaman penceresi: varsayılan yalnız güncel;\n * \"all\" tüm versiyonlar; {asOf} o andaki geçerli versiyon (FR-029). */\n validity?: \"all\" | { asOf: string };\n /** Alan-boost (FR-030): skor * (1 + w·x/(1+x)) — sınırlı, dış servissiz. */\n boost?: { field: string; weight: number };\n } = {},\n ): Promise<Row[]> {\n const cfg = searchConfigFor(table);\n if (!cfg) {\n throw new Error(`search(${table}): tablo aranabilir değil — ne vector kolonu ne search beyanı var (FR-013)`);\n }\n const excl = (params as InternalSearchParams).__excludeIds ?? [];\n // FR-058: `facets` search'ün PARAMETRESİ DEĞİL. Sayaçlar dizi ÜSTÜNDE bir\n // özellik olarak taşınıyordu ve `JSON.stringify(rows)` onu SESSİZCE\n // düşürüyor — bir kontrolcü onu döndürmeye çalıştığında yanıt gövdesinde\n // hiç görünmüyordu. Bağımsız dönüş veren `facets()` ciddi sözleşme.\n if ((params as { facets?: unknown }).facets !== undefined) {\n throw new Error(\n `search(${table}): facets artık search'ün parametresi değil — sayaçlar dizi üstünde ` +\n `taşınınca JSON.stringify onları düşürüyordu (FR-058). Bağımsız çağırın: ` +\n `facets({ facets: [...], where })`,\n );\n }\n if (params.validity !== undefined && cfg.validity !== true) {\n throw new Error(\n `search(${table}): validity parametresi verildi ama tablo validity beyanı taşımıyor (FR-029)`,\n );\n }\n // FR-029: validity filtresi where'lerle aynı bileşime girer — sem/kw/probe\n // ve chunk parent'ı; facets sayaçları da aynı pencereyi görür.\n const validityFor = (adder: (x: unknown) => string): string =>\n cfg.validity === true ? validitySql(params.validity, adder) : \"\";\n const rawLimit = params.limit ?? 20;\n if (typeof rawLimit !== \"number\" || !Number.isFinite(rawLimit)) {\n throw new Error(`search(${table}): limit sonlu bir sayı olmalı, ${String(rawLimit)} verildi (FR-013)`);\n }\n const limit = Math.min(Math.max(1, Math.trunc(rawLimit)), 100);\n const pool = Math.max(limit * 3, 30);\n if (params.minScore !== undefined && (typeof params.minScore !== \"number\" || !Number.isFinite(params.minScore))) {\n throw new Error(`search(${table}): minScore sonlu bir sayı olmalı, ${String(params.minScore)} verildi (FR-001)`);\n }\n // recency.field yalnız kolon-üyeliğiyle doğrulanır — cfg kolon TİPİ\n // taşımaz; timestamp olmayan kolon SQL'de kendi adıyla düşer (C-6).\n let recencyMul = \"\";\n if (params.recency !== undefined) {\n const { field, halfLife } = params.recency;\n if (!cfg.colSet.has(field)) {\n throw new Error(`search(${table}): recency.field \"${field}\" tabloda yok (FR-004)`);\n }\n recencyMul = ` * exp(-ln(2) * extract(epoch from (now() - t.${quoteIdent(field)})) / ${parseHalfLife(halfLife)})`;\n }\n // FR-030/D-017: alan-boost dış servissiz SINIRLI çarpandır — x/(1+x)\n // 0..1'e doyar, 1 + w·(...) hiçbir satırı sıfırlamaz; weight doğrulanmış\n // SONLU sayı olarak SQL'e literal iner (recency'nin halfLife'ı gibi).\n // Bileşim sırası FR-030: RRF → boost → recency → minScore.\n let boostMul = \"\";\n if (params.boost !== undefined) {\n const { field, weight } = params.boost;\n if (!cfg.colSet.has(field)) {\n throw new Error(`search(${table}): boost.field \"${field}\" tabloda yok (FR-030)`);\n }\n if (typeof weight !== \"number\" || !Number.isFinite(weight)) {\n throw new Error(`search(${table}): boost.weight sonlu bir sayı olmalı, ${String(weight)} verildi (FR-030)`);\n }\n const g = `greatest(t.${quoteIdent(field)},0)`;\n boostMul = ` * (1 + ${weight} * ${g}/(1+${g}))`;\n }\n const scoreMul = boostMul + recencyMul;\n if (cfg.chunk !== undefined) {\n // CHUNK-MODU (FR-015, D-010): arama türev tabloda koşar; RRF chunk\n // düzeyinde, sonra parent'a MAX-skor toplaması + en iyi blokların\n // json_agg'ı. minScore/recency GRUPLAMA-SONRASI parent skoruna\n // uygulanır (FR-018). `where` filtreleri parent satırına uygulanır;\n // RLS'i chunk tablosunun parent-mirror policy'si zaten süzer.\n const ck = cfg.chunk;\n const pidQ = quoteIdent(`parent_${cfg.pk}`);\n const bpr = Math.min(Math.max(1, Math.trunc(params.blocksPerRow ?? 3)), 10);\n const wantTextC =\n params.mode !== \"vector\" && ck.fts && typeof params.query === \"string\" && params.query !== \"\";\n let qvC: number[] | null = Array.isArray(params.vector) ? params.vector : null;\n if (qvC === null && ck.embed !== undefined && params.mode !== \"text\" &&\n typeof params.query === \"string\" && params.query !== \"\") {\n try {\n qvC = await embedQuery(ck.embed, params.query);\n } catch (e) {\n if (!wantTextC) throw e;\n qvC = null;\n }\n }\n if (!wantTextC && qvC === null) {\n throw new Error(\n `search(${table}): koşulabilir kol yok — metin için 'query' (FTS beyanı gerekir), semantik için 'vector' verin (FR-015)`,\n );\n }\n const bindC: unknown[] = [];\n const addC = (v: unknown): string => { bindC.push(v); return `$${bindC.length}`; };\n // where/validity/exclude ADAY ÜRETİMİNE gömülür (final-review C1):\n // küresel top-K chunk havuzu filtreli kümeden seçilmezse seçici bir\n // where'de eşleşen sayfa havuza hiç giremez ve arama sessizce boş\n // döner. Satır-modunun kanıtlı deseniyle simetri: filtrenin tek\n // yazarı aday CTE'leridir (sem/kw/trgm-retry); dış katman tekrarlamaz.\n const userWhereC = compileWhere(table, cfg.colSet, params.where ?? {}, addC);\n const whereC = userWhereC + excludeSql(cfg.pk, excl, addC) + validityFor(addC);\n const parentJoinC = ` JOIN ${quoteTable(table)} t ON t.${quoteIdent(cfg.pk)} = c.${pidQ} WHERE true${whereC} AND `;\n const liveC = await at();\n const K2 = 50;\n const cpool = Math.max(limit * 9, 90); // blok başına aday: parent-limit × blocksPerRow payı\n let semC = \"\";\n let kwC = \"\";\n if (qvC !== null) {\n const sch = await vectorSchemaWithGuc(liveC);\n const op = METRIC_OPERATOR[ck.metric] ?? METRIC_OPERATOR.cosine;\n // NFR-B4 kapanışı: satır-modu probe'unun chunk ikizi — filtreli chunk\n // kümesi ≤ eşikse HNSW yerine exact tarama (+ 0.0 sıralama ifadesini\n // index-eşleşmesinden düşürür); recall=1.0, ms'ler. Probe RLS'li aynı\n // tx'te, C1'in parent-JOIN'li filtresiyle aynı kümeyi sayar.\n let exactOrderC = \"\";\n if (userWhereC !== \"\") {\n const probeRows = (await liveC.unsafe(\n `SELECT count(*)::int AS n FROM (SELECT 1 FROM ${quoteTable(ck.table)} c${parentJoinC}c.embedding IS NOT NULL LIMIT ${SELECTIVITY_EXACT_THRESHOLD + 1}) s`,\n bindC.slice(),\n )) as { n?: number }[];\n const n = probeRows?.[0]?.n;\n if (typeof n === \"number\" && n <= SELECTIVITY_EXACT_THRESHOLD) {\n exactOrderC = \" + 0.0\";\n }\n }\n const vp = addC(toVectorLiteral(qvC));\n semC =\n `SELECT c.${pidQ} AS pid, c.chunk_seq, ROW_NUMBER() OVER (ORDER BY (c.embedding OPERATOR(${quoteIdent(sch)}.${op}) ${vp}::${quoteIdent(sch)}.vector)${exactOrderC}) AS r ` +\n `FROM ${quoteTable(ck.table)} c${parentJoinC}c.embedding IS NOT NULL ORDER BY r LIMIT ${cpool}`;\n }\n let qpC = \"\";\n let qpCIdx = -1;\n if (wantTextC) {\n // FR-026: genişletme yalnız websearch BIND değerine — SQL metni değişmez.\n const qTextC =\n cfg.synonyms !== undefined ? expandSynonyms(params.query!, cfg.synonyms) : params.query;\n qpC = addC(qTextC);\n qpCIdx = bindC.length - 1;\n kwC =\n `SELECT c.${pidQ} AS pid, c.chunk_seq, ROW_NUMBER() OVER (ORDER BY ts_rank_cd(c.palbase_fts, websearch_to_tsquery('simple', ${qpC})) DESC) AS r ` +\n `FROM ${quoteTable(ck.table)} c${parentJoinC}c.palbase_fts @@ websearch_to_tsquery('simple', ${qpC}) ORDER BY r LIMIT ${cpool}`;\n }\n const msC = params.minScore === undefined ? \"\" : addC(params.minScore);\n const colListC = [...cfg.cols.map((c) => columnTypeOf(table, c) === \"timestamp\" ? projectedColumn(table, c, \"t\") : `t.${quoteIdent(c)}`)].join(\", \");\n const scoreC = scoreMul === \"\" ? \"g._score\" : `(g._score)${scoreMul}`;\n const assembleC = (kwIn: string, withKwn: boolean): string => {\n const kwnCol = withKwn ? `, (SELECT count(*) FROM kw)::int AS _kwn` : \"\";\n let fusedSrc: string;\n if (semC !== \"\" && kwIn !== \"\") {\n fusedSrc =\n `WITH sem AS (${semC}), kw AS (${kwIn}), fused AS (` +\n `SELECT COALESCE(sem.pid, kw.pid) AS pid, COALESCE(sem.chunk_seq, kw.chunk_seq) AS chunk_seq, ` +\n `(COALESCE(1.0/(${K2} + sem.r), 0) + COALESCE(1.0/(${K2} + kw.r), 0))::float8 AS cscore ` +\n `FROM sem FULL OUTER JOIN kw ON sem.pid = kw.pid AND sem.chunk_seq = kw.chunk_seq)`;\n } else if (semC !== \"\") {\n fusedSrc = `WITH sem AS (${semC}), fused AS (SELECT sem.pid, sem.chunk_seq, (1.0/(${K2} + sem.r))::float8 AS cscore FROM sem)`;\n } else {\n fusedSrc = `WITH kw AS (${kwIn}), fused AS (SELECT kw.pid, kw.chunk_seq, (1.0/(${K2} + kw.r))::float8 AS cscore FROM kw)`;\n }\n const inner =\n `${fusedSrc}, ranked AS (` +\n `SELECT f.pid, f.chunk_seq, f.cscore, ROW_NUMBER() OVER (PARTITION BY f.pid ORDER BY f.cscore DESC, f.chunk_seq) AS rn FROM fused f), ` +\n `grouped AS (` +\n `SELECT r.pid, MAX(r.cscore) AS _score, ` +\n `json_agg(json_build_object('content', c.content, 'score', r.cscore, 'chunkSeq', r.chunk_seq, 'charStart', c.char_start) ORDER BY r.cscore DESC, r.chunk_seq) FILTER (WHERE r.rn <= ${bpr}) AS blocks ` +\n `FROM ranked r JOIN ${quoteTable(ck.table)} c ON c.${pidQ} = r.pid AND c.chunk_seq = r.chunk_seq ` +\n `GROUP BY r.pid) ` +\n `SELECT ${colListC}, ${scoreC}::float8 AS _score, g.blocks AS blocks${kwnCol} ` +\n `FROM grouped g JOIN ${quoteTable(table)} t ON t.${quoteIdent(cfg.pk)} = g.pid`;\n return msC === \"\"\n ? `SELECT q.*${canOuter(table)} FROM (${inner}) q ORDER BY q._score DESC, q.${quoteIdent(cfg.pk)} LIMIT ${limit}`\n : `SELECT q.*${canOuter(table)} FROM (${inner}) q WHERE q._score >= ${msC} ORDER BY q._score DESC, q.${quoteIdent(cfg.pk)} LIMIT ${limit}`;\n };\n let rowsC = (await liveC.unsafe(assembleC(kwC, kwC !== \"\"), bindC)) as Row[];\n if (wantTextC && kwC !== \"\" && (rowsC.length === 0 || (rowsC[0] as Record<string, unknown>)._kwn === 0)) {\n // FR-002 chunk-modunda da geçerli: kelime kolu 0 adaysa trgm retry —\n // ifade chunk İÇERİĞİ üstünde (türev index'in kaynağı da o).\n const tsch = await trgmSchemaOf(liveC);\n const trgmKwC =\n `SELECT c.${pidQ} AS pid, c.chunk_seq, ROW_NUMBER() OVER (ORDER BY ${quoteIdent(tsch)}.word_similarity(${qpC}, coalesce(c.content,'')) DESC) AS r ` +\n `FROM ${quoteTable(ck.table)} c${parentJoinC}${quoteIdent(tsch)}.word_similarity(${qpC}, coalesce(c.content,'')) > 0.3 ORDER BY r LIMIT ${cpool}`;\n // trgm kelime-benzerliği OR-sözdizimi tanımaz: retry aynı placeholder'ı\n // HAM query ile koşar (bind kopyası — kayıtlı ilk çağrı değişmez).\n const retryBindC = bindC.slice();\n if (qpCIdx >= 0) retryBindC[qpCIdx] = params.query;\n rowsC = (await liveC.unsafe(assembleC(trgmKwC, false), retryBindC)) as Row[];\n }\n for (const r of rowsC) delete (r as Record<string, unknown>)._kwn;\n const outC = asTableRows(table, rowsC).map((r) => ({ ...r, blocks: (r as { blocks?: unknown }).blocks ?? [] }));\n logNoResults(table, params.query, params.mode, outC.length);\n return outC;\n }\n const wantText =\n params.mode !== \"vector\" && cfg.ftsCols.length > 0 && typeof params.query === \"string\" && params.query !== \"\";\n // Vektör kolu ancak GERÇEKTEN istenecekse çözülür (FR-015, review C1):\n // çok kollu tabloda salt-text arama 'using' zorunluluğuna TAKILMAZ.\n const anyEmbed = cfg.legs.some((l) => l.embed !== undefined);\n const vectorAsked =\n params.mode !== \"text\" &&\n (Array.isArray(params.vector) || params.using !== undefined || params.mode === \"vector\" ||\n (anyEmbed && typeof params.query === \"string\" && params.query !== \"\"));\n const leg = vectorAsked ? pickLeg(table, cfg.legs, params.using) : null;\n let qv: number[] | null = Array.isArray(params.vector) ? params.vector : null;\n if (qv === null && leg?.embed !== undefined && typeof params.query === \"string\" && params.query !== \"\") {\n // FR-025: beyan edilen modelle TEK sağlayıcı çağrısı. Başarısızlıkta\n // FR-015 düşüşü: text kolu koşulabiliyorsa arama ONUNLA döner; yoksa\n // adlandırılmış hata (sessiz boş dönüş asla).\n try {\n qv = await embedQuery(leg.embed, params.query);\n } catch (e) {\n if (!wantText) throw e;\n qv = null;\n }\n }\n const wantVector = leg !== null && qv !== null;\n if (!wantText && !wantVector) {\n throw new Error(\n `search(${table}): koşulabilir kol yok — metin için 'query' (FTS beyanı gerekir), semantik için 'vector' verin (FR-015)`,\n );\n }\n const bind: unknown[] = [];\n const add = (v: unknown): string => {\n bind.push(v);\n return `$${bind.length}`;\n };\n // Probe kararı (aşağıda) kullanıcı where'ine bakar: exclude tek başına\n // neredeyse hiç seçici değildir, exact-yol probe'unu tetiklememeli.\n const userWhere = compileWhere(table, cfg.colSet, params.where ?? {}, add);\n const whereSql = userWhere + excludeSql(cfg.pk, excl, add) + validityFor(add);\n const live = await at();\n const K = 50;\n let semSql = \"\";\n let kwSql = \"\";\n if (wantVector && leg) {\n // GUC yalnız hnsw taramasını etkiler — salt-text arama onu hiç koşmaz\n // (review I4). Soğuk yolda extension-şema lookup'ı AYNI statement'a\n // biner: sıcak yol +1, soğuk yol +1 (eskiden +2) round-trip; kalan tek\n // ekstra tur NFR-002'de karar kaydıyla kabul edildi.\n const sch = await vectorSchemaWithGuc(live);\n const op = METRIC_OPERATOR[leg.metric] ?? METRIC_OPERATOR.cosine;\n // SEÇİCİ FİLTREDE EXACT YOL (NFR-005 kapanışı, ölçümle): HNSW iterative\n // scan %1 seçicilikte 100K ölçeğinde hedefe ULAŞAMIYOR — GUC gridi\n // (relaxed/strict × max_scan_tuples 200K × ef_search 200..1000) en iyi\n // 0.38 recall verdi. Filtreli küme küçükse doğru cevap index'i HİÇ\n // kullanmamak: ≤10K satırda exact mesafe taraması ms'ler sürer ve\n // recall=1.0. Seçicilik bir probe ile ölçülür (RLS aynı tx'te — sayım\n // tenant'ın görebildiği satırlarla); index'i devre dışı bırakmak için\n // sıralama ifadesine + 0.0 eklenir (planner ifade-eşleşmesini kaybeder;\n // EXPLAIN'le doğrulandı — GUC'suz, tx yan etkisiz).\n let exactOrder = \"\";\n if (userWhere !== \"\") {\n const probeRows = (await live.unsafe(\n `SELECT count(*)::int AS n FROM (SELECT 1 FROM ${quoteTable(table)} t WHERE t.${quoteIdent(leg.column)} IS NOT NULL${whereSql} LIMIT ${SELECTIVITY_EXACT_THRESHOLD + 1}) s`,\n bind.slice(),\n )) as { n?: number }[];\n const n = probeRows?.[0]?.n;\n if (typeof n === \"number\" && n <= SELECTIVITY_EXACT_THRESHOLD) {\n exactOrder = \" + 0.0\";\n }\n }\n const vp = add(toVectorLiteral(qv!));\n semSql =\n `SELECT t.${quoteIdent(cfg.pk)} AS id, ROW_NUMBER() OVER (ORDER BY (t.${quoteIdent(leg.column)} OPERATOR(${quoteIdent(sch)}.${op}) ${vp}::${quoteIdent(sch)}.vector)${exactOrder}) AS r ` +\n `FROM ${quoteTable(table)} t WHERE t.${quoteIdent(leg.column)} IS NOT NULL${whereSql} ORDER BY r LIMIT ${pool}`;\n }\n let qpRef = \"\";\n let qpIdx = -1;\n if (wantText) {\n // FR-026: genişletme yalnız websearch BIND değerine — SQL metni değişmez.\n const qText =\n cfg.synonyms !== undefined ? expandSynonyms(params.query!, cfg.synonyms) : params.query;\n const qp = add(qText);\n qpIdx = bind.length - 1;\n qpRef = qp;\n kwSql =\n `SELECT t.${quoteIdent(cfg.pk)} AS id, ROW_NUMBER() OVER (ORDER BY ts_rank_cd(t.palbase_fts, websearch_to_tsquery('simple', ${qp})) DESC) AS r ` +\n `FROM ${quoteTable(table)} t WHERE t.palbase_fts @@ websearch_to_tsquery('simple', ${qp})${whereSql} ORDER BY r LIMIT ${pool}`;\n }\n const colList = [...cfg.cols.map((c) => columnTypeOf(table, c) === \"timestamp\" ? projectedColumn(table, c, \"t\") : `t.${quoteIdent(c)}`)].join(\", \");\n // minScore parametresi BİR kez bind'lenir — assemble iki kez çağrılabilir\n // (typo-fallback retry'ı) ve her çağrıda add() bind'i şişirirdi.\n const msP = params.minScore === undefined ? \"\" : add(params.minScore);\n // FR-025: vurgu yalnız satır-modu + metinli aramada; ifade typo-fallback'in\n // sorted-kolon birleşimiyle aynı. qp placeholder'ı yeniden kullanılır.\n const hlCol =\n params.highlight === true && wantText\n ? `, ts_headline('simple', ${ftsExprOf(cfg.ftsCols)}, websearch_to_tsquery('simple', ${qpRef})) AS _highlight`\n : \"\";\n // Recency çarpanı RRF-SONRASI nihai skora biner (FR-004); recency/\n // minScore yokken SQL'in tek farkı metinli aramadaki `_kwn` scalar'ıdır:\n // kelime kolunun kaç aday bulduğunu nihai SELECT taşır — typo-fallback\n // kararı (FR-002) sonuç satırından okunur, karar için ek tur yoktur.\n const assemble = (kwIn: string, withKwn: boolean): string => {\n const kwnCol = withKwn ? `, (SELECT count(*) FROM kw)::int AS _kwn` : \"\";\n let inner: string;\n if (semSql !== \"\" && kwIn !== \"\") {\n const score = scoreMul === \"\" ? \"fused._score\" : `(fused._score)${scoreMul}`;\n inner =\n `WITH sem AS (${semSql}), kw AS (${kwIn}), fused AS (` +\n `SELECT COALESCE(sem.id, kw.id) AS id, ` +\n `(COALESCE(1.0/(${K} + sem.r), 0) + COALESCE(1.0/(${K} + kw.r), 0))::float8 AS _score ` +\n `FROM sem FULL OUTER JOIN kw ON sem.id = kw.id) ` +\n `SELECT ${colList}, ${score} AS _score${hlCol}${kwnCol} FROM fused ` +\n `JOIN ${quoteTable(table)} t ON t.${quoteIdent(cfg.pk)} = fused.id`;\n } else {\n const single = semSql !== \"\" ? `sem AS (${semSql})` : `kw AS (${kwIn})`;\n const alias = semSql !== \"\" ? \"sem\" : \"kw\";\n const base = `(1.0/(${K} + ${alias}.r))::float8`;\n const score = scoreMul === \"\" ? base : `(${base})${scoreMul}`;\n inner =\n `WITH ${single} ` +\n `SELECT ${colList}, ${score} AS _score${hlCol}${semSql !== \"\" ? \"\" : kwnCol} FROM ${alias} ` +\n `JOIN ${quoteTable(table)} t ON t.${quoteIdent(cfg.pk)} = ${alias}.id`;\n }\n // Satır modu HER ZAMAN dış sorguyla sarılır: `can` yalnız burada, `q`\n // üzerinden seçilebilir (iç FROM'da pk taşıyan CTE'ler var — ham `using`\n // belirsizleşir); minScore'suz kısayol satırı can'siz bırakıyordu ve\n // foldCan `[]` uyduruyordu (W1 r1-r3). minScore süzmesi LIMIT'ten ÖNCE\n // (FR-001): süzülen satırın yeri alttakiyle dolar.\n const ms = msP === \"\" ? \"\" : ` WHERE q._score >= ${msP}`;\n return (\n `SELECT q.*${canOuter(table)} FROM (${inner}) q${ms} ` +\n `ORDER BY q._score DESC, q.${quoteIdent(cfg.pk)} LIMIT ${limit}`\n );\n };\n let rows = (await live.unsafe(assemble(kwSql, kwSql !== \"\"), bind)) as Row[];\n if (wantText && kwSql !== \"\" && (rows.length === 0 || (rows[0] as Record<string, unknown>)._kwn === 0)) {\n // FR-002: kelime kolu HİÇ aday bulamadı — aynı sorgu pg_trgm\n // word_similarity ile BİR kez daha denenir (yalnız bu 0-sonuç yolunda\n // +1 tur, NFR-A2). Exact-önce korunur: eşleşme varken trgm hiç koşmaz.\n // İfade, Go tarafının türev trgm index'iyle BİREBİR aynı (sorted\n // kolonlar) — index'i o ifade yakalar.\n const tsch = await trgmSchemaOf(live);\n const expr = ftsExprOf(cfg.ftsCols);\n const trgmKw =\n `SELECT t.${quoteIdent(cfg.pk)} AS id, ROW_NUMBER() OVER (ORDER BY ${quoteIdent(tsch)}.word_similarity(${qpRef}, ${expr}) DESC) AS r ` +\n `FROM ${quoteTable(table)} t WHERE ${quoteIdent(tsch)}.word_similarity(${qpRef}, ${expr}) > 0.3${whereSql} ORDER BY r LIMIT ${pool}`;\n // trgm kelime-benzerliği OR-sözdizimi tanımaz: retry aynı placeholder'ı\n // HAM query ile koşar (bind kopyası — kayıtlı ilk çağrı değişmez).\n const retryBind = bind.slice();\n if (qpIdx >= 0) retryBind[qpIdx] = params.query;\n rows = (await live.unsafe(assemble(trgmKw, false), retryBind)) as Row[];\n }\n for (const r of rows) delete (r as Record<string, unknown>)._kwn;\n // FR-015: dönüş tipi iki modda aynı şekildedir — satır-modunda blok\n // kavramı yoktur, tip uyumu boş diziyle sağlanır (spec kararı).\n const out = asTableRows(table, rows).map((r) => ({ ...r, blocks: [] as unknown[] }));\n logNoResults(table, params.query, params.mode, out.length);\n return out;\n },\n\n /**\n * similar (T018, FR-022): \"bu satıra benzeyenler\". Hedef vektör DB'den\n * okunur — satır-modu satırın kendi kolonu, chunk-modu parent chunk'larının\n * şema-nitelikli avg'ı — ve ana arama search'ün vector yoluyla koşar;\n * kaynak satır sonuçtan düşer. İKİ tur BİLİNÇLİ (plan T018): target-CTE'li\n * tek SQL'de \"id yok\" ile \"0 komşu\" ayrılamazdı; +1 küçük turla id-yokluğu\n * adlandırılmış hataya çevrilir. Sonuç şekli search ile aynı (FR-015).\n */\n /** D-021 (FR-027 DX): sayaçlar BAĞIMSIZ op'la — search'ün dizi-üstü\n * `_facets` özelliği JSON.stringify'da kaybolur (dizi özelliği), tenant\n * yanıtına koyunca sessizce yok olurdu. Ayrı dönüş ciddi bir sözleşmedir;\n * search'teki alan geriye-uyum için DURUR. where + validity default'u\n * sayaçlara da uygulanır (sayaç, kullanıcının gördüğü kümeyi anlatır). */\n async facets(\n table: string,\n params: { facets: string[]; where?: Record<string, unknown>; validity?: \"all\" | { asOf: string } },\n ): Promise<Record<string, { value: string | null; count: number }[]>> {\n const cfg = searchConfigFor(table);\n if (!cfg) {\n throw new Error(`facets(${table}): tablo aranabilir değil — search beyanı yok (FR-027)`);\n }\n for (const col of params.facets) {\n if (!cfg.colSet.has(col)) {\n throw new Error(`facets(${table}): facets kolonu \"${col}\" tabloda yok (FR-027)`);\n }\n }\n const live = await at();\n const extra = cfg.validity ? (add: (v: unknown) => string) => validitySql(params.validity, add) : () => \"\";\n return fetchFacets(live, table, cfg.colSet, params.facets, params.where ?? {}, extra);\n },\n\n async similar(\n table: string,\n id: string,\n opts: {\n where?: Record<string, unknown>;\n limit?: number;\n using?: string;\n minScore?: number;\n recency?: { field: string; halfLife: string };\n blocksPerRow?: number;\n validity?: \"all\" | { asOf: string };\n boost?: { field: string; weight: number };\n } = {},\n ): Promise<Row[]> {\n const cfg = searchConfigFor(table);\n if (!cfg) {\n throw new Error(`similar(${table}): tablo aranabilir değil — ne vector kolonu ne search beyanı var (FR-013)`);\n }\n const live = await at();\n let v: unknown;\n if (cfg.chunk !== undefined) {\n const sch = await vectorSchemaWithGuc(live);\n const rows = (await live.unsafe(\n `SELECT ${quoteIdent(sch)}.avg(c.embedding) AS v FROM ${quoteTable(cfg.chunk.table)} c ` +\n `WHERE c.${quoteIdent(`parent_${cfg.pk}`)} = $1 AND c.embedding IS NOT NULL`,\n [id],\n )) as { v?: unknown }[];\n v = rows?.[0]?.v;\n } else {\n const leg = pickLeg(table, cfg.legs, opts.using);\n if (leg === null) {\n throw new Error(`similar(${table}): tabloda vektör kolonu yok — benzerlik semantik vektör ister (FR-022)`);\n }\n const rows = (await live.unsafe(\n `SELECT t.${quoteIdent(leg.column)} AS v FROM ${quoteTable(table)} t WHERE t.${quoteIdent(cfg.pk)} = $1`,\n [id],\n )) as { v?: unknown }[];\n v = rows?.[0]?.v;\n }\n // Sürücü vector'ü text literal'i olarak verir (C-9); yokluk = satır yok\n // YA DA embedding NULL — ikisi de aynı adlandırılmış hata.\n if (typeof v !== \"string\") {\n throw new Error(`similar(${table}): id \"${String(id)}\" bulunamadı ya da embedding'i yok (FR-022)`);\n }\n const p = {\n vector: JSON.parse(v) as number[],\n mode: \"vector\" as const,\n where: opts.where,\n limit: opts.limit,\n using: opts.using,\n minScore: opts.minScore,\n recency: opts.recency,\n blocksPerRow: opts.blocksPerRow,\n validity: opts.validity,\n boost: opts.boost,\n __excludeIds: [id],\n };\n return ops.search(table, p);\n },\n\n /**\n * recommend (T018, FR-023): positive/negative id kümelerinden öneri.\n * Hedef vektör DB-İÇİ CTE'lerle türer: pos = avg(embedding of positives),\n * negative varsa hedef = pos.v + (pos.v - neg.v) — pgvector avg agregası\n * ve +/- operatörleri ŞEMA-NİTELİKLİ (M-1: search_path'e güvenilmez).\n * Vektör matematiği istemciye inmez; bulunamayan positive/negative\n * adlandırılmış hatadır ve kaynak id'ler sonuçtan düşer.\n */\n async recommend(\n table: string,\n opts: {\n positive: unknown[];\n negative?: unknown[];\n where?: Record<string, unknown>;\n limit?: number;\n using?: string;\n minScore?: number;\n recency?: { field: string; halfLife: string };\n blocksPerRow?: number;\n validity?: \"all\" | { asOf: string };\n boost?: { field: string; weight: number };\n },\n ): Promise<Row[]> {\n const positive = opts?.positive;\n if (!Array.isArray(positive) || positive.length === 0) {\n throw new Error(`recommend(${table}): positive boş olamaz — en az bir kaynak id gerekir (FR-023)`);\n }\n const negative = Array.isArray(opts.negative) ? opts.negative : [];\n const cfg = searchConfigFor(table);\n if (!cfg) {\n throw new Error(`recommend(${table}): tablo aranabilir değil — ne vector kolonu ne search beyanı var (FR-013)`);\n }\n let leg: SearchLeg | null = null;\n if (cfg.chunk === undefined) {\n leg = pickLeg(table, cfg.legs, opts.using);\n if (leg === null) {\n throw new Error(`recommend(${table}): tabloda vektör kolonu yok — öneri semantik vektör ister (FR-023)`);\n }\n }\n const live = await at();\n const sch = await vectorSchemaWithGuc(live);\n const bind: unknown[] = [];\n const add = (x: unknown): string => {\n bind.push(x);\n return `$${bind.length}`;\n };\n // id listesi AYRI placeholder'larla (where.in ile aynı gerekçe).\n const avgSel = (ids: unknown[]): string => {\n const inList = ids.map((x) => add(x)).join(\", \");\n return cfg.chunk !== undefined\n ? `SELECT ${quoteIdent(sch)}.avg(c.embedding) AS v FROM ${quoteTable(cfg.chunk.table)} c ` +\n `WHERE c.${quoteIdent(`parent_${cfg.pk}`)} IN (${inList}) AND c.embedding IS NOT NULL`\n : `SELECT ${quoteIdent(sch)}.avg(t.${quoteIdent(leg!.column)}) AS v FROM ${quoteTable(table)} t ` +\n `WHERE t.${quoteIdent(cfg.pk)} IN (${inList}) AND t.${quoteIdent(leg!.column)} IS NOT NULL`;\n };\n // pos/neg yokluğu bayrak olarak AYNI sorgudan döner: aritmetik DB'de\n // kalır, hata ayrımı için ek tur gerekmez.\n const targetSql =\n negative.length === 0\n ? `WITH pos AS (${avgSel(positive)}) SELECT pos.v AS v, (pos.v IS NULL) AS pos_missing FROM pos`\n : `WITH pos AS (${avgSel(positive)}), neg AS (${avgSel(negative)}) ` +\n `SELECT (pos.v OPERATOR(${quoteIdent(sch)}.+) (pos.v OPERATOR(${quoteIdent(sch)}.-) neg.v)) AS v, ` +\n `(pos.v IS NULL) AS pos_missing, (neg.v IS NULL) AS neg_missing FROM pos, neg`;\n const rows = (await live.unsafe(targetSql, bind)) as\n { v?: unknown; pos_missing?: unknown; neg_missing?: unknown }[];\n const r0 = rows?.[0];\n if (r0 === undefined || r0.pos_missing === true) {\n throw new Error(`recommend(${table}): positive id'lerin hiçbiri bulunamadı ya da embedding'i yok (FR-023)`);\n }\n if (negative.length > 0 && r0.neg_missing === true) {\n throw new Error(`recommend(${table}): negative id'leri bulunamadı ya da embedding'i yok (FR-023)`);\n }\n if (typeof r0.v !== \"string\") {\n throw new Error(`recommend(${table}): hedef vektör hesaplanamadı (FR-023)`);\n }\n const p = {\n vector: JSON.parse(r0.v) as number[],\n mode: \"vector\" as const,\n where: opts.where,\n limit: opts.limit,\n using: opts.using,\n minScore: opts.minScore,\n recency: opts.recency,\n blocksPerRow: opts.blocksPerRow,\n validity: opts.validity,\n boost: opts.boost,\n __excludeIds: [...positive, ...negative],\n };\n return ops.search(table, p);\n },\n\n /**\n * supersede (T021, FR-029, C-9): validity'li tabloda satırın YENİ\n * versiyonunu TEK savepoint'te yazar — eski satır kapatılır\n * (valid_to = now(), superseded_by = yeni pk), yeni satır eklenir, dönüş\n * yeni satırdır. Yeni pk CLIENT'ta üretilir (row'da verilmemişse\n * randomUUID — declared şemaların uuid().defaultRandom() standardı) ki\n * kapatma UPDATE'i INSERT'ten ÖNCE koşabilsin: 0 satır = zaten superseded\n * ya da yok → INSERT hiç denenmez; INSERT hatası ise savepoint'le\n * kapatmayı da geri sarar — yarım supersede diye bir durum yoktur.\n */\n async supersede(table: string, id: string, row: Row): Promise<Row> {\n // `supersede` eski satırın `valid_to`/`superseded_by` alanlarını YAZAR —\n // yani append-only bir tabloda yasak olan şeyin ta kendisi.\n assertNotAppendOnly(\"supersede\", table);\n const cfg = searchConfigFor(table);\n if (cfg === null || cfg.validity !== true) {\n throw new Error(`supersede(${table}): tablo validity beyanı taşımıyor (FR-029)`);\n }\n const live = await at();\n return live.savepoint(async (sp) => {\n const newId = row[cfg.pk] ?? crypto.randomUUID();\n const closed = (await sp.unsafe(\n `UPDATE ${quoteTable(table)} SET \"valid_to\" = now(), \"superseded_by\" = $1 ` +\n `WHERE ${quoteIdent(cfg.pk)} = $2 AND \"valid_to\" IS NULL RETURNING ${quoteIdent(cfg.pk)}`,\n [newId, id],\n )) as Row[];\n if (closed.length === 0) {\n throw new Error(`supersede(${table}): id \"${String(id)}\" zaten superseded ya da yok (FR-029)`);\n }\n const data = { ...row, [cfg.pk]: newId };\n const cols = Object.keys(data);\n const params: unknown[] = [];\n const add = (v: unknown): string => `$${params.push(v)}`;\n const tuple = buildValueTuple(table, cols, data, add, \"supersede\");\n const rows = (await sp.unsafe(\n `INSERT INTO ${quoteTable(table)} (${cols.map(quoteIdent).join(\", \")}) ` +\n `VALUES (${tuple}) RETURNING ${rowProjection(table)}`,\n params,\n )) as Row[];\n if (!rows[0]) {\n throw new Error(\n `supersede(${table}): INSERT satır döndürmedi — yazma reddedildi (büyük olasılıkla bir RLS policy'si)`,\n );\n }\n return asTableRow(table, rows[0]);\n });\n },\n\n /** A real SAVEPOINT inside the request's transaction. */\n async transaction<T>(cb: (t: unknown) => Promise<T>): Promise<T> {\n const live = await at();\n return live.savepoint(async (sp) => cb(withTables(createOps(sp, context), currentSchema)));\n },\n\n /**\n * Run `fn` against a handle bound to a SAVEPOINT, so a failure inside it\n * rolls back only what that handle wrote and the request can keep writing.\n *\n * WHY THE HANDLE IS AN ARGUMENT. The obvious shape — `attempt(async () => {\n * ... Database.$insert(...) ... })`, with no parameter — would have to point\n * the ambient `Database` at the savepoint for the duration, and a request is\n * concurrent with itself: `Promise.all([Database.$insert(a),\n * Database.$attempt(...)])` would put `a` inside the savepoint and roll it\n * back with it. Silent data loss, and the same interleaving this file already\n * refuses for `asService()`. Passing the handle makes the boundary something\n * you can see in the code that crosses it.\n *\n * Postgres, not us: the savepoint is released on success and rolled back on\n * failure by the driver, so an aborted statement inside `fn` does not poison\n * the surrounding transaction.\n */\n async attempt<T>(fn: (tx: DBOps) => Promise<T>): Promise<T> {\n const live = await at();\n return live.savepoint(async (sp) => fn(withTables(createOps(sp, context), currentSchema) as DBOps));\n },\n\n /**\n * Execute a whole transaction plan — what `Database.$transaction(fn)` builds.\n *\n * WHY IT RUNS HERE. The platform used to carry a complete implementation\n * of this at `/internal-api/db/tx`, for tenant code that ran in an isolate\n * with no connection of its own. Running the plan there means running it on\n * a DIFFERENT connection: a transaction would not see the uncommitted\n * writes of the request that started it, and the two would hold separate\n * RLS bindings of the same identity. In this stack the tenant's code and\n * the connection share a process, so the plan runs on the request's own\n * transaction inside one SAVEPOINT — and that surface was removed on\n * 2026-08-15, once this was the last thing that could have called it.\n *\n * Until 2026-08-15 it ran NOWHERE: `runTxPlan` called `transport.txPlan` and\n * nothing here implemented it, so a live handler answered\n * \"transport.txPlan is not a function\" while every test that covered\n * transactions passed against a mock that did implement it.\n */\n async command(plan: TxPlanBody, options: CommandOptions = {}): Promise<TxPlanResponse> {\n if (options.mode !== undefined && ![\"auto\", \"compiled\", \"sequential\"].includes(options.mode)) throw new Error(\"command mode must be auto, compiled or sequential\");\n if (options.mode === \"sequential\") return ops.txPlan(plan);\n const compiled = context.commands ? compileCommand(plan) : { reason: \"the PostgreSQL command executor is not installed\" };\n if (\"reason\" in compiled) {\n if (options.mode === \"compiled\") throw new Error(`Command cannot compile: ${compiled.reason}. Use auto/sequential mode or installCommandExecutor at boot.`);\n return ops.txPlan(plan);\n }\n if (compiled.steps.length === 0 && !compiled.pipeline?.length) return { results: [] };\n if (compiled.pipeline) {\n return (await at()).savepoint(async sp => {\n // One connection preserves statement order and fresh statement\n // snapshots. A SQL guard aborts PostgreSQL before queued writes can\n // run. Drain EVERY query before ROLLBACK TO / connection reuse.\n const settled = await Promise.allSettled(compiled.pipeline!.map(statement => sp.unsafe(statement.sql, statement.params)));\n const failed = settled.find(result => result.status === \"rejected\");\n if (failed?.status === \"rejected\") {\n const error = failed.reason as { detail?: string };\n if (sqlstateOf(error) === SQLSTATE.commandGuardFailed && typeof error.detail === \"string\") {\n const detail = JSON.parse(error.detail) as { error_code?: string; slot?: number };\n if (detail.error_code === \"tx_guard_failed\" && Number.isInteger(detail.slot)) {\n throw Object.assign(new Error(\"Command expectation failed\"), detail);\n }\n }\n throw error;\n }\n return { results: settled.map((result, i) => {\n const rows = (result as PromiseFulfilledResult<{ rows: Row[] }[]>).value[0]!.rows;\n return { rows: asTableRows(plan.ops[i]!.table, rows), rows_affected: rows.length };\n }) };\n });\n }\n // Keep the request usable after a constraint error or timeout, just as\n // txPlan does. PostgreSQL errors retain the driver's diagnostics.\n const rows = await (await at()).savepoint(sp => sp.unsafe(\"SELECT palbase_runtime.command_v1($1::jsonb -> 'steps') AS result\", [{ steps: compiled.steps }])) as { result: TxPlanResponse & { error?: Record<string, unknown> } }[];\n const response = rows[0]!.result;\n if (response.error) throw Object.assign(new Error(response.error.error_code === \"tx_ref_unresolved\"\n ? \"Command reference has no source row/column; use expectOne before reading it\" : \"Command expectation failed\"), response.error);\n return { results: response.results.map((result, i) => ({ ...result, rows: asTableRows(plan.ops[i]!.table, result.rows) })) };\n },\n\n async txPlan(plan: TxPlanBody): Promise<TxPlanResponse> {\n const live = await at();\n // ONE savepoint for the whole plan: a failed expectation must undo the\n // transaction the author wrote, and nothing outside it.\n return live.savepoint(async (sp) => {\n const results: TxPlanOpResult[] = [];\n for (const op of plan.ops) {\n const rows = asTableRows(op.table, await runPlanOp(sp, op, results)) as typeof results[number][\"rows\"];\n const result: TxPlanOpResult = { rows, rows_affected: rows.length };\n results.push(result);\n assertGuard(op, result);\n }\n return { results };\n });\n },\n } satisfies DBOps & Record<string, unknown>;\n\n return ops;\n}\n\n/** The schema whose table names the typed `.tables` surface is built from —\n * and, per table, whose columns the vector transform reads. */\nlet currentSchema: {\n tables?: Record<string, { name?: string; columns?: Record<string, unknown>; policies?: PolicyDef[] }>;\n} = {};\n\nconst columnsMemo: SchemaMetadataCache<Set<string> | null> = new WeakMap();\nconst primaryMemo: SchemaMetadataCache<string | null> = new WeakMap();\nconst vectorMemo: SchemaMetadataCache<Set<string>> = new WeakMap();\nconst transformMemo: SchemaMetadataCache<ReturnType<typeof computeTransforms>> = new WeakMap();\nconst typeMemo: SchemaMetadataCache<Map<string, string | null>> = new WeakMap();\nconst timestampMemo: SchemaMetadataCache<boolean> = new WeakMap();\nconst projectionMemo: SchemaMetadataCache<Map<string, string>> = new WeakMap();\n\nfunction schemaColumns(table: string): Set<string> | null {\n return memoTable(columnsMemo, currentSchema, table, () => computeSchemaColumns(table));\n}\nfunction primaryKeyOf(table: string): string | null {\n return memoTable(primaryMemo, currentSchema, table, () => computePrimaryKey(table));\n}\nfunction vectorColumnsOf(schema: typeof currentSchema, table: string): Set<string> {\n return memoTable(vectorMemo, schema, table, () => computeVectorColumns(schema, table));\n}\nfunction transformsOf(schema: typeof currentSchema, table: string): ReturnType<typeof computeTransforms> {\n return memoTable(transformMemo, schema, table, () => computeTransforms(schema, table));\n}\nfunction columnTypeOf(table: string, col: string): string | null {\n const types = memoTable(typeMemo, currentSchema, table, () => new Map(\n [...schemaColumns(table) ?? []].map(c => [c, computeColumnType(table, c)]),\n ));\n return types.get(col) ?? null;\n}\n\n/**\n * Install the project's declarations. Called once at boot.\n *\n * It takes the SET, because a project declares one schema PER FILE. The tables\n * are flattened under this system's one key convention — `public` bare,\n * anything else `schema.table` — so the key the wire carries and the key the\n * runtime looks up are the same string. A second convention here would be a\n * second answer to \"which table is this\", and the answers would diverge on the\n * day one of them learned something.\n */\n/**\n * İlişki grafiği — `buildRelations`'ın TEK çıktısı, burada yeniden türetilmiyor.\n *\n * `buildRelations`'ın kendi yorumu tüketicilerini adlandırıyor: *\"the query\n * builder, the seed engine, the cross-boundary lock\"*. Sorgu derleyicisi o\n * listedeydi ve hiç bağlanmamıştı — yani her projenin `palbase-env.d.ts`'i\n * \"bu tablo şununla ilişkili\" diye bir vaat basıyor ve hiçbir okuma onu\n * kullanmıyordu. `has` o vaadi karşılıyor.\n *\n * Grafiği BURADA yeniden hesaplamak ikinci bir yorumcu olurdu ve aynı yorum onu\n * adıyla yasaklıyor; o yüzden `setSchema` `buildRelations`'ı çağırıp sonucu\n * saklıyor.\n */\nlet currentRelations: Map<string, Relation[]> = new Map();\n\nexport function setSchema(schemas: readonly unknown[]): void {\n // Yeni şema kurulumu yeni bir bağlanma demektir: vector extension'ının\n // şeması da yeniden çözülür (review I3 — iki DB'li süreçte bayat cache,\n // public↔extensions ikiliğini sessizce yanlış tarafa kilitlerdi).\n const tables: NonNullable<typeof currentSchema.tables> = Object.create(null);\n for (const entry of schemas) {\n const mod = entry as { default?: unknown } | undefined;\n const def = ((mod && \"default\" in mod ? mod.default : mod) ?? {}) as {\n name?: string;\n tables?: Record<string, { name?: string; columns?: Record<string, unknown> }>;\n };\n const schemaName = def.name ?? \"public\";\n for (const [key, table] of Object.entries(def.tables ?? {})) {\n tables[qualifiedTableKey(schemaName, table.name ?? key)] = table;\n }\n }\n // İlişki grafiği AYNI bildirimlerden, AYNI yazıcıyla. Bir bildirim hatalıysa\n // (iki `ownedByUser`, çakışan ilişki adı) `buildRelations` ADIYLA fırlatıyor;\n // şema kurulumunu o hatayla düşürmek doğru — yarım bir grafik, `has`'in\n // sessizce hiçbir satır döndürmesi demek olurdu.\n //\n // GİRDİ NORMALLEŞTİRİLİYOR ama HATA YUTULMUYOR. `setSchema` elle kurulmuş,\n // yarım şema nesneleriyle de çağrılabiliyor (testler, ve tablo adıyla\n // erişilen bildirilmemiş tablolar) — `tables`/`columns` eksik olabilir.\n // Eksik alanı boşa çevirmek \"ilişki yok\" demek, doğru. Ama bildirimin KENDİ\n // hatasını (iki `ownedByUser`, çakışan ilişki adı) yakalayıp yutmak yarım bir\n // grafik bırakırdı ve `has` sessizce hiçbir satır döndürürdü — o yüzden\n // try/catch YOK.\n const relations = buildRelations(\n schemas.map((entry) => {\n const mod = entry as { default?: unknown } | undefined;\n const def = ((mod && \"default\" in mod ? mod.default : mod) ?? {}) as Partial<SchemaDef>;\n const tables: Record<string, unknown> = Object.create(null);\n for (const [key, t] of Object.entries(def.tables ?? {})) {\n const table = (t ?? {}) as { name?: string; columns?: Record<string, unknown> };\n // Kolonlar da normalleştiriliyor: elle kurulmuş bir şemada bir kolon\n // düz `{}` olabiliyor ve `buildRelations` her kolonda `_def` bekliyor.\n // Boş bir `_def` \"bu kolonun yabancı anahtarı yok\" demek — doğru cevap.\n const columns: Record<string, unknown> = {};\n for (const [cname, c] of Object.entries(table.columns ?? {})) {\n const cd = (c ?? {}) as { _def?: unknown };\n columns[cname] = \"_def\" in cd ? cd : { ...cd, _def: cd };\n }\n tables[key] = { ...table, name: table.name ?? key, columns };\n }\n return { name: def.name ?? \"public\", tables } as unknown as SchemaDef;\n }),\n );\n // Install only after the complete declaration/relationship graph validates.\n for (const key of Object.keys(tables)) tables[key] = snapshotDeclaration(tables[key]!);\n currentSchema = Object.freeze({ tables: Object.freeze(tables) });\n currentRelations = relations;\n cachedVectorSchema = null;\n cachedTrgmSchema = null;\n}\n\n\n\n/**\n * Merge the typed `.tables` accessor onto a raw op surface.\n *\n * Mirrors what the pod runtime does, including the recursive application to the\n * transaction callback: without it `tx.tables.rooms.insert(...)` throws\n * \"Cannot read properties of undefined\".\n */\nconst tableNamespaces = new WeakMap<object, Map<string, Map<string, string>>>();\n\nexport function withTables<T extends ReturnType<typeof createOps>>(\n ops: T,\n schema: { tables?: Record<string, { name?: string }> } = currentSchema,\n): T & { tables: Record<string, unknown>; schema: (name: string) => { tables: Record<string, unknown> } } {\n let namespaces = tableNamespaces.get(schema);\n if (!namespaces) {\n namespaces = new Map();\n for (const key of Object.keys(schema.tables ?? {})) {\n const dot = key.indexOf(\".\");\n const name = dot === -1 ? \"public\" : key.slice(0, dot);\n const short = dot === -1 ? key : key.slice(dot + 1);\n if (!namespaces.has(name)) namespaces.set(name, new Map());\n namespaces.get(name)!.set(short, key);\n }\n if (Object.isFrozen(schema) && Object.isFrozen(schema.tables)) tableNamespaces.set(schema, namespaces);\n }\n // THE KEY IS WHAT TRAVELS, not `def.name`. A bare name cannot say which\n // schema it lives in, and two schemas may declare the same table name —\n // `public.invoices` and `billing.invoices` are different tables.\n const bind = (key: string): Record<string, unknown> => ({\n insert: (data: Row) => ops.insert(key, data),\n update: (id: string, data: Row) => ops.update(key, id, data),\n delete: (id: string) => ops.delete(key, id),\n findById: (id: string) => ops.findById(key, id),\n findUnique: (where: Row, opts?: { select?: readonly string[]; with?: Record<string, unknown> }) => ops.findUnique(key, where, opts),\n findMany: (query?: Row, opts?: FindManyOptions) => ops.findMany(key, query ?? {}, opts),\n page: (query?: Row, opts?: RawPageOptions) => ops.page(key, query ?? {}, opts),\n put: (q: { data: Row; onConflict: readonly string[] }) => ops.put(key, q.data, { onConflict: q.onConflict }),\n });\n\n // `Database.tables` is PUBLIC's, and only public's. One flat namespace would\n // make `tables.invoices` resolve by declaration order; the bare name is\n // always public's and everything else is asked for by schema.\n const surfaces = new Map<string, { tables: Record<string, unknown> }>();\n const schemaOf = (name: string): { tables: Record<string, unknown> } => {\n const cached = surfaces.get(name);\n if (cached) return cached;\n const names = namespaces!.get(name) ?? new Map<string, string>();\n const target: Record<string, unknown> = Object.create(null);\n const get = (key: string): unknown => {\n if (!Object.hasOwn(target, key) && names.has(key)) {\n Object.defineProperty(target, key, { value: bind(names.get(key)!), configurable: true, enumerable: true, writable: true });\n }\n return Reflect.get(target, key);\n };\n const tables = new Proxy(target, {\n get: (t, key, receiver) => typeof key === \"string\" ? get(key) : Reflect.get(t, key, receiver),\n has: (t, key) => (typeof key === \"string\" && names.has(key)) || Reflect.has(t, key),\n ownKeys: t => [...new Set([...names.keys(), ...Reflect.ownKeys(t)])],\n getOwnPropertyDescriptor: (t, key) => Reflect.getOwnPropertyDescriptor(t, key) ??\n (typeof key === \"string\" && names.has(key) ? { configurable: true, enumerable: true, get: () => get(key) } : undefined),\n preventExtensions: t => {\n for (const key of names.keys()) get(key);\n return Reflect.preventExtensions(t);\n },\n });\n const surface = { tables };\n // Arbitrary unknown schema names must not accumulate per request.\n if (namespaces!.has(name) || name === \"public\") surfaces.set(name, surface);\n return surface;\n };\n\n const base: Record<string, unknown> = Object.create(null);\n return Object.assign(base, ops, { tables: schemaOf(\"public\").tables, schema: schemaOf });\n}\n\n// ── the two identities one request may speak with ──────────────────────────\n\n/**\n * How long a statement on the SERVICE transaction may wait for a row lock.\n *\n * The bound exists because `asService()` runs in a SECOND transaction on a\n * SECOND connection (see {@link createRequestDatabase} for why it must). A\n * handler that writes a row through `Database.*` and then touches the same row\n * through `Database.$asService()` is waiting on a lock held by a transaction\n * that cannot commit until the handler returns — a wait that can never end.\n * Unbounded, that hangs the request AND holds two pool connections for as long\n * as the process lives; a few of those and the runtime stops answering at all.\n *\n * 5s, from the two numbers around it: a healthy contended write resolves in\n * milliseconds, and the edge cuts a tenant request at 60s\n * (v2/deploy/envoy/routes.yaml, the catch-all route).\n * So the failure arrives as a legible error at the caller instead of a 504 with\n * both connections still held.\n */\nconst SERVICE_LOCK_TIMEOUT = \"5s\";\n\n/** Postgres raises 25P02 for every statement after one failed inside the same\n * transaction: `current transaction is aborted, commands ignored until end of\n * transaction block`. True, and useless on its own — it names the SYMPTOM and\n * never the write that caused it, nor the fact that a request is one\n * transaction. */\nfunction isAbortedTransaction(e: unknown): boolean {\n const message = String((e as { message?: unknown } | null)?.message ?? \"\");\n return sqlstateOf(e) === \"25P02\" || /current transaction is aborted/i.test(message);\n}\n\n/**\n * The five-character SQLSTATE, wherever this driver put it.\n *\n * MEASURED, not assumed (local stack, real Postgres, 2026-08-30): Bun's\n * `PostgresError` puts its OWN code in `.code` — the string\n * `\"ERR_POSTGRES_SERVER_ERROR\"` — and the SQLSTATE in `.errno`. node-postgres\n * puts the SQLSTATE in `.code`. Every check below was written against `.code`\n * alone, and its unit test built an object shaped like node-postgres, so the\n * tests were green and NONE of these diagnostics ever fired in production.\n *\n * The shape decides: a SQLSTATE is five characters of [0-9A-Z]. Anything else\n * in `.code` is the driver naming its own error, and the answer is in `.errno`.\n */\n/**\n * A bulk write must carry an actual predicate.\n *\n * COUNTING THE FILTER'S KEYS IS NOT ENOUGH, and the gap was measured: an\n * operator object with no operators in it — `{ created_at: {} }` — has one key\n * and compiles to NOTHING, so `WHERE true` reached Postgres and the statement\n * became a whole-table write. The shape that produces it is ordinary:\n *\n * const where = { created_at: {} };\n * if (from) where.created_at.gte = from; // neither set on this request\n * if (to) where.created_at.lte = to;\n *\n * So the check reads what the COMPILER produced, not what the caller passed.\n */\nfunction assertHasPredicate(whereSql: string, op: string, table: string): void {\n if (whereSql.trim().length > 0) return;\n throw new Error(\n `${op}(${table}): the filter compiled to no condition, so this would have ` +\n `written EVERY row. An empty filter — or an operator object with no ` +\n `operators in it, like { col: {} } — is refused. Name a condition.`,\n );\n}\n\nfunction sqlstateOf(e: unknown): string | undefined {\n const err = e as { code?: unknown; errno?: unknown } | null;\n const isState = (v: unknown): v is string => typeof v === \"string\" && /^[0-9A-Z]{5}$/.test(v);\n if (isState(err?.code)) return err.code;\n if (isState(err?.errno)) return err.errno;\n if (typeof err?.errno === \"number\") {\n const asText = String(err.errno);\n if (isState(asText)) return asText;\n }\n return undefined;\n}\n\n/** Postgres raises 23503 when a foreign key has nothing to point at. */\nfunction isForeignKeyViolation(e: unknown): boolean {\n return sqlstateOf(e) === \"23503\";\n}\n\n/**\n * Postgres raises 23505 (unique_violation) when a write would duplicate a row.\n *\n * İKİ ŞEKLİ DE tanır, ve bu bir tercih değil zorunluluk: `wrapTx` her ifadeyi\n * `explain()`'den geçirip 23505'i `UniqueViolation`'a ÇEVİRİYOR (aşağıda), ve\n * `HttpError`'ın `code` alanı yok — dolayısıyla dönüşmüş hatada `sqlstateOf`\n * hiçbir zaman eşleşmiyordu. Ölçüldü (nihai inceleme C-1): üretim\n * kablolamasında `claim()`'in catch'i `{ inserted: false }` yerine 409\n * fırlatıyordu, yani FR-033'ün tamamı ölüydü. Testler kaçırdı çünkü ham bir\n * stand-in tx kurup `wrapTx`'i atlıyorlardı.\n */\nfunction isUniqueViolation(e: unknown): boolean {\n return sqlstateOf(e) === \"23505\" || UniqueViolation.is(e);\n}\n\n/**\n * The name of the unique constraint a 23505 names.\n *\n * The driver's own `constraint` field first — both pg and postgres.js copy it\n * straight out of the wire protocol's CONSTRAINT field, so it is the answer\n * whenever there is one. The message is the fallback, and the reason it is only\n * a fallback: it is prose, and prose is what this whole conversion exists to\n * stop anyone from matching on.\n *\n * \"\" when neither carries it. An empty name is the honest answer — the caller\n * sees it is not known — and it is still a typed 409, because whether the write\n * was a duplicate does not depend on knowing which constraint said so.\n */\nfunction constraintOf(e: unknown): string {\n const named = (e as { constraint?: unknown } | null)?.constraint;\n if (typeof named === \"string\" && named.length > 0) return named;\n const message = String((e as { message?: unknown } | null)?.message ?? \"\");\n return /violates unique constraint \"([^\"]+)\"/.exec(message)?.[1] ?? \"\";\n}\n\n/** Postgres raises 55P03 (lock_not_available) when `lock_timeout` fires. */\nfunction isLockTimeout(e: unknown): boolean {\n const message = String((e as { message?: unknown } | null)?.message ?? \"\");\n return sqlstateOf(e) === \"55P03\" || /lock timeout/i.test(message);\n}\n\n/**\n * Wrap a driver so a lock timeout says what actually happened.\n *\n * \"canceling statement due to lock timeout\" is true and useless: the author's\n * two surfaces are two transactions, which is the one thing the message cannot\n * tell them. Applied recursively through `savepoint`, so `transaction()` and\n * `txPlan` inside the service surface answer the same way.\n */\nfunction diagnosingDriver(sql: SqlDriver, surface: \"user\" | \"service\" = \"service\"): SqlDriver {\n const original = (e: unknown): string => String((e as { message?: unknown } | null)?.message ?? e);\n\n const explain = (e: unknown): unknown => {\n // A statement refused because an EARLIER one failed. The database names the\n // symptom; only this layer knows that a request is a single transaction and\n // that there is a way to keep writing.\n if (isAbortedTransaction(e)) {\n return new Error(\n \"This request cannot write any more: an earlier write in it failed, and a request runs in ONE \" +\n \"Postgres transaction, so every statement after the failure is refused. Nothing here is \" +\n \"retryable in place. Wrap a write you expect to fail in `Database.$attempt(async (tx) => …)` — \" +\n \"it takes a SAVEPOINT, so only that write rolls back — or use \" +\n \"`Database.public.<t>.upsert(data, { onConflict: [...] })` when the failure you were bracing \" +\n `for is a duplicate row. (${original(e)})`,\n );\n }\n // A duplicate row is the one database refusal an application ROUTINELY\n // expects, and until this branch existed the only way to act on it was to\n // match the driver's prose (\"duplicate key value violates unique\n // constraint …\") — a contract nobody signed, broken by a Postgres upgrade,\n // a locale, or a constraint rename, silently and in production. Typed here\n // instead: an HttpError, so an uncaught duplicate answers a generic 409\n // rather than 500 `internal_error`, and a caught one is branched on with\n // `e instanceof UniqueViolation && e.constraint === …`. The NAME rides the\n // object, not the response body — see `UniqueViolation` for whose it is.\n // Both surfaces convert: a duplicate is a duplicate whichever role wrote it.\n if (isUniqueViolation(e)) {\n return markEngineRaised(new UniqueViolation(constraintOf(e)));\n }\n // Eşzamanlılık hataları (FR-036). Aynı gerekçe: sürücünün düzyazısını\n // eşleştirmek imzalanmamış bir sözleşme. Buradaki fark, bu ikisinin\n // TEKRAR DENENEBİLİR olması — ve bunun tipte taşınması, retry sarmalayıcısının\n // neyi yeniden deneyeceğini TAHMİN etmemesini sağlıyor.\n const state = sqlstateOf(e);\n if (state === SQLSTATE.serializationFailure) return markEngineRaised(new SerializationFailure(state));\n if (state === SQLSTATE.deadlockDetected) return markEngineRaised(new DeadlockDetected(state));\n // PostgreSQL's statement timeout can beat the JS deadline timer. Both\n // races must remain an observable cancellation, never a generic 500 or an\n // automatic replay. SQLSTATE also covers operator-initiated cancellation.\n if (state === SQLSTATE.queryCancelled) return markEngineRaised(new HttpError(503, \"database_query_cancelled\", \"Database statement was cancelled\"));\n // A foreign key with nothing to point at, seen from the SERVICE surface, is\n // usually not a broken key: it is the row this request already wrote through\n // `Database.*`, which has not committed and which the service transaction\n // cannot see. On the user surface the same code is an ordinary data error and\n // is left exactly as Postgres wrote it.\n if (surface === \"service\" && isForeignKeyViolation(e)) {\n return new Error(\n \"Database.$asService() hit a foreign key with nothing to point at. It runs in its OWN \" +\n \"transaction on its OWN connection, so a row this request wrote through `Database.*` is not \" +\n \"visible to it until the request commits — and the request cannot commit until the handler \" +\n \"returns. If the row it needs is one this request just created, do both writes on ONE \" +\n `surface. (${original(e)})`,\n );\n }\n if (isLockTimeout(e)) {\n return new Error(\n \"Database.$asService() waited too long for a row lock. It runs in its OWN transaction, so a \" +\n \"row this request already wrote through Database.* is locked against it until the request \" +\n \"commits — a wait that cannot end. Do that row's work on one surface or the other. \" +\n `(${original(e)})`,\n );\n }\n return e;\n };\n\n const wrapTx = (tx: SqlTx): SqlTx => ({\n unsafe(text: string, params?: unknown[]) {\n try {\n const query = tx.unsafe(text, params) as CancellableQuery;\n const mapped = query.catch(e => { throw explain(e); }) as CancellableQuery;\n if (query.cancel) mapped.cancel = () => query.cancel!();\n return mapped;\n } catch (e) {\n return Promise.reject(explain(e));\n }\n },\n savepoint<T>(cb: (sp: SqlTx) => Promise<T>) {\n return tx.savepoint((sp) => cb(wrapTx(sp)));\n },\n });\n\n return {\n admission: sql.admission ?? databaseAdmission(sql),\n unsafe: (text: string, params?: unknown[]) => sql.unsafe(text, params),\n cancelBackend: sql.cancelBackend?.bind(sql),\n begin: <T>(cb: (tx: SqlTx) => Promise<T>) => sql.begin((tx) => cb(wrapTx(tx))).catch((e: unknown) => { throw explain(e); }),\n };\n}\n\n/** The two transactions a request may hold, and the single `Database` over them. */\nexport interface RequestDatabase {\n /** What the engine injects as the request's `Database` singleton. */\n readonly client: DBClient;\n /** @internal Core has finished its read-only authorization queries. */\n authorizationComplete?(): void;\n /** Commit whatever was opened. Called once, after the handler returns. */\n commit(): Promise<void>;\n /** Roll back whatever was opened. Called once, when the handler throws. */\n rollback(reason: unknown): Promise<void>;\n}\n\n/**\n * The `Database` one request sees: RLS-enforced by default, with the\n * service-role sibling behind `asService()`.\n *\n * # Why the sibling cannot ride the request's own transaction\n *\n * The role reaches Postgres ONCE, in the BEGIN's bind statement, and it is\n * transaction-scoped. So a sibling built on the same transaction runs as\n * `backend_authenticated` no matter what it is called — RLS still filters every\n * row and `asService()` silently means nothing. That is the failure mode worth\n * naming: it does not throw, it does not log, it simply returns the caller's own\n * rows where the author asked for everyone's, and a handler that trusts it\n * (`if (existing) throw new Conflict()`) makes the wrong decision on data it was\n * never shown.\n *\n * The obvious repair — re-issue `set_config('role', …)` around each service op\n * — is worse than the bug. Two statements are not one: `Promise.all([\n * Database.$query(…), Database.$asService().$query(…) ])` interleaves them on the\n * single connection, and the user's query can execute between the service's\n * set-role and its own statement. That is RLS silently OFF on the DEFAULT path,\n * which is precisely the direction a security seam must never fail.\n *\n * So the service surface gets its own transaction, on its own connection, bound\n * to the service role at BEGIN. The identity separation is physical: no\n * statement of either surface can change what the other runs as.\n *\n * # What that costs, stated plainly\n *\n * - **One extra connection per request that uses it**, and only then: the second\n * transaction is lazy exactly like the first, so `asService()` called and\n * never used opens nothing.\n * - **Called twice, it is the same surface** — one transaction per REQUEST, not\n * per call — so a handler cannot leak connections by reaching for it in a\n * loop.\n * - **The two are not atomic with each other.** Both settle with the request\n * (commit when the handler returns, roll back when it throws), but they settle\n * as two transactions: if the second COMMIT fails, the first has already\n * landed. The request's own work commits first, so the failure that survives\n * is never \"the audit row exists and the thing it audits does not\".\n * - **They can wait on each other's locks.** Bounded in the service direction by\n * {@link SERVICE_LOCK_TIMEOUT}; in the other direction — a `Database.*` write\n * to a row `asService()` has already written — the wait is the request's own,\n * and the answer is not to write one row from both surfaces.\n *\n * # Claims travel unchanged\n *\n * The service transaction carries the SAME `request.jwt.claims` as the user's.\n * `asService()` changes what the caller may TOUCH, not who they are, so\n * `auth.uid()` still resolves inside a trigger or a column default. It is also\n * the fail-closed direction: a service role provisioned WITHOUT `BYPASSRLS`\n * (measured live on 2026-08-13, created by hand during a diagnosis) is not named\n * by any policy, so it reads zero rows instead of quietly reading everyone's.\n */\nexport function createRequestDatabase(\n sql: SqlDriver,\n identity: { role: string; serviceRole: string; claimsJson: string },\n diagnostics?: DatabaseDiagnosticsOptions,\n signal?: AbortSignal,\n): RequestDatabase {\n const trace = diagnostics === undefined ? undefined : new DatabaseTrace(diagnostics);\n const requestControl = signal === undefined ? undefined : new TransactionControl(undefined, signal);\n let requestClosed = false;\n let authorized = false, applicationTouched = false;\n let authorizationRelease: Promise<void> | undefined;\n const contextFor = (role: string): OpsContext => {\n let scope: string | undefined;\n return { trace, get cursorScope() { return scope ??= cursorIdentity(role, identity.claimsJson); }, get commands() { return hasCommandExecutor(sql); } };\n };\n const userContext = contextFor(identity.role);\n const serviceContext = contextFor(identity.serviceRole);\n const atomic = (role: string, surface: \"user\" | \"service\") => async <T>(\n fn: (client: AtomicClient) => Promise<T>, options: AtomicOptions = {},\n ): Promise<T> => {\n validateAtomicOptions(options);\n if (requestClosed) throw new Error(\"Database request has settled; it cannot open another transaction\");\n if (atomicScope.getStore() !== undefined) throw new Error(\"Nested Database.$atomic is not supported; use tx.$attempt for a savepoint\");\n // @User/permission checks may have opened the implicit request transaction.\n // If no application SQL has run, release those read-only core checks before\n // waiting for an independent atomic connection. Otherwise a full pool can\n // consist entirely of requests waiting for a second connection.\n if (authorized && !applicationTouched && tx.opened) {\n authorizationRelease ??= (async () => { await tx.commit(); tx = requestTransaction(); })();\n }\n if (authorizationRelease) await authorizationRelease;\n const retries = retryBudget(options.retry);\n const atomicSignal = options.signal && signal ? AbortSignal.any([options.signal, signal]) : options.signal ?? signal;\n const control = options.timeoutMs !== undefined || atomicSignal !== undefined ? new TransactionControl(options.timeoutMs, atomicSignal) : undefined;\n try {\n control?.check();\n for (let attempt = 0; ; attempt++) {\n control?.check();\n const timeouts = [options.statementTimeoutMs, control?.remainingMs()].filter((n): n is number => n !== undefined);\n const scope = Symbol(\"atomic transaction\");\n const root = createLazyTransaction(diagnosingDriver(sql, surface), role, identity.claimsJson, {\n scope, isolation: options.isolation, readOnly: options.readOnly, control, trace,\n lockTimeout: `${options.lockTimeoutMs ?? 5000}ms`,\n statementTimeout: timeouts.length === 0 ? undefined : `${Math.min(...timeouts)}ms`,\n });\n try {\n const callback = atomicScope.run(scope, () => fn(withTables(createOps(root, surface === \"user\" ? userContext : serviceContext))));\n const value = await (control ? control.race(callback) : callback);\n control?.check();\n await root.commit();\n return value;\n } catch (error) {\n await root.rollback(error);\n if (attempt >= retries || !isRetryable(error)) throw error;\n trace?.retry();\n const delay = new Promise<void>((resolve) => setTimeout(resolve, Math.min(100, 2 ** attempt)));\n await (control ? control.race(delay) : delay);\n }\n }\n } finally {\n control?.dispose();\n }\n };\n const requestTransaction = () => createLazyTransaction(diagnosingDriver(sql, \"user\"), identity.role, identity.claimsJson, { trace, control: requestControl });\n let tx = requestTransaction();\n\n // Opened on FIRST use and shared by every later `asService()` call.\n let serviceTx: LazyTransaction | null = null;\n let serviceControl: TransactionControl | undefined;\n let serviceClient: Omit<DBClient, \"asService\"> | null = null;\n\n const asService = (): Omit<DBClient, \"asService\"> => {\n if (serviceClient === null) {\n serviceControl = signal === undefined ? undefined : new TransactionControl(undefined, signal);\n serviceTx = createLazyTransaction(\n diagnosingDriver(sql, \"service\"),\n identity.serviceRole,\n identity.claimsJson,\n { lockTimeout: SERVICE_LOCK_TIMEOUT, trace, control: serviceControl },\n );\n // No `asService` on it: the type says `Omit<DBClient, \"asService\">` and so\n // does the object, so a second bypass is neither typeable nor callable.\n serviceClient = Object.assign(withTables(createOps(serviceTx, serviceContext)), { atomic: atomic(identity.serviceRole, \"service\") });\n }\n return serviceClient;\n };\n\n return {\n client: Object.assign(withTables(createOps(() => {\n if (authorized) applicationTouched = true;\n return authorizationRelease ? authorizationRelease.then(() => tx) : tx;\n }, userContext)), { asService, atomic: atomic(identity.role, \"user\") }),\n authorizationComplete() { authorized = true; },\n async commit(): Promise<void> {\n requestClosed = true;\n // The request's declared work first; see \"not atomic with each other\".\n try { await tx.commit(); await serviceTx?.commit(); trace?.complete(\"committed\"); requestControl?.dispose(); serviceControl?.dispose(); }\n catch (error) { trace?.failed(); throw error; }\n },\n async rollback(reason: unknown): Promise<void> {\n requestClosed = true;\n await tx.rollback(reason);\n await serviceTx?.rollback(reason);\n requestControl?.dispose();\n serviceControl?.dispose();\n trace?.complete(\"failed\");\n },\n };\n}\n\n\n// ── the transaction plan executor ──────────────────────────────────────────\n//\n// The plan is a closed little language: five op kinds, equality-only filters,\n// and three value forms (a literal, a `$ref` to an earlier op's row, an\n// `$expr`). It is built by `TxPlanBuilder` in this same package, so the\n// executor's job is to run it faithfully rather than to defend against it —\n// with one exception that still matters: identifiers reach SQL as text, so\n// every table and column name goes through `quoteIdent`, exactly as the six\n// single-statement ops above do.\n\n/** Collects bound parameters so a value is never spliced into SQL text. */\nclass Args {\n readonly values: unknown[] = [];\n readonly columns: { column?: string; table?: string }[] = [];\n bind(value: unknown, column?: string, table?: string): string {\n this.values.push(value);\n this.columns.push({ column, table });\n return `$${this.values.length}`;\n }\n}\n\n/**\n * Plan referansı mı — ŞEKLE değil MARKAYA bakarak.\n *\n * `\"$ref\" in v` yeterliydi ve `$ref` bu dilin markasız kalan TEK işaretçisiydi.\n * Ölçüldü (gözcü): istek gövdesinden gelen `{\"id\":{\"$ref\":{\"op\":0,\"field\":\"id\"}}}`\n * filtreyi ÖNCEKİ bir işlemin satır değeriyle karşılaştırtıyordu — gövdenin hiç\n * görmediği bir değer. Enjeksiyon değil (değerler bound) ama bir ORACLE:\n * `op`/`field` seçip `rows_affected`'tan o değeri öğrenmek. `col()` ve\n * `sqlFragment` aynı sebeple markalanmıştı; bu üçüncüsü.\n */\nfunction isRef(v: unknown): v is TxWireRef {\n return isPlanRef(v);\n}\n\n/**\n * Çözülemeyen bir referansın mesajı — ve İKİ AYRI DURUMU ayırıyor.\n *\n * Eskiden ikisi de `op 7 has no column \"id\" to reference` diyordu, 7 numaralı\n * işlem HİÇ YOKKEN bile. Yazar var olmayan bir op'un kolonlarını aramaya\n * gidiyordu (gözcü M-2). Komşu mesajlar tabloyu adlandırırken bu adlandırmıyordu\n * da.\n */\nfunction refUnresolvedMessage(\n ref: { op: number; field: string },\n results: TxPlanOpResult[],\n): string {\n if (ref.op < 0 || ref.op >= results.length) {\n return (\n `transaction plan: referans ${ref.op} numaralı işleme bakıyor ama planda ` +\n `${results.length} işlem var (0…${results.length - 1}). Referans yalnız KENDİNDEN ` +\n `ÖNCEKİ bir işlemin satırına bakabilir.`\n );\n }\n const row = results[ref.op]?.rows[0];\n if (!row) {\n return (\n `transaction plan: ${ref.op} numaralı işlem HİÇ SATIR döndürmedi, o yüzden ` +\n `\"${ref.field}\" okunamıyor. Bir referans okunacak satırın var olduğunu garanti ` +\n `etmez — önce beklentiyi bildirin (\\`.expectOne(err)\\`).`\n );\n }\n return (\n `transaction plan: ${ref.op} numaralı işlemin satırında \"${ref.field}\" kolonu yok ` +\n `(dönen kolonlar: ${Object.keys(row).join(\", \")}).`\n );\n}\n\n/** Markasız bir `{ $ref: … }` taklidi ADIYLA reddedilir — sessizce DEĞER olarak\n * bağlanması, filtrenin sessizce yanlış olması demekti. */\nfunction refuseUnbrandedRef(v: unknown, where: string): void {\n if (looksLikeUnbrandedPlanRef(v)) {\n throw new Error(\n `${where}: bir plan referansı TAKLİDİ aldı ({ $ref: … }) — bu nesne bu planın ` +\n `builder'ı tarafından üretilmemiş. Referans yalnız kendi kodunuzda, önceki bir ` +\n `işlemin satırından okunarak kurulur (ör. insert(...).expectOne(err).id); ` +\n `istek gövdesinden gelen bir filtre referans TAŞIYAMAZ.`,\n );\n }\n}\nfunction isExpr(v: unknown): v is TxWireExpr {\n return typeof v === \"object\" && v !== null && \"$expr\" in v;\n}\n\n/**\n * Render one value into SQL, binding whatever is data.\n *\n * `column` is only used by `inc`/`dec`, which read the column they write.\n */\nfunction renderValue(\n value: TxWireValue,\n column: string,\n args: Args,\n results: TxPlanOpResult[],\n vectorCols?: Set<string>,\n transforms?: ReturnType<typeof transformsOf>,\n): string {\n // DEĞER tarafında da marka aranıyor, ve burada bahis daha yüksek: sahte bir\n // referans filtreyi yanıltmakla kalmaz, BAŞKA BİR SATIRIN değerini yazdırır.\n refuseUnbrandedRef(value, `transaction plan (${column})`);\n if (isRef(value)) {\n const source = results[value.$ref.op];\n const row = source?.rows[0];\n if (!row || !(value.$ref.field in row)) {\n throw Object.assign(new Error(refUnresolvedMessage(value.$ref, results)), {\n error_code: \"tx_ref_unresolved\",\n });\n }\n return bindMaybeVector(args, column, vectorCols, row[value.$ref.field], transforms);\n }\n if (isExpr(value)) {\n const fn = value.$expr;\n if (fn.fn === \"now\") return \"now()\";\n const operator = fn.fn === \"inc\" ? \"+\" : \"-\";\n // The column is an identifier; the operand is BOUND. This is the one place\n // the tenant's digits could otherwise have reached SQL text.\n return `${quoteIdent(column)} ${operator} ${bindMaybeVector(args, column, vectorCols, fn.by, transforms)}`;\n }\n return bindMaybeVector(args, column, vectorCols, value, transforms);\n}\n\n/**\n * Resolve every `$ref` handle inside a plan filter, in place-free fashion.\n *\n * Refs point at a column of an EARLIER operation's returned row. They have to\n * become ordinary values BEFORE the filter is compiled, because the compiler\n * below is the SAME one `findMany` uses and it knows nothing about plans — and\n * that sameness is the whole point (see {@link renderWhere}).\n *\n * Recursive, because the filter language has composition: a ref can sit inside\n * `OR`/`AND`/`NOT` or on the right of an operator.\n */\nfunction resolveRefsDeep(value: unknown, results: TxPlanOpResult[]): unknown {\n refuseUnbrandedRef(value, \"transaction plan filtresi\");\n if (isRef(value)) {\n const source = results[value.$ref.op];\n const row = source?.rows[0];\n if (!row || !(value.$ref.field in row)) {\n throw Object.assign(\n new Error(refUnresolvedMessage(value.$ref, results)),\n { error_code: \"tx_ref_unresolved\" },\n );\n }\n return row[value.$ref.field];\n }\n if (Array.isArray(value)) return value.map((v) => resolveRefsDeep(v, results));\n // İşaretçiler ve ifade tutamakları OLDUĞU GİBİ geçer: `col()` bir kolon\n // referansı, `sqlFragment` bir parça, ve derleyici ikisini de kendi tanıyor.\n if (value !== null && typeof value === \"object\" && !isColRef(value) && !isSqlFragment(value) && !isExpr(value) && !(value instanceof Date)) {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n out[k] = resolveRefsDeep(v, results);\n }\n return out;\n }\n return value;\n}\n\n/**\n * Render a plan operation's WHERE clause — with `findMany`'s COMPILER.\n *\n * BU FONKSİYON BİR ZAMANLAR KENDİ DERLEYİCİSİYDİ, ve ayrı olması iki şeye mal\n * oluyordu:\n *\n * 1. SESSİZ YANLIŞ SORGU. `{ balance: { gte: \"5.00\" } }` nesnenin KENDİSİNİ\n * parametre olarak bağlıyordu — `WHERE \"balance\" = $1`, `$1={\"gte\":…}` —\n * yani hiçbir satır, hatasız (gözcü ölçtü).\n * 2. İKİ FİLTRE DİLİ. FR-014'ün amiral deseni `$transaction` İÇİNDE\n * yazılamıyordu: koşullu bir yazmayı plana koyamayan yazar `$query`'ye\n * düşüyordu — tam olarak bu yüzeyin kapatmak için var olduğu düşüş.\n *\n * Artık TEK derleyici var. Plan ifadeleri `t` takma adını taşıyor (aşağıdaki\n * `AS t` / `FROM … t`), çünkü `compileWhereBare` her kolonu onunla niteliyor —\n * `findMany`'nin ürettiği SQL'le aynı şekli üretmek, aynı derleyiciyi\n * kullanmanın bedeli değil, ispatı.\n */\nfunction renderWhere(\n table: string,\n where: Record<string, TxWireValue> | undefined,\n args: Args,\n results: TxPlanOpResult[],\n): string {\n return planWhere(table, where, args, results).sql;\n}\n\n/** {@link renderWhere}'in ÇÖZÜLMÜŞ filtreyi de veren hâli — kilit sırası kararı\n * (FR-015) `$ref`'ler çözüldükten SONRAKİ şekle bakmak zorunda. */\nfunction planWhere(\n table: string,\n where: Record<string, TxWireValue> | undefined,\n args: Args,\n results: TxPlanOpResult[],\n): { sql: string; resolved: Record<string, unknown> } {\n if (where === undefined || Object.keys(where).length === 0) {\n return { sql: \"\", resolved: {} };\n }\n const resolved = resolveRefsDeep(where, results) as Record<string, unknown>;\n const known = schemaColumns(table);\n const bare = compileWhereBare(table, known, resolved, (v, column, from) => args.bind(v, column, from), \"transaction plan\");\n return { sql: bare === \"\" ? \"\" : ` AND ${bare}`, resolved };\n}\n\n/** tx-plan bind'i (FR-008, review C2): vektör kolonuna giden number[] literal'e\n * çevrilir — düz op'lardaki asBindParams'ın plan-yolu ikizi. */\nfunction bindMaybeVector(\n args: { bind(v: unknown, column?: string): string },\n column: string | undefined,\n vectorCols: Set<string> | undefined,\n value: unknown,\n transforms?: ReturnType<typeof transformsOf>,\n): string {\n if (column !== undefined && vectorCols?.has(column) && Array.isArray(value)) {\n return args.bind(toVectorLiteral(value as number[]), column);\n }\n // The column's `toDb`, exactly as `asBindParams` applies it on the direct\n // path. Without it the SAME value is stored differently depending on which\n // surface wrote it — `tables.x.insert({ amount: 12.5 })` writes \"12.5\" and\n // `tx.tables.x.insert({ amount: 12.5 })` writes 12.5 — and the caller cannot\n // tell them apart, because both take the transform's target type.\n const t = column !== undefined ? transforms?.get(column) : undefined;\n if (t?.toDb !== undefined && value !== null && value !== undefined) {\n return args.bind(t.toDb(value), column);\n }\n return args.bind(value, column);\n}\n\nfunction compilePlanOp(\n op: TxWireOp,\n results: TxPlanOpResult[],\n): { sql: string; params: unknown[]; columns: { column?: string; table?: string }[] } | null {\n const opVectorCols = vectorColumnsOf(currentSchema, op.table);\n const opTransforms = transformsOf(currentSchema, op.table);\n const args = new Args();\n // `quoteTable`, `quoteIdent` DEĞİL — ve fark bu yolda ÖLÇÜLDÜ:\n // `quoteIdent(\"billing.invoices\")` → `\"billing.invoices\"`, yani ADINDA NOKTA\n // OLAN bir public tablo. Postgres'in anladığı şey o değil. Sonuç: `billing`\n // şemasındaki iki tabloyu tek atomik planda yazmak imkânsızdı ve yazar\n // `$query`'ye düşüyordu — bu yüzeyin kapatmak için var olduğu düşüş.\n // Doğrudan yolun her operasyonu zaten `quoteTable` kullanıyor; plan yolu\n // ondan ayrışmıştı.\n const table = quoteTable(op.table);\n let sql: string;\n\n switch (op.op) {\n case \"insert\": {\n const cols = Object.keys(op.values ?? {});\n const rendered = cols.map((c) => renderValue((op.values as Record<string, TxWireValue>)[c], c, args, results, opVectorCols, opTransforms));\n sql = cols.length\n ? `INSERT INTO ${table} (${cols.map(quoteIdent).join(\", \")}) VALUES (${rendered.join(\", \")}) RETURNING ${rowProjection(op.table)}`\n : `INSERT INTO ${table} DEFAULT VALUES RETURNING ${rowProjection(op.table)}`;\n break;\n }\n case \"upsert\": {\n // `put` bir UPDATE dalı taşıyor — append-only tabloda yasak.\n assertNotAppendOnly(\"put\", op.table);\n const cols = Object.keys(op.values ?? {});\n const conflict = op.onConflict ?? [];\n if (cols.length === 0 || conflict.length === 0) {\n throw Object.assign(new Error(`upsert on ${op.table} needs columns and onConflict`), {\n error_code: \"tx_bad_upsert\",\n });\n }\n const rendered = cols.map((c) =>\n renderValue((op.values as Record<string, TxWireValue>)[c], c, args, results, opVectorCols, opTransforms),\n );\n sql =\n `INSERT INTO ${table} (${cols.map(quoteIdent).join(\", \")}) VALUES (${rendered.join(\", \")}) ` +\n `${onConflictTail(cols, conflict, \"update\")} RETURNING ${rowProjection(op.table)}`;\n break;\n }\n case \"insertMany\": {\n const rows = (op.rows ?? []) as Record<string, TxWireValue>[];\n if (rows.length === 0 || !rows[0]) return null;\n // The column list comes from the FIRST row and every row is rendered\n // against it, so a row with a stray extra key cannot shift the columns of\n // the statement it shares.\n const cols = Object.keys(rows[0]);\n const tuples = rows.map(\n (r) => `(${cols.map((c) => renderValue(r[c], c, args, results, opVectorCols, opTransforms)).join(\", \")})`,\n );\n // ON CONFLICT only when the plan asked for it: an insertMany with no\n // options must render byte-identically to what it rendered before the\n // option existed.\n //\n // DO NOTHING and RETURNING: Postgres returns only the rows it WROTE, so a\n // collided row is simply absent from the result. That is the contract the\n // caller is told about, not a rough edge.\n const conflictCols = op.onConflict ?? [];\n const tail =\n op.action !== undefined && conflictCols.length > 0\n ? ` ${onConflictTail(cols, conflictCols, op.action)}`\n : \"\";\n sql = `INSERT INTO ${table} (${cols.map(quoteIdent).join(\", \")}) VALUES ${tuples.join(\", \")}${tail} RETURNING ${rowProjection(op.table)}`;\n break;\n }\n case \"update\": {\n // Tip kapısı `TxTable`'a uygulanmıyor, motor da bu dalda susuyordu:\n // `tx.tables.entries.updateWhere({id}, {amount:\"0\"})` derleniyor VE\n // koşuyordu (inceleme C-4). Muhasebe kaydında \"TypeScript'ten\n // yazılamaz\" yeterli değil.\n assertNotAppendOnly(\"updateWhere\", op.table);\n const cols = Object.keys(op.set ?? {});\n if (cols.length === 0) throw new Error(`update ${op.table}: nothing to set`);\n const knownSet = schemaColumns(op.table);\n for (const c of cols) {\n if (knownSet !== null && !knownSet.has(c)) {\n throw new Error(`transaction plan (${op.table}): set kolonu \"${c}\" tabloda yok`);\n }\n }\n const assignments = cols.map(\n (c) => `${quoteIdent(c)} = ${renderValue((op.set as Record<string, TxWireValue>)[c], c, args, results, opVectorCols, opTransforms)}`,\n );\n // KİLİT SIRASI PLAN YOLUNDA DA (FR-015).\n //\n // `updateMany` çok satıra dokunduğunda kilitleri PK sırasında alsın diye\n // CTE'ye derleniyor; gerekçesi DOĞRUDAN yolda ölçülmüştü (T013: ters\n // sıralı iki oturumda düz form 12/12 deadlock, CTE 0/12). Plan yolu aynı\n // işi yapıyor ama düz UPDATE üretiyordu.\n //\n // BOŞLUK BU FİLTRE GENİŞLEMESİNDEN ÖNCE DE VARDI: eski `TxWhere` de\n // eşitliği HERHANGİ bir kolonda kabul ediyordu (`updateWhere({ done:\n // false }, …)` benzersiz olmayan bir kolon, yani çok satır) ve o günkü\n // `runPlanOp`'ta da CTE yoktu. Genişleme sınıfı YARATMADI, SIKLIĞINI\n // artırdı: FR-014'ün amiral deseni korumasız yolda idiomatik hâle geldi.\n //\n // VE BU YOLDA DEADLOCK ÜRETİLDİ — çıkarım değil (gözcü, canlı pg16,\n // 30 satırlık tablo, iki oturum ters plan sırasına zorlanmış, satır\n // başına 10 ms uyku ile kilit penceresi açılmış, deadlock_timeout 100ms):\n // (A) düz UPDATE … WHERE balance >= … → 7 deadlock / 100 transaction\n // (B) WITH locked … ORDER BY id FOR NO KEY UPDATE → 0 / 120\n // (B)'de tek bir hata bile yok; oturumlar deadlock yerine SIRAYA giriyor.\n // Bedeli bekleme, ve bu kabul edilmiş takas.\n //\n // Karar ÇÖZÜLMÜŞ filtreye bakıyor: `{ id: <ref> }` çözüldükten sonra tek\n // PK eşitliğidir ve CTE'ye gerek yoktur; çözülmeden bakılsaydı bir ref\n // \"nesne\" görünüp gereksiz CTE kurdururdu.\n const planned = planWhere(op.table, op.where, args, results);\n const planPk = primaryKeyOf(op.table);\n sql = isSinglePkEquality(planned.resolved, planPk) || planPk === null\n ? `UPDATE ${table} AS t SET ${assignments.join(\", \")} WHERE true${planned.sql} RETURNING ${rowProjection(op.table, \"t\")}`\n : `WITH locked AS (SELECT t.${quoteIdent(planPk)} AS \"__pb_lock\" FROM ${table} t WHERE true${planned.sql} ` +\n `ORDER BY t.${quoteIdent(planPk)} FOR NO KEY UPDATE) ` +\n `UPDATE ${table} AS t SET ${assignments.join(\", \")} FROM locked ` +\n `WHERE t.${quoteIdent(planPk)} = locked.\"__pb_lock\" RETURNING ${rowProjection(op.table, \"t\")}`;\n break;\n }\n case \"delete\": {\n assertNotAppendOnly(\"deleteWhere\", op.table);\n sql = `DELETE FROM ${table} AS t WHERE true${renderWhere(op.table, op.where, args, results)} RETURNING ${rowProjection(op.table, \"t\")}`;\n break;\n }\n case \"select\": {\n // `Number(op.limit)` NaN üretebiliyordu ve `LIMIT NaN` sözdizimi hatası.\n // Sayı değilse ADIYLA reddet.\n let limit = \"\";\n if (op.limit !== undefined) {\n const n = Number(op.limit);\n if (!Number.isInteger(n) || n < 0) {\n throw new Error(`transaction plan (${op.table}): limit bir tam sayı olmalı, \"${String(op.limit)}\" alındı`);\n }\n limit = ` LIMIT ${n}`;\n }\n const lock = op.lock === \"update\" ? \" FOR UPDATE\" : \"\";\n sql = `SELECT ${rowProjection(op.table, \"t\")} FROM ${table} t WHERE true${renderWhere(op.table, op.where, args, results)}${limit}${lock}`;\n break;\n }\n default:\n // Loudly, rather than rendering something for an op nobody wrote.\n throw new Error(`unknown operation \"${String((op as { op: string }).op)}\" in a transaction plan`);\n }\n\n return { sql, params: args.values, columns: args.columns };\n}\n\nasync function runPlanOp(sp: SqlTx, op: TxWireOp, results: TxPlanOpResult[]): Promise<Row[]> {\n const statement = compilePlanOp(op, results);\n return statement ? await sp.unsafe(statement.sql, statement.params) as Row[] : [];\n}\n\n/** Reuse the sequential plan's SQL compiler. Symbolic preceding rows let that\n * compiler resolve branded refs into parameter slots without touching the DB.\n * JavaScript codecs and raw SQL fragments deliberately use the existing path. */\nfunction compileCommand(plan: TxPlanBody): { steps: CompiledStep[]; pipeline?: { sql: string; params: unknown[] }[] } | { reason: string } {\n const symbols = new Map<string, CommandBinding>();\n const results: TxPlanOpResult[] = [];\n const steps: (CompiledStep & { sql?: string })[] = [];\n const pipeline: { sql: string; params: unknown[] }[] = [];\n let hasRefs = false;\n const prefix = `command:${crypto.randomUUID()}:`;\n const containsFragment = (v: unknown): boolean => isSqlFragment(v) ||\n (v !== null && typeof v === \"object\" && Object.values(v).some(containsFragment));\n const hasNullableFilterRef = (v: unknown): boolean => {\n if (isRef(v)) {\n const source = plan.ops[v.$ref.op];\n return source !== undefined && pageSchema(source.table).columns[v.$ref.field]?.nullable !== false;\n }\n return v !== null && typeof v === \"object\" && Object.values(v).some(hasNullableFilterRef);\n };\n // Eligibility is checked for the WHOLE plan before any statement executes.\n for (const op of plan.ops) {\n if (!schemaColumns(op.table)?.size) return { reason: `table ${op.table} has no installed declaration` };\n if (transformsOf(currentSchema, op.table).size || vectorColumnsOf(currentSchema, op.table).size) return { reason: `${op.table} uses JavaScript codecs/transforms or vector values` };\n if (containsFragment(op)) return { reason: \"SQL fragments require the sequential path\" };\n // Resolving a nullable ref can change '= $n' into 'IS NULL'. The sequential\n // compiler makes that choice after reading the row; this subset cannot.\n if (hasNullableFilterRef(op.where)) return { reason: \"nullable references in filters require the sequential path\" };\n }\n for (const [index, op] of plan.ops.entries()) {\n const statement = compilePlanOp(op, results);\n if (statement === null) {\n steps.push({ empty: true, guard: op.guard });\n pipeline.push({ sql: \"SELECT palbase_runtime.command_rows_v1('[]'::jsonb,$1::jsonb) AS rows\", params: [op.guard ?? null] });\n }\n else {\n if (statement.params.some(v => v === undefined || typeof v === \"symbol\" || typeof v === \"function\" ||\n (typeof v === \"number\" && (!Number.isInteger(v) || v < -2147483648 || v > 2147483647)))) {\n return { reason: \"non-integer/wide numeric or non-JSON parameters require the sequential driver path; use exact decimal strings\" };\n }\n // Bun binds numbers/booleans with scalar protocol types even when the\n // target is JSONB. Keep that driver behavior on the sequential path.\n // A JSONB ref can contain any scalar, so it is also outside this subset.\n for (const [i, value] of statement.params.entries()) {\n const target = statement.columns[i]!;\n if (target.column === undefined || columnTypeOf(target.table ?? op.table, target.column) !== \"jsonb\") continue;\n const source = typeof value === \"string\" ? symbols.get(value) : undefined;\n if (typeof value === \"number\" || typeof value === \"boolean\" || typeof value === \"bigint\" ||\n (source && \"ref\" in source && ![\"text\", \"uuid\", \"timestamp\", \"enum\"].includes(columnTypeOf(plan.ops[source.ref.op]!.table, source.ref.field) ?? \"\"))) {\n return { reason: \"JSONB scalar/ref binding requires the sequential driver path\" };\n }\n }\n const wide = [...schemaColumns(op.table)!].filter(c => [\"bigint\", \"numeric\"].includes(columnTypeOf(op.table, c) ?? \"\"));\n const exact = wide.length ? ` || jsonb_build_object(${wide.map(c => `${quoteLiteral(c)}, r.${quoteIdent(c)}::text`).join(\", \")})` : \"\";\n const sql = `WITH command_rows AS (${statement.sql}) SELECT coalesce(jsonb_agg(to_jsonb(r)${exact}), '[]'::jsonb) FROM command_rows r`;\n pipeline.push({\n sql: `WITH command_rows AS (${statement.sql}) SELECT palbase_runtime.command_rows_v1(coalesce(jsonb_agg(to_jsonb(r)${exact}), '[]'::jsonb),$${statement.params.length + 1}::jsonb) AS rows FROM command_rows r`,\n params: [...statement.params, op.guard ?? null],\n });\n const bindings: CommandBinding[] = statement.params.map((value, i) => {\n const target = statement.columns[i]!;\n const json = target.column !== undefined && columnTypeOf(target.table ?? op.table, target.column) === \"jsonb\";\n if (typeof value === \"string\" && symbols.has(value)) { hasRefs = true; return { ...symbols.get(value)!, json }; }\n if (typeof value === \"bigint\") return { value: value.toString(), json };\n if (value instanceof Date) return { value: value.toISOString(), json };\n return { value, json };\n });\n steps.push({ sql, bindings, guard: op.guard });\n }\n const row: Row = {};\n for (const field of schemaColumns(op.table)!) {\n const token = `${prefix}${index}:${field}`;\n symbols.set(token, { ref: { op: index, field } }); row[field] = token;\n }\n results.push({ rows: [row], rows_affected: 1 });\n }\n // Independent statements use the parameterized driver pipeline. Tokenizing\n // them for command_v1 built a second, unused representation on every call.\n // Only a plan whose statements reference preceding rows needs those chunks.\n if (!hasRefs) return { steps: [], pipeline };\n return { steps: steps.map(({ sql, ...step }) => sql === undefined\n ? step : { ...step, chunks: parameterChunks(sql) }) };\n}\n\n/**\n * Enforce the author's declared expectation.\n *\n * The Error the author passed never travels: the plan carries a SLOT index and\n * the SDK maps it back. So a failure here throws the shape `runTxPlan` knows —\n * `{error_code: \"tx_guard_failed\", slot}` — and the savepoint unwinds.\n */\nfunction assertGuard(op: TxWireOp, result: TxPlanOpResult): void {\n const guard = op.guard;\n if (!guard) return;\n const n = result.rows.length;\n const ok =\n guard.kind === \"one\"\n ? n === 1\n : guard.kind === \"none\"\n ? n === 0\n : guard.kind === \"atLeast\"\n ? n >= guard.n\n : n <= guard.n;\n if (ok) return;\n throw Object.assign(new Error(`transaction expectation failed: ${guard.kind} (${n} row(s))`), {\n error_code: \"tx_guard_failed\",\n slot: guard.slot,\n });\n}\n","/** Metadata is scoped to an installed schema snapshot, never to row values. */\nexport type SchemaMetadataCache<T> = WeakMap<object, Map<string, T>>;\n\nexport function memoTable<T>(\n cache: SchemaMetadataCache<T>, schema: { tables?: Record<string, unknown> },\n table: string, compute: () => T,\n): T {\n // Dynamic/unknown table names must not grow a process-wide cache.\n if (!schema.tables || !Object.hasOwn(schema.tables, table)) return compute();\n let tables = cache.get(schema);\n if (!tables) { tables = new Map(); cache.set(schema, tables); }\n if (!tables.has(table)) tables.set(table, compute());\n return tables.get(table) as T;\n}\n\n/** Clone before freezing: authors may reuse/extend their declarations and\n * reinstall them, while a live compiled schema remains stable. Functions retain\n * their identity so custom column codecs continue to execute normally. */\nexport function snapshotDeclaration<T>(value: T, seen = new WeakMap<object, object>()): T {\n if (value === null || typeof value !== \"object\") return value;\n const previous = seen.get(value);\n if (previous) return previous as T;\n if (value instanceof Date) return new Date(value.getTime()) as T;\n const result = Array.isArray(value) ? [] : Object.create(Object.getPrototypeOf(value));\n seen.set(value, result);\n for (const key of Reflect.ownKeys(value)) {\n if (Array.isArray(value) && key === \"length\") continue;\n const descriptor = Object.getOwnPropertyDescriptor(value, key)!;\n if (\"value\" in descriptor) descriptor.value = snapshotDeclaration(descriptor.value, seen);\n Object.defineProperty(result, key, descriptor);\n }\n return Object.freeze(result) as T;\n}\n","import { createCipheriv, createDecipheriv, createHash, randomBytes } from \"node:crypto\";\nimport { BadRequest } from \"../errors.js\";\nimport type { RawPageOptions } from \"../db/page.js\";\n\nlet key: Buffer | null = null;\nconst invalidPage = (message: string, field = \"page\") => new BadRequest({ fields: [{ field, message }] }, message);\n\n/** One application secret shared by replicas. Rotation invalidates old cursors.\n * Encryption also hides sort values omitted by the public projection. */\nexport function setCursorKey(secret: string | null): void {\n key = secret ? createHash(\"sha256\").update(\"palbase:cursor:v1\\0\").update(secret).digest() : null;\n}\n\nexport function cursorKey(): Buffer {\n if (!key) throw new Error(\"Database.page needs PALBASE_CURSOR_SECRET or PALBASE_SERVICE_ROLE_KEY shared by all replicas\");\n return key;\n}\n\n/** Stable across object property order, BigInt inputs and refreshed JWTs. */\nexport function fingerprint(value: unknown): string {\n const stable = (v: unknown): unknown => {\n if (typeof v === \"bigint\") return { $bigint: v.toString() };\n if (v instanceof Date) return { $date: v.toISOString() };\n if (Array.isArray(v)) return v.map(stable);\n if (v && typeof v === \"object\") {\n return Object.fromEntries(Object.keys(v).sort().map(k => [k, stable((v as Record<string, unknown>)[k])]));\n }\n return v;\n };\n return createHash(\"sha256\").update(JSON.stringify(stable(value))).digest(\"base64url\");\n}\n\nexport function cursorIdentity(role: string, claimsJson: string): string {\n const claims = JSON.parse(claimsJson) as Record<string, unknown>;\n const { iat, exp, nbf, jti, ...authorization } = claims;\n return fingerprint({ role, authorization });\n}\n\nexport function encodeCursor(secret: Buffer, scope: string, values: (string | null)[]): string {\n const nonce = randomBytes(12);\n const cipher = createCipheriv(\"aes-256-gcm\", secret, nonce);\n cipher.setAAD(Buffer.from(scope));\n const body = Buffer.concat([cipher.update(JSON.stringify(values), \"utf8\"), cipher.final()]);\n const token = `p1.${Buffer.concat([nonce, cipher.getAuthTag(), body]).toString(\"base64url\")}`;\n if (token.length > 16384) throw invalidPage(\"page cursor values are too large; choose shorter ordering columns\");\n return token;\n}\n\nexport function decodeCursor(secret: Buffer, scope: string, token: string, count: number): (string | null)[] {\n try {\n if (typeof token !== \"string\" || token.length > 16384 || !/^p1\\.[\\w-]+$/.test(token)) throw new Error();\n const data = Buffer.from(token.slice(3), \"base64url\");\n if (data.length < 30 || data.toString(\"base64url\") !== token.slice(3)) throw new Error();\n const cipher = createDecipheriv(\"aes-256-gcm\", secret, data.subarray(0, 12));\n cipher.setAAD(Buffer.from(scope));\n cipher.setAuthTag(data.subarray(12, 28));\n const values: unknown = JSON.parse(Buffer.concat([cipher.update(data.subarray(28)), cipher.final()]).toString(\"utf8\"));\n if (!Array.isArray(values) || values.length !== count || values.some(v => v !== null && typeof v !== \"string\")) throw new Error();\n return values;\n } catch {\n throw invalidPage(\"Invalid cursor for this query or identity; restart from the first page\", \"cursor\");\n }\n}\n\nexport interface PageColumn { type?: string; nullable?: boolean }\nexport interface PageOrder { column: string; direction: \"asc\" | \"desc\"; nulls: \"first\" | \"last\"; nullable: boolean }\n\nexport function pageOrder(columns: Record<string, PageColumn>, primaryKey: readonly string[], opts: RawPageOptions): {\n order: PageOrder[]; size: number; backward: boolean; token: string | undefined;\n} {\n const raw = opts as Record<string, unknown>;\n if (\"limit\" in raw || \"offset\" in raw) throw invalidPage(\"page uses first/after or last/before, not limit/offset\");\n const backward = opts.last !== undefined || opts.before !== undefined;\n if (backward && (opts.first !== undefined || opts.after !== undefined)) throw invalidPage(\"Use first/after or last/before in one page request\");\n const size = (backward ? opts.last : opts.first) ?? 50;\n if (!Number.isInteger(size) || size < 1 || size > 1000) throw invalidPage(\"page size must be an integer between 1 and 1000\");\n if (primaryKey.length === 0) throw new Error(\"page requires a declared primary key for a unique, stable ordering\");\n const input = opts.orderBy === undefined ? [] : Array.isArray(opts.orderBy) ? opts.orderBy : [opts.orderBy];\n if (input.length > 16) throw invalidPage(\"page supports at most 16 ordering columns\");\n const seen = new Set<string>();\n const order: PageOrder[] = [];\n const add = (o: { column: string; direction?: string; nulls?: string }) => {\n const def = columns[o?.column];\n if (!Object.hasOwn(columns, o?.column) || !def) throw invalidPage(`page order column ${o?.column} is not declared`);\n if (!new Set([\"uuid\", \"text\", \"integer\", \"bigint\", \"boolean\", \"timestamp\", \"numeric\", \"enum\"]).has(def.type ?? \"\")) {\n throw invalidPage(`page cannot order ${o.column}: ${def.type ?? \"unknown\"} is not a supported scalar column`);\n }\n if (seen.has(o.column)) throw invalidPage(`page order column ${o.column} is repeated`);\n if (o.direction !== undefined && o.direction !== \"asc\" && o.direction !== \"desc\") throw invalidPage(\"page direction must be asc or desc\");\n if (o.nulls !== undefined && o.nulls !== \"first\" && o.nulls !== \"last\") throw invalidPage(\"page nulls must be first or last\");\n const direction = o.direction ?? \"asc\";\n seen.add(o.column);\n order.push({ column: o.column, direction, nulls: o.nulls ?? (direction === \"asc\" ? \"last\" : \"first\"), nullable: def.nullable !== false });\n };\n for (const o of input) add(o);\n for (const column of primaryKey) if (!seen.has(column)) add({ column, direction: order.at(-1)?.direction ?? \"asc\" });\n return { order, size, backward, token: backward ? opts.before : opts.after };\n}\n\n/** Render a strict lexicographic boundary. NULLs follow the declared sort order,\n * independent of direction; every component of a composite PK participates. */\nexport function pageBoundary(order: readonly PageOrder[], values: readonly (string | null)[], backward: boolean,\n bind: (value: unknown) => string, column: (name: string) => string, inclusive = false): string {\n const refs = values.map(v => bind(v));\n // This form lets PostgreSQL start an index scan at the cursor, instead of\n // filtering the entire prefix for the common non-null, uniform ordering.\n if (order.every(o => !o.nullable && o.direction === order[0]!.direction) && values.every(v => v !== null)) {\n const greater = (order[0]!.direction === \"asc\") !== backward;\n return `(${order.map(o => column(o.column)).join(\", \")}) ${greater ? \">\" : \"<\"}${inclusive ? \"=\" : \"\"} (${refs.join(\", \")})`;\n }\n const parts: string[] = [];\n const prefix: string[] = [];\n for (let i = 0; i < order.length; i++) {\n const o = order[i]!, c = column(o.column), r = refs[i]!;\n const nullsLast = (o.nulls === \"last\") !== backward;\n const cmp = (o.direction === \"asc\") !== backward ? \">\" : \"<\";\n const tail = values[i] === null\n ? (nullsLast ? \"false\" : `${c} IS NOT NULL`)\n : `(${c} ${cmp} ${r}${nullsLast ? ` OR ${c} IS NULL` : \"\"})`;\n parts.push(`(${[...prefix, tail].join(\" AND \")})`);\n prefix.push(`${c} IS NOT DISTINCT FROM ${r}`);\n }\n if (inclusive) parts.push(`(${prefix.join(\" AND \")})`);\n return `(${parts.join(\" OR \")})`;\n}\n","export interface InsertManyOptions<Key extends string = string> {\n onConflict?: readonly Key[];\n /** Defaults to ignore when onConflict is supplied. */\n action?: \"ignore\" | \"update\";\n /** false returns the affected row count and skips row serialization. */\n returning?: boolean;\n}\n\nexport function validateInsertManyOptions(opts: InsertManyOptions | undefined): void {\n if (!opts) return;\n if (opts.returning !== undefined && typeof opts.returning !== \"boolean\") throw new Error(\"insertMany returning must be a boolean\");\n if (opts.action !== undefined && opts.action !== \"ignore\" && opts.action !== \"update\") throw new Error(\"insertMany action must be ignore or update\");\n if (opts.onConflict !== undefined && (!Array.isArray(opts.onConflict) || opts.onConflict.some(c => typeof c !== \"string\" || c.length === 0))) {\n throw new Error(\"insertMany onConflict must be an array of column names\");\n }\n if (opts.action !== undefined && !opts.onConflict?.length) throw new Error(\"insertMany action requires nonempty onConflict columns\");\n}\n","/** Column and table UNIQUE declarations, including composite primary keys. */\nexport function uniqueKeysOf(table: {\n columns?: Record<string, unknown>;\n primaryKey?: readonly string[];\n unique?: readonly { columns: readonly string[] }[];\n}): string[][] {\n const columns = table.columns ?? {};\n const inlinePrimary: string[] = [], keys: string[][] = [];\n for (const [name, value] of Object.entries(columns)) {\n const col = (value && typeof value === \"object\" && \"_def\" in value ? value._def : value) as\n { primaryKey?: boolean; unique?: boolean } | undefined;\n if (col?.primaryKey) inlinePrimary.push(name);\n if (col?.unique) keys.push([name]);\n }\n const primary = table.primaryKey ?? inlinePrimary;\n if (primary.length) keys.unshift([...primary]);\n for (const key of table.unique ?? []) keys.push([...key.columns]);\n const seen = new Set<string>();\n return keys.filter(key => {\n if (!key.length || new Set(key).size !== key.length || key.some(col => !Object.hasOwn(columns, col))) {\n throw new Error(\"Unique lookup requires a nonempty declared key of distinct, known columns\");\n }\n const identity = JSON.stringify([...key].sort());\n if (seen.has(identity)) return false;\n seen.add(identity); return true;\n });\n}\n\n/** Nulls in ordinary PostgreSQL UNIQUE constraints are not unique. */\nexport function assertUniqueLookup(table: string, keys: readonly (readonly string[])[], where: Record<string, unknown>): void {\n if (!where || typeof where !== \"object\" || Array.isArray(where)) throw new Error(`findUnique(${table}): where must contain one declared unique key`);\n const columns = Object.keys(where);\n if (!keys.some(key => key.length === columns.length && key.every(col => Object.hasOwn(where, col)))) {\n throw new Error(`findUnique(${table}): supply exactly one declared unique key (${keys.map(key => key.join(\" + \")).join(\"; \") || \"none declared\"}); use findMany for other filters`);\n }\n for (const [name, value] of Object.entries(where)) {\n if (value === null || value === undefined || (typeof value === \"object\" && !(value instanceof Date)) || typeof value === \"function\" || typeof value === \"symbol\") {\n throw new Error(`findUnique(${table}): ${name} requires a non-null scalar equality value`);\n }\n }\n}\n\n/** A union of exact keys, not a partial row that could match many records. */\nexport type UniqueWhere<Row, Keys> = Keys extends readonly (infer Key extends readonly string[])[]\n ? Key extends unknown\n ? { [K in Extract<Key[number], keyof Row>]-?: NonNullable<Row[K]> } &\n { [K in Exclude<keyof Row, Key[number]>]?: never }\n : never\n : never;\n","import type { SqlDriver } from \"./db.js\";\nimport type { TxWireGuard } from \"../db/tx-plan.js\";\n\nconst installed = new WeakSet<SqlDriver>();\nexport const hasCommandExecutor = (sql: SqlDriver): boolean => installed.has(sql);\n\n/** Statements remain sequential inside PostgreSQL. Each sees preceding writes,\n * including triggers, unlike sibling data-modifying CTEs in one SQL statement.\n * The exception block is a subtransaction, matching a savepoint plan. */\nexport const COMMAND_EXECUTOR_DDL = `\nCREATE SCHEMA IF NOT EXISTS palbase_runtime;\nCREATE OR REPLACE FUNCTION palbase_runtime.command_v1(steps jsonb) RETURNS jsonb\nLANGUAGE plpgsql VOLATILE SECURITY INVOKER SET search_path = pg_catalog, public AS $pb_command$\nDECLARE\n results jsonb := '[]'::jsonb;\n step jsonb; chunk jsonb; binding jsonb; source jsonb; rows jsonb;\n statement text; rendered text; detail text; guard jsonb;\n index integer := 0; affected integer; passed boolean;\nBEGIN\n FOR step IN SELECT value FROM jsonb_array_elements(steps) LOOP\n IF step->>'empty' = 'true' THEN rows := '[]'::jsonb;\n ELSE\n statement := '';\n FOR chunk IN SELECT value FROM jsonb_array_elements(step->'chunks') LOOP\n IF jsonb_typeof(chunk) = 'string' THEN statement := statement || (chunk #>> '{}');\n ELSE\n binding := step->'bindings'->((chunk->>'bind')::integer);\n IF binding ? 'ref' THEN\n source := results->((binding->'ref'->>'op')::integer)->'rows'->0;\n IF source IS NULL OR NOT source ? (binding->'ref'->>'field') THEN\n RAISE EXCEPTION 'Command reference has no source row/column; use expectOne before reading it'\n USING ERRCODE = 'PBC02', DETAIL = jsonb_build_object('error_code','tx_ref_unresolved','op',index)::text;\n END IF;\n source := source->(binding->'ref'->>'field');\n ELSE source := binding->'value'; END IF;\n rendered := CASE WHEN source IS NULL OR source = 'null'::jsonb THEN NULL\n WHEN binding->>'json' = 'true' THEN source::text\n WHEN jsonb_typeof(source) = 'string' THEN source #>> '{}' ELSE source::text END;\n -- PostgreSQL quotes the value itself. Values reach this function as\n -- one bound JSON parameter, never as application-generated SQL text.\n statement := statement || quote_nullable(rendered);\n END IF;\n END LOOP;\n EXECUTE statement INTO rows;\n END IF;\n affected := jsonb_array_length(rows);\n guard := step->'guard';\n IF guard IS NOT NULL AND guard <> 'null'::jsonb THEN\n passed := CASE guard->>'kind'\n WHEN 'one' THEN affected = 1 WHEN 'none' THEN affected = 0\n WHEN 'atLeast' THEN affected >= (guard->>'n')::integer\n WHEN 'atMost' THEN affected <= (guard->>'n')::integer ELSE false END;\n IF NOT passed THEN\n RAISE EXCEPTION 'Command expectation failed'\n USING ERRCODE = 'PBC01', DETAIL = jsonb_build_object('error_code','tx_guard_failed','slot',guard->'slot','op',index)::text;\n END IF;\n END IF;\n results := results || jsonb_build_array(jsonb_build_object('rows',rows,'rows_affected',affected));\n index := index + 1;\n END LOOP;\n RETURN jsonb_build_object('results',results);\nEXCEPTION WHEN SQLSTATE 'PBC01' OR SQLSTATE 'PBC02' THEN\n GET STACKED DIAGNOSTICS detail = PG_EXCEPTION_DETAIL;\n RETURN jsonb_build_object('error',detail::jsonb);\nEND\n$pb_command$;\nREVOKE ALL ON FUNCTION palbase_runtime.command_v1(jsonb) FROM PUBLIC;\nCREATE OR REPLACE FUNCTION palbase_runtime.command_rows_v1(rows jsonb, guard jsonb) RETURNS jsonb\nLANGUAGE plpgsql VOLATILE SECURITY INVOKER SET search_path = pg_catalog, public AS $pb_rows$\nDECLARE affected integer := jsonb_array_length(rows); passed boolean;\nBEGIN\n IF guard IS NOT NULL AND guard <> 'null'::jsonb THEN\n passed := CASE guard->>'kind'\n WHEN 'one' THEN affected = 1 WHEN 'none' THEN affected = 0\n WHEN 'atLeast' THEN affected >= (guard->>'n')::integer\n WHEN 'atMost' THEN affected <= (guard->>'n')::integer ELSE false END;\n IF NOT passed THEN\n RAISE EXCEPTION 'Command expectation failed'\n USING ERRCODE = 'PBC01', DETAIL = jsonb_build_object('error_code','tx_guard_failed','slot',guard->'slot')::text;\n END IF;\n END IF;\n RETURN rows;\nEND\n$pb_rows$;\nREVOKE ALL ON FUNCTION palbase_runtime.command_rows_v1(jsonb,jsonb) FROM PUBLIC;\n`;\n\n/** Run once with a migration/owner connection. Runtime execution retains each\n * caller's role and RLS; there is no SECURITY DEFINER capability. */\nexport async function installCommandExecutor(sql: SqlDriver, roles: readonly string[]): Promise<void> {\n const quote = (s: string) => `\"${s.replace(/\"/g, '\"\"')}\"`;\n if (roles.length === 0) throw new Error(\"Command executor needs explicit runtime roles\");\n await sql.begin(async tx => {\n // Serialize simultaneous boots installing the same version.\n await tx.unsafe(\"SELECT pg_advisory_xact_lock(196754721, 1)\");\n await tx.unsafe(COMMAND_EXECUTOR_DDL);\n const list = [...new Set(roles)].map(quote).join(\", \");\n await tx.unsafe(`GRANT USAGE ON SCHEMA palbase_runtime TO ${list}`);\n await tx.unsafe(`GRANT EXECUTE ON FUNCTION palbase_runtime.command_v1(jsonb) TO ${list}`);\n await tx.unsafe(`GRANT EXECUTE ON FUNCTION palbase_runtime.command_rows_v1(jsonb,jsonb) TO ${list}`);\n });\n installed.add(sql);\n}\n\nexport type CommandBinding = ({ value: unknown } | { ref: { op: number; field: string } }) & { json?: boolean };\nexport interface CompiledStep {\n chunks?: (string | { bind: number })[];\n bindings?: CommandBinding[];\n guard?: TxWireGuard;\n empty?: true;\n}\n\n/** Only unquoted placeholders are replaced. A declared identifier or a string\n * literal containing \"$1\" is data in the SQL grammar, not a parameter. */\nexport function parameterChunks(sql: string): (string | { bind: number })[] {\n const chunks: (string | { bind: number })[] = [];\n let start = 0, quote: \"'\" | '\"' | null = null;\n for (let i = 0; i < sql.length; i++) {\n const c = sql[i];\n if (quote) {\n if (c === quote) { if (sql[i + 1] === quote) i++; else quote = null; }\n continue;\n }\n if (c === \"'\" || c === '\"') { quote = c; continue; }\n if (c !== \"$\") continue;\n const parameter = /^\\$(\\d+)\\b/.exec(sql.slice(i));\n if (!parameter) continue;\n chunks.push(sql.slice(start, i), { bind: Number(parameter[1]) - 1 });\n i += parameter[0].length - 1; start = i + 1;\n }\n chunks.push(sql.slice(start));\n return chunks;\n}\n","import { TooManyRequests } from \"../errors.js\";\n\nexport interface AdmissionLease {\n queueMs: number;\n release(): void;\n}\n\n/** Deployment settings, never a query/workload declaration in application code. */\nexport interface DatabaseAdmissionOptions {\n concurrency: number;\n queueLimit?: number;\n queueTimeoutMs?: number;\n /** Optional signed, issuer-controlled top-level tenant claim. By default\n * fairness uses verified sub, not the installation-wide tenant_id. */\n tenantClaim?: string;\n onReject?: (event: { reason: \"full\" | \"timeout\" | \"cancelled\"; active: number; queued: number }) => void;\n}\n\ninterface DatabaseWaiter {\n grant: (lease: AdmissionLease) => void;\n reject: (error: unknown) => void;\n entered: number;\n cleanup(): void;\n}\n\nexport class DatabaseAdmission {\n private active = 0;\n private queued = 0;\n private tenants = new Map<string, number>();\n // Map insertion order is the round-robin ring; each Set is FIFO. Grant and\n // cancellation remove nodes directly, without scanning a 10,000-item queue.\n private pending = new Map<string, Set<DatabaseWaiter>>();\n private lastTenant?: string;\n private accepted = 0;\n private rejected = { full: 0, timeout: 0, cancelled: 0 };\n private readonly limit: number;\n private readonly timeout: number;\n constructor(readonly options: DatabaseAdmissionOptions) {\n this.limit = options.queueLimit ?? Math.min(512, Math.max(32, options.concurrency * 8));\n this.timeout = options.queueTimeoutMs ?? 1000;\n if (!Number.isSafeInteger(options.concurrency) || options.concurrency < 1 ||\n !Number.isSafeInteger(this.limit) || this.limit < 0 || this.limit > 10000 ||\n !Number.isSafeInteger(this.timeout) || this.timeout < 1 || this.timeout > 60000) {\n throw new Error('Invalid database pool or queue deployment settings');\n }\n }\n get snapshot() { return { active: this.active, queued: this.queued, tenants: this.tenants.size,\n accepted: this.accepted, rejected: { ...this.rejected } }; }\n private rejection(reason: 'full' | 'timeout' | 'cancelled') {\n this.rejected[reason]++;\n try { this.options.onReject?.({ reason, active: this.active, queued: this.queued }); } catch { /* telemetry cannot affect admission */ }\n }\n private take(tenant: string, entered: number): AdmissionLease {\n this.active++; this.accepted++; this.lastTenant = tenant;\n this.tenants.set(tenant, (this.tenants.get(tenant) ?? 0) + 1);\n let released = false;\n return { queueMs: performance.now() - entered, release: () => {\n if (released) return;\n released = true; this.active--;\n const count = this.tenants.get(tenant)! - 1;\n if (count) this.tenants.set(tenant, count); else this.tenants.delete(tenant);\n this.drain();\n } };\n }\n private drain() {\n while (this.active < this.options.concurrency && this.queued) {\n let tenant = this.pending.keys().next().value!;\n if (this.pending.size > 1 && tenant === this.lastTenant) {\n const queue = this.pending.get(tenant)!;\n this.pending.delete(tenant); this.pending.set(tenant, queue);\n tenant = this.pending.keys().next().value!;\n }\n const queue = this.pending.get(tenant)!, waiter = queue.values().next().value!;\n queue.delete(waiter); this.pending.delete(tenant);\n if (queue.size) this.pending.set(tenant, queue);\n this.queued--; waiter.cleanup(); waiter.grant(this.take(tenant, waiter.entered));\n }\n }\n async acquire(claimsJson: string, signal?: AbortSignal): Promise<AdmissionLease> {\n if (signal?.aborted) { this.rejection('cancelled'); throw signal.reason ?? new Error('Database admission cancelled'); }\n const claims = JSON.parse(claimsJson) as Record<string, unknown>;\n const value = this.options.tenantClaim ? claims[this.options.tenantClaim] : claims.sub;\n const tenant = typeof value === 'string' && value.length ? value : '__anonymous__';\n const entered = performance.now();\n if (this.active < this.options.concurrency && !this.queued) return this.take(tenant, entered);\n if (this.queued >= this.limit) {\n this.rejection('full');\n throw new TooManyRequests({ retryAfter: 1 }, 'Database queue is full');\n }\n return new Promise<AdmissionLease>((grant, reject) => {\n const queue = this.pending.get(tenant) ?? new Set<DatabaseWaiter>();\n if (!this.pending.has(tenant)) this.pending.set(tenant, queue);\n const waiter: DatabaseWaiter = { grant, reject, entered, cleanup() {} };\n const remove = (reason: 'cancelled' | 'timeout', error: unknown) => {\n if (!queue.delete(waiter)) return;\n if (!queue.size) this.pending.delete(tenant);\n this.queued--; waiter.cleanup(); this.rejection(reason); reject(error); this.drain();\n };\n const abort = () => remove('cancelled', signal?.reason ?? new Error('Database admission cancelled'));\n const timer = setTimeout(() => remove('timeout', new TooManyRequests({ retryAfter: 1 }, 'Database queue deadline exceeded')), this.timeout);\n waiter.cleanup = () => { clearTimeout(timer); signal?.removeEventListener('abort', abort); };\n queue.add(waiter); this.queued++;\n signal?.addEventListener('abort', abort, { once: true });\n if (signal?.aborted) abort(); else this.drain();\n });\n }\n}\n\nconst databases = new WeakMap<object, DatabaseAdmission>();\nexport function databaseAdmission(owner: object, options?: DatabaseAdmissionOptions): DatabaseAdmission {\n let admission = databases.get(owner);\n if (!admission) {\n admission = new DatabaseAdmission(options ?? { concurrency: 10 });\n databases.set(owner, admission);\n } else if (options) {\n for (const key of [\"concurrency\", \"queueLimit\", \"queueTimeoutMs\", \"tenantClaim\"] as const) {\n if (options[key] !== admission.options[key]) throw new Error(\"Database admission cannot be reconfigured while its pool is shared\");\n }\n }\n return admission;\n}\n","import { HttpError } from \"../errors.js\";\n\nexport type CancellableQuery = Promise<unknown> & { cancel?: () => unknown };\n\n/** Abort callback work and active statements, then let the transaction owner\n * await rollback. COMMIT is never raced with a timer: its acknowledged result\n * or connection failure remains authoritative. */\nexport class TransactionControl {\n private controller = new AbortController();\n private active = new Set<CancellableQuery>();\n private cancelBackend?: () => Promise<void>;\n private cancellation: Promise<unknown> = Promise.resolve();\n private timer?: ReturnType<typeof setTimeout>;\n private unlink: () => void;\n private rejection: Promise<never>;\n readonly deadline: number | undefined;\n get signal(): AbortSignal { return this.controller.signal; }\n\n constructor(timeoutMs?: number, external?: AbortSignal) {\n this.deadline = timeoutMs === undefined ? undefined : performance.now() + timeoutMs;\n this.rejection = new Promise<never>((_, reject) => {\n this.signal.addEventListener(\"abort\", () => {\n reject(this.signal.reason);\n if (this.active.size && this.cancelBackend) {\n this.cancellation = this.cancelBackend().catch(() => undefined);\n } else {\n for (const query of this.active) {\n try { query.cancel?.(); } catch { /* rollback still owns settlement */ }\n }\n }\n }, { once: true });\n });\n void this.rejection.catch(() => undefined);\n const abort = () => this.controller.abort(external?.reason ?? new DOMException(\"Database transaction cancelled\", \"AbortError\"));\n external?.addEventListener(\"abort\", abort, { once: true });\n this.unlink = () => external?.removeEventListener(\"abort\", abort);\n if (external?.aborted) abort();\n if (timeoutMs !== undefined) this.timer = setTimeout(() => this.controller.abort(\n new HttpError(503, \"database_deadline_exceeded\", \"Database transaction exceeded its deadline\")), timeoutMs);\n }\n\n check(): void {\n if (this.deadline !== undefined && performance.now() >= this.deadline && !this.signal.aborted) {\n this.controller.abort(new HttpError(503, \"database_deadline_exceeded\", \"Database transaction exceeded its deadline\"));\n }\n this.signal.throwIfAborted();\n }\n\n remainingMs(): number | undefined {\n this.check();\n return this.deadline === undefined ? undefined : Math.max(1, Math.ceil(this.deadline - performance.now()));\n }\n\n race<T>(work: Promise<T>): Promise<T> { return Promise.race([work, this.rejection]); }\n\n bindBackend(cancel: () => Promise<void>): void { this.cancelBackend = cancel; }\n\n /** Keep the application's connection parked until the cancellation request\n * and all statements settle; a late cancel must not hit its next borrower. */\n async drainCancellation(): Promise<void> {\n await this.cancellation;\n await Promise.allSettled([...this.active]);\n }\n\n async watch(query: CancellableQuery): Promise<unknown> {\n this.active.add(query);\n try {\n if (this.signal.aborted) query.cancel?.();\n return await query;\n } finally { this.active.delete(query); }\n }\n\n dispose(): void { if (this.timer !== undefined) clearTimeout(this.timer); this.unlink(); }\n}\n","import { createHash } from \"node:crypto\";\nimport { HttpError } from \"../errors.js\";\nimport type { DatabaseDiagnostics, DatabaseDiagnosticsOptions, DatabaseQueryEvent } from \"../db/diagnostics.js\";\n\ntype Timing = \"queueMs\" | \"poolMs\" | \"setupMs\" | \"sqlMs\" | \"commitMs\" | \"rollbackMs\" | \"connectionMs\";\n\n/** Allocated only when diagnostics or a budget is configured. One collector\n * follows the request's user/service handles and independent atomic attempts. */\nexport class DatabaseTrace {\n private readonly start = performance.now();\n private ended?: number;\n private failure?: HttpError;\n private readonly state: DatabaseDiagnostics;\n constructor(private readonly options: DatabaseDiagnosticsOptions) {\n for (const key of [\"maxQueries\", \"maxRows\", \"maxBytes\"] as const) {\n const value = options[key];\n if (value !== undefined && (!Number.isSafeInteger(value) || value < 0)) throw new Error(`database ${key} must be a nonnegative safe integer`);\n }\n this.state = { endpoint: options.endpoint, requestId: options.requestId, outcome: \"active\", elapsedMs: 0,\n queries: 0, rows: 0, bytes: 0, queueMs: 0, poolMs: 0, setupMs: 0, sqlMs: 0, commitMs: 0, rollbackMs: 0,\n connectionMs: 0, commits: 0, commitFailures: 0, rollbackRequests: 0, retries: 0, statements: [] };\n }\n check(): void { if (this.failure) throw this.failure; }\n time(key: Timing, started: number): void { this.state[key] = (this.state[key] ?? 0) + performance.now() - started; }\n retry(): void { this.state.retries++; }\n committed(): void { this.state.commits++; }\n commitFailed(): void { this.state.commitFailures++; }\n failed(): void { this.state.outcome = \"failed\"; }\n rolledBack(): void { this.state.rollbackRequests++; }\n private refuse(kind: string): never {\n this.failure ??= new HttpError(500, \"database_budget_exceeded\", `Database ${kind} budget exceeded${this.options.endpoint ? ` in ${this.options.endpoint}` : \"\"}`);\n throw this.failure;\n }\n private emit<T>(callback: ((event: T) => void | Promise<void>) | undefined, event: T): void {\n // A telemetry sink cannot turn an acknowledged COMMIT into a reported failure.\n try { const result = callback?.(event); if (result) void Promise.resolve(result).catch(() => undefined); } catch { /* isolated sink */ }\n }\n async query(sql: string, name: string | undefined, run: () => Promise<unknown>): Promise<unknown> {\n this.check();\n if (this.options.maxQueries !== undefined && this.state.queries >= this.options.maxQueries) this.refuse(\"query count\");\n const ordinal = ++this.state.queries;\n const event: DatabaseQueryEvent = { ordinal, fingerprint: createHash(\"sha256\").update(sql).digest(\"hex\").slice(0, 24),\n ...(name === undefined ? {} : { name: name.slice(0, 128) }),\n ...(this.options.includeSql ? { sql: sql.slice(0, 4096) } : {}), durationMs: 0, rows: 0, bytes: 0 };\n if (this.options.captureSource) event.source = new Error().stack?.split(\"\\n\").slice(1, 9).join(\"\\n\").slice(0, 2500);\n const started = performance.now();\n let measured = false;\n try {\n const result = await run();\n event.durationMs = performance.now() - started; measured = true;\n if (Array.isArray(result)) {\n event.rows = result.length;\n event.bytes = Buffer.byteLength(JSON.stringify(result, (_, value) => typeof value === \"bigint\" ? value.toString() : value));\n }\n this.state.rows += event.rows; this.state.bytes += event.bytes;\n if (this.options.maxRows !== undefined && this.state.rows > this.options.maxRows) this.refuse(\"returned rows\");\n if (this.options.maxBytes !== undefined && this.state.bytes > this.options.maxBytes) this.refuse(\"result bytes\");\n return result;\n } catch (error) {\n const e = error as { sqlstate?: string; errno?: string; code?: string } | null;\n event.errorCode = String(e?.sqlstate ?? e?.errno ?? e?.code ?? \"query_failed\").slice(0, 80);\n throw error;\n } finally {\n if (!measured) event.durationMs = performance.now() - started;\n this.state.sqlMs += event.durationMs;\n const frozen = Object.freeze(event);\n if (this.state.statements.length < 200) (this.state.statements as DatabaseQueryEvent[]).push(frozen);\n this.emit(this.options.onQuery, frozen);\n }\n }\n get snapshot(): DatabaseDiagnostics {\n return Object.freeze({ ...this.state, elapsedMs: (this.ended ?? performance.now()) - this.start,\n statements: Object.freeze([...this.state.statements].sort((a, b) => a.ordinal - b.ordinal)) });\n }\n complete(outcome: \"committed\" | \"failed\"): void {\n if (this.ended !== undefined) return;\n this.ended = performance.now(); this.state.outcome = outcome;\n this.emit(this.options.onComplete, this.snapshot);\n }\n}\n","/** On delete action for foreign key references. */\nexport type OnDeleteAction = 'cascade' | 'set null' | 'restrict' | 'no action';\n\n/**\n * The ON DELETE actions permitted on a foreign key to the built-in auth users\n * (`auth.users`). Both let a user's rows be removed (`cascade`) or detached\n * (`set null`) when the account is erased; `restrict` / `no action` would BLOCK\n * erasure and are therefore excluded. This is the CLIENT-SIDE mirror of the\n * server's auth-FK deletion policy — the server (validateAuthUserFK) is the real\n * boundary, this narrows the type so the common mistake is caught at compile time.\n */\nexport type AuthUserOnDelete = Extract<OnDeleteAction, 'cascade' | 'set null'>;\n\n/** Column type identifiers. */\nexport type ColumnType =\n | 'uuid'\n | 'text'\n | 'integer'\n | 'bigint'\n | 'numeric'\n | 'boolean'\n | 'timestamp'\n | 'jsonb'\n | 'enum'\n | 'vector';\n\n/** Base column definition shared by all column types. */\nexport interface ColumnDef {\n type: ColumnType;\n nullable: boolean;\n primaryKey: boolean;\n defaultValue?: unknown;\n defaultRandom?: boolean;\n defaultNow?: boolean;\n references?: { table: string; column: string };\n /** Pending FK target, resolved by `defineSchema` once every binding exists. */\n referencesThunk?: () => ColumnBuilder;\n /** FK onto THIS table — no thunk needed, the target is the declaring table. */\n selfRefColumn?: string;\n /** This column OWNS the row: erasure, RLS and the `owner` relation read it. */\n owns?: true;\n /** Explicit name for the FORWARD relation (child → parent), when the one\n * derived from the column would be ambiguous or unclear. */\n refAs?: string;\n /**\n * Explicit name for the REVERSE relation (parent → children).\n *\n * Separate from {@link refAs} because the two directions are different facts:\n * the forward name describes the parent this row points at (`author`), the\n * reverse one describes the rows hanging off the parent (`posts`). One option\n * naming both made an ordinary schema undeclarable — `posts.author_id` and\n * `comments.author_id` both named `{ as: \"author\" }` collided on `users`, and\n * the refusal asked for the `{ as }` they had both already written.\n */\n reverseAs?: string;\n /** The table this column belongs to; set by `defineTable`. */\n ownerTable?: { name: string; columns: Record<string, ColumnBuilder> };\n /**\n * The name this column used to have. A diff cannot tell a rename from a drop and\n * an add — both leave one name gone and another present — so the intent has to be\n * declared. Without it, renaming a column loses its data.\n */\n renamedFrom?: string;\n /**\n * This release's PROMISE that it does not reference this column — neither\n * reads it nor writes it, and never names it in a filter, a sort or a SET.\n *\n * The contraction gate reads it and nothing else does: dropping a column is\n * refused while the RUNNING release's declaration still lacks this mark, so\n * removing a column is two deploys — mark it, ship, then drop it.\n *\n * The word is `ignored` and not `deprecated` deliberately: RFC 9745 defines\n * deprecation as changing NO behaviour, and this changes what a deploy will\n * accept. Rails calls the same thing `ignored_columns`.\n */\n ignored?: boolean;\n onDeleteAction?: OnDeleteAction;\n /** FR-044: yalnız AÇIKÇA `false` bildirilince var. Türev FK index'ini kapatır. */\n index?: boolean;\n /** FR-049: kolon `increment()` ile güncelleniyor. Plan HOT çakışmasını uyarır. */\n counter?: boolean;\n enumName?: string;\n enumValues?: string[];\n unique?: boolean;\n /**\n * The value is written by the DATABASE — a trigger, a rule, an identity — not by\n * the author and not by a DEFAULT this schema declares. It makes the column\n * optional on INSERT without putting a DEFAULT in the DDL.\n *\n * Before this existed the only way to keep a trigger-filled column off the\n * INSERT type was to give it a fake `default()`: a value the schema claimed to\n * write and the trigger immediately overwrote. That made the schema lie about\n * its own data.\n */\n dbAssigned?: boolean;\n /** vector(n): the declared dimension count — part of the TYPE (typmod), read\n * by the wire serializer and the deploy's auto-index (FR-001). */\n dimensions?: number;\n /**\n * How the stored value is projected in and out of this process (FR-009).\n *\n * NOT part of the DDL: the column's Postgres type is unchanged and this pair\n * is never serialized into a migration. It exists so the row surface can hand\n * back the type the application actually works with.\n */\n /**\n * The named codec this column declares (FR-001). Unlike `transform`, the NAME\n * survives into the runtime object, so `makeEnvDts` can emit the matching\n * TypeScript type instead of falling back to the storage type. Not part of\n * the DDL: the column's Postgres type is unchanged.\n */\n codec?: CodecName;\n transform?: ColumnTransform;\n}\n\n/**\n * The read/write pair a column may declare (FR-009).\n *\n * `fromDb` takes whatever the driver produced for this column and returns the\n * value the application sees; `toDb` is its inverse on the way out. Kept\n * deliberately unexported — a column declares one inline, nobody needs to name\n * the shape.\n */\ninterface ColumnTransform<T = unknown> {\n fromDb: (value: unknown) => T;\n toDb: (value: T) => unknown;\n}\n\n/**\n * The closed set of named column codecs (FR-001).\n *\n * WHY A CLOSED SET rather than `.transform<T>()`. A transform's target type is\n * a TYPE parameter — erased at runtime — so the generator that reads the\n * bundled schema object cannot learn it. `palbase-env.d.ts` therefore said\n * `string` while the engine handed the application a number, and a consumer\n * project wrote a hand-rolled codec module plus 141 call sites to compensate.\n *\n * A codec is NAMED instead of typed: the name lands in `_def.codec`, travels in\n * the runtime object to every reader, and BOTH the conversion and the emitted\n * TypeScript type are derived from it. One declaration, one truth, and no way\n * for the two to disagree.\n */\nexport type CodecName = 'number' | 'decimal';\n\nexport const CODECS: Record<\n CodecName,\n { fromDb: (value: unknown) => unknown; toDb: (value: unknown) => unknown; tsType: 'number' | 'string' }\n> = {\n // Exact-precision column → JS number. Safe below 2^53; a value above it is\n // not representable and the author wants `asDecimal()` instead.\n number: {\n fromDb: (v) => Number(v),\n // YAZMA YOLUNDA SESSİZ BOZULMA YOK. `toDb(9007199254740993)` bir zamanlar\n // \"9007199254740992\" yazıyordu: uygulamanın tuttuğundan BAŞKA bir sayı\n // kolona gidiyordu ve hiçbir şey söylemiyordu. `asNumber()`'ın JSDoc'u\n // \"2^53'ün altında güvenli\" diyordu ama bunu uygulayan bir şey yoktu.\n toDb: (v) => {\n if (typeof v === 'number' && !Number.isSafeInteger(v)) {\n throw new Error(\n `asNumber() cannot write ${v}: it is outside the safe integer range and would be stored as a different number. Declare .asDecimal() and hand this column a string.`,\n );\n }\n return String(v);\n },\n tsType: 'number',\n },\n // Exact-precision column → the string Postgres sent. It exists so the\n // DECLARATION is explicit: \"this column is a decimal I handle as text\",\n // rather than the ABSENCE of a declaration meaning the same thing by default.\n // NULL güvencesi ÇİFTİN KENDİSİNDE. Motor NULL'ı zaten atlıyor (üç ayrı\n // yerde), ama bir değişmez, onu koruyan üç `if`'in DIŞINDA yazılmalı: biri\n // düşerse `String(null)` kolonu \"null\" dizesine çevirirdi.\n decimal: {\n fromDb: (v) => (v === null || v === undefined ? v : String(v)),\n toDb: (v) => (v === null || v === undefined ? v : String(v)),\n tsType: 'string',\n },\n};\n\n/** FR-002: a vector column cannot carry keys/defaults/references — the modifier\n * is named in the error so the author fixes the right line. */\nfunction refuseOnVector(def: ColumnDef, modifier: string): void {\n if (def.type === 'vector') {\n throw new Error(`vector column: .${modifier}() is not supported (FR-002 — allowed: nullable()/notNull())`);\n }\n}\n\n// Phantom brand symbols — never have runtime values; exist only to force\n// TypeScript's structural type system to distinguish ColumnBuilder instances\n// with different type-param combinations. Without these, TS sees all\n// ColumnBuilder<K,...> as structurally identical and the first branch of\n// ColValue matches everything.\ndeclare const __colKind: unique symbol;\ndeclare const __colNullable: unique symbol;\ndeclare const __colHasDefault: unique symbol;\ndeclare const __colEnumValues: unique symbol;\ndeclare const __colPayload: unique symbol;\ndeclare const __colTransform: unique symbol;\n\n/**\n * Fluent column builder with phantom type params:\n * K — ColumnType literal (e.g. \"text\", \"integer\")\n * N — boolean: true when nullable() has been called last (false = NOT NULL)\n * D — boolean: true when a default has been set\n * E — enum value union (never for non-enum columns)\n * P — jsonb payload shape (unknown unless jsonb<T>() supplied one)\n * T — transform target type (`never` when the column declares no transform;\n * `never` is the sentinel because it is the only type that survives\n * `[T] extends [never]` and never collides with a real target type)\n *\n * All six params have defaults so bare `ColumnBuilder` (no args) still\n * satisfies `Record<string, ColumnBuilder>` in schema.ts without modification.\n *\n * The six `declare readonly` brand fields carry the phantom types into the\n * structural shape so that conditional types like ColValue<C> can discriminate\n * on K without requiring runtime values on those fields.\n */\nexport class ColumnBuilder<\n K extends ColumnType = ColumnType,\n N extends boolean = boolean,\n D extends boolean = boolean,\n E = unknown,\n P = unknown,\n // `unknown`, not `never`: the schema's own constraint is a BARE\n // `ColumnBuilder`, whose T lands on this default. With `never` there, a\n // column that declares `.transform<number>()` is not assignable to the\n // constraint at all — `number` does not extend `never` — so a transform\n // could not appear in a schema and the whole table's `RowShape` collapsed.\n // Measured: TS2322 on `defineSchema`.\n T = unknown,\n> {\n // These fields exist only in the type layer (declared, never initialised at\n // runtime — TypeScript allows declared class members without an initializer\n // in strict mode as long as they're never read at runtime).\n declare readonly [__colKind]: K;\n declare readonly [__colNullable]: N;\n declare readonly [__colHasDefault]: D;\n declare readonly [__colEnumValues]: E;\n declare readonly [__colPayload]: P;\n declare readonly [__colTransform]: T;\n\n readonly _def: ColumnDef;\n\n constructor(type: K, existingDef?: ColumnDef) {\n this._def = existingDef ?? {\n type,\n nullable: false,\n primaryKey: false,\n };\n }\n\n /** Mark this column as the primary key. */\n primaryKey(): ColumnBuilder<K, N, D, E, P, T> {\n refuseOnVector(this._def, 'primaryKey');\n this._def.primaryKey = true;\n return new ColumnBuilder<K, N, D, E, P, T>(this._def.type as K, this._def);\n }\n\n /** Mark this column as NOT NULL (default). */\n notNull(): ColumnBuilder<K, false, D, E, P, T> {\n this._def.nullable = false;\n return new ColumnBuilder<K, false, D, E, P, T>(this._def.type as K, this._def);\n }\n\n /** Allow NULL values. */\n nullable(): ColumnBuilder<K, true, D, E, P, T> {\n this._def.nullable = true;\n return new ColumnBuilder<K, true, D, E, P, T>(this._def.type as K, this._def);\n }\n\n /** Set a default value. */\n default(value: unknown): ColumnBuilder<K, N, true, E, P, T> {\n refuseOnVector(this._def, 'default');\n this._def.defaultValue = value;\n return new ColumnBuilder<K, N, true, E, P, T>(this._def.type as K, this._def);\n }\n\n /** UUID: generate a random default (gen_random_uuid()). */\n defaultRandom(): ColumnBuilder<K, N, true, E, P, T> {\n refuseOnVector(this._def, 'defaultRandom');\n this._def.defaultRandom = true;\n return new ColumnBuilder<K, N, true, E, P, T>(this._def.type as K, this._def);\n }\n\n /** Timestamp: default to now(). */\n defaultNow(): ColumnBuilder<K, N, true, E, P, T> {\n refuseOnVector(this._def, 'defaultNow');\n this._def.defaultNow = true;\n return new ColumnBuilder<K, N, true, E, P, T>(this._def.type as K, this._def);\n }\n\n /**\n * The DATABASE assigns this column's value — a trigger, a rule, an identity.\n *\n * The column becomes optional on INSERT (the author has nothing to send) while\n * the DDL stays free of a DEFAULT this schema would not honour. It is NOT\n * `default()`: that declares a value the schema promises to write.\n *\n * Naming: deliberately not `generated()`. Postgres has GENERATED columns and\n * they are a different thing; borrowing the word would send a reader — or a\n * model writing a schema — to the wrong feature.\n */\n dbAssigned(): ColumnBuilder<K, N, true, E, P, T> {\n this._def.dbAssigned = true;\n return new ColumnBuilder<K, N, true, E, P, T>(this._def.type as K, this._def);\n }\n\n /** Add a foreign key reference. */\n /**\n * Declares that this column used to be called `previous`.\n *\n * A schema diff sees one name gone and another present; it cannot know whether\n * you renamed a column or dropped one and added another, and the two are very\n * different — the second loses every value. Saying so here turns the plan into\n * `ALTER TABLE … RENAME COLUMN` instead.\n *\n * Once the rename has been applied the annotation is inert (the old name is no\n * longer there to rename), so it can be deleted at your leisure.\n */\n renamedFrom(previous: string): ColumnBuilder<K, N, D, E, P, T> {\n this._def.renamedFrom = previous;\n return this as unknown as ColumnBuilder<K, N, D, E, P, T>;\n }\n\n /**\n * See {@link ColumnDef.ignored}.\n *\n * COPIES the def rather than mutating it. The constructor takes an existing\n * def BY REFERENCE, so every builder derived from another shares one object —\n * `const a = slug.unique()` leaves `a._def === slug._def`. An in-place\n * `ignored = true` therefore marks every column sharing that def, including\n * one another table actively reads, and the gate would let THAT column be\n * dropped. Measured before this copy existed.\n *\n * The aliasing is older than this method and other fields leak through it too.\n * The reason this one cannot wait: every other leak produces a VISIBLE schema\n * difference — the plan shows it, the DDL shows it. This one is invisible by\n * design (no DDL, no diff, no plan line), so its only effect is to disarm a\n * safety gate in silence.\n */\n ignored(): ColumnBuilder<K, N, D, E, P, T> {\n return new ColumnBuilder<K, N, D, E, P, T>(this._def.type as K, {\n ...this._def,\n ignored: true,\n });\n }\n\n /**\n * Foreign key onto another table's column.\n *\n * The target is a THUNK, not a direct reference. In a cycle (`x → y`, `y → x`)\n * the second table does not exist yet when the first is built; a direct\n * reference makes TypeScript chase its own tail (TS7022 — measured, and making\n * the return type independent of the target does NOT help). The thunk is\n * invoked in `defineSchema`, where every binding exists and every table\n * already knows its name.\n *\n * In a cycle, ONE side needs an explicit return type:\n * `references((): AnyColumn => y.id)`. One side is enough — measured.\n * For a self-reference use `selfReferences(column)`: no thunk, no annotation.\n *\n * `as` names the FORWARD relation (`author_id` → `author` by default);\n * `reverseAs` names the REVERSE one on the parent, whose default is this\n * table's own name (`users.posts`). Two foreign keys from one table onto one\n * parent therefore need a `reverseAs` on at least one of them — the reverse\n * names would otherwise both be this table's name.\n */\n references(\n target: () => AnyColumn,\n opts?: {\n as?: string;\n reverseAs?: string;\n onDelete?: OnDeleteAction;\n /**\n * Bu FK kolonu için TÜREVİ index üretilsin mi (FR-044). Varsayılan açık.\n *\n * Postgres bir foreign key'i otomatik indekslemez — yalnız hedef\n * taraftaki unique kısıt vardır. Bedeli FK üzerinden her JOIN'de ve her\n * `ON DELETE CASCADE`'de ödenir: bir parent silinirken child tablo tam\n * taranır.\n *\n * `false` demek gerçek bir ihtiyaç, nezaket değil (D-028): FK kolonu aynı\n * zamanda SIK GÜNCELLENEN bir kolonsa index HOT güncellemeyi kırar — ve\n * HOT, DEĞİŞEN kolon indeksliyse kırılır, tablo indeksli diye değil.\n */\n index?: boolean;\n },\n ): ColumnBuilder<K, N, D, E, P, T> {\n refuseOnVector(this._def, 'references');\n if (typeof target !== 'function') {\n // Fail where the mistake is. Storing a non-thunk here surfaces three\n // layers later as \"def.referencesThunk is not a function\", inside\n // defineSchema, naming neither the column nor the call that was wrong.\n throw new Error(\n `references(...) takes a callback: write references(() => otherTable.column). ` +\n `The two-string form references(\"table\", \"column\") is gone — a string cannot be type-checked ` +\n `and cannot point at a table that does not exist yet.`,\n );\n }\n this._def.referencesThunk = target;\n if (opts?.as !== undefined) this._def.refAs = opts.as;\n if (opts?.reverseAs !== undefined) this._def.reverseAs = opts.reverseAs;\n if (opts?.onDelete !== undefined) this._def.onDeleteAction = opts.onDelete;\n // Yalnız AÇIKÇA false bildirilince taşınıyor: `undefined` \"bildirilmedi,\n // türet\" demek ve wire'da hiç görünmemeli (bayt-aynılık).\n if (opts?.index === false) this._def.index = false;\n return new ColumnBuilder<K, N, D, E, P, T>(this._def.type as K, this._def);\n }\n\n /**\n * Bu kolon `increment()` / `decrement()` ile güncelleniyor (FR-049).\n *\n * Deploy kontrolcü kodunu OKUMAZ, o yüzden bildirimin söylemesi gerekiyor —\n * ve söylediği anda plan bir şeyi görebiliyor: aynı kolon hem sayaç hem\n * indeksliyse her güncelleme HOT'u kaybeder.\n *\n * ZİNCİR (D-028+D-030): HOT kaybı → ölü tuple → autovacuum yükü → ve\n * autovacuum worker'ları KÜME GENELİNDE bir kaynak, yani bedeli başka\n * kiracıların tabloları da öder.\n *\n * Sektörde çare \"dokümana uyarı yaz\"dır, çünkü index'i ekleyen kişi\n * `increment()`'i yazan kişi değildir. Bu bildirimde ikisi de YAN YANA\n * duruyor.\n *\n * Uyarı, HATA DEĞİL: sayaç kolonunu indekslemek bazen doğru karardır.\n */\n counter(): ColumnBuilder<K, N, D, E, P, T> {\n this._def.counter = true;\n return new ColumnBuilder<K, N, D, E, P, T>(this._def.type as K, this._def);\n }\n\n /**\n * Foreign key onto THIS table (`parent_id → id`) — category trees, comment\n * replies, org charts.\n *\n * No thunk and no type annotation: the target table is the one being declared,\n * so there is nothing to defer and nothing for TypeScript to chase in a circle.\n * Drizzle forces an explicit `(): AnyPgColumn =>` here because its reference\n * always goes through a callback; measured, we do not need one.\n */\n selfReferences(\n column: string,\n opts?: { as?: string; onDelete?: OnDeleteAction },\n ): ColumnBuilder<K, N, D, E, P, T> {\n refuseOnVector(this._def, 'selfReferences');\n this._def.selfRefColumn = column;\n if (opts?.as !== undefined) this._def.refAs = opts.as;\n if (opts?.onDelete !== undefined) this._def.onDeleteAction = opts.onDelete;\n return new ColumnBuilder<K, N, D, E, P, T>(this._def.type as K, this._def);\n }\n\n\n\n /** Set the ON DELETE action for a foreign key reference. */\n onDelete(action: OnDeleteAction): ColumnBuilder<K, N, D, E, P, T> {\n this._def.onDeleteAction = action;\n return new ColumnBuilder<K, N, D, E, P, T>(this._def.type as K, this._def);\n }\n\n /** Add a single-column UNIQUE constraint. */\n unique(): ColumnBuilder<K, N, D, E, P, T> {\n refuseOnVector(this._def, 'unique');\n this._def.unique = true;\n return new ColumnBuilder<K, N, D, E, P, T>(this._def.type as K, this._def);\n }\n\n /**\n * Declare how this column's value is projected in and out of the process.\n *\n * The DDL does not move: `numeric` stays `numeric`, and the driver still hands\n * back what Postgres sent. What changes is the type the row surface exposes —\n * it becomes `Target`:\n *\n * amount: numeric().transform<number>({ fromDb: Number, toDb: String })\n *\n * `numeric` surfacing as `string` is CORRECT (a JS number cannot hold\n * arbitrary precision), and that is exactly why this exists: application code\n * that does arithmetic on the column otherwise rewrites the same\n * `Number(row.amount)` / `String(x)` pair in every controller that touches it,\n * and each rewrite is a place the two directions can drift apart.\n *\n * A transform is a PROJECTION, never a constraint: it lives only in this\n * process, so it can neither validate nor migrate what is stored.\n */\n /**\n * Surface this exact-precision column as a JS `number` (FR-001).\n *\n * `numeric`/`bigint` arrive as strings because a JS number cannot hold their\n * full range — correct, and exactly why this exists: application code that\n * does arithmetic on the column otherwise rewrites the same `Number(row.x)` /\n * `String(v)` pair in every caller, and each rewrite is a place the two\n * directions can drift apart.\n */\n asNumber(): ColumnBuilder<K, N, D, E, P, number> {\n return this.withCodec<number>('number', 'asNumber');\n }\n\n /**\n * Surface this exact-precision column as a `string` — the value Postgres\n * sent, DECLARED rather than defaulted (FR-001).\n */\n asDecimal(): ColumnBuilder<K, N, D, E, P, string> {\n return this.withCodec<string>('decimal', 'asDecimal');\n }\n\n private withCodec<Target>(codec: CodecName, method: string): ColumnBuilder<K, N, D, E, P, Target> {\n if (this._def.type !== 'bigint' && this._def.type !== 'numeric') {\n throw new Error(\n `${this._def.type} column: .${method}() is only available on bigint()/numeric() — ` +\n `those are the exact-precision types that surface as string.`,\n );\n }\n if (this._def.transform !== undefined) {\n throw new Error(\n `.${method}() and .transform() are two ways to say the same thing on one column — keep .${method}().`,\n );\n }\n if (this._def.codec !== undefined) {\n throw new Error(\n `column already declares .as${this._def.codec === 'number' ? 'Number' : 'Decimal'}(); a column has ONE codec.`,\n );\n }\n // KOPYA, MUTASYON DEĞİL — `ignored()` gibi.\n //\n // `this._def.codec = codec` yazmak, ORTAK bir temelden çatallanan iki\n // kolonun ikisine de SON codec'i verirdi. Ölçüldü:\n // const money = numeric().notNull();\n // money.asNumber(); money.asDecimal();\n // → ikisinin de _def.codec === 'decimal', ve AYNI nesne.\n // Birincinin TİPİ `number`, üretecin bastığı tip `string` olurdu — yani bu\n // özelliğin kapatmak için var olduğu ayrışmanın ta kendisi.\n return new ColumnBuilder<K, N, D, E, P, Target>(this._def.type as K, {\n ...this._def,\n codec,\n });\n }\n\n transform<Target>(fns: ColumnTransform<Target>): ColumnBuilder<K, N, D, E, P, Target> {\n // AYNA KONTROLÜ. `asNumber()` mevcut bir transform'u reddediyor; burası da\n // mevcut bir codec'i reddetmeli, yoksa kapı TEK YÖNLÜ olur:\n // `numeric().asNumber().transform<Date>(…)` üç ayrı cevap üretirdi —\n // builder tipi `Date`, üretilen tip `number`, motor `Number()` uygular —\n // ve hiçbir şey adını söyleyerek reddetmezdi.\n if (this._def.codec !== undefined) {\n throw new Error(\n `column already declares a named codec; .transform() and .as*() are two ways to say the same thing — keep the codec.`,\n );\n }\n // The cast is the variance, not a shortcut: `toDb` takes `Target`, and a\n // `ColumnTransform<unknown>` would have to accept anything. The stored pair\n // is only ever called with this column's own values.\n return new ColumnBuilder<K, N, D, E, P, Target>(this._def.type as K, {\n ...this._def,\n transform: fns as ColumnTransform,\n });\n }\n}\n\n// ---------------------------------------------------------------------------\n// Type extractors — imported by Task 2 to derive insert/row shapes.\n// ---------------------------------------------------------------------------\n\n/**\n * Extracts the TypeScript value type for a column, respecting nullability.\n * - \"uuid\" | \"text\" | \"timestamp\" | \"bigint\" | \"numeric\" → string (or string | null when N = true)\n * Note: bigint/numeric surface as string — JS number loses precision past 2^53,\n * and pgx/PostgREST serialize int8/numeric as strings. App code uses\n * BigInt(row.amount) for bigint, or a decimal lib for numeric.\n * - \"integer\" → number\n * - \"boolean\" → boolean\n * - \"jsonb\" → P (the dev-supplied payload shape from jsonb<T>(), else unknown)\n * - \"enum\" → E (the union of literal values)\n *\n * A declared `.transform<T>()` OVERRIDES the table above: the column then\n * surfaces as T (or T | null when nullable), because that is the value the\n * application is handed. Nullability is still the column's, not the\n * transform's — `fromDb` is not called for a NULL.\n */\nexport type ColValue<C> =\n C extends ColumnBuilder<ColumnType, infer N, boolean, unknown, unknown, infer T>\n ? [unknown] extends [T]\n ? ColStoredValue<C>\n : N extends true\n ? T | null\n : T\n : never;\n\n/** The value as the DATABASE hands it over — the branch table above, before any\n * transform. This is what a column's `fromDb` receives. */\ntype ColStoredValue<C> =\n C extends ColumnBuilder<'uuid' | 'text' | 'timestamp' | 'bigint' | 'numeric', infer N, infer _D, infer _E, infer _P>\n ? N extends true\n ? string | null\n : string\n : C extends ColumnBuilder<'integer', infer N, infer _D, infer _E, infer _P>\n ? N extends true\n ? number | null\n : number\n : C extends ColumnBuilder<'boolean', infer N, infer _D, infer _E, infer _P>\n ? N extends true\n ? boolean | null\n : boolean\n : C extends ColumnBuilder<'jsonb', infer N, infer _D, infer _E, infer P>\n ? N extends true\n ? P | null\n : P\n : C extends ColumnBuilder<'vector', infer N, infer _D, infer _E, infer _P>\n ? N extends true\n ? number[] | null\n : number[]\n : C extends ColumnBuilder<'enum', infer N, infer _D, infer E, infer _P>\n ? N extends true\n ? E | null\n : E\n : never;\n\n/**\n * True when a column is optional on INSERT:\n * - nullable columns (N = true) — the DB allows NULL so the field may be omitted\n * - columns with a default (D = true) — the DB fills in the value when absent\n */\nexport type ColIsOptionalOnInsert<C> =\n C extends ColumnBuilder<ColumnType, true, boolean, unknown, unknown, unknown>\n ? true\n : C extends ColumnBuilder<ColumnType, boolean, true, unknown, unknown, unknown>\n ? true\n : false;\n\n// ---------------------------------------------------------------------------\n// Factory functions\n// ---------------------------------------------------------------------------\n\n/** Create a UUID column. */\nexport function uuid(): ColumnBuilder<'uuid', false, false, never> {\n return new ColumnBuilder('uuid');\n}\n\n/** Create a TEXT column. */\nexport function text(): ColumnBuilder<'text', false, false, never> {\n return new ColumnBuilder('text');\n}\n\n/** Create an INTEGER column. Emits int4 (max ~2.1B). */\nexport function integer(): ColumnBuilder<'integer', false, false, never> {\n return new ColumnBuilder('integer');\n}\n\n/**\n * Create a BIGINT column (Postgres int8, max ~9.2×10^18).\n * Surfaces as `string` in row/insert types — JS number loses precision past 2^53\n * and pgx/PostgREST serialize int8 as a JSON string. Use BigInt(row.column) in app code.\n */\nexport function bigint(): ColumnBuilder<'bigint', false, false, never> {\n return new ColumnBuilder('bigint');\n}\n\n/**\n * Create a NUMERIC column (Postgres `numeric`/`decimal`, arbitrary precision).\n * For exact fractional values (money with cents as a decimal, rates, weights)\n * where int4/int8 don't fit. Surfaces as `string` in row/insert types — JS\n * number can't hold arbitrary-precision decimals without rounding, and\n * pgx/PostgREST serialize numeric as a JSON string. Parse with a decimal lib\n * (or BigInt for scaled integers) in app code.\n */\nexport function numeric(): ColumnBuilder<'numeric', false, false, never> {\n return new ColumnBuilder('numeric');\n}\n\n/** Create a BOOLEAN column. */\nexport function boolean(): ColumnBuilder<'boolean', false, false, never> {\n return new ColumnBuilder('boolean');\n}\n\n/** Create a TIMESTAMP column. */\nexport function timestamp(): ColumnBuilder<'timestamp', false, false, never> {\n return new ColumnBuilder('timestamp');\n}\n\n/**\n * Create a JSONB column. Pass a payload type to make the generated row/insert\n * type concrete instead of `unknown`:\n *\n * tags: jsonb<string[]>() // row.tags: string[]\n * meta: jsonb<{ tier: string }>() // row.meta: { tier: string }\n * raw: jsonb() // row.raw: unknown (back-compat)\n *\n * The runtime accepts a plain JS object/array directly (no JSON.stringify); the\n * generic only refines the TYPE the env codegen emits.\n */\nexport function jsonb<T = unknown>(): ColumnBuilder<'jsonb', false, false, never, T> {\n return new ColumnBuilder('jsonb');\n}\n\n/**\n * Create an ENUM column.\n * @param name The PostgreSQL enum type name (used in DDL).\n * @param values A readonly tuple of valid string values — kept `const` so the\n * union `V[number]` is as narrow as possible.\n */\nexport function enumType<const V extends readonly string[]>(\n name: string,\n values: V,\n): ColumnBuilder<'enum', false, false, V[number]> {\n const builder = new ColumnBuilder<'enum', false, false, V[number]>('enum');\n builder._def.enumName = name;\n builder._def.enumValues = [...values];\n return builder;\n}\n\n/** vector(n) — pgvector kolonu. n TİPİN parçasıdır (typmod) ve [1, 2000] —\n * 2000 = pgvector'ün HNSW-indekslenebilir tavanı; auto-index bu beyanla bağlı\n * (spec FR-001, D-3). */\nexport function vector(dimensions: number): ColumnBuilder<'vector', false, false, unknown, number[]> {\n if (!Number.isInteger(dimensions) || dimensions < 1 || dimensions > 2000) {\n throw new Error(`vector(): dimensions must be an integer in [1, 2000], got ${String(dimensions)}`);\n }\n const b = new ColumnBuilder('vector') as ColumnBuilder<'vector', false, false, unknown, number[]>;\n (b._def as { dimensions?: number }).dimensions = dimensions;\n return b;\n}\n\n/**\n * Any column, whatever its type parameters.\n *\n * Exported so a cycle can be broken from ONE side:\n * `references((): AnyColumn => y.id)`.\n */\nexport type AnyColumn = ColumnBuilder;\n\n/**\n * The column that OWNS this row: a `text` FK onto `auth.users(id)`, NOT NULL,\n * ON DELETE CASCADE.\n *\n * Ownership drives account erasure, so cascade is the only correct action and\n * takes no argument. The referencing column must be `text` (palauth ids are\n * `usr_<uuid>`) and NOT NULL — both are implied here rather than left to the\n * caller, so three rules the type could not express before become UNWRITABLE.\n *\n * At most ONE per table. The old shape let several columns reference\n * `auth.users` and picked the FIRST IN DECLARATION ORDER as the owner — moving a\n * `created_by` above a `user_id` silently changed which rows an account deletion\n * took with it. A second one is now rejected at push.\n *\n * For a column that merely POINTS at a user without owning the row\n * (`created_by`, `edited_by`), use `userRef({ onDelete })`.\n */\nexport function ownedByUser(): ColumnBuilder<'text', false, false, never> {\n const b = new ColumnBuilder<'text', false, false, never>('text');\n b._def.nullable = false;\n b._def.references = { table: 'auth.users', column: 'id' };\n b._def.onDeleteAction = 'cascade';\n b._def.owns = true;\n return b;\n}\n\n/**\n * A plain FK onto `auth.users(id)` that does NOT own the row.\n *\n * `created_by` / `edited_by`: deleting that user must not delete the row. ON\n * DELETE is required and limited to `cascade | set null` so an erasure request\n * is never blocked by a lingering FK; `set null` needs a nullable column.\n */\nexport function userRef(opts: { onDelete: AuthUserOnDelete; as?: string }): ColumnBuilder<'text', boolean, false, never> {\n const b = new ColumnBuilder<'text', boolean, false, never>('text');\n b._def.references = { table: 'auth.users', column: 'id' };\n b._def.onDeleteAction = opts.onDelete;\n if (opts.as !== undefined) b._def.refAs = opts.as;\n return b;\n}\n\n/**\n * A plain FK onto `auth.installations(id)` — the app-scoped verified-device\n * anchor.\n *\n * An installation is an APP INSTALL, not a user: this is NOT ownership. A\n * user-owned row still needs its own `ownedByUser()` so account erasure removes\n * it; an installation reference alone does not tie a row to a user's deletion.\n */\nexport function installationRef(opts: { onDelete: AuthUserOnDelete; as?: string }): ColumnBuilder<'text', boolean, false, never> {\n const b = new ColumnBuilder<'text', boolean, false, never>('text');\n b._def.references = { table: 'auth.installations', column: 'id' };\n b._def.onDeleteAction = opts.onDelete;\n if (opts.as !== undefined) b._def.refAs = opts.as;\n return b;\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.public.<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 */\nimport { DeclarationRefused } from \"../refusals.js\";\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\";\nimport { uniqueKeysOf } from \"./unique.js\";\nimport { CODECS } from \"./columns.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 // A NAMED CODEC DECIDES THE SURFACED TYPE, and it is read BEFORE the switch\n // because the codec is exactly the declaration that overrides the storage\n // type. `numeric` surfacing as `string` is correct by default; `asNumber()`\n // is the author saying \"in this process it is a number\", and the engine\n // already makes that true (FR-003).\n if (def.codec !== undefined && def.codec in CODECS) {\n return CODECS[def.codec].tsType;\n }\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 // `unknown` DEĞİL: `unknown` taşıyan bir kolonda filtre birleşimi\n // (`V | ColRef | …`) tamamen `unknown`'a çöker, yani HİÇBİR kural\n // tutunamaz — `col()` o kolonu her şeyle karşılaştırabiliyordu\n // (D-021'in açık bıraktığı son delik). `Json` gerçek kısıtı söylüyor ve\n // markalanabiliyor.\n return \"Json\";\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 // TÜKETİCİLİK KAPISI. `ColumnType`'a yeni bir değer eklenip burası\n // güncellenmezse BU SATIR DERLEME HATASI verir.\n //\n // Eskiden burası sessizce `unknown` döndürüyordu ve `unknown` taşıyan bir\n // kolonda filtre birleşimi tamamen `unknown`'a çöker — yani `col()`,\n // `now()`, toplama, hepsi o kolonda kuralsız kalırdı. `numeric` bir\n // zamanlar tam olarak buraya düşmüştü (\"numeric had no case at all\"),\n // ve `jsonb` aynı çöküşü 28.0.0'a kadar yaşadı. Üçüncüsü olmasın.\n const unhandled: never = def.type;\n throw new Error(\n `env-gen: \"${String(unhandled)}\" kolon tipinin TypeScript karşılığı ` +\n `bildirilmemiş. baseTsType'a bir case ekleyin — sessizce \\`unknown\\` ` +\n `dönmek o kolonu her kuralın dışına çıkarır.`,\n );\n }\n }\n}\n\n/** The full row type for a column: base type, `| null` when nullable. */\n/**\n * Kolonun POSTGRES tipi, tipin İÇİNDE taşınan bir marka olarak.\n *\n * TypeScript `numeric`, `bigint`, `text`, `uuid` ve `timestamp`'i tek bir\n * `string`'e düşürüyor. Yani `integer ↔ numeric` (Postgres'te geçerli) ile\n * `integer ↔ text` (geçersiz) tipte AYNI görünüyordu ve `col()` hangi kuralı\n * koyarsa koysun bir tarafta yanılıyordu (D-021: yanlış ret mi yanlış kabul mü\n * seçilecekti — ikisi de yanlıştı).\n *\n * Marka o bilgiyi geri getiriyor. `& { readonly __pg?: \"…\" }` seçilmesinin\n * nedeni ÖLÇÜLDÜ: isteğe bağlı bir alanla kesişim, satırı hâlâ düz `string`\n * olarak okunabilir ve düz bir değerle YAZILABİLİR bırakıyor — yani marka\n * yalnız karşılaştırma kurallarının gördüğü, kullanıcının hiç görmediği bir\n * bilgi. Zorunlu bir alan olsaydı `{ balance: \"10.00\" }` derlenmezdi.\n *\n * `enum` KİMLİĞİYLE markalanıyor: iki FARKLI enum'u Postgres de karşılaştırmaz,\n * ve düz `\"enum\"` markası onları aynı sayardı.\n */\nfunction pgBrand(def: ColumnDef): string {\n if (def.type === \"enum\") {\n const values = [...(def.enumValues ?? [])].sort();\n return values.length === 0 ? \"enum\" : `enum:${values.join(\"|\")}`;\n }\n return def.type;\n}\n\nfunction rowType(def: ColumnDef): string {\n const base = baseTsType(def);\n // `unknown` MARKALANAMAZ: marka bir kesişim ve `unknown & X` doğrudan `X`'e\n // çöker. `jsonb` kolonu `Pg<unknown, \"jsonb\">` yazılınca tipi\n // `{ readonly __pg?: \"jsonb\" }` oluyordu — yani kolon DARALDI ve meşru bir\n // nesne yazılamaz hâle geldi. GERÇEK bir projede ölçüldü: 33 tablolu bir\n // şemada `user_preferences`'ın jsonb kolonlarına yazan iki çağrı kırıldı.\n //\n // Markasız kalan kolon eski (gevşek) kurala düşer — jsonb için bu zaten\n // bugünkü davranış, yani hiçbir şey kötüleşmiyor.\n\n // Takma ad, ham kesişim yerine: bu dosyayı GELİŞTİRİCİ de açıyor ve\n // `(string) & { readonly __pg?: \"uuid\" }` satırları okunmaz kılıyordu.\n // `Pg<string, \"uuid\">` hem kısa hem kolonun Postgres tipini SÖYLÜYOR.\n // Takma ad ayrıca `enum` birleşimlerini tip argümanı olarak sarmalıyor —\n // ham kesişimde `A | B & C`, `A | (B & C)` diye ayrışıp bir dalı markasız\n // bırakırdı.\n const branded = `Pg<${base}, ${JSON.stringify(pgBrand(def))}>`;\n return def.nullable ? `${branded} | null` : branded;\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 DeclarationRefused(\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 DeclarationRefused(\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 // FR-004: `can` — adlandırılmış UPDATE policy adlarının literal union'ı.\n // Policy'siz tabloda `never[]`: alan hep var (motor `[]` yazar), eleman yok.\n // Gerçek bir `can` kolonu varsa yankı yoktur (motor da kolonu korur): ikinci\n // bir `can:` satırı `skipLibCheck` altında sessizce İLK bildirime çözülürdü.\n // İlişki de aynı rezervasyon (defineTable reddeder; ham TableDef için kemer).\n const hasCanColumn =\n Object.prototype.hasOwnProperty.call(table.columns, \"can\") || relations.some((r) => r.name === \"can\");\n // Motorla aynı süzgeç: 59 baytı aşan ad (`can:` + ad > NAMEDATALEN 63) telde asla gelmez.\n const canNames = (table.policies ?? []).filter((p) => p.command === \"update\" && p.permissive !== false && Buffer.byteLength(`can:${p.name}`, \"utf8\") <= 63).map((p) => JSON.stringify(p.name));\n // The contract travels with the type (final review M-2): a reader of the .d.ts\n // sees what `can` is for without opening the docs.\n const canDoc = `${indent} /** Names of this table's UPDATE policies whose \\`using\\` is true for THIS row and caller — an AFFORDANCE for the interface (draw or hide a control); never an authorization decision, may be incomplete, the server decides again on every request. */`;\n const canLine = hasCanColumn ? null : `${canDoc}\\n${indent} can: ${canNames.length === 0 ? \"never[]\" : `(${canNames.join(\" | \")})[]`};`;\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 ...(canLine === null ? [] : [canLine]),\n `${indent} };`,\n `${indent} insert: {`,\n ...insertLines,\n `${indent} };`,\n `${indent} relations: {${relEntries === \"\" ? \"\" : ` ${relEntries} `}};`,\n `${indent} uniqueKeys: ${JSON.stringify(uniqueKeysOf(table))};`,\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 // appendOnly (FR-031): EnvTypedTable'ın altı yazma üyesini KALDIRAN yapısal\n // bayrak. `searchable` ile aynı desen ve aynı OMIT disiplini — bayrak yokken\n // satır hiç üretilmez ki mevcut şemaların d.ts'i bayt-aynı kalsın.\n ...(table.appendOnly === true ? [`${indent} appendOnly: true;`] : []),\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 */\n/**\n * A free-form `.transform<T>()` CANNOT be typed here, and must not be typed\n * WRONG (FR-004).\n *\n * The target type is a TYPE PARAMETER — erased at runtime. This generator reads\n * the bundled runtime object, so it only ever saw `{ fromDb, toDb }` and fell\n * through to the storage type: it emitted `string` for a column the engine hands\n * back as a number. A consumer project measured exactly this and wrote a\n * hand-rolled codec module plus 141 call sites rather than trust the types.\n *\n * Refusing is the fix, not a limitation: the remedy is named in the message and\n * produces BOTH the conversion and the type from one declaration.\n */\nfunction refuseFreeFormTransforms(schemas: readonly SchemaDef[]): void {\n for (const schema of schemas) {\n for (const table of Object.values(schema.tables)) {\n for (const [col, builder] of Object.entries(table.columns)) {\n const def = builder._def;\n if (def.transform === undefined || def.codec !== undefined) continue;\n const where = qualifiedTableKey(schema.name, table.name);\n // `DeclarationRefused`, NOT a bare Error. `refusals.ts` carries the\n // measured reason: a bare Error from this layer is treated as FATAL by\n // the runtime, the supervisor takes the pod down and palsvc with it —\n // and palsvc is THE PROCESS THAT ACCEPTS THE PUSH this message asks\n // for. The cure must not kill the thing that delivers it.\n throw new DeclarationRefused(\n `table \"${where}\" column \"${col}\" declares .transform<T>(): its target type does not exist at ` +\n `runtime, so the generated types would say something the engine contradicts. Declare a named ` +\n `codec instead — .asNumber() for a JS number, .asDecimal() for the exact string.`,\n );\n }\n }\n }\n}\n\nexport function makeEnvDts(schemas: readonly SchemaDef[]): string {\n refuseFreeFormTransforms(schemas);\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.public.*\\`\n// is typed with no import and no generic. Schemas other than \\`public\\` land\n// under \\`Schemas\\`, reached with \\`Database.schema(\"<name>\").tables.*\\`.\n\n/**\n * Kolonun POSTGRES tipini tipte tasiyan marka.\n *\n * __pg ISTEGE BAGLI oldugu icin satir hala duz string/number gibi okunur ve duz\n * bir degerle yazilir — marka yalniz col() ve now() karsilastirma kurallarinin\n * gordugu bir bilgidir. TypeScript numeric, bigint, text, uuid ve timestamp'i\n * tek string'e dusurdugu icin bu bilgi olmadan integer<->numeric (gecerli) ile\n * integer<->text (gecersiz) ayirt edilemiyordu.\n */\ntype Pg<T, N extends string> = T & { readonly __pg?: N };\n\n/**\n * Bir jsonb kolonunun tasiyabilecegi deger.\n *\n * undefined DAHIL, cunku JSON.stringify undefined alanlari duserur ve\n * { a: undefined } yazan kod her yerde var — reddetmek dogru olmazdi.\n */\ntype Json = string | number | boolean | null | undefined | Json[] | { [k: string]: Json };\n\ndeclare module \"@palbase/backend/env\" {\n interface Tables {${body}}\n interface Schemas {${schemasBody}}\n}\n\nexport {};\n`;\n}\n","import type { SqlDriver } from \"./db.js\";\n\n/** The control pool must be separate from the application pool, connect as the\n * same session user and to the same PostgreSQL server. Cancellation must still\n * have a connection when every application connection is occupied. */\nexport function withQueryCancellation(application: SqlDriver, control: SqlDriver): SqlDriver & { close(): Promise<void> } {\n if (application === control) throw new Error(\"Query cancellation requires a separate control pool\");\n const close = async (driver: SqlDriver) => {\n const d = driver as SqlDriver & { close?: () => unknown; end?: () => unknown };\n if (d.close) await d.close(); else if (d.end) await d.end();\n };\n return {\n unsafe: (sql, params) => application.unsafe(sql, params),\n begin: fn => application.begin(fn),\n async cancelBackend(pid, startedAt) {\n // A PID alone is insufficient after a backend exits and the OS reuses\n // it. Match its start time and original login, using a bound PID.\n await control.unsafe(`SELECT pg_cancel_backend(pid) FROM pg_stat_activity\n WHERE pid=$1::integer AND backend_start=$2::timestamptz\n AND usename=session_user AND datname=current_database() AND backend_type='client backend'`, [pid, startedAt]);\n },\n async close() { await close(application); await close(control); },\n };\n}\n","// The decorator registry — the single plain-data store the method + parameter\n// decorators write into, and the deploy/dispatch pipeline reads back. No\n// `reflect-metadata`, no `emitDecoratorMetadata`: the registry is built from the\n// decorator arguments + the parameter INDEX that esbuild/tsc preserve for legacy\n// parameter decorators (verified — see the design spec §0/§4.1).\n//\n// A controller class carries its route metadata on a symbol-keyed static\n// property (`ROUTES`). `@Get`/`@Post`/… append a {@link RouteMeta} entry;\n// `@Body`/`@User`/… append a {@link ParamMeta} entry onto the route for the\n// method they decorate. Because parameter decorators run BEFORE the method\n// decorator for the same member (TS evaluates innermost-first, params before the\n// method), the route entry may not exist yet when a param decorator fires — so\n// param metadata is buffered per method name and merged when the method\n// decorator creates the route entry.\nimport type { AuthSpec, RateLimitConfig } from \"../endpoint.js\";\nimport type { UploadConfig } from \"./upload.js\";\nimport type { SseConfig } from \"./sse.js\";\nimport type { ZodTypeAny } from \"zod\";\n\n/** The HTTP verbs a route may declare, upper-cased (the runtime router +\n * OpenAPI lower-case on their own). */\nexport type HttpMethodUpper = \"GET\" | \"POST\" | \"PUT\" | \"PATCH\" | \"DELETE\" | \"QUERY\";\n\n/** Route-level options accepted by the method decorators (`@Get`/`@Post`/…). */\nexport interface RouteOptions {\n /** Enforced before statements and COMMIT; include retries and service queries. */\n databaseBudget?: import(\"../db/diagnostics.js\").DatabaseBudget;\n /** OVERRIDES the controller-level default auth for this one route. */\n auth?: AuthSpec;\n /** Per-route rate limit. */\n rateLimit?: RateLimitConfig;\n /** Direct-storage upload config — present ONLY on `@Upload` routes (the\n * `@Get`/`@Post`/… decorators never set it). Its presence is what MARKS a\n * route as an upload route through the whole pipeline (registry → flatten →\n * openapi → codegen). The bytes go client→storage directly; the method body\n * runs as the completion handler. See {@link UploadConfig} (decorators/upload.ts). */\n uploadConfig?: UploadConfig;\n /** Streaming config — present ONLY on `@Sse` routes (the `@Get`/`@Post`/…\n * decorators never set it). Its presence is what MARKS a route as a streaming\n * route through the whole pipeline (registry → flatten → openapi → codegen),\n * exactly as `uploadConfig` does for uploads — never a special HTTP verb. An\n * `@Sse` route registers POST like any input-bearing route, so the verb cannot\n * carry the distinction. See {@link SseConfig} (decorators/sse.ts). */\n sseConfig?: SseConfig;\n}\n\n/** The kind of value a parameter decorator injects. Drives both dispatch\n * (which request slice to inject) and codegen (which OpenAPI parameter source a\n * schema-bearing kind maps to). */\nexport type ParamKind =\n | \"body\"\n | \"query\"\n | \"param\"\n | \"headers\"\n | \"user\"\n | \"optionalUser\"\n | \"client\"\n | \"requestId\"\n | \"traceId\"\n | \"req\"\n // `@UploadedObject()` — injects the uploaded object (completion input) on an\n // `@Upload` route. No schema (the shape is the fixed UploadedObject type).\n | \"uploadedObject\"\n // `@SseOut()` — injects the frame writer on an `@Sse` route. No schema (the\n // shape is the fixed SseWriter type).\n | \"sseOut\"\n // `@Signal()` — injects the request's AbortSignal, which aborts when the\n // client disconnects. No schema. NOT derivable from `@Req()`: PBRequest\n // carries only request-scoped data and has no signal (endpoint.ts:358-363).\n | \"signal\";\n\n/** One parameter decorator's recorded metadata. `index` is the parameter\n * position esbuild/tsc preserve; `schema` is present for the schema-bearing\n * kinds (`body`/`query`/`headers`); `name` is the path-param name for `param`. */\nexport interface ParamMeta {\n index: number;\n kind: ParamKind;\n /** Zod schema for `body`/`query`/`headers` (validation + codegen source). */\n schema?: ZodTypeAny;\n /** Path-param name for `@Param(\"id\")`. */\n name?: string;\n}\n\n/** One inferred throw site: the error CLASS name (e.g. \"TodoLocked\") and its\n * wire code (e.g. \"todo_locked\"). `status`, `hasData`, and the data JSON schema\n * are NOT carried here — they resolve from the error registry by `code` at\n * extract/openapi time (single source of truth). */\nexport interface ThrowDescriptor {\n name: string;\n code: string;\n}\n\n/** One route's recorded metadata: the verb + subpath + method name + options,\n * the ordered parameter metas, and the resolved return schema (injected by the\n * codegen step — see `returnSchema`). */\nexport interface RouteMeta {\n method: HttpMethodUpper;\n subpath: string;\n fnName: string;\n options: RouteOptions;\n params: ParamMeta[];\n /** Response schema for the route, if any. Derived from the method's RETURN\n * TYPE by codegen and written here via `recordReturn` (a generated top-level\n * IIFE injected per controller), not by an author-written decorator. */\n returnSchema?: ZodTypeAny;\n /** Error classes this route can throw, if inferred. Derived from the method\n * body + service call graph by the deploy stager's throw analysis and written\n * here via `recordThrows` (a generated top-level IIFE injected per controller,\n * the `recordReturn` twin), not by an author-written decorator. */\n throws?: ThrowDescriptor[];\n}\n\n/** Symbol the route metadata list is stored under on a controller class. Using\n * a symbol (not a string key) keeps it off the public structural surface and\n * avoids any chance of an authored property collision. */\nexport const ROUTES: unique symbol = Symbol.for(\"palbase.backend.routes\");\n\n/** Symbol the per-method buffered parameter metas are stored under while a class\n * is being decorated. Parameter decorators fire before the method decorator, so\n * they buffer here keyed by method name; the method decorator drains the buffer\n * into the route entry it creates. */\nconst PARAM_BUFFER: unique symbol = Symbol.for(\"palbase.backend.paramBuffer\");\n\n/** A room's own slots. Rooms are NOT routes — no verb, no path, no params — so\n * they get their own carrier slots instead of being squeezed into RouteMeta. */\nconst ROOM: unique symbol = Symbol.for(\"palbase.backend.room\");\nconst ROOM_HOOKS: unique symbol = Symbol.for(\"palbase.backend.roomHooks\");\n\n/** Symbol the per-method buffered return-type schemas are stored under while a\n * class's registry is being populated. The codegen-injected `recordReturn` call\n * can fire before OR after the method decorator; it buffers here keyed by method\n * name and `recordRoute` drains it into the route entry (and `recordReturn`\n * writes through if the route already exists). Buffering on BOTH sides means a\n * fully-formed route entry always carries its return schema — a raw-symbol\n * reader (the runtime) never has to re-merge. */\nconst RETURN_BUFFER: unique symbol = Symbol.for(\"palbase.backend.returnBuffer\");\n\n/** Symbol the per-method buffered throw descriptors are stored under while a\n * class's registry is being populated. The stager-injected `recordThrows` call\n * can fire before OR after the method decorator; it buffers here keyed by method\n * name and `recordRoute` drains it into the route entry (and `recordThrows`\n * writes through if the route already exists). Buffering on BOTH sides means a\n * fully-formed route entry always carries its throw descriptors — a raw-symbol\n * reader (the runtime) never has to re-merge. */\nconst THROWS_BUFFER: unique symbol = Symbol.for(\"palbase.backend.throwsBuffer\");\n\n/** A class constructor carrying the symbol-keyed registry slots. We type the\n * registry-bearing class as this so the decorators can read/write the slots\n * without `any` — a plain `Function` does not carry index signatures. */\ninterface RegistryCarrier {\n [ROUTES]?: RouteMeta[];\n [PARAM_BUFFER]?: Record<string, ParamMeta[]>;\n [ROOM]?: RoomMeta;\n [ROOM_HOOKS]?: RoomBuffer;\n [RETURN_BUFFER]?: Record<string, ZodTypeAny>;\n [THROWS_BUFFER]?: Record<string, ThrowDescriptor[]>;\n}\n\n/** Coerce a decorated target (class constructor or its prototype) into the\n * registry carrier that owns the slots. Method/param decorators receive the\n * PROTOTYPE as their target; the class decorator receives the constructor. We\n * always anchor the registry on the CONSTRUCTOR so `getRoutes(ctor)` finds it. */\nfunction carrierOf(target: object): RegistryCarrier {\n // For instance-member decorators, `target` is the prototype; its `.constructor`\n // is the class. For a static member or the class decorator, `target` is the\n // constructor already. Resolve to the constructor either way.\n const ctor =\n typeof target === \"function\"\n ? (target as unknown as RegistryCarrier)\n : (((target as { constructor?: unknown }).constructor ??\n target) as unknown as RegistryCarrier);\n return ctor;\n}\n\n/** Get (creating if absent) the own route list for a class constructor. Own —\n * not inherited — so a subclass does not mutate its base's routes. */\nfunction ownRoutes(carrier: RegistryCarrier): RouteMeta[] {\n if (!Object.prototype.hasOwnProperty.call(carrier, ROUTES)) {\n carrier[ROUTES] = [];\n }\n return carrier[ROUTES] as RouteMeta[];\n}\n\n/** Get (creating if absent) the own per-method param buffer for a class. */\nfunction ownParamBuffer(carrier: RegistryCarrier): Record<string, ParamMeta[]> {\n if (!Object.prototype.hasOwnProperty.call(carrier, PARAM_BUFFER)) {\n carrier[PARAM_BUFFER] = {};\n }\n return carrier[PARAM_BUFFER] as Record<string, ParamMeta[]>;\n}\n\n/** Record a route (called by the method decorators). Drains any parameter\n * metas already buffered for `fnName` into the new route entry, then sorts them\n * by parameter index so dispatch can inject positionally. */\nexport function recordRoute(\n target: object,\n fnName: string,\n method: HttpMethodUpper,\n subpath: string,\n options: RouteOptions,\n): void {\n const carrier = carrierOf(target);\n const routes = ownRoutes(carrier);\n const buffer = ownParamBuffer(carrier);\n const params = (buffer[fnName] ?? []).slice().sort((a, b) => a.index - b.index);\n const route: RouteMeta = { method, subpath, fnName, options, params };\n // Drain a buffered return schema (the recordReturn-ran-first ordering) so the\n // route entry is complete the moment it's created — a raw-symbol consumer\n // (the runtime extractor/worker) sees the return schema without re-merging.\n const returnBuffer = carrier[RETURN_BUFFER];\n if (returnBuffer && returnBuffer[fnName] !== undefined) {\n route.returnSchema = returnBuffer[fnName];\n }\n // Same drain for buffered throw descriptors (the recordThrows-ran-first\n // ordering) — the route entry is complete the moment it's created.\n const throwsBuffer = carrier[THROWS_BUFFER];\n if (throwsBuffer && throwsBuffer[fnName] !== undefined) {\n route.throws = throwsBuffer[fnName];\n }\n routes.push(route);\n}\n\n/** Record one parameter decorator (called by `@Body`/`@User`/…). Buffers per\n * method name; the method decorator merges the buffer into the route entry. If\n * the route already exists (method decorator ran first — TS does evaluate the\n * method decorator AFTER its parameter decorators, but we stay order-robust),\n * the meta is also appended directly so neither ordering loses it. */\nexport function recordParam(target: object, fnName: string, meta: ParamMeta): void {\n const carrier = carrierOf(target);\n const buffer = ownParamBuffer(carrier);\n (buffer[fnName] ??= []).push(meta);\n\n // Order-robust: if the route already exists, merge in place + keep sorted.\n const routes = carrier[ROUTES];\n if (routes) {\n const route = routes.find((r) => r.fnName === fnName);\n if (route) {\n route.params.push(meta);\n route.params.sort((a, b) => a.index - b.index);\n }\n }\n}\n\n/** Attach a return schema to the route for `fnName` (called by the codegen\n * injection that reads the method's return type). If the route does not exist\n * yet, the schema is buffered (RETURN_BUFFER) and drained into the route by\n * `recordRoute` when the method decorator runs. */\nexport function recordReturn(target: object, fnName: string, schema: ZodTypeAny): void {\n const carrier = carrierOf(target);\n const routes = carrier[ROUTES];\n const route = routes?.find((r) => r.fnName === fnName);\n if (route) {\n route.returnSchema = schema;\n return;\n }\n if (!Object.prototype.hasOwnProperty.call(carrier, RETURN_BUFFER)) {\n carrier[RETURN_BUFFER] = {};\n }\n const returnBuffer = carrier[RETURN_BUFFER];\n if (returnBuffer) returnBuffer[fnName] = schema;\n}\n\n/** Attach the inferred throw descriptors to the route for `fnName` (called by\n * the stager-injected IIFE that carries the throw analysis result — the\n * `recordReturn` twin). If the route does not exist yet, the descriptors are\n * buffered (THROWS_BUFFER) and drained into the route by `recordRoute` when the\n * method decorator runs. */\nexport function recordThrows(target: object, fnName: string, throws: ThrowDescriptor[]): void {\n const carrier = carrierOf(target);\n const routes = carrier[ROUTES];\n const route = routes?.find((r) => r.fnName === fnName);\n if (route) {\n route.throws = throws;\n return;\n }\n if (!Object.prototype.hasOwnProperty.call(carrier, THROWS_BUFFER)) {\n carrier[THROWS_BUFFER] = {};\n }\n const throwsBuffer = carrier[THROWS_BUFFER];\n if (throwsBuffer) throwsBuffer[fnName] = throws;\n}\n\n/** Read the route metadata for a controller class (the deploy/dispatch entry\n * point). Applies any buffered return schemas + throw descriptors (for the\n * recordReturn/recordThrows-runs-before orderings) and returns a defensive copy\n * so callers cannot mutate the registry.\n */\nexport function getRoutes(ctor: object): RouteMeta[] {\n const carrier = carrierOf(ctor);\n const routes = carrier[ROUTES] ?? [];\n const returnBuffer = carrier[RETURN_BUFFER];\n if (returnBuffer) {\n for (const route of routes) {\n const buffered = returnBuffer[route.fnName];\n if (buffered && route.returnSchema === undefined) {\n route.returnSchema = buffered;\n }\n }\n }\n const throwsBuffer = carrier[THROWS_BUFFER];\n if (throwsBuffer) {\n for (const route of routes) {\n const buffered = throwsBuffer[route.fnName];\n if (buffered && route.throws === undefined) {\n route.throws = buffered;\n }\n }\n }\n return routes.map((r) => ({\n ...r,\n params: r.params.slice(),\n ...(r.throws !== undefined ? { throws: r.throws.slice() } : {}),\n }));\n}\n\n// ── rooms ───────────────────────────────────────────────────────────────────\n\n/** Which lifecycle hook a method is bound to. */\nexport type RoomHook = \"authorize\" | \"first\" | \"join\" | \"leave\" | \"empty\";\n\nexport interface RoomMessageMeta {\n fnName: string;\n schema: ZodTypeAny;\n}\n\nexport interface RoomMeta {\n pattern: string;\n events: Record<string, ZodTypeAny>;\n graceMs: number;\n /** hook → the method name that implements it. */\n hooks: Partial<Record<RoomHook, string>>;\n /** inbound message name → its method and payload schema. */\n messages: Record<string, RoomMessageMeta>;\n}\n\ninterface RoomBuffer {\n hooks: Partial<Record<RoomHook, string>>;\n messages: Record<string, RoomMessageMeta>;\n}\n\n/** Get (creating if absent) the own hook buffer. Own — not inherited — so a\n * subclass never mutates its base's hooks. Member decorators fill this BEFORE\n * the class decorator runs; controller.ts:203 depends on the same ordering. */\nfunction ownRoomBuffer(carrier: RegistryCarrier): RoomBuffer {\n if (!Object.prototype.hasOwnProperty.call(carrier, ROOM_HOOKS)) {\n carrier[ROOM_HOOKS] = { hooks: {}, messages: {} };\n }\n return carrier[ROOM_HOOKS] as RoomBuffer;\n}\n\n/** Record a lifecycle hook. A second method for the same hook is refused: two\n * answers to \"who handles this\" cannot be resolved at dispatch, and silently\n * keeping one is how a hook stops running without anyone being told. */\nexport function recordRoomHook(target: object, hook: RoomHook, fnName: string): void {\n const buffer = ownRoomBuffer(carrierOf(target));\n const existing = buffer.hooks[hook];\n if (existing !== undefined && existing !== fnName) {\n const label = `On${hook.charAt(0).toUpperCase()}${hook.slice(1)}`;\n throw new Error(\n `@${label} is declared twice in one room (${existing} and ${fnName}). ` +\n `A room has one of each hook.`,\n );\n }\n buffer.hooks[hook] = fnName;\n}\n\n/** Record an inbound message handler. */\nexport function recordRoomMessage(\n target: object,\n name: string,\n fnName: string,\n schema: ZodTypeAny,\n): void {\n const buffer = ownRoomBuffer(carrierOf(target));\n const existing = buffer.messages[name];\n if (existing !== undefined && existing.fnName !== fnName) {\n throw new Error(\n `@OnMessage(\"${name}\") is declared twice in one room (${existing.fnName} and ${fnName}).`,\n );\n }\n buffer.messages[name] = { fnName, schema };\n}\n\n/** Record the room itself (called by the class decorator), draining the buffer\n * the member decorators already filled. */\nexport function recordRoom(\n ctor: object,\n meta: Omit<RoomMeta, \"hooks\" | \"messages\">,\n): void {\n const carrier = carrierOf(ctor);\n const buffer = ownRoomBuffer(carrier);\n carrier[ROOM] = { ...meta, hooks: buffer.hooks, messages: buffer.messages };\n // AND into the shared class registry, the same slot @Controller pushes to.\n //\n // Without this line a room compiles, bundles and deploys, and is never called:\n // the bundler's entry exports `SDK.getRegisteredControllers()` and the runtime\n // reads its rooms out of THAT list (server.ts's `collectRooms`). A room that\n // only marks its own constructor is a room nobody can find — measured, on the\n // fixture, at the last gate before it would have worked.\n //\n // Rooms and controllers share one list because they are one thing to the\n // loader: classes a bundle declared. What each IS is decided by the marker it\n // carries, never by which list it arrived in.\n const g = globalThis as unknown as Record<symbol, unknown[] | undefined>;\n const REGISTRY = Symbol.for(\"palbase.backend.allControllers\");\n const all = (g[REGISTRY] ??= []);\n if (!all.includes(ctor)) all.push(ctor);\n}\n\n/** The room a class declares, or undefined. A class with no `@Room` is not a\n * room — the marker is the CONFIG's presence, never a name or a base class\n * (the rule upload.ts:13-16 states for uploads). */\nexport function getRoom(ctor: object): RoomMeta | undefined {\n const carrier = carrierOf(ctor);\n if (!Object.prototype.hasOwnProperty.call(carrier, ROOM)) return undefined;\n return carrier[ROOM] as RoomMeta;\n}\n","// `@Controller(basePath, options?)` — the class decorator that marks a class as\n// a Palbase backend controller. It stamps a non-enumerable `__palbase`\n// discriminant + the resolved controller metadata onto the class so the\n// deploy/dispatch pipeline (and `isController`/`resolveController`) can detect\n// and read it without `reflect-metadata`.\nimport type { AuthSpec } from \"../endpoint.js\";\nimport { getRoutes } from \"./registry.js\";\n\n/** The controller metadata stamped onto a `@Controller`-decorated class. The\n * default export of a `controllers/*.controller.ts` file resolves to this via\n * {@link resolveController}. */\nexport interface ControllerMeta {\n /** Discriminant the runtime + tooling read. */\n readonly __palbase: \"controller\";\n /** The base path every route in this controller mounts under (e.g. \"/todos\"). */\n basePath: string;\n /** Controller-level default auth, applied to routes that don't set their own\n * (`@Get(\"/x\", { auth })` overrides this). `undefined` ⇒ the application\n * default ({@link defineDefaultAuth}), and secure-by-default below that —\n * see {@link resolveEffectiveAuth} for the whole cascade. */\n defaultAuth?: AuthSpec;\n}\n\n/** Options accepted by `@Controller`. */\nexport interface ControllerOptions {\n /** Default auth for ALL routes in this controller (route-level overrides;\n * omitting it falls through to the application default declared with\n * {@link defineDefaultAuth}). */\n auth?: AuthSpec;\n}\n\n/** Symbol the controller metadata is stamped under. Symbol-keyed (not a string\n * property) so it never collides with an authored member and stays off the\n * structural surface. */\nexport const CONTROLLER_META: unique symbol = Symbol.for(\"palbase.backend.controllerMeta\");\n\n/**\n * Every class `@Controller` has decorated, in decoration order.\n *\n * This is what lets a controller file need no export at all: importing the file\n * runs the decorator, the decorator records the class here, and the runtime\n * reads the list. Without it the only handle on a class is its export name, so\n * every controller had to be exported AND named in a generated entry — the\n * ceremony NestJS still charges (`export class` PLUS\n * `@Module({controllers:[…]})`).\n *\n * Keyed on a well-known Symbol against globalThis rather than held in a module\n * variable, because a deployed bundle inlines its own copy of this package: two\n * copies would keep two lists, and the runtime would read the empty one. The\n * same hazard `runtimeHooks` exists for, closed the same way — one shared slot.\n */\nconst REGISTRY: unique symbol = Symbol.for(\"palbase.backend.allControllers\") as never;\n\nfunction registry(): unknown[] {\n const g = globalThis as unknown as Record<symbol, unknown[] | undefined>;\n const existing = g[REGISTRY];\n if (existing) return existing;\n const fresh: unknown[] = [];\n g[REGISTRY] = fresh;\n return fresh;\n}\n\n/**\n * The controller classes this process has loaded, in decoration order.\n *\n * Decoration order is import order, which the bundler fixes by sorting the\n * files it emits imports for — so two builds of one tree produce the same\n * route table, and route precedence is not a function of module-resolution\n * accidents.\n */\nexport function getRegisteredControllers(): readonly unknown[] {\n return registry().slice();\n}\n\n/** Empty the registry. For tests, which load controllers repeatedly. */\nexport function __resetRegisteredControllers(): void {\n registry().length = 0;\n}\n\n/**\n * The APPLICATION-level default auth.\n *\n * Held on globalThis under a well-known Symbol for exactly the reason\n * {@link REGISTRY} is: a deployed bundle inlines its own copy of this package,\n * and two copies keeping two defaults is how a security setting silently\n * becomes two different settings.\n */\nconst APP_DEFAULT_AUTH: unique symbol = Symbol.for(\"palbase.backend.appDefaultAuth\") as never;\n\nfunction appAuthSlot(): Record<symbol, AuthSpec | undefined> {\n return globalThis as unknown as Record<symbol, AuthSpec | undefined>;\n}\n\n/**\n * Declare the default auth for EVERY route in the application — the ring the\n * cascade consults when neither the route nor its controller says anything.\n *\n * The measured problem it removes: `auth: { verifiedEmail: true }` repeated by\n * hand on ten `@Controller`s. A security setting that must be repeated is a\n * security setting that will be forgotten — the eleventh controller opens the\n * door and nothing says so.\n *\n * Call it at MODULE SCOPE in a file the application imports (the controllers'\n * own barrel, or a module a controller imports). The cascade reads this slot\n * when the route table is built and when the spec is emitted — both of which\n * run after module loading — so declaration order does not matter, but being\n * imported at all does.\n *\n * @example\n * defineDefaultAuth({ verifiedEmail: true }); // every route, unless it says otherwise\n */\nexport function defineDefaultAuth(auth: AuthSpec): void {\n appAuthSlot()[APP_DEFAULT_AUTH] = auth;\n}\n\n/** The declared application default, or `undefined` when none was declared. */\nexport function getDefaultAuth(): AuthSpec | undefined {\n return appAuthSlot()[APP_DEFAULT_AUTH];\n}\n\n/** Clear the application default. For tests, which declare it repeatedly. */\nexport function __resetDefaultAuth(): void {\n delete appAuthSlot()[APP_DEFAULT_AUTH];\n}\n\n/**\n * THE auth cascade: route → controller → application → `true`.\n *\n * One function, every caller — the route table (`engine/router.ts`) and the\n * spec emitter (`openapi/controllers.ts`) ASK for the answer instead of\n * spelling the chain themselves. Two hand-written copies of a cascade is how\n * the build-time answer and the runtime answer come to disagree about who may\n * call an endpoint, and the disagreement shows up as an open door.\n *\n * The terminal `true` is secure-by-default and is load-bearing: a route that\n * declared nothing, under a controller that declared nothing, in an\n * application that declared nothing, is CLOSED.\n */\nexport function resolveEffectiveAuth(\n routeAuth: AuthSpec | undefined,\n controllerAuth: AuthSpec | undefined,\n): AuthSpec {\n return routeAuth ?? controllerAuth ?? getDefaultAuth() ?? true;\n}\n\n/** A class carrying the stamped controller metadata + discriminant. */\ninterface ControllerCarrier {\n __palbase?: \"controller\";\n [CONTROLLER_META]?: ControllerMeta;\n}\n\n/** The one path segment the platform owns. The isolate matches\n * `^/webhooks/([^/]+)$` on the raw request path BEFORE controller dispatch, so\n * anything a controller resolves to under it answers `404 webhook_not_found`\n * and never runs. */\nconst RESERVED_FIRST_SEGMENT = \"webhooks\";\n\n/**\n * Throw if `path` resolves under the reserved segment. Segments are compared the\n * way the isolate compares them — `split(\"/\").filter(Boolean)` — NOT by string\n * prefix, because empty segments collapse there: `@Controller(\"/\")` +\n * `@Post(\"/webhooks/x\")` composes to `//webhooks/x`, which the isolate serves as\n * `/webhooks/x`. A prefix check reads that as safe; the segment check does not.\n * `/webhooksy` stays allowed for the same reason — it is a different segment.\n *\n * Every verb is refused, not just the POST the isolate currently intercepts: the\n * reservation is of the URL namespace, so a `@Get(\"/webhooks/x\")` that happens\n * to work today would be silently shadowed the moment the isolate's method gate\n * widens. Refusing at build is recoverable; discovering it as a 404 is not.\n */\nfunction assertNotReserved(path: string, subject: string): void {\n const [first] = path.split(\"/\").filter(Boolean);\n if (first === RESERVED_FIRST_SEGMENT) {\n throw new Error(\n `${subject} resolves under the reserved /${RESERVED_FIRST_SEGMENT} path — ` +\n \"inbound webhooks are served there and would shadow this route\",\n );\n }\n}\n\n/**\n * Mark a class as a Palbase backend controller. `basePath` is the mount path\n * for every route the class declares; `options.auth` sets the controller-level\n * default auth (a route's own `auth` overrides it; absent ⇒ secure-by-default).\n *\n * @example\n * \\@Controller(\"/todos\", { auth: false })\n * export class TodosController {\n * \\@Get(\"\") list(\\@QueryParams(ListTodosQuery) q: ListTodosQuery): TodoSchema[] { … }\n * }\n */\nexport function Controller(basePath: string, options: ControllerOptions = {}) {\n return function <T extends abstract new (...args: never[]) => object>(ctor: T): T {\n // /webhooks/* belongs to the platform: the isolate matches the inbound\n // webhook route before controller dispatch, so a controller mounted here\n // would never receive a request. Silent shadowing is the failure mode this\n // whole change exists to remove, so refuse it at build.\n //\n // The COMPOSED path is what gets shadowed, not the base path. `@Controller(\"\")`\n // and `@Controller(\"/\")` both pass a base-path-only check while a\n // `@Post(\"/webhooks/stripe\")` inside them resolves to exactly the path the\n // isolate intercepts. Method decorators run BEFORE the class decorator (TS\n // evaluates members first), so every route this class declares is already in\n // the registry here — which is why the composed check can live at this one\n // seam instead of on the dispatch read path. The `@Controller(\"\") +\n // @Post(\"/webhooks/stripe\")` test is the lock on that ordering: if it ever\n // stopped holding, that test goes red.\n assertNotReserved(basePath, `@Controller(\"${basePath}\")`);\n for (const route of getRoutes(ctor)) {\n assertNotReserved(\n `${basePath}${route.subpath}`,\n `@${route.method}(\"${route.subpath}\") in @Controller(\"${basePath}\")`,\n );\n }\n\n const carrier = ctor as unknown as ControllerCarrier;\n const meta: ControllerMeta = {\n __palbase: \"controller\",\n basePath,\n ...(options.auth !== undefined ? { defaultAuth: options.auth } : {}),\n };\n // Non-enumerable so it doesn't leak onto instances / structural checks.\n Object.defineProperty(carrier, CONTROLLER_META, {\n value: meta,\n enumerable: false,\n configurable: true,\n writable: false,\n });\n // The bare `__palbase` discriminant is the cheap detection marker the\n // runtime/extractor checks; keep it readable but non-enumerable.\n Object.defineProperty(carrier, \"__palbase\", {\n value: \"controller\",\n enumerable: false,\n configurable: true,\n writable: false,\n });\n // Record it, so importing the file is enough and exporting is optional.\n // Guarded against a double-decoration re-entering the same class twice.\n const all = registry();\n if (!all.includes(ctor)) all.push(ctor);\n return ctor;\n };\n}\n\n/** True when `value` is a `@Controller`-decorated class (cheap discriminant\n * check). Accepts the class constructor (the default export of a controller\n * file). */\nexport function isController(value: unknown): boolean {\n if (typeof value !== \"function\" && (typeof value !== \"object\" || value === null)) {\n return false;\n }\n const carrier = value as ControllerCarrier;\n return carrier.__palbase === \"controller\" && carrier[CONTROLLER_META] !== undefined;\n}\n\n/** Read the resolved controller metadata off a `@Controller`-decorated class.\n * Throws if the class was not decorated — callers should gate with\n * {@link isController} first (the loader does). */\nexport function resolveController(ctor: unknown): ControllerMeta {\n if (typeof ctor !== \"function\" && (typeof ctor !== \"object\" || ctor === null)) {\n throw new TypeError(\"resolveController: value is not a class\");\n }\n const meta = (ctor as ControllerCarrier)[CONTROLLER_META];\n if (!meta) {\n throw new TypeError(\n \"resolveController: class is not a @Controller — decorate it with `@Controller(path)` and list it in a module's `controllers`\",\n );\n }\n return meta;\n}\n\n/**\n * A class the runtime constructs takes NO constructor parameters.\n *\n * ONE writer, four callers (controller, hook, job, webhook) and the build's own\n * check. Four hand-written copies of this message is how the four come to\n * disagree about what is refused — and the disagreement is silent, because a\n * class that slips past one of them still ends up with `undefined` fields.\n *\n * Why it is refused rather than injected: there is no container. The parameter\n * would arrive `undefined`, the code would compile, deploy, and fail at the\n * first request that touches the field — the most expensive place to learn it.\n */\nexport function assertZeroArgConstructor(Ctrl: unknown, kind: string): void {\n const arity = (Ctrl as { length?: number }).length ?? 0;\n if (arity === 0) return;\n\n // This function's NAME is a promise: whatever reaches it will be constructed\n // with a zero-argument constructor. Letting a class with parameters through\n // would make the name a lie — worse than the rename FR-029 guards against.\n //\n // An earlier design made it \"declaration-aware\": pass when metadata matches\n // arity. Measured, that re-opens the exact silence this exists to close.\n // ANY decorator triggers metadata emission, not just `@Injectable`:\n //\n // @Job(...) class J { constructor(repo: unknown) {} }\n // → design:paramtypes = [Object] ← matches arity\n //\n // so J would pass, then be built with `new J()`, and `repo` would be\n // `undefined` at the first scheduled run. Four tests in this repo asserted\n // that refusal and all four went red; the tests were right.\n //\n // What changed instead is the MESSAGE, and who calls this. Callers holding a\n // container resolve from it and never come here (router.ts, job/hook/webhook);\n // this stays the guard for the container-less path, and keeps its promise.\n const name = (Ctrl as { name?: string }).name ?? \"<anonymous>\";\n throw new Error(\n `${kind} ${name} declares a constructor with ${arity} parameter(s), and this path ` +\n `builds it with a zero-argument constructor — every parameter would arrive as ` +\n `undefined. If you meant to inject them, add @Injectable() to ${name} and list it ` +\n `in a module's providers, so the container builds it instead.`,\n );\n}\n","/**\n * engine/router.ts — the route table, built from the SDK's own registry.\n *\n * No third-party router. The table is known at boot (the decorators wrote it),\n * so matching is a segment walk over a small array rather than a compiled\n * pattern engine. Both authoring forms for a path parameter are accepted:\n * `{id}` (what the decorators are written with) and `:id`.\n */\nimport { getRoutes } from \"../decorators/registry.js\";\nimport type { Container } from \"../container.js\";\nimport type { RouteMeta } from \"../decorators/registry.js\";\nimport { resolveEffectiveAuth } from \"../decorators/controller.js\";\nimport type { AuthSpec } from \"../endpoint.js\";\n\nconst ROOM_META: unique symbol = Symbol.for(\"palbase.backend.room\") as never;\nconst CONTROLLER_META = Symbol.for(\"palbase.backend.controllerMeta\");\n\nexport interface RouteEntry {\n method: string;\n /** Path segments; a parameter segment is stored as `:name`. */\n segments: string[];\n meta: RouteMeta;\n /** The controller instance the method is invoked on. */\n instance: Record<string, (...args: unknown[]) => unknown>;\n /** `GET /todos/{id}` — stable, human-readable, used as the rate-limit key. */\n id: string;\n /** The auth spec that applies when the route itself declares none —\n * controller default ?? application default ?? `true`, resolved once at boot\n * by `resolveEffectiveAuth`. `engine/index.ts` reconciles the route's own\n * spec against it per request. */\n controllerAuth: AuthSpec;\n}\n\nfunction toSegments(path: string): string[] {\n return path\n .split(\"/\")\n .filter(Boolean)\n .map((s) => (s.startsWith(\"{\") && s.endsWith(\"}\") ? `:${s.slice(1, -1)}` : s));\n}\n\n/**\n * Build the table from controller classes.\n *\n * @throws when a class carries no routes — a controller that collected zero\n * endpoints is the silent failure this whole runtime is built to refuse, and\n * it must be loud at boot rather than a 404 in production.\n * @throws when a class declares constructor parameters — the same class of\n * silence one level down (FR-010): nothing here has an argument to pass, so\n * the field would simply be `undefined` in production.\n */\nexport function buildRouteTable(\n controllers: readonly unknown[],\n container: Container,\n): RouteEntry[] {\n const table: RouteEntry[] = [];\n for (const Ctrl of controllers) {\n // A ROOM is not a routeless controller, it is a class with no HTTP surface\n // at all — server code a device reaches over the socket. It arrives here\n // because rooms and controllers share ONE registry slot (the loader's\n // `controllersOf` hands over everything a bundle declared), and the zero-route\n // refusal below is correct for a controller and wrong for a room.\n //\n // Measured on the live stack: the fixture's `@Room` reached this line and the\n // runtime refused to boot with \"controller ProbeRoom collected zero routes\" —\n // a message naming a class that was perfectly correct.\n if ((Ctrl as Record<symbol, unknown>)[ROOM_META] !== undefined) continue;\n // No `new ()` claim any more: the container builds this, and it has already\n // refused anything it could not build honestly. The cast below is only for\n // reading the decorator metadata off the class.\n const ctor = Ctrl as Record<\n symbol,\n { basePath?: string; defaultAuth?: AuthSpec } | undefined\n >;\n const meta = ctor[CONTROLLER_META];\n const basePath = meta?.basePath ?? \"\";\n const routes = getRoutes(Ctrl as never) as RouteMeta[];\n if (routes.length === 0) {\n const name = (Ctrl as { name?: string }).name ?? \"<anonymous>\";\n throw new Error(\n `controller ${name} collected zero routes. Either it declares no @Get/@Post/… , ` +\n `or its decorator metadata was erased at build time — check that the bundle was ` +\n `compiled with experimentalDecorators enabled.`,\n );\n }\n // Resolved, not constructed. `assertZeroArgConstructor` is deliberately NOT\n // called here: it keeps its promise that a class reaching it takes zero\n // arguments, and every controller on this path is built by the container —\n // which is where a dependency it cannot supply is refused, by name.\n const instance = container.get(Ctrl as never) as Record<\n string,\n (...a: unknown[]) => unknown\n >;\n for (const r of routes) {\n const full = `${basePath}${r.subpath ?? \"\"}` || \"/\";\n table.push({\n method: r.method,\n segments: toSegments(full),\n meta: r,\n instance,\n id: `${r.method} ${full}`,\n // The route's OWN spec is deliberately not folded in here: this field\n // is what applies when the route is silent, and `effectiveAuth` puts\n // the route level back on top per request.\n controllerAuth: resolveEffectiveAuth(undefined, meta?.defaultAuth),\n });\n }\n }\n return table;\n}\n\nexport interface RouteMatch {\n entry: RouteEntry;\n params: Record<string, string>;\n}\n\n/** First match wins; the table is small and declaration order is the tiebreak. */\nexport function matchRoute(\n table: readonly RouteEntry[],\n method: string,\n pathname: string,\n): RouteMatch | null {\n const parts = pathname.split(\"/\").filter(Boolean);\n for (const entry of table) {\n if (entry.method !== method || entry.segments.length !== parts.length) continue;\n const params: Record<string, string> = {};\n let ok = true;\n for (let i = 0; i < entry.segments.length; i++) {\n const seg = entry.segments[i];\n const got = parts[i];\n if (seg === undefined || got === undefined) { ok = false; break; }\n if (seg.charCodeAt(0) === 58 /* ':' */) {\n params[seg.slice(1)] = decodeURIComponent(got);\n } else if (seg !== got) {\n ok = false;\n break;\n }\n }\n if (ok) return { entry, params };\n }\n return null;\n}\n","/**\n * engine/attest.ts — the App Attest gate, and the counter that watches it.\n *\n * # Where this sits, and why here\n *\n * The tenant edge splits traffic in two: the platform's own prefixes (`/auth`,\n * `/v1`, `/admin`, `/realtime`, `/.well-known`) go to palsvc, and EVERYTHING\n * ELSE goes to the customer's runtime — this process. That split is already\n * exactly the surface App Attest is supposed to cover, and exactly the set it\n * is supposed to exempt (auth bootstrap, module routes, Storage's own byte\n * write, analytics ingestion). So the gate does not draw a boundary; it stands\n * on one that was already drawn.\n *\n * # What it does NOT do\n *\n * It does not verify anything itself. The device record, its public key and its\n * signature counter live in palauth, and a counter has to have exactly one\n * writer. So the gate asks — `POST /admin/attest/devices/assert` — and palauth\n * answers.\n *\n * The path lives under /admin, not /auth, and that is deliberate: /auth is the\n * TENANT surface — a customer's own code reaches it — while /admin carries the\n * service_role gate. A caller who could POST to the assert endpoint could ask\n * for a challenge on any anchor.\n *\n * The credential is the `apikey` header, not a bearer token, and that is what\n * every other module client here sends: palsvc's own door turns a stack API key\n * into the iJWT its gates read. A bearer token would have to be an iJWT already\n * — which only the edge mints, and this call does not go through the edge.\n * Measured against the running stack: `apikey` → 200, bearer → refused.\n *\n * That call is the only reason the gate is async.\n *\n * The fresh challenge comes back WITH the verdict. That is deliberate: minting\n * it here would mean a second implementation of the same HMAC in a second\n * language, and two implementations of one construction drift silently. It also\n * costs nothing, because when there is evidence to verify the call happens\n * anyway.\n *\n * # The three modes\n *\n * off — nothing. No call, no observation, no header.\n * monitor — COUNTS ONLY. Never rejects, never even verifies. A request\n * carrying a broken assertion passes exactly like one carrying\n * none, because monitoring that can fail is not monitoring.\n * enforce — demands a valid assertion.\n *\n * Monitoring is passive on purpose and the reason is in the client: when the\n * SDK is told to attest on a device that cannot (Simulator, macOS, an older\n * iPhone), it throws and does NOT retry. So \"sample a few requests to see who\n * can attest\" would break the exact developer that monitoring exists to\n * protect. What we count instead is what the SDK already volunteers.\n *\n * # Failure directions are opposite, on purpose\n *\n * If the POLICY cannot be read, the gate falls back to `off`: a gate that\n * cannot reach palauth must not take the customer's traffic down with it.\n * If a VERDICT cannot be obtained while enforcing, the request is REJECTED:\n * under enforcement, \"I could not check\" is not \"it is fine\".\n */\n\nimport type { VerifiedDevice } from \"../types.js\";\n\nexport type AttestMode = \"off\" | \"monitor\" | \"enforce\";\n\n/** What one request contributed to the monitoring counts. */\nexport interface AttestObservation {\n /** The SDK's own answer to \"can this device attest at all\". CLIENT-DECLARED:\n * it counts, it never gates. */\n capable: \"yes\" | \"no\" | \"unknown\";\n attested: boolean;\n /** The client-minted installation id (`X-Palbase-Installation`), so the panel\n * can join these counts with the app-version distribution. NOT the server\n * anchor (`ins_…`) — that one is a security anchor and never a counter key. */\n installationId: string | null;\n}\n\nexport interface AttestOutcome {\n outcome: \"pass\" | \"reject\";\n reason: \"\" | \"app_attest_required\" | \"assertion_invalid\" | \"assertion_stale\";\n device: VerifiedDevice | null;\n /** null in `off` — nothing is counted there. */\n observation: AttestObservation | null;\n /** Handed to the client so its NEXT assertion needs no extra round trip. */\n nextChallenge: string | null;\n}\n\nexport interface AttestGateDeps {\n moduleBaseUrl: string;\n serviceRoleKey: string;\n /** How long a read policy is trusted. Default 30s — the flag must take effect\n * without a redeploy, and 30s is short enough that flipping it feels like a\n * switch rather than a deployment. */\n policyTtlMs?: number;\n /** Per-call ceiling on palauth. Default 2s — see DEFAULT_REQUEST_TIMEOUT_MS. */\n requestTimeoutMs?: number;\n fetchImpl?: typeof fetch;\n}\n\nexport const HEADER_DEVICE_ID = \"x-palbase-device-id\";\nexport const HEADER_PAYLOAD = \"x-palbase-attest-payload\";\nexport const HEADER_SIGNATURE = \"x-palbase-attest-signature\";\nexport const HEADER_CHALLENGE = \"x-palbase-attest-challenge\";\nexport const HEADER_CAPABLE = \"x-palbase-attest-capable\";\nexport const HEADER_INSTALLATION = \"x-palbase-installation\";\n/** The SERVER-minted installation anchor (`ins_…`) the device enrolled against.\n * Distinct from HEADER_INSTALLATION, which is the client's own counting id:\n * this one is what the assertion challenge is bound to, so it has to travel\n * with the evidence or palauth cannot verify the challenge at all. */\nexport const HEADER_ANCHOR = \"x-palbase-installation-anchor\";\n\nconst DEFAULT_POLICY_TTL_MS = 30_000;\n\n/** How long the gate waits on palauth before giving up. Loopback in the same\n * pod: a healthy answer is single-digit milliseconds, so two seconds is\n * generous and still far below any client's patience. */\nconst DEFAULT_REQUEST_TIMEOUT_MS = 2_000;\n\ninterface AssertVerdict {\n ok: boolean;\n reason: string;\n sign_count: number;\n next_challenge: string;\n}\n\n/** Base64 of the SHA-256 of the body, or \"\" when the request carried none. */\nasync function bodyDigest(body: Uint8Array | null): Promise<string> {\n if (!body || body.byteLength === 0) return \"\";\n // Copied into a buffer of its own, for two reasons: a view over a LARGER\n // ArrayBuffer would otherwise hash its neighbours, and a body backed by a\n // SharedArrayBuffer is not a valid digest input at all.\n const bytes = new Uint8Array(new ArrayBuffer(body.byteLength));\n bytes.set(body);\n const buf = await crypto.subtle.digest(\"SHA-256\", bytes);\n return btoa(String.fromCharCode(...new Uint8Array(buf)));\n}\n\nfunction readCapable(req: Request): \"yes\" | \"no\" | \"unknown\" {\n const v = req.headers.get(HEADER_CAPABLE);\n return v === \"yes\" || v === \"no\" ? v : \"unknown\";\n}\n\n/**\n * The gate. One call per request, from the engine's `handle()`, after auth and\n * before the rate limiter.\n */\nexport function createAttestGate(deps: AttestGateDeps) {\n const doFetch = deps.fetchImpl ?? fetch;\n const ttl = deps.policyTtlMs ?? DEFAULT_POLICY_TTL_MS;\n const policyTimeoutMs = deps.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;\n let cachedMode: AttestMode = \"off\";\n let cachedAt = -Infinity;\n\n async function mode(): Promise<AttestMode> {\n if (Date.now() - cachedAt < ttl) return cachedMode;\n try {\n const res = await doFetch(`${deps.moduleBaseUrl}/admin/attest/devices/attest-policy`, {\n headers: { apikey: deps.serviceRoleKey },\n signal: AbortSignal.timeout(policyTimeoutMs),\n });\n if (!res.ok) throw new Error(`attest-policy ${res.status}`);\n const body = (await res.json()) as { mode?: string };\n cachedMode = body.mode === \"monitor\" || body.mode === \"enforce\" ? body.mode : \"off\";\n cachedAt = Date.now();\n } catch {\n // A failed read KEEPS THE LAST KNOWN MODE and does not extend the cache.\n //\n // Falling to `off` here — and remembering that for thirty seconds — would\n // hand an attacker a way to switch the gate off: make the policy read\n // fail and every request for the next window skips verification\n // entirely. Keeping the last good answer means a stack that was\n // enforcing keeps enforcing, and a stack that was off stays off.\n //\n // `cachedAt` is deliberately NOT advanced, so the next request retries\n // rather than waiting out a window on stale information.\n //\n // A stack that has NEVER read the policy starts at `off`, which is the\n // only honest starting point: nothing has said otherwise yet.\n }\n return cachedMode;\n }\n\n return async function gate(\n req: Request,\n body: Uint8Array | null,\n _ctx: { userId?: string },\n ): Promise<AttestOutcome> {\n const m = await mode();\n if (m === \"off\") {\n return { outcome: \"pass\", reason: \"\", device: null, observation: null, nextChallenge: null };\n }\n\n const deviceId = req.headers.get(HEADER_DEVICE_ID) ?? \"\";\n const payload = req.headers.get(HEADER_PAYLOAD) ?? \"\";\n const signature = req.headers.get(HEADER_SIGNATURE) ?? \"\";\n const hasEvidence = deviceId !== \"\" && payload !== \"\" && signature !== \"\";\n\n const observation: AttestObservation = {\n capable: readCapable(req),\n attested: false,\n installationId: req.headers.get(HEADER_INSTALLATION) || null,\n };\n\n if (m === \"monitor\") {\n // No verification call at all. Monitoring costs one buffered counter per\n // request and nothing else — see NFR-002.\n observation.attested = hasEvidence;\n return { outcome: \"pass\", reason: \"\", device: null, observation, nextChallenge: null };\n }\n\n const url = new URL(req.url);\n let verdict: AssertVerdict;\n try {\n const res = await doFetch(`${deps.moduleBaseUrl}/admin/attest/devices/assert`, {\n method: \"POST\",\n headers: { apikey: deps.serviceRoleKey, \"content-type\": \"application/json\" },\n // A HUNG palauth must not become a hung tenant. Without this, a\n // process that accepts the connection and never answers holds every\n // request open until the client gives up — the gate would take the\n // whole stack down while claiming to protect it.\n signal: AbortSignal.timeout(policyTimeoutMs),\n body: JSON.stringify({\n installation_id: req.headers.get(HEADER_ANCHOR) ?? \"\",\n device_id: deviceId,\n challenge: req.headers.get(HEADER_CHALLENGE) ?? \"\",\n payload,\n signature,\n method: req.method,\n // pathname + search, NOT pathname alone.\n //\n // The client signs the path string it was given, and that string can\n // carry a query — the transport splits and reattaches one on purpose.\n // Recomputing from pathname alone would drop the query from the\n // signed definition, which breaks it BOTH ways: an attested call\n // carrying a query would fail to verify, and a captured assertion\n // could be replayed against the same route with different query\n // parameters, which is exactly the substitution the binding exists to\n // prevent.\n path: url.pathname + url.search,\n body_sha256: await bodyDigest(body),\n }),\n });\n if (!res.ok) throw new Error(`assert ${res.status}`);\n verdict = (await res.json()) as AssertVerdict;\n } catch {\n // Enforcing and unable to check: refuse. The client re-enrols and retries,\n // which is recoverable; letting an unverified call through is not.\n return {\n outcome: \"reject\",\n reason: \"app_attest_required\",\n device: null,\n observation,\n nextChallenge: null,\n };\n }\n\n if (!verdict.ok) {\n const reason =\n verdict.reason === \"assertion_invalid\" || verdict.reason === \"assertion_stale\"\n ? verdict.reason\n : \"app_attest_required\";\n return {\n outcome: \"reject\",\n reason,\n device: null,\n observation,\n nextChallenge: verdict.next_challenge || null,\n };\n }\n\n observation.attested = true;\n return {\n outcome: \"pass\",\n reason: \"\",\n device: {\n installationId: \"\",\n authDeviceId: deviceId,\n platform: \"ios\",\n assurance: \"attested\",\n },\n observation,\n nextChallenge: verdict.next_challenge || null,\n };\n };\n}\n\nexport interface ObservationSink {\n record(o: AttestObservation): void;\n flush(): Promise<void>;\n stop(): void;\n}\n\nexport interface ObservationSinkDeps {\n moduleBaseUrl: string;\n serviceRoleKey: string;\n intervalMs?: number;\n maxBatch?: number;\n fetchImpl?: typeof fetch;\n}\n\n/**\n * Buffers observations and ships them in batches.\n *\n * Per-request writes would double a tenant's internal request count for a\n * number that changes no decision. Batching makes the cost independent of\n * traffic: at most one call per interval, plus one per full batch.\n *\n * A failed batch is DROPPED and the sink keeps going. These are counters\n * feeding a forecast, not billing — losing the last few seconds on a crash is\n * cheaper than any machinery that would prevent it.\n */\nexport function createObservationSink(deps: ObservationSinkDeps): ObservationSink {\n const doFetch = deps.fetchImpl ?? fetch;\n const maxBatch = deps.maxBatch ?? 1000;\n const intervalMs = deps.intervalMs ?? 10_000;\n\n let buffer: AttestObservation[] = [];\n let inFlight: Promise<void> = Promise.resolve();\n\n const timer = setInterval(() => {\n void flush();\n }, intervalMs);\n // Never hold the process open for a counter.\n (timer as unknown as { unref?: () => void }).unref?.();\n\n function bucketsOf(batch: AttestObservation[]) {\n const counts = { capable: 0, incapable: 0, unknown: 0, no_sdk: 0 };\n for (const o of batch) {\n if (o.attested || o.capable === \"yes\") counts.capable += 1;\n else if (o.capable === \"no\") counts.incapable += 1;\n else if (o.installationId) counts.unknown += 1;\n else counts.no_sdk += 1;\n }\n return counts;\n }\n\n async function flush(): Promise<void> {\n if (buffer.length === 0) return;\n const batch = buffer;\n buffer = [];\n inFlight = (async () => {\n try {\n await doFetch(`${deps.moduleBaseUrl}/admin/attest/devices/observations`, {\n method: \"POST\",\n headers: { apikey: deps.serviceRoleKey, \"content-type\": \"application/json\" },\n body: JSON.stringify(bucketsOf(batch)),\n });\n } catch {\n // Dropped on purpose — see the doc comment.\n }\n })();\n await inFlight;\n }\n\n return {\n record(o) {\n buffer.push(o);\n if (buffer.length >= maxBatch) void flush();\n },\n flush,\n stop() {\n clearInterval(timer);\n },\n };\n}\n","/**\n * upload.ts — the engine's half of `@Upload`.\n *\n * THE SHAPE, because it is unusual and the reason matters:\n *\n * client ──[ multipart: file + request body ]──► storage\n * storage ──[ authorize: which bucket, which path? ]──► THIS process\n * storage ── writes the bytes, renders the variants\n * storage ──[ signed: uploadedObject + request body ]──► THIS process\n * THIS process ── the handler runs, returns its typed result\n * storage ──[ that result ]──► client\n *\n * The tenant's code NEVER sees the bytes. It sees the metadata and the request\n * body, and it answers — which is what a completion handler is for. A 1 GB\n * video would otherwise stream through this process to reach the same place.\n *\n * Two calls arrive here, both from storage and neither from a browser:\n *\n * - AUTHORIZE asks which bucket and path a route writes to. Storage cannot\n * know: the answer lives in `@Upload({bucket, pathTemplate})`, which is\n * TypeScript, in the deployed bundle. Asking the process that HAS the\n * routes is what stops the client from naming its own bucket.\n * - COMPLETION runs the handler.\n *\n * Both are signed. An unsigned completion would let anyone with the route path\n * invent an upload that never happened.\n */\n\nimport type { RouteEntry } from \"./router.js\";\n\n/** What authorize answers: where this route's bytes go, and what they may be. */\nexport interface UploadGrant {\n bucket: string;\n path: string;\n maxBytes: number | null;\n mimeTypes: string[] | null;\n /**\n * Who is uploading, or null when nobody is signed in.\n *\n * Storage records this on the object row so deleting the user takes their\n * files with them. It is reported rather than DECIDED here — this process\n * already resolved the caller to render `{userId}` in a path template, and\n * storage has no identity of its own to derive one from. Authorization stays\n * exactly where it was (the route's own `auth` declaration); this is\n * attribution, which is a different question with the same answer already in\n * hand.\n *\n * null is the anonymous upload, and it stays null: a file uploaded by nobody\n * belongs to nobody, and attributing it to whoever signs in next on that\n * device would file one person's upload under another's name.\n */\n ownerUid: string | null;\n}\n\n/** The completion input storage sends after the bytes have landed. */\nexport interface CompletionEnvelope {\n uploadedObject: {\n uploadId: string;\n path: string;\n bucket: string;\n size: number;\n contentType: string;\n checksum: string;\n width?: number;\n height?: number;\n thumbhash?: string;\n variants: Record<string, string>;\n };\n /** The request body the client sent alongside the file. */\n body: unknown;\n}\n\n/** The internal path storage calls to ask where a route's bytes go. */\nexport const AUTHORIZE_PATH = \"/__palbase/upload/authorize\";\n\n/** Header carrying the shared-secret signature on both internal calls. */\nexport const SIGNATURE_HEADER = \"x-palbase-upload-signature\";\n\n/**\n * renderPath fills a `pathTemplate` on the SERVER.\n *\n * The client never chooses where its bytes land. `{filename}` is the one token\n * that comes from the caller, and it is sanitised to a single path segment:\n * without that, `../../../etc/passwd` is a filename, and a template that looks\n * like a folder structure becomes a way to write anywhere in the bucket.\n */\nexport function renderPath(template: string, tokens: {\n userId?: string | null;\n uploadId: string;\n filename?: string;\n}): string {\n return template\n .replaceAll(\"{userId}\", sanitizeSegment(tokens.userId ?? \"anonymous\"))\n .replaceAll(\"{uploadId}\", sanitizeSegment(tokens.uploadId))\n .replaceAll(\"{filename}\", sanitizeSegment(tokens.filename ?? \"file\"));\n}\n\n/**\n * sanitizeSegment reduces a value to something safe inside one path segment.\n *\n * Slashes, dots and control characters go. Keeping dots would allow `..`;\n * keeping slashes would allow a client to climb out of the prefix the template\n * put it in, which is the whole point of having a template.\n */\nexport function sanitizeSegment(raw: string): string {\n const cleaned = raw\n .replace(/[\\x00-\\x1F\\x7F]/g, \"\")\n .replace(/[/\\\\]/g, \"-\")\n .replace(/\\.{2,}/g, \".\")\n .replace(/^\\.+/, \"\")\n .trim();\n return cleaned === \"\" ? \"file\" : cleaned.slice(0, 200);\n}\n\n/**\n * grantFor resolves a route's upload configuration into a concrete grant.\n *\n * Returns null when the route is not an upload route — which is a refusal, not\n * an oversight: storage asking about a route with no `@Upload` means somebody\n * is trying to write through an endpoint that never offered to accept a file.\n */\nexport function grantFor(\n entry: RouteEntry | undefined,\n ctx: { userId: string | null; uploadId: string; filename?: string },\n bucketLimits?: { maxBytes: number | null; mimeTypes: string[] | null },\n): UploadGrant | null {\n const cfg = entry?.meta?.options?.uploadConfig;\n if (!cfg) return null;\n return {\n bucket: cfg.bucket,\n path: renderPath(cfg.pathTemplate, {\n userId: ctx.userId,\n uploadId: ctx.uploadId,\n filename: ctx.filename,\n }),\n maxBytes: bucketLimits?.maxBytes ?? null,\n mimeTypes: bucketLimits?.mimeTypes ?? null,\n ownerUid: ctx.userId ?? null,\n };\n}\n\n/**\n * CompletionLedger makes a completion run its handler EXACTLY ONCE per upload.\n *\n * The completion is a mutation — it writes the row that makes the uploaded\n * bytes mean something — and it is delivered over a network by a caller that\n * retries. A retried completion must not create a second post for one photo, so\n * the second call is answered with the FIRST call's response rather than being\n * refused: to storage, and therefore to the client waiting on it, a retry that\n * succeeds is indistinguishable from the original, which is the point.\n *\n * Bounded, and oldest-first: an upload id is interesting for as long as a retry\n * could still arrive, not forever. The cap is what keeps a long-lived process\n * from turning this into a leak — a ledger that remembered every upload would\n * be a slow way to run out of memory.\n */\nexport class CompletionLedger {\n private readonly seen = new Map<string, CompletedResponse>();\n\n constructor(private readonly capacity = 1024) {}\n\n recall(uploadId: string): CompletedResponse | undefined {\n return this.seen.get(uploadId);\n }\n\n remember(uploadId: string, response: CompletedResponse): void {\n // Delete-then-set so a repeat moves to the back: Map iterates in insertion\n // order, and the eviction below takes the front.\n this.seen.delete(uploadId);\n this.seen.set(uploadId, response);\n while (this.seen.size > this.capacity) {\n const oldest = this.seen.keys().next();\n if (oldest.done) break;\n this.seen.delete(oldest.value);\n }\n }\n\n get size(): number {\n return this.seen.size;\n }\n}\n\n/** A completion's answer, kept verbatim so a retry receives what the first call did. */\nexport interface CompletedResponse {\n status: number;\n body: string | null;\n contentType: string | null;\n}\n\n/**\n * verifySignature compares a presented signature against the expected one in\n * constant time.\n *\n * Constant time because a leaky comparison on a shared secret is recoverable\n * byte by byte, and this secret authorises running a tenant's handler with an\n * upload the caller describes.\n */\nexport function verifySignature(presented: string, expected: string): boolean {\n if (presented.length !== expected.length) return false;\n let diff = 0;\n for (let i = 0; i < presented.length; i++) {\n diff |= presented.charCodeAt(i) ^ expected.charCodeAt(i);\n }\n return diff === 0;\n}\n","// engine/sse.ts — the Server-Sent Events mechanics, extracted from the request\n// pipeline so they can be tested without driving a whole request.\n//\n// This mirrors engine/upload.ts, which extracts renderPath / grantFor /\n// verifySignature and is consumed from engine/index.ts. Keeping the mechanics\n// here means the frame format, the ordering guarantee and the first-write hook\n// each have a test that names them, rather than being reachable only through a\n// full request.\n//\n// The problem being served: a provider on the server streams from a session;\n// while a client is connected its frames reach that client, and when the client\n// disconnects the provider must stop being pulled. This file owns the first\n// half — turning handler writes into wire frames, in order, without letting\n// anything escape before the request phase has been settled.\n\nimport type { SseWriter } from \"../decorators/sse.js\";\n\n/** The response content type for every `@Sse` route. */\nexport const SSE_CONTENT_TYPE = \"text/event-stream\";\n\n/**\n * Encode one value as an SSE `data:` frame.\n *\n * The payload is JSON, and that is load-bearing rather than merely convenient:\n * a raw newline inside a frame ends it and the remainder is parsed as a new\n * field, so a handler streaming user-influenced text could otherwise forge\n * events. JSON encoding escapes the newline, which makes the frame boundary\n * something only this function decides.\n */\nexport function encodeFrame(value: unknown): string {\n return `data: ${JSON.stringify(value)}\\n\\n`;\n}\n\n/**\n * Encode the terminal frame for a handler that threw AFTER it had already\n * written. The status line is long gone by then — 200 and the stream headers\n * were committed with the first frame — so the only honest way to report the\n * failure is in-band, and named, so a client can tell \"the stream ended\" from\n * \"the stream broke\".\n */\nexport function encodeErrorFrame(requestId: string): string {\n return `event: error\\ndata: ${JSON.stringify({ requestId })}\\n\\n`;\n}\n\n/** What `makeSseWriter` returns: the handler-facing writer plus the two members\n * the engine needs. `SseWriter` itself stays minimal — a handler author sees\n * only `write`. */\nexport interface EngineSseWriter extends SseWriter {\n /** Whether anything has been written yet. The engine chooses between an\n * ordinary error envelope (nothing written — the status line is still ours)\n * and a terminal error frame (already streaming) on this answer. */\n started(): boolean;\n /** Resolves when every queued frame has been enqueued. The engine awaits it\n * before closing the stream, so a handler that returns immediately after its\n * last write does not truncate it. */\n drained(): Promise<void>;\n}\n\nexport interface SseWriterOptions {\n /** Hand one encoded frame to the transport. */\n enqueue(chunk: string): void;\n /**\n * Runs ONCE, before the first frame is enqueued, and nothing is emitted until\n * it resolves. This is the seam where the request's database transaction is\n * settled: the handler runs inside that transaction, and a stream that lives\n * for minutes must not hold one open.\n */\n onFirstWrite(): Promise<void>;\n}\n\n/**\n * Build the writer handed to an `@Sse` handler.\n *\n * `write` is SYNCHRONOUS on purpose: a handler relaying a provider writes inside\n * a `for await` loop, and making every chunk awaitable would put a promise in\n * the hot path of every token for no benefit the caller can act on. The cost is\n * that the asynchronous first-write hook has to be absorbed here — so frames are\n * queued on a promise chain and emitted in exactly the order they were written.\n *\n * Values are encoded EAGERLY, inside `write`, not when the queue drains: a\n * handler that writes a mutable object and then keeps mutating it should see the\n * value as it was at the moment it wrote, which is also the only reading that\n * survives being queued.\n */\nexport function makeSseWriter(opts: SseWriterOptions): EngineSseWriter {\n let begun = false;\n let chain: Promise<void> = Promise.resolve();\n\n return {\n write(value: unknown): void {\n const frame = encodeFrame(value);\n if (!begun) {\n begun = true;\n chain = chain.then(() => opts.onFirstWrite()).then(() => opts.enqueue(frame));\n void chain.catch(() => undefined); // drained() retains the authoritative rejection\n return;\n }\n chain = chain.then(() => opts.enqueue(frame));\n void chain.catch(() => undefined);\n },\n started(): boolean {\n return begun;\n },\n drained(): Promise<void> {\n return chain;\n },\n };\n}\n","import \"reflect-metadata\";\n\nimport { DECLARATION_REFUSAL } from \"./refusals.js\";\n\nimport { __claimInjectables, isInjectable } from \"./decorators/injectable.js\";\nimport { isEntryPointClass } from \"./decorators/kinds.js\";\nimport { __claimModules, type ModuleDef, type Token } from \"./decorators/module.js\";\n\n/**\n * `Token` is born in `decorators/module.ts` — the atom of a module's lists — and\n * re-exported here so a reader meets it on the container's surface too. ONE\n * definition: two would be two `abstract new (...)` signatures free to drift.\n */\nexport type { Token };\n\n/**\n * How a container refuses.\n *\n * Every refusal is one of these, and every one names the class involved. There\n * is deliberately no \"unknown\" member: a failure this list cannot classify is a\n * failure the error surface has not been taught to explain, and that is a defect\n * rather than a category.\n */\nexport type DiKind =\n | \"unresolvable dependency\"\n | \"private dependency\"\n | \"missing import\"\n | \"unowned class\"\n | \"dependency cycle\"\n | \"metadata missing\"\n | \"generic dependency\"\n | \"duplicate ownership\"\n | \"unknown export\"\n | \"unknown import\"\n | \"undeclared provider\";\n\n/**\n * A refusal carries four parts: what kind, the full resolution path, where\n * exactly, and what to do about it.\n *\n * The shape is borrowed on purpose — Angular's path, Awilix's failure kind, and\n * Nest's list of potential solutions — because each of the three answers a\n * question the other two leave open: what broke, where in the graph, and what\n * the author should type next.\n */\nexport class DiError extends Error {\n /**\n * EVERY `DiKind` IS A FACT ABOUT THE AUTHOR'S DECLARATIONS — an unresolvable\n * dependency, a cycle, a class no module owns. Not one of them is something\n * the environment could change, so restarting re-reads the same bytes and\n * fails identically. The cure is a new artifact, and the tag is how the\n * runtime learns that without matching on wording.\n */\n readonly [DECLARATION_REFUSAL] = true as const;\n\n constructor(\n readonly kind: DiKind,\n readonly path: string[],\n readonly at: string,\n detail: string,\n readonly fixes: string[],\n ) {\n super(\n `\\nKind: ${kind}\\n` +\n `Path: ${path.length > 0 ? path.join(\" -> \") : \"(none)\"}\\n` +\n `At: ${at}\\n` +\n `${detail}\\n\\n` +\n `Potential solutions:\\n${fixes.map((f) => ` - ${f}`).join(\"\\n\")}\\n`,\n );\n this.name = \"DiError\";\n }\n}\n\n/** How often a module appears in the OTHERS' `imports`. */\nexport interface ModulePressure {\n module: string;\n pct: number;\n /**\n * How many OTHER modules there were — the denominator.\n *\n * Without it the percentage cannot be read. Measured 2026-09-02: a project\n * with two modules, one importing the other, reports 100% — which is true and\n * says nothing, because \"all of the others\" is one module. A reader deciding\n * whether a module has become ambient needs to know whether 80% was four\n * modules or one.\n */\n of: number;\n}\n\nexport interface Container {\n get<T>(t: Token<T>): T;\n /** Every class a module claimed — the set an entry point must be in. */\n readonly owned: ReadonlySet<Token>;\n /**\n * Where `@Global()` pressure is accumulating.\n *\n * A module that appears in more than ~80% of the others' `imports` is one the\n * design is asking to be ambient. That is a JUDGEMENT — how much sharing is\n * too much depends on the domain — so this is reported as a number and never\n * enforced as a gate. Lives on the container rather than in a module-level\n * variable: the runtime builds a candidate's container beside the live app's,\n * and a shared variable would have one overwrite the other's report.\n */\n readonly pressure: readonly ModulePressure[];\n}\n\nconst nameOf = (c: unknown): string => (c as { name?: string } | null)?.name ?? String(c);\n\n/**\n * Values a transpiler emits when a parameter's type has no runtime class.\n *\n * `Object` is the sentinel — an interface, a type alias and a union all collapse\n * to it — and that it is DISTINGUISHABLE from a real class is what lets the\n * container refuse loudly instead of injecting something arbitrary. The\n * primitives are here for the same reason: they are runtime values, so a naive\n * check would happily try to `new` them.\n */\nconst UNRESOLVABLE = new Set<unknown>([\n Object,\n Function,\n String,\n Number,\n Boolean,\n Array,\n Symbol,\n Promise,\n Date,\n undefined,\n null,\n]);\n\n/** The subset worth naming separately: these say \"you passed DATA\" (FR-036). */\nconst DATA = new Set<unknown>([String, Number, Boolean, Date, Symbol]);\n\n/**\n * Does this class SAY what its constructor asks for?\n *\n * The one predicate for the metadata-against-arity cross-check.\n * `assertZeroArgConstructor` calls this rather than re-deriving it: two copies\n * of the rule are two rules, free to drift the moment one is edited.\n */\nexport function declaresDependencies(ctor: unknown): boolean {\n const arity = (ctor as { length?: number } | null)?.length ?? 0;\n if (arity === 0) return true;\n const meta = Reflect.getMetadata(\"design:paramtypes\", ctor as object) as unknown[] | undefined;\n return meta !== undefined && meta.length === arity;\n}\n\n/**\n * Validates the declared modules and returns a container over them.\n *\n * Validation runs in a fixed order, and the order is the point: each stage may\n * assume the previous one held, so a message never has to hedge. Ownership\n * before exports, exports before dependencies, dependencies before cycles,\n * cycles before construction.\n *\n * Stages 3-5 (dependencies and visibility, cycles, resolution) are added by the\n * tasks that follow; this file grows, it is not replaced.\n */\nexport function buildContainer(): Container {\n // CLAIMS the declarations rather than reading them — see `__claimModules`.\n const entries = __claimModules();\n // Claimed HERE even when the graph is about to be refused below, so a failed\n // build cannot leave a previous import's classes for the next one to inherit.\n const declared = __claimInjectables();\n\n // 0 · a project declares at least one module.\n //\n // There is no implicit module. An implicit one would be a SECOND way for a\n // class to become owned, and the whole design rests on there being one: read\n // the module, know the answer.\n if (entries.length === 0) {\n throw new DiError(\n \"unowned class\",\n [],\n \"project\",\n \"no module was declared — every project declares at least one @Module.\",\n [\n \"create `<domain>.module.ts` with @Module({ controllers: [...], providers: [...] })\",\n \"`palbase init` scaffolds one for you\",\n ],\n );\n }\n\n // 1 · ownership — a class belongs to at most one module.\n //\n // `providers` and `controllers` share ONE namespace: a class is owned or it is\n // not, and being listed as both would make \"which module owns it\" a question\n // with two answers.\n const declaredModules = new Set<Token>(entries.map((e) => e.mod));\n\n const owner = new Map<Token, string>();\n for (const { mod, def } of entries) {\n const m = nameOf(mod);\n for (const c of [...(def.providers ?? []), ...(def.controllers ?? [])]) {\n const prev = owner.get(c);\n if (prev !== undefined) {\n throw new DiError(\n \"duplicate ownership\",\n [nameOf(c)],\n `${prev} & ${m}`,\n `${nameOf(c)} is listed by two modules, so which one owns it has two answers.`,\n [\n `remove ${nameOf(c)} from ${prev}`,\n `or remove it from ${m}`,\n `if both modules need it, keep ONE owner and export it, then import that module`,\n ],\n );\n }\n owner.set(c, m);\n }\n }\n\n // 1a · every provider is a class the container can actually BUILD.\n //\n // Measured 02.09.2026: a module that listed an `abstract class` in its\n // `providers` got `new Clock()` — which succeeds in JavaScript and returns an\n // object missing every abstract member — injected into everything that asked\n // for it, and the failure surfaced mid-request as `c.now is not a function`.\n // FR-055 already refuses that shape when the abstraction is named as a\n // DEPENDENCY; this is the same defect coming in through the other door, and\n // the SDK's own test asserted the broken shape was legal.\n //\n // The signal is the decorator. An abstraction in this design is an UNDECORATED\n // `abstract class` (the scaffold's `NoteRepo`), and an implementation carries\n // `@Injectable()`; surfaces carry `@Job`/`@Hook`/`@Webhook`/`@Room`. So a\n // provider carrying none of them is either an abstraction listed in the wrong\n // place or a class somebody forgot to decorate — and the second is not benign\n // either: without a decorator TypeScript emits no `design:paramtypes`, so\n // every constructor parameter it asks for would arrive `undefined`.\n {\n for (const { mod, def } of entries) {\n for (const p of def.providers ?? []) {\n if (isInjectable(p) || isEntryPointClass(p)) continue;\n // A class whose constructor ASKS for something but carries no emitted\n // types is a different fault with a better message — `metadata missing`\n // in stage 3, which explains `emitDecoratorMetadata` and the bundler.\n // Leaving it to that stage keeps each refusal pointed at one cause. The\n // abstract seam this rule is for has a zero-argument constructor\n // (`abstract class NoteRepo { abstract findMany(…) }`), so it lands\n // here.\n if (!declaresDependencies(p)) continue;\n throw new DiError(\n \"undeclared provider\",\n [nameOf(mod), nameOf(p)],\n `${nameOf(mod)}.providers`,\n `${nameOf(p)} is listed in ${nameOf(mod)}.providers but carries no decorator, ` +\n `so the container cannot know it is constructible or what its constructor asks for.`,\n [\n `mark ${nameOf(p)} \\`@Injectable()\\` if it is a concrete class`,\n `if ${nameOf(p)} is an \\`abstract class\\`, list the class that \\`extends\\` it instead — ` +\n `name the abstraction as the DEPENDENCY and the container resolves it`,\n ],\n );\n }\n }\n }\n\n // 1b · every declared class is OWNED by a module (FR-010).\n //\n // `@Injectable()` decides nothing — ownership is read from a module and from\n // nowhere else — but it makes the class COUNTABLE, and this is the question\n // that needs counting: a service written, imported, and listed in no module.\n // It has no entry point, so `assertNoOrphanEntryPoints` never sees it; it has\n // no dependent, so the resolution stages never reach it. It simply does not\n // exist, silently, which is the one outcome this design refuses everywhere\n // else. Measured through the CLI on 2026-09-02: the build said \"build OK\".\n //\n // Not in `isolated()`: that builds a graph without consulting this file at\n // all, deliberately, because a unit test is not a second opinion about the\n // architecture.\n {\n const orphans = declared.filter((c) => !owner.has(c));\n if (orphans.length > 0) {\n const names = orphans.map(nameOf);\n throw new DiError(\n \"unowned class\",\n names,\n \"module declarations\",\n `${names.join(\", \")} ${orphans.length === 1 ? \"is\" : \"are\"} marked @Injectable() ` +\n `but listed in no module's providers, so nothing can reach ${orphans.length === 1 ? \"it\" : \"them\"}.`,\n [\n `add ${names.length === 1 ? names[0] : \"each of them\"} to a module's \\`providers\\``,\n \"or delete the class — one no module lists is never built\",\n ],\n );\n }\n }\n\n // 2 · exports — a module may only open up what it OWNS.\n //\n // Re-exporting someone else's class would be a hole in the boundary the\n // module system exists to draw: the owner's decision about who may reach it\n // would stop being the owner's.\n const exported = new Map<string, Set<Token>>();\n const importsOf = new Map<string, Set<string>>();\n for (const { mod, def } of entries) {\n const m = nameOf(mod);\n for (const e of def.exports ?? []) {\n if (owner.get(e) !== m) {\n const holder = owner.get(e);\n throw new DiError(\n \"unknown export\",\n [m],\n `${m}.exports`,\n holder === undefined\n ? `${m} exports ${nameOf(e)}, but no module owns it.`\n : `${m} exports ${nameOf(e)}, but ${holder} owns it — a module cannot re-export another's class.`,\n holder === undefined\n ? [`add ${nameOf(e)} to ${m}.providers`, `or remove it from ${m}.exports`]\n : [\n `remove ${nameOf(e)} from ${m}.exports`,\n `and have ${holder} export it instead, then add ${holder} to the importing module's imports`,\n ],\n );\n }\n }\n // An `imports` entry must BE a module. Measured before this check existed:\n // `@Module({ imports: [NotAModule] })` built cleanly and did nothing — the\n // name simply never matched an owner, so every dependency it was meant to\n // unlock kept being refused for a reason that pointed elsewhere.\n for (const i of def.imports ?? []) {\n // Self-import is expressible — legacy decorators run after the class\n // binding exists, so `@Module({ imports: [M] }) class M {}` compiles and\n // ran silently before this check. It grants a module access to its own\n // exports, which it already has, so it is always a typo for another name.\n if (i === mod) {\n throw new DiError(\n \"unknown import\",\n [m],\n `${m}.imports`,\n `${m} imports itself, which grants nothing it does not already have.`,\n [`remove ${m} from its own imports`, \"or name the module you meant instead\"],\n );\n }\n if (!declaredModules.has(i)) {\n throw new DiError(\n \"unknown import\",\n [m],\n `${m}.imports`,\n `${m} imports ${nameOf(i)}, which is not a module.`,\n [\n `add @Module({ ... }) to ${nameOf(i)}`,\n `or remove ${nameOf(i)} from ${m}.imports — to reach a class, import the module that OWNS it`,\n ],\n );\n }\n }\n\n exported.set(m, new Set(def.exports ?? []));\n importsOf.set(m, new Set((def.imports ?? []).map(nameOf)));\n }\n\n // 3 · dependencies — metadata against arity, then type validity, then module\n // visibility. In that order, because each answer makes the next question\n // meaningful.\n const deps = new Map<Token, Token[]>();\n\n /**\n * The owned classes that EXTEND `t`.\n *\n * `abstract` does not exist at runtime — JavaScript happily runs `new Clock()`\n * and returns an object missing every abstract member. Measured before this\n * existed: the container injected exactly that, the build was green, and the\n * failure surfaced mid-request as `c.now is not a function`.\n *\n * So an abstraction is resolved through its implementation, and the\n * relationship is read from the prototype chain — which is what `extends`\n * builds. That is a DECLARATION the class makes about itself, not an\n * inference from where its file sits.\n *\n * Only consulted for a token NOTHING owns. A class that IS owned is the\n * answer to its own name, so an unrelated `extends` elsewhere can never\n * change what an existing dependency resolves to.\n */\n const implementorsOf = (t: Token): Token[] =>\n [...owner.keys()].filter(\n (c) => c !== t && Object.prototype.isPrototypeOf.call(t as object, c as object),\n );\n\n // Is missing metadata GLOBAL or local? Decided BEFORE any per-class message,\n // because the two faults look identical one class at a time and lead to\n // opposite fixes: all of them missing means the build ran without\n // `emitDecoratorMetadata` (or without `reflect-metadata`, whose absence makes\n // the emitted helper a silent no-op); some of them missing means the author\n // forgot `@Injectable()` on those. Telling someone to decorate a class when\n // the flag is off sends them to edit a file that is not the problem.\n //\n // NOT a synthetic canary. An earlier design embedded a probe class in the SDK\n // and asked whether IT carried metadata — but the SDK is built with tsup, and\n // esbuild emits zero `__metadata` (measured), so that probe would report a\n // global fault on every healthy boot. The tenant's OWN classes are the only\n // honest sample of the tenant's build.\n const withArity = [...owner.keys()].filter(\n (c) => (c as unknown as { length: number }).length > 0,\n );\n const missingMeta = withArity.filter(\n (c) => Reflect.getMetadata(\"design:paramtypes\", c) === undefined,\n );\n // TWO is the smallest sample this inference is honest on. With ONE class,\n // \"all of them are missing\" is also what a single forgotten `@Injectable()`\n // looks like, and telling that author their build is broken sends them to the\n // wrong file. Below the threshold the per-class message runs, which names the\n // class and the decorator.\n if (withArity.length >= 2 && missingMeta.length === withArity.length) {\n throw new DiError(\n \"metadata missing\",\n withArity.map(nameOf),\n \"the whole build\",\n `no class carries constructor metadata — every one of the ${withArity.length} ` +\n `class(es) that asks for a dependency is missing it, so this is the build, ` +\n `not the classes.`,\n [\n \"set `emitDecoratorMetadata: true` in the project's tsconfig.json\",\n \"and import `reflect-metadata` before any decorated class evaluates — without it the emitted helper is a silent no-op\",\n \"if the build is fine, then none of these classes carries @Injectable()\",\n ],\n );\n }\n\n for (const [cls, m] of owner) {\n const arity = (cls as unknown as { length: number }).length;\n\n // ARITY IS THE GROUND TRUTH. It survives every transpile; metadata does not.\n // Measured: a decorated class with no constructor carries `undefined`\n // metadata and a decorated one with an empty constructor carries `[]` —\n // both ask for nothing, and only arity says so. Treating absent metadata as\n // a fault would refuse every dependency-free class that never wrote a\n // constructor, which is most of them.\n if (arity === 0) {\n deps.set(cls, []);\n continue;\n }\n\n // Asked through the shared predicate, so \"does this class say what it needs\"\n // has ONE definition — the same one `assertZeroArgConstructor` answers with.\n if (!declaresDependencies(cls)) {\n const meta = Reflect.getMetadata(\"design:paramtypes\", cls) as unknown[] | undefined;\n throw new DiError(\n \"metadata missing\",\n [nameOf(cls)],\n `${nameOf(cls)} constructor`,\n `${nameOf(cls)} declares ${arity} parameter(s) but carries ` +\n `${meta === undefined ? \"no\" : String(meta.length)} metadata entries, ` +\n `so every parameter would arrive as undefined.`,\n [\n `add @Injectable() to ${nameOf(cls)} — metadata is emitted for DECORATED classes only`,\n \"or the build ran without emitDecoratorMetadata: check tsconfig.json\",\n ],\n );\n }\n\n const meta = Reflect.getMetadata(\"design:paramtypes\", cls) as unknown[];\n const list: Token[] = [];\n meta.forEach((t, i) => {\n const at = `${nameOf(cls)} constructor, parameter ${i}`;\n\n if (typeof t !== \"function\" || UNRESOLVABLE.has(t)) {\n throw new DiError(\n \"unresolvable dependency\",\n [nameOf(cls)],\n at,\n `parameter ${i} has no runtime class — an interface, a type alias, a ` +\n `union, or a data type. The container has nothing to construct.`,\n DATA.has(t)\n ? [\n \"an injectable's constructor takes dependencies, not data\",\n \"move the value to a method argument instead\",\n \"or make this a plain value class (no @Injectable, in no module) and `new` it yourself\",\n ]\n : [\n \"depend on a concrete class or an abstract class\",\n \"a TypeScript interface does not exist at runtime — there is nothing to inject\",\n ],\n );\n }\n\n const dep = t as Token;\n\n {\n let dm = owner.get(dep);\n if (dm === undefined) {\n // An ABSTRACTION, resolved to its one implementation (FR-055).\n //\n // Read from `extends`, not from a second syntax: `class SystemClock\n // extends Clock` is the class declaring \"I am a Clock\", and that is a\n // declaration — not an inference from where a file sits.\n const impls = implementorsOf(dep);\n if (impls.length === 1) {\n const impl = impls[0] as Token;\n list.push(impl);\n dm = owner.get(impl) as string;\n if (dm !== m) {\n if (!importsOf.get(m)?.has(dm)) {\n throw new DiError(\n \"missing import\",\n [nameOf(cls), nameOf(impl)],\n at,\n `${nameOf(impl)} implements ${nameOf(dep)} and is owned by ${dm}, which ${m} does not import.`,\n [`add ${dm} to ${m}.imports`],\n );\n }\n if (!exported.get(dm)?.has(impl)) {\n throw new DiError(\n \"private dependency\",\n [nameOf(cls), nameOf(impl)],\n at,\n `${nameOf(impl)} implements ${nameOf(dep)} but is internal to ${dm}.`,\n [`add ${nameOf(impl)} to ${dm}.exports (and say why)`],\n );\n }\n }\n return;\n }\n if (impls.length > 1) {\n const names = impls.map(nameOf).sort();\n throw new DiError(\n \"duplicate ownership\",\n [nameOf(cls), nameOf(dep)],\n at,\n `${names.join(\" and \")} both extend ${nameOf(dep)}, so which one ` +\n `${nameOf(cls)} should receive has two answers.`,\n [\n `keep ONE class extending ${nameOf(dep)} in this graph`,\n `or depend on ${names[0]} or ${names[1]} directly, by name`,\n ],\n );\n }\n throw new DiError(\n \"unowned class\",\n [nameOf(cls), nameOf(dep)],\n at,\n `${nameOf(dep)} belongs to no module, and nothing in this graph extends it — ` +\n `so there is nothing to construct. (An abstract class cannot be built: ` +\n `\\`abstract\\` is a type-level claim, and \\`new\\` on one returns an object ` +\n `missing every abstract member.)`,\n [\n `add ${nameOf(dep)} to a module's providers if it is concrete`,\n `or add a class that \\`extends ${nameOf(dep)}\\` to a module's providers`,\n ],\n );\n }\n if (dm !== m) {\n if (!importsOf.get(m)?.has(dm)) {\n throw new DiError(\n \"missing import\",\n [nameOf(cls), nameOf(dep)],\n at,\n `${nameOf(dep)} is owned by ${dm}, which ${m} does not import.`,\n [`add ${dm} to ${m}.imports`],\n );\n }\n if (!exported.get(dm)?.has(dep)) {\n throw new DiError(\n \"private dependency\",\n [nameOf(cls), nameOf(dep)],\n at,\n `${nameOf(dep)} is internal to ${dm} — it is not exported.`,\n [\n `use one of ${dm}'s exported classes`,\n `or add ${nameOf(dep)} to ${dm}.exports (and say why it should be public)`,\n ],\n );\n }\n }\n }\n\n list.push(dep);\n });\n\n deps.set(cls, list);\n }\n\n // 4 · cycles — refused, with the path written out by name.\n //\n // There is NO `forwardRef`-style escape, and the reason is that the shape one\n // exists to rescue cannot be built: a real ESM cycle dies at import. Measured\n // in the spike — Bun throws `Cannot access 'CB' before initialization` before\n // the container is ever consulted. What CAN still be assembled is a cycle\n // inside one file, so the detector earns its place; what it never has to do is\n // offer a way to keep one.\n const state = new Map<Token, 0 | 1 | 2>();\n const stack: Token[] = [];\n const walk = (c: Token): void => {\n if (state.get(c) === 1) {\n // Slice from where this class first entered the stack, so the message is\n // the CYCLE and not the path that happened to reach it.\n const cyc = [...stack.slice(stack.indexOf(c)), c].map(nameOf);\n throw new DiError(\n \"dependency cycle\",\n cyc,\n `${cyc[0]} constructor`,\n `the dependency graph contains a cycle: ${cyc.join(\" -> \")}.`,\n [\n \"extract the shared part into a third class both can depend on\",\n \"or invert one direction — have the callee raise an event the caller listens for\",\n ],\n );\n }\n if (state.get(c) === 2) return;\n state.set(c, 1);\n stack.push(c);\n // A platform token needs no special case: it has no `deps` entry, so the\n // walk reaches it, finds nothing to follow, and marks it done. A guard here\n // would be an inert check — it was written, measured against a mutation, and\n // removed when removing it changed nothing.\n for (const d of deps.get(c) ?? []) walk(d);\n stack.pop();\n state.set(c, 2);\n };\n for (const c of owner.keys()) walk(c);\n\n // 5 · resolution — ONE lifetime, singleton.\n //\n // No `transient`, no `request`. Request scope already exists and it is an\n // AsyncLocalStorage, not an object lifetime: what varies per request is the\n // database handle and the claims, and the engine opens that scope around the\n // handler. Making the OBJECTS per-request would duplicate that mechanism and\n // then have to keep the two in agreement.\n //\n // The consequence is a rule about constructors: they stay synchronous and do\n // nothing but wiring. Real I/O belongs in `onStart`, where it can fail loudly\n // at boot instead of halfway through the first request.\n const cache = new Map<Token, unknown>();\n const make = (c: Token): unknown => {\n // A token this container never validated is NOT built. Measured before this\n // check existed: `get(Stranger)` found no `deps` entry, fell through to\n // `new Stranger()` with zero arguments, and returned it — so a class in no\n // module could still be constructed through the container's own front door,\n // which is the hole the module system exists to close (FR-053).\n //\n // There is no platform escape hatch here: platform services (Database, Log,\n // …) are AMBIENT — imported, not injected — because they are request-scoped\n // and a boot-time singleton holding one would capture the first request's\n // client forever (FR-005). Nothing supplies a platform map, so having one\n // would be an inert extension point.\n if (!owner.has(c)) {\n throw new DiError(\n \"unowned class\",\n [nameOf(c)],\n \"container.get\",\n `${nameOf(c)} belongs to no module, so this container never validated it ` +\n `and will not build it.`,\n [\n `add ${nameOf(c)} to a module's providers`,\n \"or, if it is a plain value class, construct it yourself with `new`\",\n ],\n );\n }\n const hit = cache.get(c);\n if (hit !== undefined) return hit;\n const args = (deps.get(c) ?? []).map(make);\n const inst = new (c as unknown as new (...a: unknown[]) => unknown)(...args);\n cache.set(c, inst);\n return inst;\n };\n\n return {\n get: <T,>(t: Token<T>): T => make(t) as T,\n owned: new Set(owner.keys()),\n pressure: computePressure(entries),\n };\n}\n\n/**\n * What fraction of the OTHER modules import each module.\n *\n * `total - 1` is the denominator because a module never imports itself, so the\n * most any module can reach is everyone else. Under two modules there is nothing\n * to compare and the answer is an empty list rather than a misleading 100%.\n */\nfunction computePressure(entries: { mod: Token; def: ModuleDef }[]): ModulePressure[] {\n // No `total < 2` guard, and none is needed: a single module cannot import\n // anything (there is no other module, and both self-import and non-module\n // imports are refused above), so `count` is empty and the division below never\n // runs. The guard was written, measured against a mutation, and removed when\n // removing it changed nothing — an inert check still draws a number.\n const total = entries.length;\n const count = new Map<string, number>();\n for (const { def } of entries) {\n for (const i of def.imports ?? []) {\n const n = nameOf(i);\n count.set(n, (count.get(n) ?? 0) + 1);\n }\n }\n return [...count]\n .map(([module, c]) => ({ module, pct: Math.round((c / (total - 1)) * 100), of: total - 1 }))\n .sort((a, b) => b.pct - a.pct);\n}\n\n/** Kept so the module surface is stable while stages 3-5 land. */\nexport type { ModuleDef };\n\n/**\n * Refuses an entry point that no module lists (FR-035).\n *\n * A decorated class registers itself — `@Controller` pushes into a globalThis\n * slot the moment its file is imported — so before this check a class listed in\n * no module still reached the route table, the dispatcher and the OpenAPI\n * document. It worked, which is the problem: nothing said the module system had\n * been bypassed.\n *\n * After this, a successful boot means the two sets are EQUAL: what decorated\n * itself and what a module claimed. That equality is what lets `src/openapi/`\n * stay untouched — it renders the list it is handed, and the list is now the\n * module's.\n */\nexport function assertNoOrphanEntryPoints(\n registered: readonly unknown[],\n owned: ReadonlySet<Token>,\n): void {\n const orphans = registered.filter((c) => !owned.has(c as Token));\n if (orphans.length === 0) return;\n const names = orphans.map((c) => (c as { name?: string }).name ?? \"<anonymous>\");\n throw new DiError(\n \"unowned class\",\n names,\n \"module declarations\",\n `${names.join(\", \")} ${orphans.length === 1 ? \"is\" : \"are\"} decorated as an entry ` +\n `point but listed in no module, so nothing decides whether it should be served.`,\n [\n \"add it to a module's `controllers` (for @Controller) or `providers` (for @Room/@Job/@Hook/@Webhook)\",\n \"an entry point no module lists is never mounted and never reaches the OpenAPI document\",\n ],\n );\n}\n","import { type Token } from \"./module.js\";\n\n/**\n * The slot injectable declarations accumulate in.\n *\n * On `globalThis` under a well-known Symbol for the same reason `DI_MODULES` is\n * (see `module.ts`): a tenant bundle inlines its OWN copy of `@palbase/backend`\n * and the engine that loads it carries another, so a module-local array would\n * have the decorators push into one and the container read the other.\n */\nexport const DI_INJECTABLES: unique symbol = Symbol.for(\n \"palbase.backend.diInjectables\",\n) as never;\n\n/**\n * The marker `@Injectable()` leaves ON the class.\n *\n * Two signals, because two questions are being asked and only one of them can be\n * answered by a list. \"WHICH classes were declared in this build\" needs an\n * enumeration and gets the claimable slot below. \"IS this class decorated\" needs\n * an answer that survives Bun's module cache: a rollback re-imports an artifact\n * whose body does not run again, so the slot comes back empty while the modules\n * still list the same classes. Reading the slot for that question refused a\n * correct app — measured in `engine.test.ts`, where the second `createApp` in\n * one process saw an emptied slot and called every provider undecorated.\n */\nexport const INJECTABLE: unique symbol = Symbol.for(\"palbase.backend.injectable\") as never;\n\n/** Does this class carry `@Injectable()`? Reads the class, not a registry. */\nexport const isInjectable = (c: unknown): boolean =>\n (c as Record<symbol, unknown> | null)?.[INJECTABLE] === true;\n\nfunction slot(): Token[] {\n const g = globalThis as unknown as Record<symbol, Token[] | undefined>;\n return (g[DI_INJECTABLES] ??= []);\n}\n\n/**\n * Marks a class the container can resolve.\n *\n * TWO JOBS, and the first one is why the decorator has to exist at all:\n * TypeScript under `emitDecoratorMetadata` emits `design:paramtypes` for\n * DECORATED classes only. Measured — an undecorated class with the same\n * constructor carries no metadata, and `Reflect.getMetadata` answers\n * `undefined`.\n *\n * The second is being COUNTABLE. Ownership, visibility and permission are still\n * read from a single `@Module` and never from this decorator — recording the\n * class here decides nothing. It only makes \"carries `@Injectable()` and\n * appears in no module\" a question the build can ask, which FR-010 requires it\n * to answer by name. The body was empty until 2026-09-02, and the consequence\n * was measured through the CLI: an `@Injectable()` service in no module built\n * clean, while this file's own comment claimed the build named it.\n */\nexport function Injectable(): ClassDecorator {\n return (target) => {\n (target as unknown as Record<symbol, unknown>)[INJECTABLE] = true;\n slot().push(target as unknown as Token);\n };\n}\n\n/**\n * TAKES the accumulated declarations — it does not read them.\n *\n * Same claim semantics as `__claimModules`, and for the same reason: a\n * candidate bundle is imported into the SAME process as the live app it might\n * replace, so reading would let a candidate be judged against the live app's\n * classes and a discarded candidate would leave its own behind.\n */\nexport function __claimInjectables(): Token[] {\n return slot().splice(0);\n}\n","import type { Container, Token } from \"../container.js\";\n\n/**\n * Which of a container's classes are entry points of each kind.\n *\n * Discovery used to be a DIRECTORY: `jobs/*.ts` was the list of jobs, and\n * `@Job` recorded metadata but registered nothing. That made the file system a\n * second declaration — a class could carry `@Job`, sit outside `jobs/`, and\n * never run; or sit inside it, be listed in no module, and run anyway.\n *\n * Now a module lists it and the decorator says what it is. One declaration\n * answers ownership, and the metadata answers kind. These four predicates are\n * the only place that mapping lives.\n */\nconst JOB = Symbol.for(\"palbase.backend.jobMeta\");\nconst WEBHOOK = Symbol.for(\"palbase.backend.webhookMeta\");\nconst HOOK_BLOCKING = Symbol.for(\"palbase.backend.hookBlocking\");\nconst HOOK_LISTENERS = Symbol.for(\"palbase.backend.webhookEvents\");\nconst ROOM = Symbol.for(\"palbase.backend.room\");\nconst CONTROLLER = Symbol.for(\"palbase.backend.controllerMeta\");\n\nconst has = (c: unknown, s: symbol): boolean =>\n (c as Record<symbol, unknown>)[s] !== undefined;\n\n/**\n * Does this class carry one of the surface decorators?\n *\n * The container asks, because `providers` legitimately holds `@Job`, `@Hook`,\n * `@Webhook` and `@Room` classes alongside `@Injectable()` ones, and the rule it\n * enforces there — a provider must be DECORATED, so it is constructible and its\n * constructor's types were emitted — has to know that. The predicate lives here\n * because this file is the one place the marker symbols are named.\n */\nexport const isEntryPointClass = (c: unknown): boolean =>\n has(c, JOB) || has(c, WEBHOOK) || has(c, ROOM) || has(c, CONTROLLER) ||\n has(c, HOOK_BLOCKING) || has(c, HOOK_LISTENERS);\n\nconst owned = (container: Container): Token[] => [...container.owned];\n\nexport const jobsOf = (container: Container): Token[] => owned(container).filter((c) => has(c, JOB));\n\nexport const webhooksOf = (container: Container): Token[] =>\n owned(container).filter((c) => has(c, WEBHOOK));\n\n/**\n * A hook class carries handler entries and NO class-level marker, so it is\n * recognised by having handlers while being neither a webhook nor a controller.\n * `@On` is shared with `@Webhook`, which is why the webhook marker is what\n * separates them.\n */\nexport const hooksOf = (container: Container): Token[] =>\n owned(container).filter(\n (c) =>\n !has(c, WEBHOOK) &&\n !has(c, CONTROLLER) &&\n (has(c, HOOK_BLOCKING) || has(c, HOOK_LISTENERS)),\n );\n\nexport const roomsOf = (container: Container): Token[] =>\n owned(container).filter((c) => has(c, ROOM));\n\nexport const controllersOf = (container: Container): Token[] =>\n owned(container).filter((c) => has(c, CONTROLLER));\n","/**\n * A class the container can resolve, named by its own constructor.\n *\n * There is NO separate token concept — no strings, no symbols, no `@Inject`.\n * An abstraction is an `abstract class`, which is still a runtime value and so\n * is still a token. `never[]` on the parameters makes a token something you can\n * NAME but not call: `Token` is an identity, not a factory.\n */\nexport type Token<T = unknown> = abstract new (...args: never[]) => T;\n\n/**\n * The four lists a module declares.\n *\n * `providers` is OWNERSHIP — a class belongs to exactly one module and this is\n * where that is said. `exports` is VISIBILITY — what other modules may reach.\n * `imports` is PERMISSION — whose exports this module may reach. `controllers`\n * are the entry points the module owns.\n *\n * Position in a list means nothing; ownership is read from this declaration and\n * from nowhere else — not from a directory, not from a file name, not from the\n * class's own decorator (spec FR-009).\n */\nexport interface ModuleDef {\n imports?: Token[];\n controllers?: Token[];\n providers?: Token[];\n exports?: Token[];\n}\n\n/**\n * The slot module declarations accumulate in.\n *\n * On `globalThis` under a well-known Symbol, for the same reason\n * `lifecycleHooks` is (runtime.ts:210): a tenant bundle inlines its OWN copy of\n * `@palbase/backend`, and the engine that loads it carries another. Two\n * module-local arrays would mean the engine reads the empty one — decorators\n * push into the bundle's copy, `createApp` claims from the engine's, and every\n * module silently disappears.\n */\nexport const DI_MODULES: unique symbol = Symbol.for(\"palbase.backend.diModules\") as never;\n\n/** One `@Module` declaration: the class that carried it, and what it declared. */\nexport interface ModuleEntry {\n mod: Token;\n def: ModuleDef;\n}\n\nfunction slot(): ModuleEntry[] {\n const g = globalThis as unknown as Record<symbol, ModuleEntry[] | undefined>;\n return (g[DI_MODULES] ??= []);\n}\n\n/**\n * Declares a module.\n *\n * There is no root module and nothing to mount it into: registration IS the\n * decorator running, which happens when the file is imported. A project with no\n * module file at all is not an error — it simply owns nothing, and every entry\n * point it declares is refused by name (FR-035) rather than quietly served.\n */\nexport function Module(def: ModuleDef): ClassDecorator {\n return (target) => {\n slot().push({ mod: target as unknown as Token, def });\n };\n}\n\n/**\n * TAKES the accumulated declarations — it does not read them.\n *\n * Same reason `__runStartHooks` splices (runtime.ts:297): a candidate bundle is\n * imported into the SAME process as the live app it might replace. Reading\n * would let the candidate build a container out of the live app's modules, and\n * a discarded candidate would leave its own behind for the next release to\n * adopt. Claiming makes each `createApp` see exactly the modules imported since\n * the last one, and a rollback leave nothing behind.\n */\nexport function __claimModules(): ModuleEntry[] {\n return slot().splice(0);\n}\n","/**\n * engine/fence.ts — what the tenant's own code may reach.\n *\n * The isolate used to answer this by construction: tenant code ran in a realm\n * with no ambient network and an environment scrubbed of every secret, and each\n * privileged call hopped to a host that held the credentials. Running the\n * backend as one process removes that wall, so the two guarantees it carried\n * have to be re-made here — deliberately, and with the honest note that a\n * same-process fence is a SPEED BUMP against the tenant's own code, not a\n * sandbox. The real boundary is the machine: each tenant has its own.\n *\n * That is not a hole, it is a scope. The tenant owns this database and this\n * network namespace; the thing worth preventing is an ACCIDENT — a dependency\n * that reads `process.env` and posts it somewhere, a handler that opens its own\n * unscoped connection and quietly serves every user's rows — not a determined\n * operator attacking their own stack.\n */\n\n/** Names the engine holds and the tenant's code must not find lying around. */\nconst SECRET_ENV = [\n \"DATABASE_URL\",\n \"PALBASE_SERVICE_ROLE_KEY\",\n \"REALTIME_INGESTION_SECRET\",\n \"INTERNAL_API_SECRET\",\n \"STACK_ROOT_KEY\",\n \"PEPPER\",\n \"LOCAL_JWT_PEM\",\n] as const;\n\nexport interface ScrubResult {\n removed: string[];\n kept: string[];\n}\n\n/**\n * Delete the engine's own credentials from `process.env`.\n *\n * MUST run AFTER the config is read and BEFORE the tenant bundle is imported —\n * a bundle's module-level code runs at import, so a scrub that comes later has\n * already lost the race.\n *\n * The tenant's OWN variables (`PALBASE_VAR_*` and anything else) are untouched:\n * this removes what the platform put there, not what the operator did.\n *\n * Why RLS makes this matter: the engine binds every request to the caller with\n * `set_config('role', …)` so Postgres does the row filtering. Code that finds\n * `DATABASE_URL` can open its own connection as the owner and read every user's\n * rows — not by attacking anything, just by using a driver.\n */\nexport function scrubSecrets(env: Record<string, string | undefined>): ScrubResult {\n const removed: string[] = [];\n const kept: string[] = [];\n for (const name of SECRET_ENV) {\n if (env[name] === undefined) continue;\n delete env[name];\n removed.push(name);\n }\n for (const name of Object.keys(env)) if (name.startsWith(\"PALBASE_VAR_\")) kept.push(name);\n return { removed, kept };\n}\n\nexport interface EgressPolicy {\n /** Hostnames the tenant declared. Empty ⇒ no declaration was made. */\n allow: readonly string[];\n /** Per-call ceiling in ms. 0 ⇒ no ceiling declared. */\n timeoutMs: number;\n /** What to do when nothing was declared. */\n whenUndeclared: \"allow\" | \"deny\";\n /**\n * Hosts the BACKEND ITSELF needs: its module surface, the JWKS it verifies\n * tokens against, the artifact store it reloads from.\n *\n * These are not egress. `config/egress.ts` declares where the tenant's own\n * code may reach; a call to the platform this backend is part of is internal\n * traffic, and fencing it means the first deploy with an allowlist takes the\n * backend down — which is exactly what happened when this list did not exist:\n * every request 500'd with \"egress denied: palsvc is not in this backend's\n * declared allowlist\", and the artifact reload loop stopped with it.\n */\n alwaysAllow?: readonly string[];\n}\n\n/** `api.stripe.com` matches itself; `*.stripe.com` matches any subdomain. */\nexport function hostAllowed(host: string, allow: readonly string[]): boolean {\n const h = host.toLowerCase();\n for (const raw of allow) {\n const pattern = raw.trim().toLowerCase();\n if (!pattern) continue;\n if (pattern === h) return true;\n if (pattern.startsWith(\"*.\") && h.endsWith(pattern.slice(1)) && h.length > pattern.length - 1) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Install the tenant's declared outbound allowlist over `globalThis.fetch`.\n *\n * The engine's own traffic is exempted by HOST (`alwaysAllow`), not by holding\n * a captured reference: the module clients and the verifier resolve\n * `globalThis.fetch` at CALL time, so a captured original never reaches them.\n * That distinction is not academic — the first version of this file claimed the\n * capture worked, and every request 500'd on the first deploy that declared an\n * allowlist.\n *\n * @returns the original fetch, for the engine's own use.\n */\nexport function installEgressFence(policy: EgressPolicy): typeof fetch {\n const original = globalThis.fetch.bind(globalThis);\n const declared = policy.allow.length > 0;\n const platform = (policy.alwaysAllow ?? []).map((h) => h.toLowerCase()).filter(Boolean);\n\n if (!declared && policy.whenUndeclared === \"allow\") return original;\n\n const fenced: typeof fetch = async (input, init) => {\n const url =\n typeof input === \"string\"\n ? new URL(input)\n : input instanceof URL\n ? input\n : new URL((input as Request).url);\n\n // The backend's own platform first — internal traffic is not egress.\n if (platform.includes(url.hostname.toLowerCase())) return original(input, init);\n\n if (!declared || !hostAllowed(url.hostname, policy.allow)) {\n throw new Error(\n `egress denied: ${url.hostname} is not in this backend's declared allowlist. ` +\n `Add it to config/egress.ts and deploy.`,\n );\n }\n if (policy.timeoutMs > 0) {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), policy.timeoutMs);\n try {\n return await original(input, { ...init, signal: init?.signal ?? controller.signal });\n } finally {\n clearTimeout(timer);\n }\n }\n return original(input, init);\n };\n\n globalThis.fetch = fenced;\n return original;\n}\n"],"mappings":"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","names":["REF_BRAND","Symbol","for","brandRef","v","kind","Object","defineProperty","value","enumerable","brandOf","undefined","hasOwn","looksLikeUnbrandedRef","isColumnExpr","o","$col","$sql","$expr","isColRef","isPlanRef","r","$ref","op","field","looksLikeUnbrandedPlanRef","isSqlFragment","f","Array","isArray","text","values","TX_EXPR","isNowExpr","e","fn","assertNoExpressionHandles","caller","table","cols","data","c","Error","KNOWN_OPS","Set","REFUSED_OPS","eq","assertUsableFilter","where","COMPOSITES","col","cond","entries","has","branches","b","rel","inner","length","some","x","assertUsableWriteValues","TxRefError","Error","message","name","TxPlanError","EXPR","Symbol","for","REF","ROW","ROWS","TRAPPED_PROPS","toPrimitive","trap","prop","what","hint","description","String","columnExprOf","v","exprOf","makeRef","op","field","target","REF","Proxy","get","t","prop","TRAPPED_PROPS","includes","trap","undefined","makeRowHandle","ROW","refDescriptor","v","d","isRefDescriptor","rowOpIndex","exprOf","e","EXPR","isRowsHandle","ROWS","encodeValue","value","column","allowColumnExpr","ref","brandRef","$ref","isNowExpr","$expr","fn","expr","TxPlanError","assertNoNestedHandles","encodeFilterValue","Array","isArray","map","Date","isColRef","isSqlFragment","out","k","Object","entries","encodeFilterMap","key","keys","sort","item","values","encodeMap","SKIPPED_OP","TxRowsImpl","guarded","builder","opIndex","what","then","TxRefError","expectOne","error","declareGuard","expectNone","expectAtLeast","n","assertGuardCount","expectAtMost","kind","Error","attachGuard","Number","isInteger","String","MAX_OPS","MAX_ROWS","TxPlanBuilder","ops","slots","table","name","insert","encoded","length","push","put","options","onConflict","insertMany","rows","opts","row","assertUniformRows","action","updateWhere","where","set","encodedWhere","encodedSet","deleteWhere","select","limit","lock","index","slot","guard","body","errorForSlot","first","want","wantKey","join","i","got","materializeResult","results","rowOf","rowOp","isPlainObject","result","proto","getPrototypeOf","prototype","runTxPlan","transport","handle","returned","response","txPlan","err","translateRejection","rejection","error_code","retryBudget","value","n","Number","isInteger","Error","validateAtomicOptions","options","retry","isolation","undefined","includes","readOnly","name","signal","aborted","addEventListener","assertPlanRetry","qualifiedTableKey","schemaName","tableName","REQUEST_ALS","Symbol","for","__requestALS","g","globalThis","AsyncLocalStorage","runtime","__runWithRuntime","services","fn","__requestALS","run","runtime","REQUIRED_SERVICES","refuseIncompleteBox","missing","filter","k","undefined","length","Error","join","__getRuntime","scoped","getStore","LIFECYCLE","Symbol","for","declaredLifecycle","g","globalThis","start","shutdown","reason","err","Error","message","String","drain","hooks","h","reverse","run","console","error","name","__runStartHooks","slot","declaredLifecycle","start","splice","shutdown","cause","drained","makeServiceProxy","key","handler","get","_target","prop","receiver","client","__getRuntime","value","Reflect","bind","Proxy","makeTableProxy","ops","prefix","_t","undefined","name","insert","data","aggregate","q","insertMany","rows","opts","update","where","id","set","delete","findById","findUnique","select","with","page","findMany","put","onConflict","updateMany","returning","deleteMany","count","search","params","similar","recommend","facets","supersede","row","claim","unique","extra","rawDatabase","makeTypedSurface","raw","reco","$query","sql","query","$diagnostics","diagnostics","$insert","table","$update","$delete","$findById","$findUnique","$page","$findMany","$put","$updateMany","$deleteMany","$count","$search","$similar","$recommend","$facets","$claim","$lockRows","ids","lockRows","$lockRowsWhere","lockRowsWhere","$advisoryXactLock","advisoryXactLock","$aggregate","$insertMany","$supersede","base","Object","assign","$atomic","fn","options","atomic","Error","parent","__requestALS","getStore","runtime","tx","typed","invoke","refuse","ambient","asService","run","Database","$attempt","attempt","$transaction","assertPlanRetry","builder","TxPlanBuilder","runTxPlan","makeTxPlanHandle","$command","txPlan","plan","command","target","startsWith","qualifiedTableKey","makeTxTablesAccessor","tablesProxy","publicTables","$asService","Documents","makeBucketsAccessor","storage","bucket","rawStorage","Storage","buckets","Cache","Secrets","Auth","Log","Notifications","rawFlags","Flags","isEnabled","flagName","context","getVariant","getAll","defaultOrContext","maybeContext","setOverride","Realtime","SQLSTATE","Object","freeze","serializationFailure","deadlockDetected","queryCancelled","commandGuardFailed","isTransactionRollbackState","state","HTTP_ERROR_BRAND","Symbol","for","ENGINE_RAISED","markEngineRaised","e","isEngineRaised","isHttpError","err","status","error","errorDescription","HttpError","Error","data","name","undefined","toJSON","requestId","result","error_description","request_id","NamedHttpError","HttpError","status","defaultCode","name","message","code","data","defaultMessage","spaced","replace","charAt","toUpperCase","slice","toLowerCase","BadRequest","undefined","Conflict","NamedHttpError","message","code","data","UniqueViolation","is","e","name","constraint","isRetryable","retryable","isTransactionRollbackState","sqlstate","SerializationFailure","SQLSTATE","serializationFailure","DeadlockDetected","deadlockDetected","TooManyRequests","undefined","BootRefused","Error","missing","message","name","MANDATORY","key","what","loadConfig","env","filter","m","trim","map","length","detail","includes","padEnd","join","port","Number","PORT","isInteger","poolMax","DB_POOL_MAX","capacityNumber","minimum","maximum","undefined","value","isSafeInteger","queueLimit","queueTimeoutMs","tenantClaim","PALBASE_DB_TENANT_CLAIM","test","databaseUrl","DATABASE_URL","authJwksUrl","AUTH_JWKS_URL","authIssuer","AUTH_ISSUER","moduleBaseUrl","MODULE_BASE_URL","replace","publicOrigin","PALBASE_PUBLIC_ORIGIN","uploadSecret","PALBASE_UPLOAD_SECRET","anonKey","PALBASE_ANON_KEY","serviceRoleKey","PALBASE_SERVICE_ROLE_KEY","cursorSecret","PALBASE_CURSOR_SECRET","enableCommands","PALBASE_DB_COMMANDS","realtimeSecret","REALTIME_INGESTION_SECRET","dbRole","DB_ROLE","dbServiceRole","DB_SERVICE_ROLE","databaseAdmission","PALBASE_DB_DIAGNOSTICS","databaseDiagnostics","onComplete","diagnostics","console","log","JSON","stringify","DECLARATION_REFUSAL","Symbol","for","DeclarationRefused","Error","message","name","isDeclarationRefused","e","b64urlToBytes","s","pad","replace","full","padEnd","Math","ceil","length","bin","atob","out","Uint8Array","ArrayBuffer","i","charCodeAt","AuthVerifier","keys","Map","fetchedAt","inflight","jwksUrl","issuer","fetchImpl","ttl","opts","a","fetch","keysetTtlMs","refresh","res","ok","body","json","next","jwk","kty","crv","set","kid","crypto","subtle","importKey","x","y","ext","name","namedCurve","size","Date","now","key","stale","has","get","verify","authorization","startsWith","parts","slice","trim","split","h","p","sig","undefined","header","claims","JSON","parse","TextDecoder","decode","alg","hash","TextEncoder","encode","exp","iss","effectiveAuth","routeAuth","controllerAuth","spec","required","verifiedEmail","o","role","permission","RateLimiter","buckets","Map","maxKeys","key","routeId","userId","headers","fwd","get","addr","split","trim","check","rule","now","max","window","bucket","resetAt","size","evict","set","count","Math","ceil","dropped","k","b","delete","byReset","entries","sort","a","i","length","victim","makeMemoryCache","opts","maxEntries","now","Date","store","Map","inflight","live","key","e","get","undefined","expiresAt","delete","evict","t","dropped","k","order","entries","sort","a","b","Infinity","i","Math","ceil","length","victim","set","value","ttl","size","has","del","incr","next","getOrSet","fn","hit","running","fill","import_node_async_hooks","memoTable","cache","schema","table","compute","tables","Object","hasOwn","get","Map","set","has","snapshotDeclaration","value","seen","WeakMap","previous","Date","getTime","result","Array","isArray","create","getPrototypeOf","key","Reflect","ownKeys","descriptor","getOwnPropertyDescriptor","defineProperty","freeze","key","invalidPage","message","field","BadRequest","fields","setCursorKey","secret","createHash","update","digest","cursorKey","Error","fingerprint","value","stable","v","$bigint","toString","Date","$date","toISOString","Array","isArray","map","Object","fromEntries","keys","sort","k","JSON","stringify","cursorIdentity","role","claimsJson","claims","parse","iat","exp","nbf","jti","authorization","encodeCursor","scope","values","nonce","randomBytes","cipher","createCipheriv","setAAD","Buffer","from","body","concat","final","token","getAuthTag","length","decodeCursor","count","test","data","slice","createDecipheriv","subarray","setAuthTag","some","pageOrder","columns","primaryKey","opts","raw","backward","last","undefined","before","first","after","size","Number","isInteger","input","orderBy","seen","Set","order","add","o","def","column","hasOwn","has","type","direction","nulls","push","nullable","at","pageBoundary","bind","inclusive","refs","every","greater","join","parts","prefix","i","c","r","nullsLast","cmp","tail","validateInsertManyOptions","opts","returning","undefined","Error","action","onConflict","Array","isArray","some","c","length","uniqueKeysOf","table","columns","inlinePrimary","keys","name","value","Object","entries","col","_def","primaryKey","push","unique","primary","length","unshift","key","seen","Set","filter","size","some","hasOwn","Error","identity","JSON","stringify","sort","has","add","assertUniqueLookup","where","Array","isArray","every","map","join","undefined","Date","installed","WeakSet","hasCommandExecutor","sql","has","COMMAND_EXECUTOR_DDL","installCommandExecutor","roles","quote","s","replace","length","Error","begin","tx","unsafe","list","Set","map","join","add","parameterChunks","chunks","start","i","c","parameter","exec","slice","push","bind","Number","DatabaseAdmission","active","queued","tenants","Map","pending","lastTenant","accepted","rejected","full","timeout","cancelled","limit","options","queueLimit","Math","min","max","concurrency","queueTimeoutMs","Number","isSafeInteger","Error","snapshot","size","rejection","reason","onReject","take","tenant","entered","set","get","released","queueMs","performance","now","release","count","delete","drain","keys","next","value","queue","waiter","values","cleanup","grant","acquire","claimsJson","signal","aborted","claims","JSON","parse","tenantClaim","sub","length","TooManyRequests","retryAfter","Promise","reject","Set","has","remove","error","abort","timer","setTimeout","clearTimeout","removeEventListener","add","addEventListener","once","databases","WeakMap","databaseAdmission","owner","admission","key","TransactionControl","controller","AbortController","active","Set","cancelBackend","cancellation","Promise","resolve","timer","unlink","rejection","deadline","signal","timeoutMs","external","undefined","performance","now","_","reject","addEventListener","reason","size","catch","query","cancel","once","abort","DOMException","removeEventListener","aborted","setTimeout","HttpError","check","throwIfAborted","remainingMs","Math","max","ceil","race","work","bindBackend","drainCancellation","allSettled","watch","add","delete","dispose","clearTimeout","import_node_crypto","DatabaseTrace","start","performance","now","ended","failure","state","options","key","value","undefined","Number","isSafeInteger","Error","endpoint","requestId","outcome","elapsedMs","queries","rows","bytes","queueMs","poolMs","setupMs","sqlMs","commitMs","rollbackMs","connectionMs","commits","commitFailures","rollbackRequests","retries","statements","check","time","started","retry","committed","commitFailed","failed","rolledBack","refuse","kind","HttpError","emit","callback","event","result","Promise","resolve","catch","query","sql","name","run","maxQueries","ordinal","fingerprint","createHash","update","digest","slice","includeSql","durationMs","captureSource","source","stack","split","join","measured","Array","isArray","length","Buffer","byteLength","JSON","stringify","_","toString","maxRows","maxBytes","error","e","errorCode","String","sqlstate","errno","code","frozen","Object","freeze","push","onQuery","snapshot","sort","a","b","complete","onComplete","CODECS","number","fromDb","v","Number","toDb","isSafeInteger","Error","String","tsType","decimal","undefined","forwardName","column","endsWith","slice","describeOrigin","o","direction","table","renameCall","def","owns","target","references","selfRefColumn","undefined","buildRelations","schemas","out","Map","taken","schema","t","Object","values","tables","key","qualifiedTableKey","name","set","claim","tableKey","origin","edge","names","get","held","DeclarationRefused","heldFix","originFix","remedy","push","childKey","has","col","builder","entries","columns","_def","targetKey","refAs","to","kind","via","reverse","reverseAs","quoteIdent","name","replace","quoteTable","key","dot","indexOf","slice","encodePgArray","value","element","x","undefined","Array","isArray","String","map","join","BIND_SQL","atomicScope","AsyncLocalStorage","createLazyTransaction","sql","role","claimsJson","options","lockTimeout","bindSql","bindParams","statementTimeout","push","length","opening","release","fail","settled","closed","assertAccess","Error","control","check","trace","getStore","scope","savepointALS","activeSavepoint","pendingSavepoints","Set","scoped","tx","checkParent","owner","children","access","unsafe","text","params","metadata","run","query","watch","savepoint","fn","token","Symbol","descendants","work","sp","ended","callback","race","size","Promise","allSettled","add","delete","ensure","resolveTx","rejectTx","parked","res","rej","catch","queuedAt","performance","now","lease","admission","databaseAdmission","acquire","signal","time","openingAt","connectedAt","begin","setupAt","isolation","readOnly","validateAtomicOptions","toUpperCase","cancelBackend","ticket","Number","isInteger","pid","started","bindBackend","binding","e","opened","commit","committed","error","commitFailed","rollback","reason","drainCancellation","rolledBack","asWireValue","Date","toISOString","asWireRow","row","out","Object","entries","asWireRows","rows","toVectorLiteral","v","computeVectorColumns","schema","table","def","tableDefOf","col","c","columns","d","_def","type","currentSchema","tables","reviveVectors","vectorCols","JSON","parse","computeTransforms","Map","codec","CODECS","c2","set","fromDb","toDb","t","transform","applyFromDb","transforms","asTableRow","revived","vectorColumnsOf","foldCan","transformsOf","asTableRows","withSpec","partial","result","rel","currentRelations","get","spec","nested","with","selected","select","to","asBindParams","cols","data","caller","assertUsableWriteValues","assertNoExpressionHandles","has","SELECTIVITY_EXACT_THRESHOLD","METRIC_OPERATOR","cosine","euclidean","inner_product","searchConfigFor","defOf","keys","filter","defOfFull","pkCols","primaryKey","pk","includes","search","synonyms","validity","from","model","m","embed","apiKeyName","baseURL","dimensions","metric","ftsOn","ftsColsNew","colSet","ftsCols","legs","column","chunk","fts","rawLegs","vector","leg","l","pickLeg","using","hit","find","HALF_LIFE_UNIT_SECONDS","s","h","parseHalfLife","exec","sec","isFinite","WHERE_OPS","gt","gte","lt","lte","neq","LOCK_MODES","update","share","noKeyUpdate","ftsExprOf","sort","expandSynonyms","lower","word","alts","toLowerCase","split","seg","startsWith","tok","test","searchLogger","evt","fields","console","log","stringify","logNoResults","table","query","mode","n","searchLogger","slice","fetchFacets","live","colSet","facets","where","extraWhere","bind","add","v","push","length","whereSql","compileWhere","parts","map","col","replace","quoteIdent","quoteTable","rows","unsafe","join","out","r","f","undefined","value","count","Number","validitySql","p","asOf","excludeSql","pk","ids","x","computePrimaryKey","t","tableDefOf","columns","cols","Object","keys","declared","primaryKey","Array","isArray","only","includes","pkOf","c","rec","def","_def","pks","filter","isSinglePkEquality","assertNotAppendOnly","caller","appendOnly","Error","computeSchemaColumns","Set","timestampResult","expr","columnResult","column","alias","columnTypeOf","projectedColumn","CAN_PREFIX","canMemo","WeakMap","canRoleGate","roles","length","names","flatMap","r","map","replace","join","canEntries","def","alias","policies","dropped","restrictive","p","permissive","command","renderCanUsing","name","entries","filter","q","reason","rGate","push","Buffer","byteLength","CAN_PREFIX","using","gate","parts","CanRenderError","Error","ENGINE_ALIASES","qualifier","tableName","undefined","withoutLiterals","test","includes","depth","ch","tbl","qualified","RegExp","calls","match","wrapped","rendered","canExprSql","selfParenthesized","kind","err","CAN_BINOPS","eq","neq","gt","gte","lt","lte","canLiteral","v","Number","isFinite","String","e","quoteIdent","value","op","left","right","expr","negated","quoteTable","table","predicate","canEntriesOf","byAlias","memoTable","canMemo","currentSchema","Map","hit","get","tableDefOf","warnOnce","msg","has","set","console","warn","hasCanColumn","d","canOuter","cols","canProjection","canJsonPairs","quoteLiteral","foldCan","row","partial","can","key","Object","keys","startsWith","slice","flags","columns","prototype","hasOwnProperty","call","currentRelations","some","rel","rowProjection","wildcard","schemaColumns","base","timestampMemo","c","columnTypeOf","projections","projectionMemo","sql","projectedColumn","rows","colRefSql","known","ref","caller","$col","shapeOK","selectClause","select","col","orderClauseFor","orderBy","items","Array","isArray","o","column","dir","direction","nulls","orderClause","limitClause","limit","isInteger","offsetClause","offset","compileWhereBare","colSet","where","add","transforms","transformsOf","bindFor","t","toDb","assertUsableFilter","isSqlFragment","text","values","$sql","out","i","cond","branches","compiled","b","rels","relName","inner","find","sort","ourCol","theirCol","relationColumns","missing","to","sub","innerSql","bind","isColRef","isNowExpr","lit","pattern","x","WHERE_OPS","isColumnExpr","looksLikeUnbrandedRef","made","how","compileWhere","bare","onConflictTail","conflict","action","target","conflictSet","Set","sets","cachedVectorSchema","cachedTrgmSchema","trgmSchemaOf","live","unsafe","nspname","vectorSchemaWithGuc","runner","secretReader","setSecretReader","fn","embedFetch","url","init","fetch","embedQuery","embed","text","secretReader","Error","apiKeyName","key","url","baseURL","replace","controller","AbortController","timer","setTimeout","abort","res","embedFetch","method","headers","Authorization","body","JSON","stringify","model","input","dimensions","undefined","signal","ok","status","data","json","vec","embedding","Array","isArray","clearTimeout","buildSetAssignments","table","cols","set","add","caller","map","c","expr","columnExprOf","fn","quoteIdent","operator","t","transformsOf","currentSchema","get","amount","toDb","by","asBindParams","join","buildValueTuple","computeColumnType","col","def","tableDefOf","columns","d","_def","type","NUMERIC_PG_TYPES","Set","aggregateExpr","alias","q","columnTypeOf","timestampResult","has","jsonObjectFor","extra","pairs","quoteLiteral","relationColumns","relation","child","kind","to","value","via","column","target","references","primaryKeyOf","withClauses","spec","parentAlias","depth","counter","Object","values","some","Boolean","rels","currentRelations","select","joins","jsonPairs","name","opt","entries","rel","find","r","known","sort","length","ourCol","theirCol","o","i","childAlias","childKnown","schemaColumns","childCols","nestedSpec","nested","nestedJoins","obj","canJsonPairs","innerWhere","compileWhereBare","link","cond","requestedLimit","limitClause","relationLimit","Math","min","inner","orderClauseFor","outAlias","push","quoteTable","compileFindMany","query","opts","params","v","whereSql","compileWhere","order","orderClause","orderBy","limit","offset","offsetClause","selectClause","w","with","keys","selectList","joinSql","sql","uniqueKeysCache","WeakMap","pageSchemaCache","pageSchema","memoTable","create","inlineKeys","nullable","primaryKey","stamp","fingerprint","createOps","tx","context","at","Promise","then","resolveTx","ops","diagnostics","trace","snapshot","bound","p","encodePgArray","asWireRows","unsafe","insert","tuple","rowProjection","rows","inserted","asTableRow","insertMany","validateInsertManyOptions","returning","first","missing","filter","k","includes","tuples","tail","onConflict","onConflictTail","action","out","Number","isSafeInteger","count","advisoryXactLock","lockRows","ids","unique","pk","list","id","lockRowsWhere","where","mode","clause","LOCK_MODES","String","assertHasPredicate","claim","keyCols","assertUsableWriteValues","live","savepoint","sp","row","e","isUniqueViolation","found","named","constraintOf","put","assertNotAppendOnly","conflict","searchConfigFor","validity","bindData","addPut","ph","insertSql","condSql","condBind","cur","old","second","fresh","placeholders","conflictSet","assignments","update","findById","delete","updateMany","wantRows","simple","isSinglePkEquality","lockedCte","asTableRows","deleteMany","aggregate","check","parts","wants","groups","groupBy","groupSel","columnResult","groupSql","shape","bucket","n","findUnique","uniqueKeysOf","assertUniqueLookup","findMany","compiled","page","secret","cursorKey","schema","size","backward","token","pageOrder","scope","identity","cursorScope","decodeCursor","boundary","pageBoundary","opposite","prefix","names","startsWith","ordinal","other","hidden","cursorCols","nativeOrder","direction","nulls","visible","result","hasOpposite","hasMore","slice","reverse","cursor","encodeCursor","pageInfo","startCursor","endCursor","hasNextPage","hasPreviousPage","search","cfg","excl","__excludeIds","facets","validityFor","adder","validitySql","rawLimit","isFinite","max","trunc","pool","minScore","recencyMul","recency","field","halfLife","colSet","parseHalfLife","boostMul","boost","weight","g","scoreMul","chunk","ck","pidQ","bpr","blocksPerRow","wantTextC","fts","qvC","vector","bindC","addC","userWhereC","whereC","excludeSql","parentJoinC","liveC","K2","cpool","semC","kwC","sch","vectorSchemaWithGuc","op","METRIC_OPERATOR","metric","cosine","exactOrderC","probeRows","SELECTIVITY_EXACT_THRESHOLD","vp","toVectorLiteral","qpC","qpCIdx","qTextC","synonyms","expandSynonyms","msC","colListC","projectedColumn","scoreC","assembleC","kwIn","withKwn","kwnCol","fusedSrc","canOuter","rowsC","_kwn","tsch","trgmSchemaOf","trgmKwC","retryBindC","outC","blocks","logNoResults","wantText","ftsCols","anyEmbed","legs","l","vectorAsked","using","leg","pickLeg","qv","wantVector","bind","userWhere","K","semSql","kwSql","exactOrder","qpRef","qpIdx","qText","qp","colList","msP","hlCol","highlight","ftsExprOf","assemble","score","single","base","ms","trgmKw","retryBind","fetchFacets","similar","parse","recommend","positive","negative","x","avgSel","inList","targetSql","r0","pos_missing","neg_missing","supersede","newId","crypto","randomUUID","closed","transaction","cb","withTables","attempt","command","plan","options","txPlan","commands","compileCommand","reason","steps","pipeline","results","settled","allSettled","statement","failed","error","sqlstateOf","SQLSTATE","commandGuardFailed","detail","error_code","isInteger","slot","assign","rows_affected","response","runPlanOp","assertGuard","columnsMemo","primaryMemo","vectorMemo","transformMemo","typeMemo","timestampMemo","projectionMemo","computeSchemaColumns","computePrimaryKey","vectorColumnsOf","computeVectorColumns","computeTransforms","types","Map","setSchema","schemas","tables","entry","mod","default","schemaName","qualifiedTableKey","relations","buildRelations","cname","cd","snapshotDeclaration","freeze","cachedVectorSchema","cachedTrgmSchema","tableNamespaces","namespaces","dot","indexOf","short","isFrozen","surfaces","schemaOf","cached","hasOwn","defineProperty","configurable","enumerable","writable","Reflect","Proxy","receiver","ownKeys","getOwnPropertyDescriptor","preventExtensions","surface","SERVICE_LOCK_TIMEOUT","isAbortedTransaction","message","test","trim","err","isState","code","errno","asText","isForeignKeyViolation","UniqueViolation","is","constraint","exec","isLockTimeout","diagnosingDriver","original","explain","markEngineRaised","state","serializationFailure","SerializationFailure","deadlockDetected","DeadlockDetected","queryCancelled","HttpError","wrapTx","mapped","catch","cancel","reject","admission","databaseAdmission","cancelBackend","begin","createRequestDatabase","DatabaseTrace","requestControl","TransactionControl","requestClosed","authorized","applicationTouched","authorizationRelease","contextFor","role","cursorIdentity","claimsJson","hasCommandExecutor","userContext","serviceContext","serviceRole","atomic","validateAtomicOptions","atomicScope","getStore","opened","commit","requestTransaction","retries","retryBudget","retry","atomicSignal","AbortSignal","any","control","timeoutMs","timeouts","statementTimeoutMs","remainingMs","Symbol","root","createLazyTransaction","isolation","readOnly","lockTimeout","lockTimeoutMs","statementTimeout","callback","run","race","rollback","isRetryable","delay","resolve","dispose","serviceTx","serviceControl","serviceClient","asService","client","authorizationComplete","complete","Args","isRef","isPlanRef","refUnresolvedMessage","ref","refuseUnbrandedRef","looksLikeUnbrandedPlanRef","isExpr","renderValue","args","vectorCols","transforms","source","$ref","bindMaybeVector","$expr","resolveRefsDeep","isColRef","isSqlFragment","Date","renderWhere","planWhere","resolved","bare","from","compilePlanOp","opVectorCols","opTransforms","rendered","conflictCols","knownSet","planned","planPk","lock","symbols","hasRefs","containsFragment","hasNullableFilterRef","index","empty","guard","wide","exact","bindings","toString","toISOString","step","chunks","parameterChunks","withQueryCancellation","application","control","Error","close","driver","d","end","unsafe","sql","params","begin","fn","cancelBackend","pid","startedAt","ROUTES","Symbol","for","RETURN_BUFFER","Symbol","for","THROWS_BUFFER","carrierOf","target","ctor","getRoutes","ctor","carrier","carrierOf","routes","ROUTES","returnBuffer","RETURN_BUFFER","route","buffered","fnName","returnSchema","undefined","throwsBuffer","THROWS_BUFFER","throws","map","r","params","slice","APP_DEFAULT_AUTH","Symbol","for","appAuthSlot","globalThis","getDefaultAuth","appAuthSlot","APP_DEFAULT_AUTH","resolveEffectiveAuth","routeAuth","controllerAuth","getDefaultAuth","ROOM_META","Symbol","for","CONTROLLER_META","toSegments","path","split","filter","Boolean","map","s","startsWith","endsWith","slice","buildRouteTable","controllers","container","table","Ctrl","undefined","ctor","meta","basePath","routes","getRoutes","length","name","Error","instance","get","r","full","subpath","push","method","segments","id","controllerAuth","resolveEffectiveAuth","defaultAuth","matchRoute","pathname","parts","entry","params","ok","i","seg","got","charCodeAt","decodeURIComponent","HEADER_DEVICE_ID","HEADER_PAYLOAD","HEADER_SIGNATURE","HEADER_CHALLENGE","HEADER_CAPABLE","HEADER_INSTALLATION","HEADER_ANCHOR","DEFAULT_POLICY_TTL_MS","DEFAULT_REQUEST_TIMEOUT_MS","bodyDigest","body","byteLength","bytes","Uint8Array","ArrayBuffer","set","buf","crypto","subtle","digest","btoa","String","fromCharCode","readCapable","req","v","headers","get","createAttestGate","deps","doFetch","fetchImpl","fetch","ttl","policyTtlMs","policyTimeoutMs","requestTimeoutMs","cachedMode","cachedAt","mode","Date","now","res","moduleBaseUrl","apikey","serviceRoleKey","signal","AbortSignal","timeout","ok","Error","status","json","gate","_ctx","m","outcome","reason","device","observation","nextChallenge","deviceId","payload","signature","hasEvidence","capable","attested","installationId","url","URL","verdict","method","JSON","stringify","installation_id","device_id","challenge","path","pathname","search","body_sha256","next_challenge","authDeviceId","platform","assurance","createObservationSink","maxBatch","intervalMs","buffer","inFlight","Promise","resolve","timer","setInterval","flush","unref","bucketsOf","batch","counts","incapable","unknown","no_sdk","o","length","record","push","stop","clearInterval","AUTHORIZE_PATH","SIGNATURE_HEADER","renderPath","template","tokens","replaceAll","sanitizeSegment","userId","uploadId","filename","raw","cleaned","replace","trim","slice","grantFor","entry","ctx","bucketLimits","cfg","meta","options","uploadConfig","bucket","path","pathTemplate","maxBytes","mimeTypes","ownerUid","CompletionLedger","seen","Map","capacity","recall","get","remember","response","delete","set","size","oldest","keys","next","done","value","verifySignature","presented","expected","length","diff","i","charCodeAt","SSE_CONTENT_TYPE","encodeFrame","value","JSON","stringify","encodeErrorFrame","requestId","makeSseWriter","opts","begun","chain","Promise","resolve","write","frame","then","onFirstWrite","enqueue","catch","undefined","started","drained","DI_INJECTABLES","Symbol","for","INJECTABLE","isInjectable","c","slot","g","globalThis","__claimInjectables","slot","splice","JOB","Symbol","for","WEBHOOK","HOOK_BLOCKING","HOOK_LISTENERS","ROOM","CONTROLLER","has","c","s","undefined","isEntryPointClass","DI_MODULES","Symbol","for","slot","g","globalThis","__claimModules","slot","splice","DiError","Error","DECLARATION_REFUSAL","kind","path","at","detail","fixes","length","join","map","f","name","nameOf","c","String","UNRESOLVABLE","Set","Object","Function","Number","Boolean","Array","Symbol","Promise","Date","undefined","DATA","declaresDependencies","ctor","arity","meta","Reflect","getMetadata","buildContainer","entries","__claimModules","declared","__claimInjectables","declaredModules","e","mod","owner","Map","def","m","providers","controllers","prev","get","set","p","isInjectable","isEntryPointClass","orphans","filter","has","names","exported","importsOf","exports","holder","i","imports","deps","implementorsOf","t","keys","prototype","isPrototypeOf","call","withArity","missingMeta","cls","list","forEach","dep","dm","impls","impl","push","sort","state","stack","walk","cyc","slice","indexOf","d","pop","cache","make","hit","args","inst","owned","pressure","computePressure","total","count","n","module","pct","Math","round","of","a","b","assertNoOrphanEntryPoints","registered","SECRET_ENV","scrubSecrets","env","removed","kept","name","undefined","push","Object","keys","startsWith","hostAllowed","host","allow","h","toLowerCase","raw","pattern","trim","endsWith","slice","length","installEgressFence","policy","original","globalThis","fetch","bind","declared","platform","alwaysAllow","map","filter","Boolean","whenUndeclared","fenced","input","init","url","URL","includes","hostname","Error","timeoutMs","controller","AbortController","timer","setTimeout","abort","signal","clearTimeout","MAX_BODY_BYTES","JSON_HEADERS","fieldErrors","err","issues","map","i","field","path","join","message","headersFor","raw","schema","shape","aliased","declared","Object","keys","lower","toLowerCase","value","undefined","envelope","error","description","status","requestId","extra","Response","JSON","stringify","error_description","request_id","headers","unavailable","name","Error","stubModule","Proxy","get","apply","defaultSqlDriver","config","g","globalThis","Bun","SQL","BootRefused","withQueryCancellation","url","databaseUrl","max","poolMax","AUTHOR_ANSWERED","Set","refuseUnlessAuthorized","client","spec","rolesOfCaller","permission","row","query","ok","required","role","held","includes","required_role","makeRoleResolver","pending","then","rows","r","createApp","opts","controllers","container","buildContainer","released","liveContainer","t","owned","pressure","assertNoOrphanEntryPoints","routes","buildRouteTable","length","DeclarationRefused","sql","admission","databaseAdmission","concurrency","inFlight","shuttingDown","accepting","serving","run","work","add","delete","unsafe","setSchema","schemas","setCursorKey","cursorSecret","serviceRoleKey","enableCommands","installCommandExecutor","dbRole","dbServiceRole","setSecretReader","secretReader","auth","AuthVerifier","jwksUrl","authJwksUrl","issuer","authIssuer","attestGate","createAttestGate","moduleBaseUrl","observations","createObservationSink","limiter","RateLimiter","cache","makeMemoryCache","log","logger","console","modules","runWithRuntime","runtimeHooks","__runWithRuntime","requestALS","__requestALS","uploadSecret","completions","CompletionLedger","buildServices","db","Database","Cache","Log","Auth","Documents","Storage","Notifications","Flags","Realtime","Secrets","runInServiceScope","fn","createRequestDatabase","serviceRole","claimsJson","databaseDiagnostics","endpoint","out","commit","rollback","errorResponse","isHttpError","isEngineRaised","has","errorDescription","data","handleAuthorize","req","verifySignature","SIGNATURE_HEADER","body","json","catch","uploadId","target","matchRoute","method","effectiveAuth","entry","meta","options","controllerAuth","callerClaims","verify","uploadDb","signal","refusal","grant","grantFor","userId","sub","filename","handle","crypto","randomUUID","URL","pathname","AUTHORIZE_PATH","hit","attestedDevice","attestChallengeOut","claims","databaseBudget","id","dispatched","settleBeforeRefusal","verifiedEmail","email_verified","parsedBody","bodyRead","rawBody","Number","isFinite","buf","arrayBuffer","byteLength","Uint8Array","readParsedBody","parse","TextDecoder","decode","attest","observation","record","outcome","nextChallenge","reason","device","retryAfter","check","rateLimit","key","Date","now","String","completionUploadId","args","sseEnqueue","sseSettle","sseWriter","makeSseWriter","enqueue","chunk","onFirstWrite","p","params","kind","safeParse","success","fields","index","fromEntries","searchParams","email","emailVerified","metadata","roles","envelopeIn","uploadedObject","already","recall","contentType","sdkVersion","appVersion","platform","osVersion","authorizationComplete","services","sseConfig","sseController","sseEncoder","TextEncoder","stream","ReadableStream","start","c","encode","sawFirstFrame","refuseFirstFrame","firstFrame","Promise","resolve","reject","guarded","prop","recv","started","Reflect","thrown","ran","box","getStore","idempotencyKey","instance","fnName","race","drained","encodeErrorFrame","close","SSE_CONTENT_TYPE","result","returnSchema","v","remember","payload","bootServices","runShutdownHooks","__runStartHooks","closeDriver","databasePressure","snapshot","shutdown","size","allSettled","closable","end"]}