@prisma-next/sql-contract-ts 0.14.0-dev.65 → 0.14.0-dev.67
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/contract-builder.d.mts +27 -22
- package/dist/contract-builder.d.mts.map +1 -1
- package/dist/contract-builder.mjs +10 -10
- package/dist/contract-builder.mjs.map +1 -1
- package/package.json +10 -10
- package/src/authoring-type-utils.ts +6 -3
- package/src/contract-dsl.ts +133 -102
- package/src/contract-types.ts +38 -5
package/package.json
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prisma-next/sql-contract-ts",
|
|
3
|
-
"version": "0.14.0-dev.
|
|
3
|
+
"version": "0.14.0-dev.67",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"description": "SQL-specific TypeScript contract authoring surface for Prisma Next",
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"@prisma-next/config": "0.14.0-dev.
|
|
10
|
-
"@prisma-next/contract": "0.14.0-dev.
|
|
11
|
-
"@prisma-next/contract-authoring": "0.14.0-dev.
|
|
12
|
-
"@prisma-next/framework-components": "0.14.0-dev.
|
|
13
|
-
"@prisma-next/sql-contract": "0.14.0-dev.
|
|
14
|
-
"@prisma-next/utils": "0.14.0-dev.
|
|
9
|
+
"@prisma-next/config": "0.14.0-dev.67",
|
|
10
|
+
"@prisma-next/contract": "0.14.0-dev.67",
|
|
11
|
+
"@prisma-next/contract-authoring": "0.14.0-dev.67",
|
|
12
|
+
"@prisma-next/framework-components": "0.14.0-dev.67",
|
|
13
|
+
"@prisma-next/sql-contract": "0.14.0-dev.67",
|
|
14
|
+
"@prisma-next/utils": "0.14.0-dev.67",
|
|
15
15
|
"arktype": "^2.2.0",
|
|
16
16
|
"pathe": "^2.0.3",
|
|
17
17
|
"ts-toolbelt": "^9.6.0"
|
|
18
18
|
},
|
|
19
19
|
"devDependencies": {
|
|
20
|
-
"@prisma-next/test-utils": "0.14.0-dev.
|
|
21
|
-
"@prisma-next/tsconfig": "0.14.0-dev.
|
|
20
|
+
"@prisma-next/test-utils": "0.14.0-dev.67",
|
|
21
|
+
"@prisma-next/tsconfig": "0.14.0-dev.67",
|
|
22
22
|
"@types/pg": "8.20.0",
|
|
23
23
|
"pg": "8.21.0",
|
|
24
|
-
"@prisma-next/tsdown": "0.14.0-dev.
|
|
24
|
+
"@prisma-next/tsdown": "0.14.0-dev.67",
|
|
25
25
|
"tsdown": "0.22.1",
|
|
26
26
|
"typescript": "5.9.3",
|
|
27
27
|
"vitest": "4.1.8"
|
|
@@ -2,6 +2,7 @@ import type {
|
|
|
2
2
|
AuthoringArgumentDescriptor,
|
|
3
3
|
AuthoringFieldPresetDescriptor,
|
|
4
4
|
} from '@prisma-next/framework-components/authoring';
|
|
5
|
+
import type { ColumnTypeDescriptor } from '@prisma-next/framework-components/codec';
|
|
5
6
|
import type { ScalarFieldBuilder, ScalarFieldState } from './contract-dsl';
|
|
6
7
|
|
|
7
8
|
export type UnionToIntersection<U> = (U extends unknown ? (value: U) => void : never) extends (
|
|
@@ -114,9 +115,11 @@ export type FieldBuilderFromPresetDescriptor<
|
|
|
114
115
|
ConstraintName extends string | undefined = undefined,
|
|
115
116
|
> = ScalarFieldBuilder<
|
|
116
117
|
ScalarFieldState<
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
118
|
+
ColumnTypeDescriptor<
|
|
119
|
+
ResolveTemplateValue<Descriptor['output']['codecId'], Args> extends string
|
|
120
|
+
? ResolveTemplateValue<Descriptor['output']['codecId'], Args>
|
|
121
|
+
: string
|
|
122
|
+
>,
|
|
120
123
|
undefined,
|
|
121
124
|
ResolveTemplateValue<Descriptor['output']['nullable'], Args> extends true ? true : false,
|
|
122
125
|
undefined,
|
package/src/contract-dsl.ts
CHANGED
|
@@ -40,7 +40,7 @@ type NamedConstraintNameSpec<Name extends string = string> = {
|
|
|
40
40
|
};
|
|
41
41
|
|
|
42
42
|
export type ScalarFieldState<
|
|
43
|
-
|
|
43
|
+
Descriptor extends ColumnTypeDescriptor = ColumnTypeDescriptor,
|
|
44
44
|
TypeRef extends NamedStorageTypeRef | undefined = undefined,
|
|
45
45
|
Nullable extends boolean = boolean,
|
|
46
46
|
ColumnName extends string | undefined = string | undefined,
|
|
@@ -49,7 +49,7 @@ export type ScalarFieldState<
|
|
|
49
49
|
Many extends boolean = false,
|
|
50
50
|
> = {
|
|
51
51
|
readonly kind: 'scalar';
|
|
52
|
-
readonly descriptor?:
|
|
52
|
+
readonly descriptor?: Descriptor | undefined;
|
|
53
53
|
readonly typeRef?: TypeRef | undefined;
|
|
54
54
|
readonly nullable: Nullable;
|
|
55
55
|
readonly columnName?: ColumnName | undefined;
|
|
@@ -63,7 +63,7 @@ export type ScalarFieldState<
|
|
|
63
63
|
|
|
64
64
|
type AnyScalarFieldState = {
|
|
65
65
|
readonly kind: 'scalar';
|
|
66
|
-
readonly descriptor?:
|
|
66
|
+
readonly descriptor?: ColumnTypeDescriptor | undefined;
|
|
67
67
|
readonly typeRef?: NamedStorageTypeRef | undefined;
|
|
68
68
|
readonly nullable: boolean;
|
|
69
69
|
readonly columnName?: string | undefined;
|
|
@@ -76,7 +76,7 @@ type AnyScalarFieldState = {
|
|
|
76
76
|
|
|
77
77
|
type HasNamedConstraintId<State extends AnyScalarFieldState> =
|
|
78
78
|
State extends ScalarFieldState<
|
|
79
|
-
|
|
79
|
+
ColumnTypeDescriptor,
|
|
80
80
|
NamedStorageTypeRef | undefined,
|
|
81
81
|
boolean,
|
|
82
82
|
string | undefined,
|
|
@@ -91,7 +91,7 @@ type HasNamedConstraintId<State extends AnyScalarFieldState> =
|
|
|
91
91
|
|
|
92
92
|
type HasNamedConstraintUnique<State extends AnyScalarFieldState> =
|
|
93
93
|
State extends ScalarFieldState<
|
|
94
|
-
|
|
94
|
+
ColumnTypeDescriptor,
|
|
95
95
|
NamedStorageTypeRef | undefined,
|
|
96
96
|
boolean,
|
|
97
97
|
string | undefined,
|
|
@@ -118,7 +118,7 @@ type ApplyFieldSqlSpec<
|
|
|
118
118
|
Spec extends FieldSqlSpecForState<State>,
|
|
119
119
|
> =
|
|
120
120
|
State extends ScalarFieldState<
|
|
121
|
-
infer
|
|
121
|
+
infer Descriptor,
|
|
122
122
|
infer TypeRef,
|
|
123
123
|
infer Nullable,
|
|
124
124
|
infer ColumnName,
|
|
@@ -127,7 +127,7 @@ type ApplyFieldSqlSpec<
|
|
|
127
127
|
infer Many
|
|
128
128
|
>
|
|
129
129
|
? ScalarFieldState<
|
|
130
|
-
|
|
130
|
+
Descriptor,
|
|
131
131
|
TypeRef,
|
|
132
132
|
Nullable,
|
|
133
133
|
Spec extends { readonly column: infer NextColumn extends string } ? NextColumn : ColumnName,
|
|
@@ -158,7 +158,6 @@ function toColumnDefault(value: ColumnDefaultLiteralInputValue | ColumnDefault):
|
|
|
158
158
|
return { kind: 'literal', value };
|
|
159
159
|
}
|
|
160
160
|
|
|
161
|
-
// Chaining methods use `as unknown as <ConditionalType>` because TypeScript cannot narrow generic conditional return types through object spread. The runtime values are correct — the casts bridge the gap between the spread result and the compile-time conditional type that encodes the state transition.
|
|
162
161
|
export class ScalarFieldBuilder<State extends AnyScalarFieldState = AnyScalarFieldState> {
|
|
163
162
|
declare readonly __state: State;
|
|
164
163
|
|
|
@@ -176,7 +175,7 @@ export class ScalarFieldBuilder<State extends AnyScalarFieldState = AnyScalarFie
|
|
|
176
175
|
|
|
177
176
|
optional(): ScalarFieldBuilder<
|
|
178
177
|
State extends ScalarFieldState<
|
|
179
|
-
infer
|
|
178
|
+
infer Descriptor,
|
|
180
179
|
infer TypeRef,
|
|
181
180
|
boolean,
|
|
182
181
|
infer ColumnName,
|
|
@@ -184,30 +183,35 @@ export class ScalarFieldBuilder<State extends AnyScalarFieldState = AnyScalarFie
|
|
|
184
183
|
infer UniqueSpec,
|
|
185
184
|
infer Many
|
|
186
185
|
>
|
|
187
|
-
? ScalarFieldState<
|
|
186
|
+
? ScalarFieldState<Descriptor, TypeRef, true, ColumnName, IdSpec, UniqueSpec, Many>
|
|
188
187
|
: AnyScalarFieldState
|
|
189
188
|
> {
|
|
190
|
-
return new ScalarFieldBuilder(
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
189
|
+
return new ScalarFieldBuilder(
|
|
190
|
+
blindCast<
|
|
191
|
+
State extends ScalarFieldState<
|
|
192
|
+
infer Descriptor,
|
|
193
|
+
infer TypeRef,
|
|
194
|
+
boolean,
|
|
195
|
+
infer ColumnName,
|
|
196
|
+
infer IdSpec,
|
|
197
|
+
infer UniqueSpec,
|
|
198
|
+
infer Many
|
|
199
|
+
>
|
|
200
|
+
? ScalarFieldState<Descriptor, TypeRef, true, ColumnName, IdSpec, UniqueSpec, Many>
|
|
201
|
+
: AnyScalarFieldState,
|
|
202
|
+
'object spread does not narrow the generic State conditional; runtime shape is correct'
|
|
203
|
+
>({
|
|
204
|
+
...this.state,
|
|
205
|
+
nullable: true,
|
|
206
|
+
}),
|
|
207
|
+
);
|
|
204
208
|
}
|
|
205
209
|
|
|
206
210
|
column<ColumnName extends string>(
|
|
207
211
|
name: ColumnName,
|
|
208
212
|
): ScalarFieldBuilder<
|
|
209
213
|
State extends ScalarFieldState<
|
|
210
|
-
infer
|
|
214
|
+
infer Descriptor,
|
|
211
215
|
infer TypeRef,
|
|
212
216
|
infer Nullable,
|
|
213
217
|
string | undefined,
|
|
@@ -215,28 +219,33 @@ export class ScalarFieldBuilder<State extends AnyScalarFieldState = AnyScalarFie
|
|
|
215
219
|
infer UniqueSpec,
|
|
216
220
|
infer Many
|
|
217
221
|
>
|
|
218
|
-
? ScalarFieldState<
|
|
222
|
+
? ScalarFieldState<Descriptor, TypeRef, Nullable, ColumnName, IdSpec, UniqueSpec, Many>
|
|
219
223
|
: AnyScalarFieldState
|
|
220
224
|
> {
|
|
221
|
-
return new ScalarFieldBuilder(
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
225
|
+
return new ScalarFieldBuilder(
|
|
226
|
+
blindCast<
|
|
227
|
+
State extends ScalarFieldState<
|
|
228
|
+
infer Descriptor,
|
|
229
|
+
infer TypeRef,
|
|
230
|
+
infer Nullable,
|
|
231
|
+
string | undefined,
|
|
232
|
+
infer IdSpec,
|
|
233
|
+
infer UniqueSpec,
|
|
234
|
+
infer Many
|
|
235
|
+
>
|
|
236
|
+
? ScalarFieldState<Descriptor, TypeRef, Nullable, ColumnName, IdSpec, UniqueSpec, Many>
|
|
237
|
+
: AnyScalarFieldState,
|
|
238
|
+
'object spread does not narrow the generic State conditional; runtime shape is correct'
|
|
239
|
+
>({
|
|
240
|
+
...this.state,
|
|
241
|
+
columnName: name,
|
|
242
|
+
}),
|
|
243
|
+
);
|
|
235
244
|
}
|
|
236
245
|
|
|
237
246
|
many(): ScalarFieldBuilder<
|
|
238
247
|
State extends ScalarFieldState<
|
|
239
|
-
infer
|
|
248
|
+
infer Descriptor,
|
|
240
249
|
infer TypeRef,
|
|
241
250
|
infer Nullable,
|
|
242
251
|
infer ColumnName,
|
|
@@ -244,13 +253,13 @@ export class ScalarFieldBuilder<State extends AnyScalarFieldState = AnyScalarFie
|
|
|
244
253
|
infer UniqueSpec,
|
|
245
254
|
boolean
|
|
246
255
|
>
|
|
247
|
-
? ScalarFieldState<
|
|
256
|
+
? ScalarFieldState<Descriptor, TypeRef, Nullable, ColumnName, IdSpec, UniqueSpec, true>
|
|
248
257
|
: AnyScalarFieldState
|
|
249
258
|
> {
|
|
250
259
|
return new ScalarFieldBuilder(
|
|
251
260
|
blindCast<
|
|
252
261
|
State extends ScalarFieldState<
|
|
253
|
-
infer
|
|
262
|
+
infer Descriptor,
|
|
254
263
|
infer TypeRef,
|
|
255
264
|
infer Nullable,
|
|
256
265
|
infer ColumnName,
|
|
@@ -258,7 +267,7 @@ export class ScalarFieldBuilder<State extends AnyScalarFieldState = AnyScalarFie
|
|
|
258
267
|
infer UniqueSpec,
|
|
259
268
|
boolean
|
|
260
269
|
>
|
|
261
|
-
? ScalarFieldState<
|
|
270
|
+
? ScalarFieldState<Descriptor, TypeRef, Nullable, ColumnName, IdSpec, UniqueSpec, true>
|
|
262
271
|
: AnyScalarFieldState,
|
|
263
272
|
'object spread does not narrow the generic State conditional; runtime shape is correct'
|
|
264
273
|
>({
|
|
@@ -286,7 +295,7 @@ export class ScalarFieldBuilder<State extends AnyScalarFieldState = AnyScalarFie
|
|
|
286
295
|
options?: NamedConstraintSpec<Name>,
|
|
287
296
|
): ScalarFieldBuilder<
|
|
288
297
|
State extends ScalarFieldState<
|
|
289
|
-
infer
|
|
298
|
+
infer Descriptor,
|
|
290
299
|
infer TypeRef,
|
|
291
300
|
infer Nullable,
|
|
292
301
|
infer ColumnName,
|
|
@@ -295,7 +304,7 @@ export class ScalarFieldBuilder<State extends AnyScalarFieldState = AnyScalarFie
|
|
|
295
304
|
infer Many
|
|
296
305
|
>
|
|
297
306
|
? ScalarFieldState<
|
|
298
|
-
|
|
307
|
+
Descriptor,
|
|
299
308
|
TypeRef,
|
|
300
309
|
Nullable,
|
|
301
310
|
ColumnName,
|
|
@@ -305,35 +314,40 @@ export class ScalarFieldBuilder<State extends AnyScalarFieldState = AnyScalarFie
|
|
|
305
314
|
>
|
|
306
315
|
: AnyScalarFieldState
|
|
307
316
|
> {
|
|
308
|
-
return new ScalarFieldBuilder(
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
infer Many
|
|
319
|
-
>
|
|
320
|
-
? ScalarFieldState<
|
|
321
|
-
CodecId,
|
|
322
|
-
TypeRef,
|
|
323
|
-
Nullable,
|
|
324
|
-
ColumnName,
|
|
325
|
-
NamedConstraintSpec<Name>,
|
|
326
|
-
UniqueSpec,
|
|
327
|
-
Many
|
|
317
|
+
return new ScalarFieldBuilder(
|
|
318
|
+
blindCast<
|
|
319
|
+
State extends ScalarFieldState<
|
|
320
|
+
infer Descriptor,
|
|
321
|
+
infer TypeRef,
|
|
322
|
+
infer Nullable,
|
|
323
|
+
infer ColumnName,
|
|
324
|
+
NamedConstraintSpec | undefined,
|
|
325
|
+
infer UniqueSpec,
|
|
326
|
+
infer Many
|
|
328
327
|
>
|
|
329
|
-
|
|
328
|
+
? ScalarFieldState<
|
|
329
|
+
Descriptor,
|
|
330
|
+
TypeRef,
|
|
331
|
+
Nullable,
|
|
332
|
+
ColumnName,
|
|
333
|
+
NamedConstraintSpec<Name>,
|
|
334
|
+
UniqueSpec,
|
|
335
|
+
Many
|
|
336
|
+
>
|
|
337
|
+
: AnyScalarFieldState,
|
|
338
|
+
'object spread does not narrow the generic State conditional; runtime shape is correct'
|
|
339
|
+
>({
|
|
340
|
+
...this.state,
|
|
341
|
+
id: options?.name ? { name: options.name } : {},
|
|
342
|
+
}),
|
|
343
|
+
);
|
|
330
344
|
}
|
|
331
345
|
|
|
332
346
|
unique<const Name extends string | undefined = undefined>(
|
|
333
347
|
options?: NamedConstraintSpec<Name>,
|
|
334
348
|
): ScalarFieldBuilder<
|
|
335
349
|
State extends ScalarFieldState<
|
|
336
|
-
infer
|
|
350
|
+
infer Descriptor,
|
|
337
351
|
infer TypeRef,
|
|
338
352
|
infer Nullable,
|
|
339
353
|
infer ColumnName,
|
|
@@ -342,7 +356,7 @@ export class ScalarFieldBuilder<State extends AnyScalarFieldState = AnyScalarFie
|
|
|
342
356
|
infer Many
|
|
343
357
|
>
|
|
344
358
|
? ScalarFieldState<
|
|
345
|
-
|
|
359
|
+
Descriptor,
|
|
346
360
|
TypeRef,
|
|
347
361
|
Nullable,
|
|
348
362
|
ColumnName,
|
|
@@ -352,28 +366,33 @@ export class ScalarFieldBuilder<State extends AnyScalarFieldState = AnyScalarFie
|
|
|
352
366
|
>
|
|
353
367
|
: AnyScalarFieldState
|
|
354
368
|
> {
|
|
355
|
-
return new ScalarFieldBuilder(
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
infer Many
|
|
366
|
-
>
|
|
367
|
-
? ScalarFieldState<
|
|
368
|
-
CodecId,
|
|
369
|
-
TypeRef,
|
|
370
|
-
Nullable,
|
|
371
|
-
ColumnName,
|
|
372
|
-
IdSpec,
|
|
373
|
-
NamedConstraintSpec<Name>,
|
|
374
|
-
Many
|
|
369
|
+
return new ScalarFieldBuilder(
|
|
370
|
+
blindCast<
|
|
371
|
+
State extends ScalarFieldState<
|
|
372
|
+
infer Descriptor,
|
|
373
|
+
infer TypeRef,
|
|
374
|
+
infer Nullable,
|
|
375
|
+
infer ColumnName,
|
|
376
|
+
infer IdSpec,
|
|
377
|
+
NamedConstraintSpec | undefined,
|
|
378
|
+
infer Many
|
|
375
379
|
>
|
|
376
|
-
|
|
380
|
+
? ScalarFieldState<
|
|
381
|
+
Descriptor,
|
|
382
|
+
TypeRef,
|
|
383
|
+
Nullable,
|
|
384
|
+
ColumnName,
|
|
385
|
+
IdSpec,
|
|
386
|
+
NamedConstraintSpec<Name>,
|
|
387
|
+
Many
|
|
388
|
+
>
|
|
389
|
+
: AnyScalarFieldState,
|
|
390
|
+
'object spread does not narrow the generic State conditional; runtime shape is correct'
|
|
391
|
+
>({
|
|
392
|
+
...this.state,
|
|
393
|
+
unique: options?.name ? { name: options.name } : {},
|
|
394
|
+
}),
|
|
395
|
+
);
|
|
377
396
|
}
|
|
378
397
|
|
|
379
398
|
sql<const Spec extends FieldSqlSpecForState<State>>(
|
|
@@ -391,12 +410,17 @@ export class ScalarFieldBuilder<State extends AnyScalarFieldState = AnyScalarFie
|
|
|
391
410
|
);
|
|
392
411
|
}
|
|
393
412
|
|
|
394
|
-
return new ScalarFieldBuilder(
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
413
|
+
return new ScalarFieldBuilder(
|
|
414
|
+
blindCast<
|
|
415
|
+
ApplyFieldSqlSpec<State, Spec>,
|
|
416
|
+
'conditional object spread does not narrow ApplyFieldSqlSpec; runtime shape is correct'
|
|
417
|
+
>({
|
|
418
|
+
...this.state,
|
|
419
|
+
...(spec.column ? { columnName: spec.column } : {}),
|
|
420
|
+
...(idSpec ? { id: { name: idSpec.name } } : {}),
|
|
421
|
+
...(uniqueSpec ? { unique: { name: uniqueSpec.name } } : {}),
|
|
422
|
+
}),
|
|
423
|
+
);
|
|
400
424
|
}
|
|
401
425
|
|
|
402
426
|
build(): State {
|
|
@@ -406,7 +430,12 @@ export class ScalarFieldBuilder<State extends AnyScalarFieldState = AnyScalarFie
|
|
|
406
430
|
|
|
407
431
|
export class EnumScalarFieldBuilder<
|
|
408
432
|
Handle extends EnumTypeHandle,
|
|
409
|
-
State extends AnyScalarFieldState = ScalarFieldState<
|
|
433
|
+
State extends AnyScalarFieldState = ScalarFieldState<
|
|
434
|
+
ColumnTypeDescriptor,
|
|
435
|
+
Handle,
|
|
436
|
+
false,
|
|
437
|
+
undefined
|
|
438
|
+
>,
|
|
410
439
|
> extends ScalarFieldBuilder<State> {
|
|
411
440
|
readonly #handle: Handle;
|
|
412
441
|
|
|
@@ -436,7 +465,7 @@ export class EnumScalarFieldBuilder<
|
|
|
436
465
|
|
|
437
466
|
function columnField<Descriptor extends ColumnTypeDescriptor>(
|
|
438
467
|
descriptor: Descriptor,
|
|
439
|
-
): ScalarFieldBuilder<ScalarFieldState<Descriptor
|
|
468
|
+
): ScalarFieldBuilder<ScalarFieldState<Descriptor, undefined, false, undefined>> {
|
|
440
469
|
return new ScalarFieldBuilder({
|
|
441
470
|
kind: 'scalar',
|
|
442
471
|
descriptor,
|
|
@@ -446,7 +475,7 @@ function columnField<Descriptor extends ColumnTypeDescriptor>(
|
|
|
446
475
|
|
|
447
476
|
function generatedField<Descriptor extends ColumnTypeDescriptor>(
|
|
448
477
|
spec: GeneratedFieldSpec & { readonly type: Descriptor },
|
|
449
|
-
): ScalarFieldBuilder<ScalarFieldState<Descriptor
|
|
478
|
+
): ScalarFieldBuilder<ScalarFieldState<Descriptor, undefined, false, undefined>> {
|
|
450
479
|
return new ScalarFieldBuilder({
|
|
451
480
|
kind: 'scalar',
|
|
452
481
|
descriptor: {
|
|
@@ -460,10 +489,12 @@ function generatedField<Descriptor extends ColumnTypeDescriptor>(
|
|
|
460
489
|
|
|
461
490
|
function namedTypeField<TypeRef extends string>(
|
|
462
491
|
typeRef: TypeRef,
|
|
463
|
-
): ScalarFieldBuilder<ScalarFieldState<
|
|
492
|
+
): ScalarFieldBuilder<ScalarFieldState<ColumnTypeDescriptor, TypeRef, false, undefined>>;
|
|
464
493
|
function namedTypeField<TypeRef extends StorageTypeInstance>(
|
|
465
494
|
typeRef: TypeRef,
|
|
466
|
-
): ScalarFieldBuilder<
|
|
495
|
+
): ScalarFieldBuilder<
|
|
496
|
+
ScalarFieldState<ColumnTypeDescriptor<TypeRef['codecId']>, TypeRef, false, undefined>
|
|
497
|
+
>;
|
|
467
498
|
function namedTypeField<Handle extends EnumTypeHandle>(
|
|
468
499
|
typeRef: Handle,
|
|
469
500
|
): EnumScalarFieldBuilder<Handle>;
|
|
@@ -471,7 +502,7 @@ function namedTypeField(typeRef: NamedStorageTypeRef): ScalarFieldBuilder {
|
|
|
471
502
|
if (isEnumTypeHandle(typeRef)) {
|
|
472
503
|
return new EnumScalarFieldBuilder(
|
|
473
504
|
blindCast<
|
|
474
|
-
ScalarFieldState<
|
|
505
|
+
ScalarFieldState<ColumnTypeDescriptor, typeof typeRef, false, undefined>,
|
|
475
506
|
'literal object lacks explicit many; cast to the full ScalarFieldState so optional() conditional resolves Many = false'
|
|
476
507
|
>({
|
|
477
508
|
kind: 'scalar',
|
package/src/contract-types.ts
CHANGED
|
@@ -695,6 +695,31 @@ type EnumValueUnion<FieldState> = [FieldTypeRefOf<FieldState>] extends [
|
|
|
695
695
|
: Values[number]
|
|
696
696
|
: never;
|
|
697
697
|
|
|
698
|
+
// The member-value literal tuple carried on a descriptor's `entityRef.entity`
|
|
699
|
+
// (e.g. a target's native-enum entity), or `never` when the descriptor has no
|
|
700
|
+
// entityRef, its entity has no `members`, or `members` is widened to
|
|
701
|
+
// `readonly string[]` — this is checked with non-optional property shapes so
|
|
702
|
+
// a descriptor genuinely lacking `entityRef` fails the structural match
|
|
703
|
+
// instead of matching vacuously through the framework type's optional slot.
|
|
704
|
+
type DescriptorEntityMembers<Descriptor> = Descriptor extends {
|
|
705
|
+
readonly entityRef: {
|
|
706
|
+
readonly entity: { readonly members: infer Members extends readonly string[] };
|
|
707
|
+
};
|
|
708
|
+
}
|
|
709
|
+
? Members
|
|
710
|
+
: never;
|
|
711
|
+
|
|
712
|
+
// The value-set member union for a descriptor-carried entity (the type-level
|
|
713
|
+
// mirror of the runtime's generic `deriveValueSetFromEntity` fold), or
|
|
714
|
+
// `never` for a field with no descriptor, a descriptor with no entityRef.entity,
|
|
715
|
+
// or a widened (non-literal) members tuple — mirroring `EnumValueUnion`'s
|
|
716
|
+
// erasure guard.
|
|
717
|
+
type DescriptorValueSetUnion<FieldState> = [FieldDescriptorOf<FieldState>] extends [never]
|
|
718
|
+
? never
|
|
719
|
+
: readonly string[] extends DescriptorEntityMembers<FieldDescriptorOf<FieldState>>
|
|
720
|
+
? never
|
|
721
|
+
: DescriptorEntityMembers<FieldDescriptorOf<FieldState>>[number];
|
|
722
|
+
|
|
698
723
|
// The codec's `output` / `input` JS type for a field's column, before
|
|
699
724
|
// nullability. `unknown` when the codec is not in the definition's codec map.
|
|
700
725
|
type CodecChannelType<
|
|
@@ -711,19 +736,27 @@ type CodecChannelType<
|
|
|
711
736
|
: unknown
|
|
712
737
|
: unknown;
|
|
713
738
|
|
|
714
|
-
//
|
|
715
|
-
//
|
|
739
|
+
// The literal value union for a field: the enum-typed union takes precedence
|
|
740
|
+
// (matching today's behavior), falling back to the descriptor-carried
|
|
741
|
+
// value-set union; `never` when neither applies.
|
|
742
|
+
type FieldValueUnion<FieldState> = [EnumValueUnion<FieldState>] extends [never]
|
|
743
|
+
? DescriptorValueSetUnion<FieldState>
|
|
744
|
+
: EnumValueUnion<FieldState>;
|
|
745
|
+
|
|
746
|
+
// A field's read/write JS type: the value union (enum or descriptor value-set)
|
|
747
|
+
// when the field carries one, otherwise the codec channel type, with column
|
|
748
|
+
// nullability applied.
|
|
716
749
|
type FieldChannelType<
|
|
717
750
|
Definition,
|
|
718
751
|
ModelName extends ModelNames<Definition>,
|
|
719
752
|
FieldName extends ModelFieldNames<Definition, ModelName>,
|
|
720
753
|
Channel extends 'output' | 'input',
|
|
721
754
|
> =
|
|
722
|
-
| ([
|
|
755
|
+
| ([FieldValueUnion<ModelFieldState<Definition, ModelName, FieldName>>] extends [never]
|
|
723
756
|
? CodecChannelType<Definition, ModelName, FieldName, Channel>
|
|
724
757
|
: StorageColumnManyOf<ModelStorageColumn<Definition, ModelName, FieldName>> extends true
|
|
725
|
-
? ReadonlyArray<
|
|
726
|
-
:
|
|
758
|
+
? ReadonlyArray<FieldValueUnion<ModelFieldState<Definition, ModelName, FieldName>>>
|
|
759
|
+
: FieldValueUnion<ModelFieldState<Definition, ModelName, FieldName>>)
|
|
727
760
|
| (FieldNullableOf<ModelFieldState<Definition, ModelName, FieldName>> extends true
|
|
728
761
|
? null
|
|
729
762
|
: never);
|