@prisma-next/adapter-postgres 0.16.0-dev.22 → 0.16.0-dev.23
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/{adapter-DcBWxseT.mjs → adapter-CuTsfsz3.mjs} +4 -4
- package/dist/adapter-CuTsfsz3.mjs.map +1 -0
- package/dist/adapter.d.mts.map +1 -1
- package/dist/adapter.mjs +1 -1
- package/dist/{control-adapter-hSsjUXtc.mjs → control-adapter-Xog0HsuP.mjs} +49 -25
- package/dist/control-adapter-Xog0HsuP.mjs.map +1 -0
- package/dist/control.d.mts +2 -2
- package/dist/control.d.mts.map +1 -1
- package/dist/control.mjs +4 -4
- package/dist/control.mjs.map +1 -1
- package/dist/{descriptor-meta-jMtx881n.mjs → descriptor-meta-DpA4aG-x.mjs} +26 -6
- package/dist/descriptor-meta-DpA4aG-x.mjs.map +1 -0
- package/dist/runtime.mjs +2 -2
- package/package.json +23 -23
- package/src/core/adapter-errors.ts +25 -0
- package/src/core/adapter.ts +7 -2
- package/src/core/control-adapter.ts +19 -6
- package/src/core/control-codecs.ts +4 -1
- package/src/core/descriptor-meta.ts +16 -5
- package/src/core/sql-renderer.ts +46 -16
- package/src/exports/control.ts +1 -2
- package/dist/adapter-DcBWxseT.mjs.map +0 -1
- package/dist/control-adapter-hSsjUXtc.mjs.map +0 -1
- package/dist/descriptor-meta-jMtx881n.mjs.map +0 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { i as adapterError } from "./control-adapter-Xog0HsuP.mjs";
|
|
1
2
|
import { postgresCodecRegistry } from "@prisma-next/target-postgres/codecs";
|
|
2
3
|
import { PG_BIT_CODEC_ID, PG_BOOL_CODEC_ID, PG_BYTEA_CODEC_ID, PG_CHAR_CODEC_ID, PG_FLOAT4_CODEC_ID, PG_FLOAT8_CODEC_ID, PG_FLOAT_CODEC_ID, PG_INET_CODEC_ID, PG_INT2_CODEC_ID, PG_INT4_CODEC_ID, PG_INT8_CODEC_ID, PG_INTERVAL_CODEC_ID, PG_INT_CODEC_ID, PG_JSONB_CODEC_ID, PG_JSON_CODEC_ID, PG_NUMERIC_CODEC_ID, PG_TEXT_CODEC_ID, PG_TIMESTAMPTZ_CODEC_ID, PG_TIMESTAMP_CODEC_ID, PG_TIMETZ_CODEC_ID, PG_TIME_CODEC_ID, PG_UUID_CODEC_ID, PG_VARBIT_CODEC_ID, PG_VARCHAR_CODEC_ID, SQL_CHAR_CODEC_ID, SQL_FLOAT_CODEC_ID, SQL_INT_CODEC_ID, SQL_TEXT_CODEC_ID, SQL_TIMESTAMP_CODEC_ID, SQL_VARCHAR_CODEC_ID } from "@prisma-next/target-postgres/codec-ids";
|
|
3
4
|
import { buildOperation, toExpr } from "@prisma-next/sql-relational-core/expression";
|
|
@@ -17,26 +18,45 @@ function isNonNegativeInteger(value) {
|
|
|
17
18
|
function expandLength({ nativeType, typeParams }) {
|
|
18
19
|
if (!typeParams || !("length" in typeParams)) return nativeType;
|
|
19
20
|
const length = typeParams["length"];
|
|
20
|
-
if (!isPositiveInteger(length)) throw
|
|
21
|
+
if (!isPositiveInteger(length)) throw adapterError("RUNTIME.TYPE_PARAMS_INVALID", `Invalid "length" type parameter for "${nativeType}": expected a positive integer, got ${JSON.stringify(length)}`, { meta: {
|
|
22
|
+
nativeType,
|
|
23
|
+
param: "length",
|
|
24
|
+
received: length
|
|
25
|
+
} });
|
|
21
26
|
return `${nativeType}(${length})`;
|
|
22
27
|
}
|
|
23
28
|
function expandPrecision({ nativeType, typeParams }) {
|
|
24
29
|
if (!typeParams || !("precision" in typeParams)) return nativeType;
|
|
25
30
|
const precision = typeParams["precision"];
|
|
26
|
-
if (!isPositiveInteger(precision)) throw
|
|
31
|
+
if (!isPositiveInteger(precision)) throw adapterError("RUNTIME.TYPE_PARAMS_INVALID", `Invalid "precision" type parameter for "${nativeType}": expected a positive integer, got ${JSON.stringify(precision)}`, { meta: {
|
|
32
|
+
nativeType,
|
|
33
|
+
param: "precision",
|
|
34
|
+
received: precision
|
|
35
|
+
} });
|
|
27
36
|
return `${nativeType}(${precision})`;
|
|
28
37
|
}
|
|
29
38
|
function expandNumeric({ nativeType, typeParams }) {
|
|
30
39
|
const hasPrecision = typeParams && "precision" in typeParams;
|
|
31
40
|
const hasScale = typeParams && "scale" in typeParams;
|
|
32
41
|
if (!hasPrecision && !hasScale) return nativeType;
|
|
33
|
-
if (!hasPrecision && hasScale) throw
|
|
42
|
+
if (!hasPrecision && hasScale) throw adapterError("RUNTIME.TYPE_PARAMS_INVALID", `Invalid type parameters for "${nativeType}": "scale" requires "precision" to be specified`, { meta: {
|
|
43
|
+
nativeType,
|
|
44
|
+
param: "scale"
|
|
45
|
+
} });
|
|
34
46
|
if (hasPrecision) {
|
|
35
47
|
const precision = typeParams["precision"];
|
|
36
|
-
if (!isPositiveInteger(precision)) throw
|
|
48
|
+
if (!isPositiveInteger(precision)) throw adapterError("RUNTIME.TYPE_PARAMS_INVALID", `Invalid "precision" type parameter for "${nativeType}": expected a positive integer, got ${JSON.stringify(precision)}`, { meta: {
|
|
49
|
+
nativeType,
|
|
50
|
+
param: "precision",
|
|
51
|
+
received: precision
|
|
52
|
+
} });
|
|
37
53
|
if (hasScale) {
|
|
38
54
|
const scale = typeParams["scale"];
|
|
39
|
-
if (!isNonNegativeInteger(scale)) throw
|
|
55
|
+
if (!isNonNegativeInteger(scale)) throw adapterError("RUNTIME.TYPE_PARAMS_INVALID", `Invalid "scale" type parameter for "${nativeType}": expected a non-negative integer, got ${JSON.stringify(scale)}`, { meta: {
|
|
56
|
+
nativeType,
|
|
57
|
+
param: "scale",
|
|
58
|
+
received: scale
|
|
59
|
+
} });
|
|
40
60
|
return `${nativeType}(${precision},${scale})`;
|
|
41
61
|
}
|
|
42
62
|
return `${nativeType}(${precision})`;
|
|
@@ -328,4 +348,4 @@ const postgresAdapterDescriptorMeta = {
|
|
|
328
348
|
//#endregion
|
|
329
349
|
export { postgresQueryOperations as n, postgresAdapterDescriptorMeta as t };
|
|
330
350
|
|
|
331
|
-
//# sourceMappingURL=descriptor-meta-
|
|
351
|
+
//# sourceMappingURL=descriptor-meta-DpA4aG-x.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"descriptor-meta-DpA4aG-x.mjs","names":[],"sources":["../src/core/descriptor-meta.ts"],"sourcesContent":["import type { CodecControlHooks, ExpandNativeTypeInput } from '@prisma-next/family-sql/control';\nimport {\n buildOperation,\n type CodecExpression,\n type Expression,\n type TraitExpression,\n toExpr,\n} from '@prisma-next/sql-relational-core/expression';\nimport {\n PG_BIT_CODEC_ID,\n PG_BOOL_CODEC_ID,\n PG_BYTEA_CODEC_ID,\n PG_CHAR_CODEC_ID,\n PG_FLOAT_CODEC_ID,\n PG_FLOAT4_CODEC_ID,\n PG_FLOAT8_CODEC_ID,\n PG_INET_CODEC_ID,\n PG_INT_CODEC_ID,\n PG_INT2_CODEC_ID,\n PG_INT4_CODEC_ID,\n PG_INT8_CODEC_ID,\n PG_INTERVAL_CODEC_ID,\n PG_JSON_CODEC_ID,\n PG_JSONB_CODEC_ID,\n PG_NUMERIC_CODEC_ID,\n PG_TEXT_CODEC_ID,\n PG_TIME_CODEC_ID,\n PG_TIMESTAMP_CODEC_ID,\n PG_TIMESTAMPTZ_CODEC_ID,\n PG_TIMETZ_CODEC_ID,\n PG_UUID_CODEC_ID,\n PG_VARBIT_CODEC_ID,\n PG_VARCHAR_CODEC_ID,\n SQL_CHAR_CODEC_ID,\n SQL_FLOAT_CODEC_ID,\n SQL_INT_CODEC_ID,\n SQL_TEXT_CODEC_ID,\n SQL_TIMESTAMP_CODEC_ID,\n SQL_VARCHAR_CODEC_ID,\n} from '@prisma-next/target-postgres/codec-ids';\nimport { postgresCodecRegistry } from '@prisma-next/target-postgres/codecs';\nimport type { QueryOperationTypes } from '../types/operation-types';\nimport { adapterError } from './adapter-errors';\n\n// ============================================================================ Helper functions for reducing boilerplate ============================================================================\n\n/** Creates a type import spec for codec types */\nconst codecTypeImport = (named: string) =>\n ({\n package: '@prisma-next/target-postgres/codec-types',\n named,\n alias: named,\n }) as const;\n\nfunction isPositiveInteger(value: unknown): value is number {\n return (\n typeof value === 'number' && Number.isFinite(value) && Number.isInteger(value) && value > 0\n );\n}\n\nfunction isNonNegativeInteger(value: unknown): value is number {\n return (\n typeof value === 'number' && Number.isFinite(value) && Number.isInteger(value) && value >= 0\n );\n}\n\nfunction expandLength({ nativeType, typeParams }: ExpandNativeTypeInput): string {\n if (!typeParams || !('length' in typeParams)) {\n return nativeType;\n }\n const length = typeParams['length'];\n if (!isPositiveInteger(length)) {\n throw adapterError(\n 'RUNTIME.TYPE_PARAMS_INVALID',\n `Invalid \"length\" type parameter for \"${nativeType}\": expected a positive integer, got ${JSON.stringify(length)}`,\n { meta: { nativeType, param: 'length', received: length } },\n );\n }\n return `${nativeType}(${length})`;\n}\n\nfunction expandPrecision({ nativeType, typeParams }: ExpandNativeTypeInput): string {\n if (!typeParams || !('precision' in typeParams)) {\n return nativeType;\n }\n const precision = typeParams['precision'];\n if (!isPositiveInteger(precision)) {\n throw adapterError(\n 'RUNTIME.TYPE_PARAMS_INVALID',\n `Invalid \"precision\" type parameter for \"${nativeType}\": expected a positive integer, got ${JSON.stringify(precision)}`,\n { meta: { nativeType, param: 'precision', received: precision } },\n );\n }\n return `${nativeType}(${precision})`;\n}\n\nfunction expandNumeric({ nativeType, typeParams }: ExpandNativeTypeInput): string {\n const hasPrecision = typeParams && 'precision' in typeParams;\n const hasScale = typeParams && 'scale' in typeParams;\n\n if (!hasPrecision && !hasScale) {\n return nativeType;\n }\n\n if (!hasPrecision && hasScale) {\n throw adapterError(\n 'RUNTIME.TYPE_PARAMS_INVALID',\n `Invalid type parameters for \"${nativeType}\": \"scale\" requires \"precision\" to be specified`,\n { meta: { nativeType, param: 'scale' } },\n );\n }\n\n if (hasPrecision) {\n const precision = typeParams['precision'];\n if (!isPositiveInteger(precision)) {\n throw adapterError(\n 'RUNTIME.TYPE_PARAMS_INVALID',\n `Invalid \"precision\" type parameter for \"${nativeType}\": expected a positive integer, got ${JSON.stringify(precision)}`,\n { meta: { nativeType, param: 'precision', received: precision } },\n );\n }\n if (hasScale) {\n const scale = typeParams['scale'];\n if (!isNonNegativeInteger(scale)) {\n throw adapterError(\n 'RUNTIME.TYPE_PARAMS_INVALID',\n `Invalid \"scale\" type parameter for \"${nativeType}\": expected a non-negative integer, got ${JSON.stringify(scale)}`,\n { meta: { nativeType, param: 'scale', received: scale } },\n );\n }\n return `${nativeType}(${precision},${scale})`;\n }\n return `${nativeType}(${precision})`;\n }\n\n return nativeType;\n}\n\nconst lengthHooks: CodecControlHooks = { expandNativeType: expandLength };\nconst precisionHooks: CodecControlHooks = { expandNativeType: expandPrecision };\nconst numericHooks: CodecControlHooks = { expandNativeType: expandNumeric };\nconst identityHooks: CodecControlHooks = { expandNativeType: ({ nativeType }) => nativeType };\n\n// ============================================================================ Descriptor metadata ============================================================================\n\ntype CodecTypesBase = Record<string, { readonly input: unknown; readonly output: unknown }>;\n\nexport function postgresQueryOperations<CT extends CodecTypesBase>(): QueryOperationTypes<CT> {\n return {\n ilike: {\n self: { traits: ['textual'] },\n impl: (\n self: TraitExpression<readonly ['textual'], false, CT>,\n pattern: CodecExpression<'pg/text@1', false, CT>,\n ): Expression<{ codecId: 'pg/bool@1'; nullable: false }> => {\n return buildOperation({\n method: 'ilike',\n args: [toExpr(self), toExpr(pattern, { codecId: PG_TEXT_CODEC_ID })],\n returns: { codecId: PG_BOOL_CODEC_ID, nullable: false },\n lowering: { targetFamily: 'sql', strategy: 'infix', template: '{{self}} ILIKE {{arg0}}' },\n });\n },\n },\n };\n}\n\nexport const postgresAdapterDescriptorMeta = {\n kind: 'adapter',\n familyId: 'sql',\n targetId: 'postgres',\n id: 'postgres',\n version: '0.0.1',\n capabilities: {\n postgres: {\n orderBy: true,\n limit: true,\n lateral: true,\n jsonAgg: true,\n returning: true,\n distinctOn: true,\n },\n sql: {\n enums: true,\n returning: true,\n defaultInInsert: true,\n lateral: true,\n scalarList: true,\n },\n },\n types: {\n codecTypes: {\n codecDescriptors: Array.from(postgresCodecRegistry.values()),\n import: {\n package: '@prisma-next/target-postgres/codec-types',\n named: 'CodecTypes',\n alias: 'PgTypes',\n },\n typeImports: [\n {\n package: '@prisma-next/target-postgres/codec-types',\n named: 'JsonValue',\n alias: 'JsonValue',\n },\n codecTypeImport('Char'),\n codecTypeImport('Varchar'),\n codecTypeImport('Numeric'),\n codecTypeImport('Bit'),\n codecTypeImport('VarBit'),\n codecTypeImport('Timestamp'),\n codecTypeImport('Timestamptz'),\n codecTypeImport('Time'),\n codecTypeImport('Timetz'),\n codecTypeImport('Interval'),\n ],\n controlPlaneHooks: {\n [SQL_CHAR_CODEC_ID]: lengthHooks,\n [SQL_VARCHAR_CODEC_ID]: lengthHooks,\n [SQL_TIMESTAMP_CODEC_ID]: precisionHooks,\n [PG_CHAR_CODEC_ID]: lengthHooks,\n [PG_VARCHAR_CODEC_ID]: lengthHooks,\n [PG_NUMERIC_CODEC_ID]: numericHooks,\n [PG_BIT_CODEC_ID]: lengthHooks,\n [PG_VARBIT_CODEC_ID]: lengthHooks,\n [PG_TIMESTAMP_CODEC_ID]: precisionHooks,\n [PG_TIMESTAMPTZ_CODEC_ID]: precisionHooks,\n [PG_TIME_CODEC_ID]: precisionHooks,\n [PG_TIMETZ_CODEC_ID]: precisionHooks,\n [PG_INTERVAL_CODEC_ID]: precisionHooks,\n [PG_JSON_CODEC_ID]: identityHooks,\n [PG_JSONB_CODEC_ID]: identityHooks,\n [PG_BYTEA_CODEC_ID]: identityHooks,\n [PG_UUID_CODEC_ID]: identityHooks,\n [PG_INET_CODEC_ID]: identityHooks,\n },\n },\n storage: [\n { typeId: PG_TEXT_CODEC_ID, familyId: 'sql', targetId: 'postgres', nativeType: 'text' },\n { typeId: SQL_TEXT_CODEC_ID, familyId: 'sql', targetId: 'postgres', nativeType: 'text' },\n { typeId: SQL_CHAR_CODEC_ID, familyId: 'sql', targetId: 'postgres', nativeType: 'character' },\n {\n typeId: SQL_VARCHAR_CODEC_ID,\n familyId: 'sql',\n targetId: 'postgres',\n nativeType: 'character varying',\n },\n { typeId: SQL_INT_CODEC_ID, familyId: 'sql', targetId: 'postgres', nativeType: 'int4' },\n { typeId: SQL_FLOAT_CODEC_ID, familyId: 'sql', targetId: 'postgres', nativeType: 'float8' },\n {\n typeId: SQL_TIMESTAMP_CODEC_ID,\n familyId: 'sql',\n targetId: 'postgres',\n nativeType: 'timestamp',\n },\n { typeId: PG_CHAR_CODEC_ID, familyId: 'sql', targetId: 'postgres', nativeType: 'character' },\n {\n typeId: PG_VARCHAR_CODEC_ID,\n familyId: 'sql',\n targetId: 'postgres',\n nativeType: 'character varying',\n },\n { typeId: PG_INT_CODEC_ID, familyId: 'sql', targetId: 'postgres', nativeType: 'int4' },\n { typeId: PG_FLOAT_CODEC_ID, familyId: 'sql', targetId: 'postgres', nativeType: 'float8' },\n { typeId: PG_INT4_CODEC_ID, familyId: 'sql', targetId: 'postgres', nativeType: 'int4' },\n { typeId: PG_INT2_CODEC_ID, familyId: 'sql', targetId: 'postgres', nativeType: 'int2' },\n { typeId: PG_INT8_CODEC_ID, familyId: 'sql', targetId: 'postgres', nativeType: 'int8' },\n { typeId: PG_FLOAT4_CODEC_ID, familyId: 'sql', targetId: 'postgres', nativeType: 'float4' },\n { typeId: PG_FLOAT8_CODEC_ID, familyId: 'sql', targetId: 'postgres', nativeType: 'float8' },\n { typeId: PG_NUMERIC_CODEC_ID, familyId: 'sql', targetId: 'postgres', nativeType: 'numeric' },\n {\n typeId: PG_TIMESTAMP_CODEC_ID,\n familyId: 'sql',\n targetId: 'postgres',\n nativeType: 'timestamp',\n },\n {\n typeId: PG_TIMESTAMPTZ_CODEC_ID,\n familyId: 'sql',\n targetId: 'postgres',\n nativeType: 'timestamptz',\n },\n { typeId: PG_TIME_CODEC_ID, familyId: 'sql', targetId: 'postgres', nativeType: 'time' },\n { typeId: PG_TIMETZ_CODEC_ID, familyId: 'sql', targetId: 'postgres', nativeType: 'timetz' },\n { typeId: PG_BOOL_CODEC_ID, familyId: 'sql', targetId: 'postgres', nativeType: 'bool' },\n { typeId: PG_BIT_CODEC_ID, familyId: 'sql', targetId: 'postgres', nativeType: 'bit' },\n {\n typeId: PG_VARBIT_CODEC_ID,\n familyId: 'sql',\n targetId: 'postgres',\n nativeType: 'bit varying',\n },\n {\n typeId: PG_INTERVAL_CODEC_ID,\n familyId: 'sql',\n targetId: 'postgres',\n nativeType: 'interval',\n },\n { typeId: PG_JSON_CODEC_ID, familyId: 'sql', targetId: 'postgres', nativeType: 'json' },\n { typeId: PG_JSONB_CODEC_ID, familyId: 'sql', targetId: 'postgres', nativeType: 'jsonb' },\n { typeId: PG_BYTEA_CODEC_ID, familyId: 'sql', targetId: 'postgres', nativeType: 'bytea' },\n { typeId: PG_UUID_CODEC_ID, familyId: 'sql', targetId: 'postgres', nativeType: 'uuid' },\n { typeId: PG_INET_CODEC_ID, familyId: 'sql', targetId: 'postgres', nativeType: 'inet' },\n ],\n queryOperationTypes: {\n import: {\n package: '@prisma-next/adapter-postgres/operation-types',\n named: 'QueryOperationTypes',\n alias: 'PgAdapterQueryOps',\n },\n },\n },\n} as const;\n"],"mappings":"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"}
|
package/dist/runtime.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { n as postgresRawCodecInferer, t as createPostgresAdapter } from "./adapter-
|
|
2
|
-
import { n as postgresQueryOperations, t as postgresAdapterDescriptorMeta } from "./descriptor-meta-
|
|
1
|
+
import { n as postgresRawCodecInferer, t as createPostgresAdapter } from "./adapter-CuTsfsz3.mjs";
|
|
2
|
+
import { n as postgresQueryOperations, t as postgresAdapterDescriptorMeta } from "./descriptor-meta-DpA4aG-x.mjs";
|
|
3
3
|
import { extractCodecLookup } from "@prisma-next/framework-components/control";
|
|
4
4
|
import { postgresCodecRegistry } from "@prisma-next/target-postgres/codecs";
|
|
5
5
|
import { builtinGeneratorIds } from "@prisma-next/ids";
|
package/package.json
CHANGED
|
@@ -1,35 +1,35 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prisma-next/adapter-postgres",
|
|
3
|
-
"version": "0.16.0-dev.
|
|
3
|
+
"version": "0.16.0-dev.23",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"@prisma-next/contract": "0.16.0-dev.
|
|
9
|
-
"@prisma-next/contract-authoring": "0.16.0-dev.
|
|
10
|
-
"@prisma-next/errors": "0.16.0-dev.
|
|
11
|
-
"@prisma-next/family-sql": "0.16.0-dev.
|
|
12
|
-
"@prisma-next/framework-components": "0.16.0-dev.
|
|
13
|
-
"@prisma-next/ids": "0.16.0-dev.
|
|
14
|
-
"@prisma-next/psl-parser": "0.16.0-dev.
|
|
15
|
-
"@prisma-next/sql-contract": "0.16.0-dev.
|
|
16
|
-
"@prisma-next/sql-contract-psl": "0.16.0-dev.
|
|
17
|
-
"@prisma-next/sql-contract-ts": "0.16.0-dev.
|
|
18
|
-
"@prisma-next/sql-operations": "0.16.0-dev.
|
|
19
|
-
"@prisma-next/sql-relational-core": "0.16.0-dev.
|
|
20
|
-
"@prisma-next/sql-runtime": "0.16.0-dev.
|
|
21
|
-
"@prisma-next/sql-schema-ir": "0.16.0-dev.
|
|
22
|
-
"@prisma-next/target-postgres": "0.16.0-dev.
|
|
23
|
-
"@prisma-next/utils": "0.16.0-dev.
|
|
8
|
+
"@prisma-next/contract": "0.16.0-dev.23",
|
|
9
|
+
"@prisma-next/contract-authoring": "0.16.0-dev.23",
|
|
10
|
+
"@prisma-next/errors": "0.16.0-dev.23",
|
|
11
|
+
"@prisma-next/family-sql": "0.16.0-dev.23",
|
|
12
|
+
"@prisma-next/framework-components": "0.16.0-dev.23",
|
|
13
|
+
"@prisma-next/ids": "0.16.0-dev.23",
|
|
14
|
+
"@prisma-next/psl-parser": "0.16.0-dev.23",
|
|
15
|
+
"@prisma-next/sql-contract": "0.16.0-dev.23",
|
|
16
|
+
"@prisma-next/sql-contract-psl": "0.16.0-dev.23",
|
|
17
|
+
"@prisma-next/sql-contract-ts": "0.16.0-dev.23",
|
|
18
|
+
"@prisma-next/sql-operations": "0.16.0-dev.23",
|
|
19
|
+
"@prisma-next/sql-relational-core": "0.16.0-dev.23",
|
|
20
|
+
"@prisma-next/sql-runtime": "0.16.0-dev.23",
|
|
21
|
+
"@prisma-next/sql-schema-ir": "0.16.0-dev.23",
|
|
22
|
+
"@prisma-next/target-postgres": "0.16.0-dev.23",
|
|
23
|
+
"@prisma-next/utils": "0.16.0-dev.23",
|
|
24
24
|
"arktype": "^2.2.2"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
|
-
"@prisma-next/cli": "0.16.0-dev.
|
|
28
|
-
"@prisma-next/driver-postgres": "0.16.0-dev.
|
|
29
|
-
"@prisma-next/migration-tools": "0.16.0-dev.
|
|
30
|
-
"@prisma-next/test-utils": "0.16.0-dev.
|
|
31
|
-
"@prisma-next/tsconfig": "0.16.0-dev.
|
|
32
|
-
"@prisma-next/tsdown": "0.16.0-dev.
|
|
27
|
+
"@prisma-next/cli": "0.16.0-dev.23",
|
|
28
|
+
"@prisma-next/driver-postgres": "0.16.0-dev.23",
|
|
29
|
+
"@prisma-next/migration-tools": "0.16.0-dev.23",
|
|
30
|
+
"@prisma-next/test-utils": "0.16.0-dev.23",
|
|
31
|
+
"@prisma-next/tsconfig": "0.16.0-dev.23",
|
|
32
|
+
"@prisma-next/tsdown": "0.16.0-dev.23",
|
|
33
33
|
"pathe": "^2.0.3",
|
|
34
34
|
"tsdown": "0.22.8",
|
|
35
35
|
"typescript": "5.9.3",
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { StructuredError, StructuredErrorOptions } from '@prisma-next/utils/structured-error';
|
|
2
|
+
import { structuredError } from '@prisma-next/utils/structured-error';
|
|
3
|
+
|
|
4
|
+
type RuntimeSubcode =
|
|
5
|
+
| 'DDL_UNSUPPORTED'
|
|
6
|
+
| 'RAW_SQL_UNSUPPORTED_INTERPOLATION'
|
|
7
|
+
| 'TYPE_PARAMS_INVALID'
|
|
8
|
+
| 'PARAM_REF_MISSING_CODEC'
|
|
9
|
+
| 'NAMESPACE_UNKNOWN'
|
|
10
|
+
| 'AST_INVALID';
|
|
11
|
+
|
|
12
|
+
type ContractSubcode =
|
|
13
|
+
| 'INTROSPECTION_UNSUPPORTED'
|
|
14
|
+
| 'DEFAULT_INVALID'
|
|
15
|
+
| 'PACK_CONTRIBUTION_INVALID';
|
|
16
|
+
|
|
17
|
+
export type PostgresAdapterErrorCode = `RUNTIME.${RuntimeSubcode}` | `CONTRACT.${ContractSubcode}`;
|
|
18
|
+
|
|
19
|
+
export function adapterError(
|
|
20
|
+
code: PostgresAdapterErrorCode,
|
|
21
|
+
message: string,
|
|
22
|
+
options?: StructuredErrorOptions,
|
|
23
|
+
): StructuredError {
|
|
24
|
+
return structuredError(code, message, options);
|
|
25
|
+
}
|
package/src/core/adapter.ts
CHANGED
|
@@ -11,6 +11,7 @@ import type {
|
|
|
11
11
|
import { isDdlNode } from '@prisma-next/sql-relational-core/ast';
|
|
12
12
|
import type { RawCodecInferer } from '@prisma-next/sql-relational-core/expression';
|
|
13
13
|
import type { PostgresDdlNode } from '@prisma-next/target-postgres/ddl';
|
|
14
|
+
import { adapterError } from './adapter-errors';
|
|
14
15
|
import { createPostgresBuiltinCodecLookup } from './codec-lookup';
|
|
15
16
|
import { PostgresControlAdapter } from './control-adapter';
|
|
16
17
|
import { renderLoweredSql } from './sql-renderer';
|
|
@@ -75,8 +76,10 @@ class PostgresAdapterImpl
|
|
|
75
76
|
context: LowererContext<PostgresContract>,
|
|
76
77
|
): PostgresLoweredStatement {
|
|
77
78
|
if (isDdlNode(ast)) {
|
|
78
|
-
throw
|
|
79
|
+
throw adapterError(
|
|
80
|
+
'RUNTIME.DDL_UNSUPPORTED',
|
|
79
81
|
'lower() does not lower DDL on the runtime adapter — DDL lowering is a control-plane concern handled by the control adapter.',
|
|
82
|
+
{ meta: { surface: 'runtime-adapter' } },
|
|
80
83
|
);
|
|
81
84
|
}
|
|
82
85
|
return renderLoweredSql(ast, context.contract, this.codecLookup);
|
|
@@ -98,8 +101,10 @@ export const postgresRawCodecInferer: RawCodecInferer = {
|
|
|
98
101
|
case 'object':
|
|
99
102
|
if (value instanceof Uint8Array) return 'pg/bytea';
|
|
100
103
|
}
|
|
101
|
-
throw
|
|
104
|
+
throw adapterError(
|
|
105
|
+
'RUNTIME.RAW_SQL_UNSUPPORTED_INTERPOLATION',
|
|
102
106
|
'unsupported JS value type for raw-SQL interpolation: wrap this value in `param(...)` with an explicit codec',
|
|
107
|
+
{ meta: { valueType: typeof value } },
|
|
103
108
|
);
|
|
104
109
|
},
|
|
105
110
|
};
|
|
@@ -76,6 +76,7 @@ import {
|
|
|
76
76
|
} from '@prisma-next/target-postgres/types';
|
|
77
77
|
import { blindCast } from '@prisma-next/utils/casts';
|
|
78
78
|
import { ifDefined } from '@prisma-next/utils/defined';
|
|
79
|
+
import { adapterError } from './adapter-errors';
|
|
79
80
|
import { encodeControlQueryParams } from './control-codecs';
|
|
80
81
|
import {
|
|
81
82
|
execute,
|
|
@@ -148,8 +149,10 @@ export class PostgresControlAdapter implements SqlControlAdapter<'postgres'> {
|
|
|
148
149
|
*/
|
|
149
150
|
lower(ast: AnyQueryAst | PostgresDdlNode, context: LowererContext<unknown>): LoweredStatement {
|
|
150
151
|
if (isDdlNode(ast)) {
|
|
151
|
-
throw
|
|
152
|
+
throw adapterError(
|
|
153
|
+
'RUNTIME.DDL_UNSUPPORTED',
|
|
152
154
|
'lower() cannot lower DDL: DDL default literals require inline codec encoding, which is async. Use lowerToExecuteRequest().',
|
|
155
|
+
{ meta: { surface: 'control-adapter' } },
|
|
153
156
|
);
|
|
154
157
|
}
|
|
155
158
|
return renderLoweredSql(
|
|
@@ -1548,8 +1551,10 @@ const PG_REFERENTIAL_ACTION_MAP: Record<PgReferentialActionRule, SqlReferentialA
|
|
|
1548
1551
|
function mapReferentialAction(rule: string): SqlReferentialAction | undefined {
|
|
1549
1552
|
const mapped = PG_REFERENTIAL_ACTION_MAP[rule as PgReferentialActionRule];
|
|
1550
1553
|
if (mapped === undefined) {
|
|
1551
|
-
throw
|
|
1554
|
+
throw adapterError(
|
|
1555
|
+
'CONTRACT.INTROSPECTION_UNSUPPORTED',
|
|
1552
1556
|
`Unknown PostgreSQL referential action rule: "${rule}". Expected one of: NO ACTION, RESTRICT, CASCADE, SET NULL, SET DEFAULT.`,
|
|
1557
|
+
{ meta: { rule } },
|
|
1553
1558
|
);
|
|
1554
1559
|
}
|
|
1555
1560
|
if (mapped === 'noAction') return undefined;
|
|
@@ -1620,8 +1625,10 @@ export function parsePgReloptions(
|
|
|
1620
1625
|
for (const entry of reloptions) {
|
|
1621
1626
|
const eq = entry.indexOf('=');
|
|
1622
1627
|
if (eq === -1) {
|
|
1623
|
-
throw
|
|
1628
|
+
throw adapterError(
|
|
1629
|
+
'CONTRACT.INTROSPECTION_UNSUPPORTED',
|
|
1624
1630
|
`Postgres introspection: malformed reloption entry "${entry}" on index "${indexName}" (expected "key=value")`,
|
|
1631
|
+
{ meta: { entry, indexName } },
|
|
1625
1632
|
);
|
|
1626
1633
|
}
|
|
1627
1634
|
const key = entry.slice(0, eq);
|
|
@@ -1777,8 +1784,10 @@ function pgInlineLiteral(wire: unknown, nativeType: string): string {
|
|
|
1777
1784
|
if (typeof wire === 'boolean') return wire ? 'true' : 'false';
|
|
1778
1785
|
if (typeof wire === 'number') {
|
|
1779
1786
|
if (!Number.isFinite(wire)) {
|
|
1780
|
-
throw
|
|
1787
|
+
throw adapterError(
|
|
1788
|
+
'CONTRACT.DEFAULT_INVALID',
|
|
1781
1789
|
`pgRenderDdlExecuteRequest: non-finite number wire value ${String(wire)} cannot be emitted as a DEFAULT literal for native type "${nativeType}"`,
|
|
1790
|
+
{ meta: { nativeType } },
|
|
1782
1791
|
);
|
|
1783
1792
|
}
|
|
1784
1793
|
return String(wire);
|
|
@@ -1786,8 +1795,10 @@ function pgInlineLiteral(wire: unknown, nativeType: string): string {
|
|
|
1786
1795
|
if (typeof wire === 'bigint') return String(wire);
|
|
1787
1796
|
if (wire instanceof Date) {
|
|
1788
1797
|
if (Number.isNaN(wire.getTime())) {
|
|
1789
|
-
throw
|
|
1798
|
+
throw adapterError(
|
|
1799
|
+
'CONTRACT.DEFAULT_INVALID',
|
|
1790
1800
|
`pgRenderDdlExecuteRequest: invalid Date value cannot be emitted as a DEFAULT literal for native type "${nativeType}"`,
|
|
1801
|
+
{ meta: { nativeType } },
|
|
1791
1802
|
);
|
|
1792
1803
|
}
|
|
1793
1804
|
const quoted = `'${escapeLiteral(wire.toISOString())}'`;
|
|
@@ -1810,8 +1821,10 @@ function pgInlineLiteral(wire: unknown, nativeType: string): string {
|
|
|
1810
1821
|
const quoted = `'${escapeLiteral(JSON.stringify(wire))}'`;
|
|
1811
1822
|
return `${quoted}::${nativeType}`;
|
|
1812
1823
|
}
|
|
1813
|
-
throw
|
|
1824
|
+
throw adapterError(
|
|
1825
|
+
'CONTRACT.PACK_CONTRIBUTION_INVALID',
|
|
1814
1826
|
`pgRenderDdlExecuteRequest: unexpected wire type "${typeof wire}" for native type "${nativeType}"`,
|
|
1827
|
+
{ meta: { wireType: typeof wire, nativeType } },
|
|
1815
1828
|
);
|
|
1816
1829
|
}
|
|
1817
1830
|
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
encodeParamsWithMetadata,
|
|
10
10
|
} from '@prisma-next/sql-runtime';
|
|
11
11
|
import { postgresCodecRegistry } from '@prisma-next/target-postgres/codecs';
|
|
12
|
+
import { InternalError } from '@prisma-next/utils/internal-error';
|
|
12
13
|
|
|
13
14
|
export const CONTROL_CODECS = createAstCodecRegistry(postgresCodecRegistry);
|
|
14
15
|
|
|
@@ -19,7 +20,9 @@ export async function encodeControlQueryParams(
|
|
|
19
20
|
): Promise<readonly unknown[]> {
|
|
20
21
|
const values = lowered.params.map((slot) => {
|
|
21
22
|
if (slot.kind === 'literal') return slot.value;
|
|
22
|
-
throw new
|
|
23
|
+
throw new InternalError(
|
|
24
|
+
`control query lowered to a bind slot '${slot.name}', which is unsupported`,
|
|
25
|
+
);
|
|
23
26
|
});
|
|
24
27
|
return encodeParamsWithMetadata(values, deriveParamMetadata(ast), {}, codecs);
|
|
25
28
|
}
|
|
@@ -40,6 +40,7 @@ import {
|
|
|
40
40
|
} from '@prisma-next/target-postgres/codec-ids';
|
|
41
41
|
import { postgresCodecRegistry } from '@prisma-next/target-postgres/codecs';
|
|
42
42
|
import type { QueryOperationTypes } from '../types/operation-types';
|
|
43
|
+
import { adapterError } from './adapter-errors';
|
|
43
44
|
|
|
44
45
|
// ============================================================================ Helper functions for reducing boilerplate ============================================================================
|
|
45
46
|
|
|
@@ -69,8 +70,10 @@ function expandLength({ nativeType, typeParams }: ExpandNativeTypeInput): string
|
|
|
69
70
|
}
|
|
70
71
|
const length = typeParams['length'];
|
|
71
72
|
if (!isPositiveInteger(length)) {
|
|
72
|
-
throw
|
|
73
|
+
throw adapterError(
|
|
74
|
+
'RUNTIME.TYPE_PARAMS_INVALID',
|
|
73
75
|
`Invalid "length" type parameter for "${nativeType}": expected a positive integer, got ${JSON.stringify(length)}`,
|
|
76
|
+
{ meta: { nativeType, param: 'length', received: length } },
|
|
74
77
|
);
|
|
75
78
|
}
|
|
76
79
|
return `${nativeType}(${length})`;
|
|
@@ -82,8 +85,10 @@ function expandPrecision({ nativeType, typeParams }: ExpandNativeTypeInput): str
|
|
|
82
85
|
}
|
|
83
86
|
const precision = typeParams['precision'];
|
|
84
87
|
if (!isPositiveInteger(precision)) {
|
|
85
|
-
throw
|
|
88
|
+
throw adapterError(
|
|
89
|
+
'RUNTIME.TYPE_PARAMS_INVALID',
|
|
86
90
|
`Invalid "precision" type parameter for "${nativeType}": expected a positive integer, got ${JSON.stringify(precision)}`,
|
|
91
|
+
{ meta: { nativeType, param: 'precision', received: precision } },
|
|
87
92
|
);
|
|
88
93
|
}
|
|
89
94
|
return `${nativeType}(${precision})`;
|
|
@@ -98,23 +103,29 @@ function expandNumeric({ nativeType, typeParams }: ExpandNativeTypeInput): strin
|
|
|
98
103
|
}
|
|
99
104
|
|
|
100
105
|
if (!hasPrecision && hasScale) {
|
|
101
|
-
throw
|
|
106
|
+
throw adapterError(
|
|
107
|
+
'RUNTIME.TYPE_PARAMS_INVALID',
|
|
102
108
|
`Invalid type parameters for "${nativeType}": "scale" requires "precision" to be specified`,
|
|
109
|
+
{ meta: { nativeType, param: 'scale' } },
|
|
103
110
|
);
|
|
104
111
|
}
|
|
105
112
|
|
|
106
113
|
if (hasPrecision) {
|
|
107
114
|
const precision = typeParams['precision'];
|
|
108
115
|
if (!isPositiveInteger(precision)) {
|
|
109
|
-
throw
|
|
116
|
+
throw adapterError(
|
|
117
|
+
'RUNTIME.TYPE_PARAMS_INVALID',
|
|
110
118
|
`Invalid "precision" type parameter for "${nativeType}": expected a positive integer, got ${JSON.stringify(precision)}`,
|
|
119
|
+
{ meta: { nativeType, param: 'precision', received: precision } },
|
|
111
120
|
);
|
|
112
121
|
}
|
|
113
122
|
if (hasScale) {
|
|
114
123
|
const scale = typeParams['scale'];
|
|
115
124
|
if (!isNonNegativeInteger(scale)) {
|
|
116
|
-
throw
|
|
125
|
+
throw adapterError(
|
|
126
|
+
'RUNTIME.TYPE_PARAMS_INVALID',
|
|
117
127
|
`Invalid "scale" type parameter for "${nativeType}": expected a non-negative integer, got ${JSON.stringify(scale)}`,
|
|
128
|
+
{ meta: { nativeType, param: 'scale', received: scale } },
|
|
118
129
|
);
|
|
119
130
|
}
|
|
120
131
|
return `${nativeType}(${precision},${scale})`;
|
package/src/core/sql-renderer.ts
CHANGED
|
@@ -44,6 +44,8 @@ import {
|
|
|
44
44
|
quoteQualifiedName,
|
|
45
45
|
} from '@prisma-next/target-postgres/sql-utils';
|
|
46
46
|
import { ifDefined } from '@prisma-next/utils/defined';
|
|
47
|
+
import { assertNever, InternalError } from '@prisma-next/utils/internal-error';
|
|
48
|
+
import { adapterError } from './adapter-errors';
|
|
47
49
|
import type { PostgresContract } from './types';
|
|
48
50
|
|
|
49
51
|
/**
|
|
@@ -95,13 +97,15 @@ function renderTypedParam(
|
|
|
95
97
|
meta !== undefined ||
|
|
96
98
|
codecLookup.targetTypesFor(codecId) !== undefined;
|
|
97
99
|
if (!isRegistered) {
|
|
98
|
-
throw
|
|
100
|
+
throw adapterError(
|
|
101
|
+
'RUNTIME.PARAM_REF_MISSING_CODEC',
|
|
99
102
|
`Postgres lowering: ParamRef carries codecId "${codecId}" but the ` +
|
|
100
103
|
'assembled codec lookup has no entry for it. This usually indicates ' +
|
|
101
104
|
'a missing extension pack in the runtime stack — register the pack ' +
|
|
102
105
|
'that contributes this codec (e.g. `extensions: [pgvectorRuntime]`), ' +
|
|
103
106
|
'or use the codec directly from `@prisma-next/target-postgres/codecs` ' +
|
|
104
107
|
"if it's a builtin.",
|
|
108
|
+
{ meta: { codecId } },
|
|
105
109
|
);
|
|
106
110
|
}
|
|
107
111
|
// `typeParams` above already resolved a parameterized codec's per-instance
|
|
@@ -201,7 +205,7 @@ export function renderLoweredSql(
|
|
|
201
205
|
break;
|
|
202
206
|
// v8 ignore next 4
|
|
203
207
|
default:
|
|
204
|
-
|
|
208
|
+
assertNever(node, `Unsupported AST node kind: ${unreachableKind(node)}`);
|
|
205
209
|
}
|
|
206
210
|
|
|
207
211
|
return Object.freeze({ sql, params: Object.freeze(params) });
|
|
@@ -460,14 +464,18 @@ function qualifyTableFromNamespaceCoordinate(
|
|
|
460
464
|
}
|
|
461
465
|
const namespace = contract.storage.namespaces[table.namespaceId];
|
|
462
466
|
if (namespace === undefined) {
|
|
463
|
-
throw
|
|
467
|
+
throw adapterError(
|
|
468
|
+
'RUNTIME.NAMESPACE_UNKNOWN',
|
|
464
469
|
`Table "${table.name}" references namespace "${table.namespaceId}" which is not present as a Postgres schema on the contract`,
|
|
470
|
+
{ meta: { table: table.name, namespaceId: table.namespaceId, reason: 'not-present' } },
|
|
465
471
|
);
|
|
466
472
|
}
|
|
467
473
|
const qualifyTable = namespace.qualifyTable;
|
|
468
474
|
if (qualifyTable === undefined) {
|
|
469
|
-
throw
|
|
475
|
+
throw adapterError(
|
|
476
|
+
'RUNTIME.NAMESPACE_UNKNOWN',
|
|
470
477
|
`Table "${table.name}" references namespace "${table.namespaceId}" which is not materialised as a Postgres schema on the contract`,
|
|
478
|
+
{ meta: { table: table.name, namespaceId: table.namespaceId, reason: 'not-materialised' } },
|
|
471
479
|
);
|
|
472
480
|
}
|
|
473
481
|
return qualifyTable.call(namespace, table.name);
|
|
@@ -505,13 +513,17 @@ function renderSource(
|
|
|
505
513
|
}
|
|
506
514
|
// v8 ignore next 4
|
|
507
515
|
default:
|
|
508
|
-
|
|
516
|
+
assertNever(node, `Unsupported source node kind: ${unreachableKind(node)}`);
|
|
509
517
|
}
|
|
510
518
|
}
|
|
511
519
|
|
|
512
520
|
function assertScalarSubquery(query: SelectAst): void {
|
|
513
521
|
if (query.projection.length !== 1) {
|
|
514
|
-
throw
|
|
522
|
+
throw adapterError(
|
|
523
|
+
'RUNTIME.AST_INVALID',
|
|
524
|
+
'Subquery expressions must project exactly one column',
|
|
525
|
+
{ meta: { node: 'subquery-expr' } },
|
|
526
|
+
);
|
|
515
527
|
}
|
|
516
528
|
}
|
|
517
529
|
|
|
@@ -816,14 +828,14 @@ function renderExpr(expr: AnyExpression, contract: PostgresContract, pim: ParamI
|
|
|
816
828
|
return renderRawExpr(node, contract, pim);
|
|
817
829
|
// v8 ignore next 4
|
|
818
830
|
default:
|
|
819
|
-
|
|
831
|
+
assertNever(node, `Unsupported expression node kind: ${unreachableKind(node)}`);
|
|
820
832
|
}
|
|
821
833
|
}
|
|
822
834
|
|
|
823
835
|
function renderParamRef(ref: AnyParamRef, pim: ParamIndexMap): string {
|
|
824
836
|
const index = pim.indexMap.get(ref);
|
|
825
837
|
if (index === undefined) {
|
|
826
|
-
throw new
|
|
838
|
+
throw new InternalError('ParamRef not found in index map');
|
|
827
839
|
}
|
|
828
840
|
if (ref.kind === 'prepared-param-ref') {
|
|
829
841
|
return renderTypedParam(
|
|
@@ -900,8 +912,10 @@ function renderOperation(
|
|
|
900
912
|
}
|
|
901
913
|
const arg = args[Number(argIndex)];
|
|
902
914
|
if (arg === undefined) {
|
|
903
|
-
throw
|
|
915
|
+
throw adapterError(
|
|
916
|
+
'CONTRACT.PACK_CONTRIBUTION_INVALID',
|
|
904
917
|
`Operation lowering template for "${expr.method}" referenced missing argument {{arg${argIndex}}}; template has ${args.length} arg(s)`,
|
|
918
|
+
{ meta: { method: expr.method } },
|
|
905
919
|
);
|
|
906
920
|
}
|
|
907
921
|
return arg;
|
|
@@ -964,7 +978,11 @@ function getInsertColumnOrder(
|
|
|
964
978
|
}
|
|
965
979
|
}
|
|
966
980
|
if (!table) {
|
|
967
|
-
throw
|
|
981
|
+
throw adapterError(
|
|
982
|
+
'RUNTIME.AST_INVALID',
|
|
983
|
+
`INSERT target table not found in contract storage: ${tableName}`,
|
|
984
|
+
{ meta: { node: 'insert', table: tableName } },
|
|
985
|
+
);
|
|
968
986
|
}
|
|
969
987
|
return Object.keys(table.columns);
|
|
970
988
|
}
|
|
@@ -988,7 +1006,7 @@ function renderInsertValue(
|
|
|
988
1006
|
return renderExpr(value, contract, pim);
|
|
989
1007
|
// v8 ignore next 4
|
|
990
1008
|
default:
|
|
991
|
-
|
|
1009
|
+
assertNever(value, `Unsupported value node in INSERT: ${unreachableKind(value)}`);
|
|
992
1010
|
}
|
|
993
1011
|
}
|
|
994
1012
|
|
|
@@ -996,7 +1014,9 @@ function renderInsert(ast: InsertAst, contract: PostgresContract, pim: ParamInde
|
|
|
996
1014
|
const table = qualifyTableFromNamespaceCoordinate(ast.table, contract);
|
|
997
1015
|
const rows = ast.rows;
|
|
998
1016
|
if (rows.length === 0) {
|
|
999
|
-
throw
|
|
1017
|
+
throw adapterError('RUNTIME.AST_INVALID', 'INSERT requires at least one row', {
|
|
1018
|
+
meta: { node: 'insert' },
|
|
1019
|
+
});
|
|
1000
1020
|
}
|
|
1001
1021
|
const hasExplicitValues = rows.some((row) => Object.keys(row).length > 0);
|
|
1002
1022
|
const insertClause = (() => {
|
|
@@ -1034,7 +1054,11 @@ function renderInsert(ast: InsertAst, contract: PostgresContract, pim: ParamInde
|
|
|
1034
1054
|
? (() => {
|
|
1035
1055
|
const conflictColumns = ast.onConflict.columns.map((col) => quoteIdentifier(col.column));
|
|
1036
1056
|
if (conflictColumns.length === 0) {
|
|
1037
|
-
throw
|
|
1057
|
+
throw adapterError(
|
|
1058
|
+
'RUNTIME.AST_INVALID',
|
|
1059
|
+
'INSERT onConflict requires at least one conflict column',
|
|
1060
|
+
{ meta: { node: 'insert-on-conflict' } },
|
|
1061
|
+
);
|
|
1038
1062
|
}
|
|
1039
1063
|
|
|
1040
1064
|
const action = ast.onConflict.action;
|
|
@@ -1044,7 +1068,11 @@ function renderInsert(ast: InsertAst, contract: PostgresContract, pim: ParamInde
|
|
|
1044
1068
|
case 'do-update-set': {
|
|
1045
1069
|
const updateEntries = Object.entries(action.set);
|
|
1046
1070
|
if (updateEntries.length === 0) {
|
|
1047
|
-
throw
|
|
1071
|
+
throw adapterError(
|
|
1072
|
+
'RUNTIME.AST_INVALID',
|
|
1073
|
+
'INSERT onConflict do-update-set requires at least one assignment',
|
|
1074
|
+
{ meta: { node: 'insert-on-conflict' } },
|
|
1075
|
+
);
|
|
1048
1076
|
}
|
|
1049
1077
|
const updates = updateEntries.map(([colName, value]) => {
|
|
1050
1078
|
return `${quoteIdentifier(colName)} = ${renderExpr(value, contract, pim)}`;
|
|
@@ -1053,7 +1081,7 @@ function renderInsert(ast: InsertAst, contract: PostgresContract, pim: ParamInde
|
|
|
1053
1081
|
}
|
|
1054
1082
|
// v8 ignore next 4
|
|
1055
1083
|
default:
|
|
1056
|
-
|
|
1084
|
+
assertNever(action, `Unsupported onConflict action: ${unreachableKind(action)}`);
|
|
1057
1085
|
}
|
|
1058
1086
|
})()
|
|
1059
1087
|
: '';
|
|
@@ -1068,7 +1096,9 @@ function renderUpdate(ast: UpdateAst, contract: PostgresContract, pim: ParamInde
|
|
|
1068
1096
|
const table = qualifyTableFromNamespaceCoordinate(ast.table, contract);
|
|
1069
1097
|
const setEntries = Object.entries(ast.set);
|
|
1070
1098
|
if (setEntries.length === 0) {
|
|
1071
|
-
throw
|
|
1099
|
+
throw adapterError('RUNTIME.AST_INVALID', 'UPDATE requires at least one SET assignment', {
|
|
1100
|
+
meta: { node: 'update' },
|
|
1101
|
+
});
|
|
1072
1102
|
}
|
|
1073
1103
|
const setClauses = setEntries.map(([col, val]) => {
|
|
1074
1104
|
const column = quoteIdentifier(col);
|
package/src/exports/control.ts
CHANGED
|
@@ -4,7 +4,6 @@ import {
|
|
|
4
4
|
escapeLiteral,
|
|
5
5
|
qualifyName,
|
|
6
6
|
quoteIdentifier,
|
|
7
|
-
SqlEscapeError,
|
|
8
7
|
} from '@prisma-next/target-postgres/sql-utils';
|
|
9
8
|
import { PostgresControlAdapter } from '../core/control-adapter';
|
|
10
9
|
import {
|
|
@@ -32,4 +31,4 @@ export { parsePostgresDefault } from '@prisma-next/target-postgres/default-norma
|
|
|
32
31
|
export { normalizeSchemaNativeType } from '@prisma-next/target-postgres/native-type-normalizer';
|
|
33
32
|
export { createPostgresBuiltinCodecLookup } from '../core/codec-lookup';
|
|
34
33
|
export { PostgresControlAdapter } from '../core/control-adapter';
|
|
35
|
-
export { escapeLiteral, qualifyName, quoteIdentifier
|
|
34
|
+
export { escapeLiteral, qualifyName, quoteIdentifier };
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"adapter-DcBWxseT.mjs","names":[],"sources":["../src/core/adapter.ts"],"sourcesContent":["import type { CodecRegistry } from '@prisma-next/framework-components/codec';\nimport { APP_SPACE_ID } from '@prisma-next/framework-components/control';\nimport type {\n Adapter,\n AdapterProfile,\n AnyQueryAst,\n LowererContext,\n RawSqlLiteral,\n SqlQueryable,\n} from '@prisma-next/sql-relational-core/ast';\nimport { isDdlNode } from '@prisma-next/sql-relational-core/ast';\nimport type { RawCodecInferer } from '@prisma-next/sql-relational-core/expression';\nimport type { PostgresDdlNode } from '@prisma-next/target-postgres/ddl';\nimport { createPostgresBuiltinCodecLookup } from './codec-lookup';\nimport { PostgresControlAdapter } from './control-adapter';\nimport { renderLoweredSql } from './sql-renderer';\nimport type { PostgresAdapterOptions, PostgresContract, PostgresLoweredStatement } from './types';\n\nconst defaultCapabilities = Object.freeze({\n postgres: {\n orderBy: true,\n limit: true,\n lateral: true,\n jsonAgg: true,\n returning: true,\n distinctOn: true,\n },\n sql: {\n enums: true,\n returning: true,\n defaultInInsert: true,\n lateral: true,\n scalarList: true,\n },\n});\n\nclass PostgresAdapterImpl\n implements Adapter<AnyQueryAst, PostgresContract, PostgresLoweredStatement>\n{\n // These fields make the adapter instance structurally compatible with RuntimeAdapterInstance<'sql', 'postgres'> without introducing a runtime-plane dependency.\n readonly familyId = 'sql' as const;\n readonly targetId = 'postgres' as const;\n\n readonly profile: AdapterProfile<'postgres'>;\n private readonly codecLookup: CodecRegistry;\n\n constructor(options?: PostgresAdapterOptions) {\n this.codecLookup = options?.codecLookup ?? createPostgresBuiltinCodecLookup();\n const controlAdapter = new PostgresControlAdapter(this.codecLookup);\n this.profile = Object.freeze({\n id: options?.profileId ?? 'postgres/default@1',\n target: 'postgres',\n capabilities: defaultCapabilities,\n readMarker: (queryable: SqlQueryable) =>\n controlAdapter.readMarkerDiscriminated(\n {\n familyId: 'sql',\n targetId: 'postgres',\n query: async <Row = Record<string, unknown>>(\n sql: string,\n params?: readonly unknown[],\n ) => {\n const result = await queryable.query<Row>(sql, params);\n return { rows: [...result.rows] };\n },\n close: async () => {},\n },\n APP_SPACE_ID,\n ),\n });\n }\n\n lower(\n ast: AnyQueryAst | PostgresDdlNode,\n context: LowererContext<PostgresContract>,\n ): PostgresLoweredStatement {\n if (isDdlNode(ast)) {\n throw new Error(\n 'lower() does not lower DDL on the runtime adapter — DDL lowering is a control-plane concern handled by the control adapter.',\n );\n }\n return renderLoweredSql(ast, context.contract, this.codecLookup);\n }\n}\n\n/** Codec-id lookup for bare-literal interpolations used by `fns.raw` on a postgres client. Contributed as the descriptor's static `rawCodecInferer` slot. */\nexport const postgresRawCodecInferer: RawCodecInferer = {\n inferCodec(value: RawSqlLiteral): string {\n switch (typeof value) {\n case 'number':\n return Number.isSafeInteger(value) && value % 1 === 0 ? 'pg/int4' : 'pg/float8';\n case 'bigint':\n return 'pg/int8';\n case 'string':\n return 'pg/text';\n case 'boolean':\n return 'pg/bool';\n case 'object':\n if (value instanceof Uint8Array) return 'pg/bytea';\n }\n throw new Error(\n 'unsupported JS value type for raw-SQL interpolation: wrap this value in `param(...)` with an explicit codec',\n );\n },\n};\n\nexport function createPostgresAdapter(options?: PostgresAdapterOptions) {\n return Object.freeze(new PostgresAdapterImpl(options));\n}\n"],"mappings":";;;;AAkBA,MAAM,sBAAsB,OAAO,OAAO;CACxC,UAAU;EACR,SAAS;EACT,OAAO;EACP,SAAS;EACT,SAAS;EACT,WAAW;EACX,YAAY;CACd;CACA,KAAK;EACH,OAAO;EACP,WAAW;EACX,iBAAiB;EACjB,SAAS;EACT,YAAY;CACd;AACF,CAAC;AAED,IAAM,sBAAN,MAEA;CAEE,WAAoB;CACpB,WAAoB;CAEpB;CACA;CAEA,YAAY,SAAkC;EAC5C,KAAK,cAAc,SAAS,eAAe,iCAAiC;EAC5E,MAAM,iBAAiB,IAAI,uBAAuB,KAAK,WAAW;EAClE,KAAK,UAAU,OAAO,OAAO;GAC3B,IAAI,SAAS,aAAa;GAC1B,QAAQ;GACR,cAAc;GACd,aAAa,cACX,eAAe,wBACb;IACE,UAAU;IACV,UAAU;IACV,OAAO,OACL,KACA,WACG;KAEH,OAAO,EAAE,MAAM,CAAC,IAAG,MADE,UAAU,MAAW,KAAK,MAAM,EAAA,CAC3B,IAAI,EAAE;IAClC;IACA,OAAO,YAAY,CAAC;GACtB,GACA,YACF;EACJ,CAAC;CACH;CAEA,MACE,KACA,SAC0B;EAC1B,IAAI,UAAU,GAAG,GACf,MAAM,IAAI,MACR,6HACF;EAEF,OAAO,iBAAiB,KAAK,QAAQ,UAAU,KAAK,WAAW;CACjE;AACF;;AAGA,MAAa,0BAA2C,EACtD,WAAW,OAA8B;CACvC,QAAQ,OAAO,OAAf;EACE,KAAK,UACH,OAAO,OAAO,cAAc,KAAK,KAAK,QAAQ,MAAM,IAAI,YAAY;EACtE,KAAK,UACH,OAAO;EACT,KAAK,UACH,OAAO;EACT,KAAK,WACH,OAAO;EACT,KAAK,UACH,IAAI,iBAAiB,YAAY,OAAO;CAC5C;CACA,MAAM,IAAI,MACR,6GACF;AACF,EACF;AAEA,SAAgB,sBAAsB,SAAkC;CACtE,OAAO,OAAO,OAAO,IAAI,oBAAoB,OAAO,CAAC;AACvD"}
|