objection 4.0.0-rc.2 → 4.0.0-rc.4
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/lib/queryBuilder/InternalOptions.js +4 -0
- package/lib/queryBuilder/graph/GraphLoader.js +201 -126
- package/lib/queryBuilder/graph/GraphNode.js +18 -3
- package/lib/queryBuilder/graph/GraphOptions.js +24 -49
- package/lib/queryBuilder/graph/GraphPlan.js +105 -108
- package/lib/queryBuilder/graph/GraphSchedule.js +102 -55
- package/lib/queryBuilder/graph/GraphUpsert.js +48 -548
- package/lib/queryBuilder/graph/GraphWriter.js +355 -28
- package/lib/queryBuilder/graph/graphChecks.js +534 -0
- package/lib/queryBuilder/graph/graphKeys.js +189 -418
- package/lib/queryBuilder/jsonDialects/JsonDialect.js +6 -0
- package/lib/queryBuilder/operations/UpdateOperation.js +5 -2
- package/lib/queryBuilder/operations/fieldExpressions.js +10 -7
- package/lib/relations/RelationProperty.js +6 -0
- package/package.json +3 -2
- package/typings/objection/index.d.ts +516 -163
|
@@ -18,7 +18,8 @@ import { Knex } from 'knex';
|
|
|
18
18
|
// Only the declarations marked with `export` are exported.
|
|
19
19
|
export {};
|
|
20
20
|
|
|
21
|
-
// Phantom brand of the relation types, used by `TypedRelationMappings
|
|
21
|
+
// Phantom brand of the relation types, used by `TypedRelationMappings` and
|
|
22
|
+
// `FromModel`.
|
|
22
23
|
declare const relationKind: unique symbol;
|
|
23
24
|
// Phantom brand of `Generated` properties.
|
|
24
25
|
declare const generated: unique symbol;
|
|
@@ -197,7 +198,7 @@ export interface CallbackVoid<T> {
|
|
|
197
198
|
}
|
|
198
199
|
|
|
199
200
|
export type Identity<T> = (value: T) => T;
|
|
200
|
-
export type AnyQueryBuilder = QueryBuilder<any, any>;
|
|
201
|
+
export type AnyQueryBuilder = QueryBuilder<any, any, any>;
|
|
201
202
|
export type AnyModelConstructor = ModelConstructor<Model>;
|
|
202
203
|
export type ModifierFunction<QB extends AnyQueryBuilder> = (qb: QB, ...args: any[]) => void;
|
|
203
204
|
export type Modifier<QB extends AnyQueryBuilder = AnyQueryBuilder> =
|
|
@@ -398,7 +399,7 @@ export type WithGraphTreeQueryBuilder<QB extends AnyQueryBuilder, T> = [keyof T]
|
|
|
398
399
|
? QB
|
|
399
400
|
: WithResultKind<
|
|
400
401
|
QB,
|
|
401
|
-
WithGraph<ModelType<QB>, T>['QueryBuilderType'],
|
|
402
|
+
KeepExtra<WithGraph<ModelType<QB>, T>['QueryBuilderType'], ExtraType<QB>>,
|
|
402
403
|
ModelType<QB>,
|
|
403
404
|
ResultType<QB>,
|
|
404
405
|
T
|
|
@@ -474,11 +475,12 @@ export type ItemType<T> = T extends Array<unknown> ? T[number] : T;
|
|
|
474
475
|
* Type for keys of non-function properties of T.
|
|
475
476
|
*/
|
|
476
477
|
export type NonFunctionPropertyNames<T> = {
|
|
477
|
-
[K in keyof T]
|
|
478
|
+
[K in keyof T]-?: T[K] extends Function ? never : K;
|
|
478
479
|
}[keyof T];
|
|
479
480
|
|
|
480
|
-
// The type-only members of models, which aren't data
|
|
481
|
-
|
|
481
|
+
// The type-only members of models, which aren't data, also the keys of the
|
|
482
|
+
// virtual attributes that `FromModel` adds.
|
|
483
|
+
type ModelTypeMembers = 'QueryBuilderType' | 'ColumnNameMapping' | `~virtual:${string}`;
|
|
482
484
|
|
|
483
485
|
/**
|
|
484
486
|
* Type that attempts to only select the user-defined model properties.
|
|
@@ -501,15 +503,24 @@ export type ModelObject<T extends Model> = Pick<T, DataPropertyNames<T>>;
|
|
|
501
503
|
|
|
502
504
|
/**
|
|
503
505
|
* The JSON of model M, as `toJSON()` returns it: its properties without
|
|
504
|
-
* methods,
|
|
505
|
-
*
|
|
506
|
+
* methods, the results of the methods in `virtualAttributes` on models with
|
|
507
|
+
* `FromModel`, and the related models as JSON too. Values aren't converted,
|
|
508
|
+
* e.g. dates stay dates.
|
|
506
509
|
*/
|
|
507
510
|
export type ModelJson<M> = {
|
|
508
|
-
[
|
|
511
|
+
[
|
|
512
|
+
K in keyof Pick<M, (DataPropertyNames<M> | VirtualAttributeNames<M>) & keyof M>
|
|
513
|
+
]: K extends RelationPropertyNames<M>
|
|
509
514
|
? RelationJson<M[K]>
|
|
510
|
-
: M[K]
|
|
515
|
+
: M[K] extends (...args: any) => infer R
|
|
516
|
+
? RelationJson<R>
|
|
517
|
+
: M[K];
|
|
511
518
|
};
|
|
512
519
|
|
|
520
|
+
type VirtualAttributeNames<M> = {
|
|
521
|
+
[K in keyof M]: K extends `~virtual:${infer N}` ? N : never;
|
|
522
|
+
}[keyof M];
|
|
523
|
+
|
|
513
524
|
type RelationJson<P> = P extends (infer I)[]
|
|
514
525
|
? ModelJson<I>[]
|
|
515
526
|
: P extends readonly (infer I)[]
|
|
@@ -529,7 +540,7 @@ export type PartialModelObject<T extends Model> = {
|
|
|
529
540
|
? I[] | PartialModelObject<I>[]
|
|
530
541
|
: Expression<T[K]>
|
|
531
542
|
: NonNullable<T[K]> extends Model
|
|
532
|
-
? Expression<T[K]> | PartialModelObject<NonNullable<T[K]>> //
|
|
543
|
+
? Expression<T[K]> | PartialModelObject<NonNullable<T[K]>> // Nullable to-one relations
|
|
533
544
|
: Expression<T[K]>;
|
|
534
545
|
};
|
|
535
546
|
|
|
@@ -580,7 +591,7 @@ export type GraphParameters = {
|
|
|
580
591
|
export type PartialModelGraph<M, T = M & GraphParameters> = T extends any
|
|
581
592
|
? {
|
|
582
593
|
[K in DataPropertyNames<T>]?: null extends T[K]
|
|
583
|
-
? PartialModelGraphField<NonNullable<T[K]>> | null //
|
|
594
|
+
? PartialModelGraphField<NonNullable<T[K]>> | null // Strip null to recognize to-one relations
|
|
584
595
|
: PartialModelGraphField<T[K]>;
|
|
585
596
|
}
|
|
586
597
|
: never;
|
|
@@ -624,9 +635,10 @@ export type OptionalInsertPropertyNames<M> = {
|
|
|
624
635
|
export type InsertablePropertyNames<M> = Exclude<DataPropertyNames<M>, RelationPropertyNames<M>>;
|
|
625
636
|
|
|
626
637
|
/**
|
|
627
|
-
* The data
|
|
628
|
-
*
|
|
629
|
-
*
|
|
638
|
+
* The complete data of a new row of model M, to check what is passed to
|
|
639
|
+
* `insert()`, which itself takes any subset of the properties. Unlike
|
|
640
|
+
* `PartialModelObject`, all properties are required except optional, nullable
|
|
641
|
+
* and `Generated` ones. Relation properties are left out.
|
|
630
642
|
*/
|
|
631
643
|
export type Insertable<M extends Model> = {
|
|
632
644
|
[K in Exclude<InsertablePropertyNames<M>, OptionalInsertPropertyNames<M>>]: Expression<M[K]>;
|
|
@@ -635,9 +647,9 @@ export type Insertable<M extends Model> = {
|
|
|
635
647
|
};
|
|
636
648
|
|
|
637
649
|
/**
|
|
638
|
-
* Like `Insertable`, but for `insertGraph()`: relation
|
|
639
|
-
* optional and hold the insertable graphs of the related
|
|
640
|
-
* references to existing ones through `#dbRef` or `#ref`.
|
|
650
|
+
* Like `Insertable`, but for graphs passed to `insertGraph()`: relation
|
|
651
|
+
* properties are optional and hold the insertable graphs of the related
|
|
652
|
+
* models, or references to existing ones through `#dbRef` or `#ref`.
|
|
641
653
|
*/
|
|
642
654
|
export type InsertableGraph<M extends Model> = Insertable<M> &
|
|
643
655
|
Omit<GraphParameters, '#dbRef' | '#ref'> & {
|
|
@@ -656,38 +668,15 @@ export type InsertableGraphField<F> =
|
|
|
656
668
|
/**
|
|
657
669
|
* Extracts the property names (excluding relations) of a model class.
|
|
658
670
|
*/
|
|
659
|
-
export type ModelProps<T extends Model> =
|
|
660
|
-
{
|
|
661
|
-
[K in keyof T]?: Defined<T[K]> extends Model
|
|
662
|
-
? never
|
|
663
|
-
: Defined<T[K]> extends Array<infer I>
|
|
664
|
-
? I extends Model
|
|
665
|
-
? never
|
|
666
|
-
: K
|
|
667
|
-
: T[K] extends Function
|
|
668
|
-
? never
|
|
669
|
-
: K;
|
|
670
|
-
}[keyof T],
|
|
671
|
-
undefined | ModelTypeMembers
|
|
672
|
-
>;
|
|
671
|
+
export type ModelProps<T extends Model> = InsertablePropertyNames<T>;
|
|
673
672
|
|
|
674
673
|
/**
|
|
675
|
-
* Extracts the relation names of
|
|
674
|
+
* Extracts the relation names of a model class.
|
|
676
675
|
*/
|
|
677
|
-
export type ModelRelations<T extends Model> =
|
|
678
|
-
{
|
|
679
|
-
[K in keyof T]?: Defined<T[K]> extends Model
|
|
680
|
-
? K
|
|
681
|
-
: Defined<T[K]> extends Array<infer I>
|
|
682
|
-
? I extends Model
|
|
683
|
-
? K
|
|
684
|
-
: never
|
|
685
|
-
: never;
|
|
686
|
-
}[keyof T]
|
|
687
|
-
>;
|
|
676
|
+
export type ModelRelations<T extends Model> = RelationPropertyNames<T>;
|
|
688
677
|
|
|
689
678
|
/**
|
|
690
|
-
* Given a model property type, returns a query
|
|
679
|
+
* Given a model property type, returns a query builder type of the
|
|
691
680
|
* correct kind if the property is a model or a model array. Queries for
|
|
692
681
|
* to-one relations resolve to `undefined` when there's no related row.
|
|
693
682
|
*/
|
|
@@ -728,16 +717,46 @@ export type ModelType<T extends { ModelType: any }> = T['ModelType'];
|
|
|
728
717
|
export type ResultType<T extends { ResultType: any }> = T['ResultType'];
|
|
729
718
|
|
|
730
719
|
/**
|
|
731
|
-
* Re-instantiates the query builder QB with the model type M
|
|
732
|
-
* type R, through its `RebindType`. The `~rebind` slot is
|
|
733
|
-
* intersection resolves it to exactly `[M, R]`.
|
|
734
|
-
* `RebindType` instead of QB keeps the intersection small,
|
|
735
|
-
* checks much faster.
|
|
720
|
+
* Re-instantiates the query builder QB with the model type M, the result
|
|
721
|
+
* type R and the extra type X, through its `RebindType`. The `~rebind` slot is
|
|
722
|
+
* `unknown`, so the intersection resolves it to exactly `[M, R, X]`.
|
|
723
|
+
* Rebinding QB's own `RebindType` instead of QB keeps the intersection small,
|
|
724
|
+
* which TypeScript checks much faster.
|
|
736
725
|
*/
|
|
737
|
-
type Rebind<
|
|
738
|
-
|
|
726
|
+
type Rebind<
|
|
727
|
+
QB extends AnyQueryBuilder,
|
|
728
|
+
M extends Model,
|
|
729
|
+
R,
|
|
730
|
+
X = IfStrict<unknown, ExtraType<QB>>,
|
|
731
|
+
> = (QB['RebindType'] & {
|
|
732
|
+
'~rebind': [M, R, X];
|
|
739
733
|
})['RebindType'];
|
|
740
734
|
|
|
735
|
+
/**
|
|
736
|
+
* Gets the extra type from a query builder type: what the types know about
|
|
737
|
+
* the query beyond its model and result, see `QueryExtra`.
|
|
738
|
+
*/
|
|
739
|
+
export type ExtraType<T extends { ExtraType: any }> = T['ExtraType'];
|
|
740
|
+
|
|
741
|
+
/**
|
|
742
|
+
* The extra type of queries in strict mode: the model class C that started the
|
|
743
|
+
* query, e.g. with `Person.query()`, and the modifiers P registered with
|
|
744
|
+
* `modifiers()`, to check the names of modifiers, and the id I of the class,
|
|
745
|
+
* for `findById()` and the other `*ById()` methods.
|
|
746
|
+
*/
|
|
747
|
+
export interface QueryExtra<C = unknown, P = unknown, I = MaybeCompositeId> {
|
|
748
|
+
modelClass: C;
|
|
749
|
+
registered: P;
|
|
750
|
+
id: I;
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
type WithExtra<QB extends AnyQueryBuilder, X> = Rebind<QB, ModelType<QB>, ResultType<QB>, X>;
|
|
754
|
+
|
|
755
|
+
// The narrowed query builders of `withGraph*()` start without the extra type
|
|
756
|
+
// of QB, so it is passed on, if there is one.
|
|
757
|
+
type KeepExtra<NQB extends AnyQueryBuilder, X> =
|
|
758
|
+
X extends QueryExtra<any, any, any> ? WithExtra<NQB, X> : NQB;
|
|
759
|
+
|
|
741
760
|
/**
|
|
742
761
|
* Gets the single item query builder type for a query builder.
|
|
743
762
|
*/
|
|
@@ -763,18 +782,19 @@ export type NumberQueryBuilder<QB extends AnyQueryBuilder> = QB['~number'];
|
|
|
763
782
|
*/
|
|
764
783
|
export type PageQueryBuilder<QB extends AnyQueryBuilder> = QB['~page'];
|
|
765
784
|
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
785
|
+
/**
|
|
786
|
+
* Strict mode checks the column names and values of queries against the
|
|
787
|
+
* models. Augment `TypeConfig` to opt in:
|
|
788
|
+
*
|
|
789
|
+
* declare module 'objection' {
|
|
790
|
+
* interface TypeConfig {
|
|
791
|
+
* strict: true;
|
|
792
|
+
* }
|
|
793
|
+
* }
|
|
794
|
+
*/
|
|
775
795
|
export interface TypeConfig {}
|
|
776
796
|
|
|
777
|
-
type IsStrict = TypeConfig extends { strict:
|
|
797
|
+
type IsStrict = TypeConfig extends { strict: true } ? true : false;
|
|
778
798
|
|
|
779
799
|
// As IsStrict isn't generic, IfStrict resolves eagerly.
|
|
780
800
|
type IfStrict<Loose, Strict> = IsStrict extends true ? Strict : Loose;
|
|
@@ -890,10 +910,11 @@ type CheckedColumn<M, C extends string> =
|
|
|
890
910
|
IsConcreteModel<M> extends true ? CheckColumn<M, C> : string;
|
|
891
911
|
|
|
892
912
|
/**
|
|
893
|
-
* A column argument: checked against model M in strict mode,
|
|
894
|
-
* loose mode,
|
|
913
|
+
* A column argument: checked against model M in strict mode, the model's
|
|
914
|
+
* properties in loose mode, for autocompletion. In loose mode, other columns
|
|
915
|
+
* go through the RefArg overloads.
|
|
895
916
|
*/
|
|
896
|
-
type ColumnArg<M, C extends string> = IfStrict<
|
|
917
|
+
type ColumnArg<M, C extends string> = IfStrict<InsertablePropertyNames<M>, CheckedColumn<M, C>>;
|
|
897
918
|
|
|
898
919
|
/**
|
|
899
920
|
* The value of a column of type T in conditions: `null` is always accepted,
|
|
@@ -1042,8 +1063,8 @@ type StrictSelectionObject<M, O> = {
|
|
|
1042
1063
|
/**
|
|
1043
1064
|
* The query builder QB with its result rows narrowed to the properties P in
|
|
1044
1065
|
* strict mode, next to the model's methods and relations, as after `select()`
|
|
1045
|
-
* and the aggregates, marked with SelectedBrand. Repeated selections add up.
|
|
1046
|
-
* that aren't checked, e.g. in generic code, aren't narrowed.
|
|
1066
|
+
* and the aggregates, marked with SelectedBrand. Repeated selections add up.
|
|
1067
|
+
* Queries that aren't checked, e.g. in generic code, aren't narrowed.
|
|
1047
1068
|
*/
|
|
1048
1069
|
type NarrowRows<QB extends AnyQueryBuilder, P, All extends boolean = false> = RowsQueryBuilder<
|
|
1049
1070
|
QB,
|
|
@@ -1224,9 +1245,9 @@ type SelectedType<M, C extends string> = C extends `${infer Q}.${infer Col}`
|
|
|
1224
1245
|
: ColumnType<M, C>;
|
|
1225
1246
|
|
|
1226
1247
|
/**
|
|
1227
|
-
* The property of the column or alias C in the result rows:
|
|
1228
|
-
* converts them to camel case, with `upperCase: true`
|
|
1229
|
-
* of names in upper case.
|
|
1248
|
+
* The property of the column or alias C in the result rows:
|
|
1249
|
+
* `snakeCaseMappers()` converts them to camel case, with `upperCase: true`
|
|
1250
|
+
* after lowering the case of names in upper case.
|
|
1230
1251
|
*/
|
|
1231
1252
|
type ResultKey<M, C extends string> = M extends { ColumnNameMapping: 'snakeCase' }
|
|
1232
1253
|
? CamelCase<C>
|
|
@@ -1276,17 +1297,222 @@ type UnknownRelations<M, T> = {
|
|
|
1276
1297
|
|
|
1277
1298
|
/**
|
|
1278
1299
|
* In strict mode, relation expressions are intersected with this, to reject
|
|
1279
|
-
* the names of unknown relations
|
|
1300
|
+
* the names of unknown relations, and of unknown modifiers, checked against
|
|
1301
|
+
* the related class of each node and the modifiers registered on query
|
|
1302
|
+
* builder QB.
|
|
1280
1303
|
*/
|
|
1281
|
-
type CheckRelationExpression<M, E> = IfStrict<
|
|
1304
|
+
type CheckRelationExpression<M, E, QB extends AnyQueryBuilder = never> = IfStrict<
|
|
1282
1305
|
unknown,
|
|
1283
1306
|
IsConcreteModel<M> extends true
|
|
1284
1307
|
? [UnknownRelations<M, ParseRelationExpression<E>>] extends [never]
|
|
1285
|
-
?
|
|
1308
|
+
? CheckModifierExpression<E, QB>
|
|
1286
1309
|
: { '~unknownRelation': UnknownRelations<M, ParseRelationExpression<E>> }
|
|
1287
1310
|
: unknown
|
|
1288
1311
|
>;
|
|
1289
1312
|
|
|
1313
|
+
type CheckModifierExpression<E, QB extends AnyQueryBuilder> =
|
|
1314
|
+
HasQueryClass<QB> extends true
|
|
1315
|
+
? [CheckedModifiers<E, QB>] extends [never]
|
|
1316
|
+
? unknown
|
|
1317
|
+
: { '~unknownModifier': CheckedModifiers<E, QB> }
|
|
1318
|
+
: unknown;
|
|
1319
|
+
|
|
1320
|
+
// Queries in generic code, where the model class can't be resolved, aren't
|
|
1321
|
+
// checked.
|
|
1322
|
+
type HasQueryClass<QB extends AnyQueryBuilder> =
|
|
1323
|
+
IsConcreteModel<ModelType<QB>> extends false
|
|
1324
|
+
? false
|
|
1325
|
+
: [QueryClass<QB>] extends [never]
|
|
1326
|
+
? false
|
|
1327
|
+
: true;
|
|
1328
|
+
|
|
1329
|
+
// Only expressions with modifiers are checked for them.
|
|
1330
|
+
type CheckedModifiers<E, QB> = E extends `${string}(${string}` | object
|
|
1331
|
+
? UnknownModifiers<
|
|
1332
|
+
ClassMappings<QueryClass<QB>>,
|
|
1333
|
+
ParseModifierExpression<E>,
|
|
1334
|
+
keyof RegisteredModifiers<QB>
|
|
1335
|
+
>
|
|
1336
|
+
: never;
|
|
1337
|
+
|
|
1338
|
+
/**
|
|
1339
|
+
* The modifiers that a modifier name can refer to on query builder QB: the
|
|
1340
|
+
* `modifiers` of the model class that started the query, and those registered
|
|
1341
|
+
* with `modifiers()` before. Unknown names are only rejected in strict mode,
|
|
1342
|
+
* and only on queries of model classes with literal `modifiers`.
|
|
1343
|
+
*/
|
|
1344
|
+
type KnownModifiers<QB> = ClassModifiers<QueryClass<QB>> & RegisteredModifiers<QB>;
|
|
1345
|
+
|
|
1346
|
+
// The model class that started the query, if any.
|
|
1347
|
+
type QueryClass<QB> = [QB] extends [never]
|
|
1348
|
+
? never
|
|
1349
|
+
: QB extends { ExtraType: QueryExtra<infer C, any, any> }
|
|
1350
|
+
? unknown extends C
|
|
1351
|
+
? never
|
|
1352
|
+
: C
|
|
1353
|
+
: never;
|
|
1354
|
+
|
|
1355
|
+
type ClassModifiers<C> = C extends { modifiers: infer O } ? O : {};
|
|
1356
|
+
|
|
1357
|
+
type ClassMappings<C> = C extends { relationMappings: infer T }
|
|
1358
|
+
? T extends () => infer R
|
|
1359
|
+
? R
|
|
1360
|
+
: T
|
|
1361
|
+
: {};
|
|
1362
|
+
|
|
1363
|
+
type RegisteredModifiers<QB> = [QB] extends [never]
|
|
1364
|
+
? {}
|
|
1365
|
+
: QB extends { ExtraType: { registered: infer P } }
|
|
1366
|
+
? P
|
|
1367
|
+
: {};
|
|
1368
|
+
|
|
1369
|
+
/**
|
|
1370
|
+
* The id that `findById()` and the other `*ById()` methods take on query
|
|
1371
|
+
* builder QB: in strict mode, the type of the property of the class's literal
|
|
1372
|
+
* `idColumn`, or a tuple of them for composite ids, e.g. with
|
|
1373
|
+
* `static idColumn = ['groupId', 'memberId'] as const`.
|
|
1374
|
+
*/
|
|
1375
|
+
type IdArg<QB extends AnyQueryBuilder> = IfStrict<
|
|
1376
|
+
MaybeCompositeId,
|
|
1377
|
+
[QueryClass<QB>] extends [never]
|
|
1378
|
+
? MaybeCompositeId
|
|
1379
|
+
: QB extends { ExtraType: QueryExtra<any, any, infer I> }
|
|
1380
|
+
? I
|
|
1381
|
+
: MaybeCompositeId
|
|
1382
|
+
>;
|
|
1383
|
+
|
|
1384
|
+
// The id of a related class, read from its instances.
|
|
1385
|
+
type ClassId<C> = C extends { idColumn: infer K; prototype: infer M }
|
|
1386
|
+
? ColumnsId<K, M>
|
|
1387
|
+
: MaybeCompositeId;
|
|
1388
|
+
|
|
1389
|
+
// The inherited `idColumn` and other general types give any id.
|
|
1390
|
+
type ColumnsId<K, M> = [K] extends [string]
|
|
1391
|
+
? string extends K
|
|
1392
|
+
? MaybeCompositeId
|
|
1393
|
+
: PropertyId<M, K, MaybeCompositeId>
|
|
1394
|
+
: [K] extends [readonly string[]]
|
|
1395
|
+
? string extends K[number]
|
|
1396
|
+
? MaybeCompositeId
|
|
1397
|
+
: { readonly [I in keyof K]: PropertyId<M, K[I] & string, Id> }
|
|
1398
|
+
: MaybeCompositeId;
|
|
1399
|
+
|
|
1400
|
+
// The id column is a database column, named after the property by the
|
|
1401
|
+
// model's `ColumnNameMapping`. Columns without a property give the fallback F.
|
|
1402
|
+
type PropertyId<M, C extends string, F> =
|
|
1403
|
+
ResultKey<M, C> extends infer P extends keyof M ? NonNullable<M[P]> : F;
|
|
1404
|
+
|
|
1405
|
+
// Modifiers with their general type, e.g. inherited from `Model`, aren't
|
|
1406
|
+
// checked.
|
|
1407
|
+
type ChecksModifiers<QB extends AnyQueryBuilder> = IfStrict<
|
|
1408
|
+
false,
|
|
1409
|
+
HasQueryClass<QB> extends true ? ChecksClassModifiers<ClassModifiers<QueryClass<QB>>> : false
|
|
1410
|
+
>;
|
|
1411
|
+
|
|
1412
|
+
type ChecksClassModifiers<O> = string extends keyof O ? false : true;
|
|
1413
|
+
|
|
1414
|
+
// The names that `modify()` takes on query builder QB, also in lists. Names
|
|
1415
|
+
// in variables typed `string` are rejected where they are checked.
|
|
1416
|
+
type ModifierName<QB extends AnyQueryBuilder> =
|
|
1417
|
+
ChecksModifiers<QB> extends true ? keyof KnownModifiers<QB> & string : string;
|
|
1418
|
+
|
|
1419
|
+
type ModifyArg<QB extends AnyQueryBuilder> =
|
|
1420
|
+
| ModifierName<QB>
|
|
1421
|
+
| ModifierName<QB>[]
|
|
1422
|
+
| ModifierFunction<QB>
|
|
1423
|
+
| Record<string, Expression<PrimitiveValue>>;
|
|
1424
|
+
|
|
1425
|
+
// The related classes are found through the relation mappings, at each step
|
|
1426
|
+
// of the path. P are the names registered with `modifiers()`.
|
|
1427
|
+
type UnknownModifiers<Mappings, T, P> = T extends unknown
|
|
1428
|
+
? {
|
|
1429
|
+
[K in keyof T & string]: T[K] extends { names: infer N; children: infer Children }
|
|
1430
|
+
? MappedClass<Mappings, K> extends infer C
|
|
1431
|
+
? [C] extends [never]
|
|
1432
|
+
? never
|
|
1433
|
+
: | (ChecksClassModifiers<ClassModifiers<C>> extends true
|
|
1434
|
+
? Exclude<N, keyof ClassModifiers<C> | P>
|
|
1435
|
+
: never)
|
|
1436
|
+
| UnknownModifiers<ClassMappings<C>, Children, P>
|
|
1437
|
+
: never
|
|
1438
|
+
: never;
|
|
1439
|
+
}[keyof T & string]
|
|
1440
|
+
: never;
|
|
1441
|
+
|
|
1442
|
+
// Mappings with their general type, e.g. inherited from `Model`, give no class.
|
|
1443
|
+
type MappedClass<Mappings, K> = string extends keyof Mappings
|
|
1444
|
+
? never
|
|
1445
|
+
: K extends keyof Mappings
|
|
1446
|
+
? Mappings[K] extends { modelClass: infer C }
|
|
1447
|
+
? C extends abstract new (...args: any) => any
|
|
1448
|
+
? C
|
|
1449
|
+
: C extends () => infer RC
|
|
1450
|
+
? RC
|
|
1451
|
+
: never
|
|
1452
|
+
: never
|
|
1453
|
+
: never;
|
|
1454
|
+
|
|
1455
|
+
/**
|
|
1456
|
+
* Parses the modifiers of relation expressions into a tree of the relations
|
|
1457
|
+
* with their modifier names: 'pets(a, b).owner' ->
|
|
1458
|
+
* `{ pets: { names: 'a' | 'b', children: { owner: ... } } }`. It is separate
|
|
1459
|
+
* from `ParseRelationExpression`, so that the narrowing types don't carry the
|
|
1460
|
+
* names.
|
|
1461
|
+
*/
|
|
1462
|
+
type ParseModifierExpression<E> = string extends E
|
|
1463
|
+
? {}
|
|
1464
|
+
: E extends string
|
|
1465
|
+
? ParseModifierString<E>
|
|
1466
|
+
: ParseModifierObject<E>;
|
|
1467
|
+
|
|
1468
|
+
// A union of the trees of the list items, as they can name the same relation.
|
|
1469
|
+
type ParseModifierList<L extends string[], Acc = never> = L extends [
|
|
1470
|
+
infer H extends string,
|
|
1471
|
+
...infer T extends string[],
|
|
1472
|
+
]
|
|
1473
|
+
? ParseModifierList<T, Acc | ParseModifierString<H>>
|
|
1474
|
+
: Acc;
|
|
1475
|
+
|
|
1476
|
+
type ParseModifierString<S extends string> =
|
|
1477
|
+
Trim<S> extends `[${infer Inner}]`
|
|
1478
|
+
? ParseModifierList<SplitList<Inner>>
|
|
1479
|
+
: Trim<S> extends `${infer Head}.${infer Rest}`
|
|
1480
|
+
? IsBalanced<Head> extends true
|
|
1481
|
+
? ModifierNode<Head, ParseModifierString<Rest>>
|
|
1482
|
+
: {}
|
|
1483
|
+
: ModifierNode<S, {}>;
|
|
1484
|
+
|
|
1485
|
+
type ModifierNode<S extends string, Children> = [RelationName<S>] extends [never]
|
|
1486
|
+
? {}
|
|
1487
|
+
: { [K in RelationName<S>]: { names: ModifierNames<S>; children: Children } };
|
|
1488
|
+
|
|
1489
|
+
// Empty arguments, e.g. of 'pets()' or a trailing comma, are no names.
|
|
1490
|
+
type ModifierNames<S extends string> =
|
|
1491
|
+
Trim<S> extends `${string}(${infer Args})` ? Exclude<Trim<SplitList<Args>[number]>, ''> : never;
|
|
1492
|
+
|
|
1493
|
+
type ParseModifierObject<E> = string extends keyof E
|
|
1494
|
+
? {}
|
|
1495
|
+
: {
|
|
1496
|
+
[
|
|
1497
|
+
K in keyof E as K extends `$${string}`
|
|
1498
|
+
? never
|
|
1499
|
+
: false extends E[K]
|
|
1500
|
+
? never
|
|
1501
|
+
: E[K] extends { $relation: any }
|
|
1502
|
+
? never
|
|
1503
|
+
: K
|
|
1504
|
+
]: {
|
|
1505
|
+
names: E[K] extends { $modify: infer N }
|
|
1506
|
+
? N extends readonly (infer I extends string)[]
|
|
1507
|
+
? I
|
|
1508
|
+
: N extends string
|
|
1509
|
+
? N
|
|
1510
|
+
: never
|
|
1511
|
+
: never;
|
|
1512
|
+
children: E[K] extends object ? ParseModifierObject<E[K]> : {};
|
|
1513
|
+
};
|
|
1514
|
+
};
|
|
1515
|
+
|
|
1290
1516
|
export interface ForClassMethod {
|
|
1291
1517
|
<M extends Model>(modelClass: ModelConstructor<M>): QueryBuilderType<M>;
|
|
1292
1518
|
}
|
|
@@ -1301,15 +1527,18 @@ export type JsonObjectOrFieldExpression = object | object[] | FieldExpression;
|
|
|
1301
1527
|
export type Selection<QB extends AnyQueryBuilder> = ColumnRef | AnyQueryBuilder | CallbackVoid<QB>;
|
|
1302
1528
|
|
|
1303
1529
|
export interface SelectMethod<out QB extends AnyQueryBuilder> {
|
|
1304
|
-
//
|
|
1305
|
-
|
|
1530
|
+
// The column overload comes first, for autocompletion, and last in strict
|
|
1531
|
+
// mode, so that errors are reported for it:
|
|
1532
|
+
<QBP extends QB, const C extends readonly [unknown, ...unknown[]]>(
|
|
1533
|
+
...columns: IfStrict<ModelProps<ModelType<QBP>>[], StrictSelections<ModelType<QBP>, C>>
|
|
1534
|
+
): IfStrict<QB, SelectQueryBuilder<QBP, C>>;
|
|
1306
1535
|
<QBP extends QB>(columns: IfStrict<ModelProps<ModelType<QBP>>, never>[]): QB;
|
|
1307
1536
|
|
|
1308
1537
|
<QBP extends QB>(...columns: IfStrict<Selection<QBP>, never>[]): QB;
|
|
1309
1538
|
<QBP extends QB>(columns: IfStrict<Selection<QBP>, never>[]): QB;
|
|
1310
1539
|
|
|
1311
|
-
//
|
|
1312
|
-
<QBP extends QB>(...args: IfStrict<
|
|
1540
|
+
// Allow anything else in loose mode, like `select(1)`:
|
|
1541
|
+
<QBP extends QB>(...args: IfStrict<{} | null | undefined, never>[]): QB;
|
|
1313
1542
|
|
|
1314
1543
|
<QBP extends QB, const C extends readonly unknown[] = []>(
|
|
1315
1544
|
...columns: StrictSelections<ModelType<QBP>, C>
|
|
@@ -1338,7 +1567,7 @@ export interface JsonExtraction {
|
|
|
1338
1567
|
|
|
1339
1568
|
// Extractions without an alias, or with several, add any properties.
|
|
1340
1569
|
export interface JsonExtract<out QB extends AnyQueryBuilder> {
|
|
1341
|
-
//
|
|
1570
|
+
// The column overloads come first, for autocompletion:
|
|
1342
1571
|
<QBP extends QB, const C extends string = never, const A extends string = string>(
|
|
1343
1572
|
column: ColumnArg<ModelType<QBP>, C>,
|
|
1344
1573
|
path: string,
|
|
@@ -1359,7 +1588,7 @@ export interface JsonExtract<out QB extends AnyQueryBuilder> {
|
|
|
1359
1588
|
}
|
|
1360
1589
|
|
|
1361
1590
|
export interface JsonSet<out QB extends AnyQueryBuilder> {
|
|
1362
|
-
//
|
|
1591
|
+
// The column overloads come first, for autocompletion:
|
|
1363
1592
|
<QBP extends QB, const C extends string = never>(
|
|
1364
1593
|
column: ColumnArg<ModelType<QBP>, C>,
|
|
1365
1594
|
path: string,
|
|
@@ -1371,7 +1600,7 @@ export interface JsonSet<out QB extends AnyQueryBuilder> {
|
|
|
1371
1600
|
}
|
|
1372
1601
|
|
|
1373
1602
|
export interface JsonInsert<out QB extends AnyQueryBuilder> {
|
|
1374
|
-
//
|
|
1603
|
+
// The column overloads come first, for autocompletion:
|
|
1375
1604
|
<QBP extends QB, const C extends string = never>(
|
|
1376
1605
|
column: ColumnArg<ModelType<QBP>, C>,
|
|
1377
1606
|
path: string,
|
|
@@ -1383,7 +1612,7 @@ export interface JsonInsert<out QB extends AnyQueryBuilder> {
|
|
|
1383
1612
|
}
|
|
1384
1613
|
|
|
1385
1614
|
export interface JsonRemove<out QB extends AnyQueryBuilder> {
|
|
1386
|
-
//
|
|
1615
|
+
// The column overloads come first, for autocompletion:
|
|
1387
1616
|
<QBP extends QB, const C extends string = never>(
|
|
1388
1617
|
column: ColumnArg<ModelType<QBP>, C>,
|
|
1389
1618
|
path: string,
|
|
@@ -1394,6 +1623,17 @@ export interface JsonRemove<out QB extends AnyQueryBuilder> {
|
|
|
1394
1623
|
}
|
|
1395
1624
|
|
|
1396
1625
|
export interface WhereMethod<out QB extends AnyQueryBuilder> {
|
|
1626
|
+
// The column overloads come first, for autocompletion:
|
|
1627
|
+
<QBP extends QB, const C extends string = never, const O extends Operator = Operator>(
|
|
1628
|
+
col: ColumnArg<ModelType<QBP>, C>,
|
|
1629
|
+
op: O,
|
|
1630
|
+
expr: OperatorValueArg<ModelType<QBP>, C, O>,
|
|
1631
|
+
): QB;
|
|
1632
|
+
<QBP extends QB, const C extends string = never>(
|
|
1633
|
+
col: ColumnArg<ModelType<QBP>, C>,
|
|
1634
|
+
expr: ValueArg<ModelType<QBP>, C>,
|
|
1635
|
+
): QB;
|
|
1636
|
+
|
|
1397
1637
|
(condition: boolean): QB;
|
|
1398
1638
|
(cb: CallbackVoid<QB>): QB;
|
|
1399
1639
|
(raw: Raw): QB;
|
|
@@ -1402,7 +1642,7 @@ export interface WhereMethod<out QB extends AnyQueryBuilder> {
|
|
|
1402
1642
|
(col: RefArg<QB>, op: Operator, expr: Expression<PrimitiveValue>): QB;
|
|
1403
1643
|
(col: RefArg<QB>, expr: Expression<PrimitiveValue>): QB;
|
|
1404
1644
|
|
|
1405
|
-
// The column overloads come last, so that errors are reported for them
|
|
1645
|
+
// The column overloads come last, so that errors are reported for them:
|
|
1406
1646
|
<QBP extends QB, const C extends string = never, const O extends Operator = Operator>(
|
|
1407
1647
|
col: ColumnArg<ModelType<QBP>, C>,
|
|
1408
1648
|
op: O,
|
|
@@ -1414,14 +1654,19 @@ export interface WhereMethod<out QB extends AnyQueryBuilder> {
|
|
|
1414
1654
|
): QB;
|
|
1415
1655
|
|
|
1416
1656
|
<QBP extends QB>(obj: IfStrict<PartialModelProps<ModelType<QBP>>, never>): QB;
|
|
1417
|
-
//
|
|
1418
|
-
//
|
|
1419
|
-
// tools can autocomplete using it.
|
|
1657
|
+
// Allow any keys in loose mode. The model's properties above only serve
|
|
1658
|
+
// autocompletion.
|
|
1420
1659
|
(obj: IfStrict<object, never>): QB;
|
|
1421
1660
|
<QBP extends QB, const O extends object = {}>(obj: O & StrictWhereObject<ModelType<QBP>, O>): QB;
|
|
1422
1661
|
}
|
|
1423
1662
|
|
|
1424
1663
|
export interface WhereLikeMethod<out QB extends AnyQueryBuilder> {
|
|
1664
|
+
// The column overload comes first, for autocompletion, and last, so that
|
|
1665
|
+
// errors are reported for it:
|
|
1666
|
+
<QBP extends QB, const C extends string = never>(
|
|
1667
|
+
col: ColumnArg<ModelType<QBP>, C>,
|
|
1668
|
+
expr: Expression<string>,
|
|
1669
|
+
): QB;
|
|
1425
1670
|
(col: RefArg<QB>, expr: Expression<string>): QB;
|
|
1426
1671
|
<QBP extends QB, const C extends string = never>(
|
|
1427
1672
|
col: ColumnArg<ModelType<QBP>, C>,
|
|
@@ -1442,13 +1687,12 @@ export interface WhereExistsMethod<out QB extends AnyQueryBuilder> {
|
|
|
1442
1687
|
}
|
|
1443
1688
|
|
|
1444
1689
|
export interface WhereInMethod<out QB extends AnyQueryBuilder> {
|
|
1445
|
-
//
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1690
|
+
// The column overload comes first, for autocompletion, and last in strict
|
|
1691
|
+
// mode, so that errors are reported for it:
|
|
1692
|
+
<QBP extends QB, const C extends string = never>(
|
|
1693
|
+
col: ColumnArg<ModelType<QBP>, C>,
|
|
1694
|
+
expr: IfStrict<Expression<PrimitiveValue> | CallbackVoid<QB>, WhereInValues<QB, QBP, C>>,
|
|
1449
1695
|
): QB;
|
|
1450
|
-
<QBP extends QB>(col: IfStrict<ModelProps<ModelType<QBP>>, never>, cb: CallbackVoid<QB>): QB;
|
|
1451
|
-
<QBP extends QB>(col: IfStrict<ModelProps<ModelType<QBP>>, never>, qb: AnyQueryBuilder): QB;
|
|
1452
1696
|
|
|
1453
1697
|
(col: RefArg<QB> | RefArg<QB>[], expr: readonly Expression<PrimitiveValue>[]): QB;
|
|
1454
1698
|
(col: RefArg<QB> | RefArg<QB>[], cb: CallbackVoid<QB>): QB;
|
|
@@ -1456,7 +1700,7 @@ export interface WhereInMethod<out QB extends AnyQueryBuilder> {
|
|
|
1456
1700
|
|
|
1457
1701
|
<QBP extends QB, const C extends string = never>(
|
|
1458
1702
|
col: StrictColumn<ModelType<QBP>, C>,
|
|
1459
|
-
expr:
|
|
1703
|
+
expr: WhereInValues<QB, QBP, C>,
|
|
1460
1704
|
): QB;
|
|
1461
1705
|
<QBP extends QB, const C extends readonly unknown[] = []>(
|
|
1462
1706
|
col: StrictColumns<ModelType<QBP>, C>,
|
|
@@ -1464,6 +1708,9 @@ export interface WhereInMethod<out QB extends AnyQueryBuilder> {
|
|
|
1464
1708
|
): QB;
|
|
1465
1709
|
}
|
|
1466
1710
|
|
|
1711
|
+
type WhereInValues<QB extends AnyQueryBuilder, QBP extends QB, C extends string> =
|
|
1712
|
+
readonly ValueArg<ModelType<QBP>, C>[] | Raw | AnyQueryBuilder | CallbackVoid<QB>;
|
|
1713
|
+
|
|
1467
1714
|
export interface WhereBetweenMethod<out QB extends AnyQueryBuilder> {
|
|
1468
1715
|
(column: RefArg<QB>, range: [Expression<PrimitiveValue>, Expression<PrimitiveValue>]): QB;
|
|
1469
1716
|
<QBP extends QB, const C extends string = never>(
|
|
@@ -1478,7 +1725,7 @@ export interface WhereNullMethod<out QB extends AnyQueryBuilder> {
|
|
|
1478
1725
|
}
|
|
1479
1726
|
|
|
1480
1727
|
export interface WhereColumnMethod<out QB extends AnyQueryBuilder> {
|
|
1481
|
-
//
|
|
1728
|
+
// The column overloads come first, for autocompletion:
|
|
1482
1729
|
<QBP extends QB, const C extends string = never, const D extends string = never>(
|
|
1483
1730
|
col1: ColumnArg<ModelType<QBP>, C>,
|
|
1484
1731
|
op: Operator,
|
|
@@ -1501,7 +1748,7 @@ export interface WhereColumnMethod<out QB extends AnyQueryBuilder> {
|
|
|
1501
1748
|
}
|
|
1502
1749
|
|
|
1503
1750
|
export interface WhereJsonObject<out QB extends AnyQueryBuilder> {
|
|
1504
|
-
//
|
|
1751
|
+
// The column overloads come first, for autocompletion:
|
|
1505
1752
|
<QBP extends QB, const C extends string = never>(
|
|
1506
1753
|
col: ColumnArg<ModelType<QBP>, C>,
|
|
1507
1754
|
value: any,
|
|
@@ -1511,7 +1758,7 @@ export interface WhereJsonObject<out QB extends AnyQueryBuilder> {
|
|
|
1511
1758
|
}
|
|
1512
1759
|
|
|
1513
1760
|
export interface WhereJsonPath<out QB extends AnyQueryBuilder> {
|
|
1514
|
-
//
|
|
1761
|
+
// The column overloads come first, for autocompletion:
|
|
1515
1762
|
<QBP extends QB, const C extends string = never>(
|
|
1516
1763
|
col: ColumnArg<ModelType<QBP>, C>,
|
|
1517
1764
|
jsonPath: string,
|
|
@@ -1664,7 +1911,7 @@ export interface JoinRelatedOptions {
|
|
|
1664
1911
|
|
|
1665
1912
|
export interface JoinRelatedMethod<out QB extends AnyQueryBuilder> {
|
|
1666
1913
|
<QBP extends QB, const E extends RelationExpression<ModelType<QBP>> = never>(
|
|
1667
|
-
expr: E & CheckRelationExpression<ModelType<QBP>, E>,
|
|
1914
|
+
expr: E & CheckRelationExpression<ModelType<QBP>, E, QBP>,
|
|
1668
1915
|
opt?: JoinRelatedOptions,
|
|
1669
1916
|
): QB;
|
|
1670
1917
|
}
|
|
@@ -1868,7 +2115,7 @@ type WriteQueryBuilder<QB extends AnyQueryBuilder, M extends Model, R> = [R] ext
|
|
|
1868
2115
|
* The writes after `returning()` on single and maybe-single query builders,
|
|
1869
2116
|
* which resolve to one row.
|
|
1870
2117
|
*/
|
|
1871
|
-
interface ReturningWrites<QB extends AnyQueryBuilder, M extends Model, W> {
|
|
2118
|
+
export interface ReturningWrites<QB extends AnyQueryBuilder, M extends Model, W> {
|
|
1872
2119
|
update(update: PartialModelRow<M>): Rebind<QB, M, W>;
|
|
1873
2120
|
update(): Rebind<QB, M, W>;
|
|
1874
2121
|
patch(update: PartialModelPatch<M>): Rebind<QB, M, W>;
|
|
@@ -1993,7 +2240,8 @@ export interface GraphOptions {
|
|
|
1993
2240
|
maxBatchSize?: number;
|
|
1994
2241
|
/**
|
|
1995
2242
|
* Apply `limit()`, `offset()` and `first()` in graph modifiers to the related
|
|
1996
|
-
* items of each parent. Defaults to `true`. Only applies to
|
|
2243
|
+
* items of each parent. Defaults to `true`. Only applies to
|
|
2244
|
+
* `withGraphFetched()`.
|
|
1997
2245
|
*/
|
|
1998
2246
|
limitPerParent?: boolean;
|
|
1999
2247
|
}
|
|
@@ -2033,11 +2281,24 @@ export interface ClearContextMethod<out QB extends AnyQueryBuilder> {
|
|
|
2033
2281
|
}
|
|
2034
2282
|
|
|
2035
2283
|
export interface ModifyMethod<out QB extends AnyQueryBuilder> {
|
|
2036
|
-
(modifier:
|
|
2284
|
+
(modifier: ModifyArg<QB> | ModifyArg<QB>[], ...args: any[]): QB;
|
|
2037
2285
|
}
|
|
2038
2286
|
|
|
2039
|
-
|
|
2040
|
-
|
|
2287
|
+
// Registered modifiers add up, on queries with and without a model class.
|
|
2288
|
+
type RegisterModifiers<X, O> =
|
|
2289
|
+
X extends QueryExtra<infer C, infer P, infer I>
|
|
2290
|
+
? QueryExtra<C, P & O, I>
|
|
2291
|
+
: QueryExtra<unknown, O>;
|
|
2292
|
+
|
|
2293
|
+
export interface ModifiersMethod<
|
|
2294
|
+
out QB extends AnyQueryBuilder,
|
|
2295
|
+
M extends Model = ModelType<QB>,
|
|
2296
|
+
R = ResultType<QB>,
|
|
2297
|
+
X = ExtraType<QB>,
|
|
2298
|
+
> {
|
|
2299
|
+
<const O extends Modifiers>(
|
|
2300
|
+
modifiers: O,
|
|
2301
|
+
): IfStrict<QB, Rebind<QB, M, R, RegisterModifiers<X, O>>>;
|
|
2041
2302
|
(): QB;
|
|
2042
2303
|
}
|
|
2043
2304
|
|
|
@@ -2051,7 +2312,11 @@ export interface CatchablePromiseLike<R> extends PromiseLike<R> {
|
|
|
2051
2312
|
): Promise<R | FR>;
|
|
2052
2313
|
}
|
|
2053
2314
|
|
|
2054
|
-
export class QueryBuilder<
|
|
2315
|
+
export class QueryBuilder<
|
|
2316
|
+
M extends Model,
|
|
2317
|
+
R = M[],
|
|
2318
|
+
X = unknown,
|
|
2319
|
+
> implements CatchablePromiseLike<R> {
|
|
2055
2320
|
static forClass: ForClassMethod;
|
|
2056
2321
|
|
|
2057
2322
|
constructor(modelClass: ModelConstructor<M>);
|
|
@@ -2240,35 +2505,35 @@ export class QueryBuilder<M extends Model, R = M[]> implements CatchablePromiseL
|
|
|
2240
2505
|
groupBy: GroupByMethod<this>;
|
|
2241
2506
|
groupByRaw: RawInterface<this>;
|
|
2242
2507
|
|
|
2243
|
-
findById(id:
|
|
2244
|
-
findByIds(ids:
|
|
2508
|
+
findById(id: IdArg<this>): MaybeSingleQueryBuilder<this>;
|
|
2509
|
+
findByIds(ids: IdArg<this>[]): this;
|
|
2245
2510
|
findOne: WhereMethod<MaybeSingleQueryBuilder<this>>;
|
|
2246
2511
|
|
|
2247
2512
|
execute(): Promise<R>;
|
|
2248
2513
|
castTo<MC extends Model>(modelClass: ModelConstructor<MC>): QueryBuilderType<MC>;
|
|
2249
|
-
castTo<R>(): QueryBuilder<M, R>;
|
|
2514
|
+
castTo<R>(): QueryBuilder<M, R, X>;
|
|
2250
2515
|
|
|
2251
2516
|
update(update: PartialModelRow<M>): NumberQueryBuilder<this>;
|
|
2252
2517
|
update(): NumberQueryBuilder<this>;
|
|
2253
2518
|
updateById(
|
|
2254
|
-
id:
|
|
2519
|
+
id: IdArg<this>,
|
|
2255
2520
|
update: PartialModelRow<M>,
|
|
2256
2521
|
): NumberQueryBuilder<MaybeSingleQueryBuilder<this>>;
|
|
2257
2522
|
updateAndFetch(update: PartialModelRow<M>): SingleQueryBuilder<this>;
|
|
2258
|
-
updateAndFetchById(id:
|
|
2523
|
+
updateAndFetchById(id: IdArg<this>, update: PartialModelRow<M>): SingleQueryBuilder<this>;
|
|
2259
2524
|
|
|
2260
2525
|
patch(update: PartialModelPatch<M>): NumberQueryBuilder<this>;
|
|
2261
2526
|
patch(): NumberQueryBuilder<this>;
|
|
2262
2527
|
patchById(
|
|
2263
|
-
id:
|
|
2528
|
+
id: IdArg<this>,
|
|
2264
2529
|
update: PartialModelPatch<M>,
|
|
2265
2530
|
): NumberQueryBuilder<MaybeSingleQueryBuilder<this>>;
|
|
2266
2531
|
patchAndFetch(update: PartialModelPatch<M>): SingleQueryBuilder<this>;
|
|
2267
|
-
patchAndFetchById(id:
|
|
2532
|
+
patchAndFetchById(id: IdArg<this>, update: PartialModelPatch<M>): SingleQueryBuilder<this>;
|
|
2268
2533
|
|
|
2269
2534
|
del(): NumberQueryBuilder<this>;
|
|
2270
2535
|
delete(): NumberQueryBuilder<this>;
|
|
2271
|
-
deleteById(id:
|
|
2536
|
+
deleteById(id: IdArg<this>): NumberQueryBuilder<MaybeSingleQueryBuilder<this>>;
|
|
2272
2537
|
|
|
2273
2538
|
insert(insert: PartialModelRow<M>): SingleQueryBuilder<this>;
|
|
2274
2539
|
insert(insert: PartialModelRow<M>[]): ArrayQueryBuilder<this>;
|
|
@@ -2292,15 +2557,15 @@ export class QueryBuilder<M extends Model, R = M[]> implements CatchablePromiseL
|
|
|
2292
2557
|
// With literal relation expressions, the fetched relations become required
|
|
2293
2558
|
// on the result type, see WithGraphQueryBuilder.
|
|
2294
2559
|
withGraphFetched<const E extends RelationExpression<M>>(
|
|
2295
|
-
expr: E & CheckRelationExpression<M, E>,
|
|
2560
|
+
expr: E & CheckRelationExpression<M, E, this>,
|
|
2296
2561
|
options?: GraphOptions,
|
|
2297
2562
|
): WithGraphQueryBuilder<this, E>;
|
|
2298
2563
|
withGraphJoined<const E extends RelationExpression<M>>(
|
|
2299
|
-
expr: E & CheckRelationExpression<M, E>,
|
|
2564
|
+
expr: E & CheckRelationExpression<M, E, this>,
|
|
2300
2565
|
options?: GraphOptions,
|
|
2301
2566
|
): WithGraphQueryBuilder<this, E>;
|
|
2302
2567
|
withGraph<const E extends RelationExpression<M>>(
|
|
2303
|
-
expr: E & CheckRelationExpression<M, E>,
|
|
2568
|
+
expr: E & CheckRelationExpression<M, E, this>,
|
|
2304
2569
|
options?: WithGraphOptions,
|
|
2305
2570
|
): WithGraphQueryBuilder<this, E>;
|
|
2306
2571
|
|
|
@@ -2378,7 +2643,7 @@ export class QueryBuilder<M extends Model, R = M[]> implements CatchablePromiseL
|
|
|
2378
2643
|
clearContext: ClearContextMethod<this>;
|
|
2379
2644
|
|
|
2380
2645
|
modify: ModifyMethod<this>;
|
|
2381
|
-
modifiers: ModifiersMethod<this>;
|
|
2646
|
+
modifiers: ModifiersMethod<this, M, R, X>;
|
|
2382
2647
|
|
|
2383
2648
|
isFind: BooleanReturningMethod;
|
|
2384
2649
|
isExecutable: BooleanReturningMethod;
|
|
@@ -2404,27 +2669,29 @@ export class QueryBuilder<M extends Model, R = M[]> implements CatchablePromiseL
|
|
|
2404
2669
|
|
|
2405
2670
|
ModelType: M;
|
|
2406
2671
|
ResultType: R;
|
|
2672
|
+
ExtraType: X;
|
|
2407
2673
|
|
|
2408
|
-
// The model and
|
|
2409
|
-
// are `any` where `this` isn't rebound, e.g. when TypeScript
|
|
2410
|
-
// members of a custom query builder against this class.
|
|
2674
|
+
// The model, result and extra types that `RebindType` is instantiated
|
|
2675
|
+
// with. They are `any` where `this` isn't rebound, e.g. when TypeScript
|
|
2676
|
+
// checks the members of a custom query builder against this class.
|
|
2411
2677
|
'~rebind': unknown;
|
|
2412
|
-
'~M': this['~rebind'] extends [any, any] ? this['~rebind'][0] : any;
|
|
2413
|
-
'~R': this['~rebind'] extends [any, any] ? this['~rebind'][1] : any;
|
|
2678
|
+
'~M': this['~rebind'] extends [any, any, any] ? this['~rebind'][0] : any;
|
|
2679
|
+
'~R': this['~rebind'] extends [any, any, any] ? this['~rebind'][1] : any;
|
|
2680
|
+
'~X': this['~rebind'] extends [any, any, any] ? this['~rebind'][2] : any;
|
|
2414
2681
|
|
|
2415
2682
|
/**
|
|
2416
|
-
* This query builder, re-instantiated with other model and
|
|
2417
|
-
* e.g. by `first()` or `page()`. Custom query builders redeclare it
|
|
2418
|
-
* their own type:
|
|
2683
|
+
* This query builder, re-instantiated with other model, result and extra
|
|
2684
|
+
* types, e.g. by `first()` or `page()`. Custom query builders redeclare it
|
|
2685
|
+
* to keep their own type:
|
|
2419
2686
|
*
|
|
2420
|
-
* declare RebindType: MyQueryBuilder<this['~M'], this['~R']>;
|
|
2687
|
+
* declare RebindType: MyQueryBuilder<this['~M'], this['~R'], this['~X']>;
|
|
2421
2688
|
*/
|
|
2422
|
-
RebindType: QueryBuilder<this['~M'], this['~R']>;
|
|
2689
|
+
RebindType: QueryBuilder<this['~M'], this['~R'], this['~X']>;
|
|
2423
2690
|
|
|
2424
2691
|
// The query builder rebound to the result kinds of the helper types, e.g.
|
|
2425
2692
|
// `SingleQueryBuilder`. As members, they also resolve where `this` is
|
|
2426
2693
|
// generic, e.g. in the methods of custom query builders. Of the members
|
|
2427
|
-
// starting with `~`, only `~M` and `~
|
|
2694
|
+
// starting with `~`, only `~M`, `~R` and `~X` are API, for `RebindType`.
|
|
2428
2695
|
'~single': Rebind<this, M, ResultItem<R, M>>;
|
|
2429
2696
|
'~maybeSingle': Rebind<this, M, ResultItem<R, M> | undefined>;
|
|
2430
2697
|
'~array': Rebind<this, M, ResultItem<R, M>[]>;
|
|
@@ -2441,8 +2708,6 @@ export class QueryBuilder<M extends Model, R = M[]> implements CatchablePromiseL
|
|
|
2441
2708
|
): Promise<R | FR>;
|
|
2442
2709
|
}
|
|
2443
2710
|
|
|
2444
|
-
export type X<T> = Promise<T>;
|
|
2445
|
-
|
|
2446
2711
|
export interface FetchGraphOptions {
|
|
2447
2712
|
transaction?: TransactionOrKnex;
|
|
2448
2713
|
skipFetched?: boolean;
|
|
@@ -2790,7 +3055,8 @@ export interface ConstructorFunctionType<T = any> extends PrototypeType<T> {
|
|
|
2790
3055
|
new (...args: any[]): T;
|
|
2791
3056
|
}
|
|
2792
3057
|
|
|
2793
|
-
//
|
|
3058
|
+
// Used internally to infer the generic static `this`, copied from:
|
|
3059
|
+
// https://github.com/microsoft/TypeScript/issues/5863#issuecomment-1483978415
|
|
2794
3060
|
export type ConstructorType<T = unknown, Static extends Record<string, any> = PrototypeType<T>> = (
|
|
2795
3061
|
ConstructorFunctionType<T> | PrototypeType<T>
|
|
2796
3062
|
) & {
|
|
@@ -2808,7 +3074,7 @@ export interface ModelClass<M extends Model> extends ModelConstructor<M> {
|
|
|
2808
3074
|
relationMappings: RelationMappings | RelationMappingsThunk;
|
|
2809
3075
|
modelPaths: string[];
|
|
2810
3076
|
jsonAttributes: string[] | readonly string[];
|
|
2811
|
-
virtualAttributes: string[];
|
|
3077
|
+
virtualAttributes: readonly string[];
|
|
2812
3078
|
uidProp: string;
|
|
2813
3079
|
uidRefProp: string;
|
|
2814
3080
|
dbRefProp: string;
|
|
@@ -2867,7 +3133,7 @@ export interface ModelClass<M extends Model> extends ModelConstructor<M> {
|
|
|
2867
3133
|
|
|
2868
3134
|
transaction<T>(callback: (trx: Transaction) => Promise<T>): Promise<T>;
|
|
2869
3135
|
transaction<T>(
|
|
2870
|
-
trxOrKnex: TransactionOrKnex,
|
|
3136
|
+
trxOrKnex: TransactionOrKnex | undefined,
|
|
2871
3137
|
callback: (trx: Transaction) => Promise<T>,
|
|
2872
3138
|
): Promise<T>;
|
|
2873
3139
|
|
|
@@ -2921,7 +3187,7 @@ export class Model {
|
|
|
2921
3187
|
static relationMappings: RelationMappings | RelationMappingsThunk;
|
|
2922
3188
|
static modelPaths: string[];
|
|
2923
3189
|
static jsonAttributes: string[] | readonly string[];
|
|
2924
|
-
static virtualAttributes: string[];
|
|
3190
|
+
static virtualAttributes: readonly string[];
|
|
2925
3191
|
static uidProp: string;
|
|
2926
3192
|
static uidRefProp: string;
|
|
2927
3193
|
static dbRefProp: string;
|
|
@@ -2949,16 +3215,28 @@ export class Model {
|
|
|
2949
3215
|
|
|
2950
3216
|
static defaultGraphOptions?: GraphOptions;
|
|
2951
3217
|
|
|
2952
|
-
|
|
2953
|
-
|
|
3218
|
+
// The id column K is inferred separately from the class C, so that it
|
|
3219
|
+
// resolves through the constraint of a generic class, e.g. in static helpers
|
|
3220
|
+
// with `this: T`.
|
|
3221
|
+
static query<M extends Model, C = unknown, K = unknown>(
|
|
3222
|
+
this: ConstructorType<M> & IfStrict<unknown, C & { idColumn?: K }>,
|
|
2954
3223
|
trxOrKnex?: TransactionOrKnex,
|
|
2955
|
-
):
|
|
3224
|
+
): IfStrict<
|
|
3225
|
+
QueryBuilderType<M>,
|
|
3226
|
+
WithExtra<QueryBuilderType<M>, QueryExtra<C, {}, ColumnsId<K, M>>>
|
|
3227
|
+
>;
|
|
2956
3228
|
|
|
2957
|
-
static relatedQuery<M extends Model, K extends keyof M>(
|
|
2958
|
-
this: ConstructorType<M>,
|
|
3229
|
+
static relatedQuery<M extends Model, K extends keyof M, C = unknown>(
|
|
3230
|
+
this: ConstructorType<M> & IfStrict<unknown, C>,
|
|
2959
3231
|
relationName: K,
|
|
2960
3232
|
trxOrKnex?: TransactionOrKnex,
|
|
2961
|
-
):
|
|
3233
|
+
): IfStrict<
|
|
3234
|
+
ArrayRelatedQueryBuilder<M[K]>,
|
|
3235
|
+
WithExtra<
|
|
3236
|
+
ArrayRelatedQueryBuilder<M[K]>,
|
|
3237
|
+
QueryExtra<MappedClass<ClassMappings<C>, K>, {}, ClassId<MappedClass<ClassMappings<C>, K>>>
|
|
3238
|
+
>
|
|
3239
|
+
>;
|
|
2962
3240
|
|
|
2963
3241
|
static relatedQuery<RM extends Model>(
|
|
2964
3242
|
relationName: string,
|
|
@@ -3215,32 +3493,26 @@ export interface initialize {
|
|
|
3215
3493
|
|
|
3216
3494
|
/**
|
|
3217
3495
|
* The type of the values that a JSON schema declared with `as const`
|
|
3218
|
-
* describes, e.g.
|
|
3496
|
+
* describes, e.g. of JSON columns, or of models that subclasses extend, whose
|
|
3497
|
+
* `jsonSchema` has the general type for `FromModel`:
|
|
3219
3498
|
*
|
|
3220
|
-
*
|
|
3221
|
-
* static jsonSchema = {
|
|
3222
|
-
* type: 'object',
|
|
3223
|
-
* required: ['firstName'],
|
|
3224
|
-
* properties: {
|
|
3225
|
-
* id: { type: 'integer' },
|
|
3226
|
-
* firstName: { type: 'string' },
|
|
3227
|
-
* age: { type: ['integer', 'null'] },
|
|
3228
|
-
* },
|
|
3229
|
-
* } as const;
|
|
3499
|
+
* const entrySchema = { type: 'object', properties: { ... } } as const;
|
|
3230
3500
|
*
|
|
3231
|
-
*
|
|
3501
|
+
* class Entry extends Model {
|
|
3502
|
+
* static jsonSchema: ReadonlyJSONSchema = entrySchema;
|
|
3232
3503
|
* }
|
|
3233
3504
|
*
|
|
3234
|
-
* interface
|
|
3505
|
+
* interface Entry extends FromJSONSchema<typeof entrySchema>, FromModel<typeof Entry> {}
|
|
3235
3506
|
*
|
|
3236
3507
|
* Supports `type` (also as an array), `required`, `nullable`, `enum`,
|
|
3237
3508
|
* `const`, `items` (also as a tuple), nested `properties`, `anyOf` and
|
|
3238
|
-
* `oneOf`. Formats like 'date-time' stay strings, as in JSON
|
|
3239
|
-
*
|
|
3240
|
-
*
|
|
3241
|
-
* don't change
|
|
3509
|
+
* `oneOf`. Formats like 'date-time' stay strings, as in JSON, see the
|
|
3510
|
+
* timestamps recipe for the dates that drivers return. Properties that aren't
|
|
3511
|
+
* required are optional. Next to `type` or `properties`, `anyOf` and `oneOf`
|
|
3512
|
+
* only add constraints, e.g. alternative `required` lists, and don't change
|
|
3513
|
+
* the type.
|
|
3242
3514
|
*/
|
|
3243
|
-
export type
|
|
3515
|
+
export type FromJSONSchema<S> = S extends boolean
|
|
3244
3516
|
? unknown
|
|
3245
3517
|
: S extends { const: infer C }
|
|
3246
3518
|
? Extract<C, SchemaType<S>>
|
|
@@ -3251,7 +3523,7 @@ export type FromSchema<S> = S extends boolean
|
|
|
3251
3523
|
: S extends { properties: object }
|
|
3252
3524
|
? SchemaObject<S>
|
|
3253
3525
|
: S extends { anyOf: readonly (infer A)[] } | { oneOf: readonly (infer A)[] }
|
|
3254
|
-
?
|
|
3526
|
+
? FromJSONSchema<A> | SchemaNullable<S>
|
|
3255
3527
|
: unknown;
|
|
3256
3528
|
|
|
3257
3529
|
// The type that `type` allows, which `enum` and `const` values are narrowed
|
|
@@ -3280,7 +3552,7 @@ type SchemaTypeName<N, S> = N extends 'string'
|
|
|
3280
3552
|
type SchemaArray<S> = S extends { items: infer I }
|
|
3281
3553
|
? I extends readonly unknown[]
|
|
3282
3554
|
? SchemaTuple<I, S>
|
|
3283
|
-
:
|
|
3555
|
+
: FromJSONSchema<I>[]
|
|
3284
3556
|
: unknown[];
|
|
3285
3557
|
|
|
3286
3558
|
// Tuple `items` only check the items that are present: they are required
|
|
@@ -3288,12 +3560,12 @@ type SchemaArray<S> = S extends { items: infer I }
|
|
|
3288
3560
|
// `additionalItems` restricts them.
|
|
3289
3561
|
type SchemaTuple<I extends readonly unknown[], S> = [
|
|
3290
3562
|
...(S extends { minItems: I['length'] }
|
|
3291
|
-
? { -readonly [K in keyof I]:
|
|
3292
|
-
: { -readonly [K in keyof I]?:
|
|
3563
|
+
? { -readonly [K in keyof I]: FromJSONSchema<I[K]> }
|
|
3564
|
+
: { -readonly [K in keyof I]?: FromJSONSchema<I[K]> }),
|
|
3293
3565
|
...(S extends { additionalItems: false }
|
|
3294
3566
|
? []
|
|
3295
3567
|
: S extends { additionalItems: infer A }
|
|
3296
|
-
?
|
|
3568
|
+
? FromJSONSchema<A>[]
|
|
3297
3569
|
: unknown[]),
|
|
3298
3570
|
];
|
|
3299
3571
|
|
|
@@ -3305,16 +3577,97 @@ type SchemaObject<S> = S extends { properties: infer P }
|
|
|
3305
3577
|
|
|
3306
3578
|
// The intersection is flattened into one object type for readable hovers.
|
|
3307
3579
|
type SchemaProperties<P, R> = {
|
|
3308
|
-
-readonly [K in keyof P as K extends R ? K : never]:
|
|
3580
|
+
-readonly [K in keyof P as K extends R ? K : never]: FromJSONSchema<P[K]>;
|
|
3309
3581
|
} & {
|
|
3310
|
-
-readonly [K in keyof P as K extends R ? never : K]?:
|
|
3582
|
+
-readonly [K in keyof P as K extends R ? never : K]?: FromJSONSchema<P[K]>;
|
|
3311
3583
|
} extends infer O
|
|
3312
3584
|
? { [K in keyof O]: O[K] }
|
|
3313
3585
|
: never;
|
|
3314
3586
|
|
|
3587
|
+
/**
|
|
3588
|
+
* The properties of a model class, derived from its `jsonSchema` declared
|
|
3589
|
+
* `as const` and its `relationMappings`:
|
|
3590
|
+
*
|
|
3591
|
+
* class Person extends Model {
|
|
3592
|
+
* static jsonSchema = { ... } as const;
|
|
3593
|
+
*
|
|
3594
|
+
* static relationMappings = () => ({
|
|
3595
|
+
* parent: {
|
|
3596
|
+
* relation: Model.BelongsToOneRelation,
|
|
3597
|
+
* modelClass: Person,
|
|
3598
|
+
* join: { from: 'persons.parentId', to: 'persons.id' },
|
|
3599
|
+
* },
|
|
3600
|
+
* });
|
|
3601
|
+
* }
|
|
3602
|
+
*
|
|
3603
|
+
* interface Person extends FromModel<typeof Person> {}
|
|
3604
|
+
*
|
|
3605
|
+
* The properties are typed as with `FromJSONSchema`. Relations are optional, as
|
|
3606
|
+
* they are only present when fetched: to-one relations are typed `M | null`,
|
|
3607
|
+
* as `withGraphFetched()` sets missing ones to `null`, and to-many relations
|
|
3608
|
+
* `M[]`. Relations with a module path as `modelClass`, and mappings declared
|
|
3609
|
+
* as `RelationMapping` instead of inferred, are left out, as are a schema and
|
|
3610
|
+
* mappings with their general types, e.g. inherited from `Model`. The names of
|
|
3611
|
+
* `virtualAttributes` declared `as const` are kept for `ModelJson`.
|
|
3612
|
+
*/
|
|
3613
|
+
export type FromModel<C extends { jsonSchema: unknown; relationMappings: unknown }> =
|
|
3614
|
+
ModelSchemaProperties<C['jsonSchema']> &
|
|
3615
|
+
ModelRelationProperties<C['relationMappings']> &
|
|
3616
|
+
VirtualAttributeKeys<C>;
|
|
3617
|
+
|
|
3618
|
+
// One key per name, so that subclasses that add virtual attributes have the
|
|
3619
|
+
// same keys as their parent for the inherited ones.
|
|
3620
|
+
type VirtualAttributeKeys<C> = C extends { virtualAttributes: infer V extends readonly string[] }
|
|
3621
|
+
? string extends V[number]
|
|
3622
|
+
? {}
|
|
3623
|
+
: { readonly [K in V[number] as `~virtual:${K}`]?: true }
|
|
3624
|
+
: {};
|
|
3625
|
+
|
|
3626
|
+
type ModelSchemaProperties<S> = ReadonlyJSONSchema extends S
|
|
3627
|
+
? {}
|
|
3628
|
+
: FromJSONSchema<S> extends infer P extends object
|
|
3629
|
+
? P
|
|
3630
|
+
: {};
|
|
3631
|
+
|
|
3632
|
+
// Relations are picked by their mappings, as resolving the related models
|
|
3633
|
+
// while the model's own type is built would make it its own base type.
|
|
3634
|
+
type ModelRelationProperties<T, R = T extends () => infer M ? M : T> = string extends keyof R
|
|
3635
|
+
? {}
|
|
3636
|
+
: {
|
|
3637
|
+
-readonly [K in keyof R as IsMappedRelation<R[K]> extends true ? K : never]?: MappedRelation<
|
|
3638
|
+
R[K]
|
|
3639
|
+
>;
|
|
3640
|
+
};
|
|
3641
|
+
|
|
3642
|
+
// Relation types without a brand and module paths can't be resolved.
|
|
3643
|
+
type IsMappedRelation<M> = M extends { relation: infer T; modelClass: infer C }
|
|
3644
|
+
? [MappedKind<T>] extends [never]
|
|
3645
|
+
? false
|
|
3646
|
+
: C extends string
|
|
3647
|
+
? false
|
|
3648
|
+
: true
|
|
3649
|
+
: false;
|
|
3650
|
+
|
|
3651
|
+
// The related model is inferred from the constructor without checking it
|
|
3652
|
+
// against `Model`, as that check would circle back through the relations of
|
|
3653
|
+
// self-referencing models.
|
|
3654
|
+
type MappedRelation<M> = M extends { relation: infer T; modelClass: infer C }
|
|
3655
|
+
? MappedKind<T> extends 'HasMany' | 'ManyToMany' | 'BelongsToMany'
|
|
3656
|
+
? MappedModel<C>[]
|
|
3657
|
+
: MappedModel<C> | null
|
|
3658
|
+
: never;
|
|
3659
|
+
|
|
3660
|
+
type MappedKind<T> = T extends { readonly [relationKind]?: infer K } ? K : never;
|
|
3661
|
+
|
|
3662
|
+
type MappedModel<C> = C extends abstract new (...args: any) => infer I
|
|
3663
|
+
? I
|
|
3664
|
+
: C extends () => abstract new (...args: any) => infer I
|
|
3665
|
+
? I
|
|
3666
|
+
: never;
|
|
3667
|
+
|
|
3315
3668
|
/**
|
|
3316
3669
|
* A JSON schema with readonly arrays, the type of `static jsonSchema`, so that
|
|
3317
|
-
* it takes schemas declared `as const`, for `
|
|
3670
|
+
* it takes schemas declared `as const`, for `FromJSONSchema`. A `JSONSchema` is
|
|
3318
3671
|
* assignable to it.
|
|
3319
3672
|
*/
|
|
3320
3673
|
export type ReadonlyJSONSchema = ReadonlyDeep<JSONSchema>;
|