opacacms 0.1.21 → 0.2.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/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 +2 -2
- package/dist/admin.css +1 -1
- package/dist/auth/index.d.ts +101 -41
- package/dist/{chunk-0sdceeys.js → chunk-0bq155dy.js} +86 -6
- package/dist/{chunk-59sg3pw9.js → chunk-0gtxnxmd.js} +90 -7
- 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-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-16vgcf3k.js → chunk-byq8g0rd.js} +1 -1
- package/dist/{chunk-fqastxq9.js → chunk-d1asgtke.js} +86 -6
- package/dist/{chunk-cpw2y3pn.js → chunk-dykn5hr6.js} +7 -7
- package/dist/{chunk-61kwqve4.js → chunk-esrg9qj0.js} +90 -9
- package/dist/chunk-fj19qccp.js +78 -0
- package/dist/{chunk-ekxkvqjm.js → chunk-gmee4mdc.js} +90 -9
- package/dist/{chunk-xa7rjsn2.js → chunk-j53pz21t.js} +2 -2
- package/dist/{chunk-xrfhhz85.js → chunk-kc4jfnv7.js} +480 -85
- package/dist/chunk-mkn49zmy.js +102 -0
- package/dist/{chunk-n1xraw7j.js → chunk-qb6ztvw9.js} +1 -1
- 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-swtcpvhf.js +2442 -0
- package/dist/chunk-t0zg026p.js +71 -0
- 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/better-sqlite.d.ts +1 -1
- package/dist/db/better-sqlite.js +5 -5
- package/dist/db/bun-sqlite.d.ts +1 -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 +1 -1
- package/dist/db/postgres.js +5 -5
- package/dist/db/sqlite.d.ts +1 -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/types.d.ts +222 -15
- 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 +21 -7
- 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
- package/dist/chunk-nb7ctdg8.js +0 -311
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import {
|
|
2
|
+
pluginSyncCommand
|
|
3
|
+
} from "./chunk-twpvxfce.js";
|
|
4
|
+
import {
|
|
5
|
+
logger
|
|
6
|
+
} from "./chunk-t0zg026p.js";
|
|
7
|
+
import {
|
|
8
|
+
__require
|
|
9
|
+
} from "./chunk-8sqjbsgt.js";
|
|
10
|
+
|
|
11
|
+
// src/cli/commands/plugin-build.ts
|
|
12
|
+
import fs from "node:fs";
|
|
13
|
+
import path from "node:path";
|
|
14
|
+
async function pluginBuildCommand(projectRoot) {
|
|
15
|
+
const srcDir = path.resolve(projectRoot, "src");
|
|
16
|
+
const distDir = path.resolve(projectRoot, "dist");
|
|
17
|
+
if (!fs.existsSync(srcDir)) {
|
|
18
|
+
logger.error(`No 'src' directory found in ${projectRoot}.`);
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
logger.info("Syncing plugin UI...");
|
|
22
|
+
await pluginSyncCommand(projectRoot, false);
|
|
23
|
+
const entryFiles = ["index.tsx", "index.ts", "plugin.tsx", "plugin.ts"];
|
|
24
|
+
let mainEntry = "";
|
|
25
|
+
for (const file of entryFiles) {
|
|
26
|
+
const fullPath = path.join(srcDir, file);
|
|
27
|
+
if (fs.existsSync(fullPath)) {
|
|
28
|
+
mainEntry = fullPath;
|
|
29
|
+
break;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
if (!mainEntry) {
|
|
33
|
+
logger.error(`Could not find a main entry file in ${srcDir}`);
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
logger.info(`Building plugin entry: ${path.basename(mainEntry)}...`);
|
|
37
|
+
if (!fs.existsSync(distDir)) {
|
|
38
|
+
fs.mkdirSync(distDir, { recursive: true });
|
|
39
|
+
}
|
|
40
|
+
const buildResult = await Bun.build({
|
|
41
|
+
entrypoints: [mainEntry],
|
|
42
|
+
outdir: distDir,
|
|
43
|
+
target: "node",
|
|
44
|
+
format: "esm",
|
|
45
|
+
external: [
|
|
46
|
+
"opacacms",
|
|
47
|
+
"opacacms/types",
|
|
48
|
+
"opacacms/plugins",
|
|
49
|
+
"opacacms/schema",
|
|
50
|
+
"hono",
|
|
51
|
+
"zod",
|
|
52
|
+
"react",
|
|
53
|
+
"react-dom"
|
|
54
|
+
]
|
|
55
|
+
});
|
|
56
|
+
if (!buildResult.success) {
|
|
57
|
+
logger.error("Plugin build failed.");
|
|
58
|
+
for (const msg of buildResult.logs) {
|
|
59
|
+
console.error(msg);
|
|
60
|
+
}
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
try {
|
|
64
|
+
logger.info("Generating type declarations...");
|
|
65
|
+
const { execSync } = await import("node:child_process");
|
|
66
|
+
execSync("bunx tsc --emitDeclarationOnly --outDir dist", {
|
|
67
|
+
cwd: projectRoot,
|
|
68
|
+
stdio: "ignore"
|
|
69
|
+
});
|
|
70
|
+
logger.success("Types generated.");
|
|
71
|
+
} catch (err) {
|
|
72
|
+
logger.warn("Failed to generate types. Make sure typescript is installed.");
|
|
73
|
+
}
|
|
74
|
+
logger.success(`Plugin built successfully in ${distDir}!`);
|
|
75
|
+
}
|
|
76
|
+
export {
|
|
77
|
+
pluginBuildCommand
|
|
78
|
+
};
|
|
@@ -3,17 +3,18 @@ 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,
|
|
12
|
+
getRelationalFields,
|
|
15
13
|
toSnakeCase
|
|
16
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-qxt9vge8.js";
|
|
15
|
+
import {
|
|
16
|
+
logger
|
|
17
|
+
} from "./chunk-t0zg026p.js";
|
|
17
18
|
import {
|
|
18
19
|
__require
|
|
19
20
|
} from "./chunk-8sqjbsgt.js";
|
|
@@ -67,7 +68,7 @@ class BetterSQLiteAdapter extends BaseDatabaseAdapter {
|
|
|
67
68
|
if (!colDef)
|
|
68
69
|
return data;
|
|
69
70
|
const result = { ...data };
|
|
70
|
-
const { flattenFields: flattenFields2 } = await import("./chunk-
|
|
71
|
+
const { flattenFields: flattenFields2 } = await import("./chunk-526a3gqx.js");
|
|
71
72
|
const allFields = flattenFields2(colDef.fields);
|
|
72
73
|
for (const field of allFields) {
|
|
73
74
|
const colName = toSnakeCase(field.name);
|
|
@@ -204,8 +205,8 @@ class BetterSQLiteAdapter extends BaseDatabaseAdapter {
|
|
|
204
205
|
const unflattened = unflattenRow(row);
|
|
205
206
|
const colDef = this._collections.find((c) => c.slug === collection);
|
|
206
207
|
if (colDef) {
|
|
207
|
-
const { getRelationalFields, toSnakeCase: toSnakeCase2 } = await import("./chunk-
|
|
208
|
-
const relationalFields =
|
|
208
|
+
const { getRelationalFields: getRelationalFields2, toSnakeCase: toSnakeCase2 } = await import("./chunk-526a3gqx.js");
|
|
209
|
+
const relationalFields = getRelationalFields2(colDef.fields);
|
|
209
210
|
for (const field of relationalFields) {
|
|
210
211
|
if (!field.name)
|
|
211
212
|
continue;
|
|
@@ -258,7 +259,87 @@ class BetterSQLiteAdapter extends BaseDatabaseAdapter {
|
|
|
258
259
|
qb = qb.orderBy("created_at", "desc");
|
|
259
260
|
}
|
|
260
261
|
const rows = await qb.execute();
|
|
261
|
-
|
|
262
|
+
if (rows.length === 0) {
|
|
263
|
+
const totalPages2 = Math.ceil(total / limit);
|
|
264
|
+
return {
|
|
265
|
+
docs: [],
|
|
266
|
+
totalDocs: total,
|
|
267
|
+
limit,
|
|
268
|
+
totalPages: totalPages2,
|
|
269
|
+
page,
|
|
270
|
+
pagingCounter: offset + 1,
|
|
271
|
+
hasNextPage: page * limit < total,
|
|
272
|
+
hasPrevPage: page > 1,
|
|
273
|
+
prevPage: page > 1 ? page - 1 : null,
|
|
274
|
+
nextPage: page < totalPages2 ? page + 1 : null
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
const rowIds = rows.map((r) => r.id);
|
|
278
|
+
const docs = rows.map((r) => unflattenRow(r));
|
|
279
|
+
const colDef = this._collections.find((c) => c.slug === collection);
|
|
280
|
+
if (colDef) {
|
|
281
|
+
const relationalFields = getRelationalFields(colDef.fields);
|
|
282
|
+
for (const field of relationalFields) {
|
|
283
|
+
if (!field.name)
|
|
284
|
+
continue;
|
|
285
|
+
const snakeName = toSnakeCase(field.name);
|
|
286
|
+
if (field.type === "relationship" && "hasMany" in field && field.hasMany) {
|
|
287
|
+
const joinTableName = `${toSnakeCase(collection)}_${snakeName}_relations`.toLowerCase();
|
|
288
|
+
try {
|
|
289
|
+
const allRelations = await this._db.selectFrom(joinTableName).selectAll().where("source_id", "in", rowIds).orderBy("order", "asc").execute();
|
|
290
|
+
const relationsBySource = allRelations.reduce((acc, r) => {
|
|
291
|
+
if (!acc[r.source_id])
|
|
292
|
+
acc[r.source_id] = [];
|
|
293
|
+
acc[r.source_id].push(r.target_id);
|
|
294
|
+
return acc;
|
|
295
|
+
}, {});
|
|
296
|
+
const parts = field.name.split("__");
|
|
297
|
+
for (let docIdx = 0;docIdx < docs.length; docIdx++) {
|
|
298
|
+
const rowId = rowIds[docIdx];
|
|
299
|
+
let current = docs[docIdx];
|
|
300
|
+
for (let i = 0;i < parts.length - 1; i++) {
|
|
301
|
+
if (!current[parts[i]])
|
|
302
|
+
current[parts[i]] = {};
|
|
303
|
+
current = current[parts[i]];
|
|
304
|
+
}
|
|
305
|
+
current[parts[parts.length - 1]] = relationsBySource[rowId] || [];
|
|
306
|
+
}
|
|
307
|
+
} catch (e) {}
|
|
308
|
+
} else if (field.type === "blocks" && field.blocks) {
|
|
309
|
+
const blocksBySource = {};
|
|
310
|
+
for (const b of field.blocks) {
|
|
311
|
+
const blockTableName = `${collection}_${snakeName}_${toSnakeCase(b.slug)}`.toLowerCase();
|
|
312
|
+
try {
|
|
313
|
+
const allBlocks = await this._db.selectFrom(blockTableName).selectAll().where("_parent_id", "in", rowIds).execute();
|
|
314
|
+
for (const blk of allBlocks) {
|
|
315
|
+
const uf = unflattenRow(blk);
|
|
316
|
+
uf.blockType = blk.block_type;
|
|
317
|
+
if (!blocksBySource[blk._parent_id])
|
|
318
|
+
blocksBySource[blk._parent_id] = [];
|
|
319
|
+
blocksBySource[blk._parent_id].push(uf);
|
|
320
|
+
}
|
|
321
|
+
} catch (e) {}
|
|
322
|
+
}
|
|
323
|
+
const parts = field.name.split("__");
|
|
324
|
+
for (let docIdx = 0;docIdx < docs.length; docIdx++) {
|
|
325
|
+
const rowId = rowIds[docIdx];
|
|
326
|
+
const blockData = blocksBySource[rowId] || [];
|
|
327
|
+
blockData.sort((a, b) => a._order - b._order);
|
|
328
|
+
blockData.forEach((b) => {
|
|
329
|
+
delete b._order;
|
|
330
|
+
delete b._parentId;
|
|
331
|
+
});
|
|
332
|
+
let current = docs[docIdx];
|
|
333
|
+
for (let i = 0;i < parts.length - 1; i++) {
|
|
334
|
+
if (!current[parts[i]])
|
|
335
|
+
current[parts[i]] = {};
|
|
336
|
+
current = current[parts[i]];
|
|
337
|
+
}
|
|
338
|
+
current[parts[parts.length - 1]] = blockData;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
262
343
|
const totalPages = Math.ceil(total / limit);
|
|
263
344
|
return {
|
|
264
345
|
docs: docs.filter(Boolean),
|