kysely 0.9.2 → 0.9.6

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 (96) hide show
  1. package/dist/cjs/dialect/mysql/mysql-dialect.d.ts +11 -0
  2. package/dist/cjs/dialect/mysql/mysql-dialect.js +7 -0
  3. package/dist/cjs/dialect/postgres/postgres-dialect.d.ts +13 -1
  4. package/dist/cjs/dialect/postgres/postgres-dialect.js +10 -0
  5. package/dist/cjs/dialect/postgres/postgres-driver.js +2 -2
  6. package/dist/cjs/dialect/postgres/postgres-query-compiler.js +1 -1
  7. package/dist/cjs/driver/runtime-driver.d.ts +3 -2
  8. package/dist/cjs/driver/runtime-driver.js +57 -4
  9. package/dist/cjs/index.d.ts +2 -1
  10. package/dist/cjs/kysely.d.ts +31 -9
  11. package/dist/cjs/kysely.js +25 -9
  12. package/dist/cjs/migration/migration.d.ts +32 -0
  13. package/dist/cjs/operation-node/operation-node-transformer.d.ts +2 -0
  14. package/dist/cjs/operation-node/operation-node-transformer.js +9 -0
  15. package/dist/cjs/operation-node/operation-node-visitor.d.ts +61 -59
  16. package/dist/cjs/operation-node/operation-node-visitor.js +1 -316
  17. package/dist/cjs/operation-node/operation-node.d.ts +1 -1
  18. package/dist/cjs/operation-node/operator-node.d.ts +1 -1
  19. package/dist/cjs/operation-node/operator-node.js +1 -0
  20. package/dist/cjs/operation-node/select-query-node.d.ts +3 -0
  21. package/dist/cjs/operation-node/select-query-node.js +8 -0
  22. package/dist/cjs/operation-node/union-node.d.ts +16 -0
  23. package/dist/cjs/operation-node/union-node.js +19 -0
  24. package/dist/cjs/parser/insert-values-parser.d.ts +1 -1
  25. package/dist/cjs/parser/join-parser.d.ts +4 -4
  26. package/dist/cjs/parser/union-parser.d.ts +5 -0
  27. package/dist/cjs/parser/union-parser.js +13 -0
  28. package/dist/cjs/parser/value-parser.d.ts +1 -1
  29. package/dist/cjs/plugin/camel-case/camel-case-plugin.js +5 -116
  30. package/dist/cjs/plugin/camel-case/camel-case-transformer.d.ts +8 -0
  31. package/dist/cjs/plugin/camel-case/camel-case-transformer.js +19 -0
  32. package/dist/cjs/plugin/camel-case/camel-case.d.ts +15 -0
  33. package/dist/cjs/plugin/camel-case/camel-case.js +109 -0
  34. package/dist/cjs/plugin/kysely-plugin.d.ts +1 -1
  35. package/dist/cjs/query-builder/query-builder.d.ts +65 -1
  36. package/dist/cjs/query-builder/query-builder.js +83 -0
  37. package/dist/cjs/query-compiler/default-query-compiler.d.ts +5 -0
  38. package/dist/cjs/query-compiler/default-query-compiler.js +18 -1
  39. package/dist/cjs/query-executor/default-query-executor.d.ts +1 -0
  40. package/dist/cjs/query-executor/default-query-executor.js +6 -0
  41. package/dist/cjs/query-executor/noop-query-executor.d.ts +1 -0
  42. package/dist/cjs/query-executor/noop-query-executor.js +3 -0
  43. package/dist/cjs/query-executor/query-executor.d.ts +9 -4
  44. package/dist/cjs/util/log.d.ts +19 -0
  45. package/dist/cjs/util/log.js +37 -0
  46. package/dist/cjs/util/random-string.js +6 -3
  47. package/dist/cjs/util/type-utils.d.ts +4 -4
  48. package/dist/esm/dialect/mysql/mysql-dialect.d.ts +11 -0
  49. package/dist/esm/dialect/mysql/mysql-dialect.js +7 -0
  50. package/dist/esm/dialect/mysql/mysql-driver.js +1 -1
  51. package/dist/esm/dialect/postgres/postgres-dialect.d.ts +13 -1
  52. package/dist/esm/dialect/postgres/postgres-dialect.js +10 -0
  53. package/dist/esm/dialect/postgres/postgres-driver.js +2 -2
  54. package/dist/esm/dialect/postgres/postgres-query-compiler.js +1 -1
  55. package/dist/esm/driver/runtime-driver.d.ts +3 -2
  56. package/dist/esm/driver/runtime-driver.js +57 -4
  57. package/dist/esm/index.d.ts +2 -1
  58. package/dist/esm/kysely.d.ts +31 -9
  59. package/dist/esm/kysely.js +25 -9
  60. package/dist/esm/migration/migration.d.ts +32 -0
  61. package/dist/esm/operation-node/operation-node-transformer.d.ts +2 -0
  62. package/dist/esm/operation-node/operation-node-transformer.js +9 -0
  63. package/dist/esm/operation-node/operation-node-visitor.d.ts +61 -59
  64. package/dist/esm/operation-node/operation-node-visitor.js +1 -316
  65. package/dist/esm/operation-node/operation-node.d.ts +1 -1
  66. package/dist/esm/operation-node/operator-node.d.ts +1 -1
  67. package/dist/esm/operation-node/operator-node.js +1 -0
  68. package/dist/esm/operation-node/select-query-node.d.ts +3 -0
  69. package/dist/esm/operation-node/select-query-node.js +8 -0
  70. package/dist/esm/operation-node/union-node.d.ts +16 -0
  71. package/dist/esm/operation-node/union-node.js +16 -0
  72. package/dist/esm/parser/insert-values-parser.d.ts +1 -1
  73. package/dist/esm/parser/join-parser.d.ts +4 -4
  74. package/dist/esm/parser/union-parser.d.ts +5 -0
  75. package/dist/esm/parser/union-parser.js +9 -0
  76. package/dist/esm/parser/value-parser.d.ts +1 -1
  77. package/dist/esm/plugin/camel-case/camel-case-plugin.js +4 -115
  78. package/dist/esm/plugin/camel-case/camel-case-transformer.d.ts +8 -0
  79. package/dist/esm/plugin/camel-case/camel-case-transformer.js +15 -0
  80. package/dist/esm/plugin/camel-case/camel-case.d.ts +15 -0
  81. package/dist/esm/plugin/camel-case/camel-case.js +104 -0
  82. package/dist/esm/plugin/kysely-plugin.d.ts +1 -1
  83. package/dist/esm/query-builder/query-builder.d.ts +65 -1
  84. package/dist/esm/query-builder/query-builder.js +83 -0
  85. package/dist/esm/query-compiler/default-query-compiler.d.ts +5 -0
  86. package/dist/esm/query-compiler/default-query-compiler.js +18 -1
  87. package/dist/esm/query-executor/default-query-executor.d.ts +1 -0
  88. package/dist/esm/query-executor/default-query-executor.js +6 -0
  89. package/dist/esm/query-executor/noop-query-executor.d.ts +1 -0
  90. package/dist/esm/query-executor/noop-query-executor.js +3 -0
  91. package/dist/esm/query-executor/query-executor.d.ts +9 -4
  92. package/dist/esm/util/log.d.ts +19 -0
  93. package/dist/esm/util/log.js +33 -0
  94. package/dist/esm/util/random-string.js +6 -3
  95. package/dist/esm/util/type-utils.d.ts +4 -4
  96. package/package.json +1 -1
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Creates a function that transforms camel case strings to snake case.
3
+ */
4
+ export function createSnakeCaseMapper({ upperCase = false, underscoreBeforeDigits = false, underscoreBetweenUppercaseLetters = false, } = {}) {
5
+ return memoize((str) => {
6
+ if (str.length === 0) {
7
+ return str;
8
+ }
9
+ const upper = str.toUpperCase();
10
+ const lower = str.toLowerCase();
11
+ let out = lower[0];
12
+ for (let i = 1, l = str.length; i < l; ++i) {
13
+ const char = str[i];
14
+ const prevChar = str[i - 1];
15
+ const upperChar = upper[i];
16
+ const prevUpperChar = upper[i - 1];
17
+ const lowerChar = lower[i];
18
+ const prevLowerChar = lower[i - 1];
19
+ // If underScoreBeforeDigits is true then, well, insert an underscore
20
+ // before digits :). Only the first digit gets an underscore if
21
+ // there are multiple.
22
+ if (underscoreBeforeDigits && isDigit(char) && !isDigit(prevChar)) {
23
+ out += '_' + char;
24
+ continue;
25
+ }
26
+ // Test if `char` is an upper-case character and that the character
27
+ // actually has different upper and lower case versions.
28
+ if (char === upperChar && upperChar !== lowerChar) {
29
+ const prevCharacterIsUppercase = prevChar === prevUpperChar && prevUpperChar !== prevLowerChar;
30
+ // If underscoreBetweenUppercaseLetters is true, we always place an underscore
31
+ // before consecutive uppercase letters (e.g. "fooBAR" becomes "foo_b_a_r").
32
+ // Otherwise, we don't (e.g. "fooBAR" becomes "foo_bar").
33
+ if (underscoreBetweenUppercaseLetters || !prevCharacterIsUppercase) {
34
+ out += '_' + lowerChar;
35
+ }
36
+ else {
37
+ out += lowerChar;
38
+ }
39
+ }
40
+ else {
41
+ out += char;
42
+ }
43
+ }
44
+ if (upperCase) {
45
+ return out.toUpperCase();
46
+ }
47
+ else {
48
+ return out;
49
+ }
50
+ });
51
+ }
52
+ /**
53
+ * Creates a function that transforms snake case strings to camel case.
54
+ */
55
+ export function createCamelCaseMapper({ upperCase = false, } = {}) {
56
+ return memoize((str) => {
57
+ if (str.length === 0) {
58
+ return str;
59
+ }
60
+ if (upperCase && isAllUpperCaseSnakeCase(str)) {
61
+ // Only convert to lower case if the string is all upper
62
+ // case snake_case. This allows camelCase strings to go
63
+ // through without changing.
64
+ str = str.toLowerCase();
65
+ }
66
+ let out = str[0];
67
+ for (let i = 1, l = str.length; i < l; ++i) {
68
+ const char = str[i];
69
+ const prevChar = str[i - 1];
70
+ if (char !== '_') {
71
+ if (prevChar === '_') {
72
+ out += char.toUpperCase();
73
+ }
74
+ else {
75
+ out += char;
76
+ }
77
+ }
78
+ }
79
+ return out;
80
+ });
81
+ }
82
+ function isAllUpperCaseSnakeCase(str) {
83
+ for (let i = 1, l = str.length; i < l; ++i) {
84
+ const char = str[i];
85
+ if (char !== '_' && char !== char.toUpperCase()) {
86
+ return false;
87
+ }
88
+ }
89
+ return true;
90
+ }
91
+ function isDigit(char) {
92
+ return char >= '0' && char <= '9';
93
+ }
94
+ function memoize(func) {
95
+ const cache = new Map();
96
+ return (str) => {
97
+ let mapped = cache.get(str);
98
+ if (!mapped) {
99
+ mapped = func(str);
100
+ cache.set(str, mapped);
101
+ }
102
+ return mapped;
103
+ };
104
+ }
@@ -21,7 +21,7 @@ export interface KyselyPlugin {
21
21
  * return args.node
22
22
  * },
23
23
  *
24
- * transformResult(args: PluginTransformResultArgs): QueryResult<AnyRow> {
24
+ * transformResult(args: PluginTransformResultArgs): QueryResult<UnknownRow> {
25
25
  * const data = this.data.get(args.queryId)
26
26
  * return args.result
27
27
  * }
@@ -18,6 +18,7 @@ import { QueryExecutor } from '../query-executor/query-executor.js';
18
18
  import { QueryId } from '../util/query-id.js';
19
19
  import { OnConflictConstraintTarget } from '../parser/on-conflict-parser.js';
20
20
  import { ParseContext } from '../parser/parse-context.js';
21
+ import { UnionExpression } from '../parser/union-parser.js';
21
22
  /**
22
23
  * The main query builder class.
23
24
  *
@@ -998,7 +999,7 @@ export declare class QueryBuilder<DB, TB extends keyof DB, O = {}> implements Op
998
999
  * ```
999
1000
  */
1000
1001
  values(row: InsertObject<DB, TB>): QueryBuilder<DB, TB, O>;
1001
- values(row: InsertObject<DB, TB>[]): QueryBuilder<DB, TB, O>;
1002
+ values(row: ReadonlyArray<InsertObject<DB, TB>>): QueryBuilder<DB, TB, O>;
1002
1003
  /**
1003
1004
  * Ignores the insert if the column or constraint given as the first
1004
1005
  * argument conflicts with the current rows in the database. The
@@ -1553,6 +1554,69 @@ export declare class QueryBuilder<DB, TB extends keyof DB, O = {}> implements Op
1553
1554
  * ```
1554
1555
  */
1555
1556
  offset(offset: number): QueryBuilder<DB, TB, O>;
1557
+ /**
1558
+ * Combines another select query or raw expression to this query using `union`.
1559
+ *
1560
+ * The output row type of the combined query must match `this` query.
1561
+ *
1562
+ * @xample
1563
+ * ```ts
1564
+ * db.selectFrom('person')
1565
+ * .select(['id', 'first_name as name'])
1566
+ * .union(db.selectFrom('pet').select(['id', 'name']))
1567
+ * .orderBy('name')
1568
+ * ```
1569
+ */
1570
+ union(expression: UnionExpression<DB, O>): QueryBuilder<DB, TB, O>;
1571
+ /**
1572
+ * Combines another select query or raw expression to this query using `union all`.
1573
+ *
1574
+ * The output row type of the combined query must match `this` query.
1575
+ *
1576
+ * @xample
1577
+ * ```ts
1578
+ * db.selectFrom('person')
1579
+ * .select(['id', 'first_name as name'])
1580
+ * .unionAll(db.selectFrom('pet').select(['id', 'name']))
1581
+ * .orderBy('name')
1582
+ * ```
1583
+ */
1584
+ unionAll(expression: UnionExpression<DB, O>): QueryBuilder<DB, TB, O>;
1585
+ /**
1586
+ * Simply calls the given function passing `this` as the only argument.
1587
+ *
1588
+ * This method can be useful when adding optional method calls:
1589
+ *
1590
+ * @example
1591
+ * ```ts
1592
+ * db.selectFrom('person')
1593
+ * .selectAll()
1594
+ * .call((qb) => {
1595
+ * if (something) {
1596
+ * return qb.where('something', '=', something)
1597
+ * } else {
1598
+ * return qb.where('somethingElse', '=', somethingElse)
1599
+ * }
1600
+ * })
1601
+ * .execute()
1602
+ * ```
1603
+ *
1604
+ * The next example uses a helper funtion `log` to log a query:
1605
+ *
1606
+ * @example
1607
+ * ```ts
1608
+ * function log<T extends AnyQueryBuilder>(qb: T): T {
1609
+ * console.log(qb.compile())
1610
+ * return qb
1611
+ * }
1612
+ *
1613
+ * db.selectFrom('person')
1614
+ * .selectAll()
1615
+ * .call(log)
1616
+ * .execute()
1617
+ * ```
1618
+ */
1619
+ call<T>(func: (qb: this) => T): T;
1556
1620
  /**
1557
1621
  * Gives an alias for the query. This method is only useful for sub queries.
1558
1622
  *
@@ -17,6 +17,7 @@ import { freeze } from '../util/object-utils.js';
17
17
  import { DeleteQueryNode } from '../operation-node/delete-query-node.js';
18
18
  import { OnDuplicateKeyNode } from '../operation-node/on-duplicate-key-node.js';
19
19
  import { parseGroupBy } from '../parser/group-by-parser.js';
20
+ import { parseUnion } from '../parser/union-parser.js';
20
21
  /**
21
22
  * The main query builder class.
22
23
  *
@@ -774,6 +775,83 @@ export class QueryBuilder {
774
775
  queryNode: SelectQueryNode.cloneWithOffset(this.#props.queryNode, OffsetNode.create(offset)),
775
776
  });
776
777
  }
778
+ /**
779
+ * Combines another select query or raw expression to this query using `union`.
780
+ *
781
+ * The output row type of the combined query must match `this` query.
782
+ *
783
+ * @xample
784
+ * ```ts
785
+ * db.selectFrom('person')
786
+ * .select(['id', 'first_name as name'])
787
+ * .union(db.selectFrom('pet').select(['id', 'name']))
788
+ * .orderBy('name')
789
+ * ```
790
+ */
791
+ union(expression) {
792
+ assertCanHaveUnion(this.#props.queryNode);
793
+ return new QueryBuilder({
794
+ ...this.#props,
795
+ queryNode: SelectQueryNode.cloneWithUnion(this.#props.queryNode, parseUnion(expression, false)),
796
+ });
797
+ }
798
+ /**
799
+ * Combines another select query or raw expression to this query using `union all`.
800
+ *
801
+ * The output row type of the combined query must match `this` query.
802
+ *
803
+ * @xample
804
+ * ```ts
805
+ * db.selectFrom('person')
806
+ * .select(['id', 'first_name as name'])
807
+ * .unionAll(db.selectFrom('pet').select(['id', 'name']))
808
+ * .orderBy('name')
809
+ * ```
810
+ */
811
+ unionAll(expression) {
812
+ assertCanHaveUnion(this.#props.queryNode);
813
+ return new QueryBuilder({
814
+ ...this.#props,
815
+ queryNode: SelectQueryNode.cloneWithUnion(this.#props.queryNode, parseUnion(expression, true)),
816
+ });
817
+ }
818
+ /**
819
+ * Simply calls the given function passing `this` as the only argument.
820
+ *
821
+ * This method can be useful when adding optional method calls:
822
+ *
823
+ * @example
824
+ * ```ts
825
+ * db.selectFrom('person')
826
+ * .selectAll()
827
+ * .call((qb) => {
828
+ * if (something) {
829
+ * return qb.where('something', '=', something)
830
+ * } else {
831
+ * return qb.where('somethingElse', '=', somethingElse)
832
+ * }
833
+ * })
834
+ * .execute()
835
+ * ```
836
+ *
837
+ * The next example uses a helper funtion `log` to log a query:
838
+ *
839
+ * @example
840
+ * ```ts
841
+ * function log<T extends AnyQueryBuilder>(qb: T): T {
842
+ * console.log(qb.compile())
843
+ * return qb
844
+ * }
845
+ *
846
+ * db.selectFrom('person')
847
+ * .selectAll()
848
+ * .call(log)
849
+ * .execute()
850
+ * ```
851
+ */
852
+ call(func) {
853
+ return func(this);
854
+ }
777
855
  /**
778
856
  * Gives an alias for the query. This method is only useful for sub queries.
779
857
  *
@@ -979,3 +1057,8 @@ function assertCanHaveOffset(node) {
979
1057
  throw new Error('only a select query can have an offset');
980
1058
  }
981
1059
  }
1060
+ function assertCanHaveUnion(node) {
1061
+ if (!SelectQueryNode.is(node)) {
1062
+ throw new Error('only a select query can have an union');
1063
+ }
1064
+ }
@@ -60,6 +60,8 @@ import { ForeignKeyConstraintNode } from '../operation-node/foreign-key-constrai
60
60
  import { ColumnDefinitionNode } from '../operation-node/column-definition-node.js';
61
61
  import { ModifyColumnNode } from '../operation-node/modify-column-node.js';
62
62
  import { OnDuplicateKeyNode } from '../operation-node/on-duplicate-key-node.js';
63
+ import { ColumnNode } from '../operation-node/column-node.js';
64
+ import { UnionNode } from '../operation-node/union-node.js';
63
65
  export declare class DefaultQueryCompiler extends OperationNodeVisitor implements QueryCompiler {
64
66
  #private;
65
67
  protected get numParameters(): number;
@@ -67,6 +69,8 @@ export declare class DefaultQueryCompiler extends OperationNodeVisitor implement
67
69
  protected getSql(): string;
68
70
  protected visitSelectQuery(node: SelectQueryNode): void;
69
71
  protected visitFrom(node: FromNode): void;
72
+ protected visitSelection(node: SelectionNode): void;
73
+ protected visitColumn(node: ColumnNode): void;
70
74
  protected compileDistinctOn(selections: ReadonlyArray<SelectionNode>): void;
71
75
  protected compileList(nodes: ReadonlyArray<OperationNode>, separator?: string): void;
72
76
  protected visitWhere(node: WhereNode): void;
@@ -125,6 +129,7 @@ export declare class DefaultQueryCompiler extends OperationNodeVisitor implement
125
129
  protected visitModifyColumn(node: ModifyColumnNode): void;
126
130
  protected visitAddConstraint(node: AddConstraintNode): void;
127
131
  protected visitDropConstraint(node: DropConstraintNode): void;
132
+ protected visitUnion(node: UnionNode): void;
128
133
  protected append(str: string): void;
129
134
  protected appendValue(parameter: unknown): void;
130
135
  protected getLeftIdentifierWrapper(): string;
@@ -14,7 +14,7 @@ export class DefaultQueryCompiler extends OperationNodeVisitor {
14
14
  this.visitNode(node);
15
15
  return freeze({
16
16
  sql: this.getSql(),
17
- parameters: this.#parameters,
17
+ parameters: [...this.#parameters],
18
18
  });
19
19
  }
20
20
  getSql() {
@@ -60,6 +60,10 @@ export class DefaultQueryCompiler extends OperationNodeVisitor {
60
60
  this.append(' ');
61
61
  this.visitNode(node.having);
62
62
  }
63
+ if (node.union) {
64
+ this.append(' ');
65
+ this.compileList(node.union, ' ');
66
+ }
63
67
  if (node.orderBy) {
64
68
  this.append(' ');
65
69
  this.visitNode(node.orderBy);
@@ -86,6 +90,12 @@ export class DefaultQueryCompiler extends OperationNodeVisitor {
86
90
  this.append('from ');
87
91
  this.compileList(node.froms);
88
92
  }
93
+ visitSelection(node) {
94
+ this.visitNode(node.selection);
95
+ }
96
+ visitColumn(node) {
97
+ this.visitNode(node.column);
98
+ }
89
99
  compileDistinctOn(selections) {
90
100
  this.append('distinct on (');
91
101
  this.compileList(selections);
@@ -627,6 +637,13 @@ export class DefaultQueryCompiler extends OperationNodeVisitor {
627
637
  this.append('drop constraint ');
628
638
  this.visitNode(node.constraintName);
629
639
  }
640
+ visitUnion(node) {
641
+ this.append('union ');
642
+ if (node.all) {
643
+ this.append('all ');
644
+ }
645
+ this.visitNode(node.union);
646
+ }
630
647
  append(str) {
631
648
  this.#sql += str;
632
649
  }
@@ -9,6 +9,7 @@ export declare class DefaultQueryExecutor extends QueryExecutor {
9
9
  constructor(compiler: QueryCompiler, connectionProvider: ConnectionProvider, plugins?: KyselyPlugin[]);
10
10
  compileQuery(node: RootOperationNode): CompiledQuery;
11
11
  protected executeQueryImpl<R>(compiledQuery: CompiledQuery): Promise<QueryResult<R>>;
12
+ withPlugin(plugin: KyselyPlugin): DefaultQueryExecutor;
12
13
  withPluginAtFront(plugin: KyselyPlugin): DefaultQueryExecutor;
13
14
  withConnectionProvider(connectionProvider: ConnectionProvider): QueryExecutor;
14
15
  withoutPlugins(): QueryExecutor;
@@ -15,6 +15,12 @@ export class DefaultQueryExecutor extends QueryExecutor {
15
15
  return connection.executeQuery(compiledQuery);
16
16
  });
17
17
  }
18
+ withPlugin(plugin) {
19
+ return new DefaultQueryExecutor(this.#compiler, this.#connectionProvider, [
20
+ ...this.plugins,
21
+ plugin,
22
+ ]);
23
+ }
18
24
  withPluginAtFront(plugin) {
19
25
  return new DefaultQueryExecutor(this.#compiler, this.#connectionProvider, [
20
26
  plugin,
@@ -11,6 +11,7 @@ export declare class NoopQueryExecutor extends QueryExecutor {
11
11
  compileQuery(): CompiledQuery;
12
12
  protected executeQueryImpl<R>(): Promise<QueryResult<R>>;
13
13
  withConnectionProvider(): QueryExecutor;
14
+ withPlugin(plugin: KyselyPlugin): NoopQueryExecutor;
14
15
  withPluginAtFront(plugin: KyselyPlugin): NoopQueryExecutor;
15
16
  withoutPlugins(): QueryExecutor;
16
17
  }
@@ -14,6 +14,9 @@ export class NoopQueryExecutor extends QueryExecutor {
14
14
  withConnectionProvider() {
15
15
  throw new Error('this query cannot have a connection provider');
16
16
  }
17
+ withPlugin(plugin) {
18
+ return new NoopQueryExecutor([...this.plugins, plugin]);
19
+ }
17
20
  withPluginAtFront(plugin) {
18
21
  return new NoopQueryExecutor([plugin, ...this.plugins]);
19
22
  }
@@ -35,15 +35,20 @@ export declare abstract class QueryExecutor {
35
35
  * Executes a compiled query.
36
36
  */
37
37
  protected abstract executeQueryImpl<R>(compiledQuery: CompiledQuery, queryId: QueryId): Promise<QueryResult<R>>;
38
+ /**
39
+ * Returns a copy of this executor with a new connection provider.
40
+ */
41
+ abstract withConnectionProvider(connectionProvider: ConnectionProvider): QueryExecutor;
38
42
  /**
39
43
  * Returns a copy of this executor with a plugin added as the
40
- * first plugin.
44
+ * last plugin.
41
45
  */
42
- abstract withPluginAtFront(plugin: KyselyPlugin): QueryExecutor;
46
+ abstract withPlugin(plugin: KyselyPlugin): QueryExecutor;
43
47
  /**
44
- * Returns a copy of this executor with a new connection provider.
48
+ * Returns a copy of this executor with a plugin added as the
49
+ * first plugin.
45
50
  */
46
- abstract withConnectionProvider(connectionProvider: ConnectionProvider): QueryExecutor;
51
+ abstract withPluginAtFront(plugin: KyselyPlugin): QueryExecutor;
47
52
  /**
48
53
  * Returns a copy of this executor without any plugins.
49
54
  */
@@ -0,0 +1,19 @@
1
+ import { ArrayItemType } from './type-utils.js';
2
+ export declare const LOG_LEVELS: readonly ["query", "error"];
3
+ 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
+ export interface QueryLogEvent {
12
+ readonly level: 'query';
13
+ readonly sql: string;
14
+ readonly queryDurationMillis: number;
15
+ }
16
+ export interface ErrorLogEvent {
17
+ readonly level: 'error';
18
+ readonly error: unknown;
19
+ }
@@ -0,0 +1,33 @@
1
+ import { freeze } from './object-utils.js';
2
+ export const LOG_LEVELS = ['query', 'error'];
3
+ export class Log {
4
+ #levels;
5
+ constructor(levels) {
6
+ this.#levels = freeze({
7
+ query: levels.includes('query'),
8
+ error: levels.includes('error'),
9
+ });
10
+ }
11
+ query(getEvent) {
12
+ if (this.#levels.query) {
13
+ this.#defaultQuery(getEvent());
14
+ }
15
+ }
16
+ error(getEvent) {
17
+ if (this.#levels.error) {
18
+ this.#defaultError(getEvent());
19
+ }
20
+ }
21
+ #defaultQuery(event) {
22
+ console.log(`kysely:query: ${event.sql}`);
23
+ console.log(`kysely:query: duration: ${event.queryDurationMillis.toFixed(1)}ms`);
24
+ }
25
+ #defaultError(event) {
26
+ if (event.error instanceof Error) {
27
+ console.error(`kysely:error: ${event.error.stack ?? event.error.message}`);
28
+ }
29
+ else {
30
+ console.error(`kysely:error: ${event}`);
31
+ }
32
+ }
33
+ }
@@ -1,8 +1,11 @@
1
1
  const CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
2
2
  export function randomString(length) {
3
- let chars = new Array(length);
3
+ let chars = '';
4
4
  for (let i = 0; i < length; ++i) {
5
- chars[i] = CHARS[Math.floor(Math.random() * CHARS.length)];
5
+ chars += randomChar();
6
6
  }
7
- return chars.join('');
7
+ return chars;
8
+ }
9
+ function randomChar() {
10
+ return CHARS[Math.floor(Math.random() * CHARS.length)];
8
11
  }
@@ -136,19 +136,19 @@ export declare type RawBuilderFactory<DB, TB extends keyof DB> = (qb: Expression
136
136
  export declare type AliasedRawBuilderFactory<DB, TB extends keyof DB> = (qb: ExpressionBuilder<DB, TB>) => AnyAliasedRawBuilder;
137
137
  export interface InsertResultTypeTag {
138
138
  /** @internal */
139
- __isInsertResultTypeTag__: true;
139
+ readonly __isInsertResultTypeTag__: true;
140
140
  }
141
141
  export interface DeleteResultTypeTag {
142
142
  /** @internal */
143
- __isDeleteResultTypeTag__: true;
143
+ readonly __isDeleteResultTypeTag__: true;
144
144
  }
145
145
  export interface UpdateResultTypeTag {
146
146
  /** @internal */
147
- __isUpdateResultTypeTag__: true;
147
+ readonly __isUpdateResultTypeTag__: true;
148
148
  }
149
149
  export interface GeneratedPlaceholder {
150
150
  /** @internal */
151
- __isGeneratedPlaceholder__: true;
151
+ readonly __isGeneratedPlaceholder__: true;
152
152
  }
153
153
  export declare type ManyResultRowType<O> = O extends InsertResultTypeTag ? number | undefined : O extends DeleteResultTypeTag ? number : O extends UpdateResultTypeTag ? number : O;
154
154
  export declare type SingleResultRowType<O> = O extends InsertResultTypeTag ? number | undefined : O extends DeleteResultTypeTag ? number : O extends UpdateResultTypeTag ? number : O | undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kysely",
3
- "version": "0.9.2",
3
+ "version": "0.9.6",
4
4
  "description": "Type safe SQL query builder",
5
5
  "repository": {
6
6
  "type": "git",