@prisma-next/target-postgres 0.14.0-dev.5 → 0.14.0-dev.50
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-DzHOdWTl.mjs +364 -0
- package/dist/authoring-DzHOdWTl.mjs.map +1 -0
- package/dist/canonicalize-Bn3BM1Cn.mjs +46 -0
- package/dist/canonicalize-Bn3BM1Cn.mjs.map +1 -0
- package/dist/canonicalize-CAbXtVtB.d.mts +37 -0
- package/dist/canonicalize-CAbXtVtB.d.mts.map +1 -0
- package/dist/{codec-ids-CnXu9Qy3.d.mts → codec-ids-BzrFF-I4.d.mts} +3 -2
- package/dist/codec-ids-BzrFF-I4.d.mts.map +1 -0
- package/dist/{codec-ids-BvytN2P8.mjs → codec-ids-C_-Hj6bL.mjs} +3 -2
- package/dist/codec-ids-C_-Hj6bL.mjs.map +1 -0
- package/dist/codec-ids.d.mts +2 -2
- package/dist/codec-ids.mjs +2 -2
- package/dist/{codec-types-DHCkwPKE.d.mts → codec-types-BDVmvKAW.d.mts} +3 -2
- package/dist/codec-types-BDVmvKAW.d.mts.map +1 -0
- package/dist/codec-types.d.mts +1 -1
- package/dist/{codecs--0A5_4Bq.d.mts → codecs-Dk2sxGLv.d.mts} +77 -4
- package/dist/codecs-Dk2sxGLv.d.mts.map +1 -0
- package/dist/codecs.d.mts +1 -1
- package/dist/codecs.mjs +117 -2
- package/dist/codecs.mjs.map +1 -1
- package/dist/contract-free.d.mts +8 -3
- package/dist/contract-free.d.mts.map +1 -1
- package/dist/contract-free.mjs +4 -4
- package/dist/control-policy-DUFgy9jO.mjs +1103 -0
- package/dist/control-policy-DUFgy9jO.mjs.map +1 -0
- package/dist/control.d.mts +2 -2
- package/dist/control.d.mts.map +1 -1
- package/dist/control.mjs +757 -35
- package/dist/control.mjs.map +1 -1
- package/dist/data-transform-BOWpliq8.mjs.map +1 -1
- package/dist/{data-transform-DDgWdB5o.d.mts → data-transform-DPzwBMhW.d.mts} +3 -3
- package/dist/{data-transform-DDgWdB5o.d.mts.map → data-transform-DPzwBMhW.d.mts.map} +1 -1
- package/dist/data-transform.d.mts +1 -1
- package/dist/{ddl-QDyOSeLc.mjs → ddl-ujxH2A7r.mjs} +63 -6
- package/dist/ddl-ujxH2A7r.mjs.map +1 -0
- package/dist/ddl.d.mts +3 -2
- package/dist/ddl.mjs +2 -2
- package/dist/default-normalizer.d.mts +1 -1
- package/dist/default-normalizer.d.mts.map +1 -1
- package/dist/default-normalizer.mjs +247 -1
- package/dist/default-normalizer.mjs.map +1 -0
- package/dist/descriptor-meta-CuGDsrG4.mjs +19 -0
- package/dist/descriptor-meta-CuGDsrG4.mjs.map +1 -0
- package/dist/descriptor-meta-runtime-UwYdV8fD.mjs +12 -0
- package/dist/descriptor-meta-runtime-UwYdV8fD.mjs.map +1 -0
- package/dist/diff-database-schema-BmSmWcaY.mjs +313 -0
- package/dist/diff-database-schema-BmSmWcaY.mjs.map +1 -0
- package/dist/diff-database-schema.d.mts +46 -0
- package/dist/diff-database-schema.d.mts.map +1 -0
- package/dist/diff-database-schema.mjs +2 -0
- package/dist/issue-planner.d.mts +35 -11
- package/dist/issue-planner.d.mts.map +1 -1
- package/dist/issue-planner.mjs +2 -2
- package/dist/migration.d.mts +5 -5
- package/dist/migration.d.mts.map +1 -1
- package/dist/migration.mjs +4 -4
- package/dist/namespace-ids-xtp_ZY86.mjs +7 -0
- package/dist/namespace-ids-xtp_ZY86.mjs.map +1 -0
- package/dist/native-type-normalizer.mjs +37 -1
- package/dist/native-type-normalizer.mjs.map +1 -0
- package/dist/nodes-CSkPX3rI.d.mts +120 -0
- package/dist/nodes-CSkPX3rI.d.mts.map +1 -0
- package/dist/{nodes-Bbhs2rwj.mjs → nodes-Dh__NS58.mjs} +56 -2
- package/dist/nodes-Dh__NS58.mjs.map +1 -0
- package/dist/{op-factory-call-D_p5vxwt.mjs → op-factory-call-BKRnMgrB.mjs} +205 -31
- package/dist/op-factory-call-BKRnMgrB.mjs.map +1 -0
- package/dist/{op-factory-call-DmQEc3XV.d.mts → op-factory-call-Dt-Jx5JS.d.mts} +46 -15
- package/dist/op-factory-call-Dt-Jx5JS.d.mts.map +1 -0
- package/dist/op-factory-call.d.mts +2 -2
- package/dist/op-factory-call.mjs +2 -2
- package/dist/pack.d.mts +115 -3
- package/dist/pack.d.mts.map +1 -1
- package/dist/pack.mjs +1 -1
- package/dist/planner-BMBRPzsv.mjs +367 -0
- package/dist/planner-BMBRPzsv.mjs.map +1 -0
- package/dist/{planner-ddl-builders-B2wOwLqI.mjs → planner-ddl-builders-B8Nn6nHN.mjs} +12 -27
- package/dist/planner-ddl-builders-B8Nn6nHN.mjs.map +1 -0
- package/dist/planner-ddl-builders.d.mts +4 -6
- package/dist/planner-ddl-builders.d.mts.map +1 -1
- package/dist/planner-ddl-builders.mjs +2 -2
- package/dist/planner-identity-values-CJPha2Sz.mjs.map +1 -1
- package/dist/planner-identity-values.d.mts +8 -2
- package/dist/planner-identity-values.d.mts.map +1 -1
- package/dist/planner-identity-values.mjs +2 -2
- package/dist/{planner-produced-postgres-migration-QqHa2C2l.d.mts → planner-produced-postgres-migration-C0a7I1-e.d.mts} +4 -4
- package/dist/{planner-produced-postgres-migration-QqHa2C2l.d.mts.map → planner-produced-postgres-migration-C0a7I1-e.d.mts.map} +1 -1
- package/dist/{planner-produced-postgres-migration-Cji5vxUf.mjs → planner-produced-postgres-migration-Dp6IO_gj.mjs} +3 -3
- package/dist/{planner-produced-postgres-migration-Cji5vxUf.mjs.map → planner-produced-postgres-migration-Dp6IO_gj.mjs.map} +1 -1
- package/dist/planner-produced-postgres-migration.d.mts +1 -1
- package/dist/planner-produced-postgres-migration.mjs +1 -1
- package/dist/{planner-sql-checks-jqUUGyQR.mjs → planner-sql-checks-Cze3vMfe.mjs} +2 -2
- package/dist/{planner-sql-checks-jqUUGyQR.mjs.map → planner-sql-checks-Cze3vMfe.mjs.map} +1 -1
- package/dist/planner-sql-checks.d.mts +2 -2
- package/dist/planner-sql-checks.d.mts.map +1 -1
- package/dist/planner-sql-checks.mjs +1 -1
- package/dist/{planner-target-details-CIY6tLeo.d.mts → planner-target-details-HkP4RrRO.d.mts} +2 -2
- package/dist/planner-target-details-HkP4RrRO.d.mts.map +1 -0
- package/dist/planner-target-details.d.mts +1 -1
- package/dist/planner.d.mts +55 -17
- package/dist/planner.d.mts.map +1 -1
- package/dist/planner.mjs +3 -2
- package/dist/{postgres-contract-serializer-k3TAcPMY.mjs → postgres-contract-view-3xfUgjnC.mjs} +44 -41
- package/dist/postgres-contract-view-3xfUgjnC.mjs.map +1 -0
- package/dist/postgres-contract-view-C9j5cqP0.d.mts +34 -0
- package/dist/postgres-contract-view-C9j5cqP0.d.mts.map +1 -0
- package/dist/postgres-database-schema-node-C9bTuMrd.d.mts +190 -0
- package/dist/postgres-database-schema-node-C9bTuMrd.d.mts.map +1 -0
- package/dist/{postgres-migration-B5jKrXv3.mjs → postgres-migration-D0jwzYDT.mjs} +21 -2
- package/dist/postgres-migration-D0jwzYDT.mjs.map +1 -0
- package/dist/{postgres-migration-Y4YBJqkS.d.mts → postgres-migration-DFaxuRyI.d.mts} +20 -7
- package/dist/postgres-migration-DFaxuRyI.d.mts.map +1 -0
- package/dist/postgres-native-enum-xdiqmBf_.mjs +41 -0
- package/dist/postgres-native-enum-xdiqmBf_.mjs.map +1 -0
- package/dist/postgres-rls-policy--CSddvMR.d.mts +52 -0
- package/dist/postgres-rls-policy--CSddvMR.d.mts.map +1 -0
- package/dist/{postgres-schema-COGZ1ark.mjs → postgres-schema-CajYAwny.mjs} +135 -7
- package/dist/postgres-schema-CajYAwny.mjs.map +1 -0
- package/dist/postgres-schema-DqnhQRvR.d.mts +226 -0
- package/dist/postgres-schema-DqnhQRvR.d.mts.map +1 -0
- package/dist/postgres-table-schema-node-BgaSrxYN.mjs +249 -0
- package/dist/postgres-table-schema-node-BgaSrxYN.mjs.map +1 -0
- package/dist/render-ops.d.mts +1 -1
- package/dist/{render-typescript-KMgosran.mjs → render-typescript-7yqILcwr.mjs} +45 -16
- package/dist/render-typescript-7yqILcwr.mjs.map +1 -0
- package/dist/render-typescript.mjs +1 -1
- package/dist/resolve-ddl-schema-Bv1ZvjX8.mjs +22 -0
- package/dist/resolve-ddl-schema-Bv1ZvjX8.mjs.map +1 -0
- package/dist/rls-canonicalize.d.mts +2 -0
- package/dist/rls-canonicalize.mjs +2 -0
- package/dist/runtime.d.mts +6 -8
- package/dist/runtime.d.mts.map +1 -1
- package/dist/runtime.mjs +3 -3
- package/dist/runtime.mjs.map +1 -1
- package/dist/schema-ir-annotations.d.mts +15 -0
- package/dist/schema-ir-annotations.d.mts.map +1 -0
- package/dist/schema-ir-annotations.mjs +2 -0
- package/dist/schema-node-kinds-ClScchhi.mjs +76 -0
- package/dist/schema-node-kinds-ClScchhi.mjs.map +1 -0
- package/dist/types.d.mts +4 -140
- package/dist/types.mjs +3 -2
- package/package.json +23 -17
- package/src/contract-free/checks.ts +73 -0
- package/src/contract-free/ddl.ts +45 -1
- package/src/core/authoring.ts +287 -2
- package/src/core/codec-ids.ts +1 -0
- package/src/core/codec-type-map.ts +2 -0
- package/src/core/codecs.ts +141 -1
- package/src/core/ddl/nodes.ts +94 -2
- package/src/core/default-normalizer.ts +122 -2
- package/src/core/descriptor-meta.ts +6 -1
- package/src/core/entity-kinds.ts +30 -0
- package/src/core/migrations/bound-schema.ts +10 -0
- package/src/core/migrations/column-ddl-rendering.ts +117 -0
- package/src/core/migrations/contract-to-postgres-database-schema-node.ts +149 -0
- package/src/core/migrations/control-policy.ts +70 -47
- package/src/core/migrations/diff-database-schema.ts +280 -0
- package/src/core/migrations/issue-planner.ts +647 -652
- package/src/core/migrations/op-factory-call.ts +109 -21
- package/src/core/migrations/operations/columns.ts +24 -12
- package/src/core/migrations/operations/constraints.ts +1 -1
- package/src/core/migrations/operations/data-transform.ts +6 -0
- package/src/core/migrations/operations/dependencies.ts +2 -1
- package/src/core/migrations/operations/rls.ts +106 -0
- package/src/core/migrations/operations/shared.ts +0 -30
- package/src/core/migrations/planner-ddl-builders.ts +20 -58
- package/src/core/migrations/planner-identity-values.ts +1 -1
- package/src/core/migrations/planner-recipes.ts +31 -13
- package/src/core/migrations/planner-sql-checks.ts +1 -1
- package/src/core/migrations/planner-strategies.ts +248 -216
- package/src/core/migrations/planner-target-details.ts +3 -1
- package/src/core/migrations/planner.ts +297 -59
- package/src/core/migrations/postgres-migration.ts +34 -4
- package/src/core/migrations/render-typescript.ts +42 -15
- package/src/core/migrations/resolve-ddl-schema.ts +26 -0
- package/src/core/migrations/runner.ts +10 -16
- package/src/core/migrations/verify-postgres-namespaces.ts +47 -30
- package/src/core/namespace-ids.ts +3 -0
- package/src/core/postgres-contract-serializer.ts +41 -71
- package/src/core/postgres-contract-view.ts +48 -0
- package/src/core/postgres-native-enum.ts +51 -0
- package/src/core/postgres-rls-policy.ts +64 -0
- package/src/core/postgres-role.ts +37 -0
- package/src/core/postgres-schema-verifier.ts +10 -7
- package/src/core/postgres-schema.ts +62 -14
- package/src/core/postgres-validators.ts +27 -0
- package/src/core/psl-infer/infer-psl-contract.ts +1068 -0
- package/src/core/psl-infer/postgres-default-mapping.ts +16 -0
- package/src/core/psl-infer/postgres-type-map.ts +157 -0
- package/src/core/rls/canonicalize.ts +48 -0
- package/src/core/schema-ir/postgres-database-schema-node.ts +60 -0
- package/src/core/schema-ir/postgres-namespace-schema-node.ts +60 -0
- package/src/core/schema-ir/postgres-policy-schema-node.ts +90 -0
- package/src/core/schema-ir/postgres-role-schema-node.ts +63 -0
- package/src/core/schema-ir/postgres-table-schema-node.ts +118 -0
- package/src/core/schema-ir/schema-node-kinds.ts +106 -0
- package/src/exports/contract-free.ts +7 -1
- package/src/exports/control.ts +27 -33
- package/src/exports/ddl.ts +4 -0
- package/src/exports/diff-database-schema.ts +7 -0
- package/src/exports/issue-planner.ts +1 -1
- package/src/exports/migration.ts +1 -0
- package/src/exports/op-factory-call.ts +1 -0
- package/src/exports/planner-ddl-builders.ts +0 -2
- package/src/exports/planner-identity-values.ts +4 -1
- package/src/exports/planner.ts +1 -0
- package/src/exports/rls-canonicalize.ts +6 -0
- package/src/exports/runtime.ts +1 -0
- package/src/exports/schema-ir-annotations.ts +1 -0
- package/src/exports/types.ts +28 -0
- package/dist/codec-ids-BvytN2P8.mjs.map +0 -1
- package/dist/codec-ids-CnXu9Qy3.d.mts.map +0 -1
- package/dist/codec-types-DHCkwPKE.d.mts.map +0 -1
- package/dist/codecs--0A5_4Bq.d.mts.map +0 -1
- package/dist/ddl-QDyOSeLc.mjs.map +0 -1
- package/dist/default-normalizer-DyyCHQWs.mjs +0 -131
- package/dist/default-normalizer-DyyCHQWs.mjs.map +0 -1
- package/dist/descriptor-meta-CpGygXpI.mjs +0 -140
- package/dist/descriptor-meta-CpGygXpI.mjs.map +0 -1
- package/dist/issue-planner-DL6g3CmE.mjs +0 -824
- package/dist/issue-planner-DL6g3CmE.mjs.map +0 -1
- package/dist/native-type-normalizer-Bc9XJzWC.mjs +0 -38
- package/dist/native-type-normalizer-Bc9XJzWC.mjs.map +0 -1
- package/dist/nodes-Bbhs2rwj.mjs.map +0 -1
- package/dist/nodes-pLeLgdis.d.mts +0 -67
- package/dist/nodes-pLeLgdis.d.mts.map +0 -1
- package/dist/op-factory-call-D_p5vxwt.mjs.map +0 -1
- package/dist/op-factory-call-DmQEc3XV.d.mts.map +0 -1
- package/dist/planner-Bs_baQax.mjs +0 -324
- package/dist/planner-Bs_baQax.mjs.map +0 -1
- package/dist/planner-ddl-builders-B2wOwLqI.mjs.map +0 -1
- package/dist/planner-target-details-CIY6tLeo.d.mts.map +0 -1
- package/dist/postgres-contract-serializer-k3TAcPMY.mjs.map +0 -1
- package/dist/postgres-migration-B5jKrXv3.mjs.map +0 -1
- package/dist/postgres-migration-Y4YBJqkS.d.mts.map +0 -1
- package/dist/postgres-schema-COGZ1ark.mjs.map +0 -1
- package/dist/render-typescript-KMgosran.mjs.map +0 -1
- package/dist/types.d.mts.map +0 -1
- package/src/core/postgres-enum-type-schema.ts +0 -17
package/src/contract-free/ddl.ts
CHANGED
|
@@ -2,9 +2,13 @@ import type { DdlColumn, DdlTableConstraint } from '@prisma-next/sql-relational-
|
|
|
2
2
|
import {
|
|
3
3
|
AddColumnAction,
|
|
4
4
|
type AnyAlterTableAction,
|
|
5
|
+
DropDefaultAction,
|
|
5
6
|
PostgresAlterTable,
|
|
7
|
+
PostgresCreatePolicy,
|
|
6
8
|
PostgresCreateSchema,
|
|
7
9
|
PostgresCreateTable,
|
|
10
|
+
PostgresDropPolicy,
|
|
11
|
+
type RlsPolicyOperation,
|
|
8
12
|
} from '../core/ddl/nodes';
|
|
9
13
|
|
|
10
14
|
/**
|
|
@@ -51,9 +55,17 @@ export function addColumnAction(column: DdlColumn): AddColumnAction {
|
|
|
51
55
|
return new AddColumnAction(column);
|
|
52
56
|
}
|
|
53
57
|
|
|
58
|
+
/**
|
|
59
|
+
* Build a `DROP DEFAULT` action (`ALTER COLUMN "<name>" DROP DEFAULT`) for
|
|
60
|
+
* use inside {@link alterTable}. The renderer quotes the column name.
|
|
61
|
+
*/
|
|
62
|
+
export function dropDefaultAction(columnName: string): DropDefaultAction {
|
|
63
|
+
return new DropDefaultAction(columnName);
|
|
64
|
+
}
|
|
65
|
+
|
|
54
66
|
/**
|
|
55
67
|
* Build a Postgres `ALTER TABLE` query node carrying one or more actions.
|
|
56
|
-
* See {@link addColumnAction} for building actions.
|
|
68
|
+
* See {@link addColumnAction} / {@link dropDefaultAction} for building actions.
|
|
57
69
|
*/
|
|
58
70
|
export function alterTable(options: {
|
|
59
71
|
readonly table: string;
|
|
@@ -62,3 +74,35 @@ export function alterTable(options: {
|
|
|
62
74
|
}): PostgresAlterTable {
|
|
63
75
|
return new PostgresAlterTable(options);
|
|
64
76
|
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Build a Postgres `CREATE POLICY` DDL node.
|
|
80
|
+
*
|
|
81
|
+
* Identifiers (`schema`, `table`, `name`) are quoted by the renderer.
|
|
82
|
+
* `using` and `withCheck` are emitted verbatim as predicate SQL — callers
|
|
83
|
+
* must supply safe, pre-validated SQL expressions.
|
|
84
|
+
*/
|
|
85
|
+
export function createPolicy(options: {
|
|
86
|
+
readonly schema: string;
|
|
87
|
+
readonly table: string;
|
|
88
|
+
readonly name: string;
|
|
89
|
+
readonly permissive: boolean;
|
|
90
|
+
readonly operation: RlsPolicyOperation;
|
|
91
|
+
readonly roles: readonly string[];
|
|
92
|
+
readonly using?: string;
|
|
93
|
+
readonly withCheck?: string;
|
|
94
|
+
}): PostgresCreatePolicy {
|
|
95
|
+
return new PostgresCreatePolicy(options);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Build a Postgres `DROP POLICY` DDL node.
|
|
100
|
+
* Identifiers (`schema`, `table`, `name`) are quoted by the renderer.
|
|
101
|
+
*/
|
|
102
|
+
export function dropPolicy(options: {
|
|
103
|
+
readonly schema: string;
|
|
104
|
+
readonly table: string;
|
|
105
|
+
readonly name: string;
|
|
106
|
+
}): PostgresDropPolicy {
|
|
107
|
+
return new PostgresDropPolicy(options);
|
|
108
|
+
}
|
package/src/core/authoring.ts
CHANGED
|
@@ -1,13 +1,247 @@
|
|
|
1
1
|
import { temporalAuthoringPresets } from '@prisma-next/family-sql/control';
|
|
2
2
|
import type {
|
|
3
|
+
AuthoringEntityContext,
|
|
4
|
+
AuthoringEntityTypeFactoryOutput,
|
|
3
5
|
AuthoringEntityTypeNamespace,
|
|
4
6
|
AuthoringFieldNamespace,
|
|
7
|
+
AuthoringPslBlockDescriptorNamespace,
|
|
5
8
|
AuthoringTypeNamespace,
|
|
9
|
+
PslExtensionBlock,
|
|
6
10
|
} from '@prisma-next/framework-components/authoring';
|
|
11
|
+
import type { SqlValueSetDerivingEntityTypeOutput } from '@prisma-next/sql-contract/value-set-derivation-hook';
|
|
12
|
+
import { PG_ENUM_CODEC_ID } from './codec-ids';
|
|
13
|
+
import { PostgresNativeEnum } from './postgres-native-enum';
|
|
14
|
+
import { PostgresRlsPolicy } from './postgres-rls-policy';
|
|
15
|
+
import { PostgresRole, type PostgresRoleInput } from './postgres-role';
|
|
16
|
+
import {
|
|
17
|
+
PostgresNativeEnumSchema,
|
|
18
|
+
PostgresRlsPolicySchema,
|
|
19
|
+
PostgresRoleSchema,
|
|
20
|
+
} from './postgres-validators';
|
|
21
|
+
import { computeContentHash, normalizePredicate } from './rls/canonicalize';
|
|
7
22
|
|
|
8
|
-
|
|
23
|
+
/**
|
|
24
|
+
* `pg.enum(<ref>)` registers as an ordinary type constructor whose sole
|
|
25
|
+
* positional argument names a `native_enum` entity instead of carrying a
|
|
26
|
+
* literal value. The interpreter resolves the ref to the `native_enum`
|
|
27
|
+
* entity generically (driven by `entityRefArg`); the `pg/enum@1` codec
|
|
28
|
+
* descriptor's `columnFromEntity` hook (see `codecs.ts`) converts that
|
|
29
|
+
* entity into the column's `typeParams` and native type.
|
|
30
|
+
*/
|
|
31
|
+
export const postgresAuthoringTypes = {
|
|
32
|
+
pg: {
|
|
33
|
+
enum: {
|
|
34
|
+
kind: 'typeConstructor',
|
|
35
|
+
entityRefArg: { index: 0, entityKind: 'native_enum' },
|
|
36
|
+
output: {
|
|
37
|
+
codecId: PG_ENUM_CODEC_ID,
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
} as const satisfies AuthoringTypeNamespace;
|
|
42
|
+
|
|
43
|
+
export interface RlsPolicyExtensionBlock extends PslExtensionBlock {
|
|
44
|
+
readonly namespaceId: string;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function readRefParam(block: PslExtensionBlock, key: string): string | undefined {
|
|
48
|
+
const param = block.parameters[key];
|
|
49
|
+
return param?.kind === 'ref' ? param.identifier : undefined;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function readValueParam(block: PslExtensionBlock, key: string): string | undefined {
|
|
53
|
+
const param = block.parameters[key];
|
|
54
|
+
return param?.kind === 'value' ? param.raw : undefined;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function readListRefParams(block: PslExtensionBlock, key: string): string[] {
|
|
58
|
+
const param = block.parameters[key];
|
|
59
|
+
if (param?.kind !== 'list') return [];
|
|
60
|
+
return param.items.flatMap((item) => (item.kind === 'ref' ? [item.identifier] : []));
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function unwrapQuotedString(raw: string): string {
|
|
64
|
+
if (raw.startsWith('"') && raw.endsWith('"') && raw.length >= 2) {
|
|
65
|
+
return raw.slice(1, -1).replace(/\\"/g, '"');
|
|
66
|
+
}
|
|
67
|
+
return raw;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function lowerRlsPolicyFromBlock(
|
|
71
|
+
block: RlsPolicyExtensionBlock,
|
|
72
|
+
_ctx: AuthoringEntityContext,
|
|
73
|
+
): PostgresRlsPolicy {
|
|
74
|
+
const prefix = block.name;
|
|
75
|
+
const targetModelName = readRefParam(block, 'target') ?? '';
|
|
76
|
+
const tableName = targetModelName.charAt(0).toLowerCase() + targetModelName.slice(1);
|
|
77
|
+
const roles = [...readListRefParams(block, 'roles')].sort();
|
|
78
|
+
const using = unwrapQuotedString(readValueParam(block, 'using') ?? '');
|
|
79
|
+
|
|
80
|
+
const wireHash = computeContentHash({
|
|
81
|
+
using: normalizePredicate(using),
|
|
82
|
+
roles,
|
|
83
|
+
operation: 'select',
|
|
84
|
+
permissive: true,
|
|
85
|
+
});
|
|
86
|
+
const wireName = `${prefix}_${wireHash}`;
|
|
87
|
+
|
|
88
|
+
return new PostgresRlsPolicy({
|
|
89
|
+
name: wireName,
|
|
90
|
+
prefix,
|
|
91
|
+
tableName,
|
|
92
|
+
namespaceId: block.namespaceId,
|
|
93
|
+
operation: 'select',
|
|
94
|
+
roles,
|
|
95
|
+
using,
|
|
96
|
+
permissive: true,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Lowers a `native_enum { memberName = "value" … @@map("type_name") }` block
|
|
102
|
+
* into a {@link PostgresNativeEnum}. Members must be authored as explicit
|
|
103
|
+
* `key = "value"` pairs — a bare (value-less) member is a diagnostic, not
|
|
104
|
+
* accepted (authoring-design.md §2.1). The parsed `memberName` is only used
|
|
105
|
+
* to duplicate-check and report diagnostics; the lowered entity carries just
|
|
106
|
+
* the member values (a native enum is value-only — the member "name" isn't
|
|
107
|
+
* a separate authoring concept from the value). `typeName` comes from
|
|
108
|
+
* `@@map` or defaults to the block name verbatim.
|
|
109
|
+
*/
|
|
110
|
+
function lowerNativeEnumFromBlock(
|
|
111
|
+
block: PslExtensionBlock,
|
|
112
|
+
ctx: AuthoringEntityContext,
|
|
113
|
+
): PostgresNativeEnum | undefined {
|
|
114
|
+
const sourceId = ctx.sourceId ?? 'unknown';
|
|
115
|
+
const diagnostics = ctx.diagnostics;
|
|
116
|
+
|
|
117
|
+
const mapAttr = block.blockAttributes.find((a) => a.name === 'map');
|
|
118
|
+
let typeName = block.name;
|
|
119
|
+
if (mapAttr) {
|
|
120
|
+
const rawArg = mapAttr.args[0]?.value;
|
|
121
|
+
const mapped = rawArg !== undefined ? unwrapQuotedString(rawArg) : undefined;
|
|
122
|
+
if (mapped === undefined) {
|
|
123
|
+
diagnostics?.push({
|
|
124
|
+
code: 'PSL_NATIVE_ENUM_INVALID_MAP',
|
|
125
|
+
message: `native_enum "${block.name}" @@map attribute must have a quoted type-name argument`,
|
|
126
|
+
sourceId,
|
|
127
|
+
span: mapAttr.span,
|
|
128
|
+
});
|
|
129
|
+
return undefined;
|
|
130
|
+
}
|
|
131
|
+
typeName = mapped;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
let memberError = false;
|
|
135
|
+
const seenValues = new Set<string>();
|
|
136
|
+
const members: string[] = [];
|
|
137
|
+
for (const [memberName, paramValue] of Object.entries(block.parameters)) {
|
|
138
|
+
if (paramValue.kind === 'bare') {
|
|
139
|
+
diagnostics?.push({
|
|
140
|
+
code: 'PSL_NATIVE_ENUM_BARE_MEMBER',
|
|
141
|
+
message: `native_enum "${block.name}" member "${memberName}" has no value; members must be authored as "${memberName} = \\"value\\""`,
|
|
142
|
+
sourceId,
|
|
143
|
+
span: paramValue.span,
|
|
144
|
+
});
|
|
145
|
+
memberError = true;
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
if (paramValue.kind !== 'value') continue;
|
|
149
|
+
|
|
150
|
+
let jsonValue: unknown;
|
|
151
|
+
try {
|
|
152
|
+
jsonValue = JSON.parse(paramValue.raw);
|
|
153
|
+
} catch {
|
|
154
|
+
diagnostics?.push({
|
|
155
|
+
code: 'PSL_EXTENSION_INVALID_VALUE',
|
|
156
|
+
message: `native_enum "${block.name}" member "${memberName}" value "${paramValue.raw}" is not valid JSON`,
|
|
157
|
+
sourceId,
|
|
158
|
+
span: paramValue.span,
|
|
159
|
+
});
|
|
160
|
+
memberError = true;
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
if (typeof jsonValue !== 'string') {
|
|
164
|
+
diagnostics?.push({
|
|
165
|
+
code: 'PSL_EXTENSION_INVALID_VALUE',
|
|
166
|
+
message: `native_enum "${block.name}" member "${memberName}" value must be a string`,
|
|
167
|
+
sourceId,
|
|
168
|
+
span: paramValue.span,
|
|
169
|
+
});
|
|
170
|
+
memberError = true;
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
if (seenValues.has(jsonValue)) {
|
|
174
|
+
diagnostics?.push({
|
|
175
|
+
code: 'PSL_NATIVE_ENUM_DUPLICATE_MEMBER_VALUE',
|
|
176
|
+
message: `native_enum "${block.name}": duplicate member value "${jsonValue}"`,
|
|
177
|
+
sourceId,
|
|
178
|
+
span: paramValue.span,
|
|
179
|
+
});
|
|
180
|
+
memberError = true;
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
seenValues.add(jsonValue);
|
|
184
|
+
members.push(jsonValue);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if (memberError) return undefined;
|
|
188
|
+
|
|
189
|
+
if (members.length === 0) {
|
|
190
|
+
diagnostics?.push({
|
|
191
|
+
code: 'PSL_NATIVE_ENUM_MISSING_MEMBERS',
|
|
192
|
+
message: `native_enum "${block.name}" must have at least one member`,
|
|
193
|
+
sourceId,
|
|
194
|
+
span: block.span,
|
|
195
|
+
});
|
|
196
|
+
return undefined;
|
|
197
|
+
}
|
|
9
198
|
|
|
10
|
-
|
|
199
|
+
// `control` stays unset — the effective grade is resolved at read time via `effectiveControlPolicy`, like `StorageTable`/`StorageColumn`.
|
|
200
|
+
return new PostgresNativeEnum({ typeName, members });
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* `native_enum`'s entity-type factory output, checked separately from the assembled
|
|
205
|
+
* `postgresAuthoringEntityTypes` map below: `deriveValueSet` is SQL-family surface
|
|
206
|
+
* ({@link SqlValueSetDerivingEntityTypeOutput}), not part of the framework
|
|
207
|
+
* `AuthoringEntityTypeFactoryOutput` shape, so folding it directly into the map's single
|
|
208
|
+
* `satisfies AuthoringEntityTypeNamespace` check would trip an excess-property error. Checking it
|
|
209
|
+
* here against the intersection of both shapes keeps it structurally valid against each without
|
|
210
|
+
* widening the map's own check.
|
|
211
|
+
*/
|
|
212
|
+
const nativeEnumEntityTypeOutput = {
|
|
213
|
+
factory: lowerNativeEnumFromBlock,
|
|
214
|
+
deriveValueSet: (entity: PostgresNativeEnum) => ({
|
|
215
|
+
kind: 'valueSet' as const,
|
|
216
|
+
values: [...entity.members],
|
|
217
|
+
}),
|
|
218
|
+
} satisfies AuthoringEntityTypeFactoryOutput<PslExtensionBlock, PostgresNativeEnum | undefined> &
|
|
219
|
+
SqlValueSetDerivingEntityTypeOutput;
|
|
220
|
+
|
|
221
|
+
export const postgresAuthoringEntityTypes = {
|
|
222
|
+
role: {
|
|
223
|
+
kind: 'entity',
|
|
224
|
+
discriminator: 'role',
|
|
225
|
+
validatorSchema: PostgresRoleSchema,
|
|
226
|
+
output: {
|
|
227
|
+
factory: (input: PostgresRoleInput): PostgresRole => new PostgresRole(input),
|
|
228
|
+
},
|
|
229
|
+
},
|
|
230
|
+
policy: {
|
|
231
|
+
kind: 'entity',
|
|
232
|
+
discriminator: 'policy',
|
|
233
|
+
validatorSchema: PostgresRlsPolicySchema,
|
|
234
|
+
output: {
|
|
235
|
+
factory: lowerRlsPolicyFromBlock,
|
|
236
|
+
},
|
|
237
|
+
},
|
|
238
|
+
native_enum: {
|
|
239
|
+
kind: 'entity',
|
|
240
|
+
discriminator: 'native_enum',
|
|
241
|
+
validatorSchema: PostgresNativeEnumSchema,
|
|
242
|
+
output: nativeEnumEntityTypeOutput,
|
|
243
|
+
},
|
|
244
|
+
} as const satisfies AuthoringEntityTypeNamespace;
|
|
11
245
|
|
|
12
246
|
/**
|
|
13
247
|
* Field presets contributed by the Postgres target pack.
|
|
@@ -22,6 +256,57 @@ export const postgresAuthoringEntityTypes = {} as const satisfies AuthoringEntit
|
|
|
22
256
|
* portability use `uuidString` / `id.uuidv4String` / `id.uuidv7String` from
|
|
23
257
|
* the family pack instead.
|
|
24
258
|
*/
|
|
259
|
+
/**
|
|
260
|
+
* PSL block descriptor for `policy_select`.
|
|
261
|
+
*
|
|
262
|
+
* The parser learns the block shape from this descriptor; lowering from
|
|
263
|
+
* `PslExtensionBlock` to `PostgresRlsPolicy` is wired in the PSL
|
|
264
|
+
* interpreter (a later dispatch). The `discriminator` matches
|
|
265
|
+
* `PostgresRlsPolicy.kind` so the parsed block node carries the same
|
|
266
|
+
* discriminant as the IR class it will lower to.
|
|
267
|
+
*
|
|
268
|
+
* The `roles` list uses `scope:'cross-space'` because same-namespace
|
|
269
|
+
* role ref resolution requires PSL namespace entries keyed by `refKind`
|
|
270
|
+
* (i.e. `'role'`), which in turn requires the role block discriminator to
|
|
271
|
+
* equal `'role'`. Aligning discriminator with refKind is tracked for
|
|
272
|
+
* slice 4 (cross-space roles). Until then cross-space passes validation
|
|
273
|
+
* unconditionally and the authored role names flow through unchanged.
|
|
274
|
+
*/
|
|
275
|
+
export const postgresAuthoringPslBlockDescriptors = {
|
|
276
|
+
policy_select: {
|
|
277
|
+
kind: 'pslBlock',
|
|
278
|
+
keyword: 'policy_select',
|
|
279
|
+
discriminator: 'policy',
|
|
280
|
+
name: { required: true },
|
|
281
|
+
parameters: {
|
|
282
|
+
target: { kind: 'ref', refKind: 'model', scope: 'same-namespace', required: true },
|
|
283
|
+
roles: {
|
|
284
|
+
kind: 'list',
|
|
285
|
+
of: { kind: 'ref', refKind: 'role', scope: 'cross-space' },
|
|
286
|
+
},
|
|
287
|
+
using: { kind: 'value', codecId: 'pg/text@1', required: true },
|
|
288
|
+
},
|
|
289
|
+
},
|
|
290
|
+
/**
|
|
291
|
+
* PSL block descriptor for `native_enum`.
|
|
292
|
+
*
|
|
293
|
+
* Reuses the existing variadic-block mechanism (the same shape the SQL
|
|
294
|
+
* family's `enum` block ships): the body is an open `memberName = "value"`
|
|
295
|
+
* list. `variadicParameters: true` opens the block to arbitrary keys
|
|
296
|
+
* beyond the declared (empty) `parameters` set — the lowering factory
|
|
297
|
+
* (`lowerNativeEnumFromBlock`) turns the variadic entries into ordered
|
|
298
|
+
* members and rejects a bare (value-less) member.
|
|
299
|
+
*/
|
|
300
|
+
native_enum: {
|
|
301
|
+
kind: 'pslBlock',
|
|
302
|
+
keyword: 'native_enum',
|
|
303
|
+
discriminator: 'native_enum',
|
|
304
|
+
name: { required: true },
|
|
305
|
+
parameters: {},
|
|
306
|
+
variadicParameters: true,
|
|
307
|
+
},
|
|
308
|
+
} as const satisfies AuthoringPslBlockDescriptorNamespace;
|
|
309
|
+
|
|
25
310
|
export const postgresAuthoringFieldPresets = {
|
|
26
311
|
text: {
|
|
27
312
|
kind: 'fieldPreset',
|
package/src/core/codec-ids.ts
CHANGED
|
@@ -8,6 +8,7 @@ export {
|
|
|
8
8
|
} from '@prisma-next/sql-relational-core/ast';
|
|
9
9
|
export const PG_TEXT_CODEC_ID = 'pg/text@1' as const;
|
|
10
10
|
export const PG_TEXT_ARRAY_CODEC_ID = 'pg/text-array@1' as const;
|
|
11
|
+
export const PG_ENUM_CODEC_ID = 'pg/enum@1' as const;
|
|
11
12
|
export const PG_CHAR_CODEC_ID = 'pg/char@1' as const;
|
|
12
13
|
export const PG_VARCHAR_CODEC_ID = 'pg/varchar@1' as const;
|
|
13
14
|
export const PG_INT_CODEC_ID = 'pg/int@1' as const;
|
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
pgBoolDescriptor,
|
|
22
22
|
pgByteaDescriptor,
|
|
23
23
|
pgCharDescriptor,
|
|
24
|
+
pgEnumDescriptor,
|
|
24
25
|
pgFloat4Descriptor,
|
|
25
26
|
pgFloat8Descriptor,
|
|
26
27
|
pgFloatDescriptor,
|
|
@@ -50,6 +51,7 @@ export const codecDescriptorMap = {
|
|
|
50
51
|
'sql-text': sqlTextDescriptor,
|
|
51
52
|
'sql-timestamp': sqlTimestampDescriptor,
|
|
52
53
|
text: pgTextDescriptor,
|
|
54
|
+
enum: pgEnumDescriptor,
|
|
53
55
|
character: pgCharDescriptor,
|
|
54
56
|
'character varying': pgVarcharDescriptor,
|
|
55
57
|
integer: pgIntDescriptor,
|
package/src/core/codecs.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Each codec ships as three artifacts:
|
|
5
5
|
*
|
|
6
6
|
* 1. A `PgXCodec` class extending {@link CodecImpl} that wraps the module-level encode/decode/encodeJson/decodeJson constants exported from `codec-helpers.ts` (the single source of truth for non-trivial runtime conversions; trivial identity passthroughs are inlined). 2. A `PgXDescriptor` class extending {@link CodecDescriptorImpl} declaring the codec id, traits, target types, params schema, meta, and (where applicable)
|
|
7
|
-
* the emit-path `renderOutputType`. 3. A per-codec column helper (`pgXColumn`) that calls `descriptor.factory(...)` directly and packages the result into a
|
|
7
|
+
* the emit-path `renderOutputType`. 3. A per-codec column helper (`pgXColumn`) that calls `descriptor.factory(...)` directly and packages the result into a framework `ColumnSpec` via the framework {@link column} packager. The helper is tied to its descriptor with `satisfies ColumnHelperFor` (and `ColumnHelperForStrict` where the resolved codec type is well-defined).
|
|
8
8
|
*
|
|
9
9
|
* After TML-2357 this is the canonical source of Postgres codec metadata and runtime behaviour — the legacy `mkCodec` / `defineCodec` carriers (and the parallel `byScalar`/`codecDescriptorDefinitions`/ `codecDescriptorList` collection exports) retired with the deletion sweep.
|
|
10
10
|
*
|
|
@@ -19,11 +19,14 @@ import {
|
|
|
19
19
|
CodecDescriptorImpl,
|
|
20
20
|
CodecImpl,
|
|
21
21
|
type CodecInstanceContext,
|
|
22
|
+
type CodecMeta,
|
|
22
23
|
type ColumnHelperFor,
|
|
23
24
|
type ColumnHelperForStrict,
|
|
24
25
|
column,
|
|
26
|
+
renderTsLiteral,
|
|
25
27
|
voidParamsSchema,
|
|
26
28
|
} from '@prisma-next/framework-components/codec';
|
|
29
|
+
import { UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';
|
|
27
30
|
import {
|
|
28
31
|
SqlCharCodec,
|
|
29
32
|
SqlFloatCodec,
|
|
@@ -59,6 +62,7 @@ import {
|
|
|
59
62
|
PG_BOOL_CODEC_ID,
|
|
60
63
|
PG_BYTEA_CODEC_ID,
|
|
61
64
|
PG_CHAR_CODEC_ID,
|
|
65
|
+
PG_ENUM_CODEC_ID,
|
|
62
66
|
PG_FLOAT_CODEC_ID,
|
|
63
67
|
PG_FLOAT4_CODEC_ID,
|
|
64
68
|
PG_FLOAT8_CODEC_ID,
|
|
@@ -80,6 +84,8 @@ import {
|
|
|
80
84
|
PG_VARBIT_CODEC_ID,
|
|
81
85
|
PG_VARCHAR_CODEC_ID,
|
|
82
86
|
} from './codec-ids';
|
|
87
|
+
import { DEFAULT_NAMESPACE_ID } from './namespace-ids';
|
|
88
|
+
import { PostgresNativeEnum } from './postgres-native-enum';
|
|
83
89
|
|
|
84
90
|
type LengthParams = { readonly length?: number };
|
|
85
91
|
type PrecisionParams = { readonly precision?: number };
|
|
@@ -148,6 +154,9 @@ export class PgTextDescriptor extends CodecDescriptorImpl<void> {
|
|
|
148
154
|
override readonly targetTypes = ['text'] as const;
|
|
149
155
|
override readonly meta = PG_TEXT_META;
|
|
150
156
|
override readonly paramsSchema: StandardSchemaV1<void> = voidParamsSchema;
|
|
157
|
+
override renderValueLiteral(value: JsonValue): string | undefined {
|
|
158
|
+
return renderTsLiteral(value);
|
|
159
|
+
}
|
|
151
160
|
override factory(): (ctx: CodecInstanceContext) => PgTextCodec {
|
|
152
161
|
return () => new PgTextCodec(this);
|
|
153
162
|
}
|
|
@@ -161,6 +170,106 @@ export const pgTextColumn = () =>
|
|
|
161
170
|
pgTextColumn satisfies ColumnHelperFor<PgTextDescriptor>;
|
|
162
171
|
pgTextColumn satisfies ColumnHelperForStrict<PgTextDescriptor>;
|
|
163
172
|
|
|
173
|
+
/**
|
|
174
|
+
* Codec for a `pg.enum(Ref)` column bound to a native Postgres enum type.
|
|
175
|
+
* Text passthrough, identical to `pg/text@1` — encode/decode do not carry the
|
|
176
|
+
* enum's member values; membership is enforced by the native type itself, not
|
|
177
|
+
* by this codec. `renderValueLiteral` renders a member value as its TS
|
|
178
|
+
* literal, which is what drives the column's typed value-union (via
|
|
179
|
+
* `renderValueSetType` reading the column's `valueSet` ref) — the codec
|
|
180
|
+
* itself carries no params of its own; typing comes entirely from the
|
|
181
|
+
* column's value-set, not from `pg/enum@1`.
|
|
182
|
+
*
|
|
183
|
+
* A distinct codec id (rather than reusing `pg/text@1` on a plain text
|
|
184
|
+
* column) keeps native-enum columns independently identifiable — from a
|
|
185
|
+
* column's `codecId` alone, without also inspecting `nativeType` — which
|
|
186
|
+
* the managed (DDL) phase needs to target `CREATE TYPE`/`ALTER TYPE`
|
|
187
|
+
* operations at exactly the columns that use one.
|
|
188
|
+
*/
|
|
189
|
+
export class PgEnumCodec extends CodecImpl<
|
|
190
|
+
typeof PG_ENUM_CODEC_ID,
|
|
191
|
+
readonly ['equality', 'order', 'textual'],
|
|
192
|
+
string,
|
|
193
|
+
string
|
|
194
|
+
> {
|
|
195
|
+
async encode(value: string, _ctx: CodecCallContext): Promise<string> {
|
|
196
|
+
return value;
|
|
197
|
+
}
|
|
198
|
+
async decode(wire: string, _ctx: CodecCallContext): Promise<string> {
|
|
199
|
+
return wire;
|
|
200
|
+
}
|
|
201
|
+
encodeJson(value: string): JsonValue {
|
|
202
|
+
return value;
|
|
203
|
+
}
|
|
204
|
+
decodeJson(json: JsonValue): string {
|
|
205
|
+
return blindCast<
|
|
206
|
+
string,
|
|
207
|
+
'text codec: a native-enum member value is stored as its wire string form'
|
|
208
|
+
>(json);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
type PgEnumParams = { readonly typeName: string };
|
|
213
|
+
|
|
214
|
+
const pgEnumParamsSchema = arktype({
|
|
215
|
+
typeName: 'string',
|
|
216
|
+
}) satisfies StandardSchemaV1<PgEnumParams>;
|
|
217
|
+
|
|
218
|
+
function isJsonObject(
|
|
219
|
+
value: JsonValue | undefined,
|
|
220
|
+
): value is { readonly [key: string]: JsonValue } {
|
|
221
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
export class PgEnumDescriptor extends CodecDescriptorImpl<PgEnumParams> {
|
|
225
|
+
override readonly codecId = PG_ENUM_CODEC_ID;
|
|
226
|
+
override readonly traits = ['equality', 'order', 'textual'] as const;
|
|
227
|
+
override readonly targetTypes = ['text'] as const;
|
|
228
|
+
override readonly meta = PG_TEXT_META;
|
|
229
|
+
override readonly paramsSchema = pgEnumParamsSchema satisfies StandardSchemaV1<PgEnumParams>;
|
|
230
|
+
override renderValueLiteral(value: JsonValue): string | undefined {
|
|
231
|
+
return renderTsLiteral(value);
|
|
232
|
+
}
|
|
233
|
+
override metaFor(typeParams: JsonValue | undefined): CodecMeta | undefined {
|
|
234
|
+
if (!isJsonObject(typeParams)) return this.meta;
|
|
235
|
+
const typeName = typeParams['typeName'];
|
|
236
|
+
return typeof typeName === 'string'
|
|
237
|
+
? { db: { sql: { postgres: { nativeType: typeName } } } }
|
|
238
|
+
: this.meta;
|
|
239
|
+
}
|
|
240
|
+
override factory(_params: PgEnumParams): (ctx: CodecInstanceContext) => PgEnumCodec {
|
|
241
|
+
return () => new PgEnumCodec(this);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Authoring-time hook a `pg.enum(<ref>)` type constructor calls once it has
|
|
246
|
+
* resolved its ref argument to the referenced `native_enum` entity: given
|
|
247
|
+
* that entity and the field's namespace id, produces this codec's
|
|
248
|
+
* per-column `typeParams` and native type. The type name is schema-qualified
|
|
249
|
+
* for a named non-default schema (matching `format_type()`); `public` and
|
|
250
|
+
* the unbound namespace stay bare (`search_path`). `nativeType` mirrors
|
|
251
|
+
* `typeParams.typeName` — the same value {@link metaFor} derives at
|
|
252
|
+
* render time — so the column's declared native type and the render-time
|
|
253
|
+
* cast agree. Returns `undefined` if `entity` is not a `PostgresNativeEnum`
|
|
254
|
+
* (a contributor bug, not a user-schema error — the caller decides how to
|
|
255
|
+
* report it).
|
|
256
|
+
*/
|
|
257
|
+
columnFromEntity(
|
|
258
|
+
entity: object,
|
|
259
|
+
namespaceId?: string,
|
|
260
|
+
): { readonly typeParams: PgEnumParams; readonly nativeType: string } | undefined {
|
|
261
|
+
if (!PostgresNativeEnum.is(entity)) return undefined;
|
|
262
|
+
const qualifyNativeType =
|
|
263
|
+
namespaceId !== undefined &&
|
|
264
|
+
namespaceId !== DEFAULT_NAMESPACE_ID &&
|
|
265
|
+
namespaceId !== UNBOUND_NAMESPACE_ID;
|
|
266
|
+
const typeName = qualifyNativeType ? `${namespaceId}.${entity.typeName}` : entity.typeName;
|
|
267
|
+
return { typeParams: { typeName }, nativeType: typeName };
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
export const pgEnumDescriptor = new PgEnumDescriptor();
|
|
272
|
+
|
|
164
273
|
/**
|
|
165
274
|
* Postgres `text[]` codec. Encode is an identity pass-through: the pg wire
|
|
166
275
|
* driver serialises a JS `string[]` to a Postgres array literal under the
|
|
@@ -228,6 +337,9 @@ export class PgInt4Descriptor extends CodecDescriptorImpl<void> {
|
|
|
228
337
|
override readonly targetTypes = ['int4'] as const;
|
|
229
338
|
override readonly meta = PG_INT4_META;
|
|
230
339
|
override readonly paramsSchema: StandardSchemaV1<void> = voidParamsSchema;
|
|
340
|
+
override renderValueLiteral(value: JsonValue): string | undefined {
|
|
341
|
+
return renderTsLiteral(value);
|
|
342
|
+
}
|
|
231
343
|
override factory(): (ctx: CodecInstanceContext) => PgInt4Codec {
|
|
232
344
|
return () => new PgInt4Codec(this);
|
|
233
345
|
}
|
|
@@ -267,6 +379,9 @@ export class PgInt2Descriptor extends CodecDescriptorImpl<void> {
|
|
|
267
379
|
override readonly targetTypes = ['int2'] as const;
|
|
268
380
|
override readonly meta = PG_INT2_META;
|
|
269
381
|
override readonly paramsSchema: StandardSchemaV1<void> = voidParamsSchema;
|
|
382
|
+
override renderValueLiteral(value: JsonValue): string | undefined {
|
|
383
|
+
return renderTsLiteral(value);
|
|
384
|
+
}
|
|
270
385
|
override factory(): (ctx: CodecInstanceContext) => PgInt2Codec {
|
|
271
386
|
return () => new PgInt2Codec(this);
|
|
272
387
|
}
|
|
@@ -306,6 +421,9 @@ export class PgInt8Descriptor extends CodecDescriptorImpl<void> {
|
|
|
306
421
|
override readonly targetTypes = ['int8'] as const;
|
|
307
422
|
override readonly meta = PG_INT8_META;
|
|
308
423
|
override readonly paramsSchema: StandardSchemaV1<void> = voidParamsSchema;
|
|
424
|
+
override renderValueLiteral(value: JsonValue): string | undefined {
|
|
425
|
+
return renderTsLiteral(value);
|
|
426
|
+
}
|
|
309
427
|
override factory(): (ctx: CodecInstanceContext) => PgInt8Codec {
|
|
310
428
|
return () => new PgInt8Codec(this);
|
|
311
429
|
}
|
|
@@ -345,6 +463,9 @@ export class PgFloat4Descriptor extends CodecDescriptorImpl<void> {
|
|
|
345
463
|
override readonly targetTypes = ['float4'] as const;
|
|
346
464
|
override readonly meta = PG_FLOAT4_META;
|
|
347
465
|
override readonly paramsSchema: StandardSchemaV1<void> = voidParamsSchema;
|
|
466
|
+
override renderValueLiteral(value: JsonValue): string | undefined {
|
|
467
|
+
return renderTsLiteral(value);
|
|
468
|
+
}
|
|
348
469
|
override factory(): (ctx: CodecInstanceContext) => PgFloat4Codec {
|
|
349
470
|
return () => new PgFloat4Codec(this);
|
|
350
471
|
}
|
|
@@ -384,6 +505,9 @@ export class PgFloat8Descriptor extends CodecDescriptorImpl<void> {
|
|
|
384
505
|
override readonly targetTypes = ['float8'] as const;
|
|
385
506
|
override readonly meta = PG_FLOAT8_META;
|
|
386
507
|
override readonly paramsSchema: StandardSchemaV1<void> = voidParamsSchema;
|
|
508
|
+
override renderValueLiteral(value: JsonValue): string | undefined {
|
|
509
|
+
return renderTsLiteral(value);
|
|
510
|
+
}
|
|
387
511
|
override factory(): (ctx: CodecInstanceContext) => PgFloat8Codec {
|
|
388
512
|
return () => new PgFloat8Codec(this);
|
|
389
513
|
}
|
|
@@ -423,6 +547,9 @@ export class PgBoolDescriptor extends CodecDescriptorImpl<void> {
|
|
|
423
547
|
override readonly targetTypes = ['bool'] as const;
|
|
424
548
|
override readonly meta = PG_BOOL_META;
|
|
425
549
|
override readonly paramsSchema: StandardSchemaV1<void> = voidParamsSchema;
|
|
550
|
+
override renderValueLiteral(value: JsonValue): string | undefined {
|
|
551
|
+
return renderTsLiteral(value);
|
|
552
|
+
}
|
|
426
553
|
override factory(): (ctx: CodecInstanceContext) => PgBoolCodec {
|
|
427
554
|
return () => new PgBoolCodec(this);
|
|
428
555
|
}
|
|
@@ -968,6 +1095,9 @@ export class PgCharDescriptor extends CodecDescriptorImpl<LengthParams> {
|
|
|
968
1095
|
override renderOutputType(params: LengthParams): string | undefined {
|
|
969
1096
|
return sqlCharDescriptor.renderOutputType(params);
|
|
970
1097
|
}
|
|
1098
|
+
override renderValueLiteral(value: JsonValue): string | undefined {
|
|
1099
|
+
return renderTsLiteral(value);
|
|
1100
|
+
}
|
|
971
1101
|
override factory(_params: LengthParams): (ctx: CodecInstanceContext) => SqlCharCodec {
|
|
972
1102
|
return () => new SqlCharCodec(this);
|
|
973
1103
|
}
|
|
@@ -989,6 +1119,9 @@ export class PgVarcharDescriptor extends CodecDescriptorImpl<LengthParams> {
|
|
|
989
1119
|
override renderOutputType(params: LengthParams): string | undefined {
|
|
990
1120
|
return sqlVarcharDescriptor.renderOutputType(params);
|
|
991
1121
|
}
|
|
1122
|
+
override renderValueLiteral(value: JsonValue): string | undefined {
|
|
1123
|
+
return renderTsLiteral(value);
|
|
1124
|
+
}
|
|
992
1125
|
override factory(_params: LengthParams): (ctx: CodecInstanceContext) => SqlVarcharCodec {
|
|
993
1126
|
return () => new SqlVarcharCodec(this);
|
|
994
1127
|
}
|
|
@@ -1012,6 +1145,9 @@ export class PgIntDescriptor extends CodecDescriptorImpl<void> {
|
|
|
1012
1145
|
override readonly meta = PG_INT_META;
|
|
1013
1146
|
override readonly traits = sqlIntDescriptor.traits;
|
|
1014
1147
|
override readonly paramsSchema = sqlIntDescriptor.paramsSchema;
|
|
1148
|
+
override renderValueLiteral(value: JsonValue): string | undefined {
|
|
1149
|
+
return renderTsLiteral(value);
|
|
1150
|
+
}
|
|
1015
1151
|
override factory(): (ctx: CodecInstanceContext) => SqlIntCodec {
|
|
1016
1152
|
return () => new SqlIntCodec(this);
|
|
1017
1153
|
}
|
|
@@ -1030,6 +1166,9 @@ export class PgFloatDescriptor extends CodecDescriptorImpl<void> {
|
|
|
1030
1166
|
override readonly meta = PG_FLOAT_META;
|
|
1031
1167
|
override readonly traits = sqlFloatDescriptor.traits;
|
|
1032
1168
|
override readonly paramsSchema = sqlFloatDescriptor.paramsSchema;
|
|
1169
|
+
override renderValueLiteral(value: JsonValue): string | undefined {
|
|
1170
|
+
return renderTsLiteral(value);
|
|
1171
|
+
}
|
|
1033
1172
|
override factory(): (ctx: CodecInstanceContext) => SqlFloatCodec {
|
|
1034
1173
|
return () => new SqlFloatCodec(this);
|
|
1035
1174
|
}
|
|
@@ -1052,6 +1191,7 @@ export const codecDescriptors: readonly AnyCodecDescriptor[] = [
|
|
|
1052
1191
|
sqlTextDescriptor,
|
|
1053
1192
|
sqlTimestampDescriptor,
|
|
1054
1193
|
pgTextDescriptor,
|
|
1194
|
+
pgEnumDescriptor,
|
|
1055
1195
|
pgCharDescriptor,
|
|
1056
1196
|
pgVarcharDescriptor,
|
|
1057
1197
|
pgIntDescriptor,
|