@easy-cms/drizzle 0.45.0 → 0.47.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.
Files changed (2) hide show
  1. package/dist/index.js +46 -14
  2. 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]);
@@ -570,7 +572,7 @@ var Migrator = class {
570
572
  this.options.logger.warn("Schema push drops tables or columns; data in them is lost.");
571
573
  }
572
574
  await this.runner.transaction([
573
- ...statements.map((sql2) => ({ sql: sql2 })),
575
+ ...statements.map((sql3) => ({ sql: sql3 })),
574
576
  this.record(DEV_PUSH, this.options.schema.hash, cur, true)
575
577
  ]);
576
578
  if (statements.length > 0)
@@ -639,7 +641,7 @@ ${BREAKPOINT}
639
641
  for (const migration of pending) {
640
642
  try {
641
643
  await this.runner.transaction([
642
- ...migration.statements.map((sql2) => ({ sql: sql2 })),
644
+ ...migration.statements.map((sql3) => ({ sql: sql3 })),
643
645
  this.record(migration.name, migration.hash, migration.snapshot, false)
644
646
  ]);
645
647
  } catch (error) {
@@ -690,7 +692,7 @@ function timestamp() {
690
692
  // src/query.ts
691
693
  import { parseId, QueryError } from "@easy-cms/core";
692
694
  import {
693
- and,
695
+ and as and2,
694
696
  asc as asc2,
695
697
  desc,
696
698
  eq as eq2,
@@ -910,12 +912,12 @@ var WhereBuilder = class {
910
912
  if (key === "and" || key === "or") {
911
913
  if (!Array.isArray(value)) throw new QueryError(`"${key}" must be an array`);
912
914
  const inner = value.map((w) => this.build(model, w)).filter((s) => s !== void 0);
913
- if (inner.length > 0) parts.push(key === "and" ? and(...inner) : or(...inner));
915
+ if (inner.length > 0) parts.push(key === "and" ? and2(...inner) : or(...inner));
914
916
  continue;
915
917
  }
916
918
  parts.push(this.field(model, key, value));
917
919
  }
918
- return parts.length === 0 ? void 0 : parts.length === 1 ? parts[0] : and(...parts);
920
+ return parts.length === 0 ? void 0 : parts.length === 1 ? parts[0] : and2(...parts);
919
921
  }
920
922
  field(model, path, operators) {
921
923
  if (typeof operators !== "object" || operators === null || Array.isArray(operators)) {
@@ -936,7 +938,7 @@ var WhereBuilder = class {
936
938
  if (target.kind === "blocks") return this.blocks(target, op, value, path);
937
939
  return this.child(model, target.child, target.rest, op, value, path, target.locale);
938
940
  });
939
- return parts.length === 1 ? parts[0] : and(...parts);
941
+ return parts.length === 1 ? parts[0] : and2(...parts);
940
942
  }
941
943
  /**
942
944
  * Conditions inside blocks test the JSON rows: some block (and, for nested lists, some row in
@@ -983,9 +985,9 @@ var WhereBuilder = class {
983
985
  child(parent, child, rest, op, value, path, locale) {
984
986
  const table = child.table;
985
987
  const parentLink = eq2(col2(table, "_parent_id"), col2(parent, "id"));
986
- const link = locale === void 0 ? parentLink : and(parentLink, eq2(col2(table, "_locale"), locale));
988
+ const link = locale === void 0 ? parentLink : and2(parentLink, eq2(col2(table, "_locale"), locale));
987
989
  const subquery = (condition) => exists(
988
- this.db.select({ one: sql`1` }).from(table.table).where(condition ? and(link, condition) : link)
990
+ this.db.select({ one: sql`1` }).from(table.table).where(condition ? and2(link, condition) : link)
989
991
  );
990
992
  if (child.kind === "values") {
991
993
  if (rest.length > 0) throw new QueryError(`Cannot query inside "${path}"`);
@@ -1157,13 +1159,43 @@ var DrizzleDatabase = class {
1157
1159
  }
1158
1160
  async update(args) {
1159
1161
  const model = this.model(args.collection);
1160
- await this.write(
1162
+ const condition = args.where ? this.where(args.collection, args.where) : void 0;
1163
+ const written = await this.write(
1161
1164
  () => this.db.transaction(
1162
- (tx) => replaceDocument(tx, model.root, args.id, args.data, model.config.drafts === true)
1165
+ (tx) => replaceDocument(
1166
+ tx,
1167
+ model.root,
1168
+ args.id,
1169
+ args.data,
1170
+ model.config.drafts === true,
1171
+ condition
1172
+ )
1163
1173
  )
1164
1174
  );
1175
+ if (!written) return null;
1165
1176
  return await this.findById({ collection: args.collection, id: args.id });
1166
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
+ }
1167
1199
  async delete(args) {
1168
1200
  const model = this.model(args.collection);
1169
1201
  await this.write(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@easy-cms/drizzle",
3
- "version": "0.45.0",
3
+ "version": "0.47.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.45.0"
26
+ "@easy-cms/core": "^0.47.0"
27
27
  },
28
28
  "devDependencies": {
29
- "@easy-cms/core": "^0.45.0"
29
+ "@easy-cms/core": "^0.47.0"
30
30
  },
31
31
  "publishConfig": {
32
32
  "access": "public"