@palbase/backend 39.1.7 → 40.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/dist/bin/palbase-backend.cjs.map +1 -1
  2. package/dist/bin/palbase-backend.js +2 -2
  3. package/dist/{chunk-C525N4OW.js → chunk-AS2HDWVQ.js} +3 -2
  4. package/dist/{chunk-C525N4OW.js.map → chunk-AS2HDWVQ.js.map} +1 -1
  5. package/dist/{chunk-H7EKL6HC.js → chunk-RA7KFELX.js} +88 -2
  6. package/dist/chunk-RA7KFELX.js.map +1 -0
  7. package/dist/db/index.d.cts +1 -1
  8. package/dist/db/index.d.ts +1 -1
  9. package/dist/engine/index.cjs +2 -0
  10. package/dist/engine/index.cjs.map +1 -1
  11. package/dist/engine/index.d.cts +3 -3
  12. package/dist/engine/index.d.ts +3 -3
  13. package/dist/engine/index.js +4 -2
  14. package/dist/{index-fLaf0PN2.d.ts → index-B8zC9oV0.d.ts} +3 -3
  15. package/dist/{index-Db5QHdTa.d.cts → index-BAjRbjnq.d.cts} +3 -3
  16. package/dist/{index-QWN1Ncrv.d.ts → index-Ck2K1TgC.d.ts} +3 -3
  17. package/dist/{index-CCY1h_J2.d.cts → index-t7Ie44mM.d.cts} +3 -3
  18. package/dist/index.cjs +84 -59
  19. package/dist/index.cjs.map +1 -1
  20. package/dist/index.d.cts +20 -18
  21. package/dist/index.d.ts +20 -18
  22. package/dist/index.js +2 -61
  23. package/dist/index.js.map +1 -1
  24. package/dist/openapi/index.d.cts +2 -2
  25. package/dist/openapi/index.d.ts +2 -2
  26. package/dist/{registry-CH6HRR6T.d.cts → registry-C88au7ti.d.cts} +1 -1
  27. package/dist/{registry-C7tCRyPm.d.ts → registry-wwVUGunv.d.ts} +1 -1
  28. package/dist/stack.cjs.map +1 -1
  29. package/dist/stack.d.cts +21 -6
  30. package/dist/stack.d.ts +21 -6
  31. package/dist/test/index.cjs +19 -1
  32. package/dist/test/index.cjs.map +1 -1
  33. package/dist/test/index.d.cts +21 -2
  34. package/dist/test/index.d.ts +21 -2
  35. package/dist/test/index.js +18 -1
  36. package/dist/test/index.js.map +1 -1
  37. package/docs/README.md +6 -6
  38. package/docs/llms-full.txt +6 -6
  39. package/package.json +3 -6
  40. package/template/AGENTS.md +14 -14
  41. package/template/modules/notes/notes.e2e.test.ts +53 -0
  42. package/template/package.json +2 -2
  43. package/dist/chunk-H7EKL6HC.js.map +0 -1
  44. package/template/scripts/test.sh +0 -33
@@ -26,6 +26,73 @@ function isDeclarationRefused(e) {
26
26
  }
27
27
  __name(isDeclarationRefused, "isDeclarationRefused");
28
28
 
29
+ // src/stack-gen.ts
30
+ function liveNames(names) {
31
+ return [
32
+ ...new Set(names)
33
+ ].sort();
34
+ }
35
+ __name(liveNames, "liveNames");
36
+ function memberName(name) {
37
+ return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name) ? name : JSON.stringify(name);
38
+ }
39
+ __name(memberName, "memberName");
40
+ function members(names) {
41
+ if (names.length === 0) return "";
42
+ return `
43
+ ${names.map((n) => ` ${memberName(n)}: true;`).join("\n")}
44
+ `;
45
+ }
46
+ __name(members, "members");
47
+ function bucketMembers(buckets) {
48
+ const normalized = buckets.map((b) => typeof b === "string" ? {
49
+ name: b,
50
+ variants: []
51
+ } : b);
52
+ const byName = /* @__PURE__ */ new Map();
53
+ for (const b of normalized) byName.set(b.name, b.variants);
54
+ const names = [
55
+ ...byName.keys()
56
+ ].sort();
57
+ if (names.length === 0) return "";
58
+ const rows = names.map((name) => {
59
+ const variants = [
60
+ ...new Set(byName.get(name) ?? [])
61
+ ].sort();
62
+ const union = variants.length === 0 ? "never" : variants.map((v) => JSON.stringify(v)).join(" | ");
63
+ return ` ${memberName(name)}: { variants: ${union} };`;
64
+ });
65
+ return `
66
+ ${rows.join("\n")}
67
+ `;
68
+ }
69
+ __name(bucketMembers, "bucketMembers");
70
+ function stackInterfaceBody(names) {
71
+ const secrets = liveNames(names.secrets);
72
+ const flags = liveNames(names.flags);
73
+ const roles = liveNames(names.roles ?? []);
74
+ return ` interface Secrets {${members(secrets)}}
75
+
76
+ interface Flags {${members(flags)}}
77
+
78
+ interface Buckets {${bucketMembers(names.buckets)}}
79
+
80
+ interface Roles {${members(roles)}}`;
81
+ }
82
+ __name(stackInterfaceBody, "stackInterfaceBody");
83
+ function makeStackDts(names) {
84
+ return `// palbase-stack.d.ts \u2014 GENERATED by @palbase/backend. Do not edit.
85
+ // Source: the linked environment's stack.
86
+
87
+ declare module "@palbase/backend/stack" {
88
+ ${stackInterfaceBody(names)}
89
+ }
90
+
91
+ export {};
92
+ `;
93
+ }
94
+ __name(makeStackDts, "makeStackDts");
95
+
29
96
  // src/db/unique.ts
30
97
  function uniqueKeysOf(table) {
31
98
  const columns = table.columns ?? {};
@@ -276,7 +343,17 @@ function refuseFreeFormTransforms(schemas) {
276
343
  }
277
344
  }
278
345
  __name(refuseFreeFormTransforms, "refuseFreeFormTransforms");
279
- function makeEnvDts(schemas) {
346
+ var ENV_BLOCK_START = "// palbase:env:begin";
347
+ var ENV_BLOCK_END = "// palbase:env:end";
348
+ var STACK_BLOCK_START = "// palbase:stack:begin";
349
+ var STACK_BLOCK_END = "// palbase:stack:end";
350
+ var EMPTY_STACK_NAMES = {
351
+ secrets: [],
352
+ flags: [],
353
+ buckets: [],
354
+ roles: []
355
+ };
356
+ function makeEnvDts(schemas, names) {
280
357
  refuseFreeFormTransforms(schemas);
281
358
  const relations = buildRelations(schemas);
282
359
  const publicSchema = schemas.find((s) => s.name === "public");
@@ -319,10 +396,18 @@ type Pg<T, N extends string> = T & { readonly __pg?: N };
319
396
  */
320
397
  type Json = string | number | boolean | null | undefined | Json[] | { [k: string]: Json };
321
398
 
399
+ ${ENV_BLOCK_START}
322
400
  declare module "@palbase/backend/env" {
323
401
  interface Tables {${body}}
324
402
  interface Schemas {${schemasBody}}
325
403
  }
404
+ ${ENV_BLOCK_END}
405
+
406
+ ${STACK_BLOCK_START}
407
+ declare module "@palbase/backend/stack" {
408
+ ${stackInterfaceBody(names ?? EMPTY_STACK_NAMES)}
409
+ }
410
+ ${STACK_BLOCK_END}
326
411
 
327
412
  export {};
328
413
  `;
@@ -737,6 +822,7 @@ export {
737
822
  DECLARATION_REFUSAL,
738
823
  DeclarationRefused,
739
824
  isDeclarationRefused,
825
+ makeStackDts,
740
826
  uniqueKeysOf,
741
827
  assertUniqueLookup,
742
828
  buildRelations,
@@ -754,4 +840,4 @@ export {
754
840
  buildContainer,
755
841
  assertNoOrphanEntryPoints
756
842
  };
757
- //# sourceMappingURL=chunk-H7EKL6HC.js.map
843
+ //# sourceMappingURL=chunk-RA7KFELX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/refusals.ts","../src/stack-gen.ts","../src/db/unique.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 * stack-gen.ts — generate the `palbase-stack.d.ts` text from the names the\n * linked environment's stack holds.\n *\n * The twin of `db/env-gen.ts`: the CLI calls\n * {@link makeStackDts} with the three name sets it read off the stack and\n * writes the result to `palbase-stack.d.ts` at the project root. That file\n * augments the `@palbase/backend/stack` interfaces, so `Secrets.get(...)`, the\n * Flags client and `@Upload({ bucket })` accept the project's real names and\n * nothing else.\n *\n * The generator does NOT reach the network and does NOT decide what a name is:\n * it renders what it is handed. The stack is the authority on which names exist\n * (`GET /v1/management/secrets`, `/flags`, `/storage/buckets`); re-deciding that\n * here would be a second, weaker copy of it.\n *\n * The emitted file ends in `export {};` — same as `makeEnvDts` and\n * `makePurchasesDts`. Without it the `.d.ts` is a global script, and\n * `declare module \"…\"` there DECLARES an ambient module (shadowing the real one,\n * so every name silently becomes invalid) instead of AUGMENTING it.\n */\n\n/** The three name sets read off the stack. Order is irrelevant — each set is\n * sorted here so the same stack always renders the same bytes and a diff shows\n * what CHANGED rather than how the API happened to order its answer. */\n/** One bucket and the renditions it declares. */\nexport interface BucketInput {\n name: string;\n variants: readonly string[];\n}\n\nexport interface StackNames {\n /** Secret names from the project's vault. */\n secrets: readonly string[];\n /** Flag keys from the project's flag store. */\n flags: readonly string[];\n /**\n * Buckets from the project's storage — a bare name, or a name with the\n * renditions it declares.\n *\n * A bucket is not only a NAME: `Storage.buckets.docs.getPublicUrl(p, {\n * variant })` refuses a rendition the bucket does not have, so the variant\n * union has to travel with it. The bare-string form is shorthand for \"no\n * variants\", which renders `never` and accepts none.\n */\n buckets: readonly (string | BucketInput)[];\n /**\n * Application role names the stack declares (`palbase roles`).\n *\n * OPTIONAL — omitted by every caller that predates FR-002a (this file's own\n * golden tests included). A missing set renders `interface Roles {}`, the\n * same closed default as an empty one; no existing caller breaks.\n */\n roles?: readonly string[];\n}\n\n/** Sorted, de-duplicated names. A stack that reports one twice (two pages of a\n * listing overlapping, say) must not render a duplicate member — TypeScript\n * accepts it, but the file stops being a function of the stack's contents. */\nfunction liveNames(names: readonly string[]): string[] {\n return [...new Set(names)].sort();\n}\n\n/** A bare identifier stays bare; anything else is quoted. Bucket names carry\n * dashes and dots (the Storage module's allowed shape), and an unquoted\n * `my-bucket` parses as a subtraction rather than a member name. */\nfunction memberName(name: string): string {\n return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name) ? name : JSON.stringify(name);\n}\n\nfunction members(names: string[]): string {\n if (names.length === 0) return \"\";\n return `\\n${names.map((n) => ` ${memberName(n)}: true;`).join(\"\\n\")}\\n `;\n}\n\n/** Buckets render a SHAPE rather than a marker, because each carries its variant\n * union. `never` for a bucket with none: the type then accepts no variant name\n * at all, which is exactly what a bucket without renditions offers. */\nfunction bucketMembers(buckets: readonly (string | BucketInput)[]): string {\n const normalized = buckets.map((b) => (typeof b === \"string\" ? { name: b, variants: [] as readonly string[] } : b));\n const byName = new Map<string, readonly string[]>();\n for (const b of normalized) byName.set(b.name, b.variants);\n const names = [...byName.keys()].sort();\n if (names.length === 0) return \"\";\n const rows = names.map((name) => {\n const variants = [...new Set(byName.get(name) ?? [])].sort();\n const union = variants.length === 0 ? \"never\" : variants.map((v) => JSON.stringify(v)).join(\" | \");\n return ` ${memberName(name)}: { variants: ${union} };`;\n });\n return `\\n${rows.join(\"\\n\")}\\n `;\n}\n\n/**\n * The four interface members of `declare module \"@palbase/backend/stack\"`,\n * with NO surrounding `declare module` wrapper and NO leading/trailing blank\n * line — just the body, indented two spaces, ready to be dropped inside\n * someone else's `declare module \"@palbase/backend/stack\" { … }`.\n *\n * Shared by {@link makeStackDts} (the standalone file) and `db/env-gen.ts`'s\n * `makeEnvDts` (the single combined file, T008/FR-002): two renderers writing\n * two copies of \"how a name becomes a member\" is exactly the drift `Roles`\n * must not repeat what happened to `Secrets`/`Flags`/`Buckets` — ONE function\n * owns the shape, both files call it.\n *\n * An empty set renders an empty interface, which is a MEANINGFUL value: the\n * stack holds no such names, so the corresponding union is `never` and every\n * call spelling one fails to compile. It is not the same as \"the file was\n * never generated\" only in that the file exists — both states refuse every\n * name, and both are correct.\n */\nexport function stackInterfaceBody(names: StackNames): string {\n const secrets = liveNames(names.secrets);\n const flags = liveNames(names.flags);\n const roles = liveNames(names.roles ?? []);\n\n return ` interface Secrets {${members(secrets)}}\n\n interface Flags {${members(flags)}}\n\n interface Buckets {${bucketMembers(names.buckets)}}\n\n interface Roles {${members(roles)}}`;\n}\n\n/** Render the project's standalone `palbase-stack.d.ts` (pre-T008 shape; kept\n * for the direct callers `index.ts` still exports it to). See\n * {@link stackInterfaceBody} for what actually decides the four interfaces. */\nexport function makeStackDts(names: StackNames): string {\n return `// palbase-stack.d.ts — GENERATED by @palbase/backend. Do not edit.\n// Source: the linked environment's stack.\n\ndeclare module \"@palbase/backend/stack\" {\n${stackInterfaceBody(names)}\n}\n\nexport {};\n`;\n}\n","/** Column and table UNIQUE declarations, including composite primary keys. */\nexport function uniqueKeysOf(table: {\n columns?: Record<string, unknown>;\n primaryKey?: readonly string[];\n unique?: readonly { columns: readonly string[] }[];\n}): string[][] {\n const columns = table.columns ?? {};\n const inlinePrimary: string[] = [], keys: string[][] = [];\n for (const [name, value] of Object.entries(columns)) {\n const col = (value && typeof value === \"object\" && \"_def\" in value ? value._def : value) as\n { primaryKey?: boolean; unique?: boolean } | undefined;\n if (col?.primaryKey) inlinePrimary.push(name);\n if (col?.unique) keys.push([name]);\n }\n const primary = table.primaryKey ?? inlinePrimary;\n if (primary.length) keys.unshift([...primary]);\n for (const key of table.unique ?? []) keys.push([...key.columns]);\n const seen = new Set<string>();\n return keys.filter(key => {\n if (!key.length || new Set(key).size !== key.length || key.some(col => !Object.hasOwn(columns, col))) {\n throw new Error(\"Unique lookup requires a nonempty declared key of distinct, known columns\");\n }\n const identity = JSON.stringify([...key].sort());\n if (seen.has(identity)) return false;\n seen.add(identity); return true;\n });\n}\n\n/** Nulls in ordinary PostgreSQL UNIQUE constraints are not unique. */\nexport function assertUniqueLookup(table: string, keys: readonly (readonly string[])[], where: Record<string, unknown>): void {\n if (!where || typeof where !== \"object\" || Array.isArray(where)) throw new Error(`findUnique(${table}): where must contain one declared unique key`);\n const columns = Object.keys(where);\n if (!keys.some(key => key.length === columns.length && key.every(col => Object.hasOwn(where, col)))) {\n throw new Error(`findUnique(${table}): supply exactly one declared unique key (${keys.map(key => key.join(\" + \")).join(\"; \") || \"none declared\"}); use findMany for other filters`);\n }\n for (const [name, value] of Object.entries(where)) {\n if (value === null || value === undefined || (typeof value === \"object\" && !(value instanceof Date)) || typeof value === \"function\" || typeof value === \"symbol\") {\n throw new Error(`findUnique(${table}): ${name} requires a non-null scalar equality value`);\n }\n }\n}\n\n/** A union of exact keys, not a partial row that could match many records. */\nexport type UniqueWhere<Row, Keys> = Keys extends readonly (infer Key extends readonly string[])[]\n ? Key extends unknown\n ? { [K in Extract<Key[number], keyof Row>]-?: NonNullable<Row[K]> } &\n { [K in Exclude<keyof Row, Key[number]>]?: never }\n : never\n : never;\n","/**\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\";\nimport { stackInterfaceBody, type StackNames } from \"../stack-gen.js\";\n\nimport type { ColumnDef } from \"./columns.js\";\n// FR-058: the \"public is bare, everything else is qualified\" rule lives in ONE\n// helper. This file used to carry two more copies of it — a module-level\n// `qualify` and a second, identical local one inside `makeEnvDts` — and the\n// duplication was not cosmetic: re-deriving the key here instead of reading the\n// one `resolveReferences` already wrote is exactly how a public foreign key got\n// relabelled onto another schema's table. Two names for one truth are two\n// interpreters of it.\nimport { qualifiedTableKey } from \"./schema-json.js\";\nimport type { SchemaDef, TableDef } from \"./schema.js\";\nimport { uniqueKeysOf } from \"./unique.js\";\nimport { CODECS } from \"./columns.js\";\n\n/** The TypeScript value type for a column, ignoring nullability (added by the\n * caller). Mirrors the `ColValue` mapped type in columns.ts exactly. */\nfunction baseTsType(def: ColumnDef): string {\n // A NAMED CODEC DECIDES THE SURFACED TYPE, and it is read BEFORE the switch\n // because the codec is exactly the declaration that overrides the storage\n // type. `numeric` surfacing as `string` is correct by default; `asNumber()`\n // is the author saying \"in this process it is a number\", and the engine\n // already makes that true (FR-003).\n if (def.codec !== undefined && def.codec in CODECS) {\n return CODECS[def.codec].tsType;\n }\n switch (def.type) {\n case \"uuid\":\n case \"text\":\n case \"timestamp\":\n return \"string\";\n case \"integer\":\n return \"number\";\n // Both are exact-precision in Postgres and lossy as a JSON number, so the\n // database proxy serializes them as strings — measured: 9007199254740993\n // used to arrive as ...992 and 41.00821234567890123 as 41.0082123456789.\n // numeric had no case at all and fell through to `unknown`, which typed\n // every numeric column out of existence.\n case \"bigint\":\n case \"numeric\":\n return \"string\";\n case \"boolean\":\n return \"boolean\";\n case \"jsonb\":\n // `unknown` DEĞİL: `unknown` taşıyan bir kolonda filtre birleşimi\n // (`V | ColRef | …`) tamamen `unknown`'a çöker, yani HİÇBİR kural\n // tutunamaz — `col()` o kolonu her şeyle karşılaştırabiliyordu\n // (D-021'in açık bıraktığı son delik). `Json` gerçek kısıtı söylüyor ve\n // markalanabiliyor.\n return \"Json\";\n // FR-008: the authoring type of a pgvector column. The default `unknown`\n // branch below STAYS — an unknown wire type is refused on the Go side\n // (FR-005), never papered over here.\n case \"vector\":\n return \"number[]\";\n case \"enum\": {\n const values = def.enumValues ?? [];\n if (values.length === 0) return \"string\";\n return values.map((v) => JSON.stringify(v)).join(\" | \");\n }\n default: {\n // TÜKETİCİLİK KAPISI. `ColumnType`'a yeni bir değer eklenip burası\n // güncellenmezse BU SATIR DERLEME HATASI verir.\n //\n // Eskiden burası sessizce `unknown` döndürüyordu ve `unknown` taşıyan bir\n // kolonda filtre birleşimi tamamen `unknown`'a çöker — yani `col()`,\n // `now()`, toplama, hepsi o kolonda kuralsız kalırdı. `numeric` bir\n // zamanlar tam olarak buraya düşmüştü (\"numeric had no case at all\"),\n // ve `jsonb` aynı çöküşü 28.0.0'a kadar yaşadı. Üçüncüsü olmasın.\n const unhandled: never = def.type;\n throw new Error(\n `env-gen: \"${String(unhandled)}\" kolon tipinin TypeScript karşılığı ` +\n `bildirilmemiş. baseTsType'a bir case ekleyin — sessizce \\`unknown\\` ` +\n `dönmek o kolonu her kuralın dışına çıkarır.`,\n );\n }\n }\n}\n\n/** The full row type for a column: base type, `| null` when nullable. */\n/**\n * Kolonun POSTGRES tipi, tipin İÇİNDE taşınan bir marka olarak.\n *\n * TypeScript `numeric`, `bigint`, `text`, `uuid` ve `timestamp`'i tek bir\n * `string`'e düşürüyor. Yani `integer ↔ numeric` (Postgres'te geçerli) ile\n * `integer ↔ text` (geçersiz) tipte AYNI görünüyordu ve `col()` hangi kuralı\n * koyarsa koysun bir tarafta yanılıyordu (D-021: yanlış ret mi yanlış kabul mü\n * seçilecekti — ikisi de yanlıştı).\n *\n * Marka o bilgiyi geri getiriyor. `& { readonly __pg?: \"…\" }` seçilmesinin\n * nedeni ÖLÇÜLDÜ: isteğe bağlı bir alanla kesişim, satırı hâlâ düz `string`\n * olarak okunabilir ve düz bir değerle YAZILABİLİR bırakıyor — yani marka\n * yalnız karşılaştırma kurallarının gördüğü, kullanıcının hiç görmediği bir\n * bilgi. Zorunlu bir alan olsaydı `{ balance: \"10.00\" }` derlenmezdi.\n *\n * `enum` KİMLİĞİYLE markalanıyor: iki FARKLI enum'u Postgres de karşılaştırmaz,\n * ve düz `\"enum\"` markası onları aynı sayardı.\n */\nfunction pgBrand(def: ColumnDef): string {\n if (def.type === \"enum\") {\n const values = [...(def.enumValues ?? [])].sort();\n return values.length === 0 ? \"enum\" : `enum:${values.join(\"|\")}`;\n }\n return def.type;\n}\n\nfunction rowType(def: ColumnDef): string {\n const base = baseTsType(def);\n // `unknown` MARKALANAMAZ: marka bir kesişim ve `unknown & X` doğrudan `X`'e\n // çöker. `jsonb` kolonu `Pg<unknown, \"jsonb\">` yazılınca tipi\n // `{ readonly __pg?: \"jsonb\" }` oluyordu — yani kolon DARALDI ve meşru bir\n // nesne yazılamaz hâle geldi. GERÇEK bir projede ölçüldü: 33 tablolu bir\n // şemada `user_preferences`'ın jsonb kolonlarına yazan iki çağrı kırıldı.\n //\n // Markasız kalan kolon eski (gevşek) kurala düşer — jsonb için bu zaten\n // bugünkü davranış, yani hiçbir şey kötüleşmiyor.\n\n // Takma ad, ham kesişim yerine: bu dosyayı GELİŞTİRİCİ de açıyor ve\n // `(string) & { readonly __pg?: \"uuid\" }` satırları okunmaz kılıyordu.\n // `Pg<string, \"uuid\">` hem kısa hem kolonun Postgres tipini SÖYLÜYOR.\n // Takma ad ayrıca `enum` birleşimlerini tip argümanı olarak sarmalıyor —\n // ham kesişimde `A | B & C`, `A | (B & C)` diye ayrışıp bir dalı markasız\n // bırakırdı.\n const branded = `Pg<${base}, ${JSON.stringify(pgBrand(def))}>`;\n return def.nullable ? `${branded} | null` : branded;\n}\n\n/** True when a column may be omitted on INSERT — nullable OR has any default.\n * Mirrors `ColIsOptionalOnInsert` in columns.ts. */\nfunction optionalOnInsert(def: ColumnDef): boolean {\n return (\n def.nullable === true ||\n def.defaultRandom === true ||\n def.defaultNow === true ||\n def.defaultValue !== undefined\n );\n}\n\n\n\nexport type Relation = {\n name: string;\n to: string;\n kind: \"one\" | \"many\";\n /**\n * The foreign-key COLUMN the relation runs through.\n *\n * Without it \"there is a relation\" is half the fact, and everything that\n * consumes the map — the query builder, the seed engine, the cross-boundary\n * lock — has to re-derive the column: a second interpreter of the same graph.\n */\n via: string;\n};\n\n/** `list_id` → `list`; anything else keeps its column name (FR-019). */\nfunction forwardName(column: string): string {\n return column.endsWith(\"_id\") ? column.slice(0, -3) : column;\n}\n\n/**\n * Where a relation name came from, so a refusal can say it out loud.\n *\n * A collision on a parent table can be between two REVERSE edges, or between a\n * reverse edge and the parent's own FORWARD one — `lists.todos_id` names a\n * forward `todos`, and `todos.list_id` reverses onto `lists` as `todos` too.\n * The old message called both sides \"reverse relations\", which sent the reader\n * looking for a second reverse edge that was never there.\n */\ntype NameOrigin = {\n /** The table the foreign-key COLUMN is declared on. */\n table: string;\n column: string;\n direction: \"forward\" | \"reverse\";\n def: ColumnDef;\n};\n\nfunction describeOrigin(o: NameOrigin): string {\n return o.direction === \"forward\"\n ? `the foreign key \"${o.table}.${o.column}\"`\n : `the reverse of \"${o.table}.${o.column}\"`;\n}\n\n/**\n * The call that renames THIS relation — named per verb, because the verbs do\n * not take the same options.\n *\n * NFR-002 asks every refusal to name a remedy the reader can apply. The old\n * message said `references(() => …, { as: \"…\" })` for every case, and\n * `ownedByUser()` takes no arguments at all while `userRef` /\n * `installationRef` take `{ onDelete, as }` — so following it literally was\n * impossible for exactly the columns that most often collide.\n *\n * A reverse edge only ever exists for a target that is a DECLARED table, and\n * only `references()` can point at one: `auth.*` is not declared (no reverse\n * edge) and a self-reference has no separate parent (skipped). So the reverse\n * remedy has one form and it is always the right one.\n */\nfunction renameCall(o: NameOrigin): string {\n if (o.direction === \"reverse\") return `references(() => …, { reverseAs: \"…\" })`;\n if (o.def.owns === true) {\n return `ownedByUser() takes no { as } — if \"${o.column}\" only POINTS at a user, declare it userRef({ onDelete: … }) instead`;\n }\n const target = o.def.references?.table;\n if (target === \"auth.users\") return `userRef({ onDelete: …, as: \"…\" })`;\n if (target === \"auth.installations\") return `installationRef({ onDelete: …, as: \"…\" })`;\n if (o.def.selfRefColumn !== undefined) return `selfReferences(\"…\", { as: \"…\" })`;\n return `references(() => …, { as: \"…\" })`;\n}\n\n/**\n * Derive the relation graph from the declared foreign keys.\n *\n * Until now a SECOND foreign key onto the same parent was silently dropped: only\n * the first column in declaration order was recorded, and the other one quietly\n * became an ordinary writable column. Which relation you got was decided by the\n * order somebody happened to type the columns in. That silence is what this\n * function exists to end — ambiguity is rejected and named, never resolved by\n * declaration order.\n *\n * THE HAZARD IS ONE NAME WITH TWO RELATIONS (FR-022), not two foreign keys onto\n * one target. Those are not the same set, and treating them as one refused the\n * package's own documented shape: a table with `ownedByUser()` beside a\n * `userRef()` has two foreign keys onto `auth.users` and no ambiguity whatever —\n * the names are `owner` and the pointing column's own, and `auth.users` is not a\n * declared table, so neither takes a reverse edge to collide over. The gate\n * counted the owner toward the total while exempting it from the naming\n * requirement, so `docs/schema.md`'s example threw, naming a remedy no verb in\n * it accepts.\n *\n * The two directions are named SEPARATELY. `as` sets the forward name (FR-019),\n * `reverseAs` sets the reverse one (FR-020, whose default is the child table's\n * name). One option cannot set both: two children that each name their forward\n * edge `author` collided on the parent as `author`, and the refusal asked for\n * the `{ as }` they had both already written — a refusal with no exit.\n */\nexport function buildRelations(schemas: readonly SchemaDef[]): Map<string, Relation[]> {\n const out = new Map<string, Relation[]>();\n /** Per table key: relation name → where that name came from. */\n const taken = new Map<string, Map<string, NameOrigin>>();\n for (const schema of schemas) {\n for (const t of Object.values(schema.tables)) {\n const key = qualifiedTableKey(schema.name, t.name);\n out.set(key, []);\n taken.set(key, new Map());\n }\n }\n\n /** Record one edge on `tableKey`, or refuse the name it would take twice. */\n const claim = (tableKey: string, name: string, origin: NameOrigin, edge: Relation): void => {\n const names = taken.get(tableKey);\n if (names === undefined) return;\n const held = names.get(name);\n if (held !== undefined) {\n // FR-015 asks this one to LIST the conflicting columns; it used to name\n // neither, so the reader had to find them.\n if (held.def.owns === true && origin.def.owns === true) {\n throw new DeclarationRefused(\n `table \"${tableKey}\" declares TWO owner columns (${held.column}, ${origin.column}) — a table has at most ONE ownedByUser(). If the other column only POINTS at a user, declare it userRef({ onDelete: … }) instead.`,\n );\n }\n const heldFix = renameCall(held);\n const originFix = renameCall(origin);\n const remedy =\n heldFix === originFix\n ? `rename one of them: ${heldFix}`\n : `rename one of them — \"${held.table}.${held.column}\": ${heldFix}; \"${origin.table}.${origin.column}\": ${originFix}`;\n throw new DeclarationRefused(\n `table \"${tableKey}\": ${describeOrigin(held)} and ${describeOrigin(origin)} both resolve to the relation name \"${name}\" — ${remedy}.`,\n );\n }\n names.set(name, origin);\n out.get(tableKey)?.push(edge);\n };\n\n for (const schema of schemas) {\n for (const table of Object.values(schema.tables)) {\n const childKey = qualifiedTableKey(schema.name, table.name);\n if (!out.has(childKey)) continue;\n\n for (const [col, builder] of Object.entries(table.columns)) {\n const def = builder._def;\n if (def.references === undefined) continue;\n // `references.table` IS the canonical key — `resolveReferences` wrote it\n // with `qualifiedTableKey`, so public is bare and everything else is\n // qualified, `auth.users` included.\n //\n // It used to be re-derived here from a bare-name → key map, which gave a\n // DIFFERENT answer in exactly one case: two schemas declaring the same\n // table name. The map kept whichever was declared LAST, so a public FK\n // was relabelled onto another schema's table and the real parent got no\n // reverse edge — silently, while RefJSON (and therefore the DDL) went on\n // pointing at the right one. The generated type and the database\n // disagreed, and nothing said so.\n const targetKey = def.references.table;\n\n const name = def.owns === true ? \"owner\" : (def.refAs ?? forwardName(col));\n claim(\n childKey,\n name,\n { table: table.name, column: col, direction: \"forward\", def },\n { name, to: targetKey, kind: \"one\", via: col },\n );\n\n // Reverse edge, unless the FK points outside the declared schemas (auth.users)\n // or back at the declaring table (a self-reference has no separate parent).\n if (!out.has(targetKey) || targetKey === childKey) continue;\n // FR-020: the reverse name is the CHILD TABLE's, not the forward name.\n // `as` used to set this too, which both broke FR-020 for a single named\n // FK (`users.author` where `users.posts` was required) and left two\n // children that chose the same forward name with no way to be declared.\n const reverse = def.reverseAs ?? table.name;\n claim(\n targetKey,\n reverse,\n { table: table.name, column: col, direction: \"reverse\", def },\n { name: reverse, to: childKey, kind: \"many\", via: col },\n );\n }\n }\n }\n return out;\n}\n\n\n\n\n/** Emit the `row` / `insert` / `relations` blocks for one table at the given\n * base indentation. */\nfunction tableBlock(table: TableDef, relations: Relation[], indent: string): string {\n const cols = Object.entries(table.columns);\n const rowLines = cols.map(([col, builder]) => {\n return `${indent} ${col}: ${rowType(builder._def)};`;\n });\n // FR-004: `can` — adlandırılmış UPDATE policy adlarının literal union'ı.\n // Policy'siz tabloda `never[]`: alan hep var (motor `[]` yazar), eleman yok.\n // Gerçek bir `can` kolonu varsa yankı yoktur (motor da kolonu korur): ikinci\n // bir `can:` satırı `skipLibCheck` altında sessizce İLK bildirime çözülürdü.\n // İlişki de aynı rezervasyon (defineTable reddeder; ham TableDef için kemer).\n const hasCanColumn =\n Object.prototype.hasOwnProperty.call(table.columns, \"can\") || relations.some((r) => r.name === \"can\");\n // Motorla aynı süzgeç: 59 baytı aşan ad (`can:` + ad > NAMEDATALEN 63) telde asla gelmez.\n const canNames = (table.policies ?? []).filter((p) => p.command === \"update\" && p.permissive !== false && Buffer.byteLength(`can:${p.name}`, \"utf8\") <= 63).map((p) => JSON.stringify(p.name));\n // The contract travels with the type (final review M-2): a reader of the .d.ts\n // sees what `can` is for without opening the docs.\n const canDoc = `${indent} /** Names of this table's UPDATE policies whose \\`using\\` is true for THIS row and caller — an AFFORDANCE for the interface (draw or hide a control); never an authorization decision, may be incomplete, the server decides again on every request. */`;\n const canLine = hasCanColumn ? null : `${canDoc}\\n${indent} can: ${canNames.length === 0 ? \"never[]\" : `(${canNames.join(\" | \")})[]`};`;\n const insertLines = cols.map(([col, builder]) => {\n const def = builder._def;\n const opt = optionalOnInsert(def) ? \"?\" : \"\";\n return `${indent} ${col}${opt}: ${rowType(def)};`;\n });\n const relEntries = relations\n .map(\n (r) =>\n `${r.name}: { to: ${JSON.stringify(r.to)}; kind: ${JSON.stringify(r.kind)}; via: ${JSON.stringify(r.via)} }`,\n )\n .join(\"; \");\n return [\n `${indent}${table.name}: {`,\n `${indent} row: {`,\n ...rowLines,\n ...(canLine === null ? [] : [canLine]),\n `${indent} };`,\n `${indent} insert: {`,\n ...insertLines,\n `${indent} };`,\n `${indent} relations: {${relEntries === \"\" ? \"\" : ` ${relEntries} `}};`,\n `${indent} uniqueKeys: ${JSON.stringify(uniqueKeysOf(table))};`,\n // searchable: vector kolonu YA DA search beyanı → EnvTypedTable'da search()\n // üyesini açan yapısal bayrak (FR-013). Yokken satır hiç üretilmez ki\n // mevcut şemaların d.ts'i bayt-aynı kalsın.\n ...(cols.some(([, b]) => b._def.type === \"vector\") || table.search !== undefined\n ? [`${indent} searchable: true;`]\n : []),\n // appendOnly (FR-031): EnvTypedTable'ın altı yazma üyesini KALDIRAN yapısal\n // bayrak. `searchable` ile aynı desen ve aynı OMIT disiplini — bayrak yokken\n // satır hiç üretilmez ki mevcut şemaların d.ts'i bayt-aynı kalsın.\n ...(table.appendOnly === true ? [`${indent} appendOnly: true;`] : []),\n `${indent}};`,\n ].join(\"\\n\");\n}\n\n/**\n * Generate the full `palbase-env.d.ts` text for the project's schemas.\n *\n * The emitted file ends in `export {};` — same as `makeStackDts`. Without it the\n * `.d.ts` is a global script, and `declare module \"…\"` there DECLARES an ambient\n * module (shadowing the real one, so every export of `@palbase/backend/env`\n * silently becomes invalid) instead of AUGMENTING it. Measured on a minimal tsc\n * repro: with the line, exit 0; without it, `TS2305: Module '\"…\"' has no\n * exported member`. The line was dropped once in a rewrite and nothing caught\n * it, so `env-gen.test.ts` now gates it directly.\n *\n * @example\n * import { makeEnvDts } from \"@palbase/backend\";\n * import publicSchema from \"./db/public.js\";\n * import billing from \"./db/billing.js\";\n * writeFileSync(\"palbase-env.d.ts\", makeEnvDts([publicSchema, billing]));\n */\n/**\n * A free-form `.transform<T>()` CANNOT be typed here, and must not be typed\n * WRONG (FR-004).\n *\n * The target type is a TYPE PARAMETER — erased at runtime. This generator reads\n * the bundled runtime object, so it only ever saw `{ fromDb, toDb }` and fell\n * through to the storage type: it emitted `string` for a column the engine hands\n * back as a number. A consumer project measured exactly this and wrote a\n * hand-rolled codec module plus 141 call sites rather than trust the types.\n *\n * Refusing is the fix, not a limitation: the remedy is named in the message and\n * produces BOTH the conversion and the type from one declaration.\n */\nfunction refuseFreeFormTransforms(schemas: readonly SchemaDef[]): void {\n for (const schema of schemas) {\n for (const table of Object.values(schema.tables)) {\n for (const [col, builder] of Object.entries(table.columns)) {\n const def = builder._def;\n if (def.transform === undefined || def.codec !== undefined) continue;\n const where = qualifiedTableKey(schema.name, table.name);\n // `DeclarationRefused`, NOT a bare Error. `refusals.ts` carries the\n // measured reason: a bare Error from this layer is treated as FATAL by\n // the runtime, the supervisor takes the pod down and palsvc with it —\n // and palsvc is THE PROCESS THAT ACCEPTS THE PUSH this message asks\n // for. The cure must not kill the thing that delivers it.\n throw new DeclarationRefused(\n `table \"${where}\" column \"${col}\" declares .transform<T>(): its target type does not exist at ` +\n `runtime, so the generated types would say something the engine contradicts. Declare a named ` +\n `codec instead — .asNumber() for a JS number, .asDecimal() for the exact string.`,\n );\n }\n }\n }\n}\n\n/**\n * Fixed marker comments that wrap each `declare module` block in the single\n * generated file (FR-002, C-1/C-8). They are the ONLY thing the CLI's\n * `preserveStackBlock` (T010, `sdk/cli/internal/backend/build.go`) reads: that\n * function does not parse this file as TypeScript, it slices bytes between\n * these exact lines. This literal text is a cross-repo contract — T010 hardcodes\n * the same four strings and a Go test (`TestPreserveStackBlockMarkersAreTheRenderers`)\n * greps this file for them; changing it here without changing it there breaks\n * that gate silently.\n */\nexport const ENV_BLOCK_START = \"// palbase:env:begin\";\nexport const ENV_BLOCK_END = \"// palbase:env:end\";\nexport const STACK_BLOCK_START = \"// palbase:stack:begin\";\nexport const STACK_BLOCK_END = \"// palbase:stack:end\";\n\n/** What a checkout with no linked stack (and no machine-local cache) renders:\n * four empty interfaces, same as a stack that reports no names at all\n * (FR-003a's \"never generated\" and \"generated empty\" cases render identically\n * on purpose — both correctly refuse every name). */\nconst EMPTY_STACK_NAMES: StackNames = { secrets: [], flags: [], buckets: [], roles: [] };\n\nexport function makeEnvDts(schemas: readonly SchemaDef[], names?: StackNames): 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\n${ENV_BLOCK_START}\ndeclare module \"@palbase/backend/env\" {\n interface Tables {${body}}\n interface Schemas {${schemasBody}}\n}\n${ENV_BLOCK_END}\n\n${STACK_BLOCK_START}\ndeclare module \"@palbase/backend/stack\" {\n${stackInterfaceBody(names ?? EMPTY_STACK_NAMES)}\n}\n${STACK_BLOCK_END}\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","liveNames","names","Set","sort","memberName","name","test","JSON","stringify","members","length","map","n","join","bucketMembers","buckets","normalized","b","variants","byName","Map","set","keys","rows","get","union","v","stackInterfaceBody","secrets","flags","roles","makeStackDts","uniqueKeysOf","table","columns","inlinePrimary","keys","name","value","Object","entries","col","_def","primaryKey","push","unique","primary","length","unshift","key","seen","Set","filter","size","some","hasOwn","Error","identity","JSON","stringify","sort","has","add","assertUniqueLookup","where","Array","isArray","every","map","join","undefined","Date","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","hasCanColumn","prototype","hasOwnProperty","call","some","r","canNames","policies","filter","p","command","permissive","Buffer","byteLength","canDoc","canLine","insertLines","opt","relEntries","uniqueKeysOf","b","search","appendOnly","refuseFreeFormTransforms","transform","where","ENV_BLOCK_START","ENV_BLOCK_END","STACK_BLOCK_START","STACK_BLOCK_END","EMPTY_STACK_NAMES","secrets","flags","buckets","roles","makeEnvDts","publicSchema","find","s","others","publicBlocks","keys","body","schemaBlocks","inner","schemasBody","stackInterfaceBody","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,4 +1,4 @@
1
- export { o as AnyColumn, p as AtomicDatabase, q as AtomicOptions, y as ColumnBuilder, z as ColumnDef, F as ColumnMap, G as ColumnType, C as CommandOptions, D as DatabaseBudget, d as DatabaseDiagnostics, c as DatabaseDiagnosticsOptions, K as DatabaseQueryEvent, N as EXTENSION_DEPENDENCIES, O as EmbeddingModelRef, E as EnvServiceDatabase, V as EnvTypedDatabase, af as InsertManyOptions, ag as InsertShape, al as Materialized, as as OnDeleteAction, au as PALBASE_EXTENSIONS, P as Page, aw as PageInfo, ax as PageInput, ay as PageNavigation, b5 as PalbaseExtension, c8 as PolicyBuilder, c9 as PolicyCommand, ca as PolicyDef, cd as PolicyMode, cg as RawConstraintDef, f as RawPageOptions, ci as Ref, ck as RowShape, S as SchemaDef, ct as TABLE_META, cu as TableDef, cv as TableHandle, cw as TableInput, T as TransactionIsolation, cz as TxColumnExpr, cA as TxInsertShape, cC as TxNow, cD as TxPlan, g as TxPlanBody, cE as TxPlanError, cF as TxPlanHandle, cG as TxPlanOpResult, cH as TxPlanRejection, h as TxPlanResponse, cI as TxRefError, cJ as TxRow, cK as TxRows, cL as TxSelectOptions, cM as TxSetShape, cO as TxTable, cP as TxTables, cQ as TxWhere, cW as TypedDB, cX as TypedTable, cY as TypedTx, c$ as UniqueWhere, d9 as bigint, da as boolean, de as dec, dh as defineSchema, di as defineTable, dj as enumType, dp as inc, ds as installationRef, dt as integer, du as isPalbaseExtension, dw as jsonb, dx as makeTypedDB, dy as now, dC as openai, dD as ownedByUser, dE as policy, dF as raw, dH as text, dI as timestamp, dJ as userRef, dK as uuid, dL as vector } from '../index-CCY1h_J2.cjs';
1
+ export { o as AnyColumn, p as AtomicDatabase, q as AtomicOptions, y as ColumnBuilder, z as ColumnDef, F as ColumnMap, G as ColumnType, C as CommandOptions, D as DatabaseBudget, d as DatabaseDiagnostics, c as DatabaseDiagnosticsOptions, K as DatabaseQueryEvent, N as EXTENSION_DEPENDENCIES, O as EmbeddingModelRef, E as EnvServiceDatabase, V as EnvTypedDatabase, af as InsertManyOptions, ag as InsertShape, al as Materialized, as as OnDeleteAction, au as PALBASE_EXTENSIONS, P as Page, aw as PageInfo, ax as PageInput, ay as PageNavigation, b5 as PalbaseExtension, c8 as PolicyBuilder, c9 as PolicyCommand, ca as PolicyDef, cd as PolicyMode, cg as RawConstraintDef, f as RawPageOptions, ci as Ref, ck as RowShape, S as SchemaDef, ct as TABLE_META, cu as TableDef, cv as TableHandle, cw as TableInput, T as TransactionIsolation, cz as TxColumnExpr, cA as TxInsertShape, cC as TxNow, cD as TxPlan, g as TxPlanBody, cE as TxPlanError, cF as TxPlanHandle, cG as TxPlanOpResult, cH as TxPlanRejection, h as TxPlanResponse, cI as TxRefError, cJ as TxRow, cK as TxRows, cL as TxSelectOptions, cM as TxSetShape, cO as TxTable, cP as TxTables, cQ as TxWhere, cW as TypedDB, cX as TypedTable, cY as TypedTx, c$ as UniqueWhere, d9 as bigint, da as boolean, de as dec, dh as defineSchema, di as defineTable, dj as enumType, dp as inc, ds as installationRef, dt as integer, du as isPalbaseExtension, dw as jsonb, dx as makeTypedDB, dy as now, dC as openai, dD as ownedByUser, dE as policy, dF as raw, dH as text, dI as timestamp, dJ as userRef, dK as uuid, dL as vector } from '../index-t7Ie44mM.cjs';
2
2
  import 'zod';
3
3
  import './env.cjs';
4
4
  import '../stack.cjs';
@@ -1,4 +1,4 @@
1
- export { o as AnyColumn, p as AtomicDatabase, q as AtomicOptions, y as ColumnBuilder, z as ColumnDef, F as ColumnMap, G as ColumnType, C as CommandOptions, D as DatabaseBudget, d as DatabaseDiagnostics, c as DatabaseDiagnosticsOptions, K as DatabaseQueryEvent, N as EXTENSION_DEPENDENCIES, O as EmbeddingModelRef, E as EnvServiceDatabase, V as EnvTypedDatabase, af as InsertManyOptions, ag as InsertShape, al as Materialized, as as OnDeleteAction, au as PALBASE_EXTENSIONS, P as Page, aw as PageInfo, ax as PageInput, ay as PageNavigation, b5 as PalbaseExtension, c8 as PolicyBuilder, c9 as PolicyCommand, ca as PolicyDef, cd as PolicyMode, cg as RawConstraintDef, f as RawPageOptions, ci as Ref, ck as RowShape, S as SchemaDef, ct as TABLE_META, cu as TableDef, cv as TableHandle, cw as TableInput, T as TransactionIsolation, cz as TxColumnExpr, cA as TxInsertShape, cC as TxNow, cD as TxPlan, g as TxPlanBody, cE as TxPlanError, cF as TxPlanHandle, cG as TxPlanOpResult, cH as TxPlanRejection, h as TxPlanResponse, cI as TxRefError, cJ as TxRow, cK as TxRows, cL as TxSelectOptions, cM as TxSetShape, cO as TxTable, cP as TxTables, cQ as TxWhere, cW as TypedDB, cX as TypedTable, cY as TypedTx, c$ as UniqueWhere, d9 as bigint, da as boolean, de as dec, dh as defineSchema, di as defineTable, dj as enumType, dp as inc, ds as installationRef, dt as integer, du as isPalbaseExtension, dw as jsonb, dx as makeTypedDB, dy as now, dC as openai, dD as ownedByUser, dE as policy, dF as raw, dH as text, dI as timestamp, dJ as userRef, dK as uuid, dL as vector } from '../index-fLaf0PN2.js';
1
+ export { o as AnyColumn, p as AtomicDatabase, q as AtomicOptions, y as ColumnBuilder, z as ColumnDef, F as ColumnMap, G as ColumnType, C as CommandOptions, D as DatabaseBudget, d as DatabaseDiagnostics, c as DatabaseDiagnosticsOptions, K as DatabaseQueryEvent, N as EXTENSION_DEPENDENCIES, O as EmbeddingModelRef, E as EnvServiceDatabase, V as EnvTypedDatabase, af as InsertManyOptions, ag as InsertShape, al as Materialized, as as OnDeleteAction, au as PALBASE_EXTENSIONS, P as Page, aw as PageInfo, ax as PageInput, ay as PageNavigation, b5 as PalbaseExtension, c8 as PolicyBuilder, c9 as PolicyCommand, ca as PolicyDef, cd as PolicyMode, cg as RawConstraintDef, f as RawPageOptions, ci as Ref, ck as RowShape, S as SchemaDef, ct as TABLE_META, cu as TableDef, cv as TableHandle, cw as TableInput, T as TransactionIsolation, cz as TxColumnExpr, cA as TxInsertShape, cC as TxNow, cD as TxPlan, g as TxPlanBody, cE as TxPlanError, cF as TxPlanHandle, cG as TxPlanOpResult, cH as TxPlanRejection, h as TxPlanResponse, cI as TxRefError, cJ as TxRow, cK as TxRows, cL as TxSelectOptions, cM as TxSetShape, cO as TxTable, cP as TxTables, cQ as TxWhere, cW as TypedDB, cX as TypedTable, cY as TypedTx, c$ as UniqueWhere, d9 as bigint, da as boolean, de as dec, dh as defineSchema, di as defineTable, dj as enumType, dp as inc, ds as installationRef, dt as integer, du as isPalbaseExtension, dw as jsonb, dx as makeTypedDB, dy as now, dC as openai, dD as ownedByUser, dE as policy, dF as raw, dH as text, dI as timestamp, dJ as userRef, dK as uuid, dL as vector } from '../index-B8zC9oV0.js';
2
2
  import 'zod';
3
3
  import './env.js';
4
4
  import '../stack.js';
@@ -32,6 +32,7 @@ __export(engine_exports, {
32
32
  createLazyTransaction: () => createLazyTransaction,
33
33
  createOps: () => createOps,
34
34
  createRequestDatabase: () => createRequestDatabase,
35
+ databaseAdmission: () => databaseAdmission,
35
36
  effectiveAuth: () => effectiveAuth,
36
37
  hostAllowed: () => hostAllowed,
37
38
  installCommandExecutor: () => installCommandExecutor,
@@ -7445,6 +7446,7 @@ __name(closeDriver, "closeDriver");
7445
7446
  createLazyTransaction,
7446
7447
  createOps,
7447
7448
  createRequestDatabase,
7449
+ databaseAdmission,
7448
7450
  effectiveAuth,
7449
7451
  hostAllowed,
7450
7452
  installCommandExecutor,