@nextlyhq/adapter-drizzle 0.0.2-alpha.4 → 0.0.2-alpha.41
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/dist/{adapter-nvlxFkF-.d.cts → adapter-CbGoHa-2.d.cts} +49 -56
- package/dist/{adapter-BxJVtttb.d.ts → adapter-D1vI8njz.d.ts} +49 -56
- package/dist/index.cjs +176 -38
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.mjs +177 -39
- package/dist/index.mjs.map +1 -1
- package/dist/{migration-BbO5meEV.d.cts → migration-B41DME-y.d.cts} +42 -0
- package/dist/{migration-Qe70wDOC.d.ts → migration-XV8CXMZT.d.ts} +42 -0
- package/dist/migrations.d.cts +4 -3
- package/dist/migrations.d.ts +4 -3
- package/dist/types/index.d.cts +1 -1
- package/dist/types/index.d.ts +1 -1
- package/package.json +9 -9
package/dist/index.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getColumns, desc, asc, and, or, not, like, notBetween, between, isNotNull, isNull, notInArray, inArray, ilike, lte, gte, lt, gt, ne, eq } from 'drizzle-orm';
|
|
2
2
|
|
|
3
3
|
// src/adapter.ts
|
|
4
4
|
function buildDrizzleWhere(table, where) {
|
|
5
|
-
const columns =
|
|
5
|
+
const columns = getColumns(table);
|
|
6
6
|
return processWhereClause(columns, where);
|
|
7
7
|
}
|
|
8
8
|
function processWhereClause(columns, where) {
|
|
@@ -106,6 +106,21 @@ function createDatabaseError(options) {
|
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
// src/adapter.ts
|
|
109
|
+
function affectedRowCount(result) {
|
|
110
|
+
if (Array.isArray(result)) {
|
|
111
|
+
const header = result[0];
|
|
112
|
+
if (header && typeof header.affectedRows === "number") {
|
|
113
|
+
return header.affectedRows;
|
|
114
|
+
}
|
|
115
|
+
return result.length;
|
|
116
|
+
}
|
|
117
|
+
const record = result;
|
|
118
|
+
const rowCount = record?.rowCount;
|
|
119
|
+
if (typeof rowCount === "number") return rowCount;
|
|
120
|
+
const changes = record?.changes;
|
|
121
|
+
if (typeof changes === "number") return changes;
|
|
122
|
+
return 0;
|
|
123
|
+
}
|
|
109
124
|
var DrizzleAdapter = class {
|
|
110
125
|
// ============================================================
|
|
111
126
|
// Drizzle Query API Support
|
|
@@ -173,6 +188,107 @@ var DrizzleAdapter = class {
|
|
|
173
188
|
}
|
|
174
189
|
return mapped;
|
|
175
190
|
}
|
|
191
|
+
/**
|
|
192
|
+
* Map data keys from Drizzle JS property names to SQL column names for the
|
|
193
|
+
* raw-SQL transaction insert path. The transaction context builds INSERT
|
|
194
|
+
* statements from Object.keys(data) used directly as column identifiers, so a
|
|
195
|
+
* table whose Drizzle property names differ from its SQL column names
|
|
196
|
+
* (camelCase core tables like nextly_versions) needs its keys translated
|
|
197
|
+
* first. For tables whose property names already equal their column names
|
|
198
|
+
* (the dynamic dc_/single_/comp_ tables) every lookup is identity, so
|
|
199
|
+
* existing callers are unaffected.
|
|
200
|
+
*/
|
|
201
|
+
mapKeysToSqlColumns(tableObj, data) {
|
|
202
|
+
if (!tableObj || typeof tableObj !== "object") return data;
|
|
203
|
+
const jsToSql = /* @__PURE__ */ new Map();
|
|
204
|
+
for (const [jsName, colDef] of Object.entries(
|
|
205
|
+
tableObj
|
|
206
|
+
)) {
|
|
207
|
+
if (colDef && typeof colDef === "object" && "name" in colDef && typeof colDef.name === "string") {
|
|
208
|
+
jsToSql.set(jsName, colDef.name);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
if (jsToSql.size === 0) return data;
|
|
212
|
+
const out = {};
|
|
213
|
+
for (const [key, value] of Object.entries(data)) {
|
|
214
|
+
out[jsToSql.get(key) ?? key] = value;
|
|
215
|
+
}
|
|
216
|
+
return out;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Map a list of column identifiers (Drizzle property names) to their SQL
|
|
220
|
+
* column names, for the raw-SQL transaction insert paths that build a
|
|
221
|
+
* RETURNING clause from `options.returning`. Same identity behavior as
|
|
222
|
+
* `mapKeysToSqlColumns`: names that are already SQL columns (the dynamic
|
|
223
|
+
* dc_/single_/comp_ tables) pass through unchanged.
|
|
224
|
+
*/
|
|
225
|
+
mapColumnNamesToSql(tableObj, names) {
|
|
226
|
+
if (!tableObj || typeof tableObj !== "object") return names;
|
|
227
|
+
const jsToSql = /* @__PURE__ */ new Map();
|
|
228
|
+
for (const [jsName, colDef] of Object.entries(
|
|
229
|
+
tableObj
|
|
230
|
+
)) {
|
|
231
|
+
if (colDef && typeof colDef === "object" && "name" in colDef && typeof colDef.name === "string") {
|
|
232
|
+
jsToSql.set(jsName, colDef.name);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
if (jsToSql.size === 0) return names;
|
|
236
|
+
return names.map((n) => jsToSql.get(n) ?? n);
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Remap a raw-SQL result row's KEYS from SQL column names to Drizzle property
|
|
240
|
+
* names, so the raw-SQL transaction insert paths return the same key casing
|
|
241
|
+
* as the non-transactional (Drizzle) insert. Keys only - values are left
|
|
242
|
+
* untouched, so this does not change how JSON/date columns are decoded. For
|
|
243
|
+
* tables whose property names already equal their SQL columns (the dynamic
|
|
244
|
+
* dc_/single_/comp_ tables) every lookup is identity, so existing callers see
|
|
245
|
+
* no change.
|
|
246
|
+
*/
|
|
247
|
+
mapRowKeysToJs(tableObj, row) {
|
|
248
|
+
if (!tableObj || typeof tableObj !== "object" || !row || typeof row !== "object") {
|
|
249
|
+
return row;
|
|
250
|
+
}
|
|
251
|
+
const sqlToJs = /* @__PURE__ */ new Map();
|
|
252
|
+
for (const [jsName, colDef] of Object.entries(
|
|
253
|
+
tableObj
|
|
254
|
+
)) {
|
|
255
|
+
if (colDef && typeof colDef === "object" && "name" in colDef && typeof colDef.name === "string") {
|
|
256
|
+
sqlToJs.set(colDef.name, jsName);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
if (sqlToJs.size === 0) return row;
|
|
260
|
+
const out = {};
|
|
261
|
+
for (const [key, value] of Object.entries(row)) {
|
|
262
|
+
out[sqlToJs.get(key) ?? key] = value;
|
|
263
|
+
}
|
|
264
|
+
return out;
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Build a Drizzle column projection object (`{ propertyName: column }`) from a
|
|
268
|
+
* requested column list, used by `select` (columns) and `insert` (returning).
|
|
269
|
+
* A requested name resolves against either the Drizzle property name
|
|
270
|
+
* (camelCase) or the SQL column name (snake_case); the projection is keyed by
|
|
271
|
+
* the property name so the row shape matches a full select. Returns undefined
|
|
272
|
+
* for `"*"` or when nothing resolves, so callers fall back to all columns.
|
|
273
|
+
*/
|
|
274
|
+
buildColumnProjection(tableObj, names) {
|
|
275
|
+
if (names == null || names === "*" || !tableObj || typeof tableObj !== "object") {
|
|
276
|
+
return void 0;
|
|
277
|
+
}
|
|
278
|
+
const cols = getColumns(tableObj);
|
|
279
|
+
const byAnyName = {};
|
|
280
|
+
for (const [jsName, col] of Object.entries(cols)) {
|
|
281
|
+
byAnyName[jsName] = { jsName, col };
|
|
282
|
+
const sqlName = col?.name;
|
|
283
|
+
if (typeof sqlName === "string") byAnyName[sqlName] = { jsName, col };
|
|
284
|
+
}
|
|
285
|
+
const projection = {};
|
|
286
|
+
for (const name of names) {
|
|
287
|
+
const hit = byAnyName[name];
|
|
288
|
+
if (hit) projection[hit.jsName] = hit.col;
|
|
289
|
+
}
|
|
290
|
+
return Object.keys(projection).length ? projection : void 0;
|
|
291
|
+
}
|
|
176
292
|
// ============================================================
|
|
177
293
|
// Connection Status (Default implementations, can override)
|
|
178
294
|
// ============================================================
|
|
@@ -326,12 +442,13 @@ var DrizzleAdapter = class {
|
|
|
326
442
|
* });
|
|
327
443
|
* ```
|
|
328
444
|
*/
|
|
329
|
-
async select(table, options) {
|
|
445
|
+
async select(table, options, executor) {
|
|
330
446
|
const tableObj = this.getTableObject(table);
|
|
331
447
|
if (tableObj) {
|
|
332
448
|
try {
|
|
333
|
-
const db = this.getDrizzle();
|
|
334
|
-
|
|
449
|
+
const db = executor ?? this.getDrizzle();
|
|
450
|
+
const projection = options?.columns?.length ? this.buildColumnProjection(tableObj, options.columns) : void 0;
|
|
451
|
+
let query = projection ? db.select(projection).from(tableObj) : db.select().from(tableObj);
|
|
335
452
|
if (options?.where) {
|
|
336
453
|
const whereCondition = buildDrizzleWhere(
|
|
337
454
|
tableObj,
|
|
@@ -342,7 +459,7 @@ var DrizzleAdapter = class {
|
|
|
342
459
|
}
|
|
343
460
|
}
|
|
344
461
|
if (options?.orderBy?.length) {
|
|
345
|
-
const columns =
|
|
462
|
+
const columns = getColumns(tableObj);
|
|
346
463
|
const orderClauses = options.orderBy.map((o) => {
|
|
347
464
|
const col = columns[o.column];
|
|
348
465
|
if (!col) return void 0;
|
|
@@ -358,6 +475,16 @@ var DrizzleAdapter = class {
|
|
|
358
475
|
if (options?.offset !== void 0) {
|
|
359
476
|
query = query.offset(options.offset);
|
|
360
477
|
}
|
|
478
|
+
if (options?.forUpdate && !executor) {
|
|
479
|
+
throw this.createDatabaseError(
|
|
480
|
+
"query",
|
|
481
|
+
"forUpdate requires a transaction executor: a lock request on the pooled connection takes no durable lock and cannot prevent a concurrent write.",
|
|
482
|
+
void 0
|
|
483
|
+
);
|
|
484
|
+
}
|
|
485
|
+
if (options?.forUpdate && this.dialect !== "sqlite") {
|
|
486
|
+
query = query.for("update");
|
|
487
|
+
}
|
|
361
488
|
return await query;
|
|
362
489
|
} catch (error) {
|
|
363
490
|
throw this.handleQueryError(error, "select", table);
|
|
@@ -389,8 +516,12 @@ var DrizzleAdapter = class {
|
|
|
389
516
|
* });
|
|
390
517
|
* ```
|
|
391
518
|
*/
|
|
392
|
-
async selectOne(table, options) {
|
|
393
|
-
const results = await this.select(
|
|
519
|
+
async selectOne(table, options, executor) {
|
|
520
|
+
const results = await this.select(
|
|
521
|
+
table,
|
|
522
|
+
{ ...options, limit: 1 },
|
|
523
|
+
executor
|
|
524
|
+
);
|
|
394
525
|
return results.length > 0 ? results[0] : null;
|
|
395
526
|
}
|
|
396
527
|
/**
|
|
@@ -422,19 +553,22 @@ var DrizzleAdapter = class {
|
|
|
422
553
|
const mappedData = this.mapDataToColumnNames(tableObj, data);
|
|
423
554
|
const db = this.getDrizzle();
|
|
424
555
|
const caps = this.getCapabilities();
|
|
425
|
-
|
|
426
|
-
|
|
556
|
+
const returning = options?.returning;
|
|
557
|
+
const wantsReturning = returning != null && !(Array.isArray(returning) && returning.length === 0);
|
|
558
|
+
if (caps.supportsReturning && wantsReturning) {
|
|
559
|
+
const projection = this.buildColumnProjection(tableObj, returning);
|
|
560
|
+
const insertQuery = db.insert(tableObj).values(mappedData);
|
|
561
|
+
const result2 = await (projection ? insertQuery.returning(projection) : insertQuery.returning());
|
|
427
562
|
return Array.isArray(result2) ? result2[0] : result2;
|
|
428
563
|
}
|
|
429
564
|
const result = await db.insert(tableObj).values(mappedData);
|
|
430
|
-
if (!caps.supportsReturning &&
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
}
|
|
565
|
+
if (!caps.supportsReturning && wantsReturning && data.id !== void 0) {
|
|
566
|
+
return await this.selectOne(table, {
|
|
567
|
+
columns: returning === "*" ? void 0 : returning,
|
|
568
|
+
where: {
|
|
569
|
+
and: [{ column: "id", op: "=", value: data.id }]
|
|
570
|
+
}
|
|
571
|
+
});
|
|
438
572
|
}
|
|
439
573
|
return Array.isArray(result) ? result[0] : result;
|
|
440
574
|
} catch (error) {
|
|
@@ -504,11 +638,11 @@ var DrizzleAdapter = class {
|
|
|
504
638
|
* );
|
|
505
639
|
* ```
|
|
506
640
|
*/
|
|
507
|
-
async update(table, data, where, options) {
|
|
641
|
+
async update(table, data, where, options, executor) {
|
|
508
642
|
const tableObj = this.getTableObject(table);
|
|
509
643
|
if (tableObj) {
|
|
510
644
|
try {
|
|
511
|
-
const db = this.getDrizzle();
|
|
645
|
+
const db = executor ?? this.getDrizzle();
|
|
512
646
|
const caps = this.getCapabilities();
|
|
513
647
|
const mappedData = this.mapDataToColumnNames(tableObj, data);
|
|
514
648
|
let query = db.update(tableObj).set(mappedData);
|
|
@@ -521,7 +655,7 @@ var DrizzleAdapter = class {
|
|
|
521
655
|
}
|
|
522
656
|
await query;
|
|
523
657
|
if (!caps.supportsReturning && options?.returning) {
|
|
524
|
-
return await this.select(table, { where });
|
|
658
|
+
return await this.select(table, { where }, executor);
|
|
525
659
|
}
|
|
526
660
|
return [];
|
|
527
661
|
} catch (error) {
|
|
@@ -556,18 +690,18 @@ var DrizzleAdapter = class {
|
|
|
556
690
|
* console.log(`Deleted ${count} users`);
|
|
557
691
|
* ```
|
|
558
692
|
*/
|
|
559
|
-
async delete(table, where, _options) {
|
|
693
|
+
async delete(table, where, _options, executor) {
|
|
560
694
|
const tableObj = this.getTableObject(table);
|
|
561
695
|
if (tableObj) {
|
|
562
696
|
try {
|
|
563
|
-
const db = this.getDrizzle();
|
|
697
|
+
const db = executor ?? this.getDrizzle();
|
|
564
698
|
let query = db.delete(tableObj);
|
|
565
699
|
const whereCondition = buildDrizzleWhere(tableObj, where);
|
|
566
700
|
if (whereCondition) {
|
|
567
701
|
query = query.where(whereCondition);
|
|
568
702
|
}
|
|
569
703
|
const result = await query;
|
|
570
|
-
return
|
|
704
|
+
return affectedRowCount(result);
|
|
571
705
|
} catch (error) {
|
|
572
706
|
throw this.handleQueryError(error, "delete", table);
|
|
573
707
|
}
|
|
@@ -605,13 +739,13 @@ var DrizzleAdapter = class {
|
|
|
605
739
|
* });
|
|
606
740
|
* ```
|
|
607
741
|
*/
|
|
608
|
-
async upsert(table, data, options) {
|
|
742
|
+
async upsert(table, data, options, executor) {
|
|
609
743
|
const tableObj = this.getTableObject(table);
|
|
610
744
|
if (tableObj) {
|
|
611
745
|
try {
|
|
612
|
-
const db = this.getDrizzle();
|
|
746
|
+
const db = executor ?? this.getDrizzle();
|
|
613
747
|
const caps = this.getCapabilities();
|
|
614
|
-
const columns =
|
|
748
|
+
const columns = getColumns(tableObj);
|
|
615
749
|
const conflictTarget = options.conflictColumns.map((col) => columns[col]).filter(Boolean);
|
|
616
750
|
const conflictSet = new Set(options.conflictColumns);
|
|
617
751
|
const updateData = {};
|
|
@@ -636,17 +770,21 @@ var DrizzleAdapter = class {
|
|
|
636
770
|
}
|
|
637
771
|
await query;
|
|
638
772
|
if (options.conflictColumns.length && data[options.conflictColumns[0]] !== void 0) {
|
|
639
|
-
return await this.selectOne(
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
773
|
+
return await this.selectOne(
|
|
774
|
+
table,
|
|
775
|
+
{
|
|
776
|
+
where: {
|
|
777
|
+
and: [
|
|
778
|
+
{
|
|
779
|
+
column: options.conflictColumns[0],
|
|
780
|
+
op: "=",
|
|
781
|
+
value: data[options.conflictColumns[0]]
|
|
782
|
+
}
|
|
783
|
+
]
|
|
784
|
+
}
|
|
785
|
+
},
|
|
786
|
+
executor
|
|
787
|
+
);
|
|
650
788
|
}
|
|
651
789
|
return data;
|
|
652
790
|
} catch (error) {
|
|
@@ -972,7 +1110,7 @@ var DrizzleAdapter = class {
|
|
|
972
1110
|
break;
|
|
973
1111
|
case "mysql":
|
|
974
1112
|
sql = `
|
|
975
|
-
SELECT table_name
|
|
1113
|
+
SELECT table_name AS table_name
|
|
976
1114
|
FROM information_schema.tables
|
|
977
1115
|
WHERE table_schema = DATABASE()
|
|
978
1116
|
AND table_type = 'BASE TABLE'
|