kysely 0.27.4 → 0.27.5
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.
- package/.renovaterc.json +3 -0
- package/CONTRIBUTING.md +1 -1
- package/deno.check.d.ts +86 -0
- package/deno.check.json +21 -0
- package/dist/cjs/dialect/dialect-adapter-base.d.ts +11 -2
- package/dist/cjs/dialect/dialect-adapter.d.ts +11 -2
- package/dist/cjs/dialect/mssql/mssql-adapter.d.ts +11 -2
- package/dist/cjs/dialect/mssql/mssql-dialect-config.d.ts +37 -29
- package/dist/cjs/dialect/mssql/mssql-driver.js +20 -13
- package/dist/cjs/dialect/mysql/mysql-adapter.d.ts +11 -2
- package/dist/cjs/dialect/mysql/mysql-dialect-config.d.ts +4 -0
- package/dist/cjs/dialect/mysql/mysql-driver.js +3 -0
- package/dist/cjs/dialect/postgres/postgres-adapter.d.ts +11 -2
- package/dist/cjs/dialect/postgres/postgres-dialect-config.d.ts +10 -3
- package/dist/cjs/dialect/postgres/postgres-driver.js +3 -0
- package/dist/cjs/dialect/postgres/postgres-introspector.js +5 -1
- package/dist/cjs/dialect/sqlite/sqlite-adapter.d.ts +11 -2
- package/dist/cjs/driver/dummy-driver.d.ts +13 -12
- package/dist/cjs/driver/dummy-driver.js +13 -12
- package/dist/cjs/dynamic/dynamic.d.ts +6 -6
- package/dist/cjs/dynamic/dynamic.js +6 -6
- package/dist/cjs/expression/expression-builder.d.ts +152 -61
- package/dist/cjs/expression/expression-wrapper.d.ts +92 -23
- package/dist/cjs/expression/expression.d.ts +40 -5
- package/dist/cjs/helpers/mssql.d.ts +74 -14
- package/dist/cjs/helpers/mssql.js +74 -14
- package/dist/cjs/helpers/mysql.d.ts +14 -10
- package/dist/cjs/helpers/mysql.js +14 -10
- package/dist/cjs/helpers/postgres.d.ts +7 -4
- package/dist/cjs/helpers/postgres.js +7 -4
- package/dist/cjs/helpers/sqlite.d.ts +41 -16
- package/dist/cjs/helpers/sqlite.js +41 -16
- package/dist/cjs/kysely.d.ts +99 -41
- package/dist/cjs/kysely.js +60 -36
- package/dist/cjs/migration/file-migration-provider.d.ts +2 -2
- package/dist/cjs/migration/file-migration-provider.js +2 -2
- package/dist/cjs/migration/migrator.d.ts +82 -14
- package/dist/cjs/migration/migrator.js +82 -14
- package/dist/cjs/operation-node/aggregate-function-node.d.ts +4 -0
- package/dist/cjs/operation-node/aggregate-function-node.js +9 -0
- package/dist/cjs/operation-node/data-type-node.d.ts +1 -1
- package/dist/cjs/operation-node/data-type-node.js +12 -0
- package/dist/cjs/operation-node/delete-query-node.d.ts +1 -0
- package/dist/cjs/operation-node/insert-query-node.d.ts +1 -0
- package/dist/cjs/operation-node/merge-query-node.d.ts +1 -0
- package/dist/cjs/operation-node/operation-node-transformer.d.ts +9 -3
- package/dist/cjs/operation-node/operation-node-transformer.js +14 -3
- package/dist/cjs/operation-node/query-node.d.ts +4 -0
- package/dist/cjs/operation-node/query-node.js +8 -0
- package/dist/cjs/operation-node/select-query-node.d.ts +0 -1
- package/dist/cjs/operation-node/select-query-node.js +0 -8
- package/dist/cjs/operation-node/update-query-node.d.ts +1 -0
- package/dist/cjs/plugin/camel-case/camel-case-plugin.d.ts +52 -25
- package/dist/cjs/plugin/camel-case/camel-case-plugin.js +24 -19
- package/dist/cjs/plugin/deduplicate-joins/deduplicate-joins-plugin.d.ts +29 -7
- package/dist/cjs/plugin/deduplicate-joins/deduplicate-joins-plugin.js +1 -1
- package/dist/cjs/plugin/deduplicate-joins/deduplicate-joins-transformer.js +2 -2
- package/dist/cjs/plugin/immediate-value/immediate-value-plugin.d.ts +28 -6
- package/dist/cjs/plugin/kysely-plugin.d.ts +28 -6
- package/dist/cjs/plugin/noop-plugin.d.ts +28 -6
- package/dist/cjs/plugin/parse-json-results/parse-json-results-plugin.d.ts +62 -9
- package/dist/cjs/plugin/parse-json-results/parse-json-results-plugin.js +34 -3
- package/dist/cjs/plugin/with-schema/with-schema-plugin.d.ts +28 -6
- package/dist/cjs/query-builder/aggregate-function-builder.d.ts +43 -1
- package/dist/cjs/query-builder/aggregate-function-builder.js +30 -0
- package/dist/cjs/query-builder/delete-query-builder.d.ts +137 -45
- package/dist/cjs/query-builder/delete-query-builder.js +76 -26
- package/dist/cjs/query-builder/function-module.d.ts +35 -88
- package/dist/cjs/query-builder/insert-query-builder.d.ts +239 -65
- package/dist/cjs/query-builder/insert-query-builder.js +188 -52
- package/dist/cjs/query-builder/insert-result.d.ts +10 -5
- package/dist/cjs/query-builder/insert-result.js +10 -5
- package/dist/cjs/query-builder/json-path-builder.d.ts +33 -9
- package/dist/cjs/query-builder/json-path-builder.js +8 -5
- package/dist/cjs/query-builder/merge-query-builder.d.ts +159 -21
- package/dist/cjs/query-builder/merge-query-builder.js +68 -6
- package/dist/cjs/query-builder/on-conflict-builder.d.ts +51 -18
- package/dist/cjs/query-builder/on-conflict-builder.js +41 -16
- package/dist/cjs/query-builder/output-interface.d.ts +50 -7
- package/dist/cjs/query-builder/returning-interface.d.ts +5 -5
- package/dist/cjs/query-builder/select-query-builder-expression.d.ts +8 -0
- package/dist/cjs/query-builder/select-query-builder.d.ts +295 -63
- package/dist/cjs/query-builder/select-query-builder.js +7 -7
- package/dist/cjs/query-builder/update-query-builder.d.ts +138 -29
- package/dist/cjs/query-builder/update-query-builder.js +75 -10
- package/dist/cjs/query-builder/update-result.d.ts +2 -2
- package/dist/cjs/query-builder/update-result.js +2 -2
- package/dist/cjs/query-builder/where-interface.d.ts +5 -1
- package/dist/cjs/query-compiler/default-query-compiler.js +20 -0
- package/dist/cjs/query-creator.d.ts +66 -18
- package/dist/cjs/query-creator.js +2 -2
- package/dist/cjs/raw-builder/raw-builder.d.ts +29 -7
- package/dist/cjs/raw-builder/sql.d.ts +26 -7
- package/dist/cjs/schema/alter-column-builder.d.ts +17 -3
- package/dist/cjs/schema/alter-column-builder.js +17 -3
- package/dist/cjs/schema/alter-table-add-index-builder.d.ts +43 -9
- package/dist/cjs/schema/alter-table-add-index-builder.js +26 -9
- package/dist/cjs/schema/column-definition-builder.d.ts +283 -26
- package/dist/cjs/schema/column-definition-builder.js +283 -26
- package/dist/cjs/schema/create-table-builder.d.ts +86 -33
- package/dist/cjs/schema/create-table-builder.js +86 -33
- package/dist/cjs/util/column-type.d.ts +5 -9
- package/dist/cjs/util/require-all-props.d.ts +4 -2
- package/dist/cjs/util/require-all-props.js +4 -2
- package/dist/cjs/util/streamable.d.ts +1 -1
- package/dist/cjs/util/type-utils.d.ts +4 -2
- package/dist/esm/dialect/dialect-adapter-base.d.ts +11 -2
- package/dist/esm/dialect/dialect-adapter.d.ts +11 -2
- package/dist/esm/dialect/mssql/mssql-adapter.d.ts +11 -2
- package/dist/esm/dialect/mssql/mssql-dialect-config.d.ts +37 -29
- package/dist/esm/dialect/mssql/mssql-driver.js +20 -13
- package/dist/esm/dialect/mysql/mysql-adapter.d.ts +11 -2
- package/dist/esm/dialect/mysql/mysql-dialect-config.d.ts +4 -0
- package/dist/esm/dialect/mysql/mysql-driver.js +3 -0
- package/dist/esm/dialect/postgres/postgres-adapter.d.ts +11 -2
- package/dist/esm/dialect/postgres/postgres-dialect-config.d.ts +10 -3
- package/dist/esm/dialect/postgres/postgres-driver.js +3 -0
- package/dist/esm/dialect/postgres/postgres-introspector.js +5 -1
- package/dist/esm/dialect/sqlite/sqlite-adapter.d.ts +11 -2
- package/dist/esm/driver/dummy-driver.d.ts +13 -12
- package/dist/esm/driver/dummy-driver.js +13 -12
- package/dist/esm/dynamic/dynamic.d.ts +6 -6
- package/dist/esm/dynamic/dynamic.js +6 -6
- package/dist/esm/expression/expression-builder.d.ts +152 -61
- package/dist/esm/expression/expression-wrapper.d.ts +92 -23
- package/dist/esm/expression/expression.d.ts +40 -5
- package/dist/esm/helpers/mssql.d.ts +74 -14
- package/dist/esm/helpers/mssql.js +74 -14
- package/dist/esm/helpers/mysql.d.ts +14 -10
- package/dist/esm/helpers/mysql.js +14 -10
- package/dist/esm/helpers/postgres.d.ts +7 -4
- package/dist/esm/helpers/postgres.js +7 -4
- package/dist/esm/helpers/sqlite.d.ts +41 -16
- package/dist/esm/helpers/sqlite.js +41 -16
- package/dist/esm/kysely.d.ts +99 -41
- package/dist/esm/kysely.js +60 -36
- package/dist/esm/migration/file-migration-provider.d.ts +2 -2
- package/dist/esm/migration/file-migration-provider.js +2 -2
- package/dist/esm/migration/migrator.d.ts +82 -14
- package/dist/esm/migration/migrator.js +82 -14
- package/dist/esm/operation-node/aggregate-function-node.d.ts +4 -0
- package/dist/esm/operation-node/aggregate-function-node.js +9 -0
- package/dist/esm/operation-node/data-type-node.d.ts +1 -1
- package/dist/esm/operation-node/data-type-node.js +12 -0
- package/dist/esm/operation-node/delete-query-node.d.ts +1 -0
- package/dist/esm/operation-node/insert-query-node.d.ts +1 -0
- package/dist/esm/operation-node/merge-query-node.d.ts +1 -0
- package/dist/esm/operation-node/operation-node-transformer.d.ts +9 -3
- package/dist/esm/operation-node/operation-node-transformer.js +14 -3
- package/dist/esm/operation-node/query-node.d.ts +4 -0
- package/dist/esm/operation-node/query-node.js +8 -0
- package/dist/esm/operation-node/select-query-node.d.ts +0 -1
- package/dist/esm/operation-node/select-query-node.js +0 -8
- package/dist/esm/operation-node/update-query-node.d.ts +1 -0
- package/dist/esm/plugin/camel-case/camel-case-plugin.d.ts +52 -25
- package/dist/esm/plugin/camel-case/camel-case-plugin.js +24 -19
- package/dist/esm/plugin/deduplicate-joins/deduplicate-joins-plugin.d.ts +29 -7
- package/dist/esm/plugin/deduplicate-joins/deduplicate-joins-plugin.js +1 -1
- package/dist/esm/plugin/deduplicate-joins/deduplicate-joins-transformer.js +2 -2
- package/dist/esm/plugin/immediate-value/immediate-value-plugin.d.ts +28 -6
- package/dist/esm/plugin/kysely-plugin.d.ts +28 -6
- package/dist/esm/plugin/noop-plugin.d.ts +28 -6
- package/dist/esm/plugin/parse-json-results/parse-json-results-plugin.d.ts +62 -9
- package/dist/esm/plugin/parse-json-results/parse-json-results-plugin.js +34 -3
- package/dist/esm/plugin/with-schema/with-schema-plugin.d.ts +28 -6
- package/dist/esm/query-builder/aggregate-function-builder.d.ts +43 -1
- package/dist/esm/query-builder/aggregate-function-builder.js +30 -0
- package/dist/esm/query-builder/delete-query-builder.d.ts +137 -45
- package/dist/esm/query-builder/delete-query-builder.js +76 -26
- package/dist/esm/query-builder/function-module.d.ts +35 -88
- package/dist/esm/query-builder/insert-query-builder.d.ts +239 -65
- package/dist/esm/query-builder/insert-query-builder.js +188 -52
- package/dist/esm/query-builder/insert-result.d.ts +10 -5
- package/dist/esm/query-builder/insert-result.js +10 -5
- package/dist/esm/query-builder/json-path-builder.d.ts +33 -9
- package/dist/esm/query-builder/json-path-builder.js +8 -5
- package/dist/esm/query-builder/merge-query-builder.d.ts +159 -21
- package/dist/esm/query-builder/merge-query-builder.js +68 -6
- package/dist/esm/query-builder/on-conflict-builder.d.ts +51 -18
- package/dist/esm/query-builder/on-conflict-builder.js +41 -16
- package/dist/esm/query-builder/output-interface.d.ts +50 -7
- package/dist/esm/query-builder/returning-interface.d.ts +5 -5
- package/dist/esm/query-builder/select-query-builder-expression.d.ts +8 -0
- package/dist/esm/query-builder/select-query-builder.d.ts +295 -63
- package/dist/esm/query-builder/select-query-builder.js +7 -7
- package/dist/esm/query-builder/update-query-builder.d.ts +138 -29
- package/dist/esm/query-builder/update-query-builder.js +75 -10
- package/dist/esm/query-builder/update-result.d.ts +2 -2
- package/dist/esm/query-builder/update-result.js +2 -2
- package/dist/esm/query-builder/where-interface.d.ts +5 -1
- package/dist/esm/query-compiler/default-query-compiler.js +20 -0
- package/dist/esm/query-creator.d.ts +66 -18
- package/dist/esm/query-creator.js +2 -2
- package/dist/esm/raw-builder/raw-builder.d.ts +29 -7
- package/dist/esm/raw-builder/sql.d.ts +26 -7
- package/dist/esm/schema/alter-column-builder.d.ts +17 -3
- package/dist/esm/schema/alter-column-builder.js +17 -3
- package/dist/esm/schema/alter-table-add-index-builder.d.ts +43 -9
- package/dist/esm/schema/alter-table-add-index-builder.js +26 -9
- package/dist/esm/schema/column-definition-builder.d.ts +283 -26
- package/dist/esm/schema/column-definition-builder.js +283 -26
- package/dist/esm/schema/create-table-builder.d.ts +86 -33
- package/dist/esm/schema/create-table-builder.js +86 -33
- package/dist/esm/util/column-type.d.ts +5 -9
- package/dist/esm/util/require-all-props.d.ts +4 -2
- package/dist/esm/util/require-all-props.js +4 -2
- package/dist/esm/util/streamable.d.ts +1 -1
- package/dist/esm/util/type-utils.d.ts +4 -2
- package/package.json +28 -23
package/.renovaterc.json
ADDED
package/CONTRIBUTING.md
CHANGED
|
@@ -52,7 +52,7 @@ for all cases, are best left for consumers to implement.
|
|
|
52
52
|
|
|
53
53
|
5. create a branch.
|
|
54
54
|
|
|
55
|
-
6. create a draft pull request. link the relevant issue by
|
|
55
|
+
6. create a draft pull request. link the relevant issue by referring to it in the
|
|
56
56
|
PR's description. E.g. `closes #123` will link the PR to issue/pull request #123.
|
|
57
57
|
|
|
58
58
|
7. implement your changes.
|
package/deno.check.d.ts
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ColumnType,
|
|
3
|
+
Generated,
|
|
4
|
+
GeneratedAlways,
|
|
5
|
+
Insertable,
|
|
6
|
+
Kysely,
|
|
7
|
+
Selectable,
|
|
8
|
+
SqlBool,
|
|
9
|
+
Updateable,
|
|
10
|
+
} from './dist/esm'
|
|
11
|
+
|
|
12
|
+
export interface Database {
|
|
13
|
+
person: PersonTable
|
|
14
|
+
pet: PetTable
|
|
15
|
+
toy: ToyTable
|
|
16
|
+
wine: WineTable
|
|
17
|
+
wine_stock_change: WineStockChangeTable
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
interface PersonTable {
|
|
21
|
+
id: Generated<number>
|
|
22
|
+
address: { city: string } | null
|
|
23
|
+
age: number | null
|
|
24
|
+
birthdate: ColumnType<Date | null, string | null | undefined, string | null>
|
|
25
|
+
created_at: GeneratedAlways<Date>
|
|
26
|
+
deleted_at: ColumnType<Date | null, string | null | undefined, string | null>
|
|
27
|
+
experience: { role: string }[] | null
|
|
28
|
+
first_name: string
|
|
29
|
+
gender: 'male' | 'female' | 'other' | null
|
|
30
|
+
has_pets: Generated<'Y' | 'N'>
|
|
31
|
+
last_name: string | null
|
|
32
|
+
middle_name: string | null
|
|
33
|
+
nicknames: string[] | null
|
|
34
|
+
nullable_column: string | null
|
|
35
|
+
profile: {
|
|
36
|
+
addresses: { city: string }[]
|
|
37
|
+
website: { url: string }
|
|
38
|
+
} | null
|
|
39
|
+
updated_at: ColumnType<Date | null, string | null | undefined, string | null>
|
|
40
|
+
marital_status: 'single' | 'married' | 'divorced' | 'widowed' | null
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
interface PetTable {
|
|
44
|
+
id: Generated<number>
|
|
45
|
+
created_at: GeneratedAlways<Date>
|
|
46
|
+
is_favorite: Generated<SqlBool>
|
|
47
|
+
name: string
|
|
48
|
+
owner_id: number
|
|
49
|
+
species: Species
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
interface ToyTable {
|
|
53
|
+
id: Generated<number>
|
|
54
|
+
pet_id: number
|
|
55
|
+
price: number
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
interface WineTable {
|
|
59
|
+
name: string
|
|
60
|
+
stock: number
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
interface WineStockChangeTable {
|
|
64
|
+
stock_delta: number
|
|
65
|
+
wine_name: string
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export type Person = Selectable<PersonTable>
|
|
69
|
+
export type NewPerson = Insertable<PersonTable>
|
|
70
|
+
export type PersonUpdate = Updateable<PersonTable>
|
|
71
|
+
export type Pet = Selectable<PetTable>
|
|
72
|
+
export type NewPet = Insertable<PetTable>
|
|
73
|
+
export type PetUpdate = Updateable<PetTable>
|
|
74
|
+
export type Species = 'dog' | 'cat' | 'hamster'
|
|
75
|
+
|
|
76
|
+
declare global {
|
|
77
|
+
// @ts-ignore
|
|
78
|
+
export class Buffer {
|
|
79
|
+
static isBuffer(obj: unknown): obj is { length: number }
|
|
80
|
+
static compare(a: Buffer, b: Buffer): number
|
|
81
|
+
}
|
|
82
|
+
export const db: Kysely<Database>
|
|
83
|
+
export function functionThatExpectsPersonWithNonNullValue(
|
|
84
|
+
person: Person & { nullable_column: string },
|
|
85
|
+
): void
|
|
86
|
+
}
|
package/deno.check.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://deno.land/x/deno/cli/schemas/config-file.v1.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"types": ["./deno.check.d.ts"]
|
|
5
|
+
},
|
|
6
|
+
"imports": {
|
|
7
|
+
"better-sqlite3": "npm:better-sqlite3",
|
|
8
|
+
"kysely": "./dist/esm",
|
|
9
|
+
"kysely/helpers/mssql": "./dist/esm/helpers/mssql.js",
|
|
10
|
+
"kysely/helpers/mysql": "./dist/esm/helpers/mysql.js",
|
|
11
|
+
"kysely/helpers/postgres": "./dist/esm/helpers/postgres.js",
|
|
12
|
+
"kysely/helpers/sqlite": "./dist/esm/helpers/sqlite.js",
|
|
13
|
+
"lodash/snakeCase": "npm:lodash/snakeCase",
|
|
14
|
+
"mysql2": "npm:mysql2",
|
|
15
|
+
"pg": "npm:pg",
|
|
16
|
+
"pg-cursor": "npm:pg-cursor",
|
|
17
|
+
"tarn": "npm:tarn",
|
|
18
|
+
"tedious": "npm:tedious",
|
|
19
|
+
"type-editor": "./deno.check.d.ts"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -47,8 +47,13 @@ export declare abstract class DialectAdapterBase implements DialectAdapter {
|
|
|
47
47
|
* have explicit locks but supports `FOR UPDATE` row locks and transactional DDL:
|
|
48
48
|
*
|
|
49
49
|
* ```ts
|
|
50
|
-
* {
|
|
51
|
-
*
|
|
50
|
+
* import { DialectAdapterBase, type MigrationLockOptions, Kysely } from 'kysely'
|
|
51
|
+
*
|
|
52
|
+
* export class MyAdapter extends DialectAdapterBase {
|
|
53
|
+
* override async acquireMigrationLock(
|
|
54
|
+
* db: Kysely<any>,
|
|
55
|
+
* options: MigrationLockOptions
|
|
56
|
+
* ): Promise<void> {
|
|
52
57
|
* const queryDb = options.lockTableSchema
|
|
53
58
|
* ? db.withSchema(options.lockTableSchema)
|
|
54
59
|
* : db
|
|
@@ -64,6 +69,10 @@ export declare abstract class DialectAdapterBase implements DialectAdapter {
|
|
|
64
69
|
* .forUpdate()
|
|
65
70
|
* .execute()
|
|
66
71
|
* }
|
|
72
|
+
*
|
|
73
|
+
* override async releaseMigrationLock() {
|
|
74
|
+
* // noop
|
|
75
|
+
* }
|
|
67
76
|
* }
|
|
68
77
|
* ```
|
|
69
78
|
*
|
|
@@ -52,8 +52,13 @@ export interface DialectAdapter {
|
|
|
52
52
|
* have explicit locks but supports `FOR UPDATE` row locks and transactional DDL:
|
|
53
53
|
*
|
|
54
54
|
* ```ts
|
|
55
|
-
* {
|
|
56
|
-
*
|
|
55
|
+
* import { DialectAdapterBase, type MigrationLockOptions, Kysely } from 'kysely'
|
|
56
|
+
*
|
|
57
|
+
* export class MyAdapter extends DialectAdapterBase {
|
|
58
|
+
* override async acquireMigrationLock(
|
|
59
|
+
* db: Kysely<any>,
|
|
60
|
+
* options: MigrationLockOptions
|
|
61
|
+
* ): Promise<void> {
|
|
57
62
|
* const queryDb = options.lockTableSchema
|
|
58
63
|
* ? db.withSchema(options.lockTableSchema)
|
|
59
64
|
* : db
|
|
@@ -69,6 +74,10 @@ export interface DialectAdapter {
|
|
|
69
74
|
* .forUpdate()
|
|
70
75
|
* .execute()
|
|
71
76
|
* }
|
|
77
|
+
*
|
|
78
|
+
* override async releaseMigrationLock() {
|
|
79
|
+
* // noop
|
|
80
|
+
* }
|
|
72
81
|
* }
|
|
73
82
|
* ```
|
|
74
83
|
*
|
|
@@ -36,8 +36,13 @@ export declare class MssqlAdapter extends DialectAdapterBase {
|
|
|
36
36
|
* have explicit locks but supports `FOR UPDATE` row locks and transactional DDL:
|
|
37
37
|
*
|
|
38
38
|
* ```ts
|
|
39
|
-
* {
|
|
40
|
-
*
|
|
39
|
+
* import { DialectAdapterBase, type MigrationLockOptions, Kysely } from 'kysely'
|
|
40
|
+
*
|
|
41
|
+
* export class MyAdapter extends DialectAdapterBase {
|
|
42
|
+
* override async acquireMigrationLock(
|
|
43
|
+
* db: Kysely<any>,
|
|
44
|
+
* options: MigrationLockOptions
|
|
45
|
+
* ): Promise<void> {
|
|
41
46
|
* const queryDb = options.lockTableSchema
|
|
42
47
|
* ? db.withSchema(options.lockTableSchema)
|
|
43
48
|
* : db
|
|
@@ -53,6 +58,10 @@ export declare class MssqlAdapter extends DialectAdapterBase {
|
|
|
53
58
|
* .forUpdate()
|
|
54
59
|
* .execute()
|
|
55
60
|
* }
|
|
61
|
+
*
|
|
62
|
+
* override async releaseMigrationLock() {
|
|
63
|
+
* // noop
|
|
64
|
+
* }
|
|
56
65
|
* }
|
|
57
66
|
* ```
|
|
58
67
|
*
|
|
@@ -6,21 +6,23 @@ export interface MssqlDialectConfig {
|
|
|
6
6
|
* (excluding `create`, `destroy` and `validate` functions which are controlled by this dialect),
|
|
7
7
|
* `min` & `max` connections at the very least.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
9
|
+
* ### Examples
|
|
10
10
|
*
|
|
11
11
|
* ```ts
|
|
12
|
+
* import { MssqlDialect } from 'kysely'
|
|
12
13
|
* import * as Tarn from 'tarn'
|
|
14
|
+
* import * as Tedious from 'tedious'
|
|
13
15
|
*
|
|
14
16
|
* const dialect = new MssqlDialect({
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* ...
|
|
18
|
-
*
|
|
17
|
+
* tarn: { ...Tarn, options: { max: 10, min: 0 } },
|
|
18
|
+
* tedious: {
|
|
19
|
+
* ...Tedious,
|
|
20
|
+
* connectionFactory: () => new Tedious.Connection({
|
|
19
21
|
* // ...
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* },
|
|
23
|
-
* }
|
|
22
|
+
* server: 'localhost',
|
|
23
|
+
* // ...
|
|
24
|
+
* }),
|
|
25
|
+
* }
|
|
24
26
|
* })
|
|
25
27
|
* ```
|
|
26
28
|
*/
|
|
@@ -31,17 +33,23 @@ export interface MssqlDialectConfig {
|
|
|
31
33
|
* you need to pass the `tedious` package itself. You also need to pass a factory
|
|
32
34
|
* function that creates new `tedious` `Connection` instances on demand.
|
|
33
35
|
*
|
|
34
|
-
*
|
|
36
|
+
* ### Examples
|
|
35
37
|
*
|
|
36
38
|
* ```ts
|
|
39
|
+
* import { MssqlDialect } from 'kysely'
|
|
40
|
+
* import * as Tarn from 'tarn'
|
|
37
41
|
* import * as Tedious from 'tedious'
|
|
38
42
|
*
|
|
39
43
|
* const dialect = new MssqlDialect({
|
|
40
|
-
*
|
|
44
|
+
* tarn: { ...Tarn, options: { max: 10, min: 0 } },
|
|
41
45
|
* tedious: {
|
|
42
46
|
* ...Tedious,
|
|
43
|
-
* connectionFactory: () => new Tedious.Connection({
|
|
44
|
-
*
|
|
47
|
+
* connectionFactory: () => new Tedious.Connection({
|
|
48
|
+
* // ...
|
|
49
|
+
* server: 'localhost',
|
|
50
|
+
* // ...
|
|
51
|
+
* }),
|
|
52
|
+
* }
|
|
45
53
|
* })
|
|
46
54
|
* ```
|
|
47
55
|
*/
|
|
@@ -52,6 +60,13 @@ export interface Tedious {
|
|
|
52
60
|
ISOLATION_LEVEL: TediousIsolationLevel;
|
|
53
61
|
Request: TediousRequestClass;
|
|
54
62
|
TYPES: TediousTypes;
|
|
63
|
+
/**
|
|
64
|
+
* Controls whether connections are reset to their initial states when released back to the pool. Resetting a connection performs additional requests to the database.
|
|
65
|
+
* See {@link https://tediousjs.github.io/tedious/api-connection.html#function_reset | connection.reset}.
|
|
66
|
+
*
|
|
67
|
+
* Defaults to `true`.
|
|
68
|
+
*/
|
|
69
|
+
resetConnectionOnRelease?: boolean;
|
|
55
70
|
}
|
|
56
71
|
export interface TediousConnection {
|
|
57
72
|
beginTransaction(callback: (error?: Error | null, transactionDescriptor?: any) => void, name?: string, isolationLevel?: number): void;
|
|
@@ -115,23 +130,16 @@ export interface Tarn {
|
|
|
115
130
|
* Tarn.js' pool options, excluding `create`, `destroy` and `validate` functions,
|
|
116
131
|
* which must be implemented by this dialect.
|
|
117
132
|
*/
|
|
118
|
-
options: Omit<TarnPoolOptions<any>, 'create' | 'destroy' | 'validate'
|
|
133
|
+
options: Omit<TarnPoolOptions<any>, 'create' | 'destroy' | 'validate'> & {
|
|
134
|
+
/**
|
|
135
|
+
* Controls whether connections are validated before being acquired from the pool. Connection validation performs additional requests to the database.
|
|
136
|
+
*
|
|
137
|
+
* Defaults to `true`.
|
|
138
|
+
*/
|
|
139
|
+
validateConnections?: boolean;
|
|
140
|
+
};
|
|
119
141
|
/**
|
|
120
142
|
* Tarn.js' Pool class.
|
|
121
|
-
*
|
|
122
|
-
* Example:
|
|
123
|
-
*
|
|
124
|
-
* ```ts
|
|
125
|
-
* import { Pool } from 'tarn'
|
|
126
|
-
*
|
|
127
|
-
* const dialect = new MssqlDialect({
|
|
128
|
-
* // ...
|
|
129
|
-
* tarn: {
|
|
130
|
-
* // ...
|
|
131
|
-
* Pool,
|
|
132
|
-
* },
|
|
133
|
-
* })
|
|
134
|
-
* ```
|
|
135
143
|
*/
|
|
136
144
|
Pool: typeof TarnPool;
|
|
137
145
|
}
|
|
@@ -154,7 +162,7 @@ export interface TarnPoolOptions<R> {
|
|
|
154
162
|
min: number;
|
|
155
163
|
propagateCreateError?: boolean;
|
|
156
164
|
reapIntervalMillis?: number;
|
|
157
|
-
validate(resource: R): boolean;
|
|
165
|
+
validate?(resource: R): boolean;
|
|
158
166
|
}
|
|
159
167
|
export interface TarnPendingRequest<R> {
|
|
160
168
|
promise: Promise<R>;
|
|
@@ -13,18 +13,22 @@ class MssqlDriver {
|
|
|
13
13
|
#pool;
|
|
14
14
|
constructor(config) {
|
|
15
15
|
this.#config = (0, object_utils_js_1.freeze)({ ...config });
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
const { tarn, tedious } = this.#config;
|
|
17
|
+
const { validateConnections, ...poolOptions } = tarn.options;
|
|
18
|
+
this.#pool = new tarn.Pool({
|
|
19
|
+
...poolOptions,
|
|
18
20
|
create: async () => {
|
|
19
|
-
const connection = await
|
|
20
|
-
return await new MssqlConnection(connection,
|
|
21
|
+
const connection = await tedious.connectionFactory();
|
|
22
|
+
return await new MssqlConnection(connection, tedious).connect();
|
|
21
23
|
},
|
|
22
24
|
destroy: async (connection) => {
|
|
23
25
|
await connection[PRIVATE_DESTROY_METHOD]();
|
|
24
26
|
},
|
|
25
27
|
// @ts-ignore `tarn` accepts a function that returns a promise here, but
|
|
26
28
|
// the types are not aligned and it type errors.
|
|
27
|
-
validate:
|
|
29
|
+
validate: validateConnections === false
|
|
30
|
+
? undefined
|
|
31
|
+
: (connection) => connection.validate(),
|
|
28
32
|
});
|
|
29
33
|
}
|
|
30
34
|
async init() {
|
|
@@ -189,15 +193,18 @@ class MssqlConnection {
|
|
|
189
193
|
}
|
|
190
194
|
});
|
|
191
195
|
}
|
|
192
|
-
[PRIVATE_RELEASE_METHOD]() {
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
196
|
+
async [PRIVATE_RELEASE_METHOD]() {
|
|
197
|
+
// TODO: flip this to `if (!this.#tedious.resetConnectionOnRelease) {}` in a future PR.
|
|
198
|
+
if (this.#tedious.resetConnectionOnRelease !== false) {
|
|
199
|
+
await new Promise((resolve, reject) => {
|
|
200
|
+
this.#connection.reset((error) => {
|
|
201
|
+
if (error)
|
|
202
|
+
reject(error);
|
|
203
|
+
else
|
|
204
|
+
resolve(undefined);
|
|
205
|
+
});
|
|
199
206
|
});
|
|
200
|
-
}
|
|
207
|
+
}
|
|
201
208
|
}
|
|
202
209
|
[PRIVATE_DESTROY_METHOD]() {
|
|
203
210
|
return new Promise((resolve) => {
|
|
@@ -33,8 +33,13 @@ export declare class MysqlAdapter extends DialectAdapterBase {
|
|
|
33
33
|
* have explicit locks but supports `FOR UPDATE` row locks and transactional DDL:
|
|
34
34
|
*
|
|
35
35
|
* ```ts
|
|
36
|
-
* {
|
|
37
|
-
*
|
|
36
|
+
* import { DialectAdapterBase, type MigrationLockOptions, Kysely } from 'kysely'
|
|
37
|
+
*
|
|
38
|
+
* export class MyAdapter extends DialectAdapterBase {
|
|
39
|
+
* override async acquireMigrationLock(
|
|
40
|
+
* db: Kysely<any>,
|
|
41
|
+
* options: MigrationLockOptions
|
|
42
|
+
* ): Promise<void> {
|
|
38
43
|
* const queryDb = options.lockTableSchema
|
|
39
44
|
* ? db.withSchema(options.lockTableSchema)
|
|
40
45
|
* : db
|
|
@@ -50,6 +55,10 @@ export declare class MysqlAdapter extends DialectAdapterBase {
|
|
|
50
55
|
* .forUpdate()
|
|
51
56
|
* .execute()
|
|
52
57
|
* }
|
|
58
|
+
*
|
|
59
|
+
* override async releaseMigrationLock() {
|
|
60
|
+
* // noop
|
|
61
|
+
* }
|
|
53
62
|
* }
|
|
54
63
|
* ```
|
|
55
64
|
*
|
|
@@ -17,6 +17,10 @@ export interface MysqlDialectConfig {
|
|
|
17
17
|
* Called once for each created connection.
|
|
18
18
|
*/
|
|
19
19
|
onCreateConnection?: (connection: DatabaseConnection) => Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* Called every time a connection is acquired from the connection pool.
|
|
22
|
+
*/
|
|
23
|
+
onReserveConnection?: (connection: DatabaseConnection) => Promise<void>;
|
|
20
24
|
}
|
|
21
25
|
/**
|
|
22
26
|
* This interface is the subset of mysql2 driver's `Pool` class that
|
|
@@ -33,8 +33,13 @@ export declare class PostgresAdapter extends DialectAdapterBase {
|
|
|
33
33
|
* have explicit locks but supports `FOR UPDATE` row locks and transactional DDL:
|
|
34
34
|
*
|
|
35
35
|
* ```ts
|
|
36
|
-
* {
|
|
37
|
-
*
|
|
36
|
+
* import { DialectAdapterBase, type MigrationLockOptions, Kysely } from 'kysely'
|
|
37
|
+
*
|
|
38
|
+
* export class MyAdapter extends DialectAdapterBase {
|
|
39
|
+
* override async acquireMigrationLock(
|
|
40
|
+
* db: Kysely<any>,
|
|
41
|
+
* options: MigrationLockOptions
|
|
42
|
+
* ): Promise<void> {
|
|
38
43
|
* const queryDb = options.lockTableSchema
|
|
39
44
|
* ? db.withSchema(options.lockTableSchema)
|
|
40
45
|
* : db
|
|
@@ -50,6 +55,10 @@ export declare class PostgresAdapter extends DialectAdapterBase {
|
|
|
50
55
|
* .forUpdate()
|
|
51
56
|
* .execute()
|
|
52
57
|
* }
|
|
58
|
+
*
|
|
59
|
+
* override async releaseMigrationLock() {
|
|
60
|
+
* // noop
|
|
61
|
+
* }
|
|
53
62
|
* }
|
|
54
63
|
* ```
|
|
55
64
|
*
|
|
@@ -13,13 +13,16 @@ export interface PostgresDialectConfig {
|
|
|
13
13
|
pool: PostgresPool | (() => Promise<PostgresPool>);
|
|
14
14
|
/**
|
|
15
15
|
* https://github.com/brianc/node-postgres/tree/master/packages/pg-cursor
|
|
16
|
+
*
|
|
16
17
|
* ```ts
|
|
18
|
+
* import { PostgresDialect } from 'kysely'
|
|
19
|
+
* import { Pool } from 'pg'
|
|
17
20
|
* import Cursor from 'pg-cursor'
|
|
18
|
-
* // or
|
|
19
|
-
* import * as Cursor from 'pg-cursor'
|
|
21
|
+
* // or import * as Cursor from 'pg-cursor'
|
|
20
22
|
*
|
|
21
23
|
* new PostgresDialect({
|
|
22
|
-
* cursor: Cursor
|
|
24
|
+
* cursor: Cursor,
|
|
25
|
+
* pool: new Pool('postgres://localhost:5432/mydb')
|
|
23
26
|
* })
|
|
24
27
|
* ```
|
|
25
28
|
*/
|
|
@@ -28,6 +31,10 @@ export interface PostgresDialectConfig {
|
|
|
28
31
|
* Called once for each created connection.
|
|
29
32
|
*/
|
|
30
33
|
onCreateConnection?: (connection: DatabaseConnection) => Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* Called every time a connection is acquired from the pool.
|
|
36
|
+
*/
|
|
37
|
+
onReserveConnection?: (connection: DatabaseConnection) => Promise<void>;
|
|
31
38
|
}
|
|
32
39
|
/**
|
|
33
40
|
* This interface is the subset of pg driver's `Pool` class that
|
|
@@ -32,6 +32,9 @@ class PostgresDriver {
|
|
|
32
32
|
await this.#config.onCreateConnection(connection);
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
|
+
if (this.#config.onReserveConnection) {
|
|
36
|
+
await this.#config.onReserveConnection(connection);
|
|
37
|
+
}
|
|
35
38
|
return connection;
|
|
36
39
|
}
|
|
37
40
|
async beginTransaction(connection, settings) {
|
|
@@ -51,7 +51,11 @@ class PostgresIntrospector {
|
|
|
51
51
|
.as('auto_incrementing'),
|
|
52
52
|
])
|
|
53
53
|
// r == normal table
|
|
54
|
-
.where((eb) => eb.or([
|
|
54
|
+
.where((eb) => eb.or([
|
|
55
|
+
eb('c.relkind', '=', 'r'),
|
|
56
|
+
eb('c.relkind', '=', 'v'),
|
|
57
|
+
eb('c.relkind', '=', 'p'),
|
|
58
|
+
]))
|
|
55
59
|
.where('ns.nspname', '!~', '^pg_')
|
|
56
60
|
.where('ns.nspname', '!=', 'information_schema')
|
|
57
61
|
// No system columns
|
|
@@ -33,8 +33,13 @@ export declare class SqliteAdapter extends DialectAdapterBase {
|
|
|
33
33
|
* have explicit locks but supports `FOR UPDATE` row locks and transactional DDL:
|
|
34
34
|
*
|
|
35
35
|
* ```ts
|
|
36
|
-
* {
|
|
37
|
-
*
|
|
36
|
+
* import { DialectAdapterBase, type MigrationLockOptions, Kysely } from 'kysely'
|
|
37
|
+
*
|
|
38
|
+
* export class MyAdapter extends DialectAdapterBase {
|
|
39
|
+
* override async acquireMigrationLock(
|
|
40
|
+
* db: Kysely<any>,
|
|
41
|
+
* options: MigrationLockOptions
|
|
42
|
+
* ): Promise<void> {
|
|
38
43
|
* const queryDb = options.lockTableSchema
|
|
39
44
|
* ? db.withSchema(options.lockTableSchema)
|
|
40
45
|
* : db
|
|
@@ -50,6 +55,10 @@ export declare class SqliteAdapter extends DialectAdapterBase {
|
|
|
50
55
|
* .forUpdate()
|
|
51
56
|
* .execute()
|
|
52
57
|
* }
|
|
58
|
+
*
|
|
59
|
+
* override async releaseMigrationLock() {
|
|
60
|
+
* // noop
|
|
61
|
+
* }
|
|
53
62
|
* }
|
|
54
63
|
* ```
|
|
55
64
|
*
|
|
@@ -10,20 +10,21 @@ import { Driver } from './driver.js';
|
|
|
10
10
|
* This example creates a Kysely instance for building postgres queries:
|
|
11
11
|
*
|
|
12
12
|
* ```ts
|
|
13
|
+
* import {
|
|
14
|
+
* DummyDriver,
|
|
15
|
+
* Kysely,
|
|
16
|
+
* PostgresAdapter,
|
|
17
|
+
* PostgresIntrospector,
|
|
18
|
+
* PostgresQueryCompiler
|
|
19
|
+
* } from 'kysely'
|
|
20
|
+
* import type { Database } from 'type-editor' // imaginary module
|
|
21
|
+
*
|
|
13
22
|
* const db = new Kysely<Database>({
|
|
14
23
|
* dialect: {
|
|
15
|
-
* createAdapter()
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* return new DummyDriver()
|
|
20
|
-
* },
|
|
21
|
-
* createIntrospector(db: Kysely<any>) {
|
|
22
|
-
* return new PostgresIntrospector(db)
|
|
23
|
-
* },
|
|
24
|
-
* createQueryCompiler() {
|
|
25
|
-
* return new PostgresQueryCompiler()
|
|
26
|
-
* },
|
|
24
|
+
* createAdapter: () => new PostgresAdapter(),
|
|
25
|
+
* createDriver: () => new DummyDriver(),
|
|
26
|
+
* createIntrospector: (db: Kysely<any>) => new PostgresIntrospector(db),
|
|
27
|
+
* createQueryCompiler: () => new PostgresQueryCompiler(),
|
|
27
28
|
* },
|
|
28
29
|
* })
|
|
29
30
|
* ```
|
|
@@ -11,20 +11,21 @@ exports.DummyDriver = void 0;
|
|
|
11
11
|
* This example creates a Kysely instance for building postgres queries:
|
|
12
12
|
*
|
|
13
13
|
* ```ts
|
|
14
|
+
* import {
|
|
15
|
+
* DummyDriver,
|
|
16
|
+
* Kysely,
|
|
17
|
+
* PostgresAdapter,
|
|
18
|
+
* PostgresIntrospector,
|
|
19
|
+
* PostgresQueryCompiler
|
|
20
|
+
* } from 'kysely'
|
|
21
|
+
* import type { Database } from 'type-editor' // imaginary module
|
|
22
|
+
*
|
|
14
23
|
* const db = new Kysely<Database>({
|
|
15
24
|
* dialect: {
|
|
16
|
-
* createAdapter()
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* return new DummyDriver()
|
|
21
|
-
* },
|
|
22
|
-
* createIntrospector(db: Kysely<any>) {
|
|
23
|
-
* return new PostgresIntrospector(db)
|
|
24
|
-
* },
|
|
25
|
-
* createQueryCompiler() {
|
|
26
|
-
* return new PostgresQueryCompiler()
|
|
27
|
-
* },
|
|
25
|
+
* createAdapter: () => new PostgresAdapter(),
|
|
26
|
+
* createDriver: () => new DummyDriver(),
|
|
27
|
+
* createIntrospector: (db: Kysely<any>) => new PostgresIntrospector(db),
|
|
28
|
+
* createQueryCompiler: () => new PostgresQueryCompiler(),
|
|
28
29
|
* },
|
|
29
30
|
* })
|
|
30
31
|
* ```
|
|
@@ -61,11 +61,11 @@ export declare class DynamicModule {
|
|
|
61
61
|
* const { ref } = db.dynamic
|
|
62
62
|
*
|
|
63
63
|
* // Some column name provided by the user. Value not known at compile time.
|
|
64
|
-
* const columnFromUserInput =
|
|
64
|
+
* const columnFromUserInput: PossibleColumns = 'birthdate';
|
|
65
65
|
*
|
|
66
66
|
* // A type that lists all possible values `columnFromUserInput` can have.
|
|
67
67
|
* // You can use `keyof Person` if any column of an interface is allowed.
|
|
68
|
-
* type PossibleColumns = 'last_name' | 'first_name' | '
|
|
68
|
+
* type PossibleColumns = 'last_name' | 'first_name' | 'birthdate'
|
|
69
69
|
*
|
|
70
70
|
* const [person] = await db.selectFrom('person')
|
|
71
71
|
* .select([
|
|
@@ -77,12 +77,12 @@ export declare class DynamicModule {
|
|
|
77
77
|
* // The resulting type contains all `PossibleColumns` as optional fields
|
|
78
78
|
* // because we cannot know which field was actually selected before
|
|
79
79
|
* // running the code.
|
|
80
|
-
* const lastName: string | undefined = person
|
|
81
|
-
* const firstName: string | undefined = person
|
|
82
|
-
* const birthDate:
|
|
80
|
+
* const lastName: string | null | undefined = person?.last_name
|
|
81
|
+
* const firstName: string | undefined = person?.first_name
|
|
82
|
+
* const birthDate: Date | null | undefined = person?.birthdate
|
|
83
83
|
*
|
|
84
84
|
* // The result type also contains the compile time selection `id`.
|
|
85
|
-
* person
|
|
85
|
+
* person?.id
|
|
86
86
|
* ```
|
|
87
87
|
*/
|
|
88
88
|
ref<R extends string = never>(reference: string): DynamicReferenceBuilder<R>;
|
|
@@ -64,11 +64,11 @@ class DynamicModule {
|
|
|
64
64
|
* const { ref } = db.dynamic
|
|
65
65
|
*
|
|
66
66
|
* // Some column name provided by the user. Value not known at compile time.
|
|
67
|
-
* const columnFromUserInput =
|
|
67
|
+
* const columnFromUserInput: PossibleColumns = 'birthdate';
|
|
68
68
|
*
|
|
69
69
|
* // A type that lists all possible values `columnFromUserInput` can have.
|
|
70
70
|
* // You can use `keyof Person` if any column of an interface is allowed.
|
|
71
|
-
* type PossibleColumns = 'last_name' | 'first_name' | '
|
|
71
|
+
* type PossibleColumns = 'last_name' | 'first_name' | 'birthdate'
|
|
72
72
|
*
|
|
73
73
|
* const [person] = await db.selectFrom('person')
|
|
74
74
|
* .select([
|
|
@@ -80,12 +80,12 @@ class DynamicModule {
|
|
|
80
80
|
* // The resulting type contains all `PossibleColumns` as optional fields
|
|
81
81
|
* // because we cannot know which field was actually selected before
|
|
82
82
|
* // running the code.
|
|
83
|
-
* const lastName: string | undefined = person
|
|
84
|
-
* const firstName: string | undefined = person
|
|
85
|
-
* const birthDate:
|
|
83
|
+
* const lastName: string | null | undefined = person?.last_name
|
|
84
|
+
* const firstName: string | undefined = person?.first_name
|
|
85
|
+
* const birthDate: Date | null | undefined = person?.birthdate
|
|
86
86
|
*
|
|
87
87
|
* // The result type also contains the compile time selection `id`.
|
|
88
|
-
* person
|
|
88
|
+
* person?.id
|
|
89
89
|
* ```
|
|
90
90
|
*/
|
|
91
91
|
ref(reference) {
|