objection 4.0.0-rc.3 → 4.0.0

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.
Files changed (25) hide show
  1. package/lib/dbErrors/parsers/sqlite/DBError/ConstraintViolationError/CheckViolationError/parser.js +2 -9
  2. package/lib/dbErrors/parsers/sqlite/DBError/ConstraintViolationError/ForeignKeyViolationError/parser.js +2 -9
  3. package/lib/dbErrors/parsers/sqlite/DBError/ConstraintViolationError/NotNullViolationError/parser.js +4 -2
  4. package/lib/dbErrors/parsers/sqlite/DBError/ConstraintViolationError/UniqueViolationError/parser.js +4 -2
  5. package/lib/dbErrors/parsers/sqlite/DBError/ConstraintViolationError/constraintMessage.js +16 -0
  6. package/lib/dbErrors/parsers/sqlite/DBError/ConstraintViolationError/parser.js +2 -1
  7. package/lib/dbErrors/parsers/sqlite/DBError/parser.js +2 -1
  8. package/lib/model/modelJsonAttributes.js +15 -6
  9. package/lib/objection.js +1 -0
  10. package/lib/queryBuilder/InternalOptions.js +4 -0
  11. package/lib/queryBuilder/StaticHookArguments.js +4 -2
  12. package/lib/queryBuilder/graph/GraphNode.js +8 -0
  13. package/lib/queryBuilder/graph/GraphPlan.js +13 -0
  14. package/lib/queryBuilder/graph/GraphSchedule.js +92 -40
  15. package/lib/queryBuilder/graph/GraphUpsert.js +2 -0
  16. package/lib/queryBuilder/graph/GraphWriter.js +159 -18
  17. package/lib/queryBuilder/graph/graphChecks.js +40 -3
  18. package/lib/queryBuilder/graph/graphKeys.js +146 -61
  19. package/lib/queryBuilder/jsonDialects/JsonDialect.js +6 -0
  20. package/lib/queryBuilder/operations/AsArrayOperation.js +10 -0
  21. package/lib/queryBuilder/operations/UpdateOperation.js +20 -7
  22. package/lib/queryBuilder/operations/fieldExpressions.js +15 -4
  23. package/lib/relations/RelationProperty.js +11 -0
  24. package/package.json +11 -4
  25. package/typings/objection/index.d.ts +191 -184
@@ -80,6 +80,10 @@ export class UniqueViolationError extends ConstraintViolationError {
80
80
  schema?: string;
81
81
  }
82
82
 
83
+ // Wraps an error of the database driver in the matching database error class,
84
+ // or returns it as it is.
85
+ export function wrapError<E>(err: E): DBError | E;
86
+
83
87
  export interface RawBuilder extends Aliasable {}
84
88
 
85
89
  export interface RawFunction extends RawInterface<RawBuilder> {}
@@ -214,6 +218,7 @@ export type RelationExpression<M extends Model> = string | object;
214
218
 
215
219
  // Type-level parsing of relation expressions, used to narrow the result
216
220
  // types of `withGraphFetched()`, `withGraphJoined()` and `fetchGraph()`.
221
+ // The types that declarations of inferred query types refer to are exported.
217
222
 
218
223
  /**
219
224
  * Parses a relation expression, in string or object notation, into a tree
@@ -234,9 +239,9 @@ export type ParseRelationExpression<E> = [E] extends [never]
234
239
  ? ParseRelationString<E>
235
240
  : ParseRelationObject<E>;
236
241
 
237
- export type Whitespace = ' ' | '\n' | '\r' | '\t';
242
+ type Whitespace = ' ' | '\n' | '\r' | '\t';
238
243
 
239
- export type Trim<S extends string> = S extends `${Whitespace}${infer R}`
244
+ type Trim<S extends string> = S extends `${Whitespace}${infer R}`
240
245
  ? Trim<R>
241
246
  : S extends `${infer L}${Whitespace}`
242
247
  ? Trim<L>
@@ -245,7 +250,7 @@ export type Trim<S extends string> = S extends `${Whitespace}${infer R}`
245
250
  /**
246
251
  * Counts the occurrences of character C in S, as a tuple length.
247
252
  */
248
- export type CountChar<
253
+ type CountChar<
249
254
  S extends string,
250
255
  C extends string,
251
256
  N extends 0[] = [],
@@ -254,7 +259,7 @@ export type CountChar<
254
259
  /**
255
260
  * True if S has as many opening as closing brackets and parentheses.
256
261
  */
257
- export type IsBalanced<S extends string> =
262
+ type IsBalanced<S extends string> =
258
263
  CountChar<S, '['> extends CountChar<S, ']'>
259
264
  ? CountChar<S, '('> extends CountChar<S, ')'>
260
265
  ? true
@@ -265,7 +270,7 @@ export type IsBalanced<S extends string> =
265
270
  * Splits a list of expressions at the commas that aren't nested inside
266
271
  * brackets or parentheses: 'a, b.[c, d]' -> ['a', 'b.[c, d]'].
267
272
  */
268
- export type SplitList<
273
+ type SplitList<
269
274
  S extends string,
270
275
  Acc extends string = '',
271
276
  Out extends string[] = [],
@@ -275,7 +280,7 @@ export type SplitList<
275
280
  : SplitList<Rest, `${Acc}${Head},`, Out>
276
281
  : [...Out, `${Acc}${S}`];
277
282
 
278
- export type ParseRelationList<L extends string[], Acc = {}> = L extends [
283
+ type ParseRelationList<L extends string[], Acc = {}> = L extends [
279
284
  infer H extends string,
280
285
  ...infer T extends string[],
281
286
  ]
@@ -285,7 +290,7 @@ export type ParseRelationList<L extends string[], Acc = {}> = L extends [
285
290
  /**
286
291
  * Parses '[a, b]', 'a.b' and 'a' style expressions.
287
292
  */
288
- export type ParseRelationString<S extends string> =
293
+ type ParseRelationString<S extends string> =
289
294
  Trim<S> extends `[${infer Inner}]`
290
295
  ? ParseRelationList<SplitList<Inner>>
291
296
  : Trim<S> extends `${infer Head}.${infer Rest}`
@@ -299,7 +304,7 @@ export type ParseRelationString<S extends string> =
299
304
  * 'pets(selectName)' -> 'pets'. Returns never for nodes that can't be
300
305
  * narrowed: aliases ('pets as p'), '*' and recursion ('^', '^2').
301
306
  */
302
- export type RelationName<S extends string> =
307
+ type RelationName<S extends string> =
303
308
  Trim<S> extends `${infer Name}(${string})`
304
309
  ? RelationName<Name>
305
310
  : Trim<S> extends infer Name extends string
@@ -310,7 +315,7 @@ export type RelationName<S extends string> =
310
315
  : Name
311
316
  : never;
312
317
 
313
- export type RelationNode<Name extends string, Children> = [Name] extends [never]
318
+ type RelationNode<Name extends string, Children> = [Name] extends [never]
314
319
  ? {}
315
320
  : { [K in Name]: Children };
316
321
 
@@ -319,26 +324,27 @@ export type RelationNode<Name extends string, Children> = [Name] extends [never]
319
324
  * `$` are options, and aliased nodes (`{ p: { $relation: 'pets' } }`) are
320
325
  * skipped.
321
326
  */
322
- export type ParseRelationObject<E> = string extends keyof E
323
- ? {}
324
- : {
325
- [
326
- K in keyof E as K extends `$${string}`
327
- ? never
328
- : false extends E[K]
327
+ type ParseRelationObject<E> =
328
+ HasOnlyLiteralKeys<E> extends true
329
+ ? {
330
+ [
331
+ K in keyof E as K extends `$${string}`
329
332
  ? never
330
- : E[K] extends { $relation: any }
333
+ : false extends E[K]
331
334
  ? never
332
- : K
333
- ]: E[K] extends object ? ParseRelationObject<E[K]> : {};
334
- };
335
+ : E[K] extends { $relation: any }
336
+ ? never
337
+ : K
338
+ ]: E[K] extends object ? ParseRelationObject<E[K]> : {};
339
+ }
340
+ : {};
335
341
 
336
342
  /**
337
343
  * Marks the relations in tree T as fetched on model M: they become required
338
344
  * and are narrowed recursively. Only `undefined` is removed: declared `null`
339
345
  * is kept, as to-one relations can be null when there is no related row.
340
346
  */
341
- export type WithGraph<M, T> = [keyof T] extends [never]
347
+ type WithGraph<M, T> = [keyof T] extends [never]
342
348
  ? M
343
349
  : WithGraphRelations<M, T, FetchedRelations<M, T>>;
344
350
 
@@ -362,7 +368,7 @@ export type FetchedRelations<M, T> = {
362
368
  [K in keyof M & keyof T]: NonNullable<M[K]> extends Model | Model[] ? K : never;
363
369
  }[keyof M & keyof T];
364
370
 
365
- export type WithGraphProperty<P, T> = [keyof T] extends [never]
371
+ type WithGraphProperty<P, T> = [keyof T] extends [never]
366
372
  ? P
367
373
  : P extends Array<infer I>
368
374
  ? WithGraph<I, T>[]
@@ -466,16 +472,11 @@ type ItemOf<R, M> = R extends readonly (infer I)[]
466
472
  ? R
467
473
  : M;
468
474
 
469
- /**
470
- * If T is an array, returns the item type, otherwise returns T.
471
- */
472
- export type ItemType<T> = T extends Array<unknown> ? T[number] : T;
473
-
474
475
  /**
475
476
  * Type for keys of non-function properties of T.
476
477
  */
477
478
  export type NonFunctionPropertyNames<T> = {
478
- [K in keyof T]: T[K] extends Function ? never : K;
479
+ [K in keyof T]-?: T[K] extends Function ? never : K;
479
480
  }[keyof T];
480
481
 
481
482
  // The type-only members of models, which aren't data, also the keys of the
@@ -540,7 +541,7 @@ export type PartialModelObject<T extends Model> = {
540
541
  ? I[] | PartialModelObject<I>[]
541
542
  : Expression<T[K]>
542
543
  : NonNullable<T[K]> extends Model
543
- ? Expression<T[K]> | PartialModelObject<NonNullable<T[K]>> // nullable to-one relations
544
+ ? Expression<T[K]> | PartialModelObject<NonNullable<T[K]>> // Nullable to-one relations
544
545
  : Expression<T[K]>;
545
546
  };
546
547
 
@@ -550,7 +551,7 @@ export type PartialModelObject<T extends Model> = {
550
551
  * builders for models with narrowed relations (see WithGraphModel) remain
551
552
  * assignable to the query builders for the plain models.
552
553
  */
553
- export type PartialModelProps<T extends Model> = {
554
+ type PartialModelProps<T extends Model> = {
554
555
  [K in DataPropertyNames<T>]?: K extends RelationPropertyNames<T> ? never : Expression<T[K]>;
555
556
  };
556
557
 
@@ -591,7 +592,7 @@ export type GraphParameters = {
591
592
  export type PartialModelGraph<M, T = M & GraphParameters> = T extends any
592
593
  ? {
593
594
  [K in DataPropertyNames<T>]?: null extends T[K]
594
- ? PartialModelGraphField<NonNullable<T[K]>> | null // handle nullable BelongsToOneRelations
595
+ ? PartialModelGraphField<NonNullable<T[K]>> | null // Strip null to recognize to-one relations
595
596
  : PartialModelGraphField<T[K]>;
596
597
  }
597
598
  : never;
@@ -622,7 +623,7 @@ export interface GeneratedBrand {
622
623
  /**
623
624
  * Insert keys are optional for optional, nullable and generated properties.
624
625
  */
625
- export type OptionalInsertPropertyNames<M> = {
626
+ type OptionalInsertPropertyNames<M> = {
626
627
  [K in keyof M]-?: {} extends Pick<M, K>
627
628
  ? K
628
629
  : null extends M[K]
@@ -632,12 +633,13 @@ export type OptionalInsertPropertyNames<M> = {
632
633
  : never;
633
634
  }[keyof M];
634
635
 
635
- export type InsertablePropertyNames<M> = Exclude<DataPropertyNames<M>, RelationPropertyNames<M>>;
636
+ type InsertablePropertyNames<M> = Exclude<DataPropertyNames<M>, RelationPropertyNames<M>>;
636
637
 
637
638
  /**
638
- * The data to insert a model M with `insert()`. Unlike `PartialModelObject`,
639
- * all properties are required except optional, nullable and `Generated`
640
- * ones. Relation properties are left out.
639
+ * The complete data of a new row of model M, to check what is passed to
640
+ * `insert()`, which itself takes any subset of the properties. Unlike
641
+ * `PartialModelObject`, all properties are required except optional, nullable
642
+ * and `Generated` ones. Relation properties are left out.
641
643
  */
642
644
  export type Insertable<M extends Model> = {
643
645
  [K in Exclude<InsertablePropertyNames<M>, OptionalInsertPropertyNames<M>>]: Expression<M[K]>;
@@ -646,18 +648,18 @@ export type Insertable<M extends Model> = {
646
648
  };
647
649
 
648
650
  /**
649
- * Like `Insertable`, but for `insertGraph()`: relation properties are
650
- * optional and hold the insertable graphs of the related models, or
651
- * references to existing ones through `#dbRef` or `#ref`.
651
+ * Like `Insertable`, but for graphs passed to `insertGraph()`: relation
652
+ * properties are optional and hold the insertable graphs of the related
653
+ * models, or references to existing ones through `#dbRef` or `#ref`.
652
654
  */
653
655
  export type InsertableGraph<M extends Model> = Insertable<M> &
654
656
  Omit<GraphParameters, '#dbRef' | '#ref'> & {
655
657
  [K in RelationPropertyNames<M>]?: InsertableGraphField<M[K]>;
656
658
  };
657
659
 
658
- export type InsertableGraphReference = { '#dbRef': MaybeCompositeId } | { '#ref': string };
660
+ type InsertableGraphReference = { '#dbRef': MaybeCompositeId } | { '#ref': string };
659
661
 
660
- export type InsertableGraphField<F> =
662
+ type InsertableGraphField<F> =
661
663
  NonNullable<F> extends (infer I extends Model)[]
662
664
  ? (InsertableGraph<I> | InsertableGraphReference)[]
663
665
  : NonNullable<F> extends infer I extends Model
@@ -667,38 +669,15 @@ export type InsertableGraphField<F> =
667
669
  /**
668
670
  * Extracts the property names (excluding relations) of a model class.
669
671
  */
670
- export type ModelProps<T extends Model> = Exclude<
671
- {
672
- [K in keyof T]?: Defined<T[K]> extends Model
673
- ? never
674
- : Defined<T[K]> extends Array<infer I>
675
- ? I extends Model
676
- ? never
677
- : K
678
- : T[K] extends Function
679
- ? never
680
- : K;
681
- }[keyof T],
682
- undefined | ModelTypeMembers
683
- >;
672
+ export type ModelProps<T extends Model> = InsertablePropertyNames<T>;
684
673
 
685
674
  /**
686
- * Extracts the relation names of the a model class.
675
+ * Extracts the relation names of a model class.
687
676
  */
688
- export type ModelRelations<T extends Model> = Defined<
689
- {
690
- [K in keyof T]?: Defined<T[K]> extends Model
691
- ? K
692
- : Defined<T[K]> extends Array<infer I>
693
- ? I extends Model
694
- ? K
695
- : never
696
- : never;
697
- }[keyof T]
698
- >;
677
+ export type ModelRelations<T extends Model> = RelationPropertyNames<T>;
699
678
 
700
679
  /**
701
- * Given a model property type, returns a query builer type of
680
+ * Given a model property type, returns a query builder type of the
702
681
  * correct kind if the property is a model or a model array. Queries for
703
682
  * to-one relations resolve to `undefined` when there's no related row.
704
683
  */
@@ -760,6 +739,18 @@ type Rebind<
760
739
  */
761
740
  export type ExtraType<T extends { ExtraType: any }> = T['ExtraType'];
762
741
 
742
+ /**
743
+ * The extra type of queries in strict mode: the model class C that started the
744
+ * query, e.g. with `Person.query()`, and the modifiers P registered with
745
+ * `modifiers()`, to check the names of modifiers, and the id I of the class,
746
+ * for `findById()` and the other `*ById()` methods.
747
+ */
748
+ export interface QueryExtra<C = unknown, P = unknown, I = MaybeCompositeId> {
749
+ modelClass: C;
750
+ registered: P;
751
+ id: I;
752
+ }
753
+
763
754
  type WithExtra<QB extends AnyQueryBuilder, X> = Rebind<QB, ModelType<QB>, ResultType<QB>, X>;
764
755
 
765
756
  // The narrowed query builders of `withGraph*()` start without the extra type
@@ -792,15 +783,16 @@ export type NumberQueryBuilder<QB extends AnyQueryBuilder> = QB['~number'];
792
783
  */
793
784
  export type PageQueryBuilder<QB extends AnyQueryBuilder> = QB['~page'];
794
785
 
795
- // Strict mode checks the column names and values of queries against the
796
- // models. Augment `TypeConfig` to opt in:
797
- //
798
- // declare module 'objection' {
799
- // interface TypeConfig {
800
- // strict: true;
801
- // }
802
- // }
803
-
786
+ /**
787
+ * Strict mode checks the column names and values of queries against the
788
+ * models. Augment `TypeConfig` to opt in:
789
+ *
790
+ * declare module 'objection' {
791
+ * interface TypeConfig {
792
+ * strict: true;
793
+ * }
794
+ * }
795
+ */
804
796
  export interface TypeConfig {}
805
797
 
806
798
  type IsStrict = TypeConfig extends { strict: true } ? true : false;
@@ -919,10 +911,11 @@ type CheckedColumn<M, C extends string> =
919
911
  IsConcreteModel<M> extends true ? CheckColumn<M, C> : string;
920
912
 
921
913
  /**
922
- * A column argument: checked against model M in strict mode, any column in
923
- * loose mode, where the model's properties come first, for autocompletion.
914
+ * A column argument: checked against model M in strict mode, the model's
915
+ * properties in loose mode, for autocompletion. In loose mode, other columns
916
+ * go through the RefArg overloads.
924
917
  */
925
- type ColumnArg<M, C extends string> = IfStrict<ModelProps<M & Model>, CheckedColumn<M, C>>;
918
+ type ColumnArg<M, C extends string> = IfStrict<InsertablePropertyNames<M>, CheckedColumn<M, C>>;
926
919
 
927
920
  /**
928
921
  * The value of a column of type T in conditions: `null` is always accepted,
@@ -1071,8 +1064,8 @@ type StrictSelectionObject<M, O> = {
1071
1064
  /**
1072
1065
  * The query builder QB with its result rows narrowed to the properties P in
1073
1066
  * strict mode, next to the model's methods and relations, as after `select()`
1074
- * and the aggregates, marked with SelectedBrand. Repeated selections add up. Queries
1075
- * that aren't checked, e.g. in generic code, aren't narrowed.
1067
+ * and the aggregates, marked with SelectedBrand. Repeated selections add up.
1068
+ * Queries that aren't checked, e.g. in generic code, aren't narrowed.
1076
1069
  */
1077
1070
  type NarrowRows<QB extends AnyQueryBuilder, P, All extends boolean = false> = RowsQueryBuilder<
1078
1071
  QB,
@@ -1127,7 +1120,7 @@ type ExtractedProperties<M, A extends string> = {
1127
1120
  type SelectQueryBuilder<QB extends AnyQueryBuilder, C extends readonly unknown[]> = NarrowRows<
1128
1121
  QB,
1129
1122
  SelectedRow<ModelType<QB>, C>,
1130
- true extends SelectsAll<C[number]> ? true : false
1123
+ true extends IsSelectAll<C[number]> ? true : false
1131
1124
  >;
1132
1125
 
1133
1126
  /**
@@ -1188,18 +1181,6 @@ export type SelectedBrand<A> = { readonly [selected]: A };
1188
1181
  */
1189
1182
  export type ExtractedBrand<A> = { readonly [extracted]: A };
1190
1183
 
1191
- /**
1192
- * The extra type of queries in strict mode: the model class C that started the
1193
- * query, e.g. with `Person.query()`, and the modifiers P registered with
1194
- * `modifiers()`, to check the names of modifiers, and the id I of the class,
1195
- * for `findById()` and the other `*ById()` methods.
1196
- */
1197
- export interface QueryExtra<C = unknown, P = unknown, I = MaybeCompositeId> {
1198
- modelClass: C;
1199
- registered: P;
1200
- id: I;
1201
- }
1202
-
1203
1184
  // The results whose rows have `jsonExtract()` values, which `withGraph*()`
1204
1185
  // keeps instead of converting the result kind:
1205
1186
  type ExtractedRows =
@@ -1220,7 +1201,7 @@ type SelectBase<Item, M, All extends boolean> = All extends true
1220
1201
  // unknown types, under any aliases.
1221
1202
  type UnknownSelection = { [key: string]: unknown } & SelectedBrand<{ [key: string]: true }>;
1222
1203
 
1223
- type SelectsAll<X> = X extends '*' | `${string}.*` ? true : false;
1204
+ type IsSelectAll<X> = X extends '*' | `${string}.*` ? true : false;
1224
1205
 
1225
1206
  /**
1226
1207
  * Replaces the item of the result R with the row.
@@ -1265,9 +1246,9 @@ type SelectedType<M, C extends string> = C extends `${infer Q}.${infer Col}`
1265
1246
  : ColumnType<M, C>;
1266
1247
 
1267
1248
  /**
1268
- * The property of the column or alias C in the result rows: `snakeCaseMappers()`
1269
- * converts them to camel case, with `upperCase: true` after lowering the case
1270
- * of names in upper case.
1249
+ * The property of the column or alias C in the result rows:
1250
+ * `snakeCaseMappers()` converts them to camel case, with `upperCase: true`
1251
+ * after lowering the case of names in upper case.
1271
1252
  */
1272
1253
  type ResultKey<M, C extends string> = M extends { ColumnNameMapping: 'snakeCase' }
1273
1254
  ? CamelCase<C>
@@ -1332,9 +1313,9 @@ type CheckRelationExpression<M, E, QB extends AnyQueryBuilder = never> = IfStric
1332
1313
 
1333
1314
  type CheckModifierExpression<E, QB extends AnyQueryBuilder> =
1334
1315
  HasQueryClass<QB> extends true
1335
- ? [CheckedModifiers<E, QB>] extends [never]
1316
+ ? [UnknownExpressionModifiers<E, QB>] extends [never]
1336
1317
  ? unknown
1337
- : { '~unknownModifier': CheckedModifiers<E, QB> }
1318
+ : { '~unknownModifier': UnknownExpressionModifiers<E, QB> }
1338
1319
  : unknown;
1339
1320
 
1340
1321
  // Queries in generic code, where the model class can't be resolved, aren't
@@ -1347,7 +1328,7 @@ type HasQueryClass<QB extends AnyQueryBuilder> =
1347
1328
  : true;
1348
1329
 
1349
1330
  // Only expressions with modifiers are checked for them.
1350
- type CheckedModifiers<E, QB> = E extends `${string}(${string}` | object
1331
+ type UnknownExpressionModifiers<E, QB> = E extends `${string}(${string}` | object
1351
1332
  ? UnknownModifiers<
1352
1333
  ClassMappings<QueryClass<QB>>,
1353
1334
  ParseModifierExpression<E>,
@@ -1424,17 +1405,17 @@ type PropertyId<M, C extends string, F> =
1424
1405
 
1425
1406
  // Modifiers with their general type, e.g. inherited from `Model`, aren't
1426
1407
  // checked.
1427
- type ChecksModifiers<QB extends AnyQueryBuilder> = IfStrict<
1408
+ type ShouldCheckModifiers<QB extends AnyQueryBuilder> = IfStrict<
1428
1409
  false,
1429
- HasQueryClass<QB> extends true ? ChecksClassModifiers<ClassModifiers<QueryClass<QB>>> : false
1410
+ HasQueryClass<QB> extends true ? HasOnlyLiteralKeys<ClassModifiers<QueryClass<QB>>> : false
1430
1411
  >;
1431
1412
 
1432
- type ChecksClassModifiers<O> = string extends keyof O ? false : true;
1413
+ type HasOnlyLiteralKeys<O> = string extends keyof O ? false : true;
1433
1414
 
1434
1415
  // The names that `modify()` takes on query builder QB, also in lists. Names
1435
1416
  // in variables typed `string` are rejected where they are checked.
1436
1417
  type ModifierName<QB extends AnyQueryBuilder> =
1437
- ChecksModifiers<QB> extends true ? keyof KnownModifiers<QB> & string : string;
1418
+ ShouldCheckModifiers<QB> extends true ? keyof KnownModifiers<QB> & string : string;
1438
1419
 
1439
1420
  type ModifyArg<QB extends AnyQueryBuilder> =
1440
1421
  | ModifierName<QB>
@@ -1450,7 +1431,7 @@ type UnknownModifiers<Mappings, T, P> = T extends unknown
1450
1431
  ? MappedClass<Mappings, K> extends infer C
1451
1432
  ? [C] extends [never]
1452
1433
  ? never
1453
- : | (ChecksClassModifiers<ClassModifiers<C>> extends true
1434
+ : | (HasOnlyLiteralKeys<ClassModifiers<C>> extends true
1454
1435
  ? Exclude<N, keyof ClassModifiers<C> | P>
1455
1436
  : never)
1456
1437
  | UnknownModifiers<ClassMappings<C>, Children, P>
@@ -1460,15 +1441,16 @@ type UnknownModifiers<Mappings, T, P> = T extends unknown
1460
1441
  : never;
1461
1442
 
1462
1443
  // Mappings with their general type, e.g. inherited from `Model`, give no class.
1463
- type MappedClass<Mappings, K> = string extends keyof Mappings
1464
- ? never
1465
- : K extends keyof Mappings
1466
- ? Mappings[K] extends { modelClass: infer C }
1467
- ? C extends abstract new (...args: any) => any
1468
- ? C
1469
- : C extends () => infer RC
1470
- ? RC
1471
- : never
1444
+ type MappedClass<Mappings, K> =
1445
+ HasOnlyLiteralKeys<Mappings> extends true
1446
+ ? K extends keyof Mappings
1447
+ ? Mappings[K] extends { modelClass: infer C }
1448
+ ? C extends abstract new (...args: any) => any
1449
+ ? C
1450
+ : C extends () => infer RC
1451
+ ? RC
1452
+ : never
1453
+ : never
1472
1454
  : never
1473
1455
  : never;
1474
1456
 
@@ -1510,28 +1492,29 @@ type ModifierNode<S extends string, Children> = [RelationName<S>] extends [never
1510
1492
  type ModifierNames<S extends string> =
1511
1493
  Trim<S> extends `${string}(${infer Args})` ? Exclude<Trim<SplitList<Args>[number]>, ''> : never;
1512
1494
 
1513
- type ParseModifierObject<E> = string extends keyof E
1514
- ? {}
1515
- : {
1516
- [
1517
- K in keyof E as K extends `$${string}`
1518
- ? never
1519
- : false extends E[K]
1495
+ type ParseModifierObject<E> =
1496
+ HasOnlyLiteralKeys<E> extends true
1497
+ ? {
1498
+ [
1499
+ K in keyof E as K extends `$${string}`
1520
1500
  ? never
1521
- : E[K] extends { $relation: any }
1501
+ : false extends E[K]
1522
1502
  ? never
1523
- : K
1524
- ]: {
1525
- names: E[K] extends { $modify: infer N }
1526
- ? N extends readonly (infer I extends string)[]
1527
- ? I
1528
- : N extends string
1529
- ? N
1530
- : never
1531
- : never;
1532
- children: E[K] extends object ? ParseModifierObject<E[K]> : {};
1533
- };
1534
- };
1503
+ : E[K] extends { $relation: any }
1504
+ ? never
1505
+ : K
1506
+ ]: {
1507
+ names: E[K] extends { $modify: infer N }
1508
+ ? N extends readonly (infer I extends string)[]
1509
+ ? I
1510
+ : N extends string
1511
+ ? N
1512
+ : never
1513
+ : never;
1514
+ children: E[K] extends object ? ParseModifierObject<E[K]> : {};
1515
+ };
1516
+ }
1517
+ : {};
1535
1518
 
1536
1519
  export interface ForClassMethod {
1537
1520
  <M extends Model>(modelClass: ModelConstructor<M>): QueryBuilderType<M>;
@@ -1547,22 +1530,24 @@ export type JsonObjectOrFieldExpression = object | object[] | FieldExpression;
1547
1530
  export type Selection<QB extends AnyQueryBuilder> = ColumnRef | AnyQueryBuilder | CallbackVoid<QB>;
1548
1531
 
1549
1532
  export interface SelectMethod<out QB extends AnyQueryBuilder> {
1550
- // These must come first so that we get autocomplete.
1551
- <QBP extends QB>(...columns: IfStrict<ModelProps<ModelType<QBP>>, never>[]): QB;
1533
+ // The column overload comes first, for autocompletion, and last in strict
1534
+ // mode, so that errors are reported for it:
1535
+ <QBP extends QB, const C extends readonly [unknown, ...unknown[]]>(
1536
+ ...columns: IfStrict<ModelProps<ModelType<QBP>>[], StrictSelections<ModelType<QBP>, C>>
1537
+ ): IfStrict<QB, SelectQueryBuilder<QBP, C>>;
1552
1538
  <QBP extends QB>(columns: IfStrict<ModelProps<ModelType<QBP>>, never>[]): QB;
1553
1539
 
1554
1540
  <QBP extends QB>(...columns: IfStrict<Selection<QBP>, never>[]): QB;
1555
1541
  <QBP extends QB>(columns: IfStrict<Selection<QBP>, never>[]): QB;
1556
1542
 
1557
- // Allows things like `select(1)`, not sure if we should be more specific here?
1558
- <QBP extends QB>(...args: IfStrict<any, never>[]): QB;
1559
-
1560
- <QBP extends QB, const C extends readonly unknown[] = []>(
1561
- ...columns: StrictSelections<ModelType<QBP>, C>
1562
- ): SelectQueryBuilder<QBP, C>;
1563
1543
  <QBP extends QB, const C extends readonly unknown[] = []>(
1564
1544
  columns: StrictSelections<ModelType<QBP>, C>,
1565
1545
  ): SelectQueryBuilder<QBP, C>;
1546
+ // Allow anything else in loose mode, like `select(1)`. The last overload
1547
+ // is what `Parameters<>` sees, so it takes the loose arguments:
1548
+ <QBP extends QB, const C extends readonly unknown[] = []>(
1549
+ ...columns: IfStrict<({} | null | undefined)[], StrictSelections<ModelType<QBP>, C>>
1550
+ ): IfStrict<QB, SelectQueryBuilder<QBP, C>>;
1566
1551
  }
1567
1552
 
1568
1553
  export interface AsMethod<out QB extends AnyQueryBuilder> {
@@ -1584,7 +1569,7 @@ export interface JsonExtraction {
1584
1569
 
1585
1570
  // Extractions without an alias, or with several, add any properties.
1586
1571
  export interface JsonExtract<out QB extends AnyQueryBuilder> {
1587
- // These must come first so that we get autocomplete.
1572
+ // The column overloads come first, for autocompletion:
1588
1573
  <QBP extends QB, const C extends string = never, const A extends string = string>(
1589
1574
  column: ColumnArg<ModelType<QBP>, C>,
1590
1575
  path: string,
@@ -1605,7 +1590,7 @@ export interface JsonExtract<out QB extends AnyQueryBuilder> {
1605
1590
  }
1606
1591
 
1607
1592
  export interface JsonSet<out QB extends AnyQueryBuilder> {
1608
- // These must come first so that we get autocomplete.
1593
+ // The column overloads come first, for autocompletion:
1609
1594
  <QBP extends QB, const C extends string = never>(
1610
1595
  column: ColumnArg<ModelType<QBP>, C>,
1611
1596
  path: string,
@@ -1617,7 +1602,7 @@ export interface JsonSet<out QB extends AnyQueryBuilder> {
1617
1602
  }
1618
1603
 
1619
1604
  export interface JsonInsert<out QB extends AnyQueryBuilder> {
1620
- // These must come first so that we get autocomplete.
1605
+ // The column overloads come first, for autocompletion:
1621
1606
  <QBP extends QB, const C extends string = never>(
1622
1607
  column: ColumnArg<ModelType<QBP>, C>,
1623
1608
  path: string,
@@ -1629,7 +1614,7 @@ export interface JsonInsert<out QB extends AnyQueryBuilder> {
1629
1614
  }
1630
1615
 
1631
1616
  export interface JsonRemove<out QB extends AnyQueryBuilder> {
1632
- // These must come first so that we get autocomplete.
1617
+ // The column overloads come first, for autocompletion:
1633
1618
  <QBP extends QB, const C extends string = never>(
1634
1619
  column: ColumnArg<ModelType<QBP>, C>,
1635
1620
  path: string,
@@ -1640,6 +1625,17 @@ export interface JsonRemove<out QB extends AnyQueryBuilder> {
1640
1625
  }
1641
1626
 
1642
1627
  export interface WhereMethod<out QB extends AnyQueryBuilder> {
1628
+ // The column overloads come first, for autocompletion:
1629
+ <QBP extends QB, const C extends string = never, const O extends Operator = Operator>(
1630
+ col: ColumnArg<ModelType<QBP>, C>,
1631
+ op: O,
1632
+ expr: OperatorValueArg<ModelType<QBP>, C, O>,
1633
+ ): QB;
1634
+ <QBP extends QB, const C extends string = never>(
1635
+ col: ColumnArg<ModelType<QBP>, C>,
1636
+ expr: ValueArg<ModelType<QBP>, C>,
1637
+ ): QB;
1638
+
1643
1639
  (condition: boolean): QB;
1644
1640
  (cb: CallbackVoid<QB>): QB;
1645
1641
  (raw: Raw): QB;
@@ -1648,7 +1644,7 @@ export interface WhereMethod<out QB extends AnyQueryBuilder> {
1648
1644
  (col: RefArg<QB>, op: Operator, expr: Expression<PrimitiveValue>): QB;
1649
1645
  (col: RefArg<QB>, expr: Expression<PrimitiveValue>): QB;
1650
1646
 
1651
- // The column overloads come last, so that errors are reported for them.
1647
+ // The column overloads come last, so that errors are reported for them:
1652
1648
  <QBP extends QB, const C extends string = never, const O extends Operator = Operator>(
1653
1649
  col: ColumnArg<ModelType<QBP>, C>,
1654
1650
  op: O,
@@ -1660,14 +1656,20 @@ export interface WhereMethod<out QB extends AnyQueryBuilder> {
1660
1656
  ): QB;
1661
1657
 
1662
1658
  <QBP extends QB>(obj: IfStrict<PartialModelProps<ModelType<QBP>>, never>): QB;
1663
- // We must allow any keys in the object. The previous type
1664
- // is kind of useless, but maybe one day vscode and other
1665
- // tools can autocomplete using it.
1666
- (obj: IfStrict<object, never>): QB;
1667
- <QBP extends QB, const O extends object = {}>(obj: O & StrictWhereObject<ModelType<QBP>, O>): QB;
1659
+ // Allow any keys in loose mode. The model's properties above only serve
1660
+ // autocompletion. The last overload is what `Parameters<>` sees:
1661
+ <QBP extends QB, const O extends object = {}>(
1662
+ obj: IfStrict<object, O & StrictWhereObject<ModelType<QBP>, O>>,
1663
+ ): QB;
1668
1664
  }
1669
1665
 
1670
1666
  export interface WhereLikeMethod<out QB extends AnyQueryBuilder> {
1667
+ // The column overload comes first, for autocompletion, and last, so that
1668
+ // errors are reported for it:
1669
+ <QBP extends QB, const C extends string = never>(
1670
+ col: ColumnArg<ModelType<QBP>, C>,
1671
+ expr: Expression<string>,
1672
+ ): QB;
1671
1673
  (col: RefArg<QB>, expr: Expression<string>): QB;
1672
1674
  <QBP extends QB, const C extends string = never>(
1673
1675
  col: ColumnArg<ModelType<QBP>, C>,
@@ -1688,13 +1690,12 @@ export interface WhereExistsMethod<out QB extends AnyQueryBuilder> {
1688
1690
  }
1689
1691
 
1690
1692
  export interface WhereInMethod<out QB extends AnyQueryBuilder> {
1691
- // These must come first so that we get autocomplete.
1692
- <QBP extends QB>(
1693
- col: IfStrict<ModelProps<ModelType<QBP>>, never>,
1694
- expr: Expression<PrimitiveValue>,
1693
+ // The column overload comes first, for autocompletion, and last in strict
1694
+ // mode, so that errors are reported for it:
1695
+ <QBP extends QB, const C extends string = never>(
1696
+ col: ColumnArg<ModelType<QBP>, C>,
1697
+ expr: IfStrict<Expression<PrimitiveValue> | CallbackVoid<QB>, WhereInValues<QB, QBP, C>>,
1695
1698
  ): QB;
1696
- <QBP extends QB>(col: IfStrict<ModelProps<ModelType<QBP>>, never>, cb: CallbackVoid<QB>): QB;
1697
- <QBP extends QB>(col: IfStrict<ModelProps<ModelType<QBP>>, never>, qb: AnyQueryBuilder): QB;
1698
1699
 
1699
1700
  (col: RefArg<QB> | RefArg<QB>[], expr: readonly Expression<PrimitiveValue>[]): QB;
1700
1701
  (col: RefArg<QB> | RefArg<QB>[], cb: CallbackVoid<QB>): QB;
@@ -1702,14 +1703,19 @@ export interface WhereInMethod<out QB extends AnyQueryBuilder> {
1702
1703
 
1703
1704
  <QBP extends QB, const C extends string = never>(
1704
1705
  col: StrictColumn<ModelType<QBP>, C>,
1705
- expr: readonly ValueArg<ModelType<QBP>, C>[] | Raw | AnyQueryBuilder | CallbackVoid<QB>,
1706
+ expr: WhereInValues<QB, QBP, C>,
1706
1707
  ): QB;
1708
+ // The last overload is what `Parameters<>` sees, so it takes the loose
1709
+ // columns in loose mode:
1707
1710
  <QBP extends QB, const C extends readonly unknown[] = []>(
1708
- col: StrictColumns<ModelType<QBP>, C>,
1711
+ col: IfStrict<RefArg<QB> | RefArg<QB>[], StrictColumns<ModelType<QBP>, C>>,
1709
1712
  expr: readonly Expression<PrimitiveValue>[] | Raw | AnyQueryBuilder | CallbackVoid<QB>,
1710
1713
  ): QB;
1711
1714
  }
1712
1715
 
1716
+ type WhereInValues<QB extends AnyQueryBuilder, QBP extends QB, C extends string> =
1717
+ readonly ValueArg<ModelType<QBP>, C>[] | Raw | AnyQueryBuilder | CallbackVoid<QB>;
1718
+
1713
1719
  export interface WhereBetweenMethod<out QB extends AnyQueryBuilder> {
1714
1720
  (column: RefArg<QB>, range: [Expression<PrimitiveValue>, Expression<PrimitiveValue>]): QB;
1715
1721
  <QBP extends QB, const C extends string = never>(
@@ -1724,7 +1730,7 @@ export interface WhereNullMethod<out QB extends AnyQueryBuilder> {
1724
1730
  }
1725
1731
 
1726
1732
  export interface WhereColumnMethod<out QB extends AnyQueryBuilder> {
1727
- // These must come first so that we get autocomplete.
1733
+ // The column overloads come first, for autocompletion:
1728
1734
  <QBP extends QB, const C extends string = never, const D extends string = never>(
1729
1735
  col1: ColumnArg<ModelType<QBP>, C>,
1730
1736
  op: Operator,
@@ -1747,7 +1753,7 @@ export interface WhereColumnMethod<out QB extends AnyQueryBuilder> {
1747
1753
  }
1748
1754
 
1749
1755
  export interface WhereJsonObject<out QB extends AnyQueryBuilder> {
1750
- // These must come first so that we get autocomplete.
1756
+ // The column overloads come first, for autocompletion:
1751
1757
  <QBP extends QB, const C extends string = never>(
1752
1758
  col: ColumnArg<ModelType<QBP>, C>,
1753
1759
  value: any,
@@ -1757,7 +1763,7 @@ export interface WhereJsonObject<out QB extends AnyQueryBuilder> {
1757
1763
  }
1758
1764
 
1759
1765
  export interface WhereJsonPath<out QB extends AnyQueryBuilder> {
1760
- // These must come first so that we get autocomplete.
1766
+ // The column overloads come first, for autocompletion:
1761
1767
  <QBP extends QB, const C extends string = never>(
1762
1768
  col: ColumnArg<ModelType<QBP>, C>,
1763
1769
  jsonPath: string,
@@ -2114,7 +2120,7 @@ type WriteQueryBuilder<QB extends AnyQueryBuilder, M extends Model, R> = [R] ext
2114
2120
  * The writes after `returning()` on single and maybe-single query builders,
2115
2121
  * which resolve to one row.
2116
2122
  */
2117
- interface ReturningWrites<QB extends AnyQueryBuilder, M extends Model, W> {
2123
+ export interface ReturningWrites<QB extends AnyQueryBuilder, M extends Model, W> {
2118
2124
  update(update: PartialModelRow<M>): Rebind<QB, M, W>;
2119
2125
  update(): Rebind<QB, M, W>;
2120
2126
  patch(update: PartialModelPatch<M>): Rebind<QB, M, W>;
@@ -2239,7 +2245,8 @@ export interface GraphOptions {
2239
2245
  maxBatchSize?: number;
2240
2246
  /**
2241
2247
  * Apply `limit()`, `offset()` and `first()` in graph modifiers to the related
2242
- * items of each parent. Defaults to `true`. Only applies to `withGraphFetched()`.
2248
+ * items of each parent. Defaults to `true`. Only applies to
2249
+ * `withGraphFetched()`.
2243
2250
  */
2244
2251
  limitPerParent?: boolean;
2245
2252
  }
@@ -2706,8 +2713,6 @@ export class QueryBuilder<
2706
2713
  ): Promise<R | FR>;
2707
2714
  }
2708
2715
 
2709
- export type X<T> = Promise<T>;
2710
-
2711
2716
  export interface FetchGraphOptions {
2712
2717
  transaction?: TransactionOrKnex;
2713
2718
  skipFetched?: boolean;
@@ -2807,11 +2812,11 @@ export interface BelongsToManyRelationType extends RelationType {
2807
2812
  * Names of the properties of M that hold related models. Properties typed
2808
2813
  * `any` or `any[]` are columns.
2809
2814
  */
2810
- export type RelationPropertyNames<M> = {
2811
- [K in keyof M]-?: HoldsModels<NonNullable<M[K]>> extends true ? K : never;
2815
+ type RelationPropertyNames<M> = {
2816
+ [K in keyof M]-?: HasModels<NonNullable<M[K]>> extends true ? K : never;
2812
2817
  }[keyof M];
2813
2818
 
2814
- type HoldsModels<P> = [P] extends [readonly (infer I)[]] ? IsModelLike<I> : IsModelLike<P>;
2819
+ type HasModels<P> = [P] extends [readonly (infer I)[]] ? IsModelLike<I> : IsModelLike<P>;
2815
2820
 
2816
2821
  type IsModelLike<P> = 0 extends 1 & P ? false : [P] extends [ModelLike] ? true : false;
2817
2822
 
@@ -2820,7 +2825,7 @@ type IsModelLike<P> = 0 extends 1 & P ? false : [P] extends [ModelLike] ? true :
2820
2825
  // Spreads of instances and their JSON don't have it.
2821
2826
  type ModelLike = { $clone(opt?: CloneOptions): unknown };
2822
2827
 
2823
- export type TypedModelClassSpecifier<M extends Model> =
2828
+ type TypedModelClassSpecifier<M extends Model> =
2824
2829
  string | ModelConstructor<M> | (() => ModelConstructor<M>);
2825
2830
 
2826
2831
  /**
@@ -2834,7 +2839,7 @@ export interface TypedRelationMapping<
2834
2839
  modelClass: TypedModelClassSpecifier<M>;
2835
2840
  }
2836
2841
 
2837
- export type TypedRelationMappingFor<T> =
2842
+ type TypedRelationMappingFor<T> =
2838
2843
  NonNullable<T> extends (infer I extends Model)[]
2839
2844
  ? TypedRelationMapping<
2840
2845
  I,
@@ -2951,7 +2956,7 @@ export interface SnakeCaseMappersOptions extends SnakeCaseOptions {
2951
2956
 
2952
2957
  export interface KnexSnakeCaseMappersOptions extends SnakeCaseOptions {}
2953
2958
 
2954
- export type JsonColumnFormat = 'auto' | 'text' | 'parsed';
2959
+ export type JsonColumnFormat = 'auto' | 'json' | 'text' | 'mixed';
2955
2960
 
2956
2961
  // Passed by queries to `fromDatabaseJson()`, `$setDatabaseJson()` and
2957
2962
  // `$parseDatabaseJson()`. Overrides pass them on to `super`.
@@ -3055,7 +3060,8 @@ export interface ConstructorFunctionType<T = any> extends PrototypeType<T> {
3055
3060
  new (...args: any[]): T;
3056
3061
  }
3057
3062
 
3058
- // for internal use on generic static this deduction, copied from https://github.com/microsoft/TypeScript/issues/5863#issuecomment-1483978415
3063
+ // Used internally to infer the generic static `this`, copied from:
3064
+ // https://github.com/microsoft/TypeScript/issues/5863#issuecomment-1483978415
3059
3065
  export type ConstructorType<T = unknown, Static extends Record<string, any> = PrototypeType<T>> = (
3060
3066
  ConstructorFunctionType<T> | PrototypeType<T>
3061
3067
  ) & {
@@ -3132,7 +3138,7 @@ export interface ModelClass<M extends Model> extends ModelConstructor<M> {
3132
3138
 
3133
3139
  transaction<T>(callback: (trx: Transaction) => Promise<T>): Promise<T>;
3134
3140
  transaction<T>(
3135
- trxOrKnex: TransactionOrKnex,
3141
+ trxOrKnex: TransactionOrKnex | undefined,
3136
3142
  callback: (trx: Transaction) => Promise<T>,
3137
3143
  ): Promise<T>;
3138
3144
 
@@ -3630,13 +3636,14 @@ type ModelSchemaProperties<S> = ReadonlyJSONSchema extends S
3630
3636
 
3631
3637
  // Relations are picked by their mappings, as resolving the related models
3632
3638
  // while the model's own type is built would make it its own base type.
3633
- type ModelRelationProperties<T, R = T extends () => infer M ? M : T> = string extends keyof R
3634
- ? {}
3635
- : {
3636
- -readonly [K in keyof R as IsMappedRelation<R[K]> extends true ? K : never]?: MappedRelation<
3637
- R[K]
3638
- >;
3639
- };
3639
+ type ModelRelationProperties<T, R = T extends () => infer M ? M : T> =
3640
+ HasOnlyLiteralKeys<R> extends true
3641
+ ? {
3642
+ -readonly [
3643
+ K in keyof R as IsMappedRelation<R[K]> extends true ? K : never
3644
+ ]?: MappedRelation<R[K]>;
3645
+ }
3646
+ : {};
3640
3647
 
3641
3648
  // Relation types without a brand and module paths can't be resolved.
3642
3649
  type IsMappedRelation<M> = M extends { relation: infer T; modelClass: infer C }