@lobomfz/db 0.3.5 → 0.3.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.
- package/README.md +13 -13
- package/package.json +4 -2
- package/src/database.ts +56 -23
- package/src/dialect/connection.ts +3 -1
- package/src/dialect/dialect.ts +3 -2
- package/src/dialect/driver.ts +5 -3
- package/src/env.ts +1 -0
- package/src/generated.ts +2 -5
- package/src/index.ts +17 -8
- package/src/migration/diff.ts +33 -7
- package/src/migration/execute.ts +2 -1
- package/src/migration/introspect.ts +4 -2
- package/src/plugin.ts +21 -9
package/README.md
CHANGED
|
@@ -80,20 +80,20 @@ Schema changes are applied automatically on startup. Every time `new Database(..
|
|
|
80
80
|
|
|
81
81
|
### What's supported
|
|
82
82
|
|
|
83
|
-
| Change
|
|
84
|
-
|
|
85
|
-
| New table
|
|
86
|
-
| Removed table
|
|
87
|
-
| New nullable column
|
|
83
|
+
| Change | Strategy |
|
|
84
|
+
| -------------------------------- | ------------------------ |
|
|
85
|
+
| New table | `CREATE TABLE` |
|
|
86
|
+
| Removed table | `DROP TABLE` |
|
|
87
|
+
| New nullable column | `ALTER TABLE ADD COLUMN` |
|
|
88
88
|
| New NOT NULL column with DEFAULT | `ALTER TABLE ADD COLUMN` |
|
|
89
|
-
| Removed column
|
|
90
|
-
| Type change
|
|
91
|
-
| Nullability change
|
|
92
|
-
| DEFAULT change
|
|
93
|
-
| UNIQUE added/removed
|
|
94
|
-
| FK added/removed/changed
|
|
95
|
-
| Index added
|
|
96
|
-
| Index removed
|
|
89
|
+
| Removed column | Table rebuild |
|
|
90
|
+
| Type change | Table rebuild |
|
|
91
|
+
| Nullability change | Table rebuild |
|
|
92
|
+
| DEFAULT change | Table rebuild |
|
|
93
|
+
| UNIQUE added/removed | Table rebuild |
|
|
94
|
+
| FK added/removed/changed | Table rebuild |
|
|
95
|
+
| Index added | `CREATE INDEX` |
|
|
96
|
+
| Index removed | `DROP INDEX` |
|
|
97
97
|
|
|
98
98
|
Table rebuilds follow SQLite's [recommended procedure](https://www.sqlite.org/lang_altertable.html#otheralter): create a new table with the target schema, copy data from the old table, drop the old table, rename the new one. Foreign keys are disabled during rebuilds and validated via `PRAGMA foreign_key_check` before committing.
|
|
99
99
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lobomfz/db",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.8",
|
|
4
4
|
"description": "Bun SQLite database with Arktype schemas and typed Kysely client",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"arktype",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
".": "./src/index.ts"
|
|
29
29
|
},
|
|
30
30
|
"scripts": {
|
|
31
|
-
"check": "tsgo && oxlint"
|
|
31
|
+
"check": "tsgo && oxlint && bun test.ts"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {},
|
|
34
34
|
"devDependencies": {
|
|
@@ -38,6 +38,8 @@
|
|
|
38
38
|
"oxlint": "^1.57.0"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|
|
41
|
+
"@ark/schema": ">=0.56.0",
|
|
42
|
+
"@ark/util": ">=0.56.0",
|
|
41
43
|
"arktype": "^2.1.29",
|
|
42
44
|
"kysely": "^0.28.14"
|
|
43
45
|
}
|
package/src/database.ts
CHANGED
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
import { Database as BunDatabase } from "bun:sqlite";
|
|
2
|
-
|
|
3
|
-
import { BunSqliteDialect } from "./dialect/dialect";
|
|
2
|
+
|
|
4
3
|
import type { Type } from "arktype";
|
|
5
|
-
import
|
|
6
|
-
|
|
7
|
-
import {
|
|
4
|
+
import { Kysely, ParseJSONResultsPlugin } from "kysely";
|
|
5
|
+
|
|
6
|
+
import { BunSqliteDialect } from "./dialect/dialect.js";
|
|
7
|
+
import type { DbFieldMeta } from "./env.js";
|
|
8
|
+
import type { GeneratedPreset } from "./generated.js";
|
|
9
|
+
import { Differ, type DesiredTable } from "./migration/diff.js";
|
|
10
|
+
import { Executor } from "./migration/execute.js";
|
|
11
|
+
import { Introspector } from "./migration/introspect.js";
|
|
12
|
+
import { DeserializePlugin, type ColumnCoercion, type ColumnsMap } from "./plugin.js";
|
|
8
13
|
import type {
|
|
9
14
|
DatabaseOptions,
|
|
10
15
|
IndexDefinition,
|
|
11
16
|
SchemaRecord,
|
|
12
17
|
TablesFromSchemas,
|
|
13
18
|
DatabasePragmas,
|
|
14
|
-
} from "./types";
|
|
15
|
-
import { Introspector } from "./migration/introspect";
|
|
16
|
-
import { Differ, type DesiredTable } from "./migration/diff";
|
|
17
|
-
import { Executor } from "./migration/execute";
|
|
19
|
+
} from "./types.js";
|
|
18
20
|
|
|
19
21
|
type ArkBranch = {
|
|
20
22
|
domain?: string;
|
|
@@ -22,6 +24,7 @@ type ArkBranch = {
|
|
|
22
24
|
unit?: unknown;
|
|
23
25
|
structure?: unknown;
|
|
24
26
|
inner?: { divisor?: unknown };
|
|
27
|
+
meta?: DbFieldMeta & { _generated?: GeneratedPreset };
|
|
25
28
|
};
|
|
26
29
|
|
|
27
30
|
type StructureProp = {
|
|
@@ -43,6 +46,7 @@ type Prop = {
|
|
|
43
46
|
isBoolean?: boolean;
|
|
44
47
|
isInteger?: boolean;
|
|
45
48
|
isDate?: boolean;
|
|
49
|
+
isBlob?: boolean;
|
|
46
50
|
isJson?: boolean;
|
|
47
51
|
jsonSchema?: Type;
|
|
48
52
|
meta?: DbFieldMeta;
|
|
@@ -83,7 +87,10 @@ export class Database<T extends SchemaRecord> {
|
|
|
83
87
|
|
|
84
88
|
this.kysely = new Kysely<TablesFromSchemas<T>>({
|
|
85
89
|
dialect: new BunSqliteDialect({ database: this.sqlite }),
|
|
86
|
-
plugins: [
|
|
90
|
+
plugins: [
|
|
91
|
+
new DeserializePlugin(this.columns, this.tableColumns, validation),
|
|
92
|
+
new ParseJSONResultsPlugin(),
|
|
93
|
+
],
|
|
87
94
|
});
|
|
88
95
|
}
|
|
89
96
|
|
|
@@ -108,34 +115,49 @@ export class Database<T extends SchemaRecord> {
|
|
|
108
115
|
private normalizeProp(structureProp: StructureProp, parentSchema: Type) {
|
|
109
116
|
const { key, value: v, inner } = structureProp;
|
|
110
117
|
const kind: Prop["kind"] = structureProp.required ? "required" : "optional";
|
|
111
|
-
const generated = v.meta._generated;
|
|
112
118
|
const defaultValue = inner.default;
|
|
113
119
|
|
|
114
|
-
const
|
|
115
|
-
const nullable =
|
|
120
|
+
const concrete = v.branches.filter((b) => b.unit !== null && b.domain !== "undefined");
|
|
121
|
+
const nullable = concrete.length < v.branches.length;
|
|
122
|
+
|
|
123
|
+
const branchMeta = v.branches.find((b) => b.meta && Object.keys(b.meta).length > 0)?.meta;
|
|
124
|
+
const meta = { ...branchMeta, ...v.meta };
|
|
125
|
+
const generated = meta._generated;
|
|
116
126
|
|
|
117
|
-
if (v.proto === Date ||
|
|
127
|
+
if (v.proto === Date || concrete.some((b) => b.proto === Date)) {
|
|
118
128
|
return { key, kind, nullable, isDate: true, generated, defaultValue };
|
|
119
129
|
}
|
|
120
130
|
|
|
121
|
-
if (
|
|
131
|
+
if (v.proto === Uint8Array || concrete.some((b) => b.proto === Uint8Array)) {
|
|
132
|
+
return {
|
|
133
|
+
key,
|
|
134
|
+
kind,
|
|
135
|
+
nullable,
|
|
136
|
+
isBlob: true,
|
|
137
|
+
meta,
|
|
138
|
+
generated,
|
|
139
|
+
defaultValue,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (concrete.length > 0 && concrete.every((b) => b.domain === "boolean")) {
|
|
122
144
|
return { key, kind, nullable, isBoolean: true, generated, defaultValue };
|
|
123
145
|
}
|
|
124
146
|
|
|
125
|
-
if (
|
|
147
|
+
if (concrete.some((b) => !!b.structure)) {
|
|
126
148
|
return {
|
|
127
149
|
key,
|
|
128
150
|
kind,
|
|
129
151
|
nullable,
|
|
130
152
|
isJson: true,
|
|
131
153
|
jsonSchema: (parentSchema as any).get(key) as Type,
|
|
132
|
-
meta
|
|
154
|
+
meta,
|
|
133
155
|
generated,
|
|
134
156
|
defaultValue,
|
|
135
157
|
};
|
|
136
158
|
}
|
|
137
159
|
|
|
138
|
-
const branch =
|
|
160
|
+
const branch = concrete[0];
|
|
139
161
|
|
|
140
162
|
return {
|
|
141
163
|
key,
|
|
@@ -143,7 +165,7 @@ export class Database<T extends SchemaRecord> {
|
|
|
143
165
|
nullable,
|
|
144
166
|
domain: branch?.domain,
|
|
145
167
|
isInteger: !!branch?.inner?.divisor,
|
|
146
|
-
meta
|
|
168
|
+
meta,
|
|
147
169
|
generated,
|
|
148
170
|
defaultValue,
|
|
149
171
|
};
|
|
@@ -154,6 +176,10 @@ export class Database<T extends SchemaRecord> {
|
|
|
154
176
|
return "TEXT";
|
|
155
177
|
}
|
|
156
178
|
|
|
179
|
+
if (prop.isBlob) {
|
|
180
|
+
return "BLOB";
|
|
181
|
+
}
|
|
182
|
+
|
|
157
183
|
if (prop.isDate || prop.isBoolean || prop.isInteger) {
|
|
158
184
|
return "INTEGER";
|
|
159
185
|
}
|
|
@@ -202,7 +228,9 @@ export class Database<T extends SchemaRecord> {
|
|
|
202
228
|
return `DEFAULT ${prop.defaultValue}`;
|
|
203
229
|
}
|
|
204
230
|
|
|
205
|
-
throw new Error(
|
|
231
|
+
throw new Error(
|
|
232
|
+
`Unsupported default value type: ${typeof prop.defaultValue} ${JSON.stringify(prop)}`,
|
|
233
|
+
);
|
|
206
234
|
}
|
|
207
235
|
|
|
208
236
|
private columnDef(prop: Prop) {
|
|
@@ -328,8 +356,8 @@ export class Database<T extends SchemaRecord> {
|
|
|
328
356
|
type: this.sqlType(prop),
|
|
329
357
|
notnull: isNotNull,
|
|
330
358
|
defaultValue: defaultClause
|
|
331
|
-
|
|
332
|
-
|
|
359
|
+
? defaultClause.replace("DEFAULT ", "").replace(/^\((.+)\)$/, "$1")
|
|
360
|
+
: null,
|
|
333
361
|
unique: !!prop.meta?.unique,
|
|
334
362
|
references: prop.meta?.references ?? null,
|
|
335
363
|
onDelete: prop.meta?.onDelete?.toUpperCase() ?? null,
|
|
@@ -342,7 +370,12 @@ export class Database<T extends SchemaRecord> {
|
|
|
342
370
|
sql: this.generateCreateIndexSQL(name, indexDef),
|
|
343
371
|
}));
|
|
344
372
|
|
|
345
|
-
desiredTables.push({
|
|
373
|
+
desiredTables.push({
|
|
374
|
+
name,
|
|
375
|
+
sql: this.generateCreateTableSQL(name, props),
|
|
376
|
+
columns,
|
|
377
|
+
indexes,
|
|
378
|
+
});
|
|
346
379
|
}
|
|
347
380
|
|
|
348
381
|
const existing = new Introspector(this.sqlite).introspect();
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { Database } from "bun:sqlite";
|
|
2
|
+
|
|
2
3
|
import type { CompiledQuery, DatabaseConnection, QueryResult } from "kysely";
|
|
3
|
-
|
|
4
|
+
|
|
5
|
+
import { serializeParam } from "./serialize.js";
|
|
4
6
|
|
|
5
7
|
export class BunSqliteConnection implements DatabaseConnection {
|
|
6
8
|
readonly #db: Database;
|
package/src/dialect/dialect.ts
CHANGED
|
@@ -9,8 +9,9 @@ import {
|
|
|
9
9
|
type Kysely,
|
|
10
10
|
type QueryCompiler,
|
|
11
11
|
} from "kysely";
|
|
12
|
-
|
|
13
|
-
import {
|
|
12
|
+
|
|
13
|
+
import type { BunSqliteDialectConfig } from "./config.js";
|
|
14
|
+
import { BunSqliteDriver } from "./driver.js";
|
|
14
15
|
|
|
15
16
|
export class BunSqliteDialect implements Dialect {
|
|
16
17
|
readonly #config: BunSqliteDialectConfig;
|
package/src/dialect/driver.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type { Database } from "bun:sqlite";
|
|
2
|
+
|
|
2
3
|
import { CompiledQuery, type DatabaseConnection, type Driver } from "kysely";
|
|
3
|
-
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
|
|
5
|
+
import type { BunSqliteDialectConfig } from "./config.js";
|
|
6
|
+
import { BunSqliteConnection } from "./connection.js";
|
|
7
|
+
import { ConnectionMutex } from "./mutex.js";
|
|
6
8
|
|
|
7
9
|
export class BunSqliteDriver implements Driver {
|
|
8
10
|
readonly #config: BunSqliteDialectConfig;
|
package/src/env.ts
CHANGED
package/src/generated.ts
CHANGED
|
@@ -3,13 +3,10 @@ import { type } from "arktype";
|
|
|
3
3
|
export type GeneratedPreset = "autoincrement" | "now";
|
|
4
4
|
|
|
5
5
|
const generatedTypes = {
|
|
6
|
-
autoincrement: () =>
|
|
7
|
-
type("number.integer")
|
|
8
|
-
.configure({ _generated: "autoincrement" } as any)
|
|
9
|
-
.default(0),
|
|
6
|
+
autoincrement: () => type("number.integer").configure({ _generated: "autoincrement" }).default(0),
|
|
10
7
|
now: () =>
|
|
11
8
|
type("Date")
|
|
12
|
-
.configure({ _generated: "now" }
|
|
9
|
+
.configure({ _generated: "now" })
|
|
13
10
|
.default(() => new Date(0)),
|
|
14
11
|
};
|
|
15
12
|
|
package/src/index.ts
CHANGED
|
@@ -1,10 +1,19 @@
|
|
|
1
|
-
export { Database } from "./database";
|
|
2
|
-
export { generated, type GeneratedPreset } from "./generated";
|
|
3
|
-
export { JsonParseError } from "./errors";
|
|
4
|
-
export {
|
|
5
|
-
export {
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
export { Database } from "./database.js";
|
|
2
|
+
export { generated, type GeneratedPreset } from "./generated.js";
|
|
3
|
+
export { JsonParseError } from "./errors.js";
|
|
4
|
+
export { jsonArrayFrom, jsonObjectFrom } from "kysely/helpers/sqlite";
|
|
5
|
+
export {
|
|
6
|
+
sql,
|
|
7
|
+
type Selectable,
|
|
8
|
+
type Insertable,
|
|
9
|
+
type Updateable,
|
|
10
|
+
type Kysely,
|
|
11
|
+
type ExpressionBuilder,
|
|
12
|
+
} from "kysely";
|
|
13
|
+
export { type, type Type } from "arktype";
|
|
14
|
+
export { configure } from "arktype/config";
|
|
15
|
+
export { JsonValidationError } from "./validation-error.js";
|
|
16
|
+
export type { DbFieldMeta } from "./env.js";
|
|
8
17
|
export type {
|
|
9
18
|
DatabaseOptions,
|
|
10
19
|
SchemaRecord,
|
|
@@ -16,4 +25,4 @@ export type {
|
|
|
16
25
|
DatabaseSchema,
|
|
17
26
|
JsonValidation,
|
|
18
27
|
SqliteMasterRow,
|
|
19
|
-
} from "./types";
|
|
28
|
+
} from "./types.js";
|
package/src/migration/diff.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ColumnSchema, IntrospectedTable, ColumnCopy, MigrationOp } from "./types";
|
|
1
|
+
import type { ColumnSchema, IntrospectedTable, ColumnCopy, MigrationOp } from "./types.js";
|
|
2
2
|
|
|
3
3
|
export interface DesiredColumn extends ColumnSchema {
|
|
4
4
|
addable: boolean;
|
|
@@ -42,7 +42,11 @@ export class Differ {
|
|
|
42
42
|
const existingTable = this.existing.get(table.name);
|
|
43
43
|
|
|
44
44
|
if (!existingTable) {
|
|
45
|
-
this.ops.push({
|
|
45
|
+
this.ops.push({
|
|
46
|
+
type: "CreateTable",
|
|
47
|
+
table: table.name,
|
|
48
|
+
sql: table.sql,
|
|
49
|
+
});
|
|
46
50
|
this.rebuiltTables.add(table.name);
|
|
47
51
|
continue;
|
|
48
52
|
}
|
|
@@ -101,13 +105,21 @@ export class Differ {
|
|
|
101
105
|
}
|
|
102
106
|
|
|
103
107
|
if (!existing.notnull && col.notnull && col.defaultValue !== null) {
|
|
104
|
-
columnCopies.push({
|
|
108
|
+
columnCopies.push({
|
|
109
|
+
name: col.name,
|
|
110
|
+
expr: `COALESCE("${col.name}", ${col.defaultValue})`,
|
|
111
|
+
});
|
|
105
112
|
} else {
|
|
106
113
|
columnCopies.push({ name: col.name, expr: `"${col.name}"` });
|
|
107
114
|
}
|
|
108
115
|
}
|
|
109
116
|
|
|
110
|
-
this.ops.push({
|
|
117
|
+
this.ops.push({
|
|
118
|
+
type: "RebuildTable",
|
|
119
|
+
table: table.name,
|
|
120
|
+
createSql: table.sql,
|
|
121
|
+
columnCopies,
|
|
122
|
+
});
|
|
111
123
|
this.rebuiltTables.add(table.name);
|
|
112
124
|
}
|
|
113
125
|
|
|
@@ -134,7 +146,11 @@ export class Differ {
|
|
|
134
146
|
}
|
|
135
147
|
|
|
136
148
|
for (const col of newColumns) {
|
|
137
|
-
this.ops.push({
|
|
149
|
+
this.ops.push({
|
|
150
|
+
type: "AddColumn",
|
|
151
|
+
table: table.name,
|
|
152
|
+
columnDef: col.columnDef,
|
|
153
|
+
});
|
|
138
154
|
}
|
|
139
155
|
}
|
|
140
156
|
|
|
@@ -163,7 +179,12 @@ export class Differ {
|
|
|
163
179
|
|
|
164
180
|
if (this.rebuiltTables.has(table.name)) {
|
|
165
181
|
for (const idx of tableIndexes) {
|
|
166
|
-
this.ops.push({
|
|
182
|
+
this.ops.push({
|
|
183
|
+
type: "CreateIndex",
|
|
184
|
+
table: table.name,
|
|
185
|
+
columns: idx.columns,
|
|
186
|
+
sql: idx.sql,
|
|
187
|
+
});
|
|
167
188
|
}
|
|
168
189
|
|
|
169
190
|
continue;
|
|
@@ -180,7 +201,12 @@ export class Differ {
|
|
|
180
201
|
|
|
181
202
|
for (const idx of tableIndexes) {
|
|
182
203
|
if (!existingNames.has(idx.name)) {
|
|
183
|
-
this.ops.push({
|
|
204
|
+
this.ops.push({
|
|
205
|
+
type: "CreateIndex",
|
|
206
|
+
table: table.name,
|
|
207
|
+
columns: idx.columns,
|
|
208
|
+
sql: idx.sql,
|
|
209
|
+
});
|
|
184
210
|
}
|
|
185
211
|
}
|
|
186
212
|
|
package/src/migration/execute.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Database } from "bun:sqlite";
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
import type { IntrospectedColumn, IntrospectedIndex, IntrospectedTable } from "./types.js";
|
|
3
4
|
|
|
4
5
|
type TableListRow = {
|
|
5
6
|
name: string;
|
|
@@ -131,7 +132,8 @@ export class Introspector {
|
|
|
131
132
|
onDelete: fk?.onDelete ?? null,
|
|
132
133
|
hasNulls:
|
|
133
134
|
!isNotnull &&
|
|
134
|
-
this.db.prepare(`SELECT 1 FROM "${table}" WHERE "${col.name}" IS NULL LIMIT 1`).get() !==
|
|
135
|
+
this.db.prepare(`SELECT 1 FROM "${table}" WHERE "${col.name}" IS NULL LIMIT 1`).get() !==
|
|
136
|
+
null,
|
|
135
137
|
});
|
|
136
138
|
}
|
|
137
139
|
|
package/src/plugin.ts
CHANGED
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
ValuesNode,
|
|
13
13
|
ValueNode,
|
|
14
14
|
ColumnNode,
|
|
15
|
+
DefaultInsertValueNode,
|
|
15
16
|
IdentifierNode,
|
|
16
17
|
ReferenceNode,
|
|
17
18
|
ParensNode,
|
|
@@ -19,9 +20,9 @@ import {
|
|
|
19
20
|
SelectQueryNode,
|
|
20
21
|
} from "kysely";
|
|
21
22
|
|
|
22
|
-
import { JsonParseError } from "./errors";
|
|
23
|
-
import type { JsonValidation } from "./types";
|
|
24
|
-
import { JsonValidationError } from "./validation-error";
|
|
23
|
+
import { JsonParseError } from "./errors.js";
|
|
24
|
+
import type { JsonValidation } from "./types.js";
|
|
25
|
+
import { JsonValidationError } from "./validation-error.js";
|
|
25
26
|
|
|
26
27
|
export type ColumnCoercion = "boolean" | "date" | { type: "json"; schema: Type };
|
|
27
28
|
export type ColumnsMap = Map<string, Map<string, ColumnCoercion>>;
|
|
@@ -144,7 +145,18 @@ export class DeserializePlugin implements KyselyPlugin {
|
|
|
144
145
|
}
|
|
145
146
|
|
|
146
147
|
const raw = valueList.values[i];
|
|
147
|
-
|
|
148
|
+
|
|
149
|
+
if (!raw || DefaultInsertValueNode.is(raw)) {
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
yield [col, ValueNode.is(raw) ? raw.value : raw] as [string, unknown];
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
for (const update of node.onConflict?.updates ?? []) {
|
|
158
|
+
if (ColumnNode.is(update.column) && ValueNode.is(update.value)) {
|
|
159
|
+
yield [update.column.column.name, update.value.value] as [string, unknown];
|
|
148
160
|
}
|
|
149
161
|
}
|
|
150
162
|
|
|
@@ -301,7 +313,10 @@ export class DeserializePlugin implements KyselyPlugin {
|
|
|
301
313
|
return match;
|
|
302
314
|
}
|
|
303
315
|
|
|
304
|
-
private resolveSelectionCoercion(
|
|
316
|
+
private resolveSelectionCoercion(
|
|
317
|
+
node: OperationNode,
|
|
318
|
+
scope: Map<string, string>,
|
|
319
|
+
): ResolvedCoercion | null {
|
|
305
320
|
if (AliasNode.is(node)) {
|
|
306
321
|
return this.resolveSelectionCoercion(node.node, scope);
|
|
307
322
|
}
|
|
@@ -341,10 +356,7 @@ export class DeserializePlugin implements KyselyPlugin {
|
|
|
341
356
|
return null;
|
|
342
357
|
}
|
|
343
358
|
|
|
344
|
-
return this.resolveSelectionCoercion(
|
|
345
|
-
node.selections[0]!.selection,
|
|
346
|
-
this.getTableScope(node),
|
|
347
|
-
);
|
|
359
|
+
return this.resolveSelectionCoercion(node.selections[0]!.selection, this.getTableScope(node));
|
|
348
360
|
}
|
|
349
361
|
|
|
350
362
|
private getSelectionOutputName(node: OperationNode) {
|