@prisma-next/sql-runtime 0.13.0-dev.2 → 0.13.0-dev.21
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/README.md +24 -43
- package/dist/{exports-DDqF-xmg.mjs → exports-QqFFY55a.mjs} +50 -58
- package/dist/exports-QqFFY55a.mjs.map +1 -0
- package/dist/index.d.mts +80 -2
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +2 -2
- package/dist/{index-JOQlRa75.d.mts → prepared-statement-mcZG_0rC.d.mts} +171 -106
- package/dist/prepared-statement-mcZG_0rC.d.mts.map +1 -0
- package/dist/test/utils.d.mts +16 -5
- package/dist/test/utils.d.mts.map +1 -1
- package/dist/test/utils.mjs +21 -2
- package/dist/test/utils.mjs.map +1 -1
- package/package.json +12 -12
- package/src/codecs/ast-codec-resolver.ts +2 -44
- package/src/exports/index.ts +6 -2
- package/src/runtime-spi.ts +1 -1
- package/src/sql-runtime.ts +39 -48
- package/dist/exports-DDqF-xmg.mjs.map +0 -1
- package/dist/index-JOQlRa75.d.mts.map +0 -1
package/package.json
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prisma-next/sql-runtime",
|
|
3
|
-
"version": "0.13.0-dev.
|
|
3
|
+
"version": "0.13.0-dev.21",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"description": "SQL runtime implementation for Prisma Next",
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"@prisma-next/contract": "0.13.0-dev.
|
|
10
|
-
"@prisma-next/utils": "0.13.0-dev.
|
|
11
|
-
"@prisma-next/framework-components": "0.13.0-dev.
|
|
12
|
-
"@prisma-next/ids": "0.13.0-dev.
|
|
13
|
-
"@prisma-next/operations": "0.13.0-dev.
|
|
14
|
-
"@prisma-next/sql-contract": "0.13.0-dev.
|
|
15
|
-
"@prisma-next/sql-operations": "0.13.0-dev.
|
|
16
|
-
"@prisma-next/sql-relational-core": "0.13.0-dev.
|
|
9
|
+
"@prisma-next/contract": "0.13.0-dev.21",
|
|
10
|
+
"@prisma-next/utils": "0.13.0-dev.21",
|
|
11
|
+
"@prisma-next/framework-components": "0.13.0-dev.21",
|
|
12
|
+
"@prisma-next/ids": "0.13.0-dev.21",
|
|
13
|
+
"@prisma-next/operations": "0.13.0-dev.21",
|
|
14
|
+
"@prisma-next/sql-contract": "0.13.0-dev.21",
|
|
15
|
+
"@prisma-next/sql-operations": "0.13.0-dev.21",
|
|
16
|
+
"@prisma-next/sql-relational-core": "0.13.0-dev.21",
|
|
17
17
|
"arktype": "^2.2.0"
|
|
18
18
|
},
|
|
19
19
|
"devDependencies": {
|
|
20
|
-
"@prisma-next/test-utils": "0.13.0-dev.
|
|
21
|
-
"@prisma-next/tsconfig": "0.13.0-dev.
|
|
20
|
+
"@prisma-next/test-utils": "0.13.0-dev.21",
|
|
21
|
+
"@prisma-next/tsconfig": "0.13.0-dev.21",
|
|
22
22
|
"@types/pg": "8.20.0",
|
|
23
23
|
"pg": "8.21.0",
|
|
24
|
-
"@prisma-next/tsdown": "0.13.0-dev.
|
|
24
|
+
"@prisma-next/tsdown": "0.13.0-dev.21",
|
|
25
25
|
"tsdown": "0.22.1",
|
|
26
26
|
"typescript": "5.9.3",
|
|
27
27
|
"vitest": "4.1.8"
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { CodecRef } from '@prisma-next/framework-components/codec';
|
|
2
|
+
import { materializeCodec } from '@prisma-next/framework-components/codec';
|
|
2
3
|
import { runtimeError } from '@prisma-next/framework-components/runtime';
|
|
3
4
|
import { canonicalizeJson } from '@prisma-next/framework-components/utils';
|
|
4
5
|
import type { Codec, SqlCodecInstanceContext } from '@prisma-next/sql-relational-core/ast';
|
|
@@ -46,54 +47,11 @@ export function createAstCodecResolver(
|
|
|
46
47
|
);
|
|
47
48
|
}
|
|
48
49
|
|
|
49
|
-
// Parameterized codecs whose paramsSchema accepts `{}` (every field
|
|
50
|
-
// optional, e.g. `pg/timestamptz@1` precision) tolerate refs that omit
|
|
51
|
-
// `typeParams` entirely. Normalize `undefined` to `{}` at the validation
|
|
52
|
-
// boundary; the integrity check upstream already rejected refs whose
|
|
53
|
-
// schemas reject the empty object.
|
|
54
|
-
const validated = validateTypeParams(
|
|
55
|
-
descriptor.paramsSchema,
|
|
56
|
-
descriptor.isParameterized && ref.typeParams === undefined
|
|
57
|
-
? { ...ref, typeParams: {} }
|
|
58
|
-
: ref,
|
|
59
|
-
);
|
|
60
50
|
const ctx = instanceContextFor(ref);
|
|
61
|
-
|
|
62
|
-
const codec = (
|
|
63
|
-
descriptor.factory as (params: unknown) => (ctx: SqlCodecInstanceContext) => Codec
|
|
64
|
-
)(validated)(ctx);
|
|
51
|
+
const codec = materializeCodec(descriptor, ref, ctx);
|
|
65
52
|
|
|
66
53
|
cache.set(key, codec);
|
|
67
54
|
return codec;
|
|
68
55
|
},
|
|
69
56
|
};
|
|
70
57
|
}
|
|
71
|
-
|
|
72
|
-
function validateTypeParams(
|
|
73
|
-
paramsSchema: { '~standard': { validate: (input: unknown) => unknown } },
|
|
74
|
-
ref: CodecRef,
|
|
75
|
-
): unknown {
|
|
76
|
-
const result = paramsSchema['~standard'].validate(ref.typeParams) as
|
|
77
|
-
| { value: unknown }
|
|
78
|
-
| { issues: ReadonlyArray<{ message: string }> }
|
|
79
|
-
| Promise<unknown>;
|
|
80
|
-
|
|
81
|
-
if (result instanceof Promise) {
|
|
82
|
-
throw runtimeError(
|
|
83
|
-
'RUNTIME.TYPE_PARAMS_INVALID',
|
|
84
|
-
`paramsSchema for codec '${ref.codecId}' returned a Promise; runtime validation requires a synchronous Standard Schema validator.`,
|
|
85
|
-
{ codecId: ref.codecId, typeParams: ref.typeParams },
|
|
86
|
-
);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
if ('issues' in result && result.issues) {
|
|
90
|
-
const messages = result.issues.map((issue) => issue.message).join('; ');
|
|
91
|
-
throw runtimeError(
|
|
92
|
-
'RUNTIME.TYPE_PARAMS_INVALID',
|
|
93
|
-
`Invalid typeParams for codec '${ref.codecId}': ${messages}`,
|
|
94
|
-
{ codecId: ref.codecId, typeParams: ref.typeParams },
|
|
95
|
-
);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
return (result as { value: unknown }).value;
|
|
99
|
-
}
|
package/src/exports/index.ts
CHANGED
|
@@ -16,6 +16,10 @@ export { budgets } from '../middleware/budgets';
|
|
|
16
16
|
export type { LintsOptions } from '../middleware/lints';
|
|
17
17
|
export { lints } from '../middleware/lints';
|
|
18
18
|
export type { SqlMiddleware, SqlMiddlewareContext } from '../middleware/sql-middleware';
|
|
19
|
+
export {
|
|
20
|
+
PreparedStatementImpl,
|
|
21
|
+
type PreparedStatementInternals,
|
|
22
|
+
} from '../prepared/prepared-statement';
|
|
19
23
|
export type {
|
|
20
24
|
BindSiteParams,
|
|
21
25
|
Declaration,
|
|
@@ -54,11 +58,11 @@ export {
|
|
|
54
58
|
createSqlExecutionStack,
|
|
55
59
|
} from '../sql-context';
|
|
56
60
|
export type {
|
|
57
|
-
|
|
61
|
+
ConnectionProvider,
|
|
58
62
|
Runtime,
|
|
59
63
|
RuntimeConnection,
|
|
60
64
|
RuntimeQueryable,
|
|
61
65
|
RuntimeTransaction,
|
|
62
66
|
TransactionContext,
|
|
63
67
|
} from '../sql-runtime';
|
|
64
|
-
export {
|
|
68
|
+
export { SqlRuntimeBase, withTransaction } from '../sql-runtime';
|
package/src/runtime-spi.ts
CHANGED
|
@@ -9,7 +9,7 @@ export interface MarkerReader {
|
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
|
-
* SQL family adapter SPI consumed by `
|
|
12
|
+
* SQL family adapter SPI consumed by `SqlRuntimeBase`. Encapsulates the
|
|
13
13
|
* runtime contract, marker reader, and plan validation logic so the
|
|
14
14
|
* runtime can be unit-tested without a concrete SQL adapter profile.
|
|
15
15
|
*
|
package/src/sql-runtime.ts
CHANGED
|
@@ -1,8 +1,4 @@
|
|
|
1
1
|
import type { Contract } from '@prisma-next/contract/types';
|
|
2
|
-
import type {
|
|
3
|
-
ExecutionStackInstance,
|
|
4
|
-
RuntimeDriverInstance,
|
|
5
|
-
} from '@prisma-next/framework-components/execution';
|
|
6
2
|
import {
|
|
7
3
|
AsyncIterableResult,
|
|
8
4
|
checkAborted,
|
|
@@ -23,6 +19,7 @@ import type {
|
|
|
23
19
|
LoweredStatement,
|
|
24
20
|
PreparedExecuteRequest,
|
|
25
21
|
SqlCodecCallContext,
|
|
22
|
+
SqlConnection,
|
|
26
23
|
SqlDriver,
|
|
27
24
|
SqlQueryable,
|
|
28
25
|
SqlTransaction,
|
|
@@ -64,11 +61,7 @@ import type {
|
|
|
64
61
|
TelemetryOutcome,
|
|
65
62
|
VerifyMarkerOption,
|
|
66
63
|
} from './runtime-spi';
|
|
67
|
-
import type {
|
|
68
|
-
ExecutionContext,
|
|
69
|
-
SqlRuntimeAdapterInstance,
|
|
70
|
-
SqlRuntimeExtensionInstance,
|
|
71
|
-
} from './sql-context';
|
|
64
|
+
import type { ExecutionContext } from './sql-context';
|
|
72
65
|
import { SqlFamilyAdapter } from './sql-family-adapter';
|
|
73
66
|
|
|
74
67
|
export type Log = RuntimeLog;
|
|
@@ -83,25 +76,10 @@ export interface RuntimeOptions<TContract extends Contract<SqlStorage> = Contrac
|
|
|
83
76
|
readonly log?: Log;
|
|
84
77
|
}
|
|
85
78
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
readonly stackInstance: ExecutionStackInstance<
|
|
91
|
-
'sql',
|
|
92
|
-
TTargetId,
|
|
93
|
-
SqlRuntimeAdapterInstance<TTargetId>,
|
|
94
|
-
RuntimeDriverInstance<'sql', TTargetId>,
|
|
95
|
-
SqlRuntimeExtensionInstance<TTargetId>
|
|
96
|
-
>;
|
|
97
|
-
readonly context: ExecutionContext<TContract>;
|
|
98
|
-
readonly driver: SqlDriver<unknown>;
|
|
99
|
-
readonly verifyMarker?: VerifyMarkerOption;
|
|
100
|
-
readonly middleware?: readonly SqlMiddleware[];
|
|
101
|
-
readonly mode?: 'strict' | 'permissive';
|
|
102
|
-
readonly log?: Log;
|
|
103
|
-
}
|
|
104
|
-
|
|
79
|
+
/**
|
|
80
|
+
* SQL-family runtime interface. Named `Runtime` (not `SqlRuntime`) by deliberate exception
|
|
81
|
+
* to avoid a repo-wide rename; see ADR 230 (runtime target layer) for the recorded decision.
|
|
82
|
+
*/
|
|
105
83
|
export interface Runtime extends RuntimeQueryable {
|
|
106
84
|
connection(): Promise<RuntimeConnection>;
|
|
107
85
|
telemetry(): RuntimeTelemetryEvent | null;
|
|
@@ -167,7 +145,12 @@ function isExecutionPlan(plan: SqlExecutionPlan | SqlQueryPlan): plan is SqlExec
|
|
|
167
145
|
const noopLogSink = (): void => {};
|
|
168
146
|
const noopLog: Log = { info: noopLogSink, warn: noopLogSink, error: noopLogSink };
|
|
169
147
|
|
|
170
|
-
|
|
148
|
+
/**
|
|
149
|
+
* Abstract family-layer base for SQL runtimes. Subclass to build a target runtime
|
|
150
|
+
* (e.g. `PostgresRuntimeImpl`); app code should consume the `Runtime` interface returned
|
|
151
|
+
* by the target factories, never this class directly.
|
|
152
|
+
*/
|
|
153
|
+
export abstract class SqlRuntimeBase<TContract extends Contract<SqlStorage> = Contract<SqlStorage>>
|
|
171
154
|
extends RuntimeCore<SqlQueryPlan, SqlExecutionPlan, SqlMiddleware>
|
|
172
155
|
implements Runtime
|
|
173
156
|
{
|
|
@@ -325,6 +308,16 @@ class SqlRuntimeImpl<TContract extends Contract<SqlStorage> = Contract<SqlStorag
|
|
|
325
308
|
);
|
|
326
309
|
}
|
|
327
310
|
|
|
311
|
+
/**
|
|
312
|
+
* Returns the raw driver connection. The connection is a `SqlQueryable` — SQL
|
|
313
|
+
* issued on it runs below the middleware/codec/telemetry pipeline. It carries
|
|
314
|
+
* its own lifecycle (`release`/`destroy`/`beginTransaction`); the caller owns
|
|
315
|
+
* disposal.
|
|
316
|
+
*/
|
|
317
|
+
protected acquireRawConnection(): Promise<SqlConnection> {
|
|
318
|
+
return this.driver.acquireConnection();
|
|
319
|
+
}
|
|
320
|
+
|
|
328
321
|
private async *streamRows<Row>(
|
|
329
322
|
exec: SqlExecutionPlan,
|
|
330
323
|
decodeContext: DecodeContext,
|
|
@@ -385,7 +378,12 @@ class SqlRuntimeImpl<TContract extends Contract<SqlStorage> = Contract<SqlStorag
|
|
|
385
378
|
}
|
|
386
379
|
}
|
|
387
380
|
|
|
388
|
-
|
|
381
|
+
/**
|
|
382
|
+
* Execute a plan against a caller-supplied queryable, running the full
|
|
383
|
+
* middleware/codec/telemetry pipeline. Use `acquireRawConnection` to obtain a
|
|
384
|
+
* queryable that subclasses can bind typed plans to.
|
|
385
|
+
*/
|
|
386
|
+
protected executeAgainstQueryable<Row>(
|
|
389
387
|
plan: SqlExecutionPlan<unknown> | SqlQueryPlan<unknown>,
|
|
390
388
|
queryable: SqlQueryable,
|
|
391
389
|
options?: RuntimeExecuteOptions,
|
|
@@ -526,7 +524,11 @@ class SqlRuntimeImpl<TContract extends Contract<SqlStorage> = Contract<SqlStorag
|
|
|
526
524
|
return new PreparedStatementImpl<ParamsFromDeclaration<D, CT>, Row>(internals);
|
|
527
525
|
}
|
|
528
526
|
|
|
529
|
-
|
|
527
|
+
/**
|
|
528
|
+
* Execute a prepared statement against a caller-supplied queryable, running
|
|
529
|
+
* the full middleware/codec/telemetry pipeline.
|
|
530
|
+
*/
|
|
531
|
+
protected executePreparedAgainstQueryable<P, Row>(
|
|
530
532
|
ps: PreparedStatementImpl<P, Row>,
|
|
531
533
|
userParams: Record<string, unknown>,
|
|
532
534
|
queryable: SqlQueryable,
|
|
@@ -753,8 +755,13 @@ function transactionClosedError(): Error {
|
|
|
753
755
|
);
|
|
754
756
|
}
|
|
755
757
|
|
|
758
|
+
/** Minimal structural type `withTransaction` depends on — anything that can open a connection. */
|
|
759
|
+
export interface ConnectionProvider {
|
|
760
|
+
connection(): Promise<RuntimeConnection>;
|
|
761
|
+
}
|
|
762
|
+
|
|
756
763
|
export async function withTransaction<R>(
|
|
757
|
-
runtime:
|
|
764
|
+
runtime: ConnectionProvider,
|
|
758
765
|
fn: (tx: TransactionContext) => PromiseLike<R>,
|
|
759
766
|
): Promise<R> {
|
|
760
767
|
const connection = await runtime.connection();
|
|
@@ -859,19 +866,3 @@ export async function withTransaction<R>(
|
|
|
859
866
|
}
|
|
860
867
|
}
|
|
861
868
|
}
|
|
862
|
-
|
|
863
|
-
export function createRuntime<TContract extends Contract<SqlStorage>, TTargetId extends string>(
|
|
864
|
-
options: CreateRuntimeOptions<TContract, TTargetId>,
|
|
865
|
-
): Runtime {
|
|
866
|
-
const { stackInstance, context, driver, verifyMarker, middleware, mode, log } = options;
|
|
867
|
-
|
|
868
|
-
return new SqlRuntimeImpl({
|
|
869
|
-
context,
|
|
870
|
-
adapter: stackInstance.adapter,
|
|
871
|
-
driver,
|
|
872
|
-
...ifDefined('verifyMarker', verifyMarker),
|
|
873
|
-
...ifDefined('middleware', middleware),
|
|
874
|
-
...ifDefined('mode', mode),
|
|
875
|
-
...ifDefined('log', log),
|
|
876
|
-
});
|
|
877
|
-
}
|