opacacms 0.3.2 → 0.3.3
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/admin/index.js +1 -1
- package/dist/admin/react.js +1 -1
- package/dist/admin/vue.js +1 -1
- package/dist/admin/webcomponent.js +35 -37
- package/dist/{chunk-g9bxb6h0.js → chunk-2fm4kv2q.js} +1 -1
- package/dist/chunk-2vbfc4q8.js +6 -0
- package/dist/{chunk-adq2b75c.js → chunk-40tky6qh.js} +2 -2
- package/dist/{chunk-e0g6gn7n.js → chunk-49e16hjg.js} +3 -3
- package/dist/{chunk-fnsf1dfm.js → chunk-526a3gqx.js} +1 -1
- package/dist/{chunk-sqsfk9p4.js → chunk-6m1jhxmd.js} +1 -1
- package/dist/{chunk-6bywt602.js → chunk-8sqjbsgt.js} +1 -26
- package/dist/{chunk-n1twhqmf.js → chunk-acghejk8.js} +1 -1
- package/dist/{chunk-m24yqkeq.js → chunk-b1g8jmth.js} +3 -3
- package/dist/{chunk-5422w4eq.js → chunk-cm5rvcnn.js} +5 -5
- package/dist/{chunk-941zxavt.js → chunk-h2y2t07h.js} +4 -4
- package/dist/{chunk-6qs0g65f.js → chunk-h8v093av.js} +1 -1
- package/dist/{chunk-m5ems3hh.js → chunk-hthm9srb.js} +1 -1
- package/dist/{chunk-2k3ysje3.js → chunk-nch158fe.js} +1 -1
- package/dist/{chunk-naqcqj8n.js → chunk-pj31j6j0.js} +4 -4
- package/dist/{chunk-qsh2nqz3.js → chunk-pw2a9war.js} +3 -3
- package/dist/{chunk-j8js1y0h.js → chunk-r5k7jw66.js} +1 -1
- package/dist/{chunk-48ywpd0a.js → chunk-vmz9ncf1.js} +1 -1
- package/dist/{chunk-qhdsjek6.js → chunk-wry3rqh0.js} +3 -3
- package/dist/cli/index.js +6793 -6
- package/dist/client.js +3 -3
- package/dist/db/better-sqlite.js +4 -4
- package/dist/db/bun-sqlite.js +4 -4
- package/dist/db/d1.js +4 -4
- package/dist/db/index.js +8 -8
- package/dist/db/postgres.js +4 -4
- package/dist/db/sqlite.js +4 -4
- package/dist/index.js +7 -7
- package/dist/runtimes/bun.js +6 -6
- package/dist/runtimes/cloudflare-workers.js +6 -6
- package/dist/runtimes/next.js +6 -6
- package/dist/runtimes/node.js +6 -6
- package/dist/schema/index.js +3 -3
- package/dist/server.js +6 -6
- package/dist/storage/index.js +1 -1
- package/package.json +11 -10
- package/dist/chunk-0hxz770x.js +0 -10
- package/dist/chunk-2gdsy99f.js +0 -581
- package/dist/chunk-3j9zjfmn.js +0 -376
- package/dist/chunk-5b8r0v8c.js +0 -47
- package/dist/chunk-71wwx9vj.js +0 -413
- package/dist/chunk-9by912e9.js +0 -318
- package/dist/chunk-f3dg5dq4.js +0 -75
- package/dist/chunk-g17v7yfr.js +0 -237
- package/dist/chunk-gzdfc1ct.js +0 -1137
- package/dist/chunk-h6dhexzr.js +0 -94
- package/dist/chunk-jvv72110.js +0 -98
- package/dist/chunk-rg3jrfgg.js +0 -93
- package/dist/chunk-rjvcp6ph.js +0 -95
- package/dist/chunk-v0nazhmk.js +0 -263
- package/dist/chunk-wqvdwck9.js +0 -326
- package/dist/chunk-x7bnzswh.js +0 -174
- package/dist/chunk-y4e9twg2.js +0 -76
package/dist/chunk-wqvdwck9.js
DELETED
|
@@ -1,326 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
require_picocolors
|
|
3
|
-
} from "./chunk-f3dg5dq4.js";
|
|
4
|
-
import {
|
|
5
|
-
Ct,
|
|
6
|
-
Gt,
|
|
7
|
-
Jt,
|
|
8
|
-
Nt,
|
|
9
|
-
Rt,
|
|
10
|
-
Vt,
|
|
11
|
-
Wt,
|
|
12
|
-
be
|
|
13
|
-
} from "./chunk-gzdfc1ct.js";
|
|
14
|
-
import {
|
|
15
|
-
defineCommand
|
|
16
|
-
} from "./chunk-71wwx9vj.js";
|
|
17
|
-
import {
|
|
18
|
-
__toESM
|
|
19
|
-
} from "./chunk-6bywt602.js";
|
|
20
|
-
|
|
21
|
-
// src/cli/commands/init.ts
|
|
22
|
-
import fs from "node:fs";
|
|
23
|
-
import { resolve } from "node:path";
|
|
24
|
-
var import_picocolors = __toESM(require_picocolors(), 1);
|
|
25
|
-
function detectFramework(pkgJsonPath) {
|
|
26
|
-
if (!fs.existsSync(pkgJsonPath))
|
|
27
|
-
return "unknown";
|
|
28
|
-
try {
|
|
29
|
-
const pkg = JSON.parse(fs.readFileSync(pkgJsonPath, "utf-8"));
|
|
30
|
-
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
31
|
-
if (deps.next)
|
|
32
|
-
return "nextjs";
|
|
33
|
-
if (deps.nuxt)
|
|
34
|
-
return "nuxt";
|
|
35
|
-
if (deps.vue && deps.vite)
|
|
36
|
-
return "vue";
|
|
37
|
-
if (deps.react && deps.vite)
|
|
38
|
-
return "react";
|
|
39
|
-
if (deps["@angular/core"])
|
|
40
|
-
return "angular";
|
|
41
|
-
if (deps.vite)
|
|
42
|
-
return "vite";
|
|
43
|
-
if (deps.wrangler || deps["@cloudflare/workers-types"])
|
|
44
|
-
return "cloudflare-workers";
|
|
45
|
-
return "unknown";
|
|
46
|
-
} catch (error) {
|
|
47
|
-
return "unknown";
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
var init_default = defineCommand({
|
|
51
|
-
meta: {
|
|
52
|
-
name: "init",
|
|
53
|
-
description: "Initialize OpacaCMS in an existing project"
|
|
54
|
-
},
|
|
55
|
-
args: {
|
|
56
|
-
target: {
|
|
57
|
-
type: "positional",
|
|
58
|
-
description: "Target directory (defaults to current directory)",
|
|
59
|
-
required: false
|
|
60
|
-
}
|
|
61
|
-
},
|
|
62
|
-
async run({ args }) {
|
|
63
|
-
console.log();
|
|
64
|
-
Wt(import_picocolors.default.bgBlue(import_picocolors.default.white(" Welcome to OpacaCMS Setup! ")));
|
|
65
|
-
const targetDir = args.target ? resolve(process.cwd(), args.target) : process.cwd();
|
|
66
|
-
const pkgJsonPath = resolve(targetDir, "package.json");
|
|
67
|
-
let framework = detectFramework(pkgJsonPath);
|
|
68
|
-
if (framework !== "unknown") {
|
|
69
|
-
const confirmFramework = await Rt({
|
|
70
|
-
message: `Detected ${import_picocolors.default.cyan(framework)}. Is this correct?`,
|
|
71
|
-
initialValue: true
|
|
72
|
-
});
|
|
73
|
-
if (Ct(confirmFramework)) {
|
|
74
|
-
Nt("Operation cancelled.");
|
|
75
|
-
process.exit(0);
|
|
76
|
-
}
|
|
77
|
-
if (!confirmFramework) {
|
|
78
|
-
framework = "unknown";
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
if (framework === "unknown") {
|
|
82
|
-
const selected = await Jt({
|
|
83
|
-
message: "Which framework are you using?",
|
|
84
|
-
options: [
|
|
85
|
-
{ value: "nextjs", label: "Next.js" },
|
|
86
|
-
{ value: "nuxt", label: "Nuxt" },
|
|
87
|
-
{ value: "cloudflare-workers", label: "Cloudflare Workers" },
|
|
88
|
-
{ value: "vue", label: "Vue / Vite" },
|
|
89
|
-
{ value: "react", label: "React / Vite" },
|
|
90
|
-
{ value: "angular", label: "Angular" },
|
|
91
|
-
{ value: "unknown", label: "Other / Node.js" }
|
|
92
|
-
]
|
|
93
|
-
});
|
|
94
|
-
if (Ct(selected)) {
|
|
95
|
-
Nt("Operation cancelled.");
|
|
96
|
-
process.exit(0);
|
|
97
|
-
}
|
|
98
|
-
framework = selected;
|
|
99
|
-
}
|
|
100
|
-
const dbType = await Jt({
|
|
101
|
-
message: "Which database would you like to use?",
|
|
102
|
-
options: [
|
|
103
|
-
{ value: "sqlite", label: "SQLite (Local/Bun)" },
|
|
104
|
-
{ value: "d1", label: "Cloudflare D1" },
|
|
105
|
-
{ value: "postgres", label: "PostgreSQL" }
|
|
106
|
-
],
|
|
107
|
-
initialValue: framework === "cloudflare-workers" ? "d1" : "sqlite"
|
|
108
|
-
});
|
|
109
|
-
if (Ct(dbType)) {
|
|
110
|
-
Nt("Operation cancelled.");
|
|
111
|
-
process.exit(0);
|
|
112
|
-
}
|
|
113
|
-
const useAuth = await Rt({
|
|
114
|
-
message: "Enable Authentication (Better Auth)?",
|
|
115
|
-
initialValue: true
|
|
116
|
-
});
|
|
117
|
-
if (Ct(useAuth)) {
|
|
118
|
-
Nt("Operation cancelled.");
|
|
119
|
-
process.exit(0);
|
|
120
|
-
}
|
|
121
|
-
const s = be();
|
|
122
|
-
s.start(`Generating boilerplate for ${framework}...`);
|
|
123
|
-
let dbImport = "";
|
|
124
|
-
let dbInit = "";
|
|
125
|
-
if (dbType === "sqlite") {
|
|
126
|
-
dbImport = `import { createSQLiteAdapter } from 'opacacms/db/sqlite';`;
|
|
127
|
-
dbInit = `createSQLiteAdapter('local.db')`;
|
|
128
|
-
} else if (dbType === "d1") {
|
|
129
|
-
dbImport = `import { createD1Adapter } from 'opacacms/db/d1';`;
|
|
130
|
-
dbInit = `createD1Adapter(env.DB)`;
|
|
131
|
-
} else if (dbType === "postgres") {
|
|
132
|
-
dbImport = `import { createPostgresAdapter } from 'opacacms/db/postgres';`;
|
|
133
|
-
dbInit = `createPostgresAdapter(process.env.DATABASE_URL || '')`;
|
|
134
|
-
}
|
|
135
|
-
let authConfig = "";
|
|
136
|
-
if (useAuth) {
|
|
137
|
-
authConfig = `
|
|
138
|
-
auth: {
|
|
139
|
-
strategies: { emailPassword: true },
|
|
140
|
-
features: {
|
|
141
|
-
apiKeys: { enabled: true }
|
|
142
|
-
}
|
|
143
|
-
},`;
|
|
144
|
-
}
|
|
145
|
-
const srcDir = fs.existsSync(resolve(targetDir, "src")) ? "src/" : "";
|
|
146
|
-
const nextPathPrefix = framework === "nextjs" ? `${srcDir}app/(opaca)/` : "";
|
|
147
|
-
const cfPathPrefix = framework === "cloudflare-workers" ? "src/" : "";
|
|
148
|
-
const pathPrefix = framework === "nextjs" ? nextPathPrefix : cfPathPrefix;
|
|
149
|
-
const configCode = `import { defineConfig } from 'opacacms/config';
|
|
150
|
-
${dbImport}
|
|
151
|
-
import { posts } from './${pathPrefix}opaca/collections/posts';
|
|
152
|
-
import { siteSettings } from './${pathPrefix}opaca/globals/site-settings';
|
|
153
|
-
|
|
154
|
-
${dbType === "d1" ? `const getConfig = (env: any, request: Request) => defineConfig({
|
|
155
|
-
appName: "My OpacaCMS App",
|
|
156
|
-
serverURL: new URL(request.url).origin,
|
|
157
|
-
secret: env.OPACA_SECRET,
|
|
158
|
-
db: ${dbInit},
|
|
159
|
-
runMigrationsOnStartup: true,${authConfig}
|
|
160
|
-
collections: [posts],
|
|
161
|
-
globals: [siteSettings]
|
|
162
|
-
});
|
|
163
|
-
|
|
164
|
-
export default getConfig;` : `export default defineConfig({
|
|
165
|
-
appName: "My OpacaCMS App",
|
|
166
|
-
serverURL: "http://localhost:3000",
|
|
167
|
-
secret: process.env.OPACA_SECRET || "my-super-secret-key-change-me",
|
|
168
|
-
db: ${dbInit},
|
|
169
|
-
runMigrationsOnStartup: true,${authConfig}
|
|
170
|
-
collections: [posts],
|
|
171
|
-
globals: [siteSettings]
|
|
172
|
-
});`}
|
|
173
|
-
`;
|
|
174
|
-
const postsCode = `import { defineCollection, z } from 'opacacms/schema';
|
|
175
|
-
|
|
176
|
-
export const posts = defineCollection({
|
|
177
|
-
slug: 'posts',
|
|
178
|
-
schema: z.object({
|
|
179
|
-
id: z.text().default(() => crypto.randomUUID()),
|
|
180
|
-
title: z.text().required(),
|
|
181
|
-
content: z.richText(),
|
|
182
|
-
})
|
|
183
|
-
});
|
|
184
|
-
`;
|
|
185
|
-
const globalsCode = `import { defineGlobal, z } from 'opacacms/schema';
|
|
186
|
-
|
|
187
|
-
export const siteSettings = defineGlobal({
|
|
188
|
-
slug: 'site-settings',
|
|
189
|
-
schema: z.object({
|
|
190
|
-
siteName: z.text().default("My Awesome Site"),
|
|
191
|
-
description: z.text().optional(),
|
|
192
|
-
})
|
|
193
|
-
});
|
|
194
|
-
`;
|
|
195
|
-
const createDir = (path) => {
|
|
196
|
-
fs.mkdirSync(resolve(targetDir, path), { recursive: true });
|
|
197
|
-
};
|
|
198
|
-
const writeFile = (path, content) => {
|
|
199
|
-
fs.writeFileSync(resolve(targetDir, path), content);
|
|
200
|
-
};
|
|
201
|
-
writeFile("opaca.config.ts", configCode);
|
|
202
|
-
if (framework === "nextjs") {
|
|
203
|
-
const baseDir = `${srcDir}app/(opaca)`;
|
|
204
|
-
createDir(`${baseDir}/opaca/collections`);
|
|
205
|
-
createDir(`${baseDir}/opaca/globals`);
|
|
206
|
-
createDir(`${baseDir}/api/opaca/[[...slug]]`);
|
|
207
|
-
createDir(`${baseDir}/admin/[[...slug]]`);
|
|
208
|
-
writeFile(`${baseDir}/opaca/collections/posts.ts`, postsCode);
|
|
209
|
-
writeFile(`${baseDir}/opaca/globals/site-settings.ts`, globalsCode);
|
|
210
|
-
const importSteps = srcDir ? "../../../../../../" : "../../../../../";
|
|
211
|
-
const routeCode = `import { createNextHandler } from 'opacacms/runtimes/next';
|
|
212
|
-
import config from '${importSteps}opaca.config';
|
|
213
|
-
|
|
214
|
-
const handler = createNextHandler(config);
|
|
215
|
-
|
|
216
|
-
export const GET = handler.GET;
|
|
217
|
-
export const POST = handler.POST;
|
|
218
|
-
export const PUT = handler.PUT;
|
|
219
|
-
export const PATCH = handler.PATCH;
|
|
220
|
-
export const DELETE = handler.DELETE;
|
|
221
|
-
export const OPTIONS = handler.OPTIONS;
|
|
222
|
-
`;
|
|
223
|
-
writeFile(`${baseDir}/api/opaca/[[...slug]]/route.ts`, routeCode);
|
|
224
|
-
const pageCode = `'use client';
|
|
225
|
-
|
|
226
|
-
import { useEffect, useState } from 'react';
|
|
227
|
-
|
|
228
|
-
declare module 'react' {
|
|
229
|
-
namespace JSX {
|
|
230
|
-
interface IntrinsicElements {
|
|
231
|
-
'opaca-admin': {
|
|
232
|
-
'server-url'?: string;
|
|
233
|
-
};
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
export default function Page() {
|
|
239
|
-
const [loaded, setLoaded] = useState(false);
|
|
240
|
-
|
|
241
|
-
useEffect(() => {
|
|
242
|
-
import('opacacms/admin/wc')
|
|
243
|
-
.then(() => setLoaded(true))
|
|
244
|
-
.catch((err) => console.error('Failed to load Opaca Web Component', err));
|
|
245
|
-
}, []);
|
|
246
|
-
|
|
247
|
-
if (!loaded) {
|
|
248
|
-
return (
|
|
249
|
-
<div style={{ padding: '2rem', color: '#71717a' }}>
|
|
250
|
-
Loading Admin Interface...
|
|
251
|
-
</div>
|
|
252
|
-
);
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
// Ensure this points to where your Next.js app is hosted
|
|
256
|
-
const serverUrl =
|
|
257
|
-
typeof window !== 'undefined'
|
|
258
|
-
? window.location.origin
|
|
259
|
-
: 'http://localhost:3000';
|
|
260
|
-
|
|
261
|
-
return <opaca-admin server-url={serverUrl} />;
|
|
262
|
-
}
|
|
263
|
-
`;
|
|
264
|
-
writeFile(`${baseDir}/admin/[[...slug]]/page.tsx`, pageCode);
|
|
265
|
-
} else if (framework === "cloudflare-workers") {
|
|
266
|
-
createDir("src/opaca/collections");
|
|
267
|
-
createDir("src/opaca/globals");
|
|
268
|
-
writeFile("src/opaca/collections/posts.ts", postsCode);
|
|
269
|
-
writeFile("src/opaca/globals/site-settings.ts", globalsCode);
|
|
270
|
-
const indexCode = `import { createCloudflareWorkersHandler } from "opacacms/runtimes/cloudflare-workers";
|
|
271
|
-
import config from "../opaca.config";
|
|
272
|
-
|
|
273
|
-
export default createCloudflareWorkersHandler(config, { enableAdmin: true });
|
|
274
|
-
`;
|
|
275
|
-
writeFile("src/index.ts", indexCode);
|
|
276
|
-
} else if (framework === "nuxt") {
|
|
277
|
-
createDir("opaca/collections");
|
|
278
|
-
createDir("opaca/globals");
|
|
279
|
-
createDir("server/api/opaca");
|
|
280
|
-
writeFile("opaca/collections/posts.ts", postsCode);
|
|
281
|
-
writeFile("opaca/globals/site-settings.ts", globalsCode);
|
|
282
|
-
const routeCode = `import { createAPIRouter } from 'opacacms/server/router';
|
|
283
|
-
import config from '../../../opaca.config';
|
|
284
|
-
|
|
285
|
-
// OpacaCMS API Router (You may need to adapt this to native Nuxt handler or Hono integration)
|
|
286
|
-
export default defineEventHandler(async (event) => {
|
|
287
|
-
// Placeholder for OpacaCMS Nuxt integration
|
|
288
|
-
});
|
|
289
|
-
`;
|
|
290
|
-
writeFile("server/api/opaca/[...slug].ts", routeCode);
|
|
291
|
-
} else {
|
|
292
|
-
createDir("opaca/collections");
|
|
293
|
-
createDir("opaca/globals");
|
|
294
|
-
writeFile("opaca/collections/posts.ts", postsCode);
|
|
295
|
-
writeFile("opaca/globals/site-settings.ts", globalsCode);
|
|
296
|
-
const serverCode = `import { createBunHandler } from 'opacacms/runtimes/bun';
|
|
297
|
-
import config from './opaca.config';
|
|
298
|
-
|
|
299
|
-
const { app, init } = createBunHandler(config, { port: 3001 });
|
|
300
|
-
|
|
301
|
-
await init(); // Connects DB, runs migrations, starts server
|
|
302
|
-
console.log('\uD83D\uDE80 OpacaCMS Backend Listening on http://localhost:3001');
|
|
303
|
-
`;
|
|
304
|
-
writeFile("server.ts", serverCode);
|
|
305
|
-
}
|
|
306
|
-
if (fs.existsSync(pkgJsonPath)) {
|
|
307
|
-
try {
|
|
308
|
-
const pkg = JSON.parse(fs.readFileSync(pkgJsonPath, "utf-8"));
|
|
309
|
-
if (!pkg.dependencies)
|
|
310
|
-
pkg.dependencies = {};
|
|
311
|
-
if (!pkg.dependencies.opacacms) {
|
|
312
|
-
pkg.dependencies.opacacms = "latest";
|
|
313
|
-
fs.writeFileSync(pkgJsonPath, JSON.stringify(pkg, null, 2));
|
|
314
|
-
}
|
|
315
|
-
} catch (e) {}
|
|
316
|
-
}
|
|
317
|
-
s.stop(`Scaffolding complete!`);
|
|
318
|
-
Vt(`1. Check the newly created \`opaca.config.ts\` and \`opaca\` folder.
|
|
319
|
-
2. Run \`npm install\` (or your preferred package manager) to install dependencies.
|
|
320
|
-
3. Start your dev server!`, "Next Steps");
|
|
321
|
-
Gt(`Build something awesome! \uD83C\uDF88`);
|
|
322
|
-
}
|
|
323
|
-
});
|
|
324
|
-
export {
|
|
325
|
-
init_default as default
|
|
326
|
-
};
|
package/dist/chunk-x7bnzswh.js
DELETED
|
@@ -1,174 +0,0 @@
|
|
|
1
|
-
import"./chunk-6bywt602.js";
|
|
2
|
-
|
|
3
|
-
// src/cli/core/mocks/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
|
-
if (!dbPath) {
|
|
23
|
-
finalDbPath = ":memory:";
|
|
24
|
-
console.log("[OpacaCMS] Using in-memory R2 mock");
|
|
25
|
-
} else {
|
|
26
|
-
const absolutePath = path.isAbsolute(dbPath) ? dbPath : path.resolve(process.cwd(), dbPath);
|
|
27
|
-
if (fs.existsSync(absolutePath) && fs.statSync(absolutePath).isDirectory()) {
|
|
28
|
-
finalDbPath = path.join(absolutePath, "mock-bucket.sqlite");
|
|
29
|
-
} else if (!absolutePath.endsWith(".sqlite")) {
|
|
30
|
-
finalDbPath = absolutePath.endsWith("/") ? path.join(absolutePath, "mock-bucket.sqlite") : absolutePath + ".sqlite";
|
|
31
|
-
} else {
|
|
32
|
-
finalDbPath = absolutePath;
|
|
33
|
-
}
|
|
34
|
-
console.log(`[OpacaCMS] Using local R2 mock: ${path.basename(finalDbPath)}`);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
if (finalDbPath !== ":memory:") {
|
|
38
|
-
const dir = path.dirname(finalDbPath);
|
|
39
|
-
if (!fs.existsSync(dir)) {
|
|
40
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
41
|
-
}
|
|
42
|
-
blobsDir = finalDbPath.replace(".sqlite", ".blobs");
|
|
43
|
-
if (!fs.existsSync(blobsDir)) {
|
|
44
|
-
fs.mkdirSync(blobsDir, { recursive: true });
|
|
45
|
-
}
|
|
46
|
-
} else {
|
|
47
|
-
blobsDir = path.join(fs.realpathSync("/tmp"), `opaca-blobs-${crypto.randomUUID()}`);
|
|
48
|
-
}
|
|
49
|
-
try {
|
|
50
|
-
sqlite = new Database(finalDbPath);
|
|
51
|
-
} catch (err) {
|
|
52
|
-
throw new Error(`Failed to open R2 mock database at ${finalDbPath}: ${err.message}`);
|
|
53
|
-
}
|
|
54
|
-
sqlite.exec(`
|
|
55
|
-
CREATE TABLE IF NOT EXISTS _mf_objects (
|
|
56
|
-
key TEXT PRIMARY KEY,
|
|
57
|
-
blob_id TEXT,
|
|
58
|
-
version TEXT,
|
|
59
|
-
size INTEGER,
|
|
60
|
-
etag TEXT,
|
|
61
|
-
uploaded INTEGER,
|
|
62
|
-
checksums TEXT,
|
|
63
|
-
http_metadata TEXT,
|
|
64
|
-
custom_metadata TEXT
|
|
65
|
-
)
|
|
66
|
-
`);
|
|
67
|
-
const getBlobPath = (blobId) => path.join(blobsDir, blobId);
|
|
68
|
-
return {
|
|
69
|
-
async put(key, value, options) {
|
|
70
|
-
const blobId = crypto.randomUUID();
|
|
71
|
-
const filePath = getBlobPath(blobId);
|
|
72
|
-
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());
|
|
73
|
-
fs.writeFileSync(filePath, buffer);
|
|
74
|
-
const etag = crypto.createHash("md5").update(buffer).digest("hex");
|
|
75
|
-
const uploaded = Date.now();
|
|
76
|
-
const size = buffer.length;
|
|
77
|
-
const httpMetadataObj = {};
|
|
78
|
-
if (options?.httpMetadata?.contentType) {
|
|
79
|
-
httpMetadataObj.contentType = options.httpMetadata.contentType;
|
|
80
|
-
}
|
|
81
|
-
const customMetadataObj = { ...options?.customMetadata };
|
|
82
|
-
if (options?.customMetadata?.sourceUrl) {
|
|
83
|
-
customMetadataObj.sourceUrl = options.customMetadata.sourceUrl;
|
|
84
|
-
}
|
|
85
|
-
const httpMetadata = JSON.stringify(httpMetadataObj);
|
|
86
|
-
const customMetadata = JSON.stringify(customMetadataObj);
|
|
87
|
-
sqlite.prepare(`
|
|
88
|
-
INSERT OR REPLACE INTO _mf_objects
|
|
89
|
-
(key, blob_id, version, size, etag, uploaded, checksums, http_metadata, custom_metadata)
|
|
90
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
91
|
-
`).run(key, blobId, "v1", size, etag, uploaded, "{}", httpMetadata, customMetadata);
|
|
92
|
-
return {
|
|
93
|
-
key,
|
|
94
|
-
size,
|
|
95
|
-
etag,
|
|
96
|
-
httpMetadata: options?.httpMetadata || {},
|
|
97
|
-
customMetadata: options?.customMetadata || {}
|
|
98
|
-
};
|
|
99
|
-
},
|
|
100
|
-
async get(key) {
|
|
101
|
-
const row = sqlite.prepare("SELECT * FROM _mf_objects WHERE key = ?").get(key);
|
|
102
|
-
if (!row)
|
|
103
|
-
return null;
|
|
104
|
-
const filePath = getBlobPath(row.blob_id);
|
|
105
|
-
if (!fs.existsSync(filePath))
|
|
106
|
-
return null;
|
|
107
|
-
const buffer = fs.readFileSync(filePath);
|
|
108
|
-
const stream = new ReadableStream({
|
|
109
|
-
start(controller) {
|
|
110
|
-
controller.enqueue(new Uint8Array(buffer));
|
|
111
|
-
controller.close();
|
|
112
|
-
}
|
|
113
|
-
});
|
|
114
|
-
return {
|
|
115
|
-
key: row.key,
|
|
116
|
-
size: row.size,
|
|
117
|
-
etag: row.etag,
|
|
118
|
-
uploaded: new Date(row.uploaded),
|
|
119
|
-
httpMetadata: JSON.parse(row.http_metadata || "{}"),
|
|
120
|
-
customMetadata: JSON.parse(row.custom_metadata || "{}"),
|
|
121
|
-
body: stream,
|
|
122
|
-
bodyUsed: false,
|
|
123
|
-
async arrayBuffer() {
|
|
124
|
-
return buffer.buffer;
|
|
125
|
-
},
|
|
126
|
-
async text() {
|
|
127
|
-
return buffer.toString();
|
|
128
|
-
},
|
|
129
|
-
async json() {
|
|
130
|
-
return JSON.parse(buffer.toString());
|
|
131
|
-
}
|
|
132
|
-
};
|
|
133
|
-
},
|
|
134
|
-
async head(key) {
|
|
135
|
-
const row = sqlite.prepare("SELECT key, size, etag, http_metadata, custom_metadata, uploaded FROM _mf_objects WHERE key = ?").get(key);
|
|
136
|
-
if (!row)
|
|
137
|
-
return null;
|
|
138
|
-
return {
|
|
139
|
-
key: row.key,
|
|
140
|
-
size: row.size,
|
|
141
|
-
etag: row.etag,
|
|
142
|
-
uploaded: new Date(row.uploaded),
|
|
143
|
-
httpMetadata: JSON.parse(row.http_metadata || "{}"),
|
|
144
|
-
customMetadata: JSON.parse(row.custom_metadata || "{}")
|
|
145
|
-
};
|
|
146
|
-
},
|
|
147
|
-
async delete(key) {
|
|
148
|
-
const row = sqlite.prepare("SELECT blob_id FROM _mf_objects WHERE key = ?").get(key);
|
|
149
|
-
if (row) {
|
|
150
|
-
const filePath = getBlobPath(row.blob_id);
|
|
151
|
-
if (fs.existsSync(filePath))
|
|
152
|
-
fs.unlinkSync(filePath);
|
|
153
|
-
sqlite.prepare("DELETE FROM _mf_objects WHERE key = ?").run(key);
|
|
154
|
-
}
|
|
155
|
-
},
|
|
156
|
-
async list() {
|
|
157
|
-
const rows = sqlite.prepare("SELECT * FROM _mf_objects").all();
|
|
158
|
-
return {
|
|
159
|
-
objects: rows.map((row) => ({
|
|
160
|
-
key: row.key,
|
|
161
|
-
size: row.size,
|
|
162
|
-
etag: row.etag,
|
|
163
|
-
uploaded: new Date(row.uploaded),
|
|
164
|
-
httpMetadata: JSON.parse(row.http_metadata || "{}"),
|
|
165
|
-
customMetadata: JSON.parse(row.custom_metadata || "{}")
|
|
166
|
-
})),
|
|
167
|
-
truncated: false
|
|
168
|
-
};
|
|
169
|
-
}
|
|
170
|
-
};
|
|
171
|
-
}
|
|
172
|
-
export {
|
|
173
|
-
createR2Mock
|
|
174
|
-
};
|
package/dist/chunk-y4e9twg2.js
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
require_picocolors
|
|
3
|
-
} from "./chunk-f3dg5dq4.js";
|
|
4
|
-
import {
|
|
5
|
-
Gt,
|
|
6
|
-
R,
|
|
7
|
-
Vt,
|
|
8
|
-
Wt
|
|
9
|
-
} from "./chunk-gzdfc1ct.js";
|
|
10
|
-
import {
|
|
11
|
-
defineCommand
|
|
12
|
-
} from "./chunk-71wwx9vj.js";
|
|
13
|
-
import {
|
|
14
|
-
__toESM
|
|
15
|
-
} from "./chunk-6bywt602.js";
|
|
16
|
-
|
|
17
|
-
// src/cli/commands/dev.ts
|
|
18
|
-
import { spawn } from "node:child_process";
|
|
19
|
-
import fs from "node:fs";
|
|
20
|
-
import { resolve } from "node:path";
|
|
21
|
-
var import_picocolors = __toESM(require_picocolors(), 1);
|
|
22
|
-
var dev_default = defineCommand({
|
|
23
|
-
meta: {
|
|
24
|
-
name: "dev",
|
|
25
|
-
description: "Start the OpacaCMS development server"
|
|
26
|
-
},
|
|
27
|
-
args: {
|
|
28
|
-
entry: {
|
|
29
|
-
type: "string",
|
|
30
|
-
description: "Path to your entry point (default: index.ts)",
|
|
31
|
-
default: "index.ts"
|
|
32
|
-
}
|
|
33
|
-
},
|
|
34
|
-
async run({ args }) {
|
|
35
|
-
console.log();
|
|
36
|
-
Wt(import_picocolors.default.bgBlue(import_picocolors.default.white(" OpacaCMS Dev Server ")));
|
|
37
|
-
const entryPath = resolve(process.cwd(), args.entry);
|
|
38
|
-
if (!fs.existsSync(entryPath)) {
|
|
39
|
-
R.error(import_picocolors.default.red(`Entry file not found at ${entryPath}`));
|
|
40
|
-
R.info("Try specifying the entry file: opacacms dev --entry src/index.ts");
|
|
41
|
-
process.exit(1);
|
|
42
|
-
}
|
|
43
|
-
Vt(`Watching for changes...`, "Status");
|
|
44
|
-
const isD1 = fs.readFileSync(entryPath, "utf-8").includes("createCloudflareWorkersHandler");
|
|
45
|
-
let cmd = "bun";
|
|
46
|
-
let cmdArgs = ["run", "--watch", args.entry];
|
|
47
|
-
if (isD1) {
|
|
48
|
-
cmd = "bun";
|
|
49
|
-
cmdArgs = ["x", "wrangler", "dev", args.entry];
|
|
50
|
-
}
|
|
51
|
-
const child = spawn(cmd, cmdArgs, {
|
|
52
|
-
stdio: "inherit",
|
|
53
|
-
cwd: process.cwd(),
|
|
54
|
-
env: process.env
|
|
55
|
-
});
|
|
56
|
-
child.on("error", (err) => {
|
|
57
|
-
R.error(import_picocolors.default.red(`Failed to start server: ${err.message}`));
|
|
58
|
-
});
|
|
59
|
-
child.on("exit", (code) => {
|
|
60
|
-
if (code !== 0) {
|
|
61
|
-
R.warn(`Server exited with code ${code}`);
|
|
62
|
-
}
|
|
63
|
-
Gt("Goodbye!");
|
|
64
|
-
process.exit(code || 0);
|
|
65
|
-
});
|
|
66
|
-
process.on("SIGINT", () => {
|
|
67
|
-
child.kill("SIGINT");
|
|
68
|
-
});
|
|
69
|
-
process.on("SIGTERM", () => {
|
|
70
|
-
child.kill("SIGTERM");
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
export {
|
|
75
|
-
dev_default as default
|
|
76
|
-
};
|