@easy-cms/drizzle 0.44.0 → 0.46.0
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/index.js +56 -17
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
// src/database.ts
|
|
2
2
|
import { resolve } from "path";
|
|
3
3
|
import { QueryError as QueryError2 } from "@easy-cms/core";
|
|
4
|
-
import { asc as asc3, count, eq as eq3, getTableColumns, getTableName, inArray as inArray3 } from "drizzle-orm";
|
|
4
|
+
import { and as and3, asc as asc3, count, eq as eq3, getTableColumns, getTableName, inArray as inArray3, sql as sql2 } from "drizzle-orm";
|
|
5
5
|
|
|
6
6
|
// src/documents.ts
|
|
7
|
-
import { asc, eq, inArray } from "drizzle-orm";
|
|
7
|
+
import { and, asc, eq, inArray } from "drizzle-orm";
|
|
8
8
|
var col = (model, name) => model.table[name];
|
|
9
9
|
function getAt(data, path) {
|
|
10
10
|
let current = data;
|
|
@@ -154,10 +154,12 @@ async function insertDocument(db, model, data, drafts) {
|
|
|
154
154
|
await insertChildren(db, model, id, data);
|
|
155
155
|
return id;
|
|
156
156
|
}
|
|
157
|
-
async function replaceDocument(db, model, id, data, drafts) {
|
|
158
|
-
await db.update(model.table).set({ ...dataToRow(model, data), ...systemRow(data, drafts) }).where(eq(col(model, "id"), id));
|
|
157
|
+
async function replaceDocument(db, model, id, data, drafts, condition) {
|
|
158
|
+
const updated = await db.update(model.table).set({ ...dataToRow(model, data), ...systemRow(data, drafts) }).where(condition ? and(eq(col(model, "id"), id), condition) : eq(col(model, "id"), id)).returning({ id: col(model, "id") });
|
|
159
|
+
if (updated.length === 0) return false;
|
|
159
160
|
await deleteChildren(db, model, [id]);
|
|
160
161
|
await insertChildren(db, model, id, data);
|
|
162
|
+
return true;
|
|
161
163
|
}
|
|
162
164
|
async function deleteDocument(db, model, id) {
|
|
163
165
|
await deleteChildren(db, model, [id]);
|
|
@@ -387,7 +389,12 @@ function buildTable(builder, name, kind, fields, options) {
|
|
|
387
389
|
}
|
|
388
390
|
);
|
|
389
391
|
if (topLevel && kind === "root" && (field.unique || field.type === "slug") && field.uniqueWithin !== void 0) {
|
|
390
|
-
|
|
392
|
+
const within = [field.uniqueWithin].flat().map(snake);
|
|
393
|
+
indexes.push({
|
|
394
|
+
column,
|
|
395
|
+
unique: true,
|
|
396
|
+
within: within.length === 1 ? within[0] : within
|
|
397
|
+
});
|
|
391
398
|
indexes.push({ column, unique: false });
|
|
392
399
|
} else if (topLevel && kind === "root" && (field.unique || field.type === "slug")) {
|
|
393
400
|
indexes.push({ column, unique: true });
|
|
@@ -404,8 +411,10 @@ function buildTable(builder, name, kind, fields, options) {
|
|
|
404
411
|
columns,
|
|
405
412
|
(t) => indexes.map(({ column, unique, within }) => {
|
|
406
413
|
const col3 = t[column];
|
|
407
|
-
if (within)
|
|
408
|
-
|
|
414
|
+
if (within) {
|
|
415
|
+
const columns2 = [within].flat();
|
|
416
|
+
return dialect.uniqueIndex(`${name}_${columns2.join("_")}_${column}_unique`).on(...columns2.map((w) => t[w]), col3);
|
|
417
|
+
}
|
|
409
418
|
return unique ? dialect.uniqueIndex(`${name}_${column}_unique`).on(col3) : dialect.index(`${name}_${column}_idx`).on(col3);
|
|
410
419
|
})
|
|
411
420
|
);
|
|
@@ -563,7 +572,7 @@ var Migrator = class {
|
|
|
563
572
|
this.options.logger.warn("Schema push drops tables or columns; data in them is lost.");
|
|
564
573
|
}
|
|
565
574
|
await this.runner.transaction([
|
|
566
|
-
...statements.map((
|
|
575
|
+
...statements.map((sql3) => ({ sql: sql3 })),
|
|
567
576
|
this.record(DEV_PUSH, this.options.schema.hash, cur, true)
|
|
568
577
|
]);
|
|
569
578
|
if (statements.length > 0)
|
|
@@ -632,7 +641,7 @@ ${BREAKPOINT}
|
|
|
632
641
|
for (const migration of pending) {
|
|
633
642
|
try {
|
|
634
643
|
await this.runner.transaction([
|
|
635
|
-
...migration.statements.map((
|
|
644
|
+
...migration.statements.map((sql3) => ({ sql: sql3 })),
|
|
636
645
|
this.record(migration.name, migration.hash, migration.snapshot, false)
|
|
637
646
|
]);
|
|
638
647
|
} catch (error) {
|
|
@@ -683,7 +692,7 @@ function timestamp() {
|
|
|
683
692
|
// src/query.ts
|
|
684
693
|
import { parseId, QueryError } from "@easy-cms/core";
|
|
685
694
|
import {
|
|
686
|
-
and,
|
|
695
|
+
and as and2,
|
|
687
696
|
asc as asc2,
|
|
688
697
|
desc,
|
|
689
698
|
eq as eq2,
|
|
@@ -903,12 +912,12 @@ var WhereBuilder = class {
|
|
|
903
912
|
if (key === "and" || key === "or") {
|
|
904
913
|
if (!Array.isArray(value)) throw new QueryError(`"${key}" must be an array`);
|
|
905
914
|
const inner = value.map((w) => this.build(model, w)).filter((s) => s !== void 0);
|
|
906
|
-
if (inner.length > 0) parts.push(key === "and" ?
|
|
915
|
+
if (inner.length > 0) parts.push(key === "and" ? and2(...inner) : or(...inner));
|
|
907
916
|
continue;
|
|
908
917
|
}
|
|
909
918
|
parts.push(this.field(model, key, value));
|
|
910
919
|
}
|
|
911
|
-
return parts.length === 0 ? void 0 : parts.length === 1 ? parts[0] :
|
|
920
|
+
return parts.length === 0 ? void 0 : parts.length === 1 ? parts[0] : and2(...parts);
|
|
912
921
|
}
|
|
913
922
|
field(model, path, operators) {
|
|
914
923
|
if (typeof operators !== "object" || operators === null || Array.isArray(operators)) {
|
|
@@ -929,7 +938,7 @@ var WhereBuilder = class {
|
|
|
929
938
|
if (target.kind === "blocks") return this.blocks(target, op, value, path);
|
|
930
939
|
return this.child(model, target.child, target.rest, op, value, path, target.locale);
|
|
931
940
|
});
|
|
932
|
-
return parts.length === 1 ? parts[0] :
|
|
941
|
+
return parts.length === 1 ? parts[0] : and2(...parts);
|
|
933
942
|
}
|
|
934
943
|
/**
|
|
935
944
|
* Conditions inside blocks test the JSON rows: some block (and, for nested lists, some row in
|
|
@@ -976,9 +985,9 @@ var WhereBuilder = class {
|
|
|
976
985
|
child(parent, child, rest, op, value, path, locale) {
|
|
977
986
|
const table = child.table;
|
|
978
987
|
const parentLink = eq2(col2(table, "_parent_id"), col2(parent, "id"));
|
|
979
|
-
const link = locale === void 0 ? parentLink :
|
|
988
|
+
const link = locale === void 0 ? parentLink : and2(parentLink, eq2(col2(table, "_locale"), locale));
|
|
980
989
|
const subquery = (condition) => exists(
|
|
981
|
-
this.db.select({ one: sql`1` }).from(table.table).where(condition ?
|
|
990
|
+
this.db.select({ one: sql`1` }).from(table.table).where(condition ? and2(link, condition) : link)
|
|
982
991
|
);
|
|
983
992
|
if (child.kind === "values") {
|
|
984
993
|
if (rest.length > 0) throw new QueryError(`Cannot query inside "${path}"`);
|
|
@@ -1150,13 +1159,43 @@ var DrizzleDatabase = class {
|
|
|
1150
1159
|
}
|
|
1151
1160
|
async update(args) {
|
|
1152
1161
|
const model = this.model(args.collection);
|
|
1153
|
-
|
|
1162
|
+
const condition = args.where ? this.where(args.collection, args.where) : void 0;
|
|
1163
|
+
const written = await this.write(
|
|
1154
1164
|
() => this.db.transaction(
|
|
1155
|
-
(tx) => replaceDocument(
|
|
1165
|
+
(tx) => replaceDocument(
|
|
1166
|
+
tx,
|
|
1167
|
+
model.root,
|
|
1168
|
+
args.id,
|
|
1169
|
+
args.data,
|
|
1170
|
+
model.config.drafts === true,
|
|
1171
|
+
condition
|
|
1172
|
+
)
|
|
1156
1173
|
)
|
|
1157
1174
|
);
|
|
1175
|
+
if (!written) return null;
|
|
1158
1176
|
return await this.findById({ collection: args.collection, id: args.id });
|
|
1159
1177
|
}
|
|
1178
|
+
async increment(args) {
|
|
1179
|
+
const model = this.model(args.collection);
|
|
1180
|
+
const target = model.root.columns.find(
|
|
1181
|
+
(c) => c.locale === void 0 && c.path.length === 1 && c.path[0] === args.field
|
|
1182
|
+
);
|
|
1183
|
+
if (target?.field.type !== "number")
|
|
1184
|
+
throw new QueryError2(
|
|
1185
|
+
`"${args.field}" of "${args.collection}" is not a top-level number field`
|
|
1186
|
+
);
|
|
1187
|
+
if (!Number.isFinite(args.by)) throw new QueryError2('increment: "by" must be a number');
|
|
1188
|
+
const column = model.root.table[target.column];
|
|
1189
|
+
const next = sql2`coalesce(${column}, 0) + ${args.by}`;
|
|
1190
|
+
const conditions = [eq3(model.root.table.id, args.id)];
|
|
1191
|
+
if (args.min !== void 0) conditions.push(sql2`${next} >= ${args.min}`);
|
|
1192
|
+
if (args.max !== void 0) conditions.push(sql2`${next} <= ${args.max}`);
|
|
1193
|
+
const rows = await this.write(
|
|
1194
|
+
() => this.db.update(model.root.table).set({ [target.column]: next }).where(and3(...conditions)).returning({ value: column })
|
|
1195
|
+
);
|
|
1196
|
+
const [row] = rows;
|
|
1197
|
+
return row ? Number(row.value) : null;
|
|
1198
|
+
}
|
|
1160
1199
|
async delete(args) {
|
|
1161
1200
|
const model = this.model(args.collection);
|
|
1162
1201
|
await this.write(
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@easy-cms/drizzle",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.46.0",
|
|
4
4
|
"description": "Shared Drizzle ORM layer for Easy CMS database adapters",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -23,10 +23,10 @@
|
|
|
23
23
|
"drizzle-orm": "0.45.3"
|
|
24
24
|
},
|
|
25
25
|
"peerDependencies": {
|
|
26
|
-
"@easy-cms/core": "^0.
|
|
26
|
+
"@easy-cms/core": "^0.46.0"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
|
-
"@easy-cms/core": "^0.
|
|
29
|
+
"@easy-cms/core": "^0.46.0"
|
|
30
30
|
},
|
|
31
31
|
"publishConfig": {
|
|
32
32
|
"access": "public"
|