kysely 0.9.4 → 0.9.8

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-dialect.d.ts +2 -0
  2. package/dist/cjs/dialect/postgres/postgres-dialect.d.ts +2 -0
  3. package/dist/cjs/dialect/postgres/postgres-driver.js +2 -2
  4. package/dist/cjs/dialect/postgres/postgres-query-compiler.js +1 -1
  5. package/dist/cjs/driver/runtime-driver.js +20 -6
  6. package/dist/cjs/index.d.ts +1 -0
  7. package/dist/cjs/kysely.d.ts +8 -3
  8. package/dist/cjs/kysely.js +9 -0
  9. package/dist/cjs/operation-node/operator-node.d.ts +1 -1
  10. package/dist/cjs/operation-node/operator-node.js +6 -0
  11. package/dist/cjs/plugin/camel-case/camel-case-plugin.js +5 -116
  12. package/dist/cjs/plugin/camel-case/camel-case-transformer.d.ts +8 -0
  13. package/dist/cjs/plugin/camel-case/camel-case-transformer.js +19 -0
  14. package/dist/cjs/plugin/camel-case/camel-case.d.ts +15 -0
  15. package/dist/cjs/plugin/camel-case/camel-case.js +109 -0
  16. package/dist/cjs/plugin/kysely-plugin.d.ts +1 -1
  17. package/dist/cjs/query-builder/query-builder.d.ts +1 -1
  18. package/dist/cjs/query-builder/query-builder.js +1 -1
  19. package/dist/cjs/query-executor/default-query-executor.d.ts +1 -0
  20. package/dist/cjs/query-executor/default-query-executor.js +6 -0
  21. package/dist/cjs/query-executor/noop-query-executor.d.ts +1 -0
  22. package/dist/cjs/query-executor/noop-query-executor.js +3 -0
  23. package/dist/cjs/query-executor/query-executor.d.ts +9 -4
  24. package/dist/cjs/util/log.d.ts +13 -2
  25. package/dist/cjs/util/log.js +23 -7
  26. package/dist/esm/dialect/mysql/mysql-dialect.d.ts +2 -0
  27. package/dist/esm/dialect/postgres/postgres-dialect.d.ts +2 -0
  28. package/dist/esm/dialect/postgres/postgres-driver.js +2 -2
  29. package/dist/esm/dialect/postgres/postgres-query-compiler.js +1 -1
  30. package/dist/esm/driver/runtime-driver.js +20 -6
  31. package/dist/esm/index.d.ts +1 -0
  32. package/dist/esm/kysely.d.ts +8 -3
  33. package/dist/esm/kysely.js +9 -0
  34. package/dist/esm/operation-node/operator-node.d.ts +1 -1
  35. package/dist/esm/operation-node/operator-node.js +6 -0
  36. package/dist/esm/plugin/camel-case/camel-case-plugin.js +4 -115
  37. package/dist/esm/plugin/camel-case/camel-case-transformer.d.ts +8 -0
  38. package/dist/esm/plugin/camel-case/camel-case-transformer.js +15 -0
  39. package/dist/esm/plugin/camel-case/camel-case.d.ts +15 -0
  40. package/dist/esm/plugin/camel-case/camel-case.js +104 -0
  41. package/dist/esm/plugin/kysely-plugin.d.ts +1 -1
  42. package/dist/esm/query-builder/query-builder.d.ts +1 -1
  43. package/dist/esm/query-builder/query-builder.js +1 -1
  44. package/dist/esm/query-executor/default-query-executor.d.ts +1 -0
  45. package/dist/esm/query-executor/default-query-executor.js +6 -0
  46. package/dist/esm/query-executor/noop-query-executor.d.ts +1 -0
  47. package/dist/esm/query-executor/noop-query-executor.js +3 -0
  48. package/dist/esm/query-executor/query-executor.d.ts +9 -4
  49. package/dist/esm/util/log.d.ts +13 -2
  50. package/dist/esm/util/log.js +23 -7
  51. package/package.json +4 -1
@@ -185,6 +185,8 @@ export interface MysqlDialectConfig {
185
185
  keepAliveInitialDelay?: number;
186
186
  /**
187
187
  * Called once for each created connection.
188
+ *
189
+ * This is a Kysely specific feature and does not come from the `pg` module.
188
190
  */
189
191
  onCreateConnection?: (connection: DatabaseConnection) => Promise<void>;
190
192
  }
@@ -115,6 +115,8 @@ export interface PostgresDialectConfig {
115
115
  application_name?: string;
116
116
  /**
117
117
  * Called once for each created connection.
118
+ *
119
+ * This is a Kysely specific feature and does not come from the `pg` module.
118
120
  */
119
121
  onCreateConnection?: (connection: DatabaseConnection) => Promise<void>;
120
122
  keepAlive?: boolean;
@@ -16,10 +16,10 @@ class PostgresDriver {
16
16
  // installed. As you can see, there IS an import from `pg` at the
17
17
  // top level too, but that's only for types. It doesn't get compiled
18
18
  // into javascript. You can check the built javascript code.
19
- const PoolConstrucor = await importPgPool();
19
+ const PoolConstructor = await importPgPool();
20
20
  // Use the `pg` module's own pool. All drivers should use the
21
21
  // pool provided by the database library if possible.
22
- this.#pool = new PoolConstrucor(this.#config);
22
+ this.#pool = new PoolConstructor(this.#config);
23
23
  }
24
24
  async acquireConnection() {
25
25
  const client = await this.#pool.connect();
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.PostgresQueryCompiler = void 0;
4
4
  const default_query_compiler_js_1 = require("../../query-compiler/default-query-compiler.js");
5
- // The default query compiler is for postgres dialect.
5
+ // The default query compiler is for PostgreSQL.
6
6
  class PostgresQueryCompiler extends default_query_compiler_js_1.DefaultQueryCompiler {
7
7
  }
8
8
  exports.PostgresQueryCompiler = PostgresQueryCompiler;
@@ -79,16 +79,30 @@ class RuntimeConnection {
79
79
  try {
80
80
  return await this.#connection.executeQuery(compiledQuery);
81
81
  }
82
+ catch (error) {
83
+ this.#logError(error);
84
+ throw error;
85
+ }
82
86
  finally {
83
- this.#log.query((log) => {
84
- log(compiledQuery.sql);
85
- log(`duration: ${this.#calculateDurationMillis(startTime)}ms`);
86
- });
87
+ this.#logQuery(compiledQuery, startTime);
87
88
  }
88
89
  }
90
+ #logError(error) {
91
+ this.#log.error(() => ({
92
+ level: 'error',
93
+ error,
94
+ }));
95
+ }
96
+ #logQuery(compiledQuery, startTime) {
97
+ this.#log.query(() => ({
98
+ level: 'query',
99
+ sql: compiledQuery.sql,
100
+ queryDurationMillis: this.#calculateDurationMillis(startTime),
101
+ }));
102
+ }
89
103
  #calculateDurationMillis(startTime) {
90
104
  const endTime = process.hrtime.bigint();
91
- const durationTensMillis = Number((endTime - startTime) / 100000n);
92
- return durationTensMillis / 10;
105
+ const durationNanos = Number(endTime - startTime);
106
+ return durationNanos / 1_000_000;
93
107
  }
94
108
  }
@@ -120,3 +120,4 @@ export { JoinReferenceExpression, JoinCallbackExpression, } from './parser/join-
120
120
  export { InsertObject } from './parser/insert-values-parser.js';
121
121
  export { MutationObject } from './parser/update-set-parser.js';
122
122
  export { OrderByExpression, OrderByDirectionExpression, } from './parser/order-by-parser.js';
123
+ export { UnionExpression } from './parser/union-parser.js';
@@ -194,6 +194,10 @@ export declare class Kysely<DB> extends QueryCreator<DB> {
194
194
  * ```
195
195
  */
196
196
  connection(): ConnectionBuilder<DB>;
197
+ /**
198
+ * Returns a copy of this Kysely instance with the given plugin installed.
199
+ */
200
+ withPlugin(plugin: KyselyPlugin): Kysely<DB>;
197
201
  /**
198
202
  * Returns a copy of this Kysely instance without any plugins.
199
203
  */
@@ -231,12 +235,13 @@ export interface KyselyConfig {
231
235
  /**
232
236
  * A list of log levels to log.
233
237
  *
234
- * Currently there's only one level: `query` and it's logged using
235
- * `console.log`. This will be expanded based on user request later.
238
+ * Currently there's only two levels: `query` and `error`.
239
+ * This will be expanded based on user feedback later.
236
240
  *
237
241
  * Log levels:
238
242
  *
239
- * - query: Log each query's SQL and duration.
243
+ * - query: Log each query's SQL and duration using console.log
244
+ * - error: Log all query errors using console.error
240
245
  */
241
246
  readonly log?: ReadonlyArray<LogLevel>;
242
247
  }
@@ -238,6 +238,15 @@ class Kysely extends query_creator_js_1.QueryCreator {
238
238
  connection() {
239
239
  return new ConnectionBuilder({ ...this.#props });
240
240
  }
241
+ /**
242
+ * Returns a copy of this Kysely instance with the given plugin installed.
243
+ */
244
+ withPlugin(plugin) {
245
+ return new Kysely({
246
+ ...this.#props,
247
+ executor: this.#props.executor.withPlugin(plugin),
248
+ });
249
+ }
241
250
  /**
242
251
  * Returns a copy of this Kysely instance without any plugins.
243
252
  */
@@ -1,6 +1,6 @@
1
1
  import { ArrayItemType } from '../util/type-utils.js';
2
2
  import { OperationNode } from './operation-node.js';
3
- export declare const OPERATORS: readonly ["=", "==", "!=", "<>", ">", ">=", "<", "<=", "in", "not in", "is", "is not", "like", "not like", "ilike", "not ilike", "@>", "<@", "?", "?", "?&", "!<", "!>", "<=>", "!~", "~", "~*", "!~*", "exists", "not exists"];
3
+ export declare const OPERATORS: readonly ["=", "==", "!=", "<>", ">", ">=", "<", "<=", "in", "not in", "is", "is not", "like", "not like", "ilike", "not ilike", "@>", "<@", "?", "?", "?&", "!<", "!>", "<=>", "!~", "~", "~*", "!~*", "exists", "not exists", "&&", "||", "@@", "@@@", "!!", "<->"];
4
4
  export declare type Operator = ArrayItemType<typeof OPERATORS>;
5
5
  export interface OperatorNode extends OperationNode {
6
6
  readonly kind: 'OperatorNode';
@@ -33,6 +33,12 @@ exports.OPERATORS = [
33
33
  '!~*',
34
34
  'exists',
35
35
  'not exists',
36
+ '&&',
37
+ '||',
38
+ '@@',
39
+ '@@@',
40
+ '!!',
41
+ '<->',
36
42
  ];
37
43
  /**
38
44
  * @internal
@@ -1,8 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CamelCasePlugin = void 0;
4
- const operation_node_transformer_js_1 = require("../../operation-node/operation-node-transformer.js");
5
4
  const object_utils_js_1 = require("../../util/object-utils.js");
5
+ const camel_case_transformer_js_1 = require("./camel-case-transformer.js");
6
+ const camel_case_js_1 = require("./camel-case.js");
6
7
  /**
7
8
  * A plugin that converts snake_case identifiers in the database into
8
9
  * camelCase in the javascript side.
@@ -72,9 +73,9 @@ class CamelCasePlugin {
72
73
  #snakeCase;
73
74
  #snakeCaseTransformer;
74
75
  constructor(opt = {}) {
75
- this.#camelCase = createCamelCase(opt);
76
- this.#snakeCase = createSnakeCase(opt);
77
- this.#snakeCaseTransformer = new SnakeCaseTransformer(this.snakeCase.bind(this));
76
+ this.#camelCase = (0, camel_case_js_1.createCamelCaseMapper)(opt);
77
+ this.#snakeCase = (0, camel_case_js_1.createSnakeCaseMapper)(opt);
78
+ this.#snakeCaseTransformer = new camel_case_transformer_js_1.SnakeCaseTransformer(this.snakeCase.bind(this));
78
79
  }
79
80
  transformQuery(args) {
80
81
  return this.#snakeCaseTransformer.transformNode(args.node);
@@ -109,118 +110,6 @@ class CamelCasePlugin {
109
110
  }
110
111
  }
111
112
  exports.CamelCasePlugin = CamelCasePlugin;
112
- class SnakeCaseTransformer extends operation_node_transformer_js_1.OperationNodeTransformer {
113
- #snakeCase;
114
- constructor(snakeCase) {
115
- super();
116
- this.#snakeCase = snakeCase;
117
- }
118
- transformIdentifier(node) {
119
- node = super.transformIdentifier(node);
120
- return {
121
- ...node,
122
- identifier: this.#snakeCase(node.identifier),
123
- };
124
- }
125
- }
126
113
  function canMap(obj) {
127
114
  return (0, object_utils_js_1.isObject)(obj) && !(obj instanceof Date) && !Buffer.isBuffer(obj);
128
115
  }
129
- function createSnakeCase({ upperCase = false, underscoreBeforeDigits = false, underscoreBetweenUppercaseLetters = false, } = {}) {
130
- return memoize((str) => {
131
- if (str.length === 0) {
132
- return str;
133
- }
134
- const upper = str.toUpperCase();
135
- const lower = str.toLowerCase();
136
- let out = lower[0];
137
- for (let i = 1, l = str.length; i < l; ++i) {
138
- const char = str[i];
139
- const prevChar = str[i - 1];
140
- const upperChar = upper[i];
141
- const prevUpperChar = upper[i - 1];
142
- const lowerChar = lower[i];
143
- const prevLowerChar = lower[i - 1];
144
- // If underScoreBeforeDigits is true then, well, insert an underscore
145
- // before digits :). Only the first digit gets an underscore if
146
- // there are multiple.
147
- if (underscoreBeforeDigits && isDigit(char) && !isDigit(prevChar)) {
148
- out += '_' + char;
149
- continue;
150
- }
151
- // Test if `char` is an upper-case character and that the character
152
- // actually has different upper and lower case versions.
153
- if (char === upperChar && upperChar !== lowerChar) {
154
- const prevCharacterIsUppercase = prevChar === prevUpperChar && prevUpperChar !== prevLowerChar;
155
- // If underscoreBetweenUppercaseLetters is true, we always place an underscore
156
- // before consecutive uppercase letters (e.g. "fooBAR" becomes "foo_b_a_r").
157
- // Otherwise, we don't (e.g. "fooBAR" becomes "foo_bar").
158
- if (underscoreBetweenUppercaseLetters || !prevCharacterIsUppercase) {
159
- out += '_' + lowerChar;
160
- }
161
- else {
162
- out += lowerChar;
163
- }
164
- }
165
- else {
166
- out += char;
167
- }
168
- }
169
- if (upperCase) {
170
- return out.toUpperCase();
171
- }
172
- else {
173
- return out;
174
- }
175
- });
176
- }
177
- function createCamelCase({ upperCase = false } = {}) {
178
- return memoize((str) => {
179
- if (str.length === 0) {
180
- return str;
181
- }
182
- if (upperCase && isAllUpperCaseSnakeCase(str)) {
183
- // Only convert to lower case if the string is all upper
184
- // case snake_case. This allows camelCase strings to go
185
- // through without changing.
186
- str = str.toLowerCase();
187
- }
188
- let out = str[0];
189
- for (let i = 1, l = str.length; i < l; ++i) {
190
- const char = str[i];
191
- const prevChar = str[i - 1];
192
- if (char !== '_') {
193
- if (prevChar === '_') {
194
- out += char.toUpperCase();
195
- }
196
- else {
197
- out += char;
198
- }
199
- }
200
- }
201
- return out;
202
- });
203
- }
204
- function isAllUpperCaseSnakeCase(str) {
205
- for (let i = 1, l = str.length; i < l; ++i) {
206
- const char = str[i];
207
- if (char !== '_' && char !== char.toUpperCase()) {
208
- return false;
209
- }
210
- }
211
- return true;
212
- }
213
- function isDigit(char) {
214
- return char >= '0' && char <= '9';
215
- }
216
- function memoize(func) {
217
- const cache = new Map();
218
- return (str) => {
219
- let mapped = cache.get(str);
220
- if (!mapped) {
221
- mapped = func(str);
222
- cache.set(str, mapped);
223
- }
224
- return mapped;
225
- };
226
- }
@@ -0,0 +1,8 @@
1
+ import { IdentifierNode } from '../../operation-node/identifier-node.js';
2
+ import { OperationNodeTransformer } from '../../operation-node/operation-node-transformer.js';
3
+ import { StringMapper } from './camel-case.js';
4
+ export declare class SnakeCaseTransformer extends OperationNodeTransformer {
5
+ #private;
6
+ constructor(snakeCase: StringMapper);
7
+ protected transformIdentifier(node: IdentifierNode): IdentifierNode;
8
+ }
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SnakeCaseTransformer = void 0;
4
+ const operation_node_transformer_js_1 = require("../../operation-node/operation-node-transformer.js");
5
+ class SnakeCaseTransformer extends operation_node_transformer_js_1.OperationNodeTransformer {
6
+ #snakeCase;
7
+ constructor(snakeCase) {
8
+ super();
9
+ this.#snakeCase = snakeCase;
10
+ }
11
+ transformIdentifier(node) {
12
+ node = super.transformIdentifier(node);
13
+ return {
14
+ ...node,
15
+ identifier: this.#snakeCase(node.identifier),
16
+ };
17
+ }
18
+ }
19
+ exports.SnakeCaseTransformer = SnakeCaseTransformer;
@@ -0,0 +1,15 @@
1
+ export declare type StringMapper = (str: string) => string;
2
+ /**
3
+ * Creates a function that transforms camel case strings to snake case.
4
+ */
5
+ export declare function createSnakeCaseMapper({ upperCase, underscoreBeforeDigits, underscoreBetweenUppercaseLetters, }?: {
6
+ upperCase?: boolean | undefined;
7
+ underscoreBeforeDigits?: boolean | undefined;
8
+ underscoreBetweenUppercaseLetters?: boolean | undefined;
9
+ }): StringMapper;
10
+ /**
11
+ * Creates a function that transforms snake case strings to camel case.
12
+ */
13
+ export declare function createCamelCaseMapper({ upperCase, }?: {
14
+ upperCase?: boolean | undefined;
15
+ }): StringMapper;
@@ -0,0 +1,109 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createCamelCaseMapper = exports.createSnakeCaseMapper = void 0;
4
+ /**
5
+ * Creates a function that transforms camel case strings to snake case.
6
+ */
7
+ function createSnakeCaseMapper({ upperCase = false, underscoreBeforeDigits = false, underscoreBetweenUppercaseLetters = false, } = {}) {
8
+ return memoize((str) => {
9
+ if (str.length === 0) {
10
+ return str;
11
+ }
12
+ const upper = str.toUpperCase();
13
+ const lower = str.toLowerCase();
14
+ let out = lower[0];
15
+ for (let i = 1, l = str.length; i < l; ++i) {
16
+ const char = str[i];
17
+ const prevChar = str[i - 1];
18
+ const upperChar = upper[i];
19
+ const prevUpperChar = upper[i - 1];
20
+ const lowerChar = lower[i];
21
+ const prevLowerChar = lower[i - 1];
22
+ // If underScoreBeforeDigits is true then, well, insert an underscore
23
+ // before digits :). Only the first digit gets an underscore if
24
+ // there are multiple.
25
+ if (underscoreBeforeDigits && isDigit(char) && !isDigit(prevChar)) {
26
+ out += '_' + char;
27
+ continue;
28
+ }
29
+ // Test if `char` is an upper-case character and that the character
30
+ // actually has different upper and lower case versions.
31
+ if (char === upperChar && upperChar !== lowerChar) {
32
+ const prevCharacterIsUppercase = prevChar === prevUpperChar && prevUpperChar !== prevLowerChar;
33
+ // If underscoreBetweenUppercaseLetters is true, we always place an underscore
34
+ // before consecutive uppercase letters (e.g. "fooBAR" becomes "foo_b_a_r").
35
+ // Otherwise, we don't (e.g. "fooBAR" becomes "foo_bar").
36
+ if (underscoreBetweenUppercaseLetters || !prevCharacterIsUppercase) {
37
+ out += '_' + lowerChar;
38
+ }
39
+ else {
40
+ out += lowerChar;
41
+ }
42
+ }
43
+ else {
44
+ out += char;
45
+ }
46
+ }
47
+ if (upperCase) {
48
+ return out.toUpperCase();
49
+ }
50
+ else {
51
+ return out;
52
+ }
53
+ });
54
+ }
55
+ exports.createSnakeCaseMapper = createSnakeCaseMapper;
56
+ /**
57
+ * Creates a function that transforms snake case strings to camel case.
58
+ */
59
+ function createCamelCaseMapper({ upperCase = false, } = {}) {
60
+ return memoize((str) => {
61
+ if (str.length === 0) {
62
+ return str;
63
+ }
64
+ if (upperCase && isAllUpperCaseSnakeCase(str)) {
65
+ // Only convert to lower case if the string is all upper
66
+ // case snake_case. This allows camelCase strings to go
67
+ // through without changing.
68
+ str = str.toLowerCase();
69
+ }
70
+ let out = str[0];
71
+ for (let i = 1, l = str.length; i < l; ++i) {
72
+ const char = str[i];
73
+ const prevChar = str[i - 1];
74
+ if (char !== '_') {
75
+ if (prevChar === '_') {
76
+ out += char.toUpperCase();
77
+ }
78
+ else {
79
+ out += char;
80
+ }
81
+ }
82
+ }
83
+ return out;
84
+ });
85
+ }
86
+ exports.createCamelCaseMapper = createCamelCaseMapper;
87
+ function isAllUpperCaseSnakeCase(str) {
88
+ for (let i = 1, l = str.length; i < l; ++i) {
89
+ const char = str[i];
90
+ if (char !== '_' && char !== char.toUpperCase()) {
91
+ return false;
92
+ }
93
+ }
94
+ return true;
95
+ }
96
+ function isDigit(char) {
97
+ return char >= '0' && char <= '9';
98
+ }
99
+ function memoize(func) {
100
+ const cache = new Map();
101
+ return (str) => {
102
+ let mapped = cache.get(str);
103
+ if (!mapped) {
104
+ mapped = func(str);
105
+ cache.set(str, mapped);
106
+ }
107
+ return mapped;
108
+ };
109
+ }
@@ -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
  * }
@@ -1583,7 +1583,7 @@ export declare class QueryBuilder<DB, TB extends keyof DB, O = {}> implements Op
1583
1583
  */
1584
1584
  unionAll(expression: UnionExpression<DB, O>): QueryBuilder<DB, TB, O>;
1585
1585
  /**
1586
- * Simply calls the given method passing `this` as the only argument.
1586
+ * Simply calls the given function passing `this` as the only argument.
1587
1587
  *
1588
1588
  * This method can be useful when adding optional method calls:
1589
1589
  *
@@ -819,7 +819,7 @@ class QueryBuilder {
819
819
  });
820
820
  }
821
821
  /**
822
- * Simply calls the given method passing `this` as the only argument.
822
+ * Simply calls the given function passing `this` as the only argument.
823
823
  *
824
824
  * This method can be useful when adding optional method calls:
825
825
  *
@@ -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;
@@ -18,6 +18,12 @@ class DefaultQueryExecutor extends query_executor_js_1.QueryExecutor {
18
18
  return connection.executeQuery(compiledQuery);
19
19
  });
20
20
  }
21
+ withPlugin(plugin) {
22
+ return new DefaultQueryExecutor(this.#compiler, this.#connectionProvider, [
23
+ ...this.plugins,
24
+ plugin,
25
+ ]);
26
+ }
21
27
  withPluginAtFront(plugin) {
22
28
  return new DefaultQueryExecutor(this.#compiler, this.#connectionProvider, [
23
29
  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
  }
@@ -17,6 +17,9 @@ class NoopQueryExecutor extends query_executor_js_1.QueryExecutor {
17
17
  withConnectionProvider() {
18
18
  throw new Error('this query cannot have a connection provider');
19
19
  }
20
+ withPlugin(plugin) {
21
+ return new NoopQueryExecutor([...this.plugins, plugin]);
22
+ }
20
23
  withPluginAtFront(plugin) {
21
24
  return new NoopQueryExecutor([plugin, ...this.plugins]);
22
25
  }
@@ -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
  */
@@ -1,8 +1,19 @@
1
1
  import { ArrayItemType } from './type-utils.js';
2
- export declare const LOG_LEVELS: readonly ["query"];
2
+ export declare const LOG_LEVELS: readonly ["query", "error"];
3
3
  export declare type LogLevel = ArrayItemType<typeof LOG_LEVELS>;
4
4
  export declare class Log {
5
5
  #private;
6
6
  constructor(levels: ReadonlyArray<LogLevel>);
7
- query(callback: (log: (message: string) => void) => void): void;
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;
8
19
  }
@@ -1,21 +1,37 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Log = exports.LOG_LEVELS = void 0;
4
- exports.LOG_LEVELS = ['query'];
4
+ const object_utils_js_1 = require("./object-utils.js");
5
+ exports.LOG_LEVELS = ['query', 'error'];
5
6
  class Log {
6
7
  #levels;
7
8
  constructor(levels) {
8
- this.#levels = {
9
+ this.#levels = (0, object_utils_js_1.freeze)({
9
10
  query: levels.includes('query'),
10
- };
11
+ error: levels.includes('error'),
12
+ });
11
13
  }
12
- query(callback) {
14
+ query(getEvent) {
13
15
  if (this.#levels.query) {
14
- callback(this.#query);
16
+ this.#defaultQuery(getEvent());
15
17
  }
16
18
  }
17
- #query(message) {
18
- console.log(`kysely:query: ${message}`);
19
+ error(getEvent) {
20
+ if (this.#levels.error) {
21
+ this.#defaultError(getEvent());
22
+ }
23
+ }
24
+ #defaultQuery(event) {
25
+ console.log(`kysely:query: ${event.sql}`);
26
+ console.log(`kysely:query: duration: ${event.queryDurationMillis.toFixed(1)}ms`);
27
+ }
28
+ #defaultError(event) {
29
+ if (event.error instanceof Error) {
30
+ console.error(`kysely:error: ${event.error.stack ?? event.error.message}`);
31
+ }
32
+ else {
33
+ console.error(`kysely:error: ${event}`);
34
+ }
19
35
  }
20
36
  }
21
37
  exports.Log = Log;
@@ -185,6 +185,8 @@ export interface MysqlDialectConfig {
185
185
  keepAliveInitialDelay?: number;
186
186
  /**
187
187
  * Called once for each created connection.
188
+ *
189
+ * This is a Kysely specific feature and does not come from the `pg` module.
188
190
  */
189
191
  onCreateConnection?: (connection: DatabaseConnection) => Promise<void>;
190
192
  }
@@ -115,6 +115,8 @@ export interface PostgresDialectConfig {
115
115
  application_name?: string;
116
116
  /**
117
117
  * Called once for each created connection.
118
+ *
119
+ * This is a Kysely specific feature and does not come from the `pg` module.
118
120
  */
119
121
  onCreateConnection?: (connection: DatabaseConnection) => Promise<void>;
120
122
  keepAlive?: boolean;
@@ -13,10 +13,10 @@ export class PostgresDriver {
13
13
  // installed. As you can see, there IS an import from `pg` at the
14
14
  // top level too, but that's only for types. It doesn't get compiled
15
15
  // into javascript. You can check the built javascript code.
16
- const PoolConstrucor = await importPgPool();
16
+ const PoolConstructor = await importPgPool();
17
17
  // Use the `pg` module's own pool. All drivers should use the
18
18
  // pool provided by the database library if possible.
19
- this.#pool = new PoolConstrucor(this.#config);
19
+ this.#pool = new PoolConstructor(this.#config);
20
20
  }
21
21
  async acquireConnection() {
22
22
  const client = await this.#pool.connect();