@prisma-next/target-postgres 0.14.0-dev.52 → 0.14.0-dev.54
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.
- package/dist/{authoring-ohGMgi8g.mjs → authoring-Bd9Tt3E3.mjs} +26 -3
- package/dist/authoring-Bd9Tt3E3.mjs.map +1 -0
- package/dist/control.mjs +174 -31
- package/dist/control.mjs.map +1 -1
- package/dist/{descriptor-meta-Cok-1QEK.mjs → descriptor-meta-_pn08mka.mjs} +2 -2
- package/dist/{descriptor-meta-Cok-1QEK.mjs.map → descriptor-meta-_pn08mka.mjs.map} +1 -1
- package/dist/{diff-database-schema-BivMht-X.mjs → diff-database-schema-CUSoT1Dk.mjs} +4 -3
- package/dist/diff-database-schema-CUSoT1Dk.mjs.map +1 -0
- package/dist/diff-database-schema.d.mts +1 -1
- package/dist/diff-database-schema.d.mts.map +1 -1
- package/dist/diff-database-schema.mjs +1 -1
- package/dist/migration.mjs +1 -1
- package/dist/pack.mjs +1 -1
- package/dist/{planner-r4iLpxD7.mjs → planner-ChE2d2-k.mjs} +4 -4
- package/dist/{planner-r4iLpxD7.mjs.map → planner-ChE2d2-k.mjs.map} +1 -1
- package/dist/{planner-produced-postgres-migration-kVlK1Dts.mjs → planner-produced-postgres-migration-qTr4KVlt.mjs} +2 -2
- package/dist/{planner-produced-postgres-migration-kVlK1Dts.mjs.map → planner-produced-postgres-migration-qTr4KVlt.mjs.map} +1 -1
- package/dist/planner-produced-postgres-migration.mjs +1 -1
- package/dist/planner.d.mts +1 -1
- package/dist/planner.mjs +2 -2
- package/dist/{postgres-contract-view-C5RSIHFm.mjs → postgres-contract-view-BUjK3NeM.mjs} +2 -2
- package/dist/{postgres-contract-view-C5RSIHFm.mjs.map → postgres-contract-view-BUjK3NeM.mjs.map} +1 -1
- package/dist/{postgres-database-schema-node-C9bTuMrd.d.mts → postgres-database-schema-node-UpzA0Ug5.d.mts} +15 -2
- package/dist/{postgres-database-schema-node-C9bTuMrd.d.mts.map → postgres-database-schema-node-UpzA0Ug5.d.mts.map} +1 -1
- package/dist/{postgres-migration-CiA7wpQD.mjs → postgres-migration-DqGd8mAu.mjs} +2 -2
- package/dist/{postgres-migration-CiA7wpQD.mjs.map → postgres-migration-DqGd8mAu.mjs.map} +1 -1
- package/dist/{postgres-table-schema-node-BgaSrxYN.mjs → postgres-table-schema-node-BZWWEo7B.mjs} +12 -1
- package/dist/postgres-table-schema-node-BZWWEo7B.mjs.map +1 -0
- package/dist/runtime.mjs +1 -1
- package/dist/types.d.mts +2 -2
- package/dist/types.mjs +1 -1
- package/package.json +20 -20
- package/src/core/authoring.ts +29 -3
- package/src/core/migrations/diff-database-schema.ts +1 -0
- package/src/core/psl-infer/infer-psl-contract.ts +288 -31
- package/src/core/psl-infer/postgres-type-map.ts +0 -29
- package/src/core/schema-ir/postgres-namespace-schema-node.ts +19 -0
- package/src/exports/types.ts +1 -0
- package/dist/authoring-ohGMgi8g.mjs.map +0 -1
- package/dist/diff-database-schema-BivMht-X.mjs.map +0 -1
- package/dist/postgres-table-schema-node-BgaSrxYN.mjs.map +0 -1
|
@@ -33,9 +33,32 @@ function readListRefParams(block, key) {
|
|
|
33
33
|
if (param?.kind !== "list") return [];
|
|
34
34
|
return param.items.flatMap((item) => item.kind === "ref" ? [item.identifier] : []);
|
|
35
35
|
}
|
|
36
|
+
/**
|
|
37
|
+
* Unwraps a quoted PSL string argument, inverting the printer's
|
|
38
|
+
* `escapePslString` escapes (`\\`, `\"`, `\n`, `\r`). An unknown escape
|
|
39
|
+
* sequence is kept verbatim, matching the printer-side `unescapePslString`
|
|
40
|
+
* convention.
|
|
41
|
+
*/
|
|
36
42
|
function unwrapQuotedString(raw) {
|
|
37
|
-
if (raw.startsWith("\"") && raw.endsWith("\"") && raw.length >= 2) return raw
|
|
38
|
-
|
|
43
|
+
if (!(raw.startsWith("\"") && raw.endsWith("\"") && raw.length >= 2)) return raw;
|
|
44
|
+
const inner = raw.slice(1, -1);
|
|
45
|
+
let result = "";
|
|
46
|
+
for (let i = 0; i < inner.length; i++) {
|
|
47
|
+
if (inner[i] !== "\\" || i + 1 >= inner.length) {
|
|
48
|
+
result += inner[i];
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
const next = inner[i + 1];
|
|
52
|
+
if (next === "\\" || next === "\"") result += next;
|
|
53
|
+
else if (next === "n") result += "\n";
|
|
54
|
+
else if (next === "r") result += "\r";
|
|
55
|
+
else {
|
|
56
|
+
result += "\\";
|
|
57
|
+
result += next;
|
|
58
|
+
}
|
|
59
|
+
i++;
|
|
60
|
+
}
|
|
61
|
+
return result;
|
|
39
62
|
}
|
|
40
63
|
function lowerRlsPolicyFromBlock(block, _ctx) {
|
|
41
64
|
const prefix = block.name;
|
|
@@ -361,4 +384,4 @@ const postgresAuthoringFieldPresets = {
|
|
|
361
384
|
//#endregion
|
|
362
385
|
export { postgresAuthoringTypes as i, postgresAuthoringFieldPresets as n, postgresAuthoringPslBlockDescriptors as r, postgresAuthoringEntityTypes as t };
|
|
363
386
|
|
|
364
|
-
//# sourceMappingURL=authoring-
|
|
387
|
+
//# sourceMappingURL=authoring-Bd9Tt3E3.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authoring-Bd9Tt3E3.mjs","names":[],"sources":["../src/core/authoring.ts"],"sourcesContent":["import { temporalAuthoringPresets } from '@prisma-next/family-sql/control';\nimport type {\n AuthoringEntityContext,\n AuthoringEntityTypeFactoryOutput,\n AuthoringEntityTypeNamespace,\n AuthoringFieldNamespace,\n AuthoringPslBlockDescriptorNamespace,\n AuthoringTypeNamespace,\n PslExtensionBlock,\n} from '@prisma-next/framework-components/authoring';\nimport type { SqlValueSetDerivingEntityTypeOutput } from '@prisma-next/sql-contract/value-set-derivation-hook';\nimport { PG_ENUM_CODEC_ID } from './codec-ids';\nimport { PostgresNativeEnum } from './postgres-native-enum';\nimport { PostgresRlsPolicy } from './postgres-rls-policy';\nimport { PostgresRole, type PostgresRoleInput } from './postgres-role';\nimport {\n PostgresNativeEnumSchema,\n PostgresRlsPolicySchema,\n PostgresRoleSchema,\n} from './postgres-validators';\nimport { computeContentHash, normalizePredicate } from './rls/canonicalize';\n\n/**\n * `pg.enum(<ref>)` registers as an ordinary type constructor whose sole\n * positional argument names a `native_enum` entity instead of carrying a\n * literal value. The interpreter resolves the ref to the `native_enum`\n * entity generically (driven by `entityRefArg`); the `pg/enum@1` codec\n * descriptor's `columnFromEntity` hook (see `codecs.ts`) converts that\n * entity into the column's `typeParams` and native type.\n */\nexport const postgresAuthoringTypes = {\n pg: {\n enum: {\n kind: 'typeConstructor',\n entityRefArg: { index: 0, entityKind: 'native_enum' },\n output: {\n codecId: PG_ENUM_CODEC_ID,\n },\n },\n },\n} as const satisfies AuthoringTypeNamespace;\n\nexport interface RlsPolicyExtensionBlock extends PslExtensionBlock {\n readonly namespaceId: string;\n}\n\nfunction readRefParam(block: PslExtensionBlock, key: string): string | undefined {\n const param = block.parameters[key];\n return param?.kind === 'ref' ? param.identifier : undefined;\n}\n\nfunction readValueParam(block: PslExtensionBlock, key: string): string | undefined {\n const param = block.parameters[key];\n return param?.kind === 'value' ? param.raw : undefined;\n}\n\nfunction readListRefParams(block: PslExtensionBlock, key: string): string[] {\n const param = block.parameters[key];\n if (param?.kind !== 'list') return [];\n return param.items.flatMap((item) => (item.kind === 'ref' ? [item.identifier] : []));\n}\n\n/**\n * Unwraps a quoted PSL string argument, inverting the printer's\n * `escapePslString` escapes (`\\\\`, `\\\"`, `\\n`, `\\r`). An unknown escape\n * sequence is kept verbatim, matching the printer-side `unescapePslString`\n * convention.\n */\nfunction unwrapQuotedString(raw: string): string {\n if (!(raw.startsWith('\"') && raw.endsWith('\"') && raw.length >= 2)) {\n return raw;\n }\n const inner = raw.slice(1, -1);\n let result = '';\n for (let i = 0; i < inner.length; i++) {\n if (inner[i] !== '\\\\' || i + 1 >= inner.length) {\n result += inner[i];\n continue;\n }\n const next = inner[i + 1];\n if (next === '\\\\' || next === '\"') {\n result += next;\n } else if (next === 'n') {\n result += '\\n';\n } else if (next === 'r') {\n result += '\\r';\n } else {\n result += '\\\\';\n result += next;\n }\n i++;\n }\n return result;\n}\n\nfunction lowerRlsPolicyFromBlock(\n block: RlsPolicyExtensionBlock,\n _ctx: AuthoringEntityContext,\n): PostgresRlsPolicy {\n const prefix = block.name;\n const targetModelName = readRefParam(block, 'target') ?? '';\n const tableName = targetModelName.charAt(0).toLowerCase() + targetModelName.slice(1);\n const roles = [...readListRefParams(block, 'roles')].sort();\n const using = unwrapQuotedString(readValueParam(block, 'using') ?? '');\n\n const wireHash = computeContentHash({\n using: normalizePredicate(using),\n roles,\n operation: 'select',\n permissive: true,\n });\n const wireName = `${prefix}_${wireHash}`;\n\n return new PostgresRlsPolicy({\n name: wireName,\n prefix,\n tableName,\n namespaceId: block.namespaceId,\n operation: 'select',\n roles,\n using,\n permissive: true,\n });\n}\n\n/**\n * Lowers a `native_enum { memberName = \"value\" … @@map(\"type_name\") }` block\n * into a {@link PostgresNativeEnum}. Members must be authored as explicit\n * `key = \"value\"` pairs — a bare (value-less) member is a diagnostic, not\n * accepted (authoring-design.md §2.1). The parsed `memberName` is only used\n * to duplicate-check and report diagnostics; the lowered entity carries just\n * the member values (a native enum is value-only — the member \"name\" isn't\n * a separate authoring concept from the value). `typeName` comes from\n * `@@map` or defaults to the block name verbatim.\n */\nfunction lowerNativeEnumFromBlock(\n block: PslExtensionBlock,\n ctx: AuthoringEntityContext,\n): PostgresNativeEnum | undefined {\n const sourceId = ctx.sourceId ?? 'unknown';\n const diagnostics = ctx.diagnostics;\n\n const mapAttr = block.blockAttributes.find((a) => a.name === 'map');\n let typeName = block.name;\n if (mapAttr) {\n const rawArg = mapAttr.args[0]?.value;\n const mapped = rawArg !== undefined ? unwrapQuotedString(rawArg) : undefined;\n if (mapped === undefined) {\n diagnostics?.push({\n code: 'PSL_NATIVE_ENUM_INVALID_MAP',\n message: `native_enum \"${block.name}\" @@map attribute must have a quoted type-name argument`,\n sourceId,\n span: mapAttr.span,\n });\n return undefined;\n }\n typeName = mapped;\n }\n\n let memberError = false;\n const seenValues = new Set<string>();\n const members: string[] = [];\n for (const [memberName, paramValue] of Object.entries(block.parameters)) {\n if (paramValue.kind === 'bare') {\n diagnostics?.push({\n code: 'PSL_NATIVE_ENUM_BARE_MEMBER',\n message: `native_enum \"${block.name}\" member \"${memberName}\" has no value; members must be authored as \"${memberName} = \\\\\"value\\\\\"\"`,\n sourceId,\n span: paramValue.span,\n });\n memberError = true;\n continue;\n }\n if (paramValue.kind !== 'value') continue;\n\n let jsonValue: unknown;\n try {\n jsonValue = JSON.parse(paramValue.raw);\n } catch {\n diagnostics?.push({\n code: 'PSL_EXTENSION_INVALID_VALUE',\n message: `native_enum \"${block.name}\" member \"${memberName}\" value \"${paramValue.raw}\" is not valid JSON`,\n sourceId,\n span: paramValue.span,\n });\n memberError = true;\n continue;\n }\n if (typeof jsonValue !== 'string') {\n diagnostics?.push({\n code: 'PSL_EXTENSION_INVALID_VALUE',\n message: `native_enum \"${block.name}\" member \"${memberName}\" value must be a string`,\n sourceId,\n span: paramValue.span,\n });\n memberError = true;\n continue;\n }\n if (seenValues.has(jsonValue)) {\n diagnostics?.push({\n code: 'PSL_NATIVE_ENUM_DUPLICATE_MEMBER_VALUE',\n message: `native_enum \"${block.name}\": duplicate member value \"${jsonValue}\"`,\n sourceId,\n span: paramValue.span,\n });\n memberError = true;\n continue;\n }\n seenValues.add(jsonValue);\n members.push(jsonValue);\n }\n\n if (memberError) return undefined;\n\n if (members.length === 0) {\n diagnostics?.push({\n code: 'PSL_NATIVE_ENUM_MISSING_MEMBERS',\n message: `native_enum \"${block.name}\" must have at least one member`,\n sourceId,\n span: block.span,\n });\n return undefined;\n }\n\n // `control` stays unset — the effective grade is resolved at read time via `effectiveControlPolicy`, like `StorageTable`/`StorageColumn`.\n return new PostgresNativeEnum({ typeName, members });\n}\n\n/**\n * `native_enum`'s entity-type factory output, checked separately from the assembled\n * `postgresAuthoringEntityTypes` map below: `deriveValueSet` is SQL-family surface\n * ({@link SqlValueSetDerivingEntityTypeOutput}), not part of the framework\n * `AuthoringEntityTypeFactoryOutput` shape, so folding it directly into the map's single\n * `satisfies AuthoringEntityTypeNamespace` check would trip an excess-property error. Checking it\n * here against the intersection of both shapes keeps it structurally valid against each without\n * widening the map's own check.\n */\nconst nativeEnumEntityTypeOutput = {\n factory: lowerNativeEnumFromBlock,\n deriveValueSet: (entity: PostgresNativeEnum) => ({\n kind: 'valueSet' as const,\n values: [...entity.members],\n }),\n} satisfies AuthoringEntityTypeFactoryOutput<PslExtensionBlock, PostgresNativeEnum | undefined> &\n SqlValueSetDerivingEntityTypeOutput;\n\nexport const postgresAuthoringEntityTypes = {\n role: {\n kind: 'entity',\n discriminator: 'role',\n validatorSchema: PostgresRoleSchema,\n output: {\n factory: (input: PostgresRoleInput): PostgresRole => new PostgresRole(input),\n },\n },\n policy: {\n kind: 'entity',\n discriminator: 'policy',\n validatorSchema: PostgresRlsPolicySchema,\n output: {\n factory: lowerRlsPolicyFromBlock,\n },\n },\n native_enum: {\n kind: 'entity',\n discriminator: 'native_enum',\n validatorSchema: PostgresNativeEnumSchema,\n output: nativeEnumEntityTypeOutput,\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 *\n * The `uuidNative` / `id.uuidv4Native` / `id.uuidv7Native` presets use the\n * native Postgres `uuid` type (codecId `pg/uuid@1`). For cross-target\n * portability use `uuidString` / `id.uuidv4String` / `id.uuidv7String` from\n * the family pack instead.\n */\n/**\n * PSL block descriptor for `policy_select`.\n *\n * The parser learns the block shape from this descriptor; lowering from\n * `PslExtensionBlock` to `PostgresRlsPolicy` is wired in the PSL\n * interpreter (a later dispatch). The `discriminator` matches\n * `PostgresRlsPolicy.kind` so the parsed block node carries the same\n * discriminant as the IR class it will lower to.\n *\n * The `roles` list uses `scope:'cross-space'` because same-namespace\n * role ref resolution requires PSL namespace entries keyed by `refKind`\n * (i.e. `'role'`), which in turn requires the role block discriminator to\n * equal `'role'`. Aligning discriminator with refKind is tracked for\n * slice 4 (cross-space roles). Until then cross-space passes validation\n * unconditionally and the authored role names flow through unchanged.\n */\nexport const postgresAuthoringPslBlockDescriptors = {\n policy_select: {\n kind: 'pslBlock',\n keyword: 'policy_select',\n discriminator: 'policy',\n name: { required: true },\n parameters: {\n target: { kind: 'ref', refKind: 'model', scope: 'same-namespace', required: true },\n roles: {\n kind: 'list',\n of: { kind: 'ref', refKind: 'role', scope: 'cross-space' },\n },\n using: { kind: 'value', codecId: 'pg/text@1', required: true },\n },\n },\n /**\n * PSL block descriptor for `native_enum`.\n *\n * Reuses the existing variadic-block mechanism (the same shape the SQL\n * family's `enum` block ships): the body is an open `memberName = \"value\"`\n * list. `variadicParameters: true` opens the block to arbitrary keys\n * beyond the declared (empty) `parameters` set — the lowering factory\n * (`lowerNativeEnumFromBlock`) turns the variadic entries into ordered\n * members and rejects a bare (value-less) member.\n */\n native_enum: {\n kind: 'pslBlock',\n keyword: 'native_enum',\n discriminator: 'native_enum',\n name: { required: true },\n parameters: {},\n variadicParameters: true,\n },\n} as const satisfies AuthoringPslBlockDescriptorNamespace;\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: /* @__PURE__ */ temporalAuthoringPresets({\n codecId: 'pg/timestamptz@1',\n nativeType: 'timestamptz',\n }),\n uuidNative: {\n kind: 'fieldPreset',\n output: {\n codecId: 'pg/uuid@1',\n nativeType: 'uuid',\n },\n },\n id: {\n uuidv4Native: {\n kind: 'fieldPreset',\n output: {\n codecId: 'pg/uuid@1',\n nativeType: 'uuid',\n executionDefaults: {\n onCreate: {\n kind: 'generator',\n id: 'uuidv4',\n },\n },\n id: true,\n },\n },\n uuidv7Native: {\n kind: 'fieldPreset',\n output: {\n codecId: 'pg/uuid@1',\n nativeType: 'uuid',\n executionDefaults: {\n onCreate: {\n kind: 'generator',\n id: 'uuidv7',\n },\n },\n id: true,\n },\n },\n },\n} as const satisfies AuthoringFieldNamespace;\n"],"mappings":";;;;;;;;;;;;;;AA8BA,MAAa,yBAAyB,EACpC,IAAI,EACF,MAAM;CACJ,MAAM;CACN,cAAc;EAAE,OAAO;EAAG,YAAY;CAAc;CACpD,QAAQ,EACN,SAAS,iBACX;AACF,EACF,EACF;AAMA,SAAS,aAAa,OAA0B,KAAiC;CAC/E,MAAM,QAAQ,MAAM,WAAW;CAC/B,OAAO,OAAO,SAAS,QAAQ,MAAM,aAAa,KAAA;AACpD;AAEA,SAAS,eAAe,OAA0B,KAAiC;CACjF,MAAM,QAAQ,MAAM,WAAW;CAC/B,OAAO,OAAO,SAAS,UAAU,MAAM,MAAM,KAAA;AAC/C;AAEA,SAAS,kBAAkB,OAA0B,KAAuB;CAC1E,MAAM,QAAQ,MAAM,WAAW;CAC/B,IAAI,OAAO,SAAS,QAAQ,OAAO,CAAC;CACpC,OAAO,MAAM,MAAM,SAAS,SAAU,KAAK,SAAS,QAAQ,CAAC,KAAK,UAAU,IAAI,CAAC,CAAE;AACrF;;;;;;;AAQA,SAAS,mBAAmB,KAAqB;CAC/C,IAAI,EAAE,IAAI,WAAW,IAAG,KAAK,IAAI,SAAS,IAAG,KAAK,IAAI,UAAU,IAC9D,OAAO;CAET,MAAM,QAAQ,IAAI,MAAM,GAAG,EAAE;CAC7B,IAAI,SAAS;CACb,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;EACrC,IAAI,MAAM,OAAO,QAAQ,IAAI,KAAK,MAAM,QAAQ;GAC9C,UAAU,MAAM;GAChB;EACF;EACA,MAAM,OAAO,MAAM,IAAI;EACvB,IAAI,SAAS,QAAQ,SAAS,MAC5B,UAAU;OACL,IAAI,SAAS,KAClB,UAAU;OACL,IAAI,SAAS,KAClB,UAAU;OACL;GACL,UAAU;GACV,UAAU;EACZ;EACA;CACF;CACA,OAAO;AACT;AAEA,SAAS,wBACP,OACA,MACmB;CACnB,MAAM,SAAS,MAAM;CACrB,MAAM,kBAAkB,aAAa,OAAO,QAAQ,KAAK;CACzD,MAAM,YAAY,gBAAgB,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,gBAAgB,MAAM,CAAC;CACnF,MAAM,QAAQ,CAAC,GAAG,kBAAkB,OAAO,OAAO,CAAC,CAAC,CAAC,KAAK;CAC1D,MAAM,QAAQ,mBAAmB,eAAe,OAAO,OAAO,KAAK,EAAE;CAUrE,OAAO,IAAI,kBAAkB;EAC3B,MAAM,GAHY,OAAO,GANV,mBAAmB;GAClC,OAAO,mBAAmB,KAAK;GAC/B;GACA,WAAW;GACX,YAAY;EACd,CACqC;EAInC;EACA;EACA,aAAa,MAAM;EACnB,WAAW;EACX;EACA;EACA,YAAY;CACd,CAAC;AACH;;;;;;;;;;;AAYA,SAAS,yBACP,OACA,KACgC;CAChC,MAAM,WAAW,IAAI,YAAY;CACjC,MAAM,cAAc,IAAI;CAExB,MAAM,UAAU,MAAM,gBAAgB,MAAM,MAAM,EAAE,SAAS,KAAK;CAClE,IAAI,WAAW,MAAM;CACrB,IAAI,SAAS;EACX,MAAM,SAAS,QAAQ,KAAK,EAAE,EAAE;EAChC,MAAM,SAAS,WAAW,KAAA,IAAY,mBAAmB,MAAM,IAAI,KAAA;EACnE,IAAI,WAAW,KAAA,GAAW;GACxB,aAAa,KAAK;IAChB,MAAM;IACN,SAAS,gBAAgB,MAAM,KAAK;IACpC;IACA,MAAM,QAAQ;GAChB,CAAC;GACD;EACF;EACA,WAAW;CACb;CAEA,IAAI,cAAc;CAClB,MAAM,6BAAa,IAAI,IAAY;CACnC,MAAM,UAAoB,CAAC;CAC3B,KAAK,MAAM,CAAC,YAAY,eAAe,OAAO,QAAQ,MAAM,UAAU,GAAG;EACvE,IAAI,WAAW,SAAS,QAAQ;GAC9B,aAAa,KAAK;IAChB,MAAM;IACN,SAAS,gBAAgB,MAAM,KAAK,YAAY,WAAW,+CAA+C,WAAW;IACrH;IACA,MAAM,WAAW;GACnB,CAAC;GACD,cAAc;GACd;EACF;EACA,IAAI,WAAW,SAAS,SAAS;EAEjC,IAAI;EACJ,IAAI;GACF,YAAY,KAAK,MAAM,WAAW,GAAG;EACvC,QAAQ;GACN,aAAa,KAAK;IAChB,MAAM;IACN,SAAS,gBAAgB,MAAM,KAAK,YAAY,WAAW,WAAW,WAAW,IAAI;IACrF;IACA,MAAM,WAAW;GACnB,CAAC;GACD,cAAc;GACd;EACF;EACA,IAAI,OAAO,cAAc,UAAU;GACjC,aAAa,KAAK;IAChB,MAAM;IACN,SAAS,gBAAgB,MAAM,KAAK,YAAY,WAAW;IAC3D;IACA,MAAM,WAAW;GACnB,CAAC;GACD,cAAc;GACd;EACF;EACA,IAAI,WAAW,IAAI,SAAS,GAAG;GAC7B,aAAa,KAAK;IAChB,MAAM;IACN,SAAS,gBAAgB,MAAM,KAAK,6BAA6B,UAAU;IAC3E;IACA,MAAM,WAAW;GACnB,CAAC;GACD,cAAc;GACd;EACF;EACA,WAAW,IAAI,SAAS;EACxB,QAAQ,KAAK,SAAS;CACxB;CAEA,IAAI,aAAa,OAAO,KAAA;CAExB,IAAI,QAAQ,WAAW,GAAG;EACxB,aAAa,KAAK;GAChB,MAAM;GACN,SAAS,gBAAgB,MAAM,KAAK;GACpC;GACA,MAAM,MAAM;EACd,CAAC;EACD;CACF;CAGA,OAAO,IAAI,mBAAmB;EAAE;EAAU;CAAQ,CAAC;AACrD;AAoBA,MAAa,+BAA+B;CAC1C,MAAM;EACJ,MAAM;EACN,eAAe;EACf,iBAAiB;EACjB,QAAQ,EACN,UAAU,UAA2C,IAAI,aAAa,KAAK,EAC7E;CACF;CACA,QAAQ;EACN,MAAM;EACN,eAAe;EACf,iBAAiB;EACjB,QAAQ,EACN,SAAS,wBACX;CACF;CACA,aAAa;EACX,MAAM;EACN,eAAe;EACf,iBAAiB;EACjB,QAAQ;GA7BV,SAAS;GACT,iBAAiB,YAAgC;IAC/C,MAAM;IACN,QAAQ,CAAC,GAAG,OAAO,OAAO;GAC5B;EAyBU;CACV;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+BA,MAAa,uCAAuC;CAClD,eAAe;EACb,MAAM;EACN,SAAS;EACT,eAAe;EACf,MAAM,EAAE,UAAU,KAAK;EACvB,YAAY;GACV,QAAQ;IAAE,MAAM;IAAO,SAAS;IAAS,OAAO;IAAkB,UAAU;GAAK;GACjF,OAAO;IACL,MAAM;IACN,IAAI;KAAE,MAAM;KAAO,SAAS;KAAQ,OAAO;IAAc;GAC3D;GACA,OAAO;IAAE,MAAM;IAAS,SAAS;IAAa,UAAU;GAAK;EAC/D;CACF;;;;;;;;;;;CAWA,aAAa;EACX,MAAM;EACN,SAAS;EACT,eAAe;EACf,MAAM,EAAE,UAAU,KAAK;EACvB,YAAY,CAAC;EACb,oBAAoB;CACtB;AACF;AAEA,MAAa,gCAAgC;CAC3C,MAAM;EACJ,MAAM;EACN,QAAQ;GACN,SAAS;GACT,YAAY;EACd;CACF;CACA,KAAK;EACH,MAAM;EACN,QAAQ;GACN,SAAS;GACT,YAAY;EACd;CACF;CACA,QAAQ;EACN,MAAM;EACN,QAAQ;GACN,SAAS;GACT,YAAY;EACd;CACF;CACA,OAAO;EACL,MAAM;EACN,QAAQ;GACN,SAAS;GACT,YAAY;EACd;CACF;CACA,SAAS;EACP,MAAM;EACN,QAAQ;GACN,SAAS;GACT,YAAY;EACd;CACF;CACA,SAAS;EACP,MAAM;EACN,QAAQ;GACN,SAAS;GACT,YAAY;EACd;CACF;CACA,MAAM;EACJ,MAAM;EACN,QAAQ;GACN,SAAS;GACT,YAAY;EACd;CACF;CACA,OAAO;EACL,MAAM;EACN,QAAQ;GACN,SAAS;GACT,YAAY;EACd;CACF;CACA,UAAU;EACR,MAAM;EACN,QAAQ;GACN,SAAS;GACT,YAAY;EACd;CACF;CACA,UAA0B,yCAAyB;EACjD,SAAS;EACT,YAAY;CACd,CAAC;CACD,YAAY;EACV,MAAM;EACN,QAAQ;GACN,SAAS;GACT,YAAY;EACd;CACF;CACA,IAAI;EACF,cAAc;GACZ,MAAM;GACN,QAAQ;IACN,SAAS;IACT,YAAY;IACZ,mBAAmB,EACjB,UAAU;KACR,MAAM;KACN,IAAI;IACN,EACF;IACA,IAAI;GACN;EACF;EACA,cAAc;GACZ,MAAM;GACN,QAAQ;IACN,SAAS;IACT,YAAY;IACZ,mBAAmB,EACjB,UAAU;KACR,MAAM;KACN,IAAI;IACN,EACF;IACA,IAAI;GACN;EACF;CACF;AACF"}
|
package/dist/control.mjs
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { t as
|
|
1
|
+
import { t as PostgresNativeEnum } from "./postgres-native-enum-xdiqmBf_.mjs";
|
|
2
|
+
import { t as postgresTargetDescriptorMeta } from "./descriptor-meta-_pn08mka.mjs";
|
|
2
3
|
import { n as postgresDiffSubjectEntityKind, r as postgresDiffSubjectGranularity } from "./schema-node-kinds-ClScchhi.mjs";
|
|
3
|
-
import { a as PostgresDatabaseSchemaNode } from "./postgres-table-schema-node-
|
|
4
|
-
import { n as diffPostgresSchema, r as contractToPostgresDatabaseSchemaNode } from "./diff-database-schema-
|
|
4
|
+
import { a as PostgresDatabaseSchemaNode } from "./postgres-table-schema-node-BZWWEo7B.mjs";
|
|
5
|
+
import { n as diffPostgresSchema, r as contractToPostgresDatabaseSchemaNode } from "./diff-database-schema-CUSoT1Dk.mjs";
|
|
5
6
|
import { r as renderDefaultLiteral } from "./planner-ddl-builders-B8Nn6nHN.mjs";
|
|
6
|
-
import { n as PostgresContractSerializer } from "./postgres-contract-view-
|
|
7
|
-
import { t as createPostgresMigrationPlanner } from "./planner-
|
|
8
|
-
import { UNBOUND_NAMESPACE_ID, coordinateKey, elementCoordinates } from "@prisma-next/framework-components/ir";
|
|
7
|
+
import { n as PostgresContractSerializer } from "./postgres-contract-view-BUjK3NeM.mjs";
|
|
8
|
+
import { t as createPostgresMigrationPlanner } from "./planner-ChE2d2-k.mjs";
|
|
9
|
+
import { UNBOUND_NAMESPACE_ID, coordinateKey, elementCoordinates, isPlainRecord } from "@prisma-next/framework-components/ir";
|
|
9
10
|
import { blindCast } from "@prisma-next/utils/casts";
|
|
10
11
|
import { buildNativeTypeExpander, runnerFailure, runnerSuccess } from "@prisma-next/family-sql/control";
|
|
11
12
|
import { ifDefined } from "@prisma-next/utils/defined";
|
|
@@ -14,7 +15,7 @@ import { APP_SPACE_ID } from "@prisma-next/framework-components/control";
|
|
|
14
15
|
import { notOk, ok, okVoid } from "@prisma-next/utils/result";
|
|
15
16
|
import { SqlSchemaVerifierBase } from "@prisma-next/family-sql/ir";
|
|
16
17
|
import { SqlQueryError } from "@prisma-next/sql-errors";
|
|
17
|
-
import { buildChildRelationField, deriveRelationFieldName, inferRelations, mapDefault, parseRawDefault, toFieldName, toModelName, toNamedTypeName } from "@prisma-next/family-sql/psl-infer";
|
|
18
|
+
import { buildChildRelationField, deriveRelationFieldName, inferRelations, mapDefault, parseRawDefault, toEnumMemberName, toEnumName, toFieldName, toModelName, toNamedTypeName } from "@prisma-next/family-sql/psl-infer";
|
|
18
19
|
import { UNSPECIFIED_PSL_NAMESPACE_ID, makePslNamespace, makePslNamespaceEntries } from "@prisma-next/framework-components/psl-ast";
|
|
19
20
|
//#region src/core/migrations/runner.ts
|
|
20
21
|
const LOCK_DOMAIN = "prisma_next.contract.marker";
|
|
@@ -752,42 +753,118 @@ function resolveForeignKeys(tables, owners) {
|
|
|
752
753
|
function inferPostgresPslContract(tree, describedContracts) {
|
|
753
754
|
const namespaces = Object.values(tree.namespaces);
|
|
754
755
|
const owners = describedContractOwners(describedContracts ?? []);
|
|
755
|
-
const
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
756
|
+
const enumOwners = describedNativeEnumOwnersByTypeName(describedContracts ?? []);
|
|
757
|
+
const enumDefinitions = /* @__PURE__ */ new Map();
|
|
758
|
+
const packOwnedEnumTypesByNamespace = /* @__PURE__ */ new Map();
|
|
759
|
+
const enumNamespaceNames = /* @__PURE__ */ new Set();
|
|
760
|
+
for (const namespace of namespaces) {
|
|
761
|
+
const definitionsForNamespace = new Set(namespace.nativeEnums.map((e) => e.typeName));
|
|
762
|
+
for (const typeName of namespace.nativeEnumTypeNames) if (!definitionsForNamespace.has(typeName)) throw new Error(`contract infer: introspection reported native enum type "${typeName}" in schema "${namespace.schemaName}" without member values — the introspected tree's \`nativeEnumTypeNames\` and \`nativeEnums\` are out of sync (internal invariant).`);
|
|
763
|
+
for (const { typeName, values } of namespace.nativeEnums) {
|
|
764
|
+
const owner = enumOwners.get(coordinateKey({
|
|
765
|
+
namespaceId: namespace.schemaName,
|
|
766
|
+
entityKind: "native_enum",
|
|
767
|
+
entityName: typeName
|
|
768
|
+
}));
|
|
769
|
+
if (owner !== void 0) {
|
|
770
|
+
const owned = packOwnedEnumTypesByNamespace.get(namespace.schemaName) ?? /* @__PURE__ */ new Map();
|
|
771
|
+
owned.set(typeName, owner.spaceId);
|
|
772
|
+
owned.set(`${namespace.schemaName}.${typeName}`, owner.spaceId);
|
|
773
|
+
packOwnedEnumTypesByNamespace.set(namespace.schemaName, owned);
|
|
774
|
+
continue;
|
|
775
|
+
}
|
|
776
|
+
enumDefinitions.set(typeName, values);
|
|
777
|
+
enumNamespaceNames.add(namespace.schemaName);
|
|
778
|
+
}
|
|
759
779
|
}
|
|
760
780
|
const tables = {};
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
781
|
+
const tableNamespaceNames = /* @__PURE__ */ new Set();
|
|
782
|
+
for (const namespace of namespaces) {
|
|
783
|
+
const ownedEnumTypes = packOwnedEnumTypesByNamespace.get(namespace.schemaName);
|
|
784
|
+
for (const [tableName, table] of Object.entries(namespace.tables)) {
|
|
785
|
+
if (owners.has(coordinateKey({
|
|
786
|
+
namespaceId: namespace.schemaName,
|
|
787
|
+
entityKind: "table",
|
|
788
|
+
entityName: tableName
|
|
789
|
+
}))) continue;
|
|
790
|
+
if (tables[tableName] !== void 0) throw new Error(`contract infer: duplicate table name "${tableName}" across schemas is not yet supported (single-namespace PSL inference emits one flat bucket; multi-namespace \`namespace { … }\` output is a later slice).`);
|
|
791
|
+
if (ownedEnumTypes !== void 0) for (const column of Object.values(table.columns)) {
|
|
792
|
+
const owningSpaceId = ownedEnumTypes.get(column.nativeType);
|
|
793
|
+
if (owningSpaceId !== void 0) throw new Error(`contract infer: column "${tableName}"."${column.name}" is typed by native enum type "${column.nativeType}", which extension pack space "${owningSpaceId}" already describes. A cross-space enum-typed column has no authorable PSL form yet; describe the table in that pack's contract or retype the column before re-running contract infer.`);
|
|
794
|
+
}
|
|
795
|
+
tables[tableName] = new SqlTableIR(table);
|
|
796
|
+
tableNamespaceNames.add(namespace.schemaName);
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
let wrapNamespaceName;
|
|
800
|
+
if (enumDefinitions.size > 0) {
|
|
801
|
+
const contentNamespaces = new Set([...enumNamespaceNames, ...tableNamespaceNames]);
|
|
802
|
+
if (contentNamespaces.size > 1) throw new Error(`contract infer: native enum adoption with content across multiple schemas is not yet supported (single-namespace PSL inference emits one \`namespace { … }\` block; multi-namespace output is a later slice). Schemas: ${[...contentNamespaces].sort().join(", ")}.`);
|
|
803
|
+
wrapNamespaceName = [...contentNamespaces][0];
|
|
769
804
|
}
|
|
770
805
|
const { tables: resolvedTables, extraRelationsByTable, crossSpaceFieldNamesByTable } = resolveForeignKeys(tables, owners);
|
|
771
|
-
|
|
772
|
-
|
|
806
|
+
const schemaIR = new SqlSchemaIR({ tables: resolvedTables });
|
|
807
|
+
const enumTypeNames = new Set(enumDefinitions.keys());
|
|
808
|
+
if (wrapNamespaceName !== void 0) for (const typeName of enumDefinitions.keys()) enumTypeNames.add(`${wrapNamespaceName}.${typeName}`);
|
|
809
|
+
const enumInfo = {
|
|
810
|
+
typeNames: enumTypeNames,
|
|
811
|
+
definitions: enumDefinitions
|
|
812
|
+
};
|
|
813
|
+
return buildPslDocumentAst(schemaIR, {
|
|
814
|
+
typeMap: createPostgresTypeMap(enumInfo.typeNames),
|
|
773
815
|
defaultMapping: createPostgresDefaultMapping(),
|
|
774
|
-
parseRawDefault
|
|
816
|
+
parseRawDefault,
|
|
817
|
+
...enumDefinitions.size > 0 ? { enumInfo } : {}
|
|
775
818
|
}, {
|
|
776
819
|
extraRelationsByTable,
|
|
777
820
|
crossSpaceFieldNamesByTable
|
|
778
|
-
});
|
|
821
|
+
}, wrapNamespaceName);
|
|
779
822
|
}
|
|
780
|
-
|
|
823
|
+
/**
|
|
824
|
+
* Native-enum ownership index for pack subtraction, keyed by TYPE NAME
|
|
825
|
+
* coordinate. A pack contract keys `entries.native_enum` by HANDLE name
|
|
826
|
+
* (`AalLevel`) while introspection sees the Postgres type name (`aal_level`);
|
|
827
|
+
* the entity's `typeName` field carries the mapping, so this walk indexes by
|
|
828
|
+
* it rather than reusing {@link describedContractOwners}' entries-key
|
|
829
|
+
* coordinates.
|
|
830
|
+
*
|
|
831
|
+
* Reads `entries.native_enum` directly: the kind map is carried
|
|
832
|
+
* non-enumerable on `PostgresSchema.entries`, so the generic
|
|
833
|
+
* `elementCoordinates` walk never yields it. Serialized pack contracts do
|
|
834
|
+
* not carry `native_enum` entries at all (`PostgresContractSerializer`
|
|
835
|
+
* strips them; only the derived `valueSet` survives), so this subtraction
|
|
836
|
+
* currently matches in-memory described contracts only.
|
|
837
|
+
*/
|
|
838
|
+
function describedNativeEnumOwnersByTypeName(describedContracts) {
|
|
839
|
+
const owners = /* @__PURE__ */ new Map();
|
|
840
|
+
for (const entry of describedContracts) for (const [namespaceId, ns] of Object.entries(entry.contract.storage.namespaces)) {
|
|
841
|
+
const kindMap = ns.entries["native_enum"];
|
|
842
|
+
if (!isPlainRecord(kindMap)) continue;
|
|
843
|
+
for (const entity of Object.values(kindMap)) {
|
|
844
|
+
if (!PostgresNativeEnum.is(entity)) continue;
|
|
845
|
+
owners.set(coordinateKey({
|
|
846
|
+
namespaceId,
|
|
847
|
+
entityKind: "native_enum",
|
|
848
|
+
entityName: entity.typeName
|
|
849
|
+
}), entry);
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
return owners;
|
|
853
|
+
}
|
|
854
|
+
function buildPslDocumentAst(schemaIR, options, foreignKeyExtras, namespaceName) {
|
|
781
855
|
const { typeMap, defaultMapping, parseRawDefault: rawDefaultParser } = options;
|
|
782
856
|
const { extraRelationsByTable, crossSpaceFieldNamesByTable } = foreignKeyExtras;
|
|
783
857
|
const modelNames = buildTopLevelNameMap(Object.keys(schemaIR.tables), toModelName, "model", "table");
|
|
784
858
|
const modelNameMap = new Map([...modelNames].map(([tableName, result]) => [tableName, result.name]));
|
|
785
|
-
const
|
|
859
|
+
const { enumNameMap: bareEnumNameMap, enumBlocks } = buildNativeEnumBlocks(options.enumInfo?.definitions ?? /* @__PURE__ */ new Map(), modelNames);
|
|
860
|
+
const enumNameMap = new Map(bareEnumNameMap);
|
|
861
|
+
if (namespaceName !== void 0) for (const [typeName, pslName] of bareEnumNameMap) enumNameMap.set(`${namespaceName}.${typeName}`, pslName);
|
|
862
|
+
const reservedNamedTypeNames = createReservedNamedTypeNames(modelNames, enumNameMap);
|
|
786
863
|
const fieldNamesByTable = new Map([...crossSpaceFieldNamesByTable, ...buildFieldNamesByTable(schemaIR.tables)]);
|
|
787
864
|
const { relationsByTable } = inferRelations(schemaIR.tables, modelNameMap);
|
|
788
|
-
const namedTypes = seedNamedTypeRegistry(schemaIR, typeMap,
|
|
865
|
+
const namedTypes = seedNamedTypeRegistry(schemaIR, typeMap, enumNameMap, reservedNamedTypeNames);
|
|
789
866
|
const models = [];
|
|
790
|
-
for (const table of Object.values(schemaIR.tables)) models.push(buildModel(table, typeMap,
|
|
867
|
+
for (const table of Object.values(schemaIR.tables)) models.push(buildModel(table, typeMap, enumNameMap, fieldNamesByTable, namedTypes, defaultMapping, rawDefaultParser, [...relationsByTable.get(table.name) ?? [], ...extraRelationsByTable.get(table.name) ?? []]));
|
|
791
868
|
const sortedModels = topologicalSort(models, schemaIR.tables, modelNameMap);
|
|
792
869
|
const namedTypeEntries = [...namedTypes.entriesByKey.values()].sort((a, b) => a.name.localeCompare(b.name));
|
|
793
870
|
const types = namedTypeEntries.length > 0 ? {
|
|
@@ -800,14 +877,69 @@ function buildPslDocumentAst(schemaIR, options, foreignKeyExtras) {
|
|
|
800
877
|
sourceId: "<sql-schema-ir>",
|
|
801
878
|
namespaces: [makePslNamespace({
|
|
802
879
|
kind: "namespace",
|
|
803
|
-
name: UNSPECIFIED_PSL_NAMESPACE_ID,
|
|
804
|
-
entries: makePslNamespaceEntries(sortedModels, [],
|
|
880
|
+
name: namespaceName ?? UNSPECIFIED_PSL_NAMESPACE_ID,
|
|
881
|
+
entries: makePslNamespaceEntries(sortedModels, [], enumBlocks),
|
|
805
882
|
span: SYNTHETIC_SPAN
|
|
806
883
|
})],
|
|
807
884
|
...types ? { types } : {},
|
|
808
885
|
span: SYNTHETIC_SPAN
|
|
809
886
|
};
|
|
810
887
|
}
|
|
888
|
+
/**
|
|
889
|
+
* Builds one `native_enum` extension-block AST node per introspected enum
|
|
890
|
+
* definition. Block names go through the shared top-level transform
|
|
891
|
+
* (`toEnumName`, intra-enum collisions throw like model collisions) and are
|
|
892
|
+
* then reserved against the model names — an enum whose PSL name a model
|
|
893
|
+
* already claims gets a numeric suffix, with `@@map` carrying the real type
|
|
894
|
+
* name. Members print as explicit `member = "value"` pairs: the member name
|
|
895
|
+
* is the sanitized value (deduplicated within the block), the JSON-encoded
|
|
896
|
+
* value carries the truth verbatim.
|
|
897
|
+
*/
|
|
898
|
+
function buildNativeEnumBlocks(definitions, modelNames) {
|
|
899
|
+
const enumNames = buildTopLevelNameMap([...definitions.keys()].sort(), toEnumName, "enum", "enum type");
|
|
900
|
+
const usedTopLevelNames = new Set(PSL_SCALAR_TYPE_NAMES);
|
|
901
|
+
for (const result of modelNames.values()) usedTopLevelNames.add(result.name);
|
|
902
|
+
const enumNameMap = /* @__PURE__ */ new Map();
|
|
903
|
+
const enumBlocks = [];
|
|
904
|
+
for (const [typeName, result] of enumNames) {
|
|
905
|
+
const name = createUniqueFieldName(result.name, usedTopLevelNames);
|
|
906
|
+
usedTopLevelNames.add(name);
|
|
907
|
+
enumNameMap.set(typeName, name);
|
|
908
|
+
enumBlocks.push(buildNativeEnumBlock(name, typeName, definitions.get(typeName) ?? []));
|
|
909
|
+
}
|
|
910
|
+
return {
|
|
911
|
+
enumNameMap,
|
|
912
|
+
enumBlocks
|
|
913
|
+
};
|
|
914
|
+
}
|
|
915
|
+
function buildNativeEnumBlock(name, typeName, values) {
|
|
916
|
+
const usedMemberNames = /* @__PURE__ */ new Set();
|
|
917
|
+
const parameters = {};
|
|
918
|
+
for (const value of values) {
|
|
919
|
+
const memberName = createUniqueFieldName(toEnumMemberName(value), usedMemberNames);
|
|
920
|
+
usedMemberNames.add(memberName);
|
|
921
|
+
parameters[memberName] = {
|
|
922
|
+
kind: "value",
|
|
923
|
+
raw: JSON.stringify(value),
|
|
924
|
+
span: SYNTHETIC_SPAN
|
|
925
|
+
};
|
|
926
|
+
}
|
|
927
|
+
return {
|
|
928
|
+
kind: "native_enum",
|
|
929
|
+
name,
|
|
930
|
+
parameters,
|
|
931
|
+
blockAttributes: name === typeName ? [] : [{
|
|
932
|
+
name: "map",
|
|
933
|
+
args: [{
|
|
934
|
+
kind: "positional",
|
|
935
|
+
value: `"${escapePslString(typeName)}"`,
|
|
936
|
+
span: SYNTHETIC_SPAN
|
|
937
|
+
}],
|
|
938
|
+
span: SYNTHETIC_SPAN
|
|
939
|
+
}],
|
|
940
|
+
span: SYNTHETIC_SPAN
|
|
941
|
+
};
|
|
942
|
+
}
|
|
811
943
|
function buildModel(table, typeMap, enumNameMap, fieldNamesByTable, namedTypes, defaultMapping, rawDefaultParser, relationFields) {
|
|
812
944
|
const { name: modelName, map: mapName } = toModelName(table.name);
|
|
813
945
|
const fieldNameMap = fieldNamesByTable.get(table.name);
|
|
@@ -867,8 +999,17 @@ function buildScalarField(column, table, typeMap, enumNameMap, fieldNameMap, nam
|
|
|
867
999
|
};
|
|
868
1000
|
}
|
|
869
1001
|
let typeName = resolution.pslType;
|
|
1002
|
+
let typeConstructor;
|
|
870
1003
|
const enumPslName = enumNameMap.get(column.nativeType);
|
|
871
|
-
if (enumPslName)
|
|
1004
|
+
if (enumPslName) {
|
|
1005
|
+
typeName = enumPslName;
|
|
1006
|
+
typeConstructor = {
|
|
1007
|
+
kind: "typeConstructor",
|
|
1008
|
+
path: ["pg", "enum"],
|
|
1009
|
+
args: [positionalArg(enumPslName)],
|
|
1010
|
+
span: SYNTHETIC_SPAN
|
|
1011
|
+
};
|
|
1012
|
+
}
|
|
872
1013
|
if (resolution.nativeTypeAttribute && !enumPslName) typeName = resolveNamedTypeName(namedTypes, resolution);
|
|
873
1014
|
const attributes = [];
|
|
874
1015
|
const isId = isSinglePk && pkColumns.has(column.name);
|
|
@@ -889,6 +1030,7 @@ function buildScalarField(column, table, typeMap, enumNameMap, fieldNameMap, nam
|
|
|
889
1030
|
kind: "field",
|
|
890
1031
|
name: fieldName,
|
|
891
1032
|
typeName,
|
|
1033
|
+
...ifDefined("typeConstructor", typeConstructor),
|
|
892
1034
|
optional: column.nullable,
|
|
893
1035
|
list: column.many === true,
|
|
894
1036
|
attributes,
|
|
@@ -1038,9 +1180,10 @@ function buildTopLevelNameMap(sources, normalize, kind, sourceKind) {
|
|
|
1038
1180
|
}
|
|
1039
1181
|
return results;
|
|
1040
1182
|
}
|
|
1041
|
-
function createReservedNamedTypeNames(modelNames) {
|
|
1183
|
+
function createReservedNamedTypeNames(modelNames, enumNameMap) {
|
|
1042
1184
|
const reservedNames = new Set(PSL_SCALAR_TYPE_NAMES);
|
|
1043
1185
|
for (const result of modelNames.values()) reservedNames.add(result.name);
|
|
1186
|
+
for (const enumPslName of enumNameMap.values()) reservedNames.add(enumPslName);
|
|
1044
1187
|
return reservedNames;
|
|
1045
1188
|
}
|
|
1046
1189
|
function seedNamedTypeRegistry(schemaIR, typeMap, enumNameMap, reservedNames) {
|