@prisma-next/target-postgres 0.14.0-dev.3 → 0.14.0-dev.31
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/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-types-DHCkwPKE.d.mts → codec-types-CueCoGD0.d.mts} +2 -2
- package/dist/{codec-types-DHCkwPKE.d.mts.map → codec-types-CueCoGD0.d.mts.map} +1 -1
- package/dist/codec-types.d.mts +1 -1
- package/dist/{codecs--0A5_4Bq.d.mts → codecs-Ca8upop6.d.mts} +12 -1
- package/dist/codecs-Ca8upop6.d.mts.map +1 -0
- package/dist/codecs.d.mts +1 -1
- package/dist/codecs.mjs +34 -1
- 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 +3 -3
- package/dist/control.d.mts +1 -1
- package/dist/control.d.mts.map +1 -1
- package/dist/control.mjs +11 -10
- 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-qKy1U5V9.d.mts} +2 -2
- package/dist/{data-transform-DDgWdB5o.d.mts.map → data-transform-qKy1U5V9.d.mts.map} +1 -1
- package/dist/data-transform.d.mts +1 -1
- package/dist/{ddl-QDyOSeLc.mjs → ddl-CGf6UABz.mjs} +62 -5
- package/dist/ddl-CGf6UABz.mjs.map +1 -0
- package/dist/ddl.d.mts +3 -2
- package/dist/ddl.mjs +2 -2
- package/dist/{default-normalizer-DyyCHQWs.mjs → default-normalizer-CzV8-QSu.mjs} +58 -2
- package/dist/default-normalizer-CzV8-QSu.mjs.map +1 -0
- package/dist/default-normalizer.d.mts +1 -1
- package/dist/default-normalizer.d.mts.map +1 -1
- package/dist/default-normalizer.mjs +1 -1
- package/dist/descriptor-meta-Dvvpu_jU.mjs +17 -0
- package/dist/descriptor-meta-Dvvpu_jU.mjs.map +1 -0
- package/dist/descriptor-meta-runtime-D5zHFKUz.mjs +228 -0
- package/dist/descriptor-meta-runtime-D5zHFKUz.mjs.map +1 -0
- package/dist/{issue-planner-DL6g3CmE.mjs → issue-planner-D5H1VuVP.mjs} +11 -9
- package/dist/issue-planner-D5H1VuVP.mjs.map +1 -0
- package/dist/issue-planner.d.mts +3 -3
- package/dist/issue-planner.d.mts.map +1 -1
- package/dist/issue-planner.mjs +1 -1
- package/dist/migration.d.mts +3 -3
- package/dist/migration.mjs +2 -2
- 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-DIdBDwmO.mjs} +199 -28
- package/dist/op-factory-call-DIdBDwmO.mjs.map +1 -0
- package/dist/{op-factory-call-DmQEc3XV.d.mts → op-factory-call-DPJR7tJc.d.mts} +44 -13
- package/dist/op-factory-call-DPJR7tJc.d.mts.map +1 -0
- package/dist/op-factory-call.d.mts +1 -1
- package/dist/op-factory-call.mjs +1 -1
- package/dist/pack.d.mts +74 -2
- package/dist/pack.d.mts.map +1 -1
- package/dist/pack.mjs +1 -1
- package/dist/{planner-Bs_baQax.mjs → planner-BnNEtGYM.mjs} +156 -24
- package/dist/planner-BnNEtGYM.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 +2 -4
- package/dist/planner-ddl-builders.d.mts.map +1 -1
- package/dist/planner-ddl-builders.mjs +2 -2
- package/dist/{planner-produced-postgres-migration-QqHa2C2l.d.mts → planner-produced-postgres-migration-BO-frvvN.d.mts} +3 -3
- package/dist/{planner-produced-postgres-migration-QqHa2C2l.d.mts.map → planner-produced-postgres-migration-BO-frvvN.d.mts.map} +1 -1
- package/dist/{planner-produced-postgres-migration-Cji5vxUf.mjs → planner-produced-postgres-migration-DzvdQ-7K.mjs} +2 -2
- package/dist/{planner-produced-postgres-migration-Cji5vxUf.mjs.map → planner-produced-postgres-migration-DzvdQ-7K.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-CyjaoKhm.mjs} +2 -2
- package/dist/{planner-sql-checks-jqUUGyQR.mjs.map → planner-sql-checks-CyjaoKhm.mjs.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 +31 -4
- package/dist/planner.d.mts.map +1 -1
- package/dist/planner.mjs +2 -2
- package/dist/{postgres-contract-serializer-k3TAcPMY.mjs → postgres-contract-serializer-tGMiJcl4.mjs} +30 -21
- package/dist/postgres-contract-serializer-tGMiJcl4.mjs.map +1 -0
- package/dist/{postgres-migration-B5jKrXv3.mjs → postgres-migration-C8JZyTSJ.mjs} +2 -2
- package/dist/{postgres-migration-B5jKrXv3.mjs.map → postgres-migration-C8JZyTSJ.mjs.map} +1 -1
- package/dist/{postgres-migration-Y4YBJqkS.d.mts → postgres-migration-Cs7zMOe1.d.mts} +5 -5
- package/dist/{postgres-migration-Y4YBJqkS.d.mts.map → postgres-migration-Cs7zMOe1.d.mts.map} +1 -1
- package/dist/postgres-rls-policy-12wAEQhs.d.mts +60 -0
- package/dist/postgres-rls-policy-12wAEQhs.d.mts.map +1 -0
- package/dist/postgres-schema-DJUEkWg-.d.mts +190 -0
- package/dist/postgres-schema-DJUEkWg-.d.mts.map +1 -0
- package/dist/{postgres-schema-COGZ1ark.mjs → postgres-schema-DLcc3W2-.mjs} +138 -5
- package/dist/postgres-schema-DLcc3W2-.mjs.map +1 -0
- package/dist/postgres-schema-ir-BJl_a3J7.d.mts +102 -0
- package/dist/postgres-schema-ir-BJl_a3J7.d.mts.map +1 -0
- package/dist/postgres-schema-ir-I_FiUndw.mjs +133 -0
- package/dist/postgres-schema-ir-I_FiUndw.mjs.map +1 -0
- package/dist/postgres-schema-ir-annotations-BbDSiwx2.mjs +14 -0
- package/dist/postgres-schema-ir-annotations-BbDSiwx2.mjs.map +1 -0
- package/dist/render-ops.d.mts +1 -1
- package/dist/rls-canonicalize.d.mts +2 -0
- package/dist/rls-canonicalize.mjs +2 -0
- package/dist/runtime.d.mts +5 -5
- package/dist/runtime.d.mts.map +1 -1
- package/dist/runtime.mjs +2 -2
- package/dist/schema-ir-annotations.d.mts +8 -0
- package/dist/schema-ir-annotations.d.mts.map +1 -0
- package/dist/schema-ir-annotations.mjs +2 -0
- package/dist/types.d.mts +4 -140
- package/dist/types.mjs +3 -2
- package/package.json +21 -17
- package/src/contract-free/checks.ts +73 -0
- package/src/contract-free/ddl.ts +45 -1
- package/src/core/authoring.ts +115 -1
- package/src/core/codecs.ts +35 -1
- package/src/core/ddl/nodes.ts +94 -2
- package/src/core/default-normalizer.ts +60 -2
- package/src/core/descriptor-meta.ts +4 -0
- package/src/core/entity-kinds.ts +16 -0
- package/src/core/migrations/bound-schema.ts +10 -0
- package/src/core/migrations/contract-to-postgres-schema-ir.ts +91 -0
- package/src/core/migrations/control-policy.ts +3 -0
- package/src/core/migrations/diff-postgres-schema.ts +55 -0
- package/src/core/migrations/issue-planner.ts +8 -0
- package/src/core/migrations/op-factory-call.ts +106 -21
- package/src/core/migrations/operations/columns.ts +24 -12
- package/src/core/migrations/operations/data-transform.ts +6 -0
- 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 +15 -56
- package/src/core/migrations/planner-recipes.ts +31 -13
- package/src/core/migrations/planner-strategies.ts +3 -11
- package/src/core/migrations/planner-target-details.ts +3 -1
- package/src/core/migrations/planner.ts +84 -1
- package/src/core/migrations/verify-postgres-namespaces.ts +12 -15
- package/src/core/postgres-contract-serializer.ts +48 -33
- package/src/core/postgres-schema.ts +37 -13
- package/src/core/postgres-validators.ts +20 -0
- package/src/core/rls/canonicalize.ts +48 -0
- package/src/core/schema-ir/postgres-rls-policy.ts +101 -0
- package/src/core/schema-ir/postgres-role.ts +52 -0
- package/src/core/schema-ir/postgres-schema-ir-annotations.ts +22 -0
- package/src/core/schema-ir/postgres-schema-ir.ts +138 -0
- package/src/core/schema-ir/postgres-table-ir.ts +96 -0
- package/src/exports/contract-free.ts +7 -1
- package/src/exports/control.ts +11 -12
- package/src/exports/ddl.ts +4 -0
- package/src/exports/planner-ddl-builders.ts +0 -2
- package/src/exports/planner.ts +5 -0
- package/src/exports/rls-canonicalize.ts +6 -0
- package/src/exports/schema-ir-annotations.ts +1 -0
- package/src/exports/types.ts +20 -0
- package/dist/codecs--0A5_4Bq.d.mts.map +0 -1
- package/dist/ddl-QDyOSeLc.mjs.map +0 -1
- 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.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.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-schema-COGZ1ark.mjs.map +0 -1
- package/dist/types.d.mts.map +0 -1
package/src/core/ddl/nodes.ts
CHANGED
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
DdlNode,
|
|
4
4
|
type DdlTableConstraint,
|
|
5
5
|
} from '@prisma-next/sql-relational-core/ast';
|
|
6
|
+
import type { RlsPolicyOperation } from '../rls/canonicalize';
|
|
6
7
|
|
|
7
8
|
// ---------------------------------------------------------------------------
|
|
8
9
|
// AlterTableAction — nested polymorphic hierarchy
|
|
@@ -10,6 +11,7 @@ import {
|
|
|
10
11
|
|
|
11
12
|
export interface AlterTableActionVisitor<R> {
|
|
12
13
|
addColumn(action: AddColumnAction): R;
|
|
14
|
+
dropDefault(action: DropDefaultAction): R;
|
|
13
15
|
}
|
|
14
16
|
|
|
15
17
|
export abstract class AlterTableAction {
|
|
@@ -32,7 +34,31 @@ export class AddColumnAction extends AlterTableAction {
|
|
|
32
34
|
}
|
|
33
35
|
}
|
|
34
36
|
|
|
35
|
-
export
|
|
37
|
+
export class DropDefaultAction extends AlterTableAction {
|
|
38
|
+
readonly kind = 'drop-default' as const;
|
|
39
|
+
readonly columnName: string;
|
|
40
|
+
|
|
41
|
+
constructor(columnName: string) {
|
|
42
|
+
super();
|
|
43
|
+
this.columnName = columnName;
|
|
44
|
+
Object.freeze(this);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
override accept<R>(visitor: AlterTableActionVisitor<R>): R {
|
|
48
|
+
return visitor.dropDefault(this);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* The set of ALTER TABLE subactions currently expressible as typed DDL.
|
|
54
|
+
*
|
|
55
|
+
* The remaining actions — SetDefault, SetNotNull, DropNotNull,
|
|
56
|
+
* AlterColumnType — are still emitted as raw SQL by `operations/columns.ts`
|
|
57
|
+
* and join this union as they are converted to typed DDL. Until then it is
|
|
58
|
+
* intentionally partial: only the ALTER subactions used by the
|
|
59
|
+
* already-converted ops (AddColumn, DropDefault) appear here.
|
|
60
|
+
*/
|
|
61
|
+
export type AnyAlterTableAction = AddColumnAction | DropDefaultAction;
|
|
36
62
|
|
|
37
63
|
// ---------------------------------------------------------------------------
|
|
38
64
|
// Top-level DDL visitor
|
|
@@ -42,6 +68,8 @@ export interface PostgresDdlVisitor<R> {
|
|
|
42
68
|
createTable(node: PostgresCreateTable): R;
|
|
43
69
|
createSchema(node: PostgresCreateSchema): R;
|
|
44
70
|
alterTable(node: PostgresAlterTable): R;
|
|
71
|
+
createPolicy(node: PostgresCreatePolicy): R;
|
|
72
|
+
dropPolicy(node: PostgresDropPolicy): R;
|
|
45
73
|
}
|
|
46
74
|
|
|
47
75
|
export abstract class PostgresDdlNode extends DdlNode {
|
|
@@ -127,4 +155,68 @@ export class PostgresAlterTable extends PostgresDdlNode {
|
|
|
127
155
|
}
|
|
128
156
|
}
|
|
129
157
|
|
|
130
|
-
export type
|
|
158
|
+
export type { RlsPolicyOperation };
|
|
159
|
+
|
|
160
|
+
export class PostgresCreatePolicy extends PostgresDdlNode {
|
|
161
|
+
readonly kind = 'create-policy' as const;
|
|
162
|
+
readonly schema: string;
|
|
163
|
+
readonly table: string;
|
|
164
|
+
readonly name: string;
|
|
165
|
+
readonly permissive: boolean;
|
|
166
|
+
readonly operation: RlsPolicyOperation;
|
|
167
|
+
readonly roles: ReadonlyArray<string>;
|
|
168
|
+
readonly using: string | undefined;
|
|
169
|
+
readonly withCheck: string | undefined;
|
|
170
|
+
|
|
171
|
+
constructor(options: {
|
|
172
|
+
readonly schema: string;
|
|
173
|
+
readonly table: string;
|
|
174
|
+
readonly name: string;
|
|
175
|
+
readonly permissive: boolean;
|
|
176
|
+
readonly operation: RlsPolicyOperation;
|
|
177
|
+
readonly roles: readonly string[];
|
|
178
|
+
readonly using?: string;
|
|
179
|
+
readonly withCheck?: string;
|
|
180
|
+
}) {
|
|
181
|
+
super();
|
|
182
|
+
this.schema = options.schema;
|
|
183
|
+
this.table = options.table;
|
|
184
|
+
this.name = options.name;
|
|
185
|
+
this.permissive = options.permissive;
|
|
186
|
+
this.operation = options.operation;
|
|
187
|
+
this.roles = Object.freeze([...options.roles]);
|
|
188
|
+
this.using = options.using;
|
|
189
|
+
this.withCheck = options.withCheck;
|
|
190
|
+
this.freeze();
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
override accept<R>(visitor: PostgresDdlVisitor<R>): R {
|
|
194
|
+
return visitor.createPolicy(this);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
export class PostgresDropPolicy extends PostgresDdlNode {
|
|
199
|
+
readonly kind = 'drop-policy' as const;
|
|
200
|
+
readonly schema: string;
|
|
201
|
+
readonly table: string;
|
|
202
|
+
readonly name: string;
|
|
203
|
+
|
|
204
|
+
constructor(options: { readonly schema: string; readonly table: string; readonly name: string }) {
|
|
205
|
+
super();
|
|
206
|
+
this.schema = options.schema;
|
|
207
|
+
this.table = options.table;
|
|
208
|
+
this.name = options.name;
|
|
209
|
+
this.freeze();
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
override accept<R>(visitor: PostgresDdlVisitor<R>): R {
|
|
213
|
+
return visitor.dropPolicy(this);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
export type AnyPostgresDdlNode =
|
|
218
|
+
| PostgresCreateTable
|
|
219
|
+
| PostgresCreateSchema
|
|
220
|
+
| PostgresAlterTable
|
|
221
|
+
| PostgresCreatePolicy
|
|
222
|
+
| PostgresDropPolicy;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ColumnDefault } from '@prisma-next/contract/types';
|
|
1
|
+
import type { ColumnDefault, JsonValue } from '@prisma-next/contract/types';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Pre-compiled regex patterns for performance.
|
|
@@ -18,6 +18,13 @@ const FALSE_PATTERN = /^false$/i;
|
|
|
18
18
|
const NUMERIC_PATTERN = /^-?\d+(\.\d+)?$/;
|
|
19
19
|
const STRING_LITERAL_PATTERN = /^'((?:[^']|'')*)'(?:::(?:"[^"]+"|[\w\s]+)(?:\(\d+\))?)?$/;
|
|
20
20
|
|
|
21
|
+
/**
|
|
22
|
+
* Matches a Postgres array literal default of the form `'{...}'::elemtype[]`.
|
|
23
|
+
* The literal body is captured in group 1; the cast (including `[]`) is optional.
|
|
24
|
+
* Examples: `'{}'::text[]`, `'{1,2}'::integer[]`, `'{}'`
|
|
25
|
+
*/
|
|
26
|
+
const ARRAY_LITERAL_PATTERN = /^'(\{.*\})'(?:::.+\[\])?$/;
|
|
27
|
+
|
|
21
28
|
/**
|
|
22
29
|
* Returns the canonical expression for a timestamp default function, or undefined
|
|
23
30
|
* if the expression is not a recognized timestamp default.
|
|
@@ -51,6 +58,46 @@ function canonicalizeTimestampDefault(expr: string): string | undefined {
|
|
|
51
58
|
return undefined;
|
|
52
59
|
}
|
|
53
60
|
|
|
61
|
+
/**
|
|
62
|
+
* Parses a Postgres array literal body (`{...}`) into a JS array of primitives.
|
|
63
|
+
* Returns undefined if the body cannot be reliably parsed.
|
|
64
|
+
*
|
|
65
|
+
* Handles:
|
|
66
|
+
* - `{}` → `[]`
|
|
67
|
+
* - `{elem1,elem2,...}` → `[elem1, elem2, ...]` with numeric and string element coercion
|
|
68
|
+
*/
|
|
69
|
+
function parseArrayLiteralBody(body: string): readonly JsonValue[] | undefined {
|
|
70
|
+
const inner = body.slice(1, -1).trim();
|
|
71
|
+
if (inner === '') return [];
|
|
72
|
+
const elements = inner.split(',');
|
|
73
|
+
const result: JsonValue[] = [];
|
|
74
|
+
for (const rawEl of elements) {
|
|
75
|
+
const el = rawEl.trim();
|
|
76
|
+
if (el.toUpperCase() === 'NULL') {
|
|
77
|
+
result.push(null);
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
if (el === 'true') {
|
|
81
|
+
result.push(true);
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
if (el === 'false') {
|
|
85
|
+
result.push(false);
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
if (NUMERIC_PATTERN.test(el)) {
|
|
89
|
+
result.push(Number(el));
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
if (el.startsWith('"') && el.endsWith('"')) {
|
|
93
|
+
result.push(el.slice(1, -1).replace(/""/g, '"'));
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
return undefined;
|
|
97
|
+
}
|
|
98
|
+
return result;
|
|
99
|
+
}
|
|
100
|
+
|
|
54
101
|
/**
|
|
55
102
|
* Parses a raw Postgres column default expression into a normalized ColumnDefault.
|
|
56
103
|
* This enables semantic comparison between contract defaults and introspected schema defaults.
|
|
@@ -59,7 +106,7 @@ function canonicalizeTimestampDefault(expr: string): string | undefined {
|
|
|
59
106
|
* keeping the introspection layer focused on faithful data capture.
|
|
60
107
|
*
|
|
61
108
|
* @param rawDefault - Raw default expression from information_schema.columns.column_default
|
|
62
|
-
* @param nativeType - Native column type, used for type-aware parsing (bigint
|
|
109
|
+
* @param nativeType - Native column type, used for type-aware parsing (array, bigint, JSON)
|
|
63
110
|
* @returns Normalized ColumnDefault or undefined if the expression cannot be parsed
|
|
64
111
|
*/
|
|
65
112
|
export function parsePostgresDefault(
|
|
@@ -69,11 +116,22 @@ export function parsePostgresDefault(
|
|
|
69
116
|
const trimmed = rawDefault.trim();
|
|
70
117
|
const normalizedType = nativeType?.toLowerCase();
|
|
71
118
|
const isBigInt = normalizedType === 'bigint' || normalizedType === 'int8';
|
|
119
|
+
const isArrayType = normalizedType?.endsWith('[]') ?? false;
|
|
72
120
|
|
|
73
121
|
if (NEXTVAL_PATTERN.test(trimmed)) {
|
|
74
122
|
return { kind: 'function', expression: 'autoincrement()' };
|
|
75
123
|
}
|
|
76
124
|
|
|
125
|
+
if (isArrayType) {
|
|
126
|
+
const arrayMatch = trimmed.match(ARRAY_LITERAL_PATTERN);
|
|
127
|
+
if (arrayMatch?.[1] !== undefined) {
|
|
128
|
+
const parsed = parseArrayLiteralBody(arrayMatch[1]);
|
|
129
|
+
if (parsed !== undefined) {
|
|
130
|
+
return { kind: 'literal', value: parsed };
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
77
135
|
const canonicalTimestamp = canonicalizeTimestampDefault(trimmed);
|
|
78
136
|
if (canonicalTimestamp) {
|
|
79
137
|
return { kind: 'function', expression: canonicalTimestamp };
|
|
@@ -2,9 +2,11 @@ import type { CodecTypes } from '../exports/codec-types';
|
|
|
2
2
|
import {
|
|
3
3
|
postgresAuthoringEntityTypes,
|
|
4
4
|
postgresAuthoringFieldPresets,
|
|
5
|
+
postgresAuthoringPslBlockDescriptors,
|
|
5
6
|
postgresAuthoringTypes,
|
|
6
7
|
} from './authoring';
|
|
7
8
|
import { postgresTargetDescriptorMetaRuntime } from './descriptor-meta-runtime';
|
|
9
|
+
import { postgresCreateNamespace } from './postgres-schema';
|
|
8
10
|
|
|
9
11
|
const postgresTargetDescriptorMetaBase = {
|
|
10
12
|
...postgresTargetDescriptorMetaRuntime,
|
|
@@ -13,6 +15,8 @@ const postgresTargetDescriptorMetaBase = {
|
|
|
13
15
|
type: postgresAuthoringTypes,
|
|
14
16
|
field: postgresAuthoringFieldPresets,
|
|
15
17
|
entityTypes: postgresAuthoringEntityTypes,
|
|
18
|
+
pslBlockDescriptors: postgresAuthoringPslBlockDescriptors,
|
|
19
|
+
createNamespace: postgresCreateNamespace,
|
|
16
20
|
},
|
|
17
21
|
} as const;
|
|
18
22
|
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { EntityKindDescriptor } from '@prisma-next/framework-components/ir';
|
|
2
|
+
import { PostgresRlsPolicySchema, PostgresRoleSchema } from './postgres-validators';
|
|
3
|
+
import { PostgresRlsPolicy, type PostgresRlsPolicyInput } from './schema-ir/postgres-rls-policy';
|
|
4
|
+
import { PostgresRole, type PostgresRoleInput } from './schema-ir/postgres-role';
|
|
5
|
+
|
|
6
|
+
export const policyEntityKind: EntityKindDescriptor<PostgresRlsPolicyInput, PostgresRlsPolicy> = {
|
|
7
|
+
kind: 'policy',
|
|
8
|
+
schema: PostgresRlsPolicySchema,
|
|
9
|
+
construct: (input) => new PostgresRlsPolicy(input),
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const roleEntityKind: EntityKindDescriptor<PostgresRoleInput, PostgresRole> = {
|
|
13
|
+
kind: 'role',
|
|
14
|
+
schema: PostgresRoleSchema,
|
|
15
|
+
construct: (input) => new PostgresRole(input),
|
|
16
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Maps a planner schema name to the contract-free DDL builder's optional
|
|
5
|
+
* `schema` field: the unbound sentinel becomes `undefined` (the builder omits
|
|
6
|
+
* the schema qualifier), every other name passes through.
|
|
7
|
+
*/
|
|
8
|
+
export function boundSchema(schemaName: string): string | undefined {
|
|
9
|
+
return schemaName === UNBOUND_NAMESPACE_ID ? undefined : schemaName;
|
|
10
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import type { ContractToSchemaIROptions } from '@prisma-next/family-sql/control';
|
|
2
|
+
import { contractToSchemaIR } from '@prisma-next/family-sql/control';
|
|
3
|
+
import { ifDefined } from '@prisma-next/utils/defined';
|
|
4
|
+
import type { PostgresContract } from '../postgres-schema';
|
|
5
|
+
import { isPostgresSchema } from '../postgres-schema';
|
|
6
|
+
import { PostgresRlsPolicy } from '../schema-ir/postgres-rls-policy';
|
|
7
|
+
import { PostgresSchemaIR } from '../schema-ir/postgres-schema-ir';
|
|
8
|
+
import { resolveDdlSchemaForNamespaceStorage } from '../schema-ir/postgres-schema-ir-annotations';
|
|
9
|
+
import { PostgresTableIR } from '../schema-ir/postgres-table-ir';
|
|
10
|
+
|
|
11
|
+
export function contractToPostgresSchemaIR(
|
|
12
|
+
contract: PostgresContract | null,
|
|
13
|
+
options: ContractToSchemaIROptions,
|
|
14
|
+
): PostgresSchemaIR {
|
|
15
|
+
const sqlIr = contractToSchemaIR(contract, options);
|
|
16
|
+
const ownedSchemas =
|
|
17
|
+
contract === null
|
|
18
|
+
? []
|
|
19
|
+
: Object.values(contract.storage.namespaces)
|
|
20
|
+
.filter((ns) => isPostgresSchema(ns))
|
|
21
|
+
.map((ns) => resolveDdlSchemaForNamespaceStorage(contract.storage, ns.id));
|
|
22
|
+
|
|
23
|
+
// Build a map of tableName → PostgresRlsPolicy[], resolving the DDL schema
|
|
24
|
+
// name once per namespace (not per policy).
|
|
25
|
+
const policiesByTable = new Map<string, PostgresRlsPolicy[]>();
|
|
26
|
+
if (contract !== null) {
|
|
27
|
+
for (const ns of Object.values(contract.storage.namespaces)) {
|
|
28
|
+
if (!isPostgresSchema(ns)) continue;
|
|
29
|
+
const resolvedSchema = resolveDdlSchemaForNamespaceStorage(contract.storage, ns.id);
|
|
30
|
+
for (const policy of Object.values(ns.policy)) {
|
|
31
|
+
const resolved =
|
|
32
|
+
resolvedSchema === policy.namespaceId
|
|
33
|
+
? policy
|
|
34
|
+
: new PostgresRlsPolicy({
|
|
35
|
+
name: policy.name,
|
|
36
|
+
prefix: policy.prefix,
|
|
37
|
+
tableName: policy.tableName,
|
|
38
|
+
namespaceId: resolvedSchema,
|
|
39
|
+
operation: policy.operation,
|
|
40
|
+
roles: [...policy.roles],
|
|
41
|
+
...ifDefined('using', policy.using),
|
|
42
|
+
...ifDefined('withCheck', policy.withCheck),
|
|
43
|
+
permissive: policy.permissive,
|
|
44
|
+
});
|
|
45
|
+
const list = policiesByTable.get(policy.tableName) ?? [];
|
|
46
|
+
list.push(resolved);
|
|
47
|
+
policiesByTable.set(policy.tableName, list);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Attach policies to each table from the relational projection. A policy that
|
|
53
|
+
// references a table absent from the schema IR is a malformed contract — the
|
|
54
|
+
// loop below throws rather than fabricating a stub table.
|
|
55
|
+
const tables: Record<string, PostgresTableIR> = {};
|
|
56
|
+
for (const [tableName, sqlTable] of Object.entries(sqlIr.tables)) {
|
|
57
|
+
tables[tableName] = new PostgresTableIR({
|
|
58
|
+
name: sqlTable.name,
|
|
59
|
+
columns: sqlTable.columns,
|
|
60
|
+
foreignKeys: sqlTable.foreignKeys,
|
|
61
|
+
uniques: sqlTable.uniques,
|
|
62
|
+
indexes: sqlTable.indexes,
|
|
63
|
+
...(sqlTable.primaryKey !== undefined ? { primaryKey: sqlTable.primaryKey } : {}),
|
|
64
|
+
...(sqlTable.annotations !== undefined ? { annotations: sqlTable.annotations } : {}),
|
|
65
|
+
...(sqlTable.checks !== undefined ? { checks: sqlTable.checks } : {}),
|
|
66
|
+
rlsPolicies: policiesByTable.get(tableName) ?? [],
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
for (const [tableName, policies] of policiesByTable) {
|
|
70
|
+
if (!(tableName in tables)) {
|
|
71
|
+
const policyName = policies[0]?.name ?? '(unknown)';
|
|
72
|
+
throw new Error(
|
|
73
|
+
`contract-to-postgres-schema-ir: policy "${policyName}" references table "${tableName}" not present in the schema`,
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return new PostgresSchemaIR({
|
|
79
|
+
tables,
|
|
80
|
+
roles:
|
|
81
|
+
contract === null
|
|
82
|
+
? []
|
|
83
|
+
: Object.values(contract.storage.namespaces).flatMap((ns) =>
|
|
84
|
+
isPostgresSchema(ns) ? Object.values(ns.role) : [],
|
|
85
|
+
),
|
|
86
|
+
pgSchemaName: 'public',
|
|
87
|
+
pgVersion: '',
|
|
88
|
+
existingSchemas: ownedSchemas,
|
|
89
|
+
nativeEnumTypeNames: [],
|
|
90
|
+
});
|
|
91
|
+
}
|
|
@@ -21,6 +21,8 @@ import type { PostgresOpFactoryCall } from './op-factory-call';
|
|
|
21
21
|
const OBJECT_CREATION_FACTORIES: ReadonlySet<string> = new Set<string>([
|
|
22
22
|
'createTable',
|
|
23
23
|
'createSchema',
|
|
24
|
+
'createRlsPolicy',
|
|
25
|
+
'enableRowLevelSecurity',
|
|
24
26
|
]);
|
|
25
27
|
|
|
26
28
|
function createsNewTopLevelObject(call: PostgresOpFactoryCall): boolean {
|
|
@@ -151,6 +153,7 @@ export function resolvePostgresCallControlPolicySubject(
|
|
|
151
153
|
const POSTGRES_ISSUE_CREATION_FACTORY: Readonly<Record<string, string>> = Object.freeze({
|
|
152
154
|
missing_schema: 'createSchema',
|
|
153
155
|
missing_table: 'createTable',
|
|
156
|
+
missing_rls_policy: 'createRlsPolicy',
|
|
154
157
|
});
|
|
155
158
|
|
|
156
159
|
export function resolvePostgresIssueCreationFactoryName(issue: SchemaIssue): string | undefined {
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { SchemaDiffIssue } from '@prisma-next/framework-components/control';
|
|
2
|
+
import { diffSchemas } from '@prisma-next/framework-components/control';
|
|
3
|
+
import { isPostgresRlsPolicy, type PostgresRlsPolicy } from '../schema-ir/postgres-rls-policy';
|
|
4
|
+
import { ensurePostgresSchemaIR, type PostgresSchemaIR } from '../schema-ir/postgres-schema-ir';
|
|
5
|
+
|
|
6
|
+
// Renders a display-only reference string for the diff message. If policy
|
|
7
|
+
// rendering grows, route it through the adapter's SQL renderer so the message
|
|
8
|
+
// can't diverge from the emitted policy SQL.
|
|
9
|
+
function renderPostgresPolicyReference(policy: PostgresRlsPolicy): string {
|
|
10
|
+
return `policy "${policy.name}" on "${policy.namespaceId}"."${policy.tableName}"`;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Computes schema drift between two derived schema IRs.
|
|
15
|
+
*
|
|
16
|
+
* 1. Runs the framework total diff.
|
|
17
|
+
* 2. Filters to policy-subject issues only — this is transitional: the generic
|
|
18
|
+
* differ walks the whole tree, but the legacy relational verifier still owns
|
|
19
|
+
* table/column drift, so non-policy issues are dropped here.
|
|
20
|
+
* 3. Remaps the message to a human-readable policy reference.
|
|
21
|
+
*
|
|
22
|
+
* Ownership filtering (dropping `extra` issues in namespaces a contract doesn't
|
|
23
|
+
* own) is the caller's responsibility — use `filterIssuesByOwnership`.
|
|
24
|
+
*/
|
|
25
|
+
export function diffPostgresSchema(
|
|
26
|
+
expected: PostgresSchemaIR,
|
|
27
|
+
actual: PostgresSchemaIR,
|
|
28
|
+
): readonly SchemaDiffIssue[] {
|
|
29
|
+
const safeActual = ensurePostgresSchemaIR(actual);
|
|
30
|
+
const issues = diffSchemas(expected, safeActual);
|
|
31
|
+
|
|
32
|
+
return issues
|
|
33
|
+
.filter((i) => isPostgresRlsPolicy(i.expected ?? i.actual))
|
|
34
|
+
.map((i) => {
|
|
35
|
+
const policy = i.expected ?? i.actual;
|
|
36
|
+
if (!isPostgresRlsPolicy(policy)) return i;
|
|
37
|
+
return { ...i, message: `${i.outcome}: ${renderPostgresPolicyReference(policy)}` };
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Filters `extra` policy issues to those in owned namespaces. Call after
|
|
43
|
+
* `diffPostgresSchema` with the union of namespace ids from the expected IR's
|
|
44
|
+
* policies and its `existingSchemas`.
|
|
45
|
+
*/
|
|
46
|
+
export function filterIssuesByOwnership(
|
|
47
|
+
issues: readonly SchemaDiffIssue[],
|
|
48
|
+
ownedSchemaNames: ReadonlySet<string>,
|
|
49
|
+
): readonly SchemaDiffIssue[] {
|
|
50
|
+
return issues.filter(
|
|
51
|
+
(i) =>
|
|
52
|
+
i.outcome !== 'extra' ||
|
|
53
|
+
(isPostgresRlsPolicy(i.actual) && ownedSchemaNames.has(i.actual.namespaceId)),
|
|
54
|
+
);
|
|
55
|
+
}
|
|
@@ -695,6 +695,8 @@ type CallCategory =
|
|
|
695
695
|
| 'dep'
|
|
696
696
|
| 'drop'
|
|
697
697
|
| 'table'
|
|
698
|
+
| 'rlsEnable'
|
|
699
|
+
| 'rlsPolicy'
|
|
698
700
|
| 'column'
|
|
699
701
|
| 'alter'
|
|
700
702
|
| 'primaryKey'
|
|
@@ -724,6 +726,12 @@ function classifyCall(call: PostgresOpFactoryCall): CallCategory {
|
|
|
724
726
|
return 'unique'; // after uniques, before indexes
|
|
725
727
|
case 'createTable':
|
|
726
728
|
return 'table';
|
|
729
|
+
case 'enableRowLevelSecurity':
|
|
730
|
+
return 'rlsEnable';
|
|
731
|
+
case 'createRlsPolicy':
|
|
732
|
+
return 'rlsPolicy';
|
|
733
|
+
case 'dropRlsPolicy':
|
|
734
|
+
return 'drop';
|
|
727
735
|
case 'addColumn':
|
|
728
736
|
return 'column';
|
|
729
737
|
case 'alterColumnType':
|
|
@@ -40,8 +40,10 @@ import { blindCast } from '@prisma-next/utils/casts';
|
|
|
40
40
|
import { ifDefined } from '@prisma-next/utils/defined';
|
|
41
41
|
import { columnExistsAst, tableExistsAst } from '../../contract-free/checks';
|
|
42
42
|
import * as contractFreeDdl from '../../contract-free/ddl';
|
|
43
|
+
import type { PostgresRlsPolicy } from '../schema-ir/postgres-rls-policy';
|
|
43
44
|
import { escapeLiteral, quoteIdentifier } from '../sql-utils';
|
|
44
45
|
import type { PostgresColumnDefault } from '../types';
|
|
46
|
+
import { boundSchema } from './bound-schema';
|
|
45
47
|
import {
|
|
46
48
|
addNotNullColumnDirect,
|
|
47
49
|
alterColumnType,
|
|
@@ -61,6 +63,7 @@ import {
|
|
|
61
63
|
} from './operations/constraints';
|
|
62
64
|
import { createExtension } from './operations/dependencies';
|
|
63
65
|
import { createIndex, dropIndex } from './operations/indexes';
|
|
66
|
+
import { createRlsPolicy, dropRlsPolicy, enableRowLevelSecurity } from './operations/rls';
|
|
64
67
|
import type { ForeignKeySpec } from './operations/shared';
|
|
65
68
|
import { step, targetDetails } from './operations/shared';
|
|
66
69
|
import { dropTable } from './operations/tables';
|
|
@@ -83,10 +86,6 @@ type Op = SqlMigrationPlanOperation<PostgresPlanTargetDetails>;
|
|
|
83
86
|
// transitive package on disk.
|
|
84
87
|
const POSTGRES_MIGRATION_FACADE = '@prisma-next/postgres/migration';
|
|
85
88
|
|
|
86
|
-
function boundSchema(schemaName: string): string | undefined {
|
|
87
|
-
return schemaName === UNBOUND_NAMESPACE_ID ? undefined : schemaName;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
89
|
abstract class PostgresOpFactoryCallNode extends TsExpression implements FrameworkOpFactoryCall {
|
|
91
90
|
abstract readonly factoryName: string;
|
|
92
91
|
abstract readonly operationClass: MigrationOperationClass;
|
|
@@ -684,10 +683,8 @@ export class DropDefaultCall extends PostgresOpFactoryCallNode {
|
|
|
684
683
|
|
|
685
684
|
/**
|
|
686
685
|
* Planner-internal call for adding a NOT NULL column (no contract default) to
|
|
687
|
-
* a table that must be empty at migration time. Carries the
|
|
688
|
-
*
|
|
689
|
-
* DDL) plus the parameters needed to lower the typed pre/postchecks at render
|
|
690
|
-
* time.
|
|
686
|
+
* a table that must be empty at migration time. Carries the typed `DdlColumn`
|
|
687
|
+
* and lowers it to an ADD COLUMN execute step via the adapter at `toOp` time.
|
|
691
688
|
*
|
|
692
689
|
* No authored `PostgresMigration` method: this call is only emitted by the
|
|
693
690
|
* planner, never hand-written by migration authors.
|
|
@@ -698,15 +695,15 @@ export class AddNotNullColumnDirectCall extends PostgresOpFactoryCallNode {
|
|
|
698
695
|
readonly schemaName: string;
|
|
699
696
|
readonly tableName: string;
|
|
700
697
|
readonly columnName: string;
|
|
701
|
-
readonly
|
|
698
|
+
readonly column: DdlColumn;
|
|
702
699
|
readonly label: string;
|
|
703
700
|
|
|
704
|
-
constructor(schemaName: string, tableName: string, columnName: string,
|
|
701
|
+
constructor(schemaName: string, tableName: string, columnName: string, column: DdlColumn) {
|
|
705
702
|
super();
|
|
706
703
|
this.schemaName = schemaName;
|
|
707
704
|
this.tableName = tableName;
|
|
708
705
|
this.columnName = columnName;
|
|
709
|
-
this.
|
|
706
|
+
this.column = column;
|
|
710
707
|
this.label = `Add column ${columnName} to ${tableName}`;
|
|
711
708
|
this.freeze();
|
|
712
709
|
}
|
|
@@ -717,13 +714,7 @@ export class AddNotNullColumnDirectCall extends PostgresOpFactoryCallNode {
|
|
|
717
714
|
`AddNotNullColumnDirectCall.toOp: a lowerer is required on the Postgres planner path (column "${this.columnName}" on table "${this.tableName}"). Pass the control adapter to createPostgresMigrationPlanner.`,
|
|
718
715
|
);
|
|
719
716
|
}
|
|
720
|
-
return addNotNullColumnDirect(
|
|
721
|
-
this.schemaName,
|
|
722
|
-
this.tableName,
|
|
723
|
-
this.columnName,
|
|
724
|
-
this.executeStepSql,
|
|
725
|
-
lowerer,
|
|
726
|
-
);
|
|
717
|
+
return addNotNullColumnDirect(this.schemaName, this.tableName, this.column, lowerer);
|
|
727
718
|
}
|
|
728
719
|
|
|
729
720
|
renderTypeScript(): string {
|
|
@@ -738,9 +729,9 @@ export class AddNotNullColumnDirectCall extends PostgresOpFactoryCallNode {
|
|
|
738
729
|
/**
|
|
739
730
|
* Planner-internal call for adding a NOT NULL column (no contract default)
|
|
740
731
|
* using a temporary default value for non-empty tables. Carries all parameters
|
|
741
|
-
* needed for `buildAddNotNullColumnWithTemporaryDefaultOperation`; the
|
|
742
|
-
* pre/postchecks are lowered
|
|
743
|
-
*
|
|
732
|
+
* needed for `buildAddNotNullColumnWithTemporaryDefaultOperation`; both the
|
|
733
|
+
* typed ADD COLUMN execute step and the pre/postchecks are lowered via the
|
|
734
|
+
* adapter at `toOp` time.
|
|
744
735
|
*
|
|
745
736
|
* No authored `PostgresMigration` method: this call is only emitted by the
|
|
746
737
|
* planner, never hand-written by migration authors.
|
|
@@ -1376,6 +1367,97 @@ export class DataTransformCall extends PostgresOpFactoryCallNode {
|
|
|
1376
1367
|
}
|
|
1377
1368
|
}
|
|
1378
1369
|
|
|
1370
|
+
export class CreatePostgresRlsPolicyCall extends PostgresOpFactoryCallNode {
|
|
1371
|
+
readonly factoryName = 'createRlsPolicy' as const;
|
|
1372
|
+
readonly operationClass = 'additive' as const;
|
|
1373
|
+
readonly schemaName: string;
|
|
1374
|
+
readonly tableName: string;
|
|
1375
|
+
readonly policy: PostgresRlsPolicy;
|
|
1376
|
+
readonly label: string;
|
|
1377
|
+
|
|
1378
|
+
constructor(schemaName: string, tableName: string, policy: PostgresRlsPolicy) {
|
|
1379
|
+
super();
|
|
1380
|
+
this.schemaName = schemaName;
|
|
1381
|
+
this.tableName = tableName;
|
|
1382
|
+
this.policy = policy;
|
|
1383
|
+
this.label = `Create RLS policy "${policy.name}" on "${tableName}"`;
|
|
1384
|
+
this.freeze();
|
|
1385
|
+
}
|
|
1386
|
+
|
|
1387
|
+
async toOp(lowerer?: ExecuteRequestLowerer): Promise<Op> {
|
|
1388
|
+
if (lowerer === undefined) {
|
|
1389
|
+
throw new Error(
|
|
1390
|
+
`CreatePostgresRlsPolicyCall.toOp: a lowerer is required on the Postgres planner path (policy "${this.policy.name}" on table "${this.tableName}"). Pass the control adapter to createPostgresMigrationPlanner.`,
|
|
1391
|
+
);
|
|
1392
|
+
}
|
|
1393
|
+
return createRlsPolicy(this.schemaName, this.tableName, this.policy, lowerer);
|
|
1394
|
+
}
|
|
1395
|
+
|
|
1396
|
+
renderTypeScript(): string {
|
|
1397
|
+
return `createRlsPolicy(${jsonToTsSource(this.schemaName)}, ${jsonToTsSource(this.tableName)}, ${jsonToTsSource(this.policy)})`;
|
|
1398
|
+
}
|
|
1399
|
+
}
|
|
1400
|
+
|
|
1401
|
+
export class DropPostgresRlsPolicyCall extends PostgresOpFactoryCallNode {
|
|
1402
|
+
readonly factoryName = 'dropRlsPolicy' as const;
|
|
1403
|
+
readonly operationClass = 'destructive' as const;
|
|
1404
|
+
readonly schemaName: string;
|
|
1405
|
+
readonly tableName: string;
|
|
1406
|
+
readonly policyName: string;
|
|
1407
|
+
readonly label: string;
|
|
1408
|
+
|
|
1409
|
+
constructor(schemaName: string, tableName: string, policyName: string) {
|
|
1410
|
+
super();
|
|
1411
|
+
this.schemaName = schemaName;
|
|
1412
|
+
this.tableName = tableName;
|
|
1413
|
+
this.policyName = policyName;
|
|
1414
|
+
this.label = `Drop RLS policy "${policyName}" on "${tableName}"`;
|
|
1415
|
+
this.freeze();
|
|
1416
|
+
}
|
|
1417
|
+
|
|
1418
|
+
async toOp(lowerer?: ExecuteRequestLowerer): Promise<Op> {
|
|
1419
|
+
if (lowerer === undefined) {
|
|
1420
|
+
throw new Error(
|
|
1421
|
+
`DropPostgresRlsPolicyCall.toOp: a lowerer is required on the Postgres planner path (policy "${this.policyName}" on table "${this.tableName}"). Pass the control adapter to createPostgresMigrationPlanner.`,
|
|
1422
|
+
);
|
|
1423
|
+
}
|
|
1424
|
+
return dropRlsPolicy(this.schemaName, this.tableName, this.policyName, lowerer);
|
|
1425
|
+
}
|
|
1426
|
+
|
|
1427
|
+
renderTypeScript(): string {
|
|
1428
|
+
return `dropRlsPolicy(${jsonToTsSource(this.schemaName)}, ${jsonToTsSource(this.tableName)}, ${jsonToTsSource(this.policyName)})`;
|
|
1429
|
+
}
|
|
1430
|
+
}
|
|
1431
|
+
|
|
1432
|
+
export class EnableRowLevelSecurityCall extends PostgresOpFactoryCallNode {
|
|
1433
|
+
readonly factoryName = 'enableRowLevelSecurity' as const;
|
|
1434
|
+
readonly operationClass = 'additive' as const;
|
|
1435
|
+
readonly schemaName: string;
|
|
1436
|
+
readonly tableName: string;
|
|
1437
|
+
readonly label: string;
|
|
1438
|
+
|
|
1439
|
+
constructor(schemaName: string, tableName: string) {
|
|
1440
|
+
super();
|
|
1441
|
+
this.schemaName = schemaName;
|
|
1442
|
+
this.tableName = tableName;
|
|
1443
|
+
this.label = `Enable row-level security on "${tableName}"`;
|
|
1444
|
+
this.freeze();
|
|
1445
|
+
}
|
|
1446
|
+
|
|
1447
|
+
async toOp(lowerer?: ExecuteRequestLowerer): Promise<Op> {
|
|
1448
|
+
if (lowerer === undefined) {
|
|
1449
|
+
throw new Error(
|
|
1450
|
+
`EnableRowLevelSecurityCall.toOp: a lowerer is required on the Postgres planner path (table "${this.tableName}"). Pass the control adapter to createPostgresMigrationPlanner.`,
|
|
1451
|
+
);
|
|
1452
|
+
}
|
|
1453
|
+
return enableRowLevelSecurity(this.schemaName, this.tableName, lowerer);
|
|
1454
|
+
}
|
|
1455
|
+
|
|
1456
|
+
renderTypeScript(): string {
|
|
1457
|
+
return `enableRowLevelSecurity(${jsonToTsSource(this.schemaName)}, ${jsonToTsSource(this.tableName)})`;
|
|
1458
|
+
}
|
|
1459
|
+
}
|
|
1460
|
+
|
|
1379
1461
|
export type PostgresOpFactoryCall =
|
|
1380
1462
|
| CreateTableCall
|
|
1381
1463
|
| DropTableCall
|
|
@@ -1399,4 +1481,7 @@ export type PostgresOpFactoryCall =
|
|
|
1399
1481
|
| RawSqlCall
|
|
1400
1482
|
| CreateExtensionCall
|
|
1401
1483
|
| CreateSchemaCall
|
|
1484
|
+
| CreatePostgresRlsPolicyCall
|
|
1485
|
+
| DropPostgresRlsPolicyCall
|
|
1486
|
+
| EnableRowLevelSecurityCall
|
|
1402
1487
|
| DataTransformCall;
|