@prisma-next/target-postgres 0.5.0-dev.8 → 0.5.0-dev.80
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/{codec-ids-CojIXVf9.mjs → codec-ids-C5qzBqus.mjs} +4 -4
- package/dist/{codec-ids-CojIXVf9.mjs.map → codec-ids-C5qzBqus.mjs.map} +1 -1
- package/dist/codec-ids-CplrEfmx.d.mts +29 -0
- package/dist/codec-ids-CplrEfmx.d.mts.map +1 -0
- package/dist/codec-ids.d.mts +2 -28
- package/dist/codec-ids.mjs +2 -3
- package/dist/codec-types-lrsb3N07.d.mts +79 -0
- package/dist/codec-types-lrsb3N07.d.mts.map +1 -0
- package/dist/codec-types.d.mts +2 -42
- package/dist/codec-types.mjs +1 -4
- package/dist/codecs-Cue97Xqf.d.mts +558 -0
- package/dist/codecs-Cue97Xqf.d.mts.map +1 -0
- package/dist/codecs.d.mts +13 -2
- package/dist/codecs.d.mts.map +1 -0
- package/dist/codecs.mjs +738 -3
- package/dist/codecs.mjs.map +1 -0
- package/dist/control.d.mts +1 -1
- package/dist/control.d.mts.map +1 -1
- package/dist/control.mjs +131 -94
- package/dist/control.mjs.map +1 -1
- package/dist/{data-transform-VfEGzXWt.mjs → data-transform-DKWXdHuZ.mjs} +25 -7
- package/dist/data-transform-DKWXdHuZ.mjs.map +1 -0
- package/dist/data-transform-bIeAcZIJ.d.mts +38 -0
- package/dist/data-transform-bIeAcZIJ.d.mts.map +1 -0
- package/dist/data-transform.d.mts +1 -1
- package/dist/data-transform.mjs +2 -3
- package/dist/{default-normalizer-DNOpRoOF.mjs → default-normalizer-C8XyZj85.mjs} +2 -2
- package/dist/{default-normalizer-DNOpRoOF.mjs.map → default-normalizer-C8XyZj85.mjs.map} +1 -1
- package/dist/default-normalizer.d.mts +0 -1
- package/dist/default-normalizer.d.mts.map +1 -1
- package/dist/default-normalizer.mjs +2 -3
- package/dist/descriptor-meta-Dde_BS3K.mjs +99 -0
- package/dist/descriptor-meta-Dde_BS3K.mjs.map +1 -0
- package/dist/{errors-AFvEPZ1R.mjs → errors-Chm2bKcS.mjs} +2 -3
- package/dist/{errors-AFvEPZ1R.mjs.map → errors-Chm2bKcS.mjs.map} +1 -1
- package/dist/errors.d.mts +0 -1
- package/dist/errors.d.mts.map +1 -1
- package/dist/errors.mjs +2 -3
- package/dist/{issue-planner-CFjB0_oO.mjs → issue-planner-B10B70JF.mjs} +9 -13
- package/dist/issue-planner-B10B70JF.mjs.map +1 -0
- package/dist/issue-planner.d.mts +2 -4
- package/dist/issue-planner.d.mts.map +1 -1
- package/dist/issue-planner.mjs +2 -3
- package/dist/migration.d.mts +3 -3
- package/dist/migration.d.mts.map +1 -1
- package/dist/migration.mjs +4 -5
- package/dist/migration.mjs.map +1 -1
- package/dist/{native-type-normalizer-CInai_oY.mjs → native-type-normalizer-Cry4QoLf.mjs} +2 -2
- package/dist/native-type-normalizer-Cry4QoLf.mjs.map +1 -0
- package/dist/native-type-normalizer.d.mts.map +1 -1
- package/dist/native-type-normalizer.mjs +2 -3
- package/dist/{op-factory-call-C3bWXKSP.d.mts → op-factory-call-CW8pzxmB.d.mts} +3 -4
- package/dist/op-factory-call-CW8pzxmB.d.mts.map +1 -0
- package/dist/{op-factory-call-BKlruaiC.mjs → op-factory-call-Cq8s4Fz1.mjs} +3 -4
- package/dist/{op-factory-call-BKlruaiC.mjs.map → op-factory-call-Cq8s4Fz1.mjs.map} +1 -1
- package/dist/op-factory-call.d.mts +1 -2
- package/dist/op-factory-call.mjs +2 -3
- package/dist/pack.d.mts +28 -9
- package/dist/pack.d.mts.map +1 -1
- package/dist/pack.mjs +2 -3
- package/dist/{planner-CLUvVhUN.mjs → planner-BvKUuqG-.mjs} +22 -16
- package/dist/planner-BvKUuqG-.mjs.map +1 -0
- package/dist/{planner-ddl-builders-Dxvw1LHw.mjs → planner-ddl-builders-CLB7Umhh.mjs} +4 -5
- package/dist/planner-ddl-builders-CLB7Umhh.mjs.map +1 -0
- package/dist/planner-ddl-builders.d.mts +1 -1
- package/dist/planner-ddl-builders.d.mts.map +1 -1
- package/dist/planner-ddl-builders.mjs +2 -3
- package/dist/{planner-identity-values-Dju-o5GF.mjs → planner-identity-values-DTx0gePL.mjs} +2 -3
- package/dist/{planner-identity-values-Dju-o5GF.mjs.map → planner-identity-values-DTx0gePL.mjs.map} +1 -1
- package/dist/planner-identity-values.d.mts +0 -1
- package/dist/planner-identity-values.d.mts.map +1 -1
- package/dist/planner-identity-values.mjs +2 -3
- package/dist/{planner-produced-postgres-migration-CRRTno6Z.d.mts → planner-produced-postgres-migration-CjxWIVgh.d.mts} +11 -7
- package/dist/planner-produced-postgres-migration-CjxWIVgh.d.mts.map +1 -0
- package/dist/{planner-produced-postgres-migration-DSSPq8QS.mjs → planner-produced-postgres-migration-DphktB2N.mjs} +16 -8
- package/dist/planner-produced-postgres-migration-DphktB2N.mjs.map +1 -0
- package/dist/planner-produced-postgres-migration.d.mts +1 -4
- package/dist/planner-produced-postgres-migration.mjs +2 -3
- package/dist/{planner-schema-lookup-B7lkypwn.mjs → planner-schema-lookup-B1ags8ys.mjs} +2 -2
- package/dist/{planner-schema-lookup-B7lkypwn.mjs.map → planner-schema-lookup-B1ags8ys.mjs.map} +1 -1
- package/dist/planner-schema-lookup.d.mts +0 -1
- package/dist/planner-schema-lookup.d.mts.map +1 -1
- package/dist/planner-schema-lookup.mjs +2 -3
- package/dist/{planner-sql-checks-7jkgm9TX.mjs → planner-sql-checks-DwZvGlV4.mjs} +3 -5
- package/dist/planner-sql-checks-DwZvGlV4.mjs.map +1 -0
- package/dist/planner-sql-checks.d.mts.map +1 -1
- package/dist/planner-sql-checks.mjs +2 -3
- package/dist/{planner-target-details-DH-azLu-.d.mts → planner-target-details-bVVcanWh.d.mts} +1 -1
- package/dist/planner-target-details-bVVcanWh.d.mts.map +1 -0
- package/dist/planner-target-details.d.mts +1 -1
- package/dist/planner-target-details.mjs +1 -1
- package/dist/planner.d.mts +21 -12
- package/dist/planner.d.mts.map +1 -1
- package/dist/planner.mjs +2 -4
- package/dist/{postgres-migration-qtmtbONe.mjs → postgres-migration-Bkv140RW.mjs} +4 -5
- package/dist/postgres-migration-Bkv140RW.mjs.map +1 -0
- package/dist/{postgres-migration-BjA3Zmts.d.mts → postgres-migration-UkcHfZAA.d.mts} +6 -6
- package/dist/postgres-migration-UkcHfZAA.d.mts.map +1 -0
- package/dist/render-ops--1nnfNus.mjs +23 -0
- package/dist/render-ops--1nnfNus.mjs.map +1 -0
- package/dist/render-ops.d.mts +3 -4
- package/dist/render-ops.d.mts.map +1 -1
- package/dist/render-ops.mjs +2 -3
- package/dist/{render-typescript-1rF_SB4g.mjs → render-typescript-D3doH-vX.mjs} +2 -14
- package/dist/render-typescript-D3doH-vX.mjs.map +1 -0
- package/dist/render-typescript.d.mts +3 -6
- package/dist/render-typescript.d.mts.map +1 -1
- package/dist/render-typescript.mjs +2 -3
- package/dist/runtime.d.mts +5 -9
- package/dist/runtime.d.mts.map +1 -1
- package/dist/runtime.mjs +7 -14
- package/dist/runtime.mjs.map +1 -1
- package/dist/{shared-Bxkt8pNO.d.mts → shared-MpwjwAjM.d.mts} +2 -2
- package/dist/shared-MpwjwAjM.d.mts.map +1 -0
- package/dist/{sql-utils-r-Lw535w.mjs → sql-utils-CggjWNij.mjs} +4 -2
- package/dist/sql-utils-CggjWNij.mjs.map +1 -0
- package/dist/sql-utils.d.mts.map +1 -1
- package/dist/sql-utils.mjs +2 -3
- package/dist/{statement-builders-BPnmt6wx.mjs → statement-builders-BT889jV0.mjs} +28 -13
- package/dist/statement-builders-BT889jV0.mjs.map +1 -0
- package/dist/statement-builders.d.mts +31 -3
- package/dist/statement-builders.d.mts.map +1 -1
- package/dist/statement-builders.mjs +2 -3
- package/dist/{tables-BmdW_FWO.mjs → tables-Ej122-iI.mjs} +4 -11
- package/dist/tables-Ej122-iI.mjs.map +1 -0
- package/dist/{types-ClK03Ojd.d.mts → types-CTqpysRY.d.mts} +1 -1
- package/dist/types-CTqpysRY.d.mts.map +1 -0
- package/dist/types.d.mts +1 -1
- package/dist/types.mjs +1 -1
- package/package.json +21 -19
- package/src/core/authoring.ts +5 -11
- package/src/core/codec-helpers.ts +135 -0
- package/src/core/codec-ids.ts +1 -0
- package/src/core/codec-type-map.ts +81 -0
- package/src/core/codecs.ts +941 -547
- package/src/core/descriptor-meta.ts +1 -1
- package/src/core/migrations/operations/data-transform.ts +86 -21
- package/src/core/migrations/planner-produced-postgres-migration.ts +17 -5
- package/src/core/migrations/planner.ts +62 -20
- package/src/core/migrations/postgres-migration.ts +3 -6
- package/src/core/migrations/render-ops.ts +26 -3
- package/src/core/migrations/render-typescript.ts +5 -9
- package/src/core/migrations/runner.ts +172 -151
- package/src/core/migrations/statement-builders.ts +49 -10
- package/src/core/registry.ts +11 -0
- package/src/exports/codec-types.ts +4 -13
- package/src/exports/codecs.ts +49 -2
- package/src/exports/runtime.ts +6 -11
- package/src/exports/statement-builders.ts +2 -1
- package/dist/codec-ids.d.mts.map +0 -1
- package/dist/codec-types.d.mts.map +0 -1
- package/dist/codecs-BQEm9_oo.d.mts +0 -319
- package/dist/codecs-BQEm9_oo.d.mts.map +0 -1
- package/dist/codecs-BoahtY_Q.mjs +0 -385
- package/dist/codecs-BoahtY_Q.mjs.map +0 -1
- package/dist/data-transform-CxFRBIUp.d.mts +0 -32
- package/dist/data-transform-CxFRBIUp.d.mts.map +0 -1
- package/dist/data-transform-VfEGzXWt.mjs.map +0 -1
- package/dist/descriptor-meta-BVoVtyp-.mjs +0 -120
- package/dist/descriptor-meta-BVoVtyp-.mjs.map +0 -1
- package/dist/issue-planner-CFjB0_oO.mjs.map +0 -1
- package/dist/native-type-normalizer-CInai_oY.mjs.map +0 -1
- package/dist/op-factory-call-C3bWXKSP.d.mts.map +0 -1
- package/dist/planner-CLUvVhUN.mjs.map +0 -1
- package/dist/planner-ddl-builders-Dxvw1LHw.mjs.map +0 -1
- package/dist/planner-produced-postgres-migration-CRRTno6Z.d.mts.map +0 -1
- package/dist/planner-produced-postgres-migration-DSSPq8QS.mjs.map +0 -1
- package/dist/planner-sql-checks-7jkgm9TX.mjs.map +0 -1
- package/dist/planner-target-details-DH-azLu-.d.mts.map +0 -1
- package/dist/postgres-migration-BjA3Zmts.d.mts.map +0 -1
- package/dist/postgres-migration-qtmtbONe.mjs.map +0 -1
- package/dist/render-ops-D6_DHdOK.mjs +0 -8
- package/dist/render-ops-D6_DHdOK.mjs.map +0 -1
- package/dist/render-typescript-1rF_SB4g.mjs.map +0 -1
- package/dist/shared-Bxkt8pNO.d.mts.map +0 -1
- package/dist/sql-utils-r-Lw535w.mjs.map +0 -1
- package/dist/statement-builders-BPnmt6wx.mjs.map +0 -1
- package/dist/tables-BmdW_FWO.mjs.map +0 -1
- package/dist/types-ClK03Ojd.d.mts.map +0 -1
- package/src/core/json-schema-type-expression.ts +0 -131
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ContractMarkerRecord } from '@prisma-next/contract/types';
|
|
2
2
|
import type {
|
|
3
3
|
MigrationOperationPolicy,
|
|
4
|
+
MultiSpaceRunnerResult,
|
|
4
5
|
SqlControlFamilyInstance,
|
|
5
6
|
SqlMigrationPlanContractInfo,
|
|
6
7
|
SqlMigrationPlanOperation,
|
|
@@ -9,21 +10,22 @@ import type {
|
|
|
9
10
|
SqlMigrationRunnerExecuteOptions,
|
|
10
11
|
SqlMigrationRunnerFailure,
|
|
11
12
|
SqlMigrationRunnerResult,
|
|
13
|
+
SqlMigrationRunnerSuccessValue,
|
|
12
14
|
} from '@prisma-next/family-sql/control';
|
|
13
15
|
import { runnerFailure, runnerSuccess } from '@prisma-next/family-sql/control';
|
|
14
16
|
import { verifySqlSchema } from '@prisma-next/family-sql/schema-verify';
|
|
15
|
-
import {
|
|
16
|
-
import
|
|
17
|
+
import type { ControlDriverInstance } from '@prisma-next/framework-components/control';
|
|
18
|
+
import { APP_SPACE_ID } from '@prisma-next/framework-components/control';
|
|
17
19
|
import { SqlQueryError } from '@prisma-next/sql-errors';
|
|
18
20
|
import { ifDefined } from '@prisma-next/utils/defined';
|
|
19
21
|
import type { Result } from '@prisma-next/utils/result';
|
|
20
|
-
import { ok, okVoid } from '@prisma-next/utils/result';
|
|
22
|
+
import { notOk, ok, okVoid } from '@prisma-next/utils/result';
|
|
21
23
|
import { parsePostgresDefault } from '../default-normalizer';
|
|
22
24
|
import { normalizeSchemaNativeType } from '../native-type-normalizer';
|
|
23
25
|
import type { PostgresPlanTargetDetails } from './planner-target-details';
|
|
24
26
|
import {
|
|
25
27
|
buildLedgerInsertStatement,
|
|
26
|
-
|
|
28
|
+
buildMergeMarkerStatements,
|
|
27
29
|
ensureLedgerTableStatement,
|
|
28
30
|
ensureMarkerTableStatement,
|
|
29
31
|
ensurePrismaContractSchemaStatement,
|
|
@@ -45,18 +47,6 @@ const DEFAULT_CONFIG: RunnerConfig = {
|
|
|
45
47
|
|
|
46
48
|
const LOCK_DOMAIN = 'prisma_next.contract.marker';
|
|
47
49
|
|
|
48
|
-
function isDataTransformOperation(op: unknown): op is DataTransformOperation {
|
|
49
|
-
return (
|
|
50
|
-
typeof op === 'object' &&
|
|
51
|
-
op !== null &&
|
|
52
|
-
'operationClass' in op &&
|
|
53
|
-
(op as { operationClass: string }).operationClass === 'data' &&
|
|
54
|
-
'name' in op &&
|
|
55
|
-
'check' in op &&
|
|
56
|
-
'run' in op
|
|
57
|
-
);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
50
|
/**
|
|
61
51
|
* Deep clones and freezes a record object to prevent mutation.
|
|
62
52
|
* Recursively clones nested objects and arrays to ensure complete isolation.
|
|
@@ -96,61 +86,98 @@ class PostgresMigrationRunner implements SqlMigrationRunner<PostgresPlanTargetDe
|
|
|
96
86
|
async execute(
|
|
97
87
|
options: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>,
|
|
98
88
|
): Promise<SqlMigrationRunnerResult> {
|
|
99
|
-
const schema = options.schemaName ?? this.config.defaultSchema;
|
|
100
89
|
const driver = options.driver;
|
|
101
|
-
const lockKey = `${LOCK_DOMAIN}:${schema}`;
|
|
102
90
|
|
|
103
|
-
// Static checks
|
|
91
|
+
// Static checks fail fast before any transaction work — no point
|
|
92
|
+
// burning a BEGIN/ROLLBACK round-trip on a destination-contract
|
|
93
|
+
// mismatch the caller can fix locally.
|
|
104
94
|
const destinationCheck = this.ensurePlanMatchesDestinationContract(
|
|
105
95
|
options.plan.destination,
|
|
106
96
|
options.destinationContract,
|
|
107
97
|
);
|
|
108
|
-
if (!destinationCheck.ok)
|
|
109
|
-
return destinationCheck;
|
|
110
|
-
}
|
|
98
|
+
if (!destinationCheck.ok) return destinationCheck;
|
|
111
99
|
|
|
112
100
|
const policyCheck = this.enforcePolicyCompatibility(options.policy, options.plan.operations);
|
|
113
|
-
if (!policyCheck.ok)
|
|
114
|
-
return policyCheck;
|
|
115
|
-
}
|
|
101
|
+
if (!policyCheck.ok) return policyCheck;
|
|
116
102
|
|
|
117
|
-
// Begin transaction for DB operations
|
|
118
103
|
await this.beginTransaction(driver);
|
|
119
104
|
let committed = false;
|
|
120
105
|
try {
|
|
121
|
-
await this.
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
// Validate plan origin matches existing marker (needs marker from DB)
|
|
126
|
-
const markerCheck = this.ensureMarkerCompatibility(existingMarker, options.plan);
|
|
127
|
-
if (!markerCheck.ok) {
|
|
128
|
-
return markerCheck;
|
|
106
|
+
const result = await this.executeOnConnection(options);
|
|
107
|
+
if (!result.ok) {
|
|
108
|
+
return result;
|
|
129
109
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
if (skipOperations) {
|
|
137
|
-
applyValue = { operationsExecuted: 0, executedOperations: [] };
|
|
138
|
-
} else {
|
|
139
|
-
const applyResult = await this.applyPlan(driver, options);
|
|
140
|
-
if (!applyResult.ok) {
|
|
141
|
-
return applyResult;
|
|
142
|
-
}
|
|
143
|
-
applyValue = applyResult.value;
|
|
110
|
+
await this.commitTransaction(driver);
|
|
111
|
+
committed = true;
|
|
112
|
+
return result;
|
|
113
|
+
} finally {
|
|
114
|
+
if (!committed) {
|
|
115
|
+
await this.rollbackTransaction(driver);
|
|
144
116
|
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Body of the migration runner without transaction management. The
|
|
122
|
+
* caller (single-space `execute(...)` above, or the multi-space
|
|
123
|
+
* outer-tx orchestrator at the SQL family level) owns the
|
|
124
|
+
* `BEGIN`/`COMMIT`/`ROLLBACK` lifecycle.
|
|
125
|
+
*/
|
|
126
|
+
async executeOnConnection(
|
|
127
|
+
options: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>,
|
|
128
|
+
): Promise<SqlMigrationRunnerResult> {
|
|
129
|
+
const schema = options.schemaName ?? this.config.defaultSchema;
|
|
130
|
+
const driver = options.driver;
|
|
131
|
+
if (options.space !== undefined && options.space !== options.plan.spaceId) {
|
|
132
|
+
throw new Error(
|
|
133
|
+
`SqlMigrationRunner: options.space (${options.space}) does not match plan.spaceId (${options.plan.spaceId})`,
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
const space = options.plan.spaceId;
|
|
137
|
+
const lockKey = `${LOCK_DOMAIN}:${schema}:${space}`;
|
|
145
138
|
|
|
146
|
-
|
|
147
|
-
|
|
139
|
+
// Static checks (idempotent — safe to run again when the caller is
|
|
140
|
+
// `execute(...)` because the cost is a single object comparison).
|
|
141
|
+
const destinationCheck = this.ensurePlanMatchesDestinationContract(
|
|
142
|
+
options.plan.destination,
|
|
143
|
+
options.destinationContract,
|
|
144
|
+
);
|
|
145
|
+
if (!destinationCheck.ok) return destinationCheck;
|
|
146
|
+
|
|
147
|
+
const policyCheck = this.enforcePolicyCompatibility(options.policy, options.plan.operations);
|
|
148
|
+
if (!policyCheck.ok) return policyCheck;
|
|
149
|
+
|
|
150
|
+
await this.acquireLock(driver, lockKey);
|
|
151
|
+
const ensureResult = await this.ensureControlTables(driver);
|
|
152
|
+
if (!ensureResult.ok) return ensureResult;
|
|
153
|
+
const existingMarker = await this.family.readMarker({ driver, space });
|
|
154
|
+
|
|
155
|
+
const markerCheck = this.ensureMarkerCompatibility(existingMarker, options.plan);
|
|
156
|
+
if (!markerCheck.ok) return markerCheck;
|
|
157
|
+
|
|
158
|
+
const markerAtDestination = this.markerMatchesDestination(existingMarker, options.plan);
|
|
159
|
+
const isSelfEdge = options.plan.origin?.storageHash === options.plan.destination.storageHash;
|
|
160
|
+
const skipOperations = markerAtDestination && options.plan.origin != null && !isSelfEdge;
|
|
161
|
+
let applyValue: ApplyPlanSuccessValue;
|
|
162
|
+
|
|
163
|
+
if (skipOperations) {
|
|
164
|
+
applyValue = { operationsExecuted: 0, executedOperations: [] };
|
|
165
|
+
} else {
|
|
166
|
+
const applyResult = await this.applyPlan(driver, options);
|
|
167
|
+
if (!applyResult.ok) return applyResult;
|
|
168
|
+
applyValue = applyResult.value;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Schema verification on app-space only — extension spaces don't
|
|
172
|
+
// own user-facing tables in the live schema, and `verifySqlSchema`
|
|
173
|
+
// matches the destination contract against the database, which
|
|
174
|
+
// would flag every app-space table as "extra" when called against
|
|
175
|
+
// an extension contract.
|
|
176
|
+
if (space === APP_SPACE_ID) {
|
|
148
177
|
const schemaIR = await this.family.introspect({
|
|
149
178
|
driver,
|
|
150
179
|
contract: options.destinationContract,
|
|
151
180
|
});
|
|
152
|
-
|
|
153
|
-
// Step 2: Pure verification (no DB I/O)
|
|
154
181
|
const schemaVerifyResult = verifySqlSchema({
|
|
155
182
|
contract: options.destinationContract,
|
|
156
183
|
schema: schemaIR,
|
|
@@ -164,22 +191,60 @@ class PostgresMigrationRunner implements SqlMigrationRunner<PostgresPlanTargetDe
|
|
|
164
191
|
if (!schemaVerifyResult.ok) {
|
|
165
192
|
return runnerFailure('SCHEMA_VERIFY_FAILED', schemaVerifyResult.summary, {
|
|
166
193
|
why: 'The resulting database schema does not satisfy the destination contract.',
|
|
167
|
-
meta: {
|
|
168
|
-
issues: schemaVerifyResult.schema.issues,
|
|
169
|
-
},
|
|
194
|
+
meta: { issues: schemaVerifyResult.schema.issues },
|
|
170
195
|
});
|
|
171
196
|
}
|
|
197
|
+
}
|
|
172
198
|
|
|
173
|
-
|
|
174
|
-
|
|
199
|
+
const incomingInvariants = options.plan.providedInvariants ?? [];
|
|
200
|
+
const existingInvariants = new Set(existingMarker?.invariants ?? []);
|
|
201
|
+
const incomingIsSubsetOfExisting = incomingInvariants.every((id) => existingInvariants.has(id));
|
|
202
|
+
const isSelfEdgeNoOp =
|
|
203
|
+
isSelfEdge && applyValue.operationsExecuted === 0 && incomingIsSubsetOfExisting;
|
|
204
|
+
|
|
205
|
+
if (!isSelfEdgeNoOp) {
|
|
206
|
+
await this.upsertMarker(driver, options, existingMarker, space);
|
|
175
207
|
await this.recordLedgerEntry(driver, options, existingMarker, applyValue.executedOperations);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return runnerSuccess({
|
|
211
|
+
operationsPlanned: options.plan.operations.length,
|
|
212
|
+
operationsExecuted: applyValue.operationsExecuted,
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
async executeAcrossSpaces(options: {
|
|
217
|
+
readonly driver: ControlDriverInstance<'sql', string>;
|
|
218
|
+
readonly perSpaceOptions: ReadonlyArray<
|
|
219
|
+
SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>
|
|
220
|
+
>;
|
|
221
|
+
}): Promise<MultiSpaceRunnerResult> {
|
|
222
|
+
const driver = options.driver;
|
|
223
|
+
const perSpaceOptions = options.perSpaceOptions;
|
|
224
|
+
|
|
225
|
+
if (perSpaceOptions.length === 0) {
|
|
226
|
+
return ok({ perSpaceResults: [] });
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
await this.beginTransaction(driver);
|
|
230
|
+
let committed = false;
|
|
231
|
+
try {
|
|
232
|
+
const perSpaceResults: Array<{
|
|
233
|
+
space: string;
|
|
234
|
+
value: SqlMigrationRunnerSuccessValue;
|
|
235
|
+
}> = [];
|
|
236
|
+
for (const spaceOptions of perSpaceOptions) {
|
|
237
|
+
const space = spaceOptions.space ?? spaceOptions.plan.spaceId;
|
|
238
|
+
const result = await this.executeOnConnection({ ...spaceOptions, driver, space });
|
|
239
|
+
if (!result.ok) {
|
|
240
|
+
return notOk({ ...result.failure, failingSpace: space });
|
|
241
|
+
}
|
|
242
|
+
perSpaceResults.push({ space, value: result.value });
|
|
243
|
+
}
|
|
176
244
|
|
|
177
245
|
await this.commitTransaction(driver);
|
|
178
246
|
committed = true;
|
|
179
|
-
return
|
|
180
|
-
operationsPlanned: options.plan.operations.length,
|
|
181
|
-
operationsExecuted: applyValue.operationsExecuted,
|
|
182
|
-
});
|
|
247
|
+
return ok({ perSpaceResults });
|
|
183
248
|
} finally {
|
|
184
249
|
if (!committed) {
|
|
185
250
|
await this.rollbackTransaction(driver);
|
|
@@ -201,19 +266,6 @@ class PostgresMigrationRunner implements SqlMigrationRunner<PostgresPlanTargetDe
|
|
|
201
266
|
for (const operation of options.plan.operations) {
|
|
202
267
|
options.callbacks?.onOperationStart?.(operation);
|
|
203
268
|
try {
|
|
204
|
-
// Data transform operations have a different execution lifecycle
|
|
205
|
-
if (operation.operationClass === 'data' && isDataTransformOperation(operation)) {
|
|
206
|
-
const dtResult = await this.executeDataTransform(driver, operation, {
|
|
207
|
-
runIdempotency,
|
|
208
|
-
});
|
|
209
|
-
if (!dtResult.ok) {
|
|
210
|
-
return dtResult;
|
|
211
|
-
}
|
|
212
|
-
executedOperations.push(operation);
|
|
213
|
-
operationsExecuted += 1;
|
|
214
|
-
continue;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
269
|
// Idempotency probe: only run if both postchecks and idempotency checks are enabled
|
|
218
270
|
if (runPostchecks && runIdempotency) {
|
|
219
271
|
const postcheckAlreadySatisfied = await this.expectationsAreSatisfied(
|
|
@@ -266,86 +318,51 @@ class PostgresMigrationRunner implements SqlMigrationRunner<PostgresPlanTargetDe
|
|
|
266
318
|
return ok({ operationsExecuted, executedOperations });
|
|
267
319
|
}
|
|
268
320
|
|
|
269
|
-
|
|
270
|
-
* Executes a data transform operation with the check → (skip or run) → check lifecycle.
|
|
271
|
-
*
|
|
272
|
-
* 1. If check is a query AST: render to SQL, execute. Empty result = already applied (skip).
|
|
273
|
-
* 2. If check is `true`: always skip. If `false`: always run.
|
|
274
|
-
* 3. Execute run ASTs (rendered to SQL) sequentially.
|
|
275
|
-
* 4. Re-execute check as post-run validation. If violations remain, fail.
|
|
276
|
-
*/
|
|
277
|
-
private async executeDataTransform(
|
|
321
|
+
private async ensureControlTables(
|
|
278
322
|
driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],
|
|
279
|
-
op: DataTransformOperation,
|
|
280
|
-
options: { runIdempotency: boolean },
|
|
281
323
|
): Promise<Result<void, SqlMigrationRunnerFailure>> {
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
// No violations — already applied, skip
|
|
291
|
-
return okVoid();
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
// Step 2: Execute run steps
|
|
296
|
-
if (op.run) {
|
|
297
|
-
for (const plan of op.run) {
|
|
298
|
-
try {
|
|
299
|
-
await driver.query(plan.sql, plan.params);
|
|
300
|
-
} catch (error: unknown) {
|
|
301
|
-
if (SqlQueryError.is(error)) {
|
|
302
|
-
return runnerFailure(
|
|
303
|
-
'EXECUTION_FAILED',
|
|
304
|
-
`Data transform "${op.name}" failed: ${error.message}`,
|
|
305
|
-
{
|
|
306
|
-
why: error.message,
|
|
307
|
-
meta: {
|
|
308
|
-
operationId: op.id,
|
|
309
|
-
dataTransformName: op.name,
|
|
310
|
-
sql: plan.sql,
|
|
311
|
-
sqlState: error.sqlState,
|
|
312
|
-
},
|
|
313
|
-
},
|
|
314
|
-
);
|
|
315
|
-
}
|
|
316
|
-
throw error;
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
// Step 3: Post-run validation (check again)
|
|
322
|
-
if (op.check !== null && op.check !== false) {
|
|
323
|
-
const checkResult = await driver.query(op.check.sql, op.check.params);
|
|
324
|
-
if (checkResult.rows.length > 0) {
|
|
325
|
-
return runnerFailure(
|
|
326
|
-
'POSTCHECK_FAILED',
|
|
327
|
-
`Data transform "${op.name}" did not resolve all violations (${checkResult.rows.length} remaining)`,
|
|
328
|
-
{
|
|
329
|
-
why: `After executing the data transform, the check query still returns ${checkResult.rows.length} violation(s).`,
|
|
330
|
-
meta: {
|
|
331
|
-
operationId: op.id,
|
|
332
|
-
dataTransformName: op.name,
|
|
333
|
-
remainingViolations: checkResult.rows.length,
|
|
334
|
-
},
|
|
335
|
-
},
|
|
336
|
-
);
|
|
337
|
-
}
|
|
324
|
+
await this.executeStatement(driver, ensurePrismaContractSchemaStatement);
|
|
325
|
+
// Pre-1.0 zero-range guardrail: detect a pre-cleanup single-row
|
|
326
|
+
// marker table (no `space` column) and surface a structured failure
|
|
327
|
+
// rather than silently auto-migrating it to the per-space shape.
|
|
328
|
+
// See `specs/framework-mechanism.spec.md § 2`.
|
|
329
|
+
const legacyDetection = await this.detectLegacyMarkerShape(driver);
|
|
330
|
+
if (!legacyDetection.ok) {
|
|
331
|
+
return legacyDetection;
|
|
338
332
|
}
|
|
339
|
-
|
|
333
|
+
await this.executeStatement(driver, ensureMarkerTableStatement);
|
|
334
|
+
await this.executeStatement(driver, ensureLedgerTableStatement);
|
|
340
335
|
return okVoid();
|
|
341
336
|
}
|
|
342
337
|
|
|
343
|
-
private async
|
|
338
|
+
private async detectLegacyMarkerShape(
|
|
344
339
|
driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],
|
|
345
|
-
): Promise<void
|
|
346
|
-
await
|
|
347
|
-
|
|
348
|
-
|
|
340
|
+
): Promise<Result<void, SqlMigrationRunnerFailure>> {
|
|
341
|
+
const result = await driver.query<{ column_name: string }>(
|
|
342
|
+
`select column_name
|
|
343
|
+
from information_schema.columns
|
|
344
|
+
where table_schema = 'prisma_contract'
|
|
345
|
+
and table_name = 'marker'`,
|
|
346
|
+
);
|
|
347
|
+
if (result.rows.length === 0) {
|
|
348
|
+
return okVoid();
|
|
349
|
+
}
|
|
350
|
+
const columns = new Set(result.rows.map((row) => row.column_name));
|
|
351
|
+
if (columns.has('space')) {
|
|
352
|
+
return okVoid();
|
|
353
|
+
}
|
|
354
|
+
return runnerFailure(
|
|
355
|
+
'LEGACY_MARKER_SHAPE',
|
|
356
|
+
'Legacy marker-table shape detected on prisma_contract.marker (no `space` column). ' +
|
|
357
|
+
'Prisma Next is in pre-1.0; the previous transitional auto-migration to the per-space-row schema has been removed. ' +
|
|
358
|
+
'Drop `prisma_contract.marker` and re-run `dbInit` to reinitialise from a clean baseline.',
|
|
359
|
+
{
|
|
360
|
+
meta: {
|
|
361
|
+
table: 'prisma_contract.marker',
|
|
362
|
+
columns: [...columns].sort(),
|
|
363
|
+
},
|
|
364
|
+
},
|
|
365
|
+
);
|
|
349
366
|
}
|
|
350
367
|
|
|
351
368
|
private async runExpectationSteps(
|
|
@@ -355,7 +372,7 @@ class PostgresMigrationRunner implements SqlMigrationRunner<PostgresPlanTargetDe
|
|
|
355
372
|
phase: 'precheck' | 'postcheck',
|
|
356
373
|
): Promise<Result<void, SqlMigrationRunnerFailure>> {
|
|
357
374
|
for (const step of steps) {
|
|
358
|
-
const result = await driver.query(step.sql);
|
|
375
|
+
const result = await driver.query(step.sql, step.params ?? []);
|
|
359
376
|
if (!this.stepResultIsTrue(result.rows)) {
|
|
360
377
|
const code = phase === 'precheck' ? 'PRECHECK_FAILED' : 'POSTCHECK_FAILED';
|
|
361
378
|
return runnerFailure(
|
|
@@ -381,7 +398,7 @@ class PostgresMigrationRunner implements SqlMigrationRunner<PostgresPlanTargetDe
|
|
|
381
398
|
): Promise<Result<void, SqlMigrationRunnerFailure>> {
|
|
382
399
|
for (const step of steps) {
|
|
383
400
|
try {
|
|
384
|
-
await driver.query(step.sql);
|
|
401
|
+
await driver.query(step.sql, step.params ?? []);
|
|
385
402
|
} catch (error: unknown) {
|
|
386
403
|
// Catch SqlQueryError and include normalized metadata
|
|
387
404
|
if (SqlQueryError.is(error)) {
|
|
@@ -445,7 +462,7 @@ class PostgresMigrationRunner implements SqlMigrationRunner<PostgresPlanTargetDe
|
|
|
445
462
|
return false;
|
|
446
463
|
}
|
|
447
464
|
for (const step of steps) {
|
|
448
|
-
const result = await driver.query(step.sql);
|
|
465
|
+
const result = await driver.query(step.sql, step.params ?? []);
|
|
449
466
|
if (!this.stepResultIsTrue(result.rows)) {
|
|
450
467
|
return false;
|
|
451
468
|
}
|
|
@@ -616,8 +633,11 @@ class PostgresMigrationRunner implements SqlMigrationRunner<PostgresPlanTargetDe
|
|
|
616
633
|
driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],
|
|
617
634
|
options: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>,
|
|
618
635
|
existingMarker: ContractMarkerRecord | null,
|
|
636
|
+
space: string,
|
|
619
637
|
): Promise<void> {
|
|
620
|
-
const
|
|
638
|
+
const incomingInvariants = options.plan.providedInvariants ?? [];
|
|
639
|
+
const writeStatements = buildMergeMarkerStatements({
|
|
640
|
+
space,
|
|
621
641
|
storageHash: options.plan.destination.storageHash,
|
|
622
642
|
profileHash:
|
|
623
643
|
options.plan.destination.profileHash ??
|
|
@@ -626,6 +646,7 @@ class PostgresMigrationRunner implements SqlMigrationRunner<PostgresPlanTargetDe
|
|
|
626
646
|
contractJson: options.destinationContract,
|
|
627
647
|
canonicalVersion: null,
|
|
628
648
|
meta: {},
|
|
649
|
+
invariants: incomingInvariants,
|
|
629
650
|
});
|
|
630
651
|
const statement = existingMarker ? writeStatements.update : writeStatements.insert;
|
|
631
652
|
await this.executeStatement(driver, statement);
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import { APP_SPACE_ID } from '@prisma-next/framework-components/control';
|
|
2
|
+
|
|
3
|
+
export { APP_SPACE_ID };
|
|
4
|
+
|
|
1
5
|
export interface SqlStatement {
|
|
2
6
|
readonly sql: string;
|
|
3
7
|
readonly params: readonly unknown[];
|
|
@@ -8,16 +12,26 @@ export const ensurePrismaContractSchemaStatement: SqlStatement = {
|
|
|
8
12
|
params: [],
|
|
9
13
|
};
|
|
10
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Schema for `prisma_contract.marker`. The `space text` primary key
|
|
17
|
+
* supports one row per loaded contract space (`'app'`,
|
|
18
|
+
* `'<extension-id>'`, …); on a brand-new database `CREATE TABLE IF NOT
|
|
19
|
+
* EXISTS` produces this shape directly. The migration runner detects
|
|
20
|
+
* pre-1.0 single-row markers (no `space` column) at boot and fails with
|
|
21
|
+
* a structured `LEGACY_MARKER_SHAPE` error rather than auto-migrating —
|
|
22
|
+
* see `specs/framework-mechanism.spec.md § 2`.
|
|
23
|
+
*/
|
|
11
24
|
export const ensureMarkerTableStatement: SqlStatement = {
|
|
12
25
|
sql: `create table if not exists prisma_contract.marker (
|
|
13
|
-
|
|
26
|
+
space text not null primary key default '${APP_SPACE_ID}',
|
|
14
27
|
core_hash text not null,
|
|
15
28
|
profile_hash text not null,
|
|
16
29
|
contract_json jsonb,
|
|
17
30
|
canonical_version int,
|
|
18
31
|
updated_at timestamptz not null default now(),
|
|
19
32
|
app_tag text,
|
|
20
|
-
meta jsonb not null default '{}'
|
|
33
|
+
meta jsonb not null default '{}',
|
|
34
|
+
invariants text[] not null default '{}'
|
|
21
35
|
)`,
|
|
22
36
|
params: [],
|
|
23
37
|
};
|
|
@@ -37,40 +51,59 @@ export const ensureLedgerTableStatement: SqlStatement = {
|
|
|
37
51
|
params: [],
|
|
38
52
|
};
|
|
39
53
|
|
|
40
|
-
export interface
|
|
54
|
+
export interface MergeMarkerInput {
|
|
55
|
+
/**
|
|
56
|
+
* Logical space identifier for this marker row. Required at every
|
|
57
|
+
* call site so the type system surfaces every place that needs to
|
|
58
|
+
* thread the value (rather than letting an `?? APP_SPACE_ID`
|
|
59
|
+
* fall-through silently collapse multi-space markers onto the
|
|
60
|
+
* `'app'` row). App-plan callers pass {@link APP_SPACE_ID}
|
|
61
|
+
* (`'app'`); per-extension callers (planner / runner / verifier
|
|
62
|
+
* extensions over contract spaces) pass the extension's space id.
|
|
63
|
+
*/
|
|
64
|
+
readonly space: string;
|
|
41
65
|
readonly storageHash: string;
|
|
42
66
|
readonly profileHash: string;
|
|
43
67
|
readonly contractJson?: unknown;
|
|
44
68
|
readonly canonicalVersion?: number | null;
|
|
45
69
|
readonly appTag?: string | null;
|
|
46
70
|
readonly meta?: Record<string, unknown>;
|
|
71
|
+
/**
|
|
72
|
+
* Invariants to merge into `marker.invariants`. INSERT writes them as
|
|
73
|
+
* the initial value (callers are expected to pass a sorted, deduped
|
|
74
|
+
* array). UPDATE merges them with the existing column server-side via
|
|
75
|
+
* a single atomic SQL expression.
|
|
76
|
+
*/
|
|
77
|
+
readonly invariants: readonly string[];
|
|
47
78
|
}
|
|
48
79
|
|
|
49
|
-
export function
|
|
80
|
+
export function buildMergeMarkerStatements(input: MergeMarkerInput): {
|
|
50
81
|
readonly insert: SqlStatement;
|
|
51
82
|
readonly update: SqlStatement;
|
|
52
83
|
} {
|
|
53
84
|
const params: readonly unknown[] = [
|
|
54
|
-
|
|
85
|
+
input.space,
|
|
55
86
|
input.storageHash,
|
|
56
87
|
input.profileHash,
|
|
57
88
|
jsonParam(input.contractJson),
|
|
58
89
|
input.canonicalVersion ?? null,
|
|
59
90
|
input.appTag ?? null,
|
|
60
91
|
jsonParam(input.meta ?? {}),
|
|
92
|
+
input.invariants,
|
|
61
93
|
];
|
|
62
94
|
|
|
63
95
|
return {
|
|
64
96
|
insert: {
|
|
65
97
|
sql: `insert into prisma_contract.marker (
|
|
66
|
-
|
|
98
|
+
space,
|
|
67
99
|
core_hash,
|
|
68
100
|
profile_hash,
|
|
69
101
|
contract_json,
|
|
70
102
|
canonical_version,
|
|
71
103
|
updated_at,
|
|
72
104
|
app_tag,
|
|
73
|
-
meta
|
|
105
|
+
meta,
|
|
106
|
+
invariants
|
|
74
107
|
) values (
|
|
75
108
|
$1,
|
|
76
109
|
$2,
|
|
@@ -79,11 +112,16 @@ export function buildWriteMarkerStatements(input: WriteMarkerInput): {
|
|
|
79
112
|
$5,
|
|
80
113
|
now(),
|
|
81
114
|
$6,
|
|
82
|
-
$7::jsonb
|
|
115
|
+
$7::jsonb,
|
|
116
|
+
$8::text[]
|
|
83
117
|
)`,
|
|
84
118
|
params,
|
|
85
119
|
},
|
|
86
120
|
update: {
|
|
121
|
+
// `invariants = array(select distinct unnest(invariants || $8::text[]) order by 1)`
|
|
122
|
+
// reads the current column value under the UPDATE's row lock, unions
|
|
123
|
+
// with the incoming array, dedupes, and sorts ascending — single
|
|
124
|
+
// statement, atomic, no read-then-write window.
|
|
87
125
|
sql: `update prisma_contract.marker set
|
|
88
126
|
core_hash = $2,
|
|
89
127
|
profile_hash = $3,
|
|
@@ -91,8 +129,9 @@ export function buildWriteMarkerStatements(input: WriteMarkerInput): {
|
|
|
91
129
|
canonical_version = $5,
|
|
92
130
|
updated_at = now(),
|
|
93
131
|
app_tag = $6,
|
|
94
|
-
meta = $7::jsonb
|
|
95
|
-
|
|
132
|
+
meta = $7::jsonb,
|
|
133
|
+
invariants = array(select distinct unnest(invariants || $8::text[]) order by 1)
|
|
134
|
+
where space = $1`,
|
|
96
135
|
params,
|
|
97
136
|
},
|
|
98
137
|
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { buildCodecDescriptorRegistry } from '@prisma-next/sql-relational-core/codec-descriptor-registry';
|
|
2
|
+
import type { CodecDescriptorRegistry } from '@prisma-next/sql-relational-core/query-lane-context';
|
|
3
|
+
import { codecDescriptors } from './codecs';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Registry of every codec descriptor shipped by `@prisma-next/target-postgres`.
|
|
7
|
+
*
|
|
8
|
+
* Public consumer surface for the postgres codec set: the postgres adapter and any other consumer that needs to enumerate or look up a postgres codec by id consumes this rather than the raw descriptor array. See ADR 208.
|
|
9
|
+
*/
|
|
10
|
+
export const postgresCodecRegistry: CodecDescriptorRegistry =
|
|
11
|
+
buildCodecDescriptorRegistry(codecDescriptors);
|
|
@@ -1,26 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Codec type definitions for the Postgres target.
|
|
3
3
|
*
|
|
4
|
-
* This file
|
|
5
|
-
* These types are imported by generated `contract.d.ts` files for compile-time
|
|
6
|
-
* type inference.
|
|
4
|
+
* This file is the public origin of `CodecTypes`. The `Resolve<...>` materialisation happens here (rather than in `core/codec-type-map.ts`) so the tsdown DTS bundler resolves consumer-side `.d.mts` references via this public entry point rather than a hash-named internal chunk (the `TS2742` family).
|
|
7
5
|
*
|
|
8
|
-
* Lives in `target-postgres` because codec types describe the target's value
|
|
9
|
-
* space - both the control adapter (introspection / schema verification) and
|
|
10
|
-
* the runtime adapter (encode/decode) share the same definitions, and the
|
|
11
|
-
* target package is the natural home that both adapters depend on.
|
|
12
|
-
*
|
|
13
|
-
* Runtime codec implementations are provided by the runtime adapter's
|
|
14
|
-
* codec registry, which is built from `core/codecs.ts`.
|
|
6
|
+
* Lives in `target-postgres` because codec types describe the target's value space — both the control adapter (introspection / schema verification) and the runtime adapter (encode/decode) share the same definitions, and the target package is the natural home that both adapters depend on.
|
|
15
7
|
*/
|
|
16
8
|
|
|
17
9
|
import type { JsonValue } from '@prisma-next/contract/types';
|
|
18
|
-
import type {
|
|
10
|
+
import type { ExtractedCodecTypes, Resolve } from '../core/codec-type-map';
|
|
19
11
|
|
|
20
|
-
export type CodecTypes =
|
|
12
|
+
export type CodecTypes = Resolve<ExtractedCodecTypes>;
|
|
21
13
|
|
|
22
14
|
export type { JsonValue };
|
|
23
|
-
export { dataTypes } from '../core/codecs';
|
|
24
15
|
|
|
25
16
|
type Branded<T, Shape extends Record<string, unknown>> = T & {
|
|
26
17
|
readonly [K in keyof Shape]: Shape[K];
|
package/src/exports/codecs.ts
CHANGED
|
@@ -1,2 +1,49 @@
|
|
|
1
|
-
export type {
|
|
2
|
-
|
|
1
|
+
export type {
|
|
2
|
+
PgBitDescriptor,
|
|
3
|
+
PgBoolDescriptor,
|
|
4
|
+
PgCharDescriptor,
|
|
5
|
+
PgEnumDescriptor,
|
|
6
|
+
PgFloat4Descriptor,
|
|
7
|
+
PgFloat8Descriptor,
|
|
8
|
+
PgFloatDescriptor,
|
|
9
|
+
PgInt2Descriptor,
|
|
10
|
+
PgInt4Descriptor,
|
|
11
|
+
PgInt8Descriptor,
|
|
12
|
+
PgIntDescriptor,
|
|
13
|
+
PgIntervalDescriptor,
|
|
14
|
+
PgJsonbDescriptor,
|
|
15
|
+
PgJsonDescriptor,
|
|
16
|
+
PgNumericDescriptor,
|
|
17
|
+
PgTextDescriptor,
|
|
18
|
+
PgTimeDescriptor,
|
|
19
|
+
PgTimestampDescriptor,
|
|
20
|
+
PgTimestamptzDescriptor,
|
|
21
|
+
PgTimetzDescriptor,
|
|
22
|
+
PgVarbitDescriptor,
|
|
23
|
+
PgVarcharDescriptor,
|
|
24
|
+
} from '../core/codecs';
|
|
25
|
+
export {
|
|
26
|
+
pgBitColumn,
|
|
27
|
+
pgBoolColumn,
|
|
28
|
+
pgCharColumn,
|
|
29
|
+
pgEnumColumn,
|
|
30
|
+
pgFloat4Column,
|
|
31
|
+
pgFloat8Column,
|
|
32
|
+
pgFloatColumn,
|
|
33
|
+
pgInt2Column,
|
|
34
|
+
pgInt4Column,
|
|
35
|
+
pgInt8Column,
|
|
36
|
+
pgIntColumn,
|
|
37
|
+
pgIntervalColumn,
|
|
38
|
+
pgJsonbColumn,
|
|
39
|
+
pgJsonColumn,
|
|
40
|
+
pgNumericColumn,
|
|
41
|
+
pgTextColumn,
|
|
42
|
+
pgTimeColumn,
|
|
43
|
+
pgTimestampColumn,
|
|
44
|
+
pgTimestamptzColumn,
|
|
45
|
+
pgTimetzColumn,
|
|
46
|
+
pgVarbitColumn,
|
|
47
|
+
pgVarcharColumn,
|
|
48
|
+
} from '../core/codecs';
|
|
49
|
+
export { postgresCodecRegistry } from '../core/registry';
|