@prisma-next/sql-orm-client 0.5.1 → 0.6.0-dev.17
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/index.d.mts +10 -10
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +43 -77
- package/dist/index.mjs.map +1 -1
- package/package.json +17 -17
- package/src/collection-internal-types.ts +8 -7
- package/src/model-accessor.ts +10 -3
- package/src/query-plan-aggregate.ts +17 -12
- package/src/query-plan-mutations.ts +18 -14
- package/src/query-plan-select.ts +7 -4
- package/src/types.ts +246 -287
- package/src/where-binding.ts +5 -8
package/package.json
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prisma-next/sql-orm-client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0-dev.17",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"description": "ORM client for Prisma Next — fluent, type-safe model collections",
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"@prisma-next/
|
|
10
|
-
"@prisma-next/sql-
|
|
11
|
-
"@prisma-next/
|
|
12
|
-
"@prisma-next/
|
|
13
|
-
"@prisma-next/
|
|
14
|
-
"@prisma-next/sql-
|
|
15
|
-
"@prisma-next/sql-runtime": "0.
|
|
16
|
-
"@prisma-next/utils": "0.
|
|
9
|
+
"@prisma-next/operations": "0.6.0-dev.17",
|
|
10
|
+
"@prisma-next/sql-contract": "0.6.0-dev.17",
|
|
11
|
+
"@prisma-next/framework-components": "0.6.0-dev.17",
|
|
12
|
+
"@prisma-next/sql-operations": "0.6.0-dev.17",
|
|
13
|
+
"@prisma-next/contract": "0.6.0-dev.17",
|
|
14
|
+
"@prisma-next/sql-relational-core": "0.6.0-dev.17",
|
|
15
|
+
"@prisma-next/sql-runtime": "0.6.0-dev.17",
|
|
16
|
+
"@prisma-next/utils": "0.6.0-dev.17"
|
|
17
17
|
},
|
|
18
18
|
"devDependencies": {
|
|
19
19
|
"@types/pg": "8.20.0",
|
|
@@ -21,14 +21,14 @@
|
|
|
21
21
|
"tsdown": "0.22.0",
|
|
22
22
|
"typescript": "5.9.3",
|
|
23
23
|
"vitest": "4.1.5",
|
|
24
|
-
"@prisma-next/
|
|
25
|
-
"@prisma-next/driver-postgres": "0.
|
|
26
|
-
"@prisma-next/
|
|
27
|
-
"@prisma-next/
|
|
28
|
-
"@prisma-next/
|
|
29
|
-
"@prisma-next/
|
|
30
|
-
"@prisma-next/ids": "0.
|
|
31
|
-
"@prisma-next/
|
|
24
|
+
"@prisma-next/extension-pgvector": "0.6.0-dev.17",
|
|
25
|
+
"@prisma-next/driver-postgres": "0.6.0-dev.17",
|
|
26
|
+
"@prisma-next/cli": "0.6.0-dev.17",
|
|
27
|
+
"@prisma-next/family-sql": "0.6.0-dev.17",
|
|
28
|
+
"@prisma-next/sql-contract-ts": "0.6.0-dev.17",
|
|
29
|
+
"@prisma-next/adapter-postgres": "0.6.0-dev.17",
|
|
30
|
+
"@prisma-next/ids": "0.6.0-dev.17",
|
|
31
|
+
"@prisma-next/target-postgres": "0.6.0-dev.17",
|
|
32
32
|
"@prisma-next/test-utils": "0.0.1",
|
|
33
33
|
"@prisma-next/tsdown": "0.0.0",
|
|
34
34
|
"@prisma-next/tsconfig": "0.0.0"
|
|
@@ -109,13 +109,14 @@ export type IncludeRefinementValue<
|
|
|
109
109
|
RelName extends string,
|
|
110
110
|
DefaultIncludedRow,
|
|
111
111
|
RefinedResult,
|
|
112
|
-
> =
|
|
113
|
-
|
|
114
|
-
//
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
112
|
+
> =
|
|
113
|
+
RefinedResult extends RowSelection<infer V>
|
|
114
|
+
? // IncludeScalar / IncludeCombine carry a final value that must not be
|
|
115
|
+
// cardinality-wrapped; Collection carries a raw row that still needs it.
|
|
116
|
+
RefinedResult extends { readonly kind: 'includeScalar' | 'includeCombine' }
|
|
117
|
+
? V
|
|
118
|
+
: IncludeRelationValue<TContract, ParentModelName, RelName, V>
|
|
119
|
+
: IncludeRelationValue<TContract, ParentModelName, RelName, DefaultIncludedRow>;
|
|
119
120
|
|
|
120
121
|
export type WhereInput<TContract extends Contract<SqlStorage>, ModelName extends string> =
|
|
121
122
|
| ((model: ModelAccessor<TContract, ModelName>) => AnyExpression)
|
package/src/model-accessor.ts
CHANGED
|
@@ -5,12 +5,14 @@ import {
|
|
|
5
5
|
AndExpr,
|
|
6
6
|
type AnyExpression,
|
|
7
7
|
BinaryExpr,
|
|
8
|
+
type CodecRef,
|
|
8
9
|
ColumnRef,
|
|
9
10
|
ExistsExpr,
|
|
10
11
|
ProjectionItem,
|
|
11
12
|
SelectAst,
|
|
12
13
|
TableSource,
|
|
13
14
|
} from '@prisma-next/sql-relational-core/ast';
|
|
15
|
+
import { codecRefForStorageColumn } from '@prisma-next/sql-relational-core/codec-descriptor-registry';
|
|
14
16
|
import type { Expression, ScopeField } from '@prisma-next/sql-relational-core/expression';
|
|
15
17
|
import type { ExecutionContext } from '@prisma-next/sql-relational-core/query-lane-context';
|
|
16
18
|
import {
|
|
@@ -104,11 +106,13 @@ export function createModelAccessor<
|
|
|
104
106
|
}
|
|
105
107
|
const traits = context.codecDescriptors.descriptorFor(column.codecId)?.traits ?? [];
|
|
106
108
|
const operations = opsByCodecId.get(column.codecId) ?? [];
|
|
109
|
+
const codec = codecRefForStorageColumn(contract.storage, tableName, columnName);
|
|
107
110
|
return createScalarFieldAccessor(
|
|
108
111
|
tableName,
|
|
109
112
|
columnName,
|
|
110
113
|
column.codecId,
|
|
111
114
|
column.nullable,
|
|
115
|
+
codec,
|
|
112
116
|
traits,
|
|
113
117
|
operations,
|
|
114
118
|
context,
|
|
@@ -132,6 +136,7 @@ function createScalarFieldAccessor(
|
|
|
132
136
|
columnName: string,
|
|
133
137
|
codecId: string,
|
|
134
138
|
nullable: boolean,
|
|
139
|
+
codec: CodecRef | undefined,
|
|
135
140
|
traits: readonly string[],
|
|
136
141
|
operations: readonly NamedOp[],
|
|
137
142
|
context: ExecutionContext,
|
|
@@ -140,11 +145,12 @@ function createScalarFieldAccessor(
|
|
|
140
145
|
const comparisonEntries: Array<[string, unknown]> = [];
|
|
141
146
|
for (const [name, meta] of Object.entries(COMPARISON_METHODS_META)) {
|
|
142
147
|
if (meta.traits.some((t) => !traits.includes(t))) continue;
|
|
143
|
-
comparisonEntries.push([name, meta.create(column,
|
|
148
|
+
comparisonEntries.push([name, meta.create(column, codec)]);
|
|
144
149
|
}
|
|
145
150
|
|
|
146
151
|
const accessor = {
|
|
147
|
-
returnType: { codecId, nullable },
|
|
152
|
+
returnType: { codecId, nullable, codec },
|
|
153
|
+
codec,
|
|
148
154
|
buildAst: () => column,
|
|
149
155
|
...Object.fromEntries(comparisonEntries),
|
|
150
156
|
} as Expression<ScopeField> & Record<string, unknown>;
|
|
@@ -178,10 +184,11 @@ function createExtensionMethodFactory(
|
|
|
178
184
|
}
|
|
179
185
|
|
|
180
186
|
const resultAst = result.buildAst();
|
|
187
|
+
const returnCodec: CodecRef = { codecId: returnCodecId };
|
|
181
188
|
const methods: Record<string, unknown> = {};
|
|
182
189
|
for (const [resultMethodName, meta] of Object.entries(COMPARISON_METHODS_META)) {
|
|
183
190
|
if (meta.traits.some((t) => !returnTraits.includes(t))) continue;
|
|
184
|
-
methods[resultMethodName] = meta.create(resultAst,
|
|
191
|
+
methods[resultMethodName] = meta.create(resultAst, returnCodec);
|
|
185
192
|
}
|
|
186
193
|
return methods;
|
|
187
194
|
};
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
AndExpr,
|
|
6
6
|
type AnyExpression,
|
|
7
7
|
BinaryExpr,
|
|
8
|
+
type CodecRef,
|
|
8
9
|
ColumnRef,
|
|
9
10
|
NotExpr,
|
|
10
11
|
NullCheckExpr,
|
|
@@ -13,6 +14,7 @@ import {
|
|
|
13
14
|
SelectAst,
|
|
14
15
|
TableSource,
|
|
15
16
|
} from '@prisma-next/sql-relational-core/ast';
|
|
17
|
+
import { codecRefForStorageColumn } from '@prisma-next/sql-relational-core/codec-descriptor-registry';
|
|
16
18
|
import type { SqlQueryPlan } from '@prisma-next/sql-relational-core/plan';
|
|
17
19
|
import { buildOrmQueryPlan, deriveParamsFromAst } from './query-plan-meta';
|
|
18
20
|
import type { AggregateSelector } from './types';
|
|
@@ -22,11 +24,11 @@ function toAggregateProjection(
|
|
|
22
24
|
contract: Contract<SqlStorage>,
|
|
23
25
|
tableName: string,
|
|
24
26
|
selector: AggregateSelector<unknown>,
|
|
25
|
-
): { expr: AggregateExpr;
|
|
27
|
+
): { expr: AggregateExpr; codec: CodecRef | undefined } {
|
|
26
28
|
if (selector.fn === 'count') {
|
|
27
29
|
// count() returns a target-specific bigint; mapping isn't derivable here
|
|
28
|
-
// without target coupling, so we leave
|
|
29
|
-
return { expr: AggregateExpr.count(),
|
|
30
|
+
// without target coupling, so we leave the codec slot empty.
|
|
31
|
+
return { expr: AggregateExpr.count(), codec: undefined };
|
|
30
32
|
}
|
|
31
33
|
|
|
32
34
|
if (!selector.column) {
|
|
@@ -38,10 +40,10 @@ function toAggregateProjection(
|
|
|
38
40
|
// sum widens (int4 → int8 in Postgres) and avg → numeric; both need
|
|
39
41
|
// target+input-aware mapping that doesn't exist yet, so leave unstamped.
|
|
40
42
|
if (selector.fn === 'min' || selector.fn === 'max') {
|
|
41
|
-
const
|
|
42
|
-
return { expr,
|
|
43
|
+
const codec = codecRefForStorageColumn(contract.storage, tableName, selector.column);
|
|
44
|
+
return { expr, codec };
|
|
43
45
|
}
|
|
44
|
-
return { expr,
|
|
46
|
+
return { expr, codec: undefined };
|
|
45
47
|
}
|
|
46
48
|
|
|
47
49
|
// ORM HAVING filters use literal binding (values inlined at plan-build time),
|
|
@@ -130,8 +132,8 @@ export function compileAggregate(
|
|
|
130
132
|
}
|
|
131
133
|
|
|
132
134
|
const projection: ProjectionItem[] = entries.map(([alias, selector]) => {
|
|
133
|
-
const { expr,
|
|
134
|
-
return ProjectionItem.of(alias, expr,
|
|
135
|
+
const { expr, codec } = toAggregateProjection(contract, tableName, selector);
|
|
136
|
+
return ProjectionItem.of(alias, expr, codec);
|
|
135
137
|
});
|
|
136
138
|
let ast = SelectAst.from(TableSource.named(tableName)).withProjection(projection);
|
|
137
139
|
const where = combineWhereExprs(filters);
|
|
@@ -160,14 +162,17 @@ export function compileGroupedAggregate(
|
|
|
160
162
|
throw new Error('groupBy().aggregate() requires at least one aggregation selector');
|
|
161
163
|
}
|
|
162
164
|
|
|
163
|
-
const table = contract.storage.tables[tableName];
|
|
164
165
|
const projection: ProjectionItem[] = [
|
|
165
166
|
...groupByColumns.map((column) =>
|
|
166
|
-
ProjectionItem.of(
|
|
167
|
+
ProjectionItem.of(
|
|
168
|
+
column,
|
|
169
|
+
ColumnRef.of(tableName, column),
|
|
170
|
+
codecRefForStorageColumn(contract.storage, tableName, column),
|
|
171
|
+
),
|
|
167
172
|
),
|
|
168
173
|
...entries.map(([alias, selector]) => {
|
|
169
|
-
const { expr,
|
|
170
|
-
return ProjectionItem.of(alias, expr,
|
|
174
|
+
const { expr, codec } = toAggregateProjection(contract, tableName, selector);
|
|
175
|
+
return ProjectionItem.of(alias, expr, codec);
|
|
171
176
|
}),
|
|
172
177
|
];
|
|
173
178
|
|
|
@@ -12,7 +12,9 @@ import {
|
|
|
12
12
|
TableSource,
|
|
13
13
|
UpdateAst,
|
|
14
14
|
} from '@prisma-next/sql-relational-core/ast';
|
|
15
|
+
import { codecRefForStorageColumn } from '@prisma-next/sql-relational-core/codec-descriptor-registry';
|
|
15
16
|
import type { SqlQueryPlan } from '@prisma-next/sql-relational-core/plan';
|
|
17
|
+
import { ifDefined } from '@prisma-next/utils/defined';
|
|
16
18
|
import { buildOrmQueryPlan, deriveParamsFromAst, resolveTableColumns } from './query-plan-meta';
|
|
17
19
|
import { combineWhereExprs } from './where-utils';
|
|
18
20
|
|
|
@@ -26,9 +28,12 @@ function buildReturningColumns(
|
|
|
26
28
|
? [...returningColumns]
|
|
27
29
|
: resolveTableColumns(contract, tableName);
|
|
28
30
|
|
|
29
|
-
const table = contract.storage.tables[tableName];
|
|
30
31
|
return columns.map((column) =>
|
|
31
|
-
ProjectionItem.of(
|
|
32
|
+
ProjectionItem.of(
|
|
33
|
+
column,
|
|
34
|
+
ColumnRef.of(tableName, column),
|
|
35
|
+
codecRefForStorageColumn(contract.storage, tableName, column),
|
|
36
|
+
),
|
|
32
37
|
);
|
|
33
38
|
}
|
|
34
39
|
|
|
@@ -47,14 +52,13 @@ function toParamAssignments(
|
|
|
47
52
|
}
|
|
48
53
|
|
|
49
54
|
for (const [column, value] of Object.entries(values)) {
|
|
50
|
-
|
|
51
|
-
if (!codecId) {
|
|
55
|
+
if (!table.columns[column]) {
|
|
52
56
|
throw new Error(`Unknown column "${column}" in table "${tableName}"`);
|
|
53
57
|
}
|
|
58
|
+
const codec = codecRefForStorageColumn(contract.storage, tableName, column);
|
|
54
59
|
assignments[column] = ParamRef.of(value, {
|
|
55
60
|
name: column,
|
|
56
|
-
|
|
57
|
-
refs: { table: tableName, column },
|
|
61
|
+
...ifDefined('codec', codec),
|
|
58
62
|
});
|
|
59
63
|
}
|
|
60
64
|
|
|
@@ -85,6 +89,11 @@ function normalizeInsertRows(
|
|
|
85
89
|
}
|
|
86
90
|
}
|
|
87
91
|
|
|
92
|
+
const table = contract.storage.tables[tableName];
|
|
93
|
+
if (!table) {
|
|
94
|
+
throw new Error(`Unknown table "${tableName}"`);
|
|
95
|
+
}
|
|
96
|
+
|
|
88
97
|
const normalizedRows = rows.map((row) => {
|
|
89
98
|
if (orderedColumns.length === 0) {
|
|
90
99
|
return {};
|
|
@@ -93,18 +102,13 @@ function normalizeInsertRows(
|
|
|
93
102
|
const normalizedRow: Record<string, ParamRef | DefaultValueExpr> = {};
|
|
94
103
|
for (const column of orderedColumns) {
|
|
95
104
|
if (Object.hasOwn(row, column)) {
|
|
96
|
-
|
|
97
|
-
if (!table) {
|
|
98
|
-
throw new Error(`Unknown table "${tableName}"`);
|
|
99
|
-
}
|
|
100
|
-
const codecId = table?.columns[column]?.codecId;
|
|
101
|
-
if (!codecId) {
|
|
105
|
+
if (!table.columns[column]) {
|
|
102
106
|
throw new Error(`Unknown column "${column}" in table "${tableName}"`);
|
|
103
107
|
}
|
|
108
|
+
const codec = codecRefForStorageColumn(contract.storage, tableName, column);
|
|
104
109
|
normalizedRow[column] = ParamRef.of(row[column], {
|
|
105
110
|
name: column,
|
|
106
|
-
|
|
107
|
-
refs: { table: tableName, column },
|
|
111
|
+
...ifDefined('codec', codec),
|
|
108
112
|
});
|
|
109
113
|
continue;
|
|
110
114
|
}
|
package/src/query-plan-select.ts
CHANGED
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
SubqueryExpr,
|
|
22
22
|
TableSource,
|
|
23
23
|
} from '@prisma-next/sql-relational-core/ast';
|
|
24
|
+
import { codecRefForStorageColumn } from '@prisma-next/sql-relational-core/codec-descriptor-registry';
|
|
24
25
|
import type { SqlQueryPlan } from '@prisma-next/sql-relational-core/plan';
|
|
25
26
|
import {
|
|
26
27
|
type PolymorphismInfo,
|
|
@@ -49,9 +50,12 @@ function buildProjection(
|
|
|
49
50
|
? [...selectedFields]
|
|
50
51
|
: resolveTableColumns(contract, tableName);
|
|
51
52
|
|
|
52
|
-
const table = contract.storage.tables[tableName];
|
|
53
53
|
return columns.map((column) =>
|
|
54
|
-
ProjectionItem.of(
|
|
54
|
+
ProjectionItem.of(
|
|
55
|
+
column,
|
|
56
|
+
ColumnRef.of(tableRef, column),
|
|
57
|
+
codecRefForStorageColumn(contract.storage, tableName, column),
|
|
58
|
+
),
|
|
55
59
|
);
|
|
56
60
|
}
|
|
57
61
|
|
|
@@ -406,7 +410,6 @@ function buildMtiJoins(
|
|
|
406
410
|
joins.push(join);
|
|
407
411
|
|
|
408
412
|
const variantColumns = resolveTableColumns(contract, variant.table);
|
|
409
|
-
const variantTable = contract.storage.tables[variant.table];
|
|
410
413
|
for (const col of variantColumns) {
|
|
411
414
|
if (col === pkColumn) continue;
|
|
412
415
|
const alias = `${variant.table}__${col}`;
|
|
@@ -414,7 +417,7 @@ function buildMtiJoins(
|
|
|
414
417
|
ProjectionItem.of(
|
|
415
418
|
alias,
|
|
416
419
|
ColumnRef.of(variant.table, col),
|
|
417
|
-
|
|
420
|
+
codecRefForStorageColumn(contract.storage, variant.table, col),
|
|
418
421
|
),
|
|
419
422
|
);
|
|
420
423
|
}
|