@prisma-next/target-postgres 0.13.0-dev.25 → 0.13.0-dev.27
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/control.mjs +4 -4
- package/dist/{descriptor-meta-26XbSdrs.mjs → descriptor-meta-C7O6XHfh.mjs} +2 -2
- package/dist/{descriptor-meta-26XbSdrs.mjs.map → descriptor-meta-C7O6XHfh.mjs.map} +1 -1
- package/dist/{descriptor-meta-runtime-B5ZtrgVF.mjs → descriptor-meta-runtime-BToWdas9.mjs} +2 -2
- package/dist/descriptor-meta-runtime-BToWdas9.mjs.map +1 -0
- package/dist/{enum-planning-eI1gxdKF.mjs → enum-planning-D8z4FH7y.mjs} +2 -2
- package/dist/{enum-planning-eI1gxdKF.mjs.map → enum-planning-D8z4FH7y.mjs.map} +1 -1
- package/dist/enum-planning.mjs +1 -1
- package/dist/{issue-planner-BcVsU7Hh.mjs → issue-planner-CK-XWGB0.mjs} +19 -19
- package/dist/issue-planner-CK-XWGB0.mjs.map +1 -0
- package/dist/issue-planner.mjs +1 -1
- package/dist/migration.mjs +2 -2
- package/dist/{op-factory-call-CQQwTUTj.mjs → op-factory-call-CHvtj70z.mjs} +2 -2
- package/dist/{op-factory-call-CQQwTUTj.mjs.map → op-factory-call-CHvtj70z.mjs.map} +1 -1
- package/dist/op-factory-call.mjs +1 -1
- package/dist/pack.mjs +1 -1
- package/dist/{planner-B_o3sWWt.mjs → planner-4FbY_95H.mjs} +24 -12
- package/dist/planner-4FbY_95H.mjs.map +1 -0
- package/dist/{planner-produced-postgres-migration-UBDGd5v_.mjs → planner-produced-postgres-migration-qfkCkGVe.mjs} +2 -2
- package/dist/{planner-produced-postgres-migration-UBDGd5v_.mjs.map → planner-produced-postgres-migration-qfkCkGVe.mjs.map} +1 -1
- package/dist/planner-produced-postgres-migration.mjs +1 -1
- package/dist/{planner-sql-checks-CrAbk7gX.mjs → planner-sql-checks-BLgdXLsA.mjs} +2 -2
- package/dist/{planner-sql-checks-CrAbk7gX.mjs.map → planner-sql-checks-BLgdXLsA.mjs.map} +1 -1
- package/dist/planner-sql-checks.mjs +1 -1
- package/dist/planner.mjs +1 -1
- package/dist/{postgres-contract-serializer-BDbqgeFb.mjs → postgres-contract-serializer-CTxVcCVW.mjs} +38 -38
- package/dist/postgres-contract-serializer-CTxVcCVW.mjs.map +1 -0
- package/dist/postgres-enum-type-schema-DZBTtvBF.mjs +20 -0
- package/dist/postgres-enum-type-schema-DZBTtvBF.mjs.map +1 -0
- package/dist/{postgres-migration-BQ62jZR_.mjs → postgres-migration-DF5ApLqQ.mjs} +2 -2
- package/dist/{postgres-migration-BQ62jZR_.mjs.map → postgres-migration-DF5ApLqQ.mjs.map} +1 -1
- package/dist/{postgres-schema-BAgkIU9u.mjs → postgres-schema-C7c9rhGk.mjs} +36 -16
- package/dist/postgres-schema-C7c9rhGk.mjs.map +1 -0
- package/dist/runtime.d.mts +2 -0
- package/dist/runtime.d.mts.map +1 -1
- package/dist/runtime.mjs +2 -2
- package/dist/types.d.mts +26 -13
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs +3 -2
- package/package.json +17 -17
- package/src/core/authoring.ts +1 -1
- package/src/core/migrations/control-policy.ts +19 -7
- package/src/core/migrations/issue-planner.ts +1 -1
- package/src/core/migrations/planner-strategies.ts +8 -11
- package/src/core/postgres-contract-serializer.ts +75 -53
- package/src/core/postgres-enum-type-schema.ts +17 -0
- package/src/core/postgres-schema.ts +80 -46
- package/src/exports/types.ts +1 -0
- package/dist/descriptor-meta-runtime-B5ZtrgVF.mjs.map +0 -1
- package/dist/issue-planner-BcVsU7Hh.mjs.map +0 -1
- package/dist/planner-B_o3sWWt.mjs.map +0 -1
- package/dist/postgres-contract-serializer-BDbqgeFb.mjs.map +0 -1
- package/dist/postgres-schema-BAgkIU9u.mjs.map +0 -1
package/dist/types.d.mts
CHANGED
|
@@ -1,16 +1,30 @@
|
|
|
1
1
|
import { n as PostgresEnumTypeInput, t as PostgresEnumType } from "./postgres-enum-type-BVn63a89.mjs";
|
|
2
2
|
import { t as PostgresColumnDefault } from "./types-BDKkx8MA.mjs";
|
|
3
3
|
import { NamespaceBase } from "@prisma-next/framework-components/ir";
|
|
4
|
-
import { PostgresEnumStorageEntry, SqlNamespaceTablesInput, SqlStorage, StorageTable,
|
|
4
|
+
import { PostgresEnumStorageEntry, SqlNamespaceEntries, SqlNamespaceTablesInput, SqlStorage, StorageTable, StorageValueSet } from "@prisma-next/sql-contract/types";
|
|
5
5
|
|
|
6
|
+
//#region src/core/postgres-enum-type-schema.d.ts
|
|
7
|
+
/**
|
|
8
|
+
* Arktype validator for a `postgres-enum` entry under
|
|
9
|
+
* `storage.namespaces[id].entries.type[name]`. Registered by the Postgres
|
|
10
|
+
* target pack against the `'type'` entries key so the family-layer namespace
|
|
11
|
+
* validator accepts (and rejects) entries of this kind.
|
|
12
|
+
*/
|
|
13
|
+
declare const PostgresEnumTypeSchema: import("arktype/internal/variants/object.ts").ObjectType<{
|
|
14
|
+
kind: "postgres-enum";
|
|
15
|
+
values: readonly string[];
|
|
16
|
+
name?: string;
|
|
17
|
+
nativeType?: string;
|
|
18
|
+
control?: "managed" | "tolerated" | "external" | "observed";
|
|
19
|
+
}, {}>;
|
|
20
|
+
//#endregion
|
|
6
21
|
//#region src/core/postgres-schema.d.ts
|
|
22
|
+
type PostgresNamespaceEntries = SqlNamespaceEntries & {
|
|
23
|
+
readonly type?: Readonly<Record<string, PostgresEnumType>>;
|
|
24
|
+
};
|
|
7
25
|
interface PostgresSchemaInput {
|
|
8
26
|
readonly id: string;
|
|
9
|
-
readonly entries:
|
|
10
|
-
readonly table: Record<string, StorageTable | StorageTableInput>;
|
|
11
|
-
readonly type: Record<string, PostgresEnumType | PostgresEnumTypeInput>;
|
|
12
|
-
readonly valueSet?: Record<string, StorageValueSet | StorageValueSetInput>;
|
|
13
|
-
};
|
|
27
|
+
readonly entries: Readonly<Record<string, Readonly<Record<string, unknown>>>>;
|
|
14
28
|
}
|
|
15
29
|
/**
|
|
16
30
|
* Postgres target `Namespace` concretion — a Postgres schema (`CREATE
|
|
@@ -18,7 +32,7 @@ interface PostgresSchemaInput {
|
|
|
18
32
|
* `namespaces: Record<NamespaceId, PostgresSchema>` map populated by
|
|
19
33
|
* the Postgres PSL interpreter from `namespace { … }` AST buckets.
|
|
20
34
|
*
|
|
21
|
-
* `entries` holds entity-kind
|
|
35
|
+
* `entries` holds entity-kind maps (`table`, `type`). Qualifier
|
|
22
36
|
* emission is the rendering seam: DDL / SQL emission asks the namespace
|
|
23
37
|
* for its qualifier (`"<schema>"`) or for a qualified table name
|
|
24
38
|
* (`"<schema>"."<table>"`) and consumes the result polymorphically.
|
|
@@ -37,12 +51,11 @@ declare class PostgresSchema extends NamespaceBase {
|
|
|
37
51
|
static unbound: PostgresUnboundSchema;
|
|
38
52
|
readonly kind: 'schema';
|
|
39
53
|
readonly id: string;
|
|
40
|
-
readonly entries:
|
|
41
|
-
readonly table: Readonly<Record<string, StorageTable>>;
|
|
42
|
-
readonly type: Readonly<Record<string, PostgresEnumType>>;
|
|
43
|
-
readonly valueSet?: Readonly<Record<string, StorageValueSet>>;
|
|
44
|
-
}>;
|
|
54
|
+
readonly entries: PostgresNamespaceEntries;
|
|
45
55
|
constructor(input: PostgresSchemaInput);
|
|
56
|
+
get table(): Readonly<Record<string, StorageTable>>;
|
|
57
|
+
get type(): Readonly<Record<string, PostgresEnumType>>;
|
|
58
|
+
get valueSet(): Readonly<Record<string, StorageValueSet>> | undefined;
|
|
46
59
|
/**
|
|
47
60
|
* The bare schema qualifier as it would appear in a rendered SQL
|
|
48
61
|
* fragment (already quoted). The unbound-schema singleton overrides
|
|
@@ -124,5 +137,5 @@ declare class PostgresUnboundSchema extends PostgresSchema {
|
|
|
124
137
|
*/
|
|
125
138
|
declare function postgresCreateNamespace(input: SqlNamespaceTablesInput, enumTypes?: Readonly<Record<string, PostgresEnumStorageEntry>>): PostgresSchema;
|
|
126
139
|
//#endregion
|
|
127
|
-
export { type PostgresColumnDefault, PostgresEnumType, type PostgresEnumTypeInput, PostgresSchema, PostgresUnboundSchema, postgresCreateNamespace };
|
|
140
|
+
export { type PostgresColumnDefault, PostgresEnumType, type PostgresEnumTypeInput, PostgresEnumTypeSchema, PostgresSchema, PostgresUnboundSchema, postgresCreateNamespace };
|
|
128
141
|
//# sourceMappingURL=types.d.mts.map
|
package/dist/types.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.mts","names":[],"sources":["../src/core/postgres-schema.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.d.mts","names":[],"sources":["../src/core/postgres-enum-type-schema.ts","../src/core/postgres-schema.ts"],"mappings":";;;;;;;;;;;;cAUa,sBAAA,gDAAsB,UAAA;;;;;;;;;KCUvB,wBAAA,GAA2B,mBAAA;EAAA,SAC5B,IAAA,GAAO,QAAA,CAAS,MAAA,SAAe,gBAAA;AAAA;AAAA,UAGzB,mBAAA;EAAA,SACN,EAAA;EAAA,SACA,OAAA,EAAS,QAAA,CAAS,MAAA,SAAe,QAAA,CAAS,MAAA;AAAA;;;;;;;;;;;;AANrD;;;cAuBa,cAAA,SAAuB,aAAA;EAtBM;;;;;;;EAAA,OA8BjC,OAAA,EAAS,qBAAA;EAAA,SAEC,IAAA;EAAA,SACR,EAAA;EAAA,SACA,OAAA,EAAS,wBAAA;cAEN,KAAA,EAAO,mBAAA;EAAA,IAgEf,KAAA,IAAS,QAAA,CAAS,MAAA,SAAe,YAAA;EAAA,IAIjC,IAAA,IAAQ,QAAA,CAAS,MAAA,SAAe,gBAAA;EAAA,IAIhC,QAAA,IAAY,QAAA,CAAS,MAAA,SAAe,eAAA;EAvGW;;;;;EAgHnD,SAAA;EAjHS;;;;;;EA2HT,YAAA,CAAa,SAAA;EA1H4C;AAiB3D;;;;;EAmHE,eAAA,CAAgB,IAAA;EArCqB;;;;;;;;EAiDrC,mBAAA;EAewB;;;;;;;;;;;EAAxB,aAAA,CAAc,QAAA,EAAU,UAAA;AAAA;;;;;;;;;;;;;;;;;;;;cAwBb,qBAAA,SAA8B,cAAA;EAAA,gBACzB,QAAA,EAAU,qBAAA;cAEd,KAAA,GAAQ,mBAAA;EAIX,SAAA;EAIA,YAAA,CAAa,SAAA;EAIb,mBAAA;AAAA;;;;;;;;AAAmB;AA+B9B;;;iBAAgB,uBAAA,CACd,KAAA,EAAO,uBAAA,EACP,SAAA,GAAY,QAAA,CAAS,MAAA,SAAe,wBAAA,KACnC,cAAA"}
|
package/dist/types.mjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import { t as PostgresEnumType } from "./postgres-enum-type-DPKqCBem.mjs";
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import { t as PostgresEnumTypeSchema } from "./postgres-enum-type-schema-DZBTtvBF.mjs";
|
|
3
|
+
import { i as postgresCreateNamespace, n as PostgresUnboundSchema, t as PostgresSchema } from "./postgres-schema-C7c9rhGk.mjs";
|
|
4
|
+
export { PostgresEnumType, PostgresEnumTypeSchema, PostgresSchema, PostgresUnboundSchema, postgresCreateNamespace };
|
package/package.json
CHANGED
|
@@ -1,32 +1,32 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prisma-next/target-postgres",
|
|
3
|
-
"version": "0.13.0-dev.
|
|
3
|
+
"version": "0.13.0-dev.27",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"description": "Postgres target pack for Prisma Next",
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"@prisma-next/cli": "0.13.0-dev.
|
|
10
|
-
"@prisma-next/contract": "0.13.0-dev.
|
|
11
|
-
"@prisma-next/errors": "0.13.0-dev.
|
|
12
|
-
"@prisma-next/family-sql": "0.13.0-dev.
|
|
13
|
-
"@prisma-next/framework-components": "0.13.0-dev.
|
|
14
|
-
"@prisma-next/migration-tools": "0.13.0-dev.
|
|
15
|
-
"@prisma-next/ts-render": "0.13.0-dev.
|
|
16
|
-
"@prisma-next/sql-contract": "0.13.0-dev.
|
|
17
|
-
"@prisma-next/sql-errors": "0.13.0-dev.
|
|
18
|
-
"@prisma-next/sql-operations": "0.13.0-dev.
|
|
19
|
-
"@prisma-next/sql-relational-core": "0.13.0-dev.
|
|
20
|
-
"@prisma-next/sql-schema-ir": "0.13.0-dev.
|
|
21
|
-
"@prisma-next/utils": "0.13.0-dev.
|
|
9
|
+
"@prisma-next/cli": "0.13.0-dev.27",
|
|
10
|
+
"@prisma-next/contract": "0.13.0-dev.27",
|
|
11
|
+
"@prisma-next/errors": "0.13.0-dev.27",
|
|
12
|
+
"@prisma-next/family-sql": "0.13.0-dev.27",
|
|
13
|
+
"@prisma-next/framework-components": "0.13.0-dev.27",
|
|
14
|
+
"@prisma-next/migration-tools": "0.13.0-dev.27",
|
|
15
|
+
"@prisma-next/ts-render": "0.13.0-dev.27",
|
|
16
|
+
"@prisma-next/sql-contract": "0.13.0-dev.27",
|
|
17
|
+
"@prisma-next/sql-errors": "0.13.0-dev.27",
|
|
18
|
+
"@prisma-next/sql-operations": "0.13.0-dev.27",
|
|
19
|
+
"@prisma-next/sql-relational-core": "0.13.0-dev.27",
|
|
20
|
+
"@prisma-next/sql-schema-ir": "0.13.0-dev.27",
|
|
21
|
+
"@prisma-next/utils": "0.13.0-dev.27",
|
|
22
22
|
"@standard-schema/spec": "^1.1.0",
|
|
23
23
|
"arktype": "^2.2.0",
|
|
24
24
|
"pathe": "^2.0.3"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
|
-
"@prisma-next/test-utils": "0.13.0-dev.
|
|
28
|
-
"@prisma-next/tsconfig": "0.13.0-dev.
|
|
29
|
-
"@prisma-next/tsdown": "0.13.0-dev.
|
|
27
|
+
"@prisma-next/test-utils": "0.13.0-dev.27",
|
|
28
|
+
"@prisma-next/tsconfig": "0.13.0-dev.27",
|
|
29
|
+
"@prisma-next/tsdown": "0.13.0-dev.27",
|
|
30
30
|
"tsdown": "0.22.1",
|
|
31
31
|
"typescript": "5.9.3",
|
|
32
32
|
"vitest": "4.1.8"
|
package/src/core/authoring.ts
CHANGED
|
@@ -5,8 +5,8 @@ import type {
|
|
|
5
5
|
AuthoringTypeNamespace,
|
|
6
6
|
} from '@prisma-next/framework-components/authoring';
|
|
7
7
|
import type { PostgresEnumStorageEntry } from '@prisma-next/sql-contract/types';
|
|
8
|
-
import { PostgresEnumTypeSchema } from '@prisma-next/sql-contract/validators';
|
|
9
8
|
import { PostgresEnumType, type PostgresEnumTypeInput } from './postgres-enum-type';
|
|
9
|
+
import { PostgresEnumTypeSchema } from './postgres-enum-type-schema';
|
|
10
10
|
|
|
11
11
|
export const postgresAuthoringTypes = {} as const satisfies AuthoringTypeNamespace;
|
|
12
12
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { Contract } from '@prisma-next/contract/types';
|
|
2
2
|
import type { ControlPolicySubject } from '@prisma-next/family-sql/control';
|
|
3
3
|
import type { SchemaIssue } from '@prisma-next/framework-components/control';
|
|
4
|
-
import { UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';
|
|
4
|
+
import { entityAt, UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';
|
|
5
5
|
import {
|
|
6
6
|
isPostgresEnumStorageEntry,
|
|
7
7
|
type SqlStorage,
|
|
8
|
-
|
|
8
|
+
type StorageTable,
|
|
9
9
|
} from '@prisma-next/sql-contract/types';
|
|
10
10
|
import { ifDefined } from '@prisma-next/utils/defined';
|
|
11
11
|
import { isPostgresSchema } from '../postgres-schema';
|
|
@@ -43,7 +43,11 @@ function resolveNamespaceIdForTable(
|
|
|
43
43
|
ddlSchemaName: string | undefined,
|
|
44
44
|
): string {
|
|
45
45
|
for (const namespaceId of Object.keys(contract.storage.namespaces)) {
|
|
46
|
-
const table =
|
|
46
|
+
const table = entityAt<StorageTable>(contract.storage, {
|
|
47
|
+
namespaceId,
|
|
48
|
+
entityKind: 'table',
|
|
49
|
+
entityName: tableName,
|
|
50
|
+
});
|
|
47
51
|
if (!table) continue;
|
|
48
52
|
if (
|
|
49
53
|
ddlSchemaName === undefined ||
|
|
@@ -122,7 +126,7 @@ export function resolvePostgresCallControlPolicySubject(
|
|
|
122
126
|
? resolveNamespaceIdForDdlSchema(contract, callFields.schemaName)
|
|
123
127
|
: UNBOUND_NAMESPACE_ID;
|
|
124
128
|
const ns = contract.storage.namespaces[namespaceId];
|
|
125
|
-
const rawEnum = isPostgresSchema(ns) ? ns.
|
|
129
|
+
const rawEnum = isPostgresSchema(ns) ? ns.type[callFields.typeName] : undefined;
|
|
126
130
|
const controlPolicy = isPostgresEnumStorageEntry(rawEnum) ? rawEnum.control : undefined;
|
|
127
131
|
return {
|
|
128
132
|
namespaceId,
|
|
@@ -138,7 +142,11 @@ export function resolvePostgresCallControlPolicySubject(
|
|
|
138
142
|
callFields.tableName,
|
|
139
143
|
callFields.schemaName,
|
|
140
144
|
);
|
|
141
|
-
const table =
|
|
145
|
+
const table = entityAt<StorageTable>(contract.storage, {
|
|
146
|
+
namespaceId,
|
|
147
|
+
entityKind: 'table',
|
|
148
|
+
entityName: callFields.tableName,
|
|
149
|
+
});
|
|
142
150
|
const tableControlPolicy = table?.control;
|
|
143
151
|
return {
|
|
144
152
|
namespaceId,
|
|
@@ -205,7 +213,7 @@ export function resolvePostgresIssueControlPolicySubject(
|
|
|
205
213
|
const namespaceId =
|
|
206
214
|
'namespaceId' in issue && issue.namespaceId ? issue.namespaceId : UNBOUND_NAMESPACE_ID;
|
|
207
215
|
const ns = contract.storage.namespaces[namespaceId];
|
|
208
|
-
const rawEnum = isPostgresSchema(ns) ? ns.
|
|
216
|
+
const rawEnum = isPostgresSchema(ns) ? ns.type[issue.typeName] : undefined;
|
|
209
217
|
const controlPolicy = isPostgresEnumStorageEntry(rawEnum) ? rawEnum.control : undefined;
|
|
210
218
|
return {
|
|
211
219
|
namespaceId,
|
|
@@ -220,7 +228,11 @@ export function resolvePostgresIssueControlPolicySubject(
|
|
|
220
228
|
'namespaceId' in issue && issue.namespaceId
|
|
221
229
|
? issue.namespaceId
|
|
222
230
|
: resolveNamespaceIdForTable(contract, issue.table, undefined);
|
|
223
|
-
const table =
|
|
231
|
+
const table = entityAt<StorageTable>(contract.storage, {
|
|
232
|
+
namespaceId,
|
|
233
|
+
entityKind: 'table',
|
|
234
|
+
entityName: issue.table,
|
|
235
|
+
});
|
|
224
236
|
return {
|
|
225
237
|
namespaceId,
|
|
226
238
|
...ifDefined('explicitNodeControlPolicy', table?.control),
|
|
@@ -81,7 +81,7 @@ function locateNamespaceTypeInStorage(
|
|
|
81
81
|
typeName: string,
|
|
82
82
|
): unknown {
|
|
83
83
|
const ns = storage.namespaces[namespaceId];
|
|
84
|
-
return isPostgresSchema(ns) ? ns.
|
|
84
|
+
return isPostgresSchema(ns) ? ns.type[typeName] : undefined;
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
// ============================================================================
|
|
@@ -97,9 +97,9 @@ export function tableAt(
|
|
|
97
97
|
namespaceId: string,
|
|
98
98
|
tableName: string,
|
|
99
99
|
): StorageTable | undefined {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
return
|
|
100
|
+
const ns = storage.namespaces[namespaceId];
|
|
101
|
+
if (ns === undefined) return undefined;
|
|
102
|
+
return ns.entries.table?.[tableName];
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
/**
|
|
@@ -141,7 +141,7 @@ const DEFAULT_ENUM_NAMESPACE_ID = 'public';
|
|
|
141
141
|
function namespaceHasEnum(storage: SqlStorage, namespaceId: string, typeName: string): boolean {
|
|
142
142
|
const ns = storage.namespaces[namespaceId];
|
|
143
143
|
if (!isPostgresSchema(ns)) return false;
|
|
144
|
-
return ns.
|
|
144
|
+
return ns.type[typeName] !== undefined;
|
|
145
145
|
}
|
|
146
146
|
|
|
147
147
|
/**
|
|
@@ -463,8 +463,7 @@ function enumRebuildCallRecipe(
|
|
|
463
463
|
// same-named enums in distinct namespaces keep their columns disjoint.
|
|
464
464
|
const columnRefs: { namespaceId: string; table: string; column: string }[] = [];
|
|
465
465
|
for (const [nsId, ns] of Object.entries(ctx.toContract.storage.namespaces)) {
|
|
466
|
-
for (const [tableName,
|
|
467
|
-
const table = tableNode as StorageTable;
|
|
466
|
+
for (const [tableName, table] of Object.entries(ns.entries.table ?? {})) {
|
|
468
467
|
for (const [columnName, column] of Object.entries(table.columns)) {
|
|
469
468
|
if (
|
|
470
469
|
column.typeRef === typeName &&
|
|
@@ -667,9 +666,7 @@ function collectPostgresEnumTypes(storage: SqlStorage): ReadonlyMap<string, Post
|
|
|
667
666
|
const result = new Map<string, PostgresEnumType>();
|
|
668
667
|
for (const [nsId, ns] of Object.entries(storage.namespaces)) {
|
|
669
668
|
if (!isPostgresSchema(ns)) continue;
|
|
670
|
-
for (const [name, instance] of Object.entries(ns.
|
|
671
|
-
a.localeCompare(b),
|
|
672
|
-
)) {
|
|
669
|
+
for (const [name, instance] of Object.entries(ns.type).sort(([a], [b]) => a.localeCompare(b))) {
|
|
673
670
|
if (instance instanceof PostgresEnumType) {
|
|
674
671
|
result.set(enumCompoundKey(nsId, name), instance);
|
|
675
672
|
}
|
|
@@ -688,7 +685,7 @@ function collectContractChecks(
|
|
|
688
685
|
tableName: string,
|
|
689
686
|
): ReadonlyArray<{ name: string; column: string; permittedValues: readonly string[] }> {
|
|
690
687
|
const ns = storage.namespaces[namespaceId];
|
|
691
|
-
const tableRaw = ns
|
|
688
|
+
const tableRaw = ns !== undefined ? ns.entries.table?.[tableName] : undefined;
|
|
692
689
|
if (!(tableRaw instanceof StorageTable)) return [];
|
|
693
690
|
const checks = tableRaw.checks;
|
|
694
691
|
if (!checks || checks.length === 0) return [];
|
|
@@ -734,7 +731,7 @@ export const checkConstraintPlanCallStrategy: CallMigrationStrategy = (issues, c
|
|
|
734
731
|
const handledIssueKeys = new Set<string>();
|
|
735
732
|
|
|
736
733
|
for (const [namespaceId, ns] of Object.entries(ctx.toContract.storage.namespaces)) {
|
|
737
|
-
for (const tableName of Object.keys(ns.entries.table)) {
|
|
734
|
+
for (const tableName of Object.keys(ns.entries.table ?? {})) {
|
|
738
735
|
const contractChecks = collectContractChecks(ctx.toContract.storage, namespaceId, tableName);
|
|
739
736
|
if (contractChecks.length === 0) continue;
|
|
740
737
|
|
|
@@ -15,11 +15,12 @@ import {
|
|
|
15
15
|
UNBOUND_NAMESPACE_ID,
|
|
16
16
|
} from '@prisma-next/framework-components/ir';
|
|
17
17
|
import type { SqlNamespaceTablesInput, SqlStorage } from '@prisma-next/sql-contract/types';
|
|
18
|
-
import { blindCast } from '@prisma-next/utils/casts';
|
|
18
|
+
import { blindCast, castAs } from '@prisma-next/utils/casts';
|
|
19
19
|
import type { JsonObject } from '@prisma-next/utils/json';
|
|
20
20
|
import type { Type } from 'arktype';
|
|
21
21
|
import { postgresAuthoringEntityTypes } from './authoring';
|
|
22
22
|
import type { PostgresEnumType } from './postgres-enum-type';
|
|
23
|
+
import { PostgresEnumTypeSchema } from './postgres-enum-type-schema';
|
|
23
24
|
import { isPostgresSchema, PostgresSchema } from './postgres-schema';
|
|
24
25
|
|
|
25
26
|
const POSTGRES_AUTHORING_CTX: AuthoringEntityContext = {
|
|
@@ -38,27 +39,21 @@ function isAuthoringEntityTypeFactoryOutput(
|
|
|
38
39
|
}
|
|
39
40
|
|
|
40
41
|
/**
|
|
41
|
-
* Walks a pack's entity-type namespace tree and emits
|
|
42
|
-
*
|
|
43
|
-
*
|
|
42
|
+
* Walks a pack's entity-type namespace tree and emits hydration factories
|
|
43
|
+
* keyed by the descriptor's `discriminator`. Used for `storage.types`
|
|
44
|
+
* (codec-triple hydration). Namespace entries hydration dispatches by
|
|
45
|
+
* entries key, not discriminator — handled by `hydrateEntriesKind`.
|
|
44
46
|
*/
|
|
45
|
-
function
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
const entityTypeRegistry = new Map<string, SqlEntityHydrationFactory>();
|
|
50
|
-
const validatorFragments = new Map<string, Type<unknown>>();
|
|
47
|
+
function collectStorageTypesHydrators(
|
|
48
|
+
namespace: AuthoringEntityTypeNamespace,
|
|
49
|
+
): ReadonlyMap<string, SqlEntityHydrationFactory> {
|
|
50
|
+
const registry = new Map<string, SqlEntityHydrationFactory>();
|
|
51
51
|
const walk = (node: AuthoringEntityTypeNamespace): void => {
|
|
52
52
|
for (const value of Object.values(node)) {
|
|
53
53
|
if (isAuthoringEntityTypeDescriptor(value)) {
|
|
54
54
|
if (isAuthoringEntityTypeFactoryOutput(value.output)) {
|
|
55
55
|
const { factory } = value.output;
|
|
56
|
-
|
|
57
|
-
factory(raw, POSTGRES_AUTHORING_CTX),
|
|
58
|
-
);
|
|
59
|
-
}
|
|
60
|
-
if (value.validatorSchema !== undefined) {
|
|
61
|
-
validatorFragments.set(value.discriminator, value.validatorSchema);
|
|
56
|
+
registry.set(value.discriminator, (raw) => factory(raw, POSTGRES_AUTHORING_CTX));
|
|
62
57
|
}
|
|
63
58
|
continue;
|
|
64
59
|
}
|
|
@@ -68,15 +63,47 @@ function collectEntityRegistryContributions(namespace: AuthoringEntityTypeNamesp
|
|
|
68
63
|
}
|
|
69
64
|
};
|
|
70
65
|
walk(namespace);
|
|
71
|
-
return
|
|
66
|
+
return registry;
|
|
72
67
|
}
|
|
73
68
|
|
|
69
|
+
// Pack-contributed validator schemas keyed by entries key: postgres registers
|
|
70
|
+
// 'type' → the inner name→entry map schema. The family base composes these
|
|
71
|
+
// into the single registry alongside SQL core's 'table'/'valueSet' via
|
|
72
|
+
// createSqlEntrySchemaRegistry.
|
|
73
|
+
const POSTGRES_VALIDATOR_REGISTRY: ReadonlyMap<string, Type<unknown>> = new Map<
|
|
74
|
+
string,
|
|
75
|
+
Type<unknown>
|
|
76
|
+
>([['type', castAs<Type<unknown>>(PostgresEnumTypeSchema)]]);
|
|
77
|
+
|
|
74
78
|
export class PostgresContractSerializer extends SqlContractSerializerBase<Contract<SqlStorage>> {
|
|
79
|
+
private readonly enumFactory: SqlEntityHydrationFactory | undefined;
|
|
80
|
+
|
|
75
81
|
constructor() {
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
);
|
|
79
|
-
|
|
82
|
+
const storageTypesHydrators = collectStorageTypesHydrators(postgresAuthoringEntityTypes);
|
|
83
|
+
super(storageTypesHydrators, POSTGRES_VALIDATOR_REGISTRY);
|
|
84
|
+
this.enumFactory = storageTypesHydrators.get('postgres-enum');
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
protected override hydrateEntriesKind(
|
|
88
|
+
key: string,
|
|
89
|
+
innerMap: unknown,
|
|
90
|
+
): Record<string, unknown> | undefined {
|
|
91
|
+
if (key === 'type') {
|
|
92
|
+
if (innerMap === null || typeof innerMap !== 'object' || Array.isArray(innerMap)) {
|
|
93
|
+
return {};
|
|
94
|
+
}
|
|
95
|
+
return Object.fromEntries(
|
|
96
|
+
Object.entries(
|
|
97
|
+
blindCast<Record<string, unknown>, 'checked object, non-null, non-array above'>(innerMap),
|
|
98
|
+
).map(([name, entry]) => [
|
|
99
|
+
name,
|
|
100
|
+
blindCast<PostgresEnumType, 'postgres-enum factory returns PostgresEnumType'>(
|
|
101
|
+
this.enumFactory !== undefined ? this.enumFactory(entry) : entry,
|
|
102
|
+
),
|
|
103
|
+
]),
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
return super.hydrateEntriesKind(key, innerMap);
|
|
80
107
|
}
|
|
81
108
|
|
|
82
109
|
protected override hydrateSqlNamespaceEntry(
|
|
@@ -88,43 +115,38 @@ export class PostgresContractSerializer extends SqlContractSerializerBase<Contra
|
|
|
88
115
|
}
|
|
89
116
|
const hydrated = blindCast<
|
|
90
117
|
SqlNamespaceTablesInput,
|
|
91
|
-
'super.hydrateSqlNamespaceEntry returns
|
|
118
|
+
'super.hydrateSqlNamespaceEntry returns SqlNamespaceTablesInput when raw is not a NamespaceBase'
|
|
92
119
|
>(super.hydrateSqlNamespaceEntry(nsId, raw));
|
|
93
120
|
const { id, entries } = hydrated;
|
|
94
121
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
typeSlot = Object.fromEntries(
|
|
105
|
-
Object.entries(rawTypeSlot as Record<string, unknown>).map(([name, entry]) => [
|
|
106
|
-
name,
|
|
107
|
-
blindCast<PostgresEnumType, 'postgres-enum factory returns PostgresEnumType'>(
|
|
108
|
-
enumFactory !== undefined ? enumFactory(entry) : entry,
|
|
109
|
-
),
|
|
110
|
-
]),
|
|
111
|
-
);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
const valueSetSlot = entries.valueSet;
|
|
116
|
-
const hasValueSets = valueSetSlot !== undefined && Object.keys(valueSetSlot).length > 0;
|
|
117
|
-
const emptyTables = Object.keys(entries.table).length === 0;
|
|
118
|
-
const emptyTypes = !typeSlot || Object.keys(typeSlot).length === 0;
|
|
122
|
+
const typeEntries = blindCast<
|
|
123
|
+
Record<string, PostgresEnumType> | undefined,
|
|
124
|
+
'hydrateEntriesKind populates entries[type] with PostgresEnumType instances'
|
|
125
|
+
>(entries['type']);
|
|
126
|
+
const valueSetEntries = entries['valueSet'];
|
|
127
|
+
const hasValueSets = valueSetEntries !== undefined && Object.keys(valueSetEntries).length > 0;
|
|
128
|
+
const tableEntries = entries['table'] ?? {};
|
|
129
|
+
const emptyTables = Object.keys(tableEntries).length === 0;
|
|
130
|
+
const emptyTypes = !typeEntries || Object.keys(typeEntries).length === 0;
|
|
119
131
|
if (id === UNBOUND_NAMESPACE_ID && emptyTables && emptyTypes && !hasValueSets) {
|
|
120
132
|
return PostgresSchema.unbound;
|
|
121
133
|
}
|
|
122
134
|
return new PostgresSchema({
|
|
123
135
|
id,
|
|
124
136
|
entries: {
|
|
125
|
-
table:
|
|
126
|
-
|
|
127
|
-
|
|
137
|
+
table: blindCast<
|
|
138
|
+
Record<string, unknown>,
|
|
139
|
+
'table entries are StorageTable instances after base hydration'
|
|
140
|
+
>(tableEntries),
|
|
141
|
+
type: typeEntries ?? {},
|
|
142
|
+
...(hasValueSets
|
|
143
|
+
? {
|
|
144
|
+
valueSet: blindCast<
|
|
145
|
+
Record<string, unknown>,
|
|
146
|
+
'valueSet entries are StorageValueSet instances after base hydration'
|
|
147
|
+
>(valueSetEntries),
|
|
148
|
+
}
|
|
149
|
+
: {}),
|
|
128
150
|
},
|
|
129
151
|
});
|
|
130
152
|
}
|
|
@@ -142,7 +164,7 @@ export class PostgresContractSerializer extends SqlContractSerializerBase<Contra
|
|
|
142
164
|
kind: isUnboundSlot ? 'postgres-unbound-schema' : 'postgres-schema',
|
|
143
165
|
entries: {
|
|
144
166
|
table: Object.fromEntries(
|
|
145
|
-
Object.entries(ns.entries.table).map(([tableName, table]) => [
|
|
167
|
+
Object.entries(ns.entries.table ?? {}).map(([tableName, table]) => [
|
|
146
168
|
tableName,
|
|
147
169
|
this.serializeJsonValue(table) as JsonObject,
|
|
148
170
|
]),
|
|
@@ -170,14 +192,14 @@ export class PostgresContractSerializer extends SqlContractSerializerBase<Contra
|
|
|
170
192
|
|
|
171
193
|
private serializePostgresNamespace(ns: PostgresSchema, isUnboundSlot: boolean): JsonObject {
|
|
172
194
|
const tablesOut: Record<string, JsonObject> = {};
|
|
173
|
-
for (const [tableName, table] of Object.entries(ns.
|
|
195
|
+
for (const [tableName, table] of Object.entries(ns.table)) {
|
|
174
196
|
tablesOut[tableName] = this.serializeJsonValue(table) as JsonObject;
|
|
175
197
|
}
|
|
176
198
|
const typeOut: Record<string, JsonObject> = {};
|
|
177
|
-
for (const [typeName, ty] of Object.entries(ns.
|
|
199
|
+
for (const [typeName, ty] of Object.entries(ns.type)) {
|
|
178
200
|
typeOut[typeName] = this.serializeJsonValue(ty) as JsonObject;
|
|
179
201
|
}
|
|
180
|
-
const valueSetEntries = ns.
|
|
202
|
+
const valueSetEntries = ns.valueSet;
|
|
181
203
|
const valueSetOut: Record<string, JsonObject> = {};
|
|
182
204
|
if (valueSetEntries !== undefined) {
|
|
183
205
|
for (const [valueSetName, valueSet] of Object.entries(valueSetEntries)) {
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type } from 'arktype';
|
|
2
|
+
|
|
3
|
+
const ControlPolicySchema = type("'managed' | 'tolerated' | 'external' | 'observed'");
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Arktype validator for a `postgres-enum` entry under
|
|
7
|
+
* `storage.namespaces[id].entries.type[name]`. Registered by the Postgres
|
|
8
|
+
* target pack against the `'type'` entries key so the family-layer namespace
|
|
9
|
+
* validator accepts (and rejects) entries of this kind.
|
|
10
|
+
*/
|
|
11
|
+
export const PostgresEnumTypeSchema = type({
|
|
12
|
+
kind: "'postgres-enum'",
|
|
13
|
+
'name?': 'string',
|
|
14
|
+
'nativeType?': 'string',
|
|
15
|
+
values: type.string.array().readonly(),
|
|
16
|
+
'control?': ControlPolicySchema,
|
|
17
|
+
});
|