@prisma-next/target-postgres 0.10.0-dev.2 → 0.10.0-dev.20

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 (41) hide show
  1. package/dist/control.mjs +4 -4
  2. package/dist/descriptor-meta-DLA2xV6B.mjs +126 -0
  3. package/dist/descriptor-meta-DLA2xV6B.mjs.map +1 -0
  4. package/dist/{issue-planner-qalHRCI2.mjs → issue-planner-BLMwKt1N.mjs} +5 -5
  5. package/dist/{issue-planner-qalHRCI2.mjs.map → issue-planner-BLMwKt1N.mjs.map} +1 -1
  6. package/dist/issue-planner.mjs +1 -1
  7. package/dist/migration.mjs +1 -1
  8. package/dist/{op-factory-call-Zsrdty3k.mjs → op-factory-call-YAmICvwh.mjs} +2 -2
  9. package/dist/{op-factory-call-Zsrdty3k.mjs.map → op-factory-call-YAmICvwh.mjs.map} +1 -1
  10. package/dist/op-factory-call.mjs +1 -1
  11. package/dist/pack.d.mts +7 -0
  12. package/dist/pack.d.mts.map +1 -1
  13. package/dist/pack.mjs +1 -1
  14. package/dist/{planner-C8yhbXOq.mjs → planner-DT4HZkBf.mjs} +3 -3
  15. package/dist/{planner-C8yhbXOq.mjs.map → planner-DT4HZkBf.mjs.map} +1 -1
  16. package/dist/{planner-ddl-builders-DINYrbJ3.mjs → planner-ddl-builders-DYMuN0w1.mjs} +2 -2
  17. package/dist/{planner-ddl-builders-DINYrbJ3.mjs.map → planner-ddl-builders-DYMuN0w1.mjs.map} +1 -1
  18. package/dist/planner-ddl-builders.mjs +1 -1
  19. package/dist/{planner-sql-checks-BM4sD6Xc.mjs → planner-sql-checks-K-mTBJDi.mjs} +2 -2
  20. package/dist/{planner-sql-checks-BM4sD6Xc.mjs.map → planner-sql-checks-K-mTBJDi.mjs.map} +1 -1
  21. package/dist/planner-sql-checks.mjs +1 -1
  22. package/dist/planner.mjs +1 -1
  23. package/dist/{postgres-contract-serializer-CcZO9ukP.mjs → postgres-contract-serializer-CrET5Ov0.mjs} +41 -19
  24. package/dist/postgres-contract-serializer-CrET5Ov0.mjs.map +1 -0
  25. package/dist/{postgres-schema-BosNxhWq.mjs → postgres-schema-CK82EuWq.mjs} +7 -2
  26. package/dist/postgres-schema-CK82EuWq.mjs.map +1 -0
  27. package/dist/runtime.d.mts.map +1 -1
  28. package/dist/runtime.mjs +2 -2
  29. package/dist/{tables-DZ-5Yxi0.mjs → tables-CWxZgD0H.mjs} +2 -2
  30. package/dist/{tables-DZ-5Yxi0.mjs.map → tables-CWxZgD0H.mjs.map} +1 -1
  31. package/dist/types.d.mts +1 -1
  32. package/dist/types.d.mts.map +1 -1
  33. package/dist/types.mjs +1 -1
  34. package/package.json +17 -17
  35. package/src/core/authoring.ts +2 -0
  36. package/src/core/postgres-contract-serializer.ts +76 -41
  37. package/src/core/postgres-schema.ts +7 -1
  38. package/dist/descriptor-meta-zrZzWmJF.mjs +0 -91
  39. package/dist/descriptor-meta-zrZzWmJF.mjs.map +0 -1
  40. package/dist/postgres-contract-serializer-CcZO9ukP.mjs.map +0 -1
  41. package/dist/postgres-schema-BosNxhWq.mjs.map +0 -1
@@ -1,91 +0,0 @@
1
- import { t as PostgresEnumType } from "./postgres-enum-type-DS-KLVRH.mjs";
2
- import { temporalAuthoringPresets } from "@prisma-next/family-sql/control";
3
- const postgresTargetDescriptorMeta = {
4
- kind: "target",
5
- familyId: "sql",
6
- targetId: "postgres",
7
- id: "postgres",
8
- version: "0.0.1",
9
- capabilities: {},
10
- authoring: {
11
- type: {},
12
- field: {
13
- text: {
14
- kind: "fieldPreset",
15
- output: {
16
- codecId: "pg/text@1",
17
- nativeType: "text"
18
- }
19
- },
20
- int: {
21
- kind: "fieldPreset",
22
- output: {
23
- codecId: "pg/int4@1",
24
- nativeType: "int4"
25
- }
26
- },
27
- bigint: {
28
- kind: "fieldPreset",
29
- output: {
30
- codecId: "pg/int8@1",
31
- nativeType: "int8"
32
- }
33
- },
34
- float: {
35
- kind: "fieldPreset",
36
- output: {
37
- codecId: "pg/float8@1",
38
- nativeType: "float8"
39
- }
40
- },
41
- decimal: {
42
- kind: "fieldPreset",
43
- output: {
44
- codecId: "pg/numeric@1",
45
- nativeType: "numeric"
46
- }
47
- },
48
- boolean: {
49
- kind: "fieldPreset",
50
- output: {
51
- codecId: "pg/bool@1",
52
- nativeType: "bool"
53
- }
54
- },
55
- json: {
56
- kind: "fieldPreset",
57
- output: {
58
- codecId: "pg/jsonb@1",
59
- nativeType: "jsonb"
60
- }
61
- },
62
- bytes: {
63
- kind: "fieldPreset",
64
- output: {
65
- codecId: "pg/bytea@1",
66
- nativeType: "bytea"
67
- }
68
- },
69
- dateTime: {
70
- kind: "fieldPreset",
71
- output: {
72
- codecId: "pg/timestamptz@1",
73
- nativeType: "timestamptz"
74
- }
75
- },
76
- temporal: temporalAuthoringPresets({
77
- codecId: "pg/timestamptz@1",
78
- nativeType: "timestamptz"
79
- })
80
- },
81
- entityTypes: { enum: {
82
- kind: "entity",
83
- discriminator: "postgres-enum",
84
- output: { factory: (input) => new PostgresEnumType(input) }
85
- } }
86
- }
87
- };
88
- //#endregion
89
- export { postgresTargetDescriptorMeta as t };
90
-
91
- //# sourceMappingURL=descriptor-meta-zrZzWmJF.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"descriptor-meta-zrZzWmJF.mjs","names":[],"sources":["../src/core/authoring.ts","../src/core/descriptor-meta.ts"],"sourcesContent":["import { temporalAuthoringPresets } from '@prisma-next/family-sql/control';\nimport type {\n AuthoringEntityTypeNamespace,\n AuthoringFieldNamespace,\n AuthoringTypeNamespace,\n} from '@prisma-next/framework-components/authoring';\nimport type { PostgresEnumStorageEntry } from '@prisma-next/sql-contract/types';\nimport { PostgresEnumType, type PostgresEnumTypeInput } from './postgres-enum-type';\n\nexport const postgresAuthoringTypes = {} as const satisfies AuthoringTypeNamespace;\n\n/**\n * Entity type contributions surface as top-level helpers on the\n * composed-helpers shape (e.g. `helpers.enum({...})`), flattened\n * alongside the built-in `model` / `rel` helpers. Pack contributions\n * still ship via the contribution data structure\n * `authoring.entityTypes.<name>`; the composed-helpers template\n * performs the rename in the type system.\n *\n * `enum` is the first real consumer of the entities-namespace mechanism:\n * the factory constructs a `PostgresEnumType` IR-class instance from\n * the user-supplied input. Both authoring runtimes (TS DSL and PSL)\n * dispatch through this single contribution — PSL `enum Status { … }`\n * declarations are lowered by the interpreter into a factory call\n * with the parsed name + value list; TS DSL `helpers.enum({...})`\n * resolves through the same path. Removing this contribution makes\n * both surfaces fail with a \"no entity helper named `enum`\" type\n * error at the contract-definition site.\n */\n/**\n * The factory constructs a `PostgresEnumType` instance natively — the\n * `SqlStorage.types` slot accepts polymorphic IR (the framework\n * `StorageType` alphabet), so no cast is needed at the contribution\n * surface. The declared return type is the structural\n * `PostgresEnumStorageEntry` so the inferred contract type stays\n * portable (it names a type exported from\n * `@prisma-next/sql-contract/types`, a public surface every consumer\n * already imports). Sharpening the inferred contract type to surface\n * enum-specific narrowing through `EntityHelperFunction` is a\n * separable refinement and lives outside this PR.\n */\nexport const postgresAuthoringEntityTypes = {\n enum: {\n kind: 'entity',\n discriminator: 'postgres-enum',\n output: {\n factory: (input: PostgresEnumTypeInput): PostgresEnumStorageEntry =>\n new PostgresEnumType(input),\n },\n },\n} as const satisfies AuthoringEntityTypeNamespace;\n\n/**\n * Field presets contributed by the Postgres target pack.\n *\n * These mirror the PSL scalar-to-codec mapping used by the Postgres adapter\n * (see `createPostgresPslScalarTypeDescriptors`), so that authoring a field\n * via the TS callback surface (e.g. `field.int()`) and via the PSL scalar\n * surface (e.g. `Int`) lowers to byte-identical contracts.\n */\nexport const postgresAuthoringFieldPresets = {\n text: {\n kind: 'fieldPreset',\n output: {\n codecId: 'pg/text@1',\n nativeType: 'text',\n },\n },\n int: {\n kind: 'fieldPreset',\n output: {\n codecId: 'pg/int4@1',\n nativeType: 'int4',\n },\n },\n bigint: {\n kind: 'fieldPreset',\n output: {\n codecId: 'pg/int8@1',\n nativeType: 'int8',\n },\n },\n float: {\n kind: 'fieldPreset',\n output: {\n codecId: 'pg/float8@1',\n nativeType: 'float8',\n },\n },\n decimal: {\n kind: 'fieldPreset',\n output: {\n codecId: 'pg/numeric@1',\n nativeType: 'numeric',\n },\n },\n boolean: {\n kind: 'fieldPreset',\n output: {\n codecId: 'pg/bool@1',\n nativeType: 'bool',\n },\n },\n json: {\n kind: 'fieldPreset',\n output: {\n codecId: 'pg/jsonb@1',\n nativeType: 'jsonb',\n },\n },\n bytes: {\n kind: 'fieldPreset',\n output: {\n codecId: 'pg/bytea@1',\n nativeType: 'bytea',\n },\n },\n dateTime: {\n kind: 'fieldPreset',\n output: {\n codecId: 'pg/timestamptz@1',\n nativeType: 'timestamptz',\n },\n },\n temporal: temporalAuthoringPresets({\n codecId: 'pg/timestamptz@1',\n nativeType: 'timestamptz',\n }),\n} as const satisfies AuthoringFieldNamespace;\n","import type { CodecTypes } from '../exports/codec-types';\nimport {\n postgresAuthoringEntityTypes,\n postgresAuthoringFieldPresets,\n postgresAuthoringTypes,\n} from './authoring';\n\nconst postgresTargetDescriptorMetaBase = {\n kind: 'target',\n familyId: 'sql',\n targetId: 'postgres',\n id: 'postgres',\n version: '0.0.1',\n capabilities: {},\n authoring: {\n type: postgresAuthoringTypes,\n field: postgresAuthoringFieldPresets,\n entityTypes: postgresAuthoringEntityTypes,\n },\n} as const;\n\nexport const postgresTargetDescriptorMeta: typeof postgresTargetDescriptorMetaBase & {\n readonly __codecTypes?: CodecTypes;\n} = postgresTargetDescriptorMetaBase;\n"],"mappings":";;ACqBA,MAAa,+BAET;CAfF,MAAM;CACN,UAAU;CACV,UAAU;CACV,IAAI;CACJ,SAAS;CACT,cAAc,EAAE;CAChB,WAAW;EACT,MAAM,EAAA;EACN,OAAO;GD6CT,MAAM;IACJ,MAAM;IACN,QAAQ;KACN,SAAS;KACT,YAAY;KACb;IACF;GACD,KAAK;IACH,MAAM;IACN,QAAQ;KACN,SAAS;KACT,YAAY;KACb;IACF;GACD,QAAQ;IACN,MAAM;IACN,QAAQ;KACN,SAAS;KACT,YAAY;KACb;IACF;GACD,OAAO;IACL,MAAM;IACN,QAAQ;KACN,SAAS;KACT,YAAY;KACb;IACF;GACD,SAAS;IACP,MAAM;IACN,QAAQ;KACN,SAAS;KACT,YAAY;KACb;IACF;GACD,SAAS;IACP,MAAM;IACN,QAAQ;KACN,SAAS;KACT,YAAY;KACb;IACF;GACD,MAAM;IACJ,MAAM;IACN,QAAQ;KACN,SAAS;KACT,YAAY;KACb;IACF;GACD,OAAO;IACL,MAAM;IACN,QAAQ;KACN,SAAS;KACT,YAAY;KACb;IACF;GACD,UAAU;IACR,MAAM;IACN,QAAQ;KACN,SAAS;KACT,YAAY;KACb;IACF;GACD,UAAU,yBAAyB;IACjC,SAAS;IACT,YAAY;IACb,CAAC;GC/GO;EACP,aAAa,EDyBf,MAAM;GACJ,MAAM;GACN,eAAe;GACf,QAAQ,EACN,UAAU,UACR,IAAI,iBAAiB,MAAM,EAC9B;GACF,EChCc;EACd;CAKC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"postgres-contract-serializer-CcZO9ukP.mjs","names":[],"sources":["../src/core/postgres-contract-serializer.ts"],"sourcesContent":["import type { Contract } from '@prisma-next/contract/types';\nimport { SqlContractSerializerBase } from '@prisma-next/family-sql/ir';\nimport {\n type Namespace,\n NamespaceBase,\n UNBOUND_NAMESPACE_ID,\n} from '@prisma-next/framework-components/ir';\nimport {\n type SqlNamespaceTablesInput,\n type SqlStorage,\n StorageTable,\n type StorageTableInput,\n} from '@prisma-next/sql-contract/types';\nimport type { JsonObject } from '@prisma-next/utils/json';\nimport { PostgresEnumType, type PostgresEnumTypeInput } from './postgres-enum-type';\nimport { isPostgresSchema, PostgresSchema } from './postgres-schema';\n\nexport class PostgresContractSerializer extends SqlContractSerializerBase<Contract<SqlStorage>> {\n constructor() {\n // Postgres entity types (enums) are namespace-level and hydrated in\n // hydrateSqlNamespaceEntry; there are no storage-level codec alias entities\n // specific to Postgres, so the registry is empty.\n super(new Map());\n }\n\n protected override hydrateSqlNamespaceEntry(\n nsId: string,\n raw: Namespace | Record<string, unknown>,\n ): Namespace | SqlNamespaceTablesInput {\n if (raw instanceof NamespaceBase) {\n return raw;\n }\n const obj = raw as {\n id?: string;\n tables?: Record<string, unknown>;\n types?: Record<string, unknown>;\n };\n const id = obj.id ?? nsId;\n const tables = Object.fromEntries(\n Object.entries(obj.tables ?? {}).map(([tableName, table]) => [\n tableName,\n table instanceof StorageTable ? table : new StorageTable(table as StorageTableInput),\n ]),\n );\n const typeEntries = obj.types;\n const hydratedNsTypes =\n typeEntries !== undefined && Object.keys(typeEntries).length > 0\n ? Object.fromEntries(\n Object.entries(typeEntries).map(([typeName, entry]) => {\n if (entry instanceof PostgresEnumType) {\n return [typeName, entry];\n }\n const plain = entry as Record<string, unknown>;\n const name = typeof plain['name'] === 'string' ? plain['name'] : typeName;\n const nativeType =\n typeof plain['nativeType'] === 'string' ? plain['nativeType'] : name;\n const values = Array.isArray(plain['values']) ? (plain['values'] as string[]) : [];\n return [\n typeName,\n new PostgresEnumType({ name, nativeType, values } as PostgresEnumTypeInput),\n ];\n }),\n )\n : undefined;\n\n const emptyTables = Object.keys(tables).length === 0;\n const emptyTypes = !hydratedNsTypes || Object.keys(hydratedNsTypes).length === 0;\n if (id === UNBOUND_NAMESPACE_ID && emptyTables && emptyTypes) {\n return PostgresSchema.unbound;\n }\n return new PostgresSchema({\n id,\n tables,\n ...(hydratedNsTypes !== undefined ? { types: hydratedNsTypes } : {}),\n });\n }\n\n override serializeContract(contract: Contract<SqlStorage>): JsonObject {\n const { storage, ...rest } = contract;\n const namespacesJson: Record<string, JsonObject> = {};\n for (const [nsId, ns] of Object.entries(storage.namespaces)) {\n if (isPostgresSchema(ns)) {\n namespacesJson[nsId] = this.serializePostgresNamespace(ns, ns.id === UNBOUND_NAMESPACE_ID);\n } else {\n // Family-level SqlNamespacePayload / SqlUnboundNamespace haven't\n // been promoted to a PostgresSchema instance yet (e.g. they came\n // straight from the TS builder, which uses the family-shared\n // SqlStorage constructor). Serialise them as postgres-schema /\n // postgres-unbound-schema so the round-trip through\n // deserializeContract hydrates them back into PostgresSchema\n // instances.\n const isUnboundSlot = nsId === UNBOUND_NAMESPACE_ID;\n const nsTypes = (ns as { readonly types?: Readonly<Record<string, unknown>> }).types ?? {};\n namespacesJson[nsId] = {\n id: nsId,\n kind: isUnboundSlot ? 'postgres-unbound-schema' : 'postgres-schema',\n tables: Object.fromEntries(\n Object.entries(ns.tables).map(([tableName, table]) => [\n tableName,\n this.serializeJsonValue(table) as JsonObject,\n ]),\n ),\n types: Object.fromEntries(\n Object.entries(nsTypes).map(([typeName, entry]) => [\n typeName,\n this.serializeJsonValue(entry) as JsonObject,\n ]),\n ),\n };\n }\n }\n const storageOut: Record<string, unknown> = {\n storageHash: String(storage.storageHash),\n namespaces: namespacesJson,\n };\n if (storage.types !== undefined) {\n const typesOut: Record<string, JsonObject> = {};\n for (const [name, entry] of Object.entries(storage.types)) {\n typesOut[name] = this.serializeJsonValue(entry) as JsonObject;\n }\n storageOut['types'] = typesOut;\n }\n return {\n ...rest,\n storage: storageOut,\n } as unknown as JsonObject;\n }\n\n private serializePostgresNamespace(ns: PostgresSchema, isUnboundSlot: boolean): JsonObject {\n const tablesOut: Record<string, JsonObject> = {};\n for (const [tableName, table] of Object.entries(ns.tables)) {\n tablesOut[tableName] = this.serializeJsonValue(table) as JsonObject;\n }\n const typesOut: Record<string, JsonObject> = {};\n for (const [typeName, ty] of Object.entries(ns.types)) {\n typesOut[typeName] = this.serializeJsonValue(ty) as JsonObject;\n }\n return {\n id: ns.id,\n kind: isUnboundSlot ? 'postgres-unbound-schema' : 'postgres-schema',\n tables: tablesOut,\n types: typesOut,\n };\n }\n\n private serializeJsonValue(value: unknown): unknown {\n return JSON.parse(JSON.stringify(value)) as unknown;\n }\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"postgres-schema-BosNxhWq.mjs","names":[],"sources":["../src/core/postgres-schema.ts"],"sourcesContent":["import {\n freezeNode,\n NamespaceBase,\n UNBOUND_NAMESPACE_ID,\n} from '@prisma-next/framework-components/ir';\nimport {\n type SqlNamespaceTablesInput,\n type SqlStorage,\n StorageTable,\n type StorageTableInput,\n} from '@prisma-next/sql-contract/types';\nimport { PostgresEnumType, type PostgresEnumTypeInput } from './postgres-enum-type';\nimport { escapeLiteral } from './sql-utils';\n\nexport interface PostgresSchemaInput {\n readonly id: string;\n readonly tables?: Record<string, StorageTable | StorageTableInput>;\n readonly types?: Record<string, PostgresEnumType | PostgresEnumTypeInput>;\n}\n\n/**\n * Postgres target `Namespace` concretion — a Postgres schema (`CREATE\n * SCHEMA …`). Each Postgres `SqlStorage` carries a\n * `namespaces: Record<NamespaceId, PostgresSchema>` map populated by\n * the Postgres PSL interpreter from `namespace { … }` AST buckets.\n *\n * Qualifier emission is the rendering seam: DDL / SQL emission asks the\n * namespace for its qualifier (`\"<schema>\"`) or for a qualified table\n * name (`\"<schema>\".\"<table>\"`) and consumes the result polymorphically.\n * The unbound singleton below overrides these methods to elide the\n * prefix entirely — call sites stay polymorphic and never branch on\n * `id === UNBOUND_NAMESPACE_ID`.\n */\nexport class PostgresSchema extends NamespaceBase {\n /**\n * Stable singleton reference for the late-bound slot. Materialised\n * lazily below the singleton subclass declaration so the static\n * initialiser sees the subclass before assigning. Consumers always\n * reach for `PostgresSchema.unbound` (or `PostgresUnboundSchema.instance`\n * — same identity).\n */\n static unbound: PostgresUnboundSchema;\n\n readonly kind = 'schema' as const;\n readonly id: string;\n readonly tables: Readonly<Record<string, StorageTable>>;\n readonly types: Readonly<Record<string, PostgresEnumType>>;\n\n constructor(input: PostgresSchemaInput) {\n super();\n this.id = input.id;\n this.tables = Object.freeze(\n Object.fromEntries(\n Object.entries(input.tables ?? {}).map(([name, t]) => [\n name,\n t instanceof StorageTable ? t : new StorageTable(t),\n ]),\n ),\n );\n this.types = Object.freeze(\n Object.fromEntries(\n Object.entries(input.types ?? {}).map(([name, ty]) => [\n name,\n ty instanceof PostgresEnumType ? ty : new PostgresEnumType(ty),\n ]),\n ),\n );\n freezeNode(this);\n }\n\n /**\n * The bare schema qualifier as it would appear in a rendered SQL\n * fragment (already quoted). The unbound-schema singleton overrides\n * this to return `''`.\n */\n qualifier(): string {\n return `\"${this.id}\"`;\n }\n\n /**\n * Qualify a table name with the schema prefix\n * (`\"<schema>\".\"<table>\"`). The unbound-schema singleton overrides\n * this to emit just `\"<table>\"` so the resolved DDL is unqualified\n * and `search_path` decides where the object lands at runtime.\n */\n qualifyTable(tableName: string): string {\n return `\"${this.id}\".\"${tableName}\"`;\n }\n\n /**\n * Render a SQL string-literal containing the qualified-name form\n * suitable for `to_regclass(...)` arguments (e.g. `'\"public\".\"user\"'`).\n * The unbound singleton overrides this to elide the schema prefix\n * (`'\"user\"'`) so `search_path` resolves the object at runtime.\n */\n regclassLiteral(name: string): string {\n return `'${escapeLiteral(this.qualifyTable(name))}'`;\n }\n\n /**\n * Render a SQL expression that evaluates to this namespace's schema\n * name at runtime, ready to drop into a `WHERE table_schema = …` /\n * `WHERE n.nspname = …` clause. Named schemas emit a quoted SQL\n * literal (`'public'`); the unbound singleton overrides this to emit\n * `current_schema()` so catalog queries match whichever schema the\n * connection's `search_path` resolved at runtime.\n */\n schemaSqlExpression(): string {\n return `'${escapeLiteral(this.id)}'`;\n }\n\n /**\n * The bare schema name a DDL planner should target when emitting\n * statements that need to identify this namespace in the live\n * database (e.g. `CREATE TABLE \"<ddlSchemaName>\".\"<table>\" …`,\n * catalog filters, planner conflict lookups). Named schemas resolve\n * to their own id; the unbound singleton overrides this to project\n * to `'public'` when a sibling public namespace exists in the same\n * contract — and falls back to the framework sentinel otherwise so\n * the planner can detect the missing-projection case explicitly.\n */\n ddlSchemaName(_storage: SqlStorage): string {\n return this.id;\n }\n}\n\n/**\n * Singleton subclass for the reserved sentinel namespace id\n * (`UNBOUND_NAMESPACE_ID`) — the late-bound Postgres slot whose binding\n * the connection's `search_path` resolves at runtime. Overrides\n * qualifier emission to elide the schema prefix; call sites that consume\n * `qualifier()` / `qualifyTable()` get unqualified output without\n * branching on the namespace id.\n *\n * This is the target-side materialization of \"the framework provides\n * affordances; targets implement specifics\": the framework names the\n * sentinel; Postgres decides what late-bound means here (the table\n * name, naked — the schema is supplied by the live connection's\n * `search_path`).\n */\nexport class PostgresUnboundSchema extends PostgresSchema {\n static readonly instance: PostgresUnboundSchema = new PostgresUnboundSchema();\n\n constructor(input?: PostgresSchemaInput) {\n super(input ?? { id: UNBOUND_NAMESPACE_ID });\n }\n\n override qualifier(): string {\n return '';\n }\n\n override qualifyTable(tableName: string): string {\n return `\"${tableName}\"`;\n }\n\n override schemaSqlExpression(): string {\n return 'current_schema()';\n }\n\n /**\n * The unbound slot has no schema name of its own, so DDL emission\n * projects it onto a sibling when one is available: if the contract\n * carries a `public` namespace, the late-bound slot resolves to\n * `'public'` (the default Postgres landing schema); otherwise it\n * resolves to the framework sentinel `UNBOUND_NAMESPACE_ID` so the\n * planner can recognise the unprojected case and route accordingly\n * (e.g. emit a conflict instead of silently picking a schema).\n */\n override ddlSchemaName(storage: SqlStorage): string {\n if (storage.namespaces['public'] !== undefined) {\n return 'public';\n }\n return UNBOUND_NAMESPACE_ID;\n }\n}\n\nPostgresSchema.unbound = PostgresUnboundSchema.instance;\n\n/**\n * Narrow an arbitrary namespace (or `undefined`) to `PostgresSchema`\n * so callers can dispatch to the polymorphic emission methods without\n * branching at the call site. Uses the structural `kind` discriminator\n * (`'schema'`) rather than `instanceof` so the check survives realm /\n * bundle / hot-reload boundaries — matching the rest of the IR's\n * narrowing convention. `PostgresUnboundSchema` passes through because\n * it inherits the same `kind: 'schema'` from `PostgresSchema`.\n */\nexport function isPostgresSchema(ns: unknown): ns is PostgresSchema {\n return (ns as { kind?: unknown } | null | undefined)?.kind === 'schema';\n}\n\n/**\n * Target-supplied `Namespace` factory the Postgres target plumbs\n * through `defineContract({ createNamespace })` and the SQL PSL\n * interpreter. Returns the unbound singleton for the framework\n * sentinel and a fresh `PostgresSchema` for any other coordinate.\n *\n * The factory has no per-call state — every named id deterministically\n * maps to a distinct schema instance — so callers can pass it through\n * by reference and trust the resulting `SqlStorage.namespaces` map to\n * be value-stable for a given input set.\n */\nexport function postgresCreateNamespace(input: SqlNamespaceTablesInput): PostgresSchema {\n if (input.id === UNBOUND_NAMESPACE_ID) {\n return new PostgresUnboundSchema(input);\n }\n return new PostgresSchema(input);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAiCA,IAAa,iBAAb,cAAoC,cAAc;;;;;;;;CAQhD,OAAO;CAEP,OAAgB;CAChB;CACA;CACA;CAEA,YAAY,OAA4B;EACtC,OAAO;EACP,KAAK,KAAK,MAAM;EAChB,KAAK,SAAS,OAAO,OACnB,OAAO,YACL,OAAO,QAAQ,MAAM,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,OAAO,CACpD,MACA,aAAa,eAAe,IAAI,IAAI,aAAa,EAAE,CACpD,CAAC,CACH,CACF;EACD,KAAK,QAAQ,OAAO,OAClB,OAAO,YACL,OAAO,QAAQ,MAAM,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,QAAQ,CACpD,MACA,cAAc,mBAAmB,KAAK,IAAI,iBAAiB,GAAG,CAC/D,CAAC,CACH,CACF;EACD,WAAW,KAAK;;;;;;;CAQlB,YAAoB;EAClB,OAAO,IAAI,KAAK,GAAG;;;;;;;;CASrB,aAAa,WAA2B;EACtC,OAAO,IAAI,KAAK,GAAG,KAAK,UAAU;;;;;;;;CASpC,gBAAgB,MAAsB;EACpC,OAAO,IAAI,cAAc,KAAK,aAAa,KAAK,CAAC,CAAC;;;;;;;;;;CAWpD,sBAA8B;EAC5B,OAAO,IAAI,cAAc,KAAK,GAAG,CAAC;;;;;;;;;;;;CAapC,cAAc,UAA8B;EAC1C,OAAO,KAAK;;;;;;;;;;;;;;;;;AAkBhB,IAAa,wBAAb,MAAa,8BAA8B,eAAe;CACxD,OAAgB,WAAkC,IAAI,uBAAuB;CAE7E,YAAY,OAA6B;EACvC,MAAM,SAAS,EAAE,IAAI,sBAAsB,CAAC;;CAG9C,YAA6B;EAC3B,OAAO;;CAGT,aAAsB,WAA2B;EAC/C,OAAO,IAAI,UAAU;;CAGvB,sBAAuC;EACrC,OAAO;;;;;;;;;;;CAYT,cAAuB,SAA6B;EAClD,IAAI,QAAQ,WAAW,cAAc,KAAA,GACnC,OAAO;EAET,OAAO;;;AAIX,eAAe,UAAU,sBAAsB;;;;;;;;;;AAW/C,SAAgB,iBAAiB,IAAmC;CAClE,OAAQ,IAA8C,SAAS;;;;;;;;;;;;;AAcjE,SAAgB,wBAAwB,OAAgD;CACtF,IAAI,MAAM,OAAO,sBACf,OAAO,IAAI,sBAAsB,MAAM;CAEzC,OAAO,IAAI,eAAe,MAAM"}