kysely 0.16.6 → 0.16.7

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 (74) hide show
  1. package/README.md +118 -5
  2. package/dist/cjs/dialect/mysql/mysql-dialect.js +2 -1
  3. package/dist/cjs/dialect/mysql/mysql-driver.js +1 -1
  4. package/dist/cjs/dialect/postgres/postgres-dialect.js +2 -1
  5. package/dist/cjs/dialect/postgres/postgres-driver.js +1 -1
  6. package/dist/cjs/dialect/sqlite/sqlite-dialect.js +2 -1
  7. package/dist/cjs/dialect/sqlite/sqlite-driver.js +1 -1
  8. package/dist/cjs/driver/dummy-driver.d.ts +28 -0
  9. package/dist/cjs/driver/dummy-driver.js +31 -3
  10. package/dist/cjs/index-nodeless.d.ts +1 -0
  11. package/dist/cjs/index-nodeless.js +1 -0
  12. package/dist/cjs/kysely.d.ts +8 -6
  13. package/dist/cjs/kysely.js +8 -6
  14. package/dist/cjs/plugin/deduplicate-joins/deduplicate-joins-plugin.d.ts +48 -0
  15. package/dist/cjs/plugin/deduplicate-joins/deduplicate-joins-plugin.js +19 -0
  16. package/dist/cjs/plugin/deduplicate-joins/deduplicate-joins-transformer.d.ts +9 -0
  17. package/dist/cjs/plugin/deduplicate-joins/deduplicate-joins-transformer.js +42 -0
  18. package/dist/cjs/plugin/{immediate-value.ts → immediate-value}/immediate-value-plugin.d.ts +0 -0
  19. package/dist/cjs/plugin/{immediate-value.ts → immediate-value}/immediate-value-plugin.js +0 -0
  20. package/dist/cjs/plugin/{immediate-value.ts → immediate-value}/immediate-value-transformer.d.ts +0 -0
  21. package/dist/cjs/plugin/{immediate-value.ts → immediate-value}/immediate-value-transformer.js +0 -0
  22. package/dist/cjs/query-builder/delete-query-builder.d.ts +51 -9
  23. package/dist/cjs/query-builder/delete-query-builder.js +56 -8
  24. package/dist/cjs/query-builder/function-builder.d.ts +29 -5
  25. package/dist/cjs/query-builder/function-builder.js +31 -7
  26. package/dist/cjs/query-builder/insert-query-builder.d.ts +53 -11
  27. package/dist/cjs/query-builder/insert-query-builder.js +58 -10
  28. package/dist/cjs/query-builder/select-query-builder.d.ts +58 -16
  29. package/dist/cjs/query-builder/select-query-builder.js +64 -15
  30. package/dist/cjs/query-builder/update-query-builder.d.ts +52 -9
  31. package/dist/cjs/query-builder/update-query-builder.js +57 -8
  32. package/dist/cjs/query-creator.d.ts +2 -2
  33. package/dist/cjs/query-creator.js +2 -2
  34. package/dist/cjs/schema/create-view-builder.js +1 -1
  35. package/dist/cjs/util/object-utils.d.ts +1 -0
  36. package/dist/cjs/util/object-utils.js +50 -1
  37. package/dist/cjs/util/type-utils.d.ts +21 -0
  38. package/dist/esm/dialect/mysql/mysql-dialect.js +2 -1
  39. package/dist/esm/dialect/mysql/mysql-driver.js +2 -2
  40. package/dist/esm/dialect/postgres/postgres-dialect.js +2 -1
  41. package/dist/esm/dialect/postgres/postgres-driver.js +2 -2
  42. package/dist/esm/dialect/sqlite/sqlite-dialect.js +2 -1
  43. package/dist/esm/dialect/sqlite/sqlite-driver.js +2 -2
  44. package/dist/esm/driver/dummy-driver.d.ts +28 -0
  45. package/dist/esm/driver/dummy-driver.js +31 -3
  46. package/dist/esm/index-nodeless.d.ts +1 -0
  47. package/dist/esm/index-nodeless.js +1 -0
  48. package/dist/esm/kysely.d.ts +8 -6
  49. package/dist/esm/kysely.js +8 -6
  50. package/dist/esm/plugin/deduplicate-joins/deduplicate-joins-plugin.d.ts +48 -0
  51. package/dist/esm/plugin/deduplicate-joins/deduplicate-joins-plugin.js +16 -0
  52. package/dist/esm/plugin/deduplicate-joins/deduplicate-joins-transformer.d.ts +9 -0
  53. package/dist/esm/plugin/deduplicate-joins/deduplicate-joins-transformer.js +39 -0
  54. package/dist/esm/plugin/{immediate-value.ts → immediate-value}/immediate-value-plugin.d.ts +0 -0
  55. package/dist/esm/plugin/{immediate-value.ts → immediate-value}/immediate-value-plugin.js +0 -0
  56. package/dist/esm/plugin/{immediate-value.ts → immediate-value}/immediate-value-transformer.d.ts +0 -0
  57. package/dist/esm/plugin/{immediate-value.ts → immediate-value}/immediate-value-transformer.js +0 -0
  58. package/dist/esm/query-builder/delete-query-builder.d.ts +51 -9
  59. package/dist/esm/query-builder/delete-query-builder.js +56 -8
  60. package/dist/esm/query-builder/function-builder.d.ts +29 -5
  61. package/dist/esm/query-builder/function-builder.js +31 -7
  62. package/dist/esm/query-builder/insert-query-builder.d.ts +53 -11
  63. package/dist/esm/query-builder/insert-query-builder.js +58 -10
  64. package/dist/esm/query-builder/select-query-builder.d.ts +58 -16
  65. package/dist/esm/query-builder/select-query-builder.js +64 -15
  66. package/dist/esm/query-builder/update-query-builder.d.ts +52 -9
  67. package/dist/esm/query-builder/update-query-builder.js +57 -8
  68. package/dist/esm/query-creator.d.ts +2 -2
  69. package/dist/esm/query-creator.js +2 -2
  70. package/dist/esm/schema/create-view-builder.js +1 -1
  71. package/dist/esm/util/object-utils.d.ts +1 -0
  72. package/dist/esm/util/object-utils.js +48 -0
  73. package/dist/esm/util/type-utils.d.ts +21 -0
  74. package/package.json +4 -2
@@ -0,0 +1,9 @@
1
+ import { DeleteQueryNode, UpdateQueryNode } from '../../index-nodeless.js';
2
+ import { OperationNodeTransformer } from '../../operation-node/operation-node-transformer.js';
3
+ import { SelectQueryNode } from '../../operation-node/select-query-node.js';
4
+ export declare class DeduplicateJoinsTransformer extends OperationNodeTransformer {
5
+ #private;
6
+ protected transformSelectQuery(node: SelectQueryNode): SelectQueryNode;
7
+ protected transformUpdateQuery(node: UpdateQueryNode): UpdateQueryNode;
8
+ protected transformDeleteQuery(node: DeleteQueryNode): DeleteQueryNode;
9
+ }
@@ -0,0 +1,39 @@
1
+ /// <reference types="./deduplicate-joins-transformer.d.ts" />
2
+ import { OperationNodeTransformer } from '../../operation-node/operation-node-transformer.js';
3
+ import { compare, freeze } from '../../util/object-utils.js';
4
+ export class DeduplicateJoinsTransformer extends OperationNodeTransformer {
5
+ transformSelectQuery(node) {
6
+ return this.#transformQuery(super.transformSelectQuery(node));
7
+ }
8
+ transformUpdateQuery(node) {
9
+ return this.#transformQuery(super.transformUpdateQuery(node));
10
+ }
11
+ transformDeleteQuery(node) {
12
+ return this.#transformQuery(super.transformDeleteQuery(node));
13
+ }
14
+ #transformQuery(node) {
15
+ if (!node.joins || node.joins.length === 0) {
16
+ return node;
17
+ }
18
+ return freeze({
19
+ ...node,
20
+ joins: this.#deduplicateJoins(node.joins),
21
+ });
22
+ }
23
+ #deduplicateJoins(joins) {
24
+ const out = [];
25
+ for (let i = 0; i < joins.length; ++i) {
26
+ let foundDuplicate = false;
27
+ for (let j = i + 1; j < joins.length; ++j) {
28
+ if (compare(joins[i], joins[j])) {
29
+ foundDuplicate = true;
30
+ break;
31
+ }
32
+ }
33
+ if (!foundDuplicate) {
34
+ out.push(joins[i]);
35
+ }
36
+ }
37
+ return freeze(out);
38
+ }
39
+ }
@@ -6,7 +6,7 @@ import { SelectExpression } from '../parser/select-parser.js';
6
6
  import { ExistsExpression, FilterOperator, FilterValueExpressionOrList, WhereGrouper } from '../parser/filter-parser.js';
7
7
  import { ReturningRow } from '../parser/returning-parser.js';
8
8
  import { ReferenceExpression } from '../parser/reference-parser.js';
9
- import { AnyRawBuilder, SingleResultType } from '../util/type-utils.js';
9
+ import { AnyRawBuilder, MergePartial, SingleResultType } from '../util/type-utils.js';
10
10
  import { Compilable } from '../util/compilable.js';
11
11
  import { QueryExecutor } from '../query-executor/query-executor.js';
12
12
  import { QueryId } from '../util/query-id.js';
@@ -16,6 +16,7 @@ import { WhereInterface } from './where-interface.js';
16
16
  import { JoinInterface } from './join-interface.js';
17
17
  import { ReturningInterface } from './returning-interface.js';
18
18
  import { NoResultErrorConstructor } from './no-result-error.js';
19
+ import { DeleteResult } from './delete-result.js';
19
20
  import { DeleteQueryNode } from '../operation-node/delete-query-node.js';
20
21
  import { Selectable } from '../util/column-type.js';
21
22
  export declare class DeleteQueryBuilder<DB, TB extends keyof DB, O> implements WhereInterface<DB, TB>, JoinInterface<DB, TB>, ReturningInterface<DB, TB, O>, OperationNodeSource, Compilable {
@@ -589,23 +590,61 @@ export declare class DeleteQueryBuilder<DB, TB extends keyof DB, O> implements W
589
590
  /**
590
591
  * Simply calls the given function passing `this` as the only argument.
591
592
  *
592
- * This method can be useful when adding optional method calls:
593
+ * If you want to conditionally call a method on `this`, see
594
+ * the {@link if} method.
593
595
  *
594
596
  * ### Examples
595
597
  *
598
+ * The next example uses a helper funtion `log` to log a query:
599
+ *
596
600
  * ```ts
601
+ * function log<T extends Compilable>(qb: T): T {
602
+ * console.log(qb.compile())
603
+ * return qb
604
+ * }
605
+ *
597
606
  * db.deleteFrom('person')
598
- * .call((qb) => {
599
- * if (something) {
600
- * return qb.where('something', '=', something)
601
- * } else {
602
- * return qb.where('somethingElse', '=', somethingElse)
603
- * }
604
- * })
607
+ * .call(log)
605
608
  * .execute()
606
609
  * ```
607
610
  */
608
611
  call<T>(func: (qb: this) => T): T;
612
+ /**
613
+ * Call `func(this)` if `condition` is true.
614
+ *
615
+ * This method is especially handy with optional selects. Any `returning` or `returningAll`
616
+ * method calls add columns as optional fields to the output type when called inside
617
+ * the `func` callback. This is because we can't know if those selections were actually
618
+ * made before running the code.
619
+ *
620
+ * You can also call any other methods inside the callback.
621
+ *
622
+ * ### Examples
623
+ *
624
+ * ```ts
625
+ * async function deletePerson(id: number, returnLastName: boolean) {
626
+ * return await db
627
+ * .deleteFrom('person')
628
+ * .where('id', '=', id)
629
+ * .returning(['id', 'first_name'])
630
+ * .if(returnLastName, (qb) => qb.returning('last_name'))
631
+ * .executeTakeFirstOrThrow()
632
+ * }
633
+ * ```
634
+ *
635
+ * Any selections added inside the `if` callback will be added as optional fields to the
636
+ * output type since we can't know if the selections were actually made before running
637
+ * the code. In the example above the return type of the `deletePerson` function is:
638
+ *
639
+ * ```ts
640
+ * {
641
+ * id: number
642
+ * first_name: string
643
+ * last_name?: string
644
+ * }
645
+ * ```
646
+ */
647
+ if<O2>(condition: boolean, func: (qb: this) => DeleteQueryBuilder<DB, TB, O2>): DeleteQueryBuilder<DB, TB, O2 extends DeleteResult ? DeleteResult : O extends DeleteResult ? Partial<O2> : MergePartial<O, O2>>;
609
648
  /**
610
649
  * Change the output type of the query.
611
650
  *
@@ -613,6 +652,9 @@ export declare class DeleteQueryBuilder<DB, TB extends keyof DB, O> implements W
613
652
  * don't support your use case.
614
653
  */
615
654
  castTo<T>(): DeleteQueryBuilder<DB, TB, T>;
655
+ /**
656
+ * Returns a copy of this DeleteQueryBuilder instance with the given plugin installed.
657
+ */
616
658
  withPlugin(plugin: KyselyPlugin): DeleteQueryBuilder<DB, TB, O>;
617
659
  toOperationNode(): DeleteQueryNode;
618
660
  compile(): CompiledQuery;
@@ -99,25 +99,70 @@ export class DeleteQueryBuilder {
99
99
  /**
100
100
  * Simply calls the given function passing `this` as the only argument.
101
101
  *
102
- * This method can be useful when adding optional method calls:
102
+ * If you want to conditionally call a method on `this`, see
103
+ * the {@link if} method.
103
104
  *
104
105
  * ### Examples
105
106
  *
107
+ * The next example uses a helper funtion `log` to log a query:
108
+ *
106
109
  * ```ts
110
+ * function log<T extends Compilable>(qb: T): T {
111
+ * console.log(qb.compile())
112
+ * return qb
113
+ * }
114
+ *
107
115
  * db.deleteFrom('person')
108
- * .call((qb) => {
109
- * if (something) {
110
- * return qb.where('something', '=', something)
111
- * } else {
112
- * return qb.where('somethingElse', '=', somethingElse)
113
- * }
114
- * })
116
+ * .call(log)
115
117
  * .execute()
116
118
  * ```
117
119
  */
118
120
  call(func) {
119
121
  return func(this);
120
122
  }
123
+ /**
124
+ * Call `func(this)` if `condition` is true.
125
+ *
126
+ * This method is especially handy with optional selects. Any `returning` or `returningAll`
127
+ * method calls add columns as optional fields to the output type when called inside
128
+ * the `func` callback. This is because we can't know if those selections were actually
129
+ * made before running the code.
130
+ *
131
+ * You can also call any other methods inside the callback.
132
+ *
133
+ * ### Examples
134
+ *
135
+ * ```ts
136
+ * async function deletePerson(id: number, returnLastName: boolean) {
137
+ * return await db
138
+ * .deleteFrom('person')
139
+ * .where('id', '=', id)
140
+ * .returning(['id', 'first_name'])
141
+ * .if(returnLastName, (qb) => qb.returning('last_name'))
142
+ * .executeTakeFirstOrThrow()
143
+ * }
144
+ * ```
145
+ *
146
+ * Any selections added inside the `if` callback will be added as optional fields to the
147
+ * output type since we can't know if the selections were actually made before running
148
+ * the code. In the example above the return type of the `deletePerson` function is:
149
+ *
150
+ * ```ts
151
+ * {
152
+ * id: number
153
+ * first_name: string
154
+ * last_name?: string
155
+ * }
156
+ * ```
157
+ */
158
+ if(condition, func) {
159
+ if (condition) {
160
+ return func(this);
161
+ }
162
+ return new DeleteQueryBuilder({
163
+ ...this.#props,
164
+ });
165
+ }
121
166
  /**
122
167
  * Change the output type of the query.
123
168
  *
@@ -127,6 +172,9 @@ export class DeleteQueryBuilder {
127
172
  castTo() {
128
173
  return new DeleteQueryBuilder(this.#props);
129
174
  }
175
+ /**
176
+ * Returns a copy of this DeleteQueryBuilder instance with the given plugin installed.
177
+ */
130
178
  withPlugin(plugin) {
131
179
  return new DeleteQueryBuilder({
132
180
  ...this.#props,
@@ -4,6 +4,9 @@ import { RawBuilder } from '../raw-builder/raw-builder.js';
4
4
  /**
5
5
  * Helpers for type safe SQL function calls.
6
6
  *
7
+ * You can always use {@link Kysely.raw} to call functions and build arbitrary
8
+ * expressions. This module simply has shortcuts for most common function calls.
9
+ *
7
10
  * ### Examples
8
11
  *
9
12
  * ```ts
@@ -35,12 +38,33 @@ export declare class FunctionBuilder<DB, TB extends keyof DB> {
35
38
  constructor(props: FunctionBuilderProps);
36
39
  /**
37
40
  * Calls the `max` function for the column given as the argument.
41
+ *
42
+ * ### Examples
43
+ *
44
+ * ```ts
45
+ * const { max } = db.fn
46
+ *
47
+ * db.selectFrom('toy')
48
+ * .select(max('price').as('max_price'))
49
+ * .execute()
50
+ * ```
38
51
  */
39
- min<C extends StringReference<DB, TB>>(column: C): RawBuilder<ExtractTypeFromReferenceExpression<DB, TB, C>>;
52
+ max<C extends StringReference<DB, TB>>(column: C): RawBuilder<ExtractTypeFromReferenceExpression<DB, TB, C>>;
40
53
  /**
41
54
  * Calls the `min` function for the column given as the argument.
55
+ *
56
+ * ### Examples
57
+ *
58
+ * ```ts
59
+ * const { min } = db.fn
60
+ *
61
+ * db.selectFrom('toy')
62
+ * .select(min('price').as('min_price'))
63
+ * .execute()
64
+ * ```
65
+ *
42
66
  */
43
- max<C extends StringReference<DB, TB>>(column: C): RawBuilder<ExtractTypeFromReferenceExpression<DB, TB, C>>;
67
+ min<C extends StringReference<DB, TB>>(column: C): RawBuilder<ExtractTypeFromReferenceExpression<DB, TB, C>>;
44
68
  /**
45
69
  * Calls the `avg` function for the column given as the argument.
46
70
  *
@@ -58,7 +82,7 @@ export declare class FunctionBuilder<DB, TB extends keyof DB> {
58
82
  * const { avg } = db.fn
59
83
  *
60
84
  * db.selectFrom('toy')
61
- * .select(avg<number>('price'))
85
+ * .select(avg<number>('price').as('avg_price'))
62
86
  * .execute()
63
87
  * ```
64
88
  */
@@ -80,7 +104,7 @@ export declare class FunctionBuilder<DB, TB extends keyof DB> {
80
104
  * const { sum } = db.fn
81
105
  *
82
106
  * db.selectFrom('toy')
83
- * .select(sum<number>('price'))
107
+ * .select(sum<number>('price').as('total_price'))
84
108
  * .execute()
85
109
  * ```
86
110
  */
@@ -102,7 +126,7 @@ export declare class FunctionBuilder<DB, TB extends keyof DB> {
102
126
  * const { count } = db.fn
103
127
  *
104
128
  * db.selectFrom('toy')
105
- * .select(count<number>('price'))
129
+ * .select(count<number>('id').as('num_toys'))
106
130
  * .execute()
107
131
  * ```
108
132
  */
@@ -5,6 +5,9 @@ import { createQueryId } from '../util/query-id.js';
5
5
  /**
6
6
  * Helpers for type safe SQL function calls.
7
7
  *
8
+ * You can always use {@link Kysely.raw} to call functions and build arbitrary
9
+ * expressions. This module simply has shortcuts for most common function calls.
10
+ *
8
11
  * ### Examples
9
12
  *
10
13
  * ```ts
@@ -43,15 +46,36 @@ export class FunctionBuilder {
43
46
  }
44
47
  /**
45
48
  * Calls the `max` function for the column given as the argument.
49
+ *
50
+ * ### Examples
51
+ *
52
+ * ```ts
53
+ * const { max } = db.fn
54
+ *
55
+ * db.selectFrom('toy')
56
+ * .select(max('price').as('max_price'))
57
+ * .execute()
58
+ * ```
46
59
  */
47
- min(column) {
48
- return this.#oneArgFunction('min', column);
60
+ max(column) {
61
+ return this.#oneArgFunction('max', column);
49
62
  }
50
63
  /**
51
64
  * Calls the `min` function for the column given as the argument.
65
+ *
66
+ * ### Examples
67
+ *
68
+ * ```ts
69
+ * const { min } = db.fn
70
+ *
71
+ * db.selectFrom('toy')
72
+ * .select(min('price').as('min_price'))
73
+ * .execute()
74
+ * ```
75
+ *
52
76
  */
53
- max(column) {
54
- return this.#oneArgFunction('max', column);
77
+ min(column) {
78
+ return this.#oneArgFunction('min', column);
55
79
  }
56
80
  /**
57
81
  * Calls the `avg` function for the column given as the argument.
@@ -70,7 +94,7 @@ export class FunctionBuilder {
70
94
  * const { avg } = db.fn
71
95
  *
72
96
  * db.selectFrom('toy')
73
- * .select(avg<number>('price'))
97
+ * .select(avg<number>('price').as('avg_price'))
74
98
  * .execute()
75
99
  * ```
76
100
  */
@@ -94,7 +118,7 @@ export class FunctionBuilder {
94
118
  * const { sum } = db.fn
95
119
  *
96
120
  * db.selectFrom('toy')
97
- * .select(sum<number>('price'))
121
+ * .select(sum<number>('price').as('total_price'))
98
122
  * .execute()
99
123
  * ```
100
124
  */
@@ -118,7 +142,7 @@ export class FunctionBuilder {
118
142
  * const { count } = db.fn
119
143
  *
120
144
  * db.selectFrom('toy')
121
- * .select(count<number>('price'))
145
+ * .select(count<number>('id').as('num_toys'))
122
146
  * .execute()
123
147
  * ```
124
148
  */
@@ -3,12 +3,13 @@ import { CompiledQuery } from '../query-compiler/compiled-query.js';
3
3
  import { SelectExpression } from '../parser/select-parser.js';
4
4
  import { InsertObject } from '../parser/insert-values-parser.js';
5
5
  import { InsertQueryNode } from '../operation-node/insert-query-node.js';
6
- import { SingleResultType } from '../util/type-utils.js';
6
+ import { MergePartial, SingleResultType } from '../util/type-utils.js';
7
7
  import { MutationObject } from '../parser/update-set-parser.js';
8
8
  import { Compilable } from '../util/compilable.js';
9
9
  import { QueryExecutor } from '../query-executor/query-executor.js';
10
10
  import { QueryId } from '../util/query-id.js';
11
11
  import { ParseContext } from '../parser/parse-context.js';
12
+ import { InsertResult } from './insert-result.js';
12
13
  import { KyselyPlugin } from '../plugin/kysely-plugin.js';
13
14
  import { ReturningRow } from '../parser/returning-parser.js';
14
15
  import { NoResultErrorConstructor } from './no-result-error.js';
@@ -448,24 +449,62 @@ export declare class InsertQueryBuilder<DB, TB extends keyof DB, O> implements R
448
449
  /**
449
450
  * Simply calls the given function passing `this` as the only argument.
450
451
  *
451
- * This method can be useful when adding optional method calls:
452
+ * If you want to conditionally call a method on `this`, see
453
+ * the {@link if} method.
452
454
  *
453
455
  * ### Examples
454
456
  *
457
+ * The next example uses a helper funtion `log` to log a query:
458
+ *
455
459
  * ```ts
456
- * db.insertInto('person')
457
- * .selectAll()
458
- * .call((qb) => {
459
- * if (something) {
460
- * return qb.onConflict((oc) => oc.column('something').doNothing())
461
- * } else {
462
- * return qb.onConflict((oc) => oc.column('something_else').doNothing())
463
- * }
464
- * })
460
+ * function log<T extends Compilable>(qb: T): T {
461
+ * console.log(qb.compile())
462
+ * return qb
463
+ * }
464
+ *
465
+ * db.updateTable('person')
466
+ * .set(values)
467
+ * .call(log)
465
468
  * .execute()
466
469
  * ```
467
470
  */
468
471
  call<T>(func: (qb: this) => T): T;
472
+ /**
473
+ * Call `func(this)` if `condition` is true.
474
+ *
475
+ * This method is especially handy with optional selects. Any `returning` or `returningAll`
476
+ * method calls add columns as optional fields to the output type when called inside
477
+ * the `func` callback. This is because we can't know if those selections were actually
478
+ * made before running the code.
479
+ *
480
+ * You can also call any other methods inside the callback.
481
+ *
482
+ * ### Examples
483
+ *
484
+ * ```ts
485
+ * async function insertPerson(values: InsertablePerson, returnLastName: boolean) {
486
+ * return await db
487
+ * .insertInto('person')
488
+ * .values(values)
489
+ * .returning(['id', 'first_name'])
490
+ * .if(returnLastName, (qb) => qb.returning('last_name'))
491
+ * .executeTakeFirstOrThrow()
492
+ * }
493
+ * ```
494
+ *
495
+ * Any selections added inside the `if` callback will be added as optional fields to the
496
+ * output type since we can't know if the selections were actually made before running
497
+ * the code. In the example above the return type of the `insertPerson` function is:
498
+ *
499
+ * ```ts
500
+ * {
501
+ * id: number
502
+ * first_name: string
503
+ * last_name?: string
504
+ * }
505
+ * ```
506
+ */
507
+ if<O2>(condition: boolean, func: (qb: this) => InsertQueryBuilder<DB, TB, O2>): InsertQueryBuilder<DB, TB, O2 extends InsertResult ? InsertResult : O extends InsertResult ? Partial<O2> : MergePartial<O, O2>>;
469
508
  /**
470
509
  * Change the output type of the query.
471
510
  *
@@ -473,6 +512,9 @@ export declare class InsertQueryBuilder<DB, TB extends keyof DB, O> implements R
473
512
  * don't support your use case.
474
513
  */
475
514
  castTo<T>(): InsertQueryBuilder<DB, TB, T>;
515
+ /**
516
+ * Returns a copy of this InsertQueryBuilder instance with the given plugin installed.
517
+ */
476
518
  withPlugin(plugin: KyselyPlugin): InsertQueryBuilder<DB, TB, O>;
477
519
  toOperationNode(): InsertQueryNode;
478
520
  compile(): CompiledQuery;
@@ -315,26 +315,71 @@ export class InsertQueryBuilder {
315
315
  /**
316
316
  * Simply calls the given function passing `this` as the only argument.
317
317
  *
318
- * This method can be useful when adding optional method calls:
318
+ * If you want to conditionally call a method on `this`, see
319
+ * the {@link if} method.
319
320
  *
320
321
  * ### Examples
321
322
  *
323
+ * The next example uses a helper funtion `log` to log a query:
324
+ *
322
325
  * ```ts
323
- * db.insertInto('person')
324
- * .selectAll()
325
- * .call((qb) => {
326
- * if (something) {
327
- * return qb.onConflict((oc) => oc.column('something').doNothing())
328
- * } else {
329
- * return qb.onConflict((oc) => oc.column('something_else').doNothing())
330
- * }
331
- * })
326
+ * function log<T extends Compilable>(qb: T): T {
327
+ * console.log(qb.compile())
328
+ * return qb
329
+ * }
330
+ *
331
+ * db.updateTable('person')
332
+ * .set(values)
333
+ * .call(log)
332
334
  * .execute()
333
335
  * ```
334
336
  */
335
337
  call(func) {
336
338
  return func(this);
337
339
  }
340
+ /**
341
+ * Call `func(this)` if `condition` is true.
342
+ *
343
+ * This method is especially handy with optional selects. Any `returning` or `returningAll`
344
+ * method calls add columns as optional fields to the output type when called inside
345
+ * the `func` callback. This is because we can't know if those selections were actually
346
+ * made before running the code.
347
+ *
348
+ * You can also call any other methods inside the callback.
349
+ *
350
+ * ### Examples
351
+ *
352
+ * ```ts
353
+ * async function insertPerson(values: InsertablePerson, returnLastName: boolean) {
354
+ * return await db
355
+ * .insertInto('person')
356
+ * .values(values)
357
+ * .returning(['id', 'first_name'])
358
+ * .if(returnLastName, (qb) => qb.returning('last_name'))
359
+ * .executeTakeFirstOrThrow()
360
+ * }
361
+ * ```
362
+ *
363
+ * Any selections added inside the `if` callback will be added as optional fields to the
364
+ * output type since we can't know if the selections were actually made before running
365
+ * the code. In the example above the return type of the `insertPerson` function is:
366
+ *
367
+ * ```ts
368
+ * {
369
+ * id: number
370
+ * first_name: string
371
+ * last_name?: string
372
+ * }
373
+ * ```
374
+ */
375
+ if(condition, func) {
376
+ if (condition) {
377
+ return func(this);
378
+ }
379
+ return new InsertQueryBuilder({
380
+ ...this.#props,
381
+ });
382
+ }
338
383
  /**
339
384
  * Change the output type of the query.
340
385
  *
@@ -344,6 +389,9 @@ export class InsertQueryBuilder {
344
389
  castTo() {
345
390
  return new InsertQueryBuilder(this.#props);
346
391
  }
392
+ /**
393
+ * Returns a copy of this InsertQueryBuilder instance with the given plugin installed.
394
+ */
347
395
  withPlugin(plugin) {
348
396
  return new InsertQueryBuilder({
349
397
  ...this.#props,