kysely 0.16.5 → 0.16.9

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 (92) hide show
  1. package/README.md +139 -14
  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 +68 -0
  9. package/dist/cjs/driver/dummy-driver.js +62 -0
  10. package/dist/cjs/driver/runtime-driver.d.ts +1 -1
  11. package/dist/cjs/driver/runtime-driver.js +30 -33
  12. package/dist/cjs/index-nodeless.d.ts +2 -0
  13. package/dist/cjs/index-nodeless.js +2 -0
  14. package/dist/cjs/kysely.d.ts +8 -6
  15. package/dist/cjs/kysely.js +8 -6
  16. package/dist/cjs/migration/migrator.d.ts +22 -0
  17. package/dist/cjs/migration/migrator.js +23 -1
  18. package/dist/cjs/plugin/deduplicate-joins/deduplicate-joins-plugin.d.ts +48 -0
  19. package/dist/cjs/plugin/deduplicate-joins/deduplicate-joins-plugin.js +19 -0
  20. package/dist/cjs/plugin/deduplicate-joins/deduplicate-joins-transformer.d.ts +9 -0
  21. package/dist/cjs/plugin/deduplicate-joins/deduplicate-joins-transformer.js +42 -0
  22. package/dist/cjs/plugin/{immediate-value.ts → immediate-value}/immediate-value-plugin.d.ts +0 -0
  23. package/dist/cjs/plugin/{immediate-value.ts → immediate-value}/immediate-value-plugin.js +0 -0
  24. package/dist/cjs/plugin/{immediate-value.ts → immediate-value}/immediate-value-transformer.d.ts +0 -0
  25. package/dist/cjs/plugin/{immediate-value.ts → immediate-value}/immediate-value-transformer.js +0 -0
  26. package/dist/cjs/query-builder/delete-query-builder.d.ts +51 -9
  27. package/dist/cjs/query-builder/delete-query-builder.js +56 -8
  28. package/dist/cjs/query-builder/function-builder.d.ts +29 -5
  29. package/dist/cjs/query-builder/function-builder.js +31 -7
  30. package/dist/cjs/query-builder/insert-query-builder.d.ts +53 -11
  31. package/dist/cjs/query-builder/insert-query-builder.js +58 -10
  32. package/dist/cjs/query-builder/select-query-builder.d.ts +58 -16
  33. package/dist/cjs/query-builder/select-query-builder.js +64 -15
  34. package/dist/cjs/query-builder/update-query-builder.d.ts +52 -9
  35. package/dist/cjs/query-builder/update-query-builder.js +57 -8
  36. package/dist/cjs/query-creator.d.ts +2 -2
  37. package/dist/cjs/query-creator.js +2 -2
  38. package/dist/cjs/query-executor/query-executor.js +3 -2
  39. package/dist/cjs/raw-builder/raw-builder.d.ts +2 -2
  40. package/dist/cjs/raw-builder/raw-builder.js +8 -1
  41. package/dist/cjs/schema/create-view-builder.js +1 -1
  42. package/dist/cjs/util/log.d.ts +1 -0
  43. package/dist/cjs/util/log.js +3 -0
  44. package/dist/cjs/util/object-utils.d.ts +1 -0
  45. package/dist/cjs/util/object-utils.js +50 -1
  46. package/dist/cjs/util/type-utils.d.ts +21 -0
  47. package/dist/esm/dialect/mysql/mysql-dialect.js +2 -1
  48. package/dist/esm/dialect/mysql/mysql-driver.js +2 -2
  49. package/dist/esm/dialect/postgres/postgres-dialect.js +2 -1
  50. package/dist/esm/dialect/postgres/postgres-driver.js +2 -2
  51. package/dist/esm/dialect/sqlite/sqlite-dialect.js +2 -1
  52. package/dist/esm/dialect/sqlite/sqlite-driver.js +2 -2
  53. package/dist/esm/driver/dummy-driver.d.ts +68 -0
  54. package/dist/esm/driver/dummy-driver.js +59 -0
  55. package/dist/esm/driver/runtime-driver.d.ts +1 -1
  56. package/dist/esm/driver/runtime-driver.js +29 -32
  57. package/dist/esm/index-nodeless.d.ts +2 -0
  58. package/dist/esm/index-nodeless.js +2 -0
  59. package/dist/esm/kysely.d.ts +8 -6
  60. package/dist/esm/kysely.js +8 -6
  61. package/dist/esm/migration/migrator.d.ts +22 -0
  62. package/dist/esm/migration/migrator.js +23 -1
  63. package/dist/esm/plugin/deduplicate-joins/deduplicate-joins-plugin.d.ts +48 -0
  64. package/dist/esm/plugin/deduplicate-joins/deduplicate-joins-plugin.js +16 -0
  65. package/dist/esm/plugin/deduplicate-joins/deduplicate-joins-transformer.d.ts +9 -0
  66. package/dist/esm/plugin/deduplicate-joins/deduplicate-joins-transformer.js +39 -0
  67. package/dist/esm/plugin/{immediate-value.ts → immediate-value}/immediate-value-plugin.d.ts +0 -0
  68. package/dist/esm/plugin/{immediate-value.ts → immediate-value}/immediate-value-plugin.js +0 -0
  69. package/dist/esm/plugin/{immediate-value.ts → immediate-value}/immediate-value-transformer.d.ts +0 -0
  70. package/dist/esm/plugin/{immediate-value.ts → immediate-value}/immediate-value-transformer.js +0 -0
  71. package/dist/esm/query-builder/delete-query-builder.d.ts +51 -9
  72. package/dist/esm/query-builder/delete-query-builder.js +56 -8
  73. package/dist/esm/query-builder/function-builder.d.ts +29 -5
  74. package/dist/esm/query-builder/function-builder.js +31 -7
  75. package/dist/esm/query-builder/insert-query-builder.d.ts +53 -11
  76. package/dist/esm/query-builder/insert-query-builder.js +58 -10
  77. package/dist/esm/query-builder/select-query-builder.d.ts +58 -16
  78. package/dist/esm/query-builder/select-query-builder.js +64 -15
  79. package/dist/esm/query-builder/update-query-builder.d.ts +52 -9
  80. package/dist/esm/query-builder/update-query-builder.js +57 -8
  81. package/dist/esm/query-creator.d.ts +2 -2
  82. package/dist/esm/query-creator.js +2 -2
  83. package/dist/esm/query-executor/query-executor.js +3 -2
  84. package/dist/esm/raw-builder/raw-builder.d.ts +2 -2
  85. package/dist/esm/raw-builder/raw-builder.js +8 -1
  86. package/dist/esm/schema/create-view-builder.js +1 -1
  87. package/dist/esm/util/log.d.ts +1 -0
  88. package/dist/esm/util/log.js +3 -0
  89. package/dist/esm/util/object-utils.d.ts +1 -0
  90. package/dist/esm/util/object-utils.js +48 -0
  91. package/dist/esm/util/type-utils.d.ts +21 -0
  92. package/package.json +11 -5
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.noop = exports.isReadonlyArray = exports.asReadonlyArray = exports.asArray = exports.freeze = exports.getLast = exports.isObject = exports.isFunction = exports.isBuffer = exports.isBigInt = exports.isDate = exports.isNull = exports.isBoolean = exports.isNumber = exports.isString = exports.isEmpty = void 0;
3
+ exports.compare = exports.noop = exports.isReadonlyArray = exports.asReadonlyArray = exports.asArray = exports.freeze = exports.getLast = exports.isObject = exports.isFunction = exports.isBuffer = exports.isBigInt = exports.isDate = exports.isNull = exports.isBoolean = exports.isNumber = exports.isString = exports.isEmpty = void 0;
4
4
  function isEmpty(obj) {
5
5
  if (Array.isArray(obj) || isString(obj) || isBuffer(obj)) {
6
6
  return obj.length === 0;
@@ -83,3 +83,52 @@ function noop(obj) {
83
83
  return obj;
84
84
  }
85
85
  exports.noop = noop;
86
+ function compare(obj1, obj2) {
87
+ if (isReadonlyArray(obj1) && isReadonlyArray(obj2)) {
88
+ return compareArrays(obj1, obj2);
89
+ }
90
+ else if (isObject(obj1) && isObject(obj2)) {
91
+ return compareObjects(obj1, obj2);
92
+ }
93
+ return obj1 === obj2;
94
+ }
95
+ exports.compare = compare;
96
+ function compareArrays(arr1, arr2) {
97
+ if (arr1.length !== arr2.length) {
98
+ return false;
99
+ }
100
+ for (let i = 0; i < arr1.length; ++i) {
101
+ if (!compare(arr1[i], arr2[i])) {
102
+ return false;
103
+ }
104
+ }
105
+ return true;
106
+ }
107
+ function compareObjects(obj1, obj2) {
108
+ if (isBuffer(obj1) && isBuffer(obj2)) {
109
+ return compareBuffers(obj1, obj2);
110
+ }
111
+ else if (isDate(obj1) && isDate(obj2)) {
112
+ return compareDates(obj1, obj2);
113
+ }
114
+ return compareGenericObjects(obj1, obj2);
115
+ }
116
+ function compareBuffers(buf1, buf2) {
117
+ return Buffer.compare(buf1, buf2) === 0;
118
+ }
119
+ function compareDates(date1, date2) {
120
+ return date1.getTime() === date2.getTime();
121
+ }
122
+ function compareGenericObjects(obj1, obj2) {
123
+ const keys1 = Object.keys(obj1);
124
+ const keys2 = Object.keys(obj2);
125
+ if (keys1.length !== keys2.length) {
126
+ return false;
127
+ }
128
+ for (const key of keys1) {
129
+ if (!compare(obj1[key], obj2[key])) {
130
+ return false;
131
+ }
132
+ }
133
+ return true;
134
+ }
@@ -111,3 +111,24 @@ export declare type UnknownRow = Record<string, unknown>;
111
111
  export declare type Nullable<T> = {
112
112
  [P in keyof T]: T[P] | null;
113
113
  };
114
+ /**
115
+ * Takes all properties from T1 and merges all properties from T2
116
+ * that don't exist in T1 as optional properties.
117
+ *
118
+ * Example:
119
+ *
120
+ * interface Person {
121
+ * name: string
122
+ * age: number
123
+ * }
124
+ *
125
+ * interface Pet {
126
+ * name: string
127
+ * species: 'cat' | 'dog'
128
+ * }
129
+ *
130
+ * type Merged = MergePartial<Person, Pet>
131
+ *
132
+ * // { name: string, age: number, species?: 'cat' | 'dog' }
133
+ */
134
+ export declare type MergePartial<T1, T2> = T1 & Partial<Omit<T2, keyof T1>>;
@@ -3,6 +3,7 @@ import { MysqlDriver } from './mysql-driver.js';
3
3
  import { MysqlQueryCompiler } from './mysql-query-compiler.js';
4
4
  import { MysqlIntrospector } from './mysql-introspector.js';
5
5
  import { MysqlAdapter } from './mysql-adapter.js';
6
+ import { freeze } from '../../util/object-utils.js';
6
7
  /**
7
8
  * MySQL dialect that uses the [mysql2](https://github.com/sidorares/node-mysql2#readme) library.
8
9
  *
@@ -13,7 +14,7 @@ import { MysqlAdapter } from './mysql-adapter.js';
13
14
  export class MysqlDialect {
14
15
  #config;
15
16
  constructor(config) {
16
- this.#config = config;
17
+ this.#config = freeze({ ...config });
17
18
  }
18
19
  createDriver() {
19
20
  return new MysqlDriver(this.#config);
@@ -1,13 +1,13 @@
1
1
  /// <reference types="./mysql-driver.d.ts" />
2
2
  import { CompiledQuery } from '../../query-compiler/compiled-query.js';
3
- import { isFunction, isObject } from '../../util/object-utils.js';
3
+ import { isFunction, isObject, freeze } from '../../util/object-utils.js';
4
4
  const PRIVATE_RELEASE_METHOD = Symbol();
5
5
  export class MysqlDriver {
6
6
  #config;
7
7
  #connections = new WeakMap();
8
8
  #pool;
9
9
  constructor(config) {
10
- this.#config = config;
10
+ this.#config = freeze({ ...config });
11
11
  }
12
12
  async init() {
13
13
  // Import the `mysql2` module here instead at the top of the file
@@ -3,6 +3,7 @@ import { PostgresDriver } from './postgres-driver.js';
3
3
  import { PostgresIntrospector } from './postgres-introspector.js';
4
4
  import { PostgresQueryCompiler } from './postgres-query-compiler.js';
5
5
  import { PostgresAdapter } from './postgres-adapter.js';
6
+ import { freeze } from '../../util/object-utils.js';
6
7
  /**
7
8
  * PostgreSQL dialect that uses the [pg](https://node-postgres.com/) library.
8
9
  *
@@ -16,7 +17,7 @@ import { PostgresAdapter } from './postgres-adapter.js';
16
17
  export class PostgresDialect {
17
18
  #config;
18
19
  constructor(config) {
19
- this.#config = config;
20
+ this.#config = freeze({ ...config });
20
21
  }
21
22
  createDriver() {
22
23
  return new PostgresDriver(this.#config);
@@ -1,13 +1,13 @@
1
1
  /// <reference types="./postgres-driver.d.ts" />
2
2
  import { CompiledQuery } from '../../query-compiler/compiled-query.js';
3
- import { isFunction } from '../../util/object-utils.js';
3
+ import { isFunction, freeze } from '../../util/object-utils.js';
4
4
  const PRIVATE_RELEASE_METHOD = Symbol();
5
5
  export class PostgresDriver {
6
6
  #config;
7
7
  #connections = new WeakMap();
8
8
  #pool = null;
9
9
  constructor(config) {
10
- this.#config = config;
10
+ this.#config = freeze({ ...config });
11
11
  }
12
12
  async init() {
13
13
  // Import the `pg` module here instead at the top of the file
@@ -3,6 +3,7 @@ import { SqliteDriver } from './sqlite-driver.js';
3
3
  import { SqliteQueryCompiler } from './sqlite-query-compiler.js';
4
4
  import { SqliteIntrospector } from './sqlite-introspector.js';
5
5
  import { SqliteAdapter } from './sqlite-adapter.js';
6
+ import { freeze } from '../../util/object-utils.js';
6
7
  /**
7
8
  * SQLite dialect that uses the [better-sqlite3](https://github.com/JoshuaWise/better-sqlite3) library.
8
9
  *
@@ -13,7 +14,7 @@ import { SqliteAdapter } from './sqlite-adapter.js';
13
14
  export class SqliteDialect {
14
15
  #config;
15
16
  constructor(config) {
16
- this.#config = config;
17
+ this.#config = freeze({ ...config });
17
18
  }
18
19
  createDriver() {
19
20
  return new SqliteDriver(this.#config);
@@ -1,13 +1,13 @@
1
1
  /// <reference types="./sqlite-driver.d.ts" />
2
2
  import { CompiledQuery } from '../../query-compiler/compiled-query.js';
3
- import { isBoolean, isFunction, isNumber } from '../../util/object-utils.js';
3
+ import { freeze, isBoolean, isFunction, isNumber, } from '../../util/object-utils.js';
4
4
  export class SqliteDriver {
5
5
  #config;
6
6
  #connectionMutex = new ConnectionMutex();
7
7
  #db;
8
8
  #connection;
9
9
  constructor(config) {
10
- this.#config = config;
10
+ this.#config = freeze({ ...config });
11
11
  }
12
12
  async init() {
13
13
  // Import the `better-sqlite3` module here instead at the top of the file
@@ -0,0 +1,68 @@
1
+ import { DatabaseConnection } from './database-connection.js';
2
+ import { Driver } from './driver.js';
3
+ /**
4
+ * A driver that does absolutely nothing.
5
+ *
6
+ * You can use this to create Kysely instances solely for building queries
7
+ *
8
+ * ### Examples
9
+ *
10
+ * This example creates a Kysely instance for building postgres queries:
11
+ *
12
+ * ```ts
13
+ * const db = new Kysely<Database>({
14
+ * dialect: {
15
+ * createAdapter() {
16
+ * return new PostgresAdapter()
17
+ * },
18
+ * createDriver() {
19
+ * return new DummyDriver()
20
+ * },
21
+ * createIntrospector(db: Kysely<any>) {
22
+ * return new PostgresIntrospector(db)
23
+ * },
24
+ * createQueryCompiler() {
25
+ * return new PostgresQueryCompiler()
26
+ * },
27
+ * },
28
+ * })
29
+ * ```
30
+ */
31
+ export declare class DummyDriver implements Driver {
32
+ /**
33
+ * Initializes the driver.
34
+ *
35
+ * After calling this method the driver should be usable and `acquireConnection` etc.
36
+ * methods should be callable.
37
+ *
38
+ * IMPORTANT: The underlying database engine driver (like [pg](https://node-postgres.com/))
39
+ * should be imported inside this function, not at the top of the driver file! This is
40
+ * important so that Kysely is usable without installing all database driver libraries
41
+ * it supports.
42
+ */
43
+ init(): Promise<void>;
44
+ /**
45
+ * Acquires a new connection from the pool.
46
+ */
47
+ acquireConnection(): Promise<DatabaseConnection>;
48
+ /**
49
+ * Begins a transaction.
50
+ */
51
+ beginTransaction(): Promise<void>;
52
+ /**
53
+ * Commits a transaction.
54
+ */
55
+ commitTransaction(): Promise<void>;
56
+ /**
57
+ * Rolls back a transaction.
58
+ */
59
+ rollbackTransaction(): Promise<void>;
60
+ /**
61
+ * Releases a connection back to the pool.
62
+ */
63
+ releaseConnection(): Promise<void>;
64
+ /**
65
+ * Destroys the driver and releases all resources.
66
+ */
67
+ destroy(): Promise<void>;
68
+ }
@@ -0,0 +1,59 @@
1
+ /// <reference types="./dummy-driver.d.ts" />
2
+ /**
3
+ * A driver that does absolutely nothing.
4
+ *
5
+ * You can use this to create Kysely instances solely for building queries
6
+ *
7
+ * ### Examples
8
+ *
9
+ * This example creates a Kysely instance for building postgres queries:
10
+ *
11
+ * ```ts
12
+ * const db = new Kysely<Database>({
13
+ * dialect: {
14
+ * createAdapter() {
15
+ * return new PostgresAdapter()
16
+ * },
17
+ * createDriver() {
18
+ * return new DummyDriver()
19
+ * },
20
+ * createIntrospector(db: Kysely<any>) {
21
+ * return new PostgresIntrospector(db)
22
+ * },
23
+ * createQueryCompiler() {
24
+ * return new PostgresQueryCompiler()
25
+ * },
26
+ * },
27
+ * })
28
+ * ```
29
+ */
30
+ export class DummyDriver {
31
+ async init() {
32
+ // Nothing to do here.
33
+ }
34
+ async acquireConnection() {
35
+ return new DummyConnection();
36
+ }
37
+ async beginTransaction() {
38
+ // Nothing to do here.
39
+ }
40
+ async commitTransaction() {
41
+ // Nothing to do here.
42
+ }
43
+ async rollbackTransaction() {
44
+ // Nothing to do here.
45
+ }
46
+ async releaseConnection() {
47
+ // Nothing to do here.
48
+ }
49
+ async destroy() {
50
+ // Nothing to do here.
51
+ }
52
+ }
53
+ class DummyConnection {
54
+ async executeQuery() {
55
+ return {
56
+ rows: [],
57
+ };
58
+ }
59
+ }
@@ -28,7 +28,7 @@ export declare class RuntimeDriver implements Driver {
28
28
  /**
29
29
  * Releases a connection back to the pool.
30
30
  */
31
- releaseConnection(runtimeConnection: DatabaseConnection): Promise<void>;
31
+ releaseConnection(connection: DatabaseConnection): Promise<void>;
32
32
  /**
33
33
  * Begins a transaction.
34
34
  */
@@ -10,7 +10,7 @@ export class RuntimeDriver {
10
10
  #log;
11
11
  #initPromise;
12
12
  #destroyPromise;
13
- #connections = new WeakMap();
13
+ #connections = new WeakSet();
14
14
  constructor(driver, log) {
15
15
  this.#driver = driver;
16
16
  this.#log = log;
@@ -27,17 +27,16 @@ export class RuntimeDriver {
27
27
  async acquireConnection() {
28
28
  await this.init();
29
29
  const connection = await this.#driver.acquireConnection();
30
- let runtimeConnection = this.#connections.get(connection);
31
- if (!runtimeConnection) {
32
- runtimeConnection = new RuntimeConnection(connection, this.#log);
33
- this.#connections.set(connection, runtimeConnection);
30
+ if (!this.#connections.has(connection)) {
31
+ if (this.#needsLogging()) {
32
+ this.#addLogging(connection);
33
+ }
34
+ this.#connections.add(connection);
34
35
  }
35
- return runtimeConnection;
36
+ return connection;
36
37
  }
37
- async releaseConnection(runtimeConnection) {
38
- if (runtimeConnection instanceof RuntimeConnection) {
39
- await this.#driver.releaseConnection(runtimeConnection.connection);
40
- }
38
+ async releaseConnection(connection) {
39
+ await this.#driver.releaseConnection(connection);
41
40
  }
42
41
  beginTransaction(connection, settings) {
43
42
  return this.#driver.beginTransaction(connection, settings);
@@ -61,29 +60,27 @@ export class RuntimeDriver {
61
60
  }
62
61
  await this.#destroyPromise;
63
62
  }
64
- }
65
- class RuntimeConnection {
66
- #connection;
67
- #log;
68
- get connection() {
69
- return this.#connection;
70
- }
71
- constructor(connection, log) {
72
- this.#connection = connection;
73
- this.#log = log;
63
+ #needsLogging() {
64
+ return (this.#log.isLevelEnabled('query') || this.#log.isLevelEnabled('error'));
74
65
  }
75
- async executeQuery(compiledQuery) {
76
- const startTime = performanceNow();
77
- try {
78
- return await this.#connection.executeQuery(compiledQuery);
79
- }
80
- catch (error) {
81
- this.#logError(error);
82
- throw error;
83
- }
84
- finally {
85
- this.#logQuery(compiledQuery, startTime);
86
- }
66
+ // This method monkey patches the database connection's executeQuery method
67
+ // by adding logging code around it. Monkey patching is not pretty, but it's
68
+ // the best option in this case.
69
+ #addLogging(connection) {
70
+ const executeQuery = connection.executeQuery;
71
+ connection.executeQuery = async (compiledQuery) => {
72
+ const startTime = performanceNow();
73
+ try {
74
+ return await executeQuery.call(connection, compiledQuery);
75
+ }
76
+ catch (error) {
77
+ this.#logError(error);
78
+ throw error;
79
+ }
80
+ finally {
81
+ this.#logQuery(compiledQuery, startTime);
82
+ }
83
+ };
87
84
  }
88
85
  #logError(error) {
89
86
  this.#log.error(() => ({
@@ -40,6 +40,7 @@ export * from './driver/database-connection.js';
40
40
  export * from './driver/connection-provider.js';
41
41
  export * from './driver/default-connection-provider.js';
42
42
  export * from './driver/single-connection-provider.js';
43
+ export * from './driver/dummy-driver.js';
43
44
  export * from './dialect/dialect.js';
44
45
  export * from './dialect/dialect-adapter.js';
45
46
  export * from './dialect/dialect-adapter-base.js';
@@ -58,6 +59,7 @@ export * from './query-compiler/query-compiler.js';
58
59
  export * from './migration/migrator.js';
59
60
  export * from './plugin/kysely-plugin.js';
60
61
  export * from './plugin/camel-case/camel-case-plugin.js';
62
+ export * from './plugin/deduplicate-joins/deduplicate-joins-plugin.js';
61
63
  export * from './operation-node/add-column-node.js';
62
64
  export * from './operation-node/add-constraint-node.js';
63
65
  export * from './operation-node/alias-node.js';
@@ -41,6 +41,7 @@ export * from './driver/database-connection.js';
41
41
  export * from './driver/connection-provider.js';
42
42
  export * from './driver/default-connection-provider.js';
43
43
  export * from './driver/single-connection-provider.js';
44
+ export * from './driver/dummy-driver.js';
44
45
  export * from './dialect/dialect.js';
45
46
  export * from './dialect/dialect-adapter.js';
46
47
  export * from './dialect/dialect-adapter-base.js';
@@ -59,6 +60,7 @@ export * from './query-compiler/query-compiler.js';
59
60
  export * from './migration/migrator.js';
60
61
  export * from './plugin/kysely-plugin.js';
61
62
  export * from './plugin/camel-case/camel-case-plugin.js';
63
+ export * from './plugin/deduplicate-joins/deduplicate-joins-plugin.js';
62
64
  export * from './operation-node/add-column-node.js';
63
65
  export * from './operation-node/add-constraint-node.js';
64
66
  export * from './operation-node/alias-node.js';
@@ -22,22 +22,24 @@ import { DialectAdapter } from './dialect/dialect-adapter.js';
22
22
  * This example assumes your database has tables `person` and `pet`:
23
23
  *
24
24
  * ```ts
25
- * interface Person {
26
- * id: number
25
+ * import { Kysely, Generated, PostgresDialect } from 'kysely'
26
+ *
27
+ * interface PersonTable {
28
+ * id: Generated<number>
27
29
  * first_name: string
28
30
  * last_name: string
29
31
  * }
30
32
  *
31
- * interface Pet {
32
- * id: number
33
+ * interface PetTable {
34
+ * id: Generated<number>
33
35
  * owner_id: number
34
36
  * name: string
35
37
  * species 'cat' | 'dog'
36
38
  * }
37
39
  *
38
40
  * interface Database {
39
- * person: Person,
40
- * pet: Pet
41
+ * person: PersonTable,
42
+ * pet: PetTable
41
43
  * }
42
44
  *
43
45
  * const db = new Kysely<Database>({
@@ -24,22 +24,24 @@ import { PRIVATE_ADAPTER } from './util/private-symbols.js';
24
24
  * This example assumes your database has tables `person` and `pet`:
25
25
  *
26
26
  * ```ts
27
- * interface Person {
28
- * id: number
27
+ * import { Kysely, Generated, PostgresDialect } from 'kysely'
28
+ *
29
+ * interface PersonTable {
30
+ * id: Generated<number>
29
31
  * first_name: string
30
32
  * last_name: string
31
33
  * }
32
34
  *
33
- * interface Pet {
34
- * id: number
35
+ * interface PetTable {
36
+ * id: Generated<number>
35
37
  * owner_id: number
36
38
  * name: string
37
39
  * species 'cat' | 'dog'
38
40
  * }
39
41
  *
40
42
  * interface Database {
41
- * person: Person,
42
- * pet: Pet
43
+ * person: PersonTable,
44
+ * pet: PetTable
43
45
  * }
44
46
  *
45
47
  * const db = new Kysely<Database>({
@@ -36,6 +36,12 @@ export interface Migration {
36
36
  export declare class Migrator {
37
37
  #private;
38
38
  constructor(props: MigratorProps);
39
+ /**
40
+ * Returns a {@link MigrationInfo} object for each migration.
41
+ *
42
+ * The returned array is sorted by migration name.
43
+ */
44
+ getMigrations(): Promise<ReadonlyArray<MigrationInfo>>;
39
45
  /**
40
46
  * Runs all migrations that have not yet been run.
41
47
  *
@@ -219,3 +225,19 @@ export interface MigrationProvider {
219
225
  export interface NoMigrations {
220
226
  readonly __noMigrations__: true;
221
227
  }
228
+ export interface MigrationInfo {
229
+ /**
230
+ * Name of the migration.
231
+ */
232
+ name: string;
233
+ /**
234
+ * The actual migration.
235
+ */
236
+ migration: Migration;
237
+ /**
238
+ * When was the migration executed.
239
+ *
240
+ * If this is undefined, the migration hasn't been executed yet.
241
+ */
242
+ executedAt?: Date;
243
+ }
@@ -30,6 +30,28 @@ export class Migrator {
30
30
  constructor(props) {
31
31
  this.#props = freeze(props);
32
32
  }
33
+ /**
34
+ * Returns a {@link MigrationInfo} object for each migration.
35
+ *
36
+ * The returned array is sorted by migration name.
37
+ */
38
+ async getMigrations() {
39
+ const executedMigrations = (await this.#doesTableExists(MIGRATION_TABLE))
40
+ ? await this.#props.db
41
+ .selectFrom(MIGRATION_TABLE)
42
+ .select(['name', 'timestamp'])
43
+ .execute()
44
+ : [];
45
+ const migrations = await this.#resolveMigrations();
46
+ return migrations.map(({ name, ...migration }) => {
47
+ const executed = executedMigrations.find((it) => it.name === name);
48
+ return {
49
+ name,
50
+ migration,
51
+ executedAt: executed ? new Date(executed.timestamp) : undefined,
52
+ };
53
+ });
54
+ }
33
55
  /**
34
56
  * Runs all migrations that have not yet been run.
35
57
  *
@@ -213,7 +235,7 @@ export class Migrator {
213
235
  try {
214
236
  await this.#props.db
215
237
  .insertInto(MIGRATION_LOCK_TABLE)
216
- .values({ id: MIGRATION_LOCK_ID })
238
+ .values({ id: MIGRATION_LOCK_ID, is_locked: 0 })
217
239
  .execute();
218
240
  }
219
241
  catch (error) {
@@ -0,0 +1,48 @@
1
+ import { QueryResult } from '../../driver/database-connection.js';
2
+ import { RootOperationNode } from '../../query-compiler/query-compiler.js';
3
+ import { UnknownRow } from '../../util/type-utils.js';
4
+ import { KyselyPlugin, PluginTransformQueryArgs, PluginTransformResultArgs } from '../kysely-plugin.js';
5
+ /**
6
+ * Plugin that removes duplicate joins from queries.
7
+ *
8
+ * See [this recipe](https://github.com/koskimas/kysely/tree/master/recipes/deduplicate-joins.md)
9
+ */
10
+ export declare class DeduplicateJoinsPlugin implements KyselyPlugin {
11
+ #private;
12
+ /**
13
+ * This is called for each query before it is executed. You can modify the query by
14
+ * transforming its {@link OperationNode} tree provided in {@link PluginTransformQueryArgs.node | args.node}
15
+ * and returning the transformed tree. You'd usually want to use an {@link OperationNodeTransformer}
16
+ * for this.
17
+ *
18
+ * If you need to pass some query-related data between this method and `transformResult` you
19
+ * can use a `WeakMap` with {@link PluginTransformQueryArgs.queryId | args.queryId} as the key:
20
+ *
21
+ * ```ts
22
+ * const plugin = {
23
+ * data: new WeakMap<QueryId, SomeData>(),
24
+ *
25
+ * transformQuery(args: PluginTransformQueryArgs): RootOperationNode {
26
+ * this.data.set(args.queryId, something)
27
+ * return args.node
28
+ * },
29
+ *
30
+ * transformResult(args: PluginTransformResultArgs): QueryResult<UnknownRow> {
31
+ * const data = this.data.get(args.queryId)
32
+ * return args.result
33
+ * }
34
+ * }
35
+ * ```
36
+ *
37
+ * You should use a `WeakMap` instead of a `Map` or some other strong references because `transformQuery`
38
+ * is not always matched by a call to `transformResult` which would leave orphaned items in the map
39
+ * and cause a memory leak.
40
+ */
41
+ transformQuery(args: PluginTransformQueryArgs): RootOperationNode;
42
+ /**
43
+ * This method is called for each query after it has been executed. The result
44
+ * of the query can be accessed through {@link PluginTransformResultArgs.result | args.result}.
45
+ * You can modify the result and return the modifier result.
46
+ */
47
+ transformResult(args: PluginTransformResultArgs): Promise<QueryResult<UnknownRow>>;
48
+ }
@@ -0,0 +1,16 @@
1
+ /// <reference types="./deduplicate-joins-plugin.d.ts" />
2
+ import { DeduplicateJoinsTransformer } from './deduplicate-joins-transformer.js';
3
+ /**
4
+ * Plugin that removes duplicate joins from queries.
5
+ *
6
+ * See [this recipe](https://github.com/koskimas/kysely/tree/master/recipes/deduplicate-joins.md)
7
+ */
8
+ export class DeduplicateJoinsPlugin {
9
+ #transformer = new DeduplicateJoinsTransformer();
10
+ transformQuery(args) {
11
+ return this.#transformer.transformNode(args.node);
12
+ }
13
+ transformResult(args) {
14
+ return Promise.resolve(args.result);
15
+ }
16
+ }
@@ -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
+ }