@palbase/backend 33.0.1 → 34.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 (85) hide show
  1. package/dist/bin/palbase-backend.cjs +2020 -350
  2. package/dist/bin/palbase-backend.cjs.map +1 -1
  3. package/dist/bin/palbase-backend.js +9 -7
  4. package/dist/bin/palbase-backend.js.map +1 -1
  5. package/dist/{chunk-SI4KGEM3.js → chunk-FOWA7PF4.js} +97 -96
  6. package/dist/chunk-FOWA7PF4.js.map +1 -0
  7. package/dist/chunk-GHNC2UHS.js +20 -0
  8. package/dist/chunk-GHNC2UHS.js.map +1 -0
  9. package/dist/{chunk-BRLJOXWS.js → chunk-JJW3L62T.js} +3 -3
  10. package/dist/chunk-JJW3L62T.js.map +1 -0
  11. package/dist/{chunk-TVCCR6SO.js → chunk-LOGL2ZHD.js} +58 -9
  12. package/dist/chunk-LOGL2ZHD.js.map +1 -0
  13. package/dist/{chunk-IKDONZ5D.js → chunk-MNGZE2MM.js} +1651 -186
  14. package/dist/chunk-MNGZE2MM.js.map +1 -0
  15. package/dist/{chunk-XOX6RFPZ.js → chunk-PRH45NZU.js} +46 -3
  16. package/dist/chunk-PRH45NZU.js.map +1 -0
  17. package/dist/{chunk-26GH54D2.js → chunk-RZLY4BOY.js} +5 -3
  18. package/dist/{chunk-26GH54D2.js.map → chunk-RZLY4BOY.js.map} +1 -1
  19. package/dist/{chunk-YIQ4RS4F.js → chunk-SEM36BWY.js} +283 -5
  20. package/dist/chunk-SEM36BWY.js.map +1 -0
  21. package/dist/{chunk-KATPXCJ5.js → chunk-UMESJJRS.js} +19 -40
  22. package/dist/chunk-UMESJJRS.js.map +1 -0
  23. package/dist/chunk-VXPNPVAG.js +40 -0
  24. package/dist/chunk-VXPNPVAG.js.map +1 -0
  25. package/dist/{chunk-WWUG2QXF.js → chunk-YX7UA7VC.js} +53 -4
  26. package/dist/chunk-YX7UA7VC.js.map +1 -0
  27. package/dist/db/env.cjs.map +1 -1
  28. package/dist/db/env.d.cts +2 -0
  29. package/dist/db/env.d.ts +2 -0
  30. package/dist/db/index.cjs +261 -2
  31. package/dist/db/index.cjs.map +1 -1
  32. package/dist/db/index.d.cts +46 -3
  33. package/dist/db/index.d.ts +46 -3
  34. package/dist/db/index.js +14 -5
  35. package/dist/{index-DMZG3kpo.d.ts → endpoint-DpNUx-ON.d.ts} +315 -57
  36. package/dist/{index-DB_nW-AV.d.cts → endpoint-kYgEHrrV.d.cts} +315 -57
  37. package/dist/engine/index.cjs +2026 -348
  38. package/dist/engine/index.cjs.map +1 -1
  39. package/dist/engine/index.d.cts +5 -5
  40. package/dist/engine/index.d.ts +5 -5
  41. package/dist/engine/index.js +17 -7
  42. package/dist/{index-D-3duy8Y.d.ts → index-JrHqNsjQ.d.ts} +108 -50
  43. package/dist/{index-DLveQoOf.d.cts → index-pnDsEfxJ.d.cts} +108 -50
  44. package/dist/index.cjs +616 -254
  45. package/dist/index.cjs.map +1 -1
  46. package/dist/index.d.cts +7 -6
  47. package/dist/index.d.ts +7 -6
  48. package/dist/index.js +25 -15
  49. package/dist/index.js.map +1 -1
  50. package/dist/openapi/index.cjs +8 -1
  51. package/dist/openapi/index.cjs.map +1 -1
  52. package/dist/openapi/index.d.cts +3 -3
  53. package/dist/openapi/index.d.ts +3 -3
  54. package/dist/openapi/index.js +4 -3
  55. package/dist/openapi/index.js.map +1 -1
  56. package/dist/{registry-DSTThhKf.d.cts → registry-BcOd8Zhf.d.cts} +3 -1
  57. package/dist/{registry-JjF5lcj4.d.ts → registry-BoX5iNyY.d.ts} +3 -1
  58. package/dist/test/index.cjs +103 -66
  59. package/dist/test/index.cjs.map +1 -1
  60. package/dist/test/index.d.cts +3 -3
  61. package/dist/test/index.d.ts +3 -3
  62. package/dist/test/index.js +33 -7
  63. package/dist/test/index.js.map +1 -1
  64. package/docs/README.md +1 -1
  65. package/docs/database.md +308 -0
  66. package/docs/examples/check-query-contracts.ts +5 -0
  67. package/docs/examples/database-dx.contract.json +65 -0
  68. package/docs/examples/database-dx.ts +63 -0
  69. package/docs/examples/money-transfer.ts +73 -0
  70. package/docs/llms-full.txt +309 -1
  71. package/package.json +1 -2
  72. package/template/AGENTS.md +7 -7
  73. package/template/modules/health/health.controller.ts +7 -4
  74. package/template/modules/notes/dto/create.ts +4 -3
  75. package/template/modules/notes/notes.controller.ts +8 -6
  76. package/template/package.json +1 -1
  77. package/dist/chunk-BRLJOXWS.js.map +0 -1
  78. package/dist/chunk-IKDONZ5D.js.map +0 -1
  79. package/dist/chunk-KATPXCJ5.js.map +0 -1
  80. package/dist/chunk-SI4KGEM3.js.map +0 -1
  81. package/dist/chunk-TVCCR6SO.js.map +0 -1
  82. package/dist/chunk-WWUG2QXF.js.map +0 -1
  83. package/dist/chunk-XOX6RFPZ.js.map +0 -1
  84. package/dist/chunk-YIQ4RS4F.js.map +0 -1
  85. package/stack-images.json +0 -24
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/runtime.ts"],"sourcesContent":["/**\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 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 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 { withRetry } from \"./db/typed-db.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?: { onConflict: readonly string[]; action?: \"ignore\" | \"update\" },\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 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> }) =>\n ops().updateMany(name, q.where, q.set),\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: Omit<DBClient, \"asService\">): 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 $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 $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?: { onConflict: readonly string[]; action?: \"ignore\" | \"update\" },\n ) => raw.insertMany(table, rows, opts),\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 // 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 // Retry de HER DENEMEDE taze bir builder istiyor (FR-037): önceki denemenin\n // op'ları planda kalsaydı ikinci deneme birincinin yazmalarını TEKRAR\n // gönderirdi. Bu yüzden builder döngünün İÇİNDE kuruluyor.\n return withRetry(() => {\n const builder = new TxPlanBuilder();\n return runTxPlan(raw, makeTxPlanHandle(builder), builder, fn) as Promise<\n Materialized<T>\n >;\n }, opts ?? {}) 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"],"mappings":"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","names":["AsyncLocalStorage","REQUEST_ALS","Symbol","for","__requestALS","g","globalThis","AsyncLocalStorage","runtime","__setRuntime","services","__runWithRuntime","fn","run","REQUIRED_SERVICES","refuseIncompleteBox","missing","filter","k","undefined","length","Error","join","__getRuntime","scoped","getStore","LIFECYCLE","declaredLifecycle","start","shutdown","onStart","name","hook","push","onShutdown","reason","err","message","String","drain","hooks","h","reverse","console","error","__runStartHooks","slot","splice","cause","drained","__resetLifecycleHooks","makeServiceProxy","key","handler","get","_target","prop","receiver","client","value","Reflect","bind","Proxy","makeTableProxy","ops","prefix","_t","insert","data","aggregate","q","insertMany","rows","opts","update","where","id","set","delete","findById","findMany","put","onConflict","updateMany","deleteMany","count","search","params","similar","recommend","facets","supersede","row","claim","unique","extra","rawDatabase","makeTypedSurface","raw","reco","$query","sql","query","$insert","table","$update","$delete","$findById","$findMany","$put","$updateMany","$deleteMany","$count","$search","$similar","$recommend","$facets","$claim","$lockRows","ids","lockRows","$advisoryXactLock","advisoryXactLock","$aggregate","$insertMany","$supersede","base","Object","assign","$attempt","attempt","$transaction","withRetry","builder","TxPlanBuilder","runTxPlan","makeTxPlanHandle","target","startsWith","qualifiedTableKey","makeTxTablesAccessor","tablesProxy","publicTables","Database","$asService","asService","Documents","makeBucketsAccessor","storage","bucket","rawStorage","Storage","buckets","Cache","Secrets","Auth","Log","Notifications","rawFlags","Flags","isEnabled","flagName","context","getVariant","getAll","defaultOrContext","maybeContext","setOverride","Realtime"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/refusals.ts","../src/db/env-gen.ts","../src/decorators/injectable.ts","../src/decorators/kinds.ts","../src/decorators/module.ts","../src/container.ts"],"sourcesContent":["/**\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 * 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 { 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 const insertLines = cols.map(([col, builder]) => {\n const def = builder._def;\n const opt = optionalOnInsert(def) ? \"?\" : \"\";\n return `${indent} ${col}${opt}: ${rowType(def)};`;\n });\n const relEntries = relations\n .map(\n (r) =>\n `${r.name}: { to: ${JSON.stringify(r.to)}; kind: ${JSON.stringify(r.kind)}; via: ${JSON.stringify(r.via)} }`,\n )\n .join(\"; \");\n return [\n `${indent}${table.name}: {`,\n `${indent} row: {`,\n ...rowLines,\n `${indent} };`,\n `${indent} insert: {`,\n ...insertLines,\n `${indent} };`,\n `${indent} relations: {${relEntries === \"\" ? \"\" : ` ${relEntries} `}};`,\n // searchable: vector kolonu YA DA search beyanı → EnvTypedTable'da search()\n // üyesini açan yapısal bayrak (FR-013). Yokken satır hiç üretilmez ki\n // mevcut şemaların d.ts'i bayt-aynı kalsın.\n ...(cols.some(([, b]) => b._def.type === \"vector\") || table.search !== undefined\n ? [`${indent} searchable: true;`]\n : []),\n // 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 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","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"],"mappings":"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","names":["DECLARATION_REFUSAL","Symbol","for","DeclarationRefused","Error","message","name","isDeclarationRefused","e","baseTsType","def","codec","undefined","CODECS","tsType","type","values","enumValues","length","map","v","JSON","stringify","join","unhandled","Error","String","pgBrand","sort","rowType","base","branded","nullable","optionalOnInsert","defaultRandom","defaultNow","defaultValue","forwardName","column","endsWith","slice","describeOrigin","o","direction","table","renameCall","owns","target","references","selfRefColumn","buildRelations","schemas","out","Map","taken","schema","t","Object","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","tableBlock","relations","indent","cols","rowLines","insertLines","opt","relEntries","r","some","b","search","appendOnly","refuseFreeFormTransforms","transform","where","makeEnvDts","publicSchema","find","s","others","filter","publicBlocks","keys","body","schemaBlocks","inner","schemasBody","DI_INJECTABLES","Symbol","for","INJECTABLE","isInjectable","c","slot","g","globalThis","Injectable","target","push","__claimInjectables","splice","JOB","Symbol","for","WEBHOOK","HOOK_BLOCKING","HOOK_LISTENERS","ROOM","CONTROLLER","has","c","s","undefined","isEntryPointClass","owned","container","jobsOf","filter","webhooksOf","hooksOf","roomsOf","controllersOf","DI_MODULES","Symbol","for","slot","g","globalThis","Module","def","target","push","mod","__claimModules","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"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/db/columns.ts"],"sourcesContent":["/** 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"],"mappings":"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","names":["CODECS","number","fromDb","v","Number","toDb","isSafeInteger","Error","String","tsType","decimal","undefined","refuseOnVector","def","modifier","type","ColumnBuilder","_def","existingDef","nullable","primaryKey","notNull","default","value","defaultValue","defaultRandom","defaultNow","dbAssigned","renamedFrom","previous","ignored","references","target","opts","referencesThunk","as","refAs","reverseAs","onDelete","onDeleteAction","index","counter","selfReferences","column","selfRefColumn","action","unique","asNumber","withCodec","asDecimal","codec","method","transform","fns","uuid","text","integer","bigint","numeric","boolean","timestamp","jsonb","enumType","name","values","builder","enumName","enumValues","vector","dimensions","isInteger","b","ownedByUser","table","owns","userRef","installationRef"]}