opacacms 0.1.21 → 0.2.1
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 +792 -50
- package/dist/admin/auth-client.d.ts +39 -39
- package/dist/admin/index.js +2360 -1392
- package/dist/admin/react.d.ts +1 -1
- package/dist/admin/react.js +8 -0
- package/dist/admin/router.d.ts +1 -0
- package/dist/admin/stores/ui.d.ts +10 -0
- package/dist/admin/ui/admin-layout.d.ts +4 -4
- package/dist/admin/ui/components/DataDetailView.d.ts +1 -1
- package/dist/admin/ui/components/DetailSheet.d.ts +19 -0
- package/dist/admin/ui/components/PluginSettingsForm.d.ts +11 -0
- package/dist/admin/ui/components/fields/BooleanField.d.ts +2 -1
- package/dist/admin/ui/components/fields/DateField.d.ts +1 -1
- package/dist/admin/ui/components/fields/FieldLabel.d.ts +11 -0
- package/dist/admin/ui/components/fields/FileField.d.ts +1 -1
- package/dist/admin/ui/components/fields/NumberField.d.ts +1 -1
- package/dist/admin/ui/components/fields/RadioField.d.ts +1 -1
- package/dist/admin/ui/components/fields/RelationshipField.d.ts +3 -1
- package/dist/admin/ui/components/fields/SelectField.d.ts +1 -1
- package/dist/admin/ui/components/fields/TextAreaField.d.ts +1 -1
- package/dist/admin/ui/components/fields/TextField.d.ts +1 -1
- package/dist/admin/ui/components/fields/VirtualField.d.ts +1 -0
- package/dist/admin/ui/components/fields/index.d.ts +16 -16
- package/dist/admin/ui/components/fields/richtext-editor/index.d.ts +1 -1
- package/dist/admin/ui/components/media/AssetManagerModal.d.ts +1 -1
- package/dist/admin/ui/components/toast.d.ts +1 -1
- package/dist/admin/ui/components/ui/accordion.d.ts +1 -1
- package/dist/admin/ui/components/ui/button.d.ts +1 -1
- package/dist/admin/ui/components/ui/collapsible.d.ts +1 -1
- package/dist/admin/ui/components/ui/dialog.d.ts +1 -1
- package/dist/admin/ui/components/ui/group.d.ts +1 -1
- package/dist/admin/ui/components/ui/index.d.ts +17 -17
- package/dist/admin/ui/components/ui/input.d.ts +1 -1
- package/dist/admin/ui/components/ui/label.d.ts +1 -1
- package/dist/admin/ui/components/ui/radio-group.d.ts +1 -1
- package/dist/admin/ui/components/ui/relationship.d.ts +4 -4
- package/dist/admin/ui/components/ui/select.d.ts +1 -1
- package/dist/admin/ui/components/ui/sheet.d.ts +1 -1
- package/dist/admin/ui/components/ui/tabs.d.ts +1 -1
- package/dist/admin/ui/components/versions-sheet.d.ts +11 -0
- package/dist/admin/ui/views/media-registry-view.d.ts +1 -1
- package/dist/admin/ui/views/settings-view.d.ts +2 -2
- package/dist/admin/vue.js +8 -0
- package/dist/admin/webcomponent.js +20 -2
- package/dist/admin.css +1 -1
- package/dist/auth/index.d.ts +101 -41
- package/dist/{chunk-fqastxq9.js → chunk-06ks4ggh.js} +133 -44
- package/dist/{chunk-xrfhhz85.js → chunk-2es275xs.js} +480 -85
- package/dist/{chunk-v521d72w.js → chunk-3rdhbedb.js} +1 -1
- package/dist/chunk-51z3x7kq.js +20 -0
- package/dist/{chunk-7fyepksb.js → chunk-526a3gqx.js} +1 -1
- package/dist/{chunk-0sdceeys.js → chunk-6d1vdfwa.js} +121 -31
- package/dist/{chunk-wmvjvn7b.js → chunk-6qq3ne6b.js} +39 -1
- package/dist/{chunk-0am1m47g.js → chunk-6v1fw7q7.js} +5 -5
- package/dist/{chunk-t9v845m2.js → chunk-7y1nbmw6.js} +34 -3
- package/dist/chunk-8scgdznr.js +44 -0
- package/dist/{chunk-mycmsjd9.js → chunk-b3kr8w41.js} +57 -6
- package/dist/chunk-bexcv7xe.js +36 -0
- package/dist/{chunk-ekxkvqjm.js → chunk-bygjkgrx.js} +124 -34
- package/dist/{chunk-16vgcf3k.js → chunk-byq8g0rd.js} +1 -1
- package/dist/{chunk-cpw2y3pn.js → chunk-dykn5hr6.js} +7 -7
- package/dist/chunk-fj19qccp.js +78 -0
- package/dist/{chunk-n1xraw7j.js → chunk-g1jb60xd.js} +1 -1
- package/dist/{chunk-xa7rjsn2.js → chunk-j53pz21t.js} +2 -2
- package/dist/{chunk-nb7ctdg8.js → chunk-jdfw4v3r.js} +1 -1
- package/dist/chunk-mkn49zmy.js +102 -0
- package/dist/{chunk-59sg3pw9.js → chunk-n133qpsm.js} +128 -34
- package/dist/{chunk-2kyhqvhc.js → chunk-qxt9vge8.js} +1 -1
- package/dist/chunk-r39em4yj.js +29 -0
- package/dist/chunk-rqyjjqgy.js +91 -0
- package/dist/chunk-rsf0tpy1.js +8 -0
- package/dist/chunk-t0zg026p.js +71 -0
- package/dist/{chunk-61kwqve4.js → chunk-tfnaf41w.js} +118 -37
- package/dist/chunk-twpvxfce.js +64 -0
- package/dist/{chunk-ybbbqj63.js → chunk-v9z61v3g.js} +15 -0
- package/dist/{chunk-jwjk85ze.js → chunk-ywm4t2gm.js} +6 -2
- package/dist/cli/commands/plugin-build.d.ts +1 -0
- package/dist/cli/commands/plugin-init.d.ts +1 -0
- package/dist/cli/commands/plugin-sync.d.ts +1 -0
- package/dist/cli/index.js +24 -6
- package/dist/config-utils.d.ts +1 -1
- package/dist/config.d.ts +21 -4
- package/dist/db/adapter.d.ts +2 -2
- package/dist/db/better-sqlite.d.ts +2 -1
- package/dist/db/better-sqlite.js +5 -5
- package/dist/db/bun-sqlite.d.ts +2 -1
- package/dist/db/bun-sqlite.js +5 -5
- package/dist/db/d1.d.ts +1 -1
- package/dist/db/d1.js +5 -5
- package/dist/db/index.js +9 -9
- package/dist/db/postgres.d.ts +3 -3
- package/dist/db/postgres.js +5 -5
- package/dist/db/sqlite.d.ts +2 -1
- package/dist/db/sqlite.js +5 -5
- package/dist/index.js +4 -3
- package/dist/plugins/index.d.ts +1 -0
- package/dist/plugins/ui-bridge.d.ts +12 -0
- package/dist/plugins/utils.d.ts +5 -0
- package/dist/runtimes/bun.js +13 -7
- package/dist/runtimes/cloudflare-workers.js +5 -5
- package/dist/runtimes/next.js +5 -5
- package/dist/runtimes/node.js +13 -7
- package/dist/schema/collection.d.ts +9 -26
- package/dist/schema/fields/base.d.ts +3 -2
- package/dist/schema/fields/index.d.ts +12 -0
- package/dist/schema/fields/validation.test.d.ts +1 -0
- package/dist/schema/global.d.ts +10 -7
- package/dist/schema/index.js +22 -6
- package/dist/server/admin-router.d.ts +2 -2
- package/dist/server/admin.d.ts +2 -1
- package/dist/server/collection-router.d.ts +1 -1
- package/dist/server/handlers.d.ts +10 -0
- package/dist/server/middlewares/admin.d.ts +2 -2
- package/dist/server/middlewares/auth.d.ts +1 -1
- package/dist/server/middlewares/context.d.ts +2 -0
- package/dist/server/middlewares/rate-limit.d.ts +1 -1
- package/dist/server/openapi.d.ts +2 -0
- package/dist/server/plugins-loader.d.ts +6 -0
- package/dist/server/router.d.ts +3 -3
- package/dist/server/routers/admin.d.ts +2 -2
- package/dist/server/routers/auth.d.ts +1 -1
- package/dist/server/routers/collections.d.ts +1 -1
- package/dist/server/routers/plugins.d.ts +18 -0
- package/dist/server/setup-middlewares.d.ts +2 -2
- package/dist/server/system-router.d.ts +1 -1
- package/dist/server.js +11 -7
- package/dist/storage/adapters/local.d.ts +1 -1
- package/dist/storage/adapters/s3.d.ts +1 -1
- package/dist/storage/index.js +34 -25
- package/dist/types.d.ts +224 -17
- package/dist/utils/logger.d.ts +13 -35
- package/dist/validation.d.ts +40 -0
- package/dist/validator.d.ts +1 -1
- package/package.json +41 -27
- package/dist/admin/ui/components/DataDetailSheet.d.ts +0 -13
- package/dist/admin/ui/components/ui/relationship-detail-sheet.d.ts +0 -9
- package/dist/chunk-62ev8gnc.js +0 -41
- package/dist/chunk-j4d50hrx.js +0 -20
|
@@ -3,28 +3,30 @@ import {
|
|
|
3
3
|
flattenPayload,
|
|
4
4
|
pushSchema,
|
|
5
5
|
unflattenRow
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-dykn5hr6.js";
|
|
7
7
|
import {
|
|
8
8
|
BaseDatabaseAdapter
|
|
9
9
|
} from "./chunk-s8mqwnm1.js";
|
|
10
|
-
import {
|
|
11
|
-
logger
|
|
12
|
-
} from "./chunk-62ev8gnc.js";
|
|
13
10
|
import {
|
|
14
11
|
flattenFields,
|
|
15
12
|
getRelationalFields,
|
|
16
13
|
toSnakeCase
|
|
17
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-qxt9vge8.js";
|
|
15
|
+
import {
|
|
16
|
+
logger
|
|
17
|
+
} from "./chunk-t0zg026p.js";
|
|
18
|
+
import {
|
|
19
|
+
__require
|
|
20
|
+
} from "./chunk-8sqjbsgt.js";
|
|
18
21
|
|
|
19
22
|
// src/db/d1.ts
|
|
20
23
|
import fs from "node:fs/promises";
|
|
21
24
|
import path from "node:path";
|
|
22
25
|
import { CompiledQuery, FileMigrationProvider, Kysely, Migrator } from "kysely";
|
|
23
|
-
import { D1Dialect } from "kysely-d1";
|
|
24
26
|
class D1Adapter extends BaseDatabaseAdapter {
|
|
25
27
|
name = "d1";
|
|
26
28
|
_rawDb;
|
|
27
|
-
_db;
|
|
29
|
+
_db = null;
|
|
28
30
|
_collections = [];
|
|
29
31
|
_globals = [];
|
|
30
32
|
push;
|
|
@@ -34,26 +36,33 @@ class D1Adapter extends BaseDatabaseAdapter {
|
|
|
34
36
|
return this._rawDb;
|
|
35
37
|
}
|
|
36
38
|
get db() {
|
|
39
|
+
if (!this._db)
|
|
40
|
+
throw new Error("Database not connected. Call connect() first.");
|
|
37
41
|
return this._db;
|
|
38
42
|
}
|
|
39
43
|
constructor(db, options) {
|
|
40
44
|
super();
|
|
41
45
|
this._rawDb = db;
|
|
42
|
-
this._db = new Kysely({
|
|
43
|
-
dialect: new D1Dialect({ database: db })
|
|
44
|
-
});
|
|
45
46
|
const isDev = typeof process !== "undefined" && true;
|
|
46
47
|
this.push = options?.push ?? isDev;
|
|
47
48
|
this.pushDestructive = options?.pushDestructive ?? false;
|
|
48
49
|
this.migrationDir = options?.migrationDir ?? "./migrations";
|
|
49
50
|
}
|
|
50
|
-
async connect() {
|
|
51
|
+
async connect() {
|
|
52
|
+
if (this._db)
|
|
53
|
+
return;
|
|
54
|
+
const { D1Dialect } = await import("kysely-d1");
|
|
55
|
+
this._db = new Kysely({
|
|
56
|
+
dialect: new D1Dialect({ database: this._rawDb })
|
|
57
|
+
});
|
|
58
|
+
}
|
|
51
59
|
async disconnect() {
|
|
52
|
-
|
|
60
|
+
if (this._db)
|
|
61
|
+
await this.db.destroy();
|
|
53
62
|
}
|
|
54
63
|
async unsafe(query, params) {
|
|
55
64
|
const compiled = CompiledQuery.raw(query, params || []);
|
|
56
|
-
const result = await this.
|
|
65
|
+
const result = await this.db.executeQuery(compiled);
|
|
57
66
|
return result.rows;
|
|
58
67
|
}
|
|
59
68
|
async coerceData(collection, data) {
|
|
@@ -96,7 +105,7 @@ class D1Adapter extends BaseDatabaseAdapter {
|
|
|
96
105
|
}
|
|
97
106
|
async count(collection, query) {
|
|
98
107
|
const tableName = toSnakeCase(collection);
|
|
99
|
-
let qb = this.
|
|
108
|
+
let qb = this.db.selectFrom(tableName).select((eb) => eb.fn.count("id").as("count"));
|
|
100
109
|
if (query && Object.keys(query).length > 0) {
|
|
101
110
|
qb = qb.where((eb) => buildKyselyWhere(eb, query) || eb.val(true));
|
|
102
111
|
}
|
|
@@ -140,7 +149,7 @@ class D1Adapter extends BaseDatabaseAdapter {
|
|
|
140
149
|
}
|
|
141
150
|
const coercedData = await this.coerceData(collection, filteredData);
|
|
142
151
|
try {
|
|
143
|
-
await this.
|
|
152
|
+
await this.db.insertInto(tableName).values(coercedData).execute();
|
|
144
153
|
} catch (e) {
|
|
145
154
|
logger.error(`[D1] Create failed in ${collection}: ${e.message}`);
|
|
146
155
|
throw e;
|
|
@@ -152,7 +161,7 @@ class D1Adapter extends BaseDatabaseAdapter {
|
|
|
152
161
|
const tId = typeof val === "object" ? val.id : val;
|
|
153
162
|
return { id: crypto.randomUUID(), source_id: flatData.id, target_id: tId, order: idx };
|
|
154
163
|
});
|
|
155
|
-
await this.
|
|
164
|
+
await this.db.insertInto(joinTableName).values(joinData).execute();
|
|
156
165
|
}
|
|
157
166
|
}
|
|
158
167
|
for (const [key, blocks] of Object.entries(blocksData)) {
|
|
@@ -178,14 +187,14 @@ class D1Adapter extends BaseDatabaseAdapter {
|
|
|
178
187
|
_order: i,
|
|
179
188
|
block_type: block.blockType
|
|
180
189
|
});
|
|
181
|
-
await this.
|
|
190
|
+
await this.db.insertInto(blockTableName).values(coercedBlockData).execute();
|
|
182
191
|
}
|
|
183
192
|
}
|
|
184
|
-
return this.findOne(collection, { id: flatData.id }, this.
|
|
193
|
+
return this.findOne(collection, { id: flatData.id }, this.db);
|
|
185
194
|
}
|
|
186
195
|
async findOne(collection, query, tx) {
|
|
187
196
|
const tableName = toSnakeCase(collection);
|
|
188
|
-
const executor = tx || this.
|
|
197
|
+
const executor = tx || this.db;
|
|
189
198
|
let qb = executor.selectFrom(tableName).selectAll();
|
|
190
199
|
if (query && Object.keys(query).length > 0) {
|
|
191
200
|
qb = qb.where((eb) => buildKyselyWhere(eb, query) || eb.val(true));
|
|
@@ -251,7 +260,7 @@ class D1Adapter extends BaseDatabaseAdapter {
|
|
|
251
260
|
const offset = (page - 1) * limit;
|
|
252
261
|
const total = await this.count(collection, query);
|
|
253
262
|
const tableName = toSnakeCase(collection);
|
|
254
|
-
let qb = this.
|
|
263
|
+
let qb = this.db.selectFrom(tableName).selectAll().limit(limit).offset(offset);
|
|
255
264
|
if (query && Object.keys(query).length > 0) {
|
|
256
265
|
qb = qb.where((eb) => buildKyselyWhere(eb, query) || eb.val(true));
|
|
257
266
|
}
|
|
@@ -264,7 +273,87 @@ class D1Adapter extends BaseDatabaseAdapter {
|
|
|
264
273
|
qb = qb.orderBy("created_at", "desc");
|
|
265
274
|
}
|
|
266
275
|
const rows = await qb.execute();
|
|
267
|
-
|
|
276
|
+
if (rows.length === 0) {
|
|
277
|
+
const totalPages2 = Math.ceil(total / limit);
|
|
278
|
+
return {
|
|
279
|
+
docs: [],
|
|
280
|
+
totalDocs: total,
|
|
281
|
+
limit,
|
|
282
|
+
totalPages: totalPages2,
|
|
283
|
+
page,
|
|
284
|
+
pagingCounter: offset + 1,
|
|
285
|
+
hasNextPage: page * limit < total,
|
|
286
|
+
hasPrevPage: page > 1,
|
|
287
|
+
prevPage: page > 1 ? page - 1 : null,
|
|
288
|
+
nextPage: page < totalPages2 ? page + 1 : null
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
const rowIds = rows.map((r) => r.id);
|
|
292
|
+
const docs = rows.map((r) => unflattenRow(r));
|
|
293
|
+
const colDef = this._collections.find((c) => c.slug === collection);
|
|
294
|
+
if (colDef) {
|
|
295
|
+
const relationalFields = getRelationalFields(colDef.fields);
|
|
296
|
+
for (const field of relationalFields) {
|
|
297
|
+
if (!field.name)
|
|
298
|
+
continue;
|
|
299
|
+
const snakeName = toSnakeCase(field.name);
|
|
300
|
+
if (field.type === "relationship" && "hasMany" in field && field.hasMany) {
|
|
301
|
+
const joinTableName = `${toSnakeCase(collection)}_${snakeName}_relations`.toLowerCase();
|
|
302
|
+
try {
|
|
303
|
+
const allRelations = await this.db.selectFrom(joinTableName).selectAll().where("source_id", "in", rowIds).orderBy("order", "asc").execute();
|
|
304
|
+
const relationsBySource = allRelations.reduce((acc, r) => {
|
|
305
|
+
if (!acc[r.source_id])
|
|
306
|
+
acc[r.source_id] = [];
|
|
307
|
+
acc[r.source_id].push(r.target_id);
|
|
308
|
+
return acc;
|
|
309
|
+
}, {});
|
|
310
|
+
const parts = field.name.split("__");
|
|
311
|
+
for (let docIdx = 0;docIdx < docs.length; docIdx++) {
|
|
312
|
+
const rowId = rowIds[docIdx];
|
|
313
|
+
let current = docs[docIdx];
|
|
314
|
+
for (let i = 0;i < parts.length - 1; i++) {
|
|
315
|
+
if (!current[parts[i]])
|
|
316
|
+
current[parts[i]] = {};
|
|
317
|
+
current = current[parts[i]];
|
|
318
|
+
}
|
|
319
|
+
current[parts[parts.length - 1]] = relationsBySource[rowId] || [];
|
|
320
|
+
}
|
|
321
|
+
} catch (e) {}
|
|
322
|
+
} else if (field.type === "blocks" && field.blocks) {
|
|
323
|
+
const blocksBySource = {};
|
|
324
|
+
for (const b of field.blocks) {
|
|
325
|
+
const blockTableName = `${collection}_${snakeName}_${toSnakeCase(b.slug)}`.toLowerCase();
|
|
326
|
+
try {
|
|
327
|
+
const allBlocks = await this.db.selectFrom(blockTableName).selectAll().where("_parent_id", "in", rowIds).execute();
|
|
328
|
+
for (const blk of allBlocks) {
|
|
329
|
+
const uf = unflattenRow(blk);
|
|
330
|
+
uf.blockType = blk.block_type;
|
|
331
|
+
if (!blocksBySource[blk._parent_id])
|
|
332
|
+
blocksBySource[blk._parent_id] = [];
|
|
333
|
+
blocksBySource[blk._parent_id].push(uf);
|
|
334
|
+
}
|
|
335
|
+
} catch (e) {}
|
|
336
|
+
}
|
|
337
|
+
const parts = field.name.split("__");
|
|
338
|
+
for (let docIdx = 0;docIdx < docs.length; docIdx++) {
|
|
339
|
+
const rowId = rowIds[docIdx];
|
|
340
|
+
const blockData = blocksBySource[rowId] || [];
|
|
341
|
+
blockData.sort((a, b) => a._order - b._order);
|
|
342
|
+
blockData.forEach((b) => {
|
|
343
|
+
delete b._order;
|
|
344
|
+
delete b._parentId;
|
|
345
|
+
});
|
|
346
|
+
let current = docs[docIdx];
|
|
347
|
+
for (let i = 0;i < parts.length - 1; i++) {
|
|
348
|
+
if (!current[parts[i]])
|
|
349
|
+
current[parts[i]] = {};
|
|
350
|
+
current = current[parts[i]];
|
|
351
|
+
}
|
|
352
|
+
current[parts[parts.length - 1]] = blockData;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}
|
|
268
357
|
const totalPages = Math.ceil(total / limit);
|
|
269
358
|
return {
|
|
270
359
|
docs: docs.filter(Boolean),
|
|
@@ -285,7 +374,7 @@ class D1Adapter extends BaseDatabaseAdapter {
|
|
|
285
374
|
if (typeof query !== "object" || query === null) {
|
|
286
375
|
normalizedQuery = { id: query };
|
|
287
376
|
}
|
|
288
|
-
const current = await this.findOne(collection, normalizedQuery, this.
|
|
377
|
+
const current = await this.findOne(collection, normalizedQuery, this.db);
|
|
289
378
|
if (!current)
|
|
290
379
|
throw new Error("Document not found");
|
|
291
380
|
const colDef = this._collections.find((c) => c.slug === collection);
|
|
@@ -328,7 +417,7 @@ class D1Adapter extends BaseDatabaseAdapter {
|
|
|
328
417
|
}
|
|
329
418
|
const coercedData = await this.coerceData(collection, filteredData);
|
|
330
419
|
try {
|
|
331
|
-
await this.
|
|
420
|
+
await this.db.updateTable(tableName).set(coercedData).where("id", "=", current.id).execute();
|
|
332
421
|
} catch (e) {
|
|
333
422
|
logger.error(`[D1] Update failed in ${collection}: ${e.message}`);
|
|
334
423
|
throw e;
|
|
@@ -336,13 +425,13 @@ class D1Adapter extends BaseDatabaseAdapter {
|
|
|
336
425
|
}
|
|
337
426
|
for (const [key, values] of Object.entries(hasManyData)) {
|
|
338
427
|
const joinTableName = `${tableName}_${toSnakeCase(key)}_relations`.toLowerCase();
|
|
339
|
-
await this.
|
|
428
|
+
await this.db.deleteFrom(joinTableName).where("source_id", "=", current.id).execute();
|
|
340
429
|
if (values.length > 0) {
|
|
341
430
|
const joinData = values.map((val, idx) => {
|
|
342
431
|
const tId = typeof val === "object" ? val.id : val;
|
|
343
432
|
return { id: crypto.randomUUID(), source_id: current.id, target_id: tId, order: idx };
|
|
344
433
|
});
|
|
345
|
-
await this.
|
|
434
|
+
await this.db.insertInto(joinTableName).values(joinData).execute();
|
|
346
435
|
}
|
|
347
436
|
}
|
|
348
437
|
for (const [key, blocks] of Object.entries(blocksData)) {
|
|
@@ -351,7 +440,7 @@ class D1Adapter extends BaseDatabaseAdapter {
|
|
|
351
440
|
for (const b of blockDef.blocks) {
|
|
352
441
|
const blockTableName = `${tableName}_${toSnakeCase(key)}_${toSnakeCase(b.slug)}`.toLowerCase();
|
|
353
442
|
try {
|
|
354
|
-
await this.
|
|
443
|
+
await this.db.deleteFrom(blockTableName).where("_parent_id", "=", current.id).execute();
|
|
355
444
|
} catch (e) {}
|
|
356
445
|
}
|
|
357
446
|
}
|
|
@@ -376,14 +465,14 @@ class D1Adapter extends BaseDatabaseAdapter {
|
|
|
376
465
|
_order: i,
|
|
377
466
|
block_type: block.blockType
|
|
378
467
|
});
|
|
379
|
-
await this.
|
|
468
|
+
await this.db.insertInto(blockTableName).values(coercedBlockData).execute();
|
|
380
469
|
}
|
|
381
470
|
}
|
|
382
|
-
return this.findOne(collection, { id: current.id }, this.
|
|
471
|
+
return this.findOne(collection, { id: current.id }, this.db);
|
|
383
472
|
}
|
|
384
473
|
async updateMany(collection, query, data) {
|
|
385
474
|
const tableName = toSnakeCase(collection);
|
|
386
|
-
let qb = this.
|
|
475
|
+
let qb = this.db.updateTable(tableName);
|
|
387
476
|
if (query && Object.keys(query).length > 0) {
|
|
388
477
|
qb = qb.where((eb) => buildKyselyWhere(eb, query) || eb.val(true));
|
|
389
478
|
}
|
|
@@ -447,31 +536,31 @@ class D1Adapter extends BaseDatabaseAdapter {
|
|
|
447
536
|
if (field.type === "relationship" && "hasMany" in field && field.hasMany) {
|
|
448
537
|
const joinTableName = `${tableName}_${snakeName}_relations`.toLowerCase();
|
|
449
538
|
try {
|
|
450
|
-
await this.
|
|
539
|
+
await this.db.deleteFrom(joinTableName).where("source_id", "=", current.id).execute();
|
|
451
540
|
} catch (e) {}
|
|
452
541
|
} else if (field.type === "blocks" && "blocks" in field && field.blocks) {
|
|
453
542
|
for (const b of field.blocks) {
|
|
454
543
|
const blockTableName = `${tableName}_${snakeName}_${toSnakeCase(b.slug)}`.toLowerCase();
|
|
455
544
|
try {
|
|
456
|
-
await this.
|
|
545
|
+
await this.db.deleteFrom(blockTableName).where("_parent_id", "=", current.id).execute();
|
|
457
546
|
} catch (e) {}
|
|
458
547
|
}
|
|
459
548
|
}
|
|
460
549
|
}
|
|
461
550
|
}
|
|
462
|
-
await this.
|
|
551
|
+
await this.db.deleteFrom(tableName).where("id", "=", current.id).execute();
|
|
463
552
|
return true;
|
|
464
553
|
}
|
|
465
554
|
async deleteMany(collection, query) {
|
|
466
555
|
const tableName = toSnakeCase(collection);
|
|
467
|
-
let selectQb = this.
|
|
556
|
+
let selectQb = this.db.selectFrom(tableName).select("id");
|
|
468
557
|
if (query && Object.keys(query).length > 0) {
|
|
469
558
|
selectQb = selectQb.where((eb) => buildKyselyWhere(eb, query) || eb.val(true));
|
|
470
559
|
}
|
|
471
|
-
const
|
|
472
|
-
|
|
560
|
+
const rowsToDelete = await selectQb.execute();
|
|
561
|
+
const idsToDelete = rowsToDelete.map((row) => row.id);
|
|
562
|
+
if (idsToDelete.length === 0)
|
|
473
563
|
return 0;
|
|
474
|
-
const ids = docs.map((d) => d.id);
|
|
475
564
|
const colDef = this._collections.find((c) => c.slug === collection);
|
|
476
565
|
if (colDef) {
|
|
477
566
|
const relationalFields = getRelationalFields(colDef.fields);
|
|
@@ -482,24 +571,24 @@ class D1Adapter extends BaseDatabaseAdapter {
|
|
|
482
571
|
if (field.type === "relationship" && "hasMany" in field && field.hasMany) {
|
|
483
572
|
const joinTableName = `${tableName}_${snakeName}_relations`.toLowerCase();
|
|
484
573
|
try {
|
|
485
|
-
await this.
|
|
574
|
+
await this.db.deleteFrom(joinTableName).where("source_id", "in", idsToDelete).execute();
|
|
486
575
|
} catch (e) {}
|
|
487
576
|
} else if (field.type === "blocks" && "blocks" in field && field.blocks) {
|
|
488
577
|
for (const b of field.blocks) {
|
|
489
578
|
const blockTableName = `${tableName}_${snakeName}_${toSnakeCase(b.slug)}`.toLowerCase();
|
|
490
579
|
try {
|
|
491
|
-
await this.
|
|
580
|
+
await this.db.deleteFrom(blockTableName).where("_parent_id", "in", idsToDelete).execute();
|
|
492
581
|
} catch (e) {}
|
|
493
582
|
}
|
|
494
583
|
}
|
|
495
584
|
}
|
|
496
585
|
}
|
|
497
|
-
const result = await this.
|
|
586
|
+
const result = await this.db.deleteFrom(tableName).where("id", "in", idsToDelete).executeTakeFirst();
|
|
498
587
|
return Number(result.numDeletedRows || 0);
|
|
499
588
|
}
|
|
500
589
|
async findGlobal(slug) {
|
|
501
590
|
const tableName = toSnakeCase(slug);
|
|
502
|
-
const row = await this.
|
|
591
|
+
const row = await this.db.selectFrom(tableName).selectAll().limit(1).executeTakeFirst();
|
|
503
592
|
return row ? unflattenRow(row) : null;
|
|
504
593
|
}
|
|
505
594
|
async updateGlobal(slug, data) {
|
|
@@ -513,15 +602,15 @@ class D1Adapter extends BaseDatabaseAdapter {
|
|
|
513
602
|
if (!flatData.id)
|
|
514
603
|
flatData.id = "global";
|
|
515
604
|
flatData[toSnakeCase("createdAt")] = now;
|
|
516
|
-
await this.
|
|
605
|
+
await this.db.insertInto(tableName).values(flatData).execute();
|
|
517
606
|
} else {
|
|
518
|
-
await this.
|
|
607
|
+
await this.db.updateTable(tableName).set(flatData).where("id", "=", existing.id).execute();
|
|
519
608
|
}
|
|
520
609
|
return this.findGlobal(slug);
|
|
521
610
|
}
|
|
522
611
|
async runMigrations() {
|
|
523
612
|
const migrator = new Migrator({
|
|
524
|
-
db: this.
|
|
613
|
+
db: this.db,
|
|
525
614
|
provider: new FileMigrationProvider({
|
|
526
615
|
fs,
|
|
527
616
|
path,
|
|
@@ -544,7 +633,7 @@ class D1Adapter extends BaseDatabaseAdapter {
|
|
|
544
633
|
this._collections = collections;
|
|
545
634
|
this._globals = globals;
|
|
546
635
|
if (this.push) {
|
|
547
|
-
await pushSchema(this.
|
|
636
|
+
await pushSchema(this.db, "d1", collections, globals, {
|
|
548
637
|
pushDestructive: this.pushDestructive
|
|
549
638
|
});
|
|
550
639
|
}
|