opacacms 0.1.7 → 0.1.8

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 (46) hide show
  1. package/dist/admin/index.js +255 -20
  2. package/dist/admin/webcomponent.js +291 -46
  3. package/dist/cli/index.js +3638 -30
  4. package/dist/client.js +126 -5
  5. package/dist/db/bun-sqlite.js +790 -21
  6. package/dist/db/d1.js +788 -19
  7. package/dist/db/index.js +53 -4
  8. package/dist/db/postgres.js +792 -23
  9. package/dist/db/sqlite.js +788 -19
  10. package/dist/index.js +456 -8
  11. package/dist/runtimes/bun.js +1909 -8
  12. package/dist/runtimes/cloudflare-workers.js +1910 -9
  13. package/dist/runtimes/next.js +1908 -7
  14. package/dist/runtimes/node.js +1909 -8
  15. package/dist/schema/collection.d.ts +3 -7
  16. package/dist/schema/fields/index.d.ts +24 -25
  17. package/dist/schema/global.d.ts +9 -9
  18. package/dist/schema/index.d.ts +30 -4
  19. package/dist/schema/index.js +546 -1
  20. package/dist/server.js +2246 -17
  21. package/dist/storage/index.js +40 -1
  22. package/package.json +1 -1
  23. package/dist/chunk-16vgcf3k.js +0 -88
  24. package/dist/chunk-2yz1nsxs.js +0 -126
  25. package/dist/chunk-5gvbp2qa.js +0 -167
  26. package/dist/chunk-62ev8gnc.js +0 -41
  27. package/dist/chunk-6ew02s0c.js +0 -472
  28. package/dist/chunk-7a9kn0np.js +0 -116
  29. package/dist/chunk-8sqjbsgt.js +0 -42
  30. package/dist/chunk-9kxpbcb1.js +0 -85
  31. package/dist/chunk-cvdd4eqh.js +0 -110
  32. package/dist/chunk-d3ffeqp9.js +0 -87
  33. package/dist/chunk-fa5mg0hr.js +0 -96
  34. package/dist/chunk-j4d50hrx.js +0 -20
  35. package/dist/chunk-jwjk85ze.js +0 -15
  36. package/dist/chunk-m09hahe2.js +0 -250
  37. package/dist/chunk-s8mqwnm1.js +0 -14
  38. package/dist/chunk-srsac177.js +0 -85
  39. package/dist/chunk-v521d72w.js +0 -10
  40. package/dist/chunk-vtvqfhgy.js +0 -2442
  41. package/dist/chunk-xa7rjsn2.js +0 -20
  42. package/dist/chunk-xg35h5a3.js +0 -15
  43. package/dist/chunk-y8hc6nm4.js +0 -17
  44. package/dist/chunk-ybbbqj63.js +0 -130
  45. package/dist/chunk-yr32cp7h.js +0 -1603
  46. package/dist/chunk-zvwb67nd.js +0 -332
@@ -1,4 +1,43 @@
1
- import"../chunk-8sqjbsgt.js";
1
+ import { createRequire } from "node:module";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ function __accessProp(key) {
7
+ return this[key];
8
+ }
9
+ var __toCommonJS = (from) => {
10
+ var entry = (__moduleCache ??= new WeakMap).get(from), desc;
11
+ if (entry)
12
+ return entry;
13
+ entry = __defProp({}, "__esModule", { value: true });
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (var key of __getOwnPropNames(from))
16
+ if (!__hasOwnProp.call(entry, key))
17
+ __defProp(entry, key, {
18
+ get: __accessProp.bind(from, key),
19
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
20
+ });
21
+ }
22
+ __moduleCache.set(from, entry);
23
+ return entry;
24
+ };
25
+ var __moduleCache;
26
+ var __returnValue = (v) => v;
27
+ function __exportSetter(name, newValue) {
28
+ this[name] = __returnValue.bind(null, newValue);
29
+ }
30
+ var __export = (target, all) => {
31
+ for (var name in all)
32
+ __defProp(target, name, {
33
+ get: all[name],
34
+ enumerable: true,
35
+ configurable: true,
36
+ set: __exportSetter.bind(all, name)
37
+ });
38
+ };
39
+ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
40
+ var __require = /* @__PURE__ */ createRequire(import.meta.url);
2
41
 
3
42
  // src/storage/errors.ts
4
43
  class StorageError extends Error {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opacacms",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "sideEffects": false,
5
5
  "scripts": {
6
6
  "build": "bun run ../../scripts/build.ts && tsc --emitDeclarationOnly",
@@ -1,88 +0,0 @@
1
- import {
2
- notify
3
- } from "./chunk-j4d50hrx.js";
4
-
5
- // src/admin/stores/auth.ts
6
- import { atom, computed } from "nanostores";
7
-
8
- // src/admin/auth-client.ts
9
- import { createAuthClient } from "better-auth/client";
10
- import { adminClient } from "better-auth/client/plugins";
11
- var client = null;
12
- var currentURL = null;
13
- var configureAuth = (serverUrl) => {
14
- if (!serverUrl || !serverUrl.startsWith("http"))
15
- return;
16
- const url = serverUrl;
17
- const baseURL = url.replace(/\/$/, "") + "/api/auth";
18
- if (client && currentURL === baseURL)
19
- return;
20
- currentURL = baseURL;
21
- client = createAuthClient({
22
- baseURL,
23
- autoRefresh: true,
24
- fetchOptions: {
25
- credentials: "include"
26
- },
27
- plugins: [adminClient()]
28
- });
29
- };
30
- var authClient = new Proxy({}, {
31
- get(_, prop) {
32
- if (!client) {
33
- throw new Error("Auth client not configured. Did you provide a valid serverUrl?");
34
- }
35
- return client[prop];
36
- }
37
- });
38
-
39
- // src/admin/stores/auth.ts
40
- var $session = atom(null);
41
- var $isAuthPending = atom(true);
42
- var $user = computed($session, (session) => session?.user ?? null);
43
- var $isAuthenticated = computed($session, (session) => !!session);
44
- async function syncSession() {
45
- $isAuthPending.set(true);
46
- try {
47
- const res = await authClient.getSession();
48
- $session.set(res.data);
49
- } catch (err) {
50
- console.error("[OpacaCMS] Failed to sync session:", err);
51
- } finally {
52
- $isAuthPending.set(false);
53
- }
54
- }
55
- async function login(data) {
56
- $isAuthPending.set(true);
57
- try {
58
- const res = await authClient.signIn.email({
59
- email: data.email,
60
- password: data.password
61
- });
62
- if (res.error) {
63
- throw new Error(res.error.message || "Invalid credentials");
64
- }
65
- await syncSession();
66
- notify("Logged in successfully", "success");
67
- return res;
68
- } catch (error) {
69
- notify(error instanceof Error ? error.message : "Login failed", "error");
70
- throw error;
71
- } finally {
72
- $isAuthPending.set(false);
73
- }
74
- }
75
- async function logout() {
76
- $isAuthPending.set(true);
77
- try {
78
- await authClient.signOut();
79
- $session.set(null);
80
- notify("Logged out successfully");
81
- } catch {
82
- notify("Logout failed", "error");
83
- } finally {
84
- $isAuthPending.set(false);
85
- }
86
- }
87
-
88
- export { configureAuth, authClient, $session, $isAuthPending, $user, $isAuthenticated, syncSession, login, logout };
@@ -1,126 +0,0 @@
1
- import {
2
- logger
3
- } from "./chunk-62ev8gnc.js";
4
- import {
5
- __require
6
- } from "./chunk-8sqjbsgt.js";
7
-
8
- // src/cli/commands/migrate-commands.ts
9
- import fs from "node:fs";
10
- import { relative, resolve } from "node:path";
11
- import { spawnSync } from "node:child_process";
12
- async function migrateCreateCommand(opaca, migrationName = "migration", outDir) {
13
- const db = opaca.db;
14
- const migrationDir = outDir || db.migrationDir || "./migrations";
15
- const fullMigrationDir = resolve(process.cwd(), migrationDir);
16
- if (!fs.existsSync(fullMigrationDir)) {
17
- fs.mkdirSync(fullMigrationDir, { recursive: true });
18
- }
19
- const timestamp = new Date().toISOString().replace(/[-:T]/g, "").split(".")[0];
20
- const { generateMigrationCode, generateSQLCode } = await import("./chunk-m09hahe2.js");
21
- const { getSystemCollections } = await import("./chunk-v521d72w.js");
22
- let dialect = "sqlite";
23
- if (db.name === "postgres")
24
- dialect = "postgres";
25
- if (db.name === "d1")
26
- dialect = "d1";
27
- const isD1 = dialect === "d1";
28
- const fileName = `${timestamp}_${migrationName}.${isD1 ? "sql" : "ts"}`;
29
- const filePath = resolve(fullMigrationDir, fileName);
30
- const allCollections = [...getSystemCollections(), ...opaca.collections || []];
31
- const template = isD1 ? generateSQLCode(allCollections, opaca.globals || []) : generateMigrationCode(allCollections, opaca.globals || [], dialect);
32
- fs.writeFileSync(filePath, template);
33
- logger.success(`\uD83D\uDE80 Migration created successfully at ${relative(process.cwd(), filePath)}`);
34
- }
35
- async function migrateRunCommand(db) {
36
- logger.info("\uD83C\uDFAC Running migrations...");
37
- if (db.runMigrations) {
38
- await db.connect();
39
- try {
40
- await db.runMigrations();
41
- logger.success("✅ Migrations applied successfully!");
42
- } catch (error) {
43
- logger.error(`❌ Failed to run migrations: ${error.message}`);
44
- throw error;
45
- } finally {}
46
- } else {
47
- throw new Error(`Adapter ${db.name} does not support running migrations.`);
48
- }
49
- }
50
- async function migrateStatusCommand(opaca) {
51
- logger.info("\uD83D\uDCCA Checking migration status...");
52
- const db = opaca.db;
53
- const migrationDir = db.migrationDir || "./migrations";
54
- const fullMigrationDir = resolve(process.cwd(), migrationDir);
55
- if (!fs.existsSync(fullMigrationDir)) {
56
- logger.info("No migrations directory found.");
57
- return;
58
- }
59
- const migrationFiles = fs.readdirSync(fullMigrationDir).filter((f) => f.endsWith(".ts") || f.endsWith(".sql")).sort();
60
- let appliedMigrations = [];
61
- try {
62
- await db.connect();
63
- const rows = await db.unsafe("SELECT name FROM kysely_migration").catch(() => []);
64
- appliedMigrations = rows.map((r) => r.name);
65
- } catch (e) {} finally {}
66
- console.log(`
67
- Found ${migrationFiles.length} migration files in ${migrationDir}:`);
68
- for (const file of migrationFiles) {
69
- const name = file.replace(/\.(ts|sql)$/, "");
70
- const isApplied = appliedMigrations.includes(name);
71
- console.log(` ${isApplied ? "✅ [Applied] " : "❌ [Pending] "} ${file}`);
72
- }
73
- const pending = migrationFiles.filter((f) => !appliedMigrations.includes(f.replace(/\.(ts|sql)$/, "")));
74
- if (pending.length > 0) {
75
- console.log(`
76
- \uD83D\uDCA1 You have ${pending.length} pending migrations. Run 'opacacms migrate' to apply them.`);
77
- } else {
78
- console.log(`
79
- ✨ All migrations are up to date.`);
80
- }
81
- }
82
- async function migrateD1Command(migrationDir, isRemote, binding = "DB") {
83
- const fullMigrationDir = resolve(process.cwd(), migrationDir);
84
- if (!fs.existsSync(fullMigrationDir)) {
85
- throw new Error(`[OpacaCMS] Migration directory not found: ${fullMigrationDir}`);
86
- }
87
- const migrations = fs.readdirSync(fullMigrationDir).filter((file) => file.endsWith(".sql")).sort();
88
- if (migrations.length === 0) {
89
- console.log(`[OpacaCMS] No SQL migrations found in ${fullMigrationDir}`);
90
- return;
91
- }
92
- console.log(`[OpacaCMS] Found ${migrations.length} migrations. Applying to ${isRemote ? "\uD83C\uDF0A REMOTE (Cloudflare D1)" : "\uD83D\uDCBB LOCAL (SQLite)"}...`);
93
- for (const migration of migrations) {
94
- const filePath = resolve(fullMigrationDir, migration);
95
- console.log(`
96
- [OpacaCMS] \uD83D\uDCE6 Applying: ${migration}...`);
97
- const wranglerArgs = [
98
- "wrangler",
99
- "d1",
100
- "execute",
101
- binding,
102
- "--file",
103
- filePath,
104
- isRemote ? "--remote" : "--local",
105
- "--yes"
106
- ];
107
- const result = spawnSync("bunx", wranglerArgs, {
108
- stdio: "inherit",
109
- shell: true,
110
- cwd: process.cwd()
111
- });
112
- if (result.status !== 0) {
113
- console.error(`[OpacaCMS] ❌ Failed to apply migration: ${migration}`);
114
- } else {
115
- console.log(`[OpacaCMS] ✅ Success: ${migration}`);
116
- }
117
- }
118
- console.log(`
119
- [OpacaCMS] ✨ Database migration process completed!`);
120
- }
121
- export {
122
- migrateStatusCommand,
123
- migrateRunCommand,
124
- migrateD1Command,
125
- migrateCreateCommand
126
- };
@@ -1,167 +0,0 @@
1
- import"./chunk-8sqjbsgt.js";
2
-
3
- // src/cli/r2-mock.ts
4
- import { Database } from "bun:sqlite";
5
- import crypto from "node:crypto";
6
- import fs from "node:fs";
7
- import path from "node:path";
8
- function createR2Mock(dbPath) {
9
- let sqlite;
10
- let blobsDir;
11
- let finalDbPath;
12
- const wranglerR2Dir = path.resolve(process.cwd(), ".wrangler/state/v3/r2/miniflare-R2BucketObject");
13
- if (!dbPath && fs.existsSync(wranglerR2Dir)) {
14
- const files = fs.readdirSync(wranglerR2Dir);
15
- const sqliteFile = files.find((f) => f.endsWith(".sqlite"));
16
- if (sqliteFile) {
17
- finalDbPath = path.join(wranglerR2Dir, sqliteFile);
18
- console.log(`[OpacaCMS] Using Wrangler R2 local state: ${sqliteFile}`);
19
- }
20
- }
21
- if (!finalDbPath) {
22
- const inputPath = dbPath || ".opaca/local-r2/mock-bucket.sqlite";
23
- const absolutePath = path.isAbsolute(inputPath) ? inputPath : path.resolve(process.cwd(), inputPath);
24
- if (fs.existsSync(absolutePath) && fs.statSync(absolutePath).isDirectory()) {
25
- finalDbPath = path.join(absolutePath, "mock-bucket.sqlite");
26
- } else if (!absolutePath.endsWith(".sqlite")) {
27
- finalDbPath = absolutePath.endsWith("/") ? path.join(absolutePath, "mock-bucket.sqlite") : absolutePath + ".sqlite";
28
- } else {
29
- finalDbPath = absolutePath;
30
- }
31
- console.log(`[OpacaCMS] Using local R2 mock: ${path.basename(finalDbPath)}`);
32
- }
33
- const dir = path.dirname(finalDbPath);
34
- if (!fs.existsSync(dir)) {
35
- fs.mkdirSync(dir, { recursive: true });
36
- }
37
- try {
38
- sqlite = new Database(finalDbPath);
39
- } catch (err) {
40
- throw new Error(`Failed to open R2 mock database at ${finalDbPath}: ${err.message}`);
41
- }
42
- blobsDir = finalDbPath.replace(".sqlite", ".blobs");
43
- if (!fs.existsSync(blobsDir)) {
44
- fs.mkdirSync(dir, { recursive: true });
45
- fs.mkdirSync(blobsDir, { recursive: true });
46
- }
47
- sqlite.exec(`
48
- CREATE TABLE IF NOT EXISTS _mf_objects (
49
- key TEXT PRIMARY KEY,
50
- blob_id TEXT,
51
- version TEXT,
52
- size INTEGER,
53
- etag TEXT,
54
- uploaded INTEGER,
55
- checksums TEXT,
56
- http_metadata TEXT,
57
- custom_metadata TEXT
58
- )
59
- `);
60
- const getBlobPath = (blobId) => path.join(blobsDir, blobId);
61
- return {
62
- async put(key, value, options) {
63
- const blobId = crypto.randomUUID();
64
- const filePath = getBlobPath(blobId);
65
- const buffer = value instanceof Uint8Array ? value : value instanceof ArrayBuffer ? new Uint8Array(value) : typeof value === "string" || value instanceof Buffer ? Buffer.from(value) : new Uint8Array(await value.arrayBuffer());
66
- fs.writeFileSync(filePath, buffer);
67
- const etag = crypto.createHash("md5").update(buffer).digest("hex");
68
- const uploaded = Date.now();
69
- const size = buffer.length;
70
- const httpMetadataObj = {};
71
- if (options?.httpMetadata?.contentType) {
72
- httpMetadataObj.contentType = options.httpMetadata.contentType;
73
- }
74
- const customMetadataObj = { ...options?.customMetadata };
75
- if (options?.customMetadata?.sourceUrl) {
76
- customMetadataObj.sourceUrl = options.customMetadata.sourceUrl;
77
- }
78
- const httpMetadata = JSON.stringify(httpMetadataObj);
79
- const customMetadata = JSON.stringify(customMetadataObj);
80
- sqlite.prepare(`
81
- INSERT OR REPLACE INTO _mf_objects
82
- (key, blob_id, version, size, etag, uploaded, checksums, http_metadata, custom_metadata)
83
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
84
- `).run(key, blobId, "v1", size, etag, uploaded, "{}", httpMetadata, customMetadata);
85
- return {
86
- key,
87
- size,
88
- etag,
89
- httpMetadata: options?.httpMetadata || {},
90
- customMetadata: options?.customMetadata || {}
91
- };
92
- },
93
- async get(key) {
94
- const row = sqlite.prepare("SELECT * FROM _mf_objects WHERE key = ?").get(key);
95
- if (!row)
96
- return null;
97
- const filePath = getBlobPath(row.blob_id);
98
- if (!fs.existsSync(filePath))
99
- return null;
100
- const buffer = fs.readFileSync(filePath);
101
- const stream = new ReadableStream({
102
- start(controller) {
103
- controller.enqueue(new Uint8Array(buffer));
104
- controller.close();
105
- }
106
- });
107
- return {
108
- key: row.key,
109
- size: row.size,
110
- etag: row.etag,
111
- uploaded: new Date(row.uploaded),
112
- httpMetadata: JSON.parse(row.http_metadata || "{}"),
113
- customMetadata: JSON.parse(row.custom_metadata || "{}"),
114
- body: stream,
115
- bodyUsed: false,
116
- async arrayBuffer() {
117
- return buffer.buffer;
118
- },
119
- async text() {
120
- return buffer.toString();
121
- },
122
- async json() {
123
- return JSON.parse(buffer.toString());
124
- }
125
- };
126
- },
127
- async head(key) {
128
- const row = sqlite.prepare("SELECT key, size, etag, http_metadata, custom_metadata, uploaded FROM _mf_objects WHERE key = ?").get(key);
129
- if (!row)
130
- return null;
131
- return {
132
- key: row.key,
133
- size: row.size,
134
- etag: row.etag,
135
- uploaded: new Date(row.uploaded),
136
- httpMetadata: JSON.parse(row.http_metadata || "{}"),
137
- customMetadata: JSON.parse(row.custom_metadata || "{}")
138
- };
139
- },
140
- async delete(key) {
141
- const row = sqlite.prepare("SELECT blob_id FROM _mf_objects WHERE key = ?").get(key);
142
- if (row) {
143
- const filePath = getBlobPath(row.blob_id);
144
- if (fs.existsSync(filePath))
145
- fs.unlinkSync(filePath);
146
- sqlite.prepare("DELETE FROM _mf_objects WHERE key = ?").run(key);
147
- }
148
- },
149
- async list() {
150
- const rows = sqlite.prepare("SELECT * FROM _mf_objects").all();
151
- return {
152
- objects: rows.map((row) => ({
153
- key: row.key,
154
- size: row.size,
155
- etag: row.etag,
156
- uploaded: new Date(row.uploaded),
157
- httpMetadata: JSON.parse(row.http_metadata || "{}"),
158
- customMetadata: JSON.parse(row.custom_metadata || "{}")
159
- })),
160
- truncated: false
161
- };
162
- }
163
- };
164
- }
165
- export {
166
- createR2Mock
167
- };
@@ -1,41 +0,0 @@
1
- // src/utils/logger.ts
2
- var RESET = "\x1B[0m";
3
- var BLUE = "\x1B[34m";
4
- var GREEN = "\x1B[32m";
5
- var YELLOW = "\x1B[33m";
6
- var RED = "\x1B[31m";
7
- var GRAY = "\x1B[90m";
8
- var PREFIX = `${BLUE}[OpacaCMS]${RESET}`;
9
- var logger = {
10
- info: (message, ...args) => {
11
- console.log(`${PREFIX} ${message}`, ...args);
12
- },
13
- success: (message, ...args) => {
14
- console.log(`${PREFIX} ${GREEN}${message}${RESET}`, ...args);
15
- },
16
- debug: (message, ...args) => {
17
- console.log(`${PREFIX} ${GRAY}${message}${RESET}`, ...args);
18
- },
19
- warn: (message, ...args) => {
20
- console.warn(`${PREFIX} ${YELLOW}Warning: ${message}${RESET}`, ...args);
21
- },
22
- error: (message, ...args) => {
23
- console.error(`${PREFIX} ${RED}Error: ${message}${RESET}`, ...args);
24
- },
25
- format: (color, msg) => {
26
- switch (color) {
27
- case "green":
28
- return `${GREEN}${msg}${RESET}`;
29
- case "red":
30
- return `${RED}${msg}${RESET}`;
31
- case "yellow":
32
- return `${YELLOW}${msg}${RESET}`;
33
- case "gray":
34
- return `${GRAY}${msg}${RESET}`;
35
- default:
36
- return msg;
37
- }
38
- }
39
- };
40
-
41
- export { logger };