kysely 0.11.0 → 0.11.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.
Files changed (51) hide show
  1. package/dist/cjs/dialect/mysql/mysql-query-compiler.d.ts +0 -2
  2. package/dist/cjs/dialect/mysql/mysql-query-compiler.js +0 -6
  3. package/dist/cjs/dialect/postgres/postgres-query-compiler.d.ts +3 -0
  4. package/dist/cjs/dialect/postgres/postgres-query-compiler.js +9 -1
  5. package/dist/cjs/dialect/sqlite/sqlite-adapter.js +6 -2
  6. package/dist/cjs/dialect/sqlite/sqlite-driver.js +7 -7
  7. package/dist/cjs/dialect/sqlite/sqlite-introspector.js +19 -6
  8. package/dist/cjs/dialect/sqlite/sqlite-query-compiler.d.ts +2 -2
  9. package/dist/cjs/dialect/sqlite/sqlite-query-compiler.js +6 -6
  10. package/dist/cjs/driver/runtime-driver.js +1 -1
  11. package/dist/cjs/index.d.ts +38 -30
  12. package/dist/cjs/index.js +37 -29
  13. package/dist/cjs/kysely.d.ts +22 -6
  14. package/dist/cjs/operation-node/alias-node.d.ts +1 -1
  15. package/dist/cjs/operation-node/operation-node-utils.d.ts +1 -1
  16. package/dist/cjs/parser/filter-parser.d.ts +1 -0
  17. package/dist/cjs/parser/filter-parser.js +49 -52
  18. package/dist/cjs/parser/insert-values-parser.d.ts +6 -5
  19. package/dist/cjs/parser/insert-values-parser.js +11 -5
  20. package/dist/cjs/query-builder/join-builder.d.ts +3 -0
  21. package/dist/cjs/query-builder/query-builder.d.ts +22 -1
  22. package/dist/cjs/query-builder/query-builder.js +1 -1
  23. package/dist/cjs/util/dynamic-import.js +1 -1
  24. package/dist/cjs/util/log.d.ts +10 -8
  25. package/dist/cjs/util/log.js +29 -9
  26. package/dist/esm/dialect/mysql/mysql-query-compiler.d.ts +0 -2
  27. package/dist/esm/dialect/mysql/mysql-query-compiler.js +0 -6
  28. package/dist/esm/dialect/postgres/postgres-query-compiler.d.ts +3 -0
  29. package/dist/esm/dialect/postgres/postgres-query-compiler.js +9 -1
  30. package/dist/esm/dialect/sqlite/sqlite-adapter.js +6 -2
  31. package/dist/esm/dialect/sqlite/sqlite-driver.js +7 -7
  32. package/dist/esm/dialect/sqlite/sqlite-introspector.js +19 -6
  33. package/dist/esm/dialect/sqlite/sqlite-query-compiler.d.ts +2 -2
  34. package/dist/esm/dialect/sqlite/sqlite-query-compiler.js +6 -6
  35. package/dist/esm/driver/runtime-driver.js +1 -1
  36. package/dist/esm/index.d.ts +38 -30
  37. package/dist/esm/index.js +37 -29
  38. package/dist/esm/kysely.d.ts +22 -6
  39. package/dist/esm/operation-node/alias-node.d.ts +1 -1
  40. package/dist/esm/operation-node/operation-node-utils.d.ts +1 -1
  41. package/dist/esm/parser/filter-parser.d.ts +1 -0
  42. package/dist/esm/parser/filter-parser.js +48 -52
  43. package/dist/esm/parser/insert-values-parser.d.ts +6 -5
  44. package/dist/esm/parser/insert-values-parser.js +12 -6
  45. package/dist/esm/query-builder/join-builder.d.ts +3 -0
  46. package/dist/esm/query-builder/query-builder.d.ts +22 -1
  47. package/dist/esm/query-builder/query-builder.js +1 -1
  48. package/dist/esm/util/dynamic-import.js +1 -1
  49. package/dist/esm/util/log.d.ts +10 -8
  50. package/dist/esm/util/log.js +30 -10
  51. package/package.json +1 -1
@@ -10,7 +10,7 @@ import { DatabaseIntrospector } from './introspection/database-introspector.js';
10
10
  import { Driver, IsolationLevel } from './driver/driver.js';
11
11
  import { ParseContext } from './parser/parse-context.js';
12
12
  import { FunctionBuilder } from './query-builder/function-builder.js';
13
- import { LogLevel } from './util/log.js';
13
+ import { LogConfig } from './util/log.js';
14
14
  /**
15
15
  * The main Kysely class.
16
16
  *
@@ -235,17 +235,33 @@ export interface KyselyConfig {
235
235
  readonly dialect: Dialect;
236
236
  readonly plugins?: KyselyPlugin[];
237
237
  /**
238
- * A list of log levels to log.
238
+ * A list of log levels to log or a custom logger function.
239
239
  *
240
240
  * Currently there's only two levels: `query` and `error`.
241
241
  * This will be expanded based on user feedback later.
242
242
  *
243
- * Log levels:
243
+ * @example
244
+ * ```ts
245
+ * const db = new Kysely<Database>({
246
+ * dialect: new PostgresDialect(postgresConfig),
247
+ * log: ['query', 'error']
248
+ * })
249
+ * ```
244
250
  *
245
- * - query: Log each query's SQL and duration using console.log
246
- * - error: Log all query errors using console.error
251
+ * @example
252
+ * ```ts
253
+ * const db = new Kysely<Database>({
254
+ * dialect: new PostgresDialect(postgresConfig),
255
+ * log(event): void {
256
+ * if (event.level === 'query') {
257
+ * console.log(event.query.sql)
258
+ * console.log(event.query.parameters)
259
+ * }
260
+ * }
261
+ * })
262
+ * ```
247
263
  */
248
- readonly log?: ReadonlyArray<LogLevel>;
264
+ readonly log?: LogConfig;
249
265
  }
250
266
  export declare class ConnectionBuilder<DB> {
251
267
  #private;
@@ -5,7 +5,7 @@ import { RawNode } from './raw-node.js';
5
5
  import { ReferenceNode } from './reference-node.js';
6
6
  import { SelectQueryNode } from './select-query-node.js';
7
7
  import { TableNode } from './table-node.js';
8
- export declare type AliasNodeChild = ColumnNode | ReferenceNode | TableNode | RawNode | SelectQueryNode;
8
+ export declare type AliasNodeChild = ColumnNode | ReferenceNode | TableNode | SelectQueryNode | RawNode;
9
9
  export interface AliasNode extends OperationNode {
10
10
  readonly kind: 'AliasNode';
11
11
  readonly node: AliasNodeChild;
@@ -14,4 +14,4 @@ import { ValueNode } from './value-node.js';
14
14
  export declare type ReferenceExpressionNode = ColumnNode | ReferenceNode | SelectQueryNode | RawNode;
15
15
  export declare type ValueExpressionNode = ValueNode | ValueListNode | PrimitiveValueListNode | ReferenceExpressionNode;
16
16
  export declare type TableExpressionNode = TableNode | AliasNode;
17
- export declare type FilterExpressionNode = FilterNode | AndNode | OrNode | ParensNode;
17
+ export declare type FilterExpressionNode = FilterNode | AndNode | OrNode | ParensNode | RawNode;
@@ -12,3 +12,4 @@ export declare function parseOnFilter(ctx: ParseContext, args: any[]): FilterExp
12
12
  export declare function parseReferenceFilter(ctx: ParseContext, lhs: ReferenceExpression<any, any>, op: FilterOperator, rhs: ReferenceExpression<any, any>): FilterNode;
13
13
  export declare function parseExistFilter(ctx: ParseContext, arg: ExistsExpression<any, any>): FilterNode;
14
14
  export declare function parseNotExistFilter(ctx: ParseContext, arg: ExistsExpression<any, any>): FilterNode;
15
+ export declare function parseFilter(ctx: ParseContext, type: 'where' | 'having' | 'on', args: any[]): FilterExpressionNode;
@@ -1,5 +1,5 @@
1
1
  import { FilterNode } from '../operation-node/filter-node.js';
2
- import { isBoolean, isFunction, isNull, isString, } from '../util/object-utils.js';
2
+ import { freeze, isBoolean, isFunction, isNull, isString, } from '../util/object-utils.js';
3
3
  import { isOperationNodeSource } from '../operation-node/operation-node-source.js';
4
4
  import { RawNode } from '../operation-node/raw-node.js';
5
5
  import { OperatorNode, OPERATORS, } from '../operation-node/operator-node.js';
@@ -9,37 +9,13 @@ import { parseValueExpressionOrList, } from './value-parser.js';
9
9
  import { SelectQueryNode } from '../operation-node/select-query-node.js';
10
10
  import { ValueNode } from '../operation-node/value-node.js';
11
11
  export function parseWhereFilter(ctx, args) {
12
- if (args.length === 3) {
13
- return parseThreeArgFilter(ctx, args[0], args[1], args[2]);
14
- }
15
- else if (args.length === 1 && isFunction(args[0])) {
16
- return parseWhereGroup(ctx, args[0]);
17
- }
18
- else {
19
- throw new Error(`invalid arguments passed to a where method ${JSON.stringify(args)}`);
20
- }
12
+ return parseFilter(ctx, 'where', args);
21
13
  }
22
14
  export function parseHavingFilter(ctx, args) {
23
- if (args.length === 3) {
24
- return parseThreeArgFilter(ctx, args[0], args[1], args[2]);
25
- }
26
- else if (args.length === 1 && isFunction(args[0])) {
27
- return parseHavingGroup(ctx, args[0]);
28
- }
29
- else {
30
- throw new Error(`invalid arguments passed to a having method ${JSON.stringify(args)}`);
31
- }
15
+ return parseFilter(ctx, 'having', args);
32
16
  }
33
17
  export function parseOnFilter(ctx, args) {
34
- if (args.length === 3) {
35
- return parseThreeArgFilter(ctx, args[0], args[1], args[2]);
36
- }
37
- else if (args.length === 1 && isFunction(args[0])) {
38
- return parseOnGroup(ctx, args[0]);
39
- }
40
- else {
41
- throw new Error(`invalid arguments passed to an on method ${JSON.stringify(args)}`);
42
- }
18
+ return parseFilter(ctx, 'on', args);
43
19
  }
44
20
  export function parseReferenceFilter(ctx, lhs, op, rhs) {
45
21
  return FilterNode.create(parseReferenceExpression(ctx, lhs), parseFilterOperator(op), parseReferenceExpression(ctx, rhs));
@@ -50,6 +26,24 @@ export function parseExistFilter(ctx, arg) {
50
26
  export function parseNotExistFilter(ctx, arg) {
51
27
  return parseExistExpression(ctx, 'not exists', arg);
52
28
  }
29
+ export function parseFilter(ctx, type, args) {
30
+ if (args.length === 3) {
31
+ return parseThreeArgFilter(ctx, args[0], args[1], args[2]);
32
+ }
33
+ else if (args.length === 1) {
34
+ const arg = args[0];
35
+ if (isFunction(arg)) {
36
+ return GROUP_PARSERS[type](ctx, arg);
37
+ }
38
+ else if (isOperationNodeSource(arg)) {
39
+ const node = arg.toOperationNode();
40
+ if (RawNode.is(node)) {
41
+ return node;
42
+ }
43
+ }
44
+ }
45
+ throw new Error(`invalid arguments passed to a '${type}' method: ${JSON.stringify(args)}`);
46
+ }
53
47
  function parseThreeArgFilter(ctx, left, op, right) {
54
48
  if ((op === 'is' || op === 'is not') && (isNull(right) || isBoolean(right))) {
55
49
  return parseIsFilter(ctx, left, op, right);
@@ -70,30 +64,6 @@ function parseFilterOperator(op) {
70
64
  }
71
65
  throw new Error(`invalid comparison operator ${JSON.stringify(op)} passed to a filter method`);
72
66
  }
73
- function parseWhereGroup(ctx, callback) {
74
- const query = callback(ctx.createSelectQueryBuilder([]));
75
- const queryNode = query.toOperationNode();
76
- if (!queryNode.where) {
77
- throw new Error('no `where*` methods called insided a group callback');
78
- }
79
- return ParensNode.create(queryNode.where.where);
80
- }
81
- function parseHavingGroup(ctx, callback) {
82
- const query = callback(ctx.createSelectQueryBuilder([]));
83
- const queryNode = query.toOperationNode();
84
- if (!queryNode.having) {
85
- throw new Error('no `having*` methods called insided a group callback');
86
- }
87
- return ParensNode.create(queryNode.having.having);
88
- }
89
- function parseOnGroup(ctx, callback) {
90
- const joinBuilder = callback(ctx.createJoinBuilder('InnerJoin', 'table'));
91
- const joinNode = joinBuilder.toOperationNode();
92
- if (!joinNode.on) {
93
- throw new Error('no `on*` methods called insided a group callback');
94
- }
95
- return ParensNode.create(joinNode.on.on);
96
- }
97
67
  function parseExistExpression(ctx, type, arg) {
98
68
  const node = isFunction(arg)
99
69
  ? arg(ctx.createExpressionBuilder()).toOperationNode()
@@ -103,3 +73,29 @@ function parseExistExpression(ctx, type, arg) {
103
73
  }
104
74
  return FilterNode.create(undefined, OperatorNode.create(type), node);
105
75
  }
76
+ const GROUP_PARSERS = freeze({
77
+ where(ctx, callback) {
78
+ const query = callback(ctx.createSelectQueryBuilder([]));
79
+ const queryNode = query.toOperationNode();
80
+ if (!queryNode.where) {
81
+ throw new Error('no `where` methods called insided a group callback');
82
+ }
83
+ return ParensNode.create(queryNode.where.where);
84
+ },
85
+ having(ctx, callback) {
86
+ const query = callback(ctx.createSelectQueryBuilder([]));
87
+ const queryNode = query.toOperationNode();
88
+ if (!queryNode.having) {
89
+ throw new Error('no `having` methods called insided a group callback');
90
+ }
91
+ return ParensNode.create(queryNode.having.having);
92
+ },
93
+ on(ctx, callback) {
94
+ const joinBuilder = callback(ctx.createJoinBuilder('InnerJoin', 'table'));
95
+ const joinNode = joinBuilder.toOperationNode();
96
+ if (!joinNode.on) {
97
+ throw new Error('no `on` methods called insided a group callback');
98
+ }
99
+ return ParensNode.create(joinNode.on.on);
100
+ },
101
+ });
@@ -3,13 +3,14 @@ import { InsertValuesNode } from '../operation-node/insert-query-node.js';
3
3
  import { RawNode } from '../operation-node/raw-node.js';
4
4
  import { SelectQueryNode } from '../operation-node/select-query-node.js';
5
5
  import { ValueNode } from '../operation-node/value-node.js';
6
- import { AnyQueryBuilder, AnyRawBuilder, GeneratedPlaceholder } from '../util/type-utils.js';
6
+ import { AnyQueryBuilder, AnyRawBuilder, GeneratedPlaceholder, QueryBuilderFactory, RawBuilderFactory } from '../util/type-utils.js';
7
7
  import { PrimitiveValue } from '../util/object-utils.js';
8
+ import { ParseContext } from './parse-context.js';
8
9
  export declare type InsertObject<DB, TB extends keyof DB> = {
9
- [C in keyof DB[TB]]: InsertValueExpression<DB[TB][C]>;
10
+ [C in keyof DB[TB]]: InsertValueExpression<DB, TB, DB[TB][C]>;
10
11
  };
11
12
  export declare type InsertObjectOrList<DB, TB extends keyof DB> = InsertObject<DB, TB> | ReadonlyArray<InsertObject<DB, TB>>;
12
- declare type InsertValueExpression<T> = T | AnyQueryBuilder | AnyRawBuilder | GeneratedPlaceholder;
13
- export declare function parseInsertObjectOrList(args: InsertObjectOrList<any, any>): [ReadonlyArray<ColumnNode>, ReadonlyArray<InsertValuesNode>];
14
- export declare function parseInsertValueExpression(value: InsertValueExpression<PrimitiveValue>): ValueNode | RawNode | SelectQueryNode;
13
+ declare type InsertValueExpression<DB, TB extends keyof DB, T> = T | AnyQueryBuilder | QueryBuilderFactory<DB, TB> | AnyRawBuilder | RawBuilderFactory<DB, TB> | GeneratedPlaceholder;
14
+ export declare function parseInsertObjectOrList(ctx: ParseContext, args: InsertObjectOrList<any, any>): [ReadonlyArray<ColumnNode>, ReadonlyArray<InsertValuesNode>];
15
+ export declare function parseInsertValueExpression(ctx: ParseContext, value: InsertValueExpression<any, any, PrimitiveValue>): ValueNode | RawNode | SelectQueryNode;
15
16
  export {};
@@ -5,11 +5,11 @@ import { QueryNode } from '../operation-node/query-node.js';
5
5
  import { ValueListNode } from '../operation-node/value-list-node.js';
6
6
  import { ValueNode } from '../operation-node/value-node.js';
7
7
  import { isGeneratedPlaceholder } from '../util/generated-placeholder.js';
8
- import { isPrimitive } from '../util/object-utils.js';
9
- export function parseInsertObjectOrList(args) {
10
- return parseInsertColumnsAndValues(Array.isArray(args) ? args : [args]);
8
+ import { isFunction, isPrimitive, } from '../util/object-utils.js';
9
+ export function parseInsertObjectOrList(ctx, args) {
10
+ return parseInsertColumnsAndValues(ctx, Array.isArray(args) ? args : [args]);
11
11
  }
12
- function parseInsertColumnsAndValues(rows) {
12
+ function parseInsertColumnsAndValues(ctx, rows) {
13
13
  const columns = [];
14
14
  const values = [];
15
15
  for (const row of rows) {
@@ -32,12 +32,12 @@ function parseInsertColumnsAndValues(rows) {
32
32
  values.push(PrimitiveValueListNode.create(rowValues));
33
33
  }
34
34
  else {
35
- values.push(ValueListNode.create(rowValues.map(parseInsertValueExpression)));
35
+ values.push(ValueListNode.create(rowValues.map((it) => parseInsertValueExpression(ctx, it))));
36
36
  }
37
37
  }
38
38
  return [columns.map(ColumnNode.create), values];
39
39
  }
40
- export function parseInsertValueExpression(value) {
40
+ export function parseInsertValueExpression(ctx, value) {
41
41
  if (isPrimitive(value)) {
42
42
  return ValueNode.create(value);
43
43
  }
@@ -47,5 +47,11 @@ export function parseInsertValueExpression(value) {
47
47
  return node;
48
48
  }
49
49
  }
50
+ else if (isFunction(value)) {
51
+ const node = value(ctx.createExpressionBuilder()).toOperationNode();
52
+ if (!QueryNode.isMutating(node)) {
53
+ return node;
54
+ }
55
+ }
50
56
  throw new Error(`unsupported value for insert object ${JSON.stringify(value)}`);
51
57
  }
@@ -4,6 +4,7 @@ import { ExistsExpression, FilterOperator } from '../parser/filter-parser.js';
4
4
  import { ParseContext } from '../parser/parse-context.js';
5
5
  import { ReferenceExpression } from '../parser/reference-parser.js';
6
6
  import { ValueExpressionOrList } from '../parser/value-parser.js';
7
+ import { AnyRawBuilder } from '../util/type-utils.js';
7
8
  export declare class JoinBuilder<DB, TB extends keyof DB> implements OperationNodeSource {
8
9
  #private;
9
10
  constructor(props: JoinBuilderProps);
@@ -15,6 +16,7 @@ export declare class JoinBuilder<DB, TB extends keyof DB> implements OperationNo
15
16
  */
16
17
  on<RE extends ReferenceExpression<DB, TB>>(lhs: RE, op: FilterOperator, rhs: ValueExpressionOrList<DB, TB, RE>): JoinBuilder<DB, TB>;
17
18
  on(grouper: (qb: JoinBuilder<DB, TB>) => JoinBuilder<DB, TB>): JoinBuilder<DB, TB>;
19
+ on(raw: AnyRawBuilder): JoinBuilder<DB, TB>;
18
20
  /**
19
21
  * Just like {@link QueryBuilder.orWhere} but adds an item to the join's
20
22
  * `on` clause instead.
@@ -23,6 +25,7 @@ export declare class JoinBuilder<DB, TB extends keyof DB> implements OperationNo
23
25
  */
24
26
  orOn<RE extends ReferenceExpression<DB, TB>>(lhs: RE, op: FilterOperator, rhs: ValueExpressionOrList<DB, TB, RE>): JoinBuilder<DB, TB>;
25
27
  orOn(grouper: (qb: JoinBuilder<DB, TB>) => JoinBuilder<DB, TB>): JoinBuilder<DB, TB>;
28
+ orOn(raw: AnyRawBuilder): JoinBuilder<DB, TB>;
26
29
  /**
27
30
  * Just like {@link QueryBuilder.whereRef} but adds an item to the join's
28
31
  * `on` clause instead.
@@ -10,7 +10,7 @@ import { QueryBuilderWithReturning } from '../parser/returning-parser.js';
10
10
  import { ReferenceExpression } from '../parser/reference-parser.js';
11
11
  import { ValueExpressionOrList } from '../parser/value-parser.js';
12
12
  import { QueryNode } from '../operation-node/query-node.js';
13
- import { AnyColumn, SingleResultType } from '../util/type-utils.js';
13
+ import { AnyColumn, AnyRawBuilder, SingleResultType } from '../util/type-utils.js';
14
14
  import { OrderByDirectionExpression, OrderByExpression } from '../parser/order-by-parser.js';
15
15
  import { MutationObject } from '../parser/update-set-parser.js';
16
16
  import { Compilable } from '../util/compilable.js';
@@ -220,6 +220,7 @@ export declare class QueryBuilder<DB, TB extends keyof DB, O = {}> implements Op
220
220
  */
221
221
  where<RE extends ReferenceExpression<DB, TB>>(lhs: RE, op: FilterOperator, rhs: ValueExpressionOrList<DB, TB, RE>): QueryBuilder<DB, TB, O>;
222
222
  where(grouper: (qb: QueryBuilder<DB, TB, O>) => QueryBuilder<DB, TB, O>): QueryBuilder<DB, TB, O>;
223
+ where(raw: AnyRawBuilder): QueryBuilder<DB, TB, O>;
223
224
  /**
224
225
  * Adds a `where` clause where both sides of the operator are references
225
226
  * to columns.
@@ -339,6 +340,7 @@ export declare class QueryBuilder<DB, TB extends keyof DB, O = {}> implements Op
339
340
  */
340
341
  orWhere<RE extends ReferenceExpression<DB, TB>>(lhs: RE, op: FilterOperator, rhs: ValueExpressionOrList<DB, TB, RE>): QueryBuilder<DB, TB, O>;
341
342
  orWhere(grouper: (qb: QueryBuilder<DB, TB, O>) => QueryBuilder<DB, TB, O>): QueryBuilder<DB, TB, O>;
343
+ orWhere(raw: AnyRawBuilder): QueryBuilder<DB, TB, O>;
342
344
  /**
343
345
  * Adds an `or where` clause to the query. Otherwise works just like
344
346
  * {@link QueryBuilder.whereRef | whereRef}.
@@ -424,6 +426,7 @@ export declare class QueryBuilder<DB, TB extends keyof DB, O = {}> implements Op
424
426
  */
425
427
  having<RE extends ReferenceExpression<DB, TB>>(lhs: RE, op: FilterOperator, rhs: ValueExpressionOrList<DB, TB, RE>): QueryBuilder<DB, TB, O>;
426
428
  having(grouper: (qb: QueryBuilder<DB, TB, O>) => QueryBuilder<DB, TB, O>): QueryBuilder<DB, TB, O>;
429
+ having(raw: AnyRawBuilder): QueryBuilder<DB, TB, O>;
427
430
  /**
428
431
  * Just like {@link QueryBuilder.whereRef | whereRef} but adds a `having` statement
429
432
  * instead of a `where` statement.
@@ -435,6 +438,7 @@ export declare class QueryBuilder<DB, TB extends keyof DB, O = {}> implements Op
435
438
  */
436
439
  orHaving<RE extends ReferenceExpression<DB, TB>>(lhs: RE, op: FilterOperator, rhs: ValueExpressionOrList<DB, TB, RE>): QueryBuilder<DB, TB, O>;
437
440
  orHaving(grouper: (qb: QueryBuilder<DB, TB, O>) => QueryBuilder<DB, TB, O>): QueryBuilder<DB, TB, O>;
441
+ orHaving(raw: AnyRawBuilder): QueryBuilder<DB, TB, O>;
438
442
  /**
439
443
  * Just like {@link QueryBuilder.orWhereRef | orWhereRef} but adds a `having` statement
440
444
  * instead of a `where` statement.
@@ -998,6 +1002,23 @@ export declare class QueryBuilder<DB, TB extends keyof DB, O = {}> implements Op
998
1002
  * insert into "person" ("first_name", "last_name", "age")
999
1003
  * values ($1, $2 || $3, (select avg(age) from "person"))
1000
1004
  * ```
1005
+ *
1006
+ * @example
1007
+ * You can also use the callback version of subqueries or raw expressions:
1008
+ *
1009
+ * ```ts
1010
+ * db.with('jennifer', (db) => db
1011
+ * .selectFrom('person')
1012
+ * .where('first_name', '=', 'Jennifer')
1013
+ * .select(['id', 'first_name', 'gender'])
1014
+ * .limit(1)
1015
+ * ).insertInto('pet').values({
1016
+ * id: db.generated,
1017
+ * owner_id: (eb) => eb.subQuery('jennifer').select('id'),
1018
+ * name: (eb) => eb.subQuery('jennifer').select('first_name'),
1019
+ * species: 'cat',
1020
+ * })
1021
+ * ```
1001
1022
  */
1002
1023
  values(row: InsertObject<DB, TB>): QueryBuilder<DB, TB, O>;
1003
1024
  values(row: ReadonlyArray<InsertObject<DB, TB>>): QueryBuilder<DB, TB, O>;
@@ -437,7 +437,7 @@ export class QueryBuilder {
437
437
  }
438
438
  values(args) {
439
439
  assertCanHaveInsertValues(this.#props.queryNode);
440
- const [columns, values] = parseInsertObjectOrList(args);
440
+ const [columns, values] = parseInsertObjectOrList(this.#props.parseContext, args);
441
441
  return new QueryBuilder({
442
442
  ...this.#props,
443
443
  queryNode: InsertQueryNode.cloneWith(this.#props.queryNode, {
@@ -1,7 +1,7 @@
1
1
  import { isFunction, isObject } from './object-utils.js';
2
2
  export async function importFunction(modulePath) {
3
3
  const module = await import(modulePath);
4
- const errorMessage = `module "${modulePath}" doesn export a function`;
4
+ const errorMessage = `module "${modulePath}" doesn't export a function`;
5
5
  if (isFunction(module)) {
6
6
  return module;
7
7
  }
@@ -1,19 +1,21 @@
1
+ import { CompiledQuery } from '../index.js';
1
2
  import { ArrayItemType } from './type-utils.js';
2
3
  export declare const LOG_LEVELS: readonly ["query", "error"];
3
4
  export declare type LogLevel = ArrayItemType<typeof LOG_LEVELS>;
4
- export declare class Log {
5
- #private;
6
- constructor(levels: ReadonlyArray<LogLevel>);
7
- query(getEvent: () => QueryLogEvent): void;
8
- error(getEvent: () => ErrorLogEvent): void;
9
- }
10
- export declare type LogEvent = QueryLogEvent | ErrorLogEvent;
11
5
  export interface QueryLogEvent {
12
6
  readonly level: 'query';
13
- readonly sql: string;
7
+ readonly query: CompiledQuery;
14
8
  readonly queryDurationMillis: number;
15
9
  }
16
10
  export interface ErrorLogEvent {
17
11
  readonly level: 'error';
18
12
  readonly error: unknown;
19
13
  }
14
+ export declare type LogEvent = QueryLogEvent | ErrorLogEvent;
15
+ export declare type LogConfig = ReadonlyArray<LogLevel> | ((event: LogEvent) => void);
16
+ export declare class Log {
17
+ #private;
18
+ constructor(config: LogConfig);
19
+ query(getEvent: () => QueryLogEvent): void;
20
+ error(getEvent: () => ErrorLogEvent): void;
21
+ }
@@ -1,25 +1,45 @@
1
- import { freeze } from './object-utils.js';
2
- export const LOG_LEVELS = ['query', 'error'];
1
+ import { freeze, isFunction } from './object-utils.js';
2
+ export const LOG_LEVELS = freeze(['query', 'error']);
3
3
  export class Log {
4
4
  #levels;
5
- constructor(levels) {
6
- this.#levels = freeze({
7
- query: levels.includes('query'),
8
- error: levels.includes('error'),
9
- });
5
+ #logger;
6
+ constructor(config) {
7
+ if (isFunction(config)) {
8
+ this.#logger = config;
9
+ this.#levels = freeze({
10
+ query: true,
11
+ error: true,
12
+ });
13
+ }
14
+ else {
15
+ this.#levels = freeze({
16
+ query: config.includes('query'),
17
+ error: config.includes('error'),
18
+ });
19
+ }
10
20
  }
11
21
  query(getEvent) {
12
22
  if (this.#levels.query) {
13
- this.#defaultQuery(getEvent());
23
+ if (this.#logger) {
24
+ this.#logger(getEvent());
25
+ }
26
+ else {
27
+ this.#defaultQuery(getEvent());
28
+ }
14
29
  }
15
30
  }
16
31
  error(getEvent) {
17
32
  if (this.#levels.error) {
18
- this.#defaultError(getEvent());
33
+ if (this.#logger) {
34
+ this.#logger(getEvent());
35
+ }
36
+ else {
37
+ this.#defaultError(getEvent());
38
+ }
19
39
  }
20
40
  }
21
41
  #defaultQuery(event) {
22
- console.log(`kysely:query: ${event.sql}`);
42
+ console.log(`kysely:query: ${event.query.sql}`);
23
43
  console.log(`kysely:query: duration: ${event.queryDurationMillis.toFixed(1)}ms`);
24
44
  }
25
45
  #defaultError(event) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kysely",
3
- "version": "0.11.0",
3
+ "version": "0.11.4",
4
4
  "description": "Type safe SQL query builder",
5
5
  "repository": {
6
6
  "type": "git",