opacacms 0.3.1 → 0.3.2
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/auth-client.d.ts +41 -41
- package/dist/admin/webcomponent.js +37 -35
- package/dist/auth/index.d.ts +43 -48
- package/dist/{chunk-gyaf5kgf.js → chunk-0hxz770x.js} +2 -2
- package/dist/{chunk-7rr5p01g.js → chunk-2gdsy99f.js} +1 -1
- package/dist/{chunk-1qm0m8r8.js → chunk-71wwx9vj.js} +2 -2
- package/dist/{chunk-d7cgd6vn.js → chunk-9by912e9.js} +6 -6
- package/dist/{chunk-rwqwsanx.js → chunk-f3dg5dq4.js} +1 -1
- package/dist/{chunk-mp2gt9yh.js → chunk-g17v7yfr.js} +3 -3
- package/dist/{chunk-ec4jhybj.js → chunk-gzdfc1ct.js} +3 -3
- package/dist/{chunk-majsbncm.js → chunk-jvv72110.js} +8 -8
- package/dist/{chunk-d0tb1xjw.js → chunk-rg3jrfgg.js} +4 -4
- package/dist/{chunk-56n342hs.js → chunk-rjvcp6ph.js} +4 -4
- package/dist/{chunk-63yg00vx.js → chunk-v0nazhmk.js} +3 -3
- package/dist/chunk-wqvdwck9.js +326 -0
- package/dist/{chunk-r0ms5tk1.js → chunk-y4e9twg2.js} +3 -3
- package/dist/cli/commands/init.d.ts +1 -6
- package/dist/cli/index.js +2 -2
- package/package.json +11 -10
- package/dist/chunk-fatyf6f7.js +0 -221
|
@@ -0,0 +1,326 @@
|
|
|
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
|
+
};
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
require_picocolors
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-f3dg5dq4.js";
|
|
4
4
|
import {
|
|
5
5
|
Gt,
|
|
6
6
|
R,
|
|
7
7
|
Vt,
|
|
8
8
|
Wt
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-gzdfc1ct.js";
|
|
10
10
|
import {
|
|
11
11
|
defineCommand
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-71wwx9vj.js";
|
|
13
13
|
import {
|
|
14
14
|
__toESM
|
|
15
15
|
} from "./chunk-6bywt602.js";
|
|
@@ -1,13 +1,8 @@
|
|
|
1
1
|
declare const _default: import("citty").CommandDef<{
|
|
2
2
|
readonly target: {
|
|
3
3
|
readonly type: "positional";
|
|
4
|
-
readonly description: "Target directory
|
|
4
|
+
readonly description: "Target directory (defaults to current directory)";
|
|
5
5
|
readonly required: false;
|
|
6
6
|
};
|
|
7
|
-
readonly example: {
|
|
8
|
-
readonly type: "string";
|
|
9
|
-
readonly alias: "e";
|
|
10
|
-
readonly description: "Use an example template";
|
|
11
|
-
};
|
|
12
7
|
}>;
|
|
13
8
|
export default _default;
|
package/dist/cli/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opacacms",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "OpacaCMS: A lightweight, type-safe, and developer-first Headless CMS for the edge and beyond.",
|
|
6
6
|
"keywords": [
|
|
@@ -146,6 +146,7 @@
|
|
|
146
146
|
"@hono-rate-limiter/cloudflare": "^0.2.2",
|
|
147
147
|
"@hono/bun-transpiler": "^0.2.1",
|
|
148
148
|
"@hono/esbuild-transpiler": "^0.1.4",
|
|
149
|
+
"@hono/graphql-server": "^0.7.0",
|
|
149
150
|
"@hono/node-server": "^1.19.11",
|
|
150
151
|
"@lexical/code": "^0.41.0",
|
|
151
152
|
"@lexical/history": "^0.41.0",
|
|
@@ -162,6 +163,8 @@
|
|
|
162
163
|
"@nanostores/react": "^1.0.0",
|
|
163
164
|
"@nanostores/router": "^1.0.0",
|
|
164
165
|
"@r2wc/react-to-web-component": "^2.1.1",
|
|
166
|
+
"@radix-ui/react-accordion": "^1.2.12",
|
|
167
|
+
"@radix-ui/react-tooltip": "^1.2.8",
|
|
165
168
|
"@scalar/hono-api-reference": "^0.10.4",
|
|
166
169
|
"@tanstack/react-form": "^1.28.5",
|
|
167
170
|
"@testing-library/dom": "^10.4.1",
|
|
@@ -170,15 +173,19 @@
|
|
|
170
173
|
"@types/bun": "latest",
|
|
171
174
|
"@types/react": "^19.2.14",
|
|
172
175
|
"@types/react-dom": "^19.2.3",
|
|
176
|
+
"better-auth": "^1.5.5",
|
|
173
177
|
"better-sqlite3": "^12.6.2",
|
|
174
178
|
"bun-plugin-scss": "^1.0.0",
|
|
175
179
|
"class-variance-authority": "^0.7.1",
|
|
176
180
|
"dotenv": "^17.3.1",
|
|
177
181
|
"esbuild": "^0.27.4",
|
|
178
182
|
"esbuild-wasm": "^0.27.4",
|
|
183
|
+
"graphql": "^16.13.1",
|
|
179
184
|
"happy-dom": "^20.8.4",
|
|
180
185
|
"hono": "^4.12.7",
|
|
186
|
+
"hono-rate-limiter": "^0.5.3",
|
|
181
187
|
"ky": "^1.14.3",
|
|
188
|
+
"kysely": "^0.28.11",
|
|
182
189
|
"kysely-bun-sqlite": "^0.4.0",
|
|
183
190
|
"kysely-d1": "^0.4.0",
|
|
184
191
|
"kysely-postgres-js": "^3.0.0",
|
|
@@ -188,7 +195,8 @@
|
|
|
188
195
|
"postgres": "^3.4.8",
|
|
189
196
|
"radix-ui": "^1.4.3",
|
|
190
197
|
"sass": "^1.98.0",
|
|
191
|
-
"zod": "^4.3.6"
|
|
198
|
+
"zod": "^4.3.6",
|
|
199
|
+
"zod-to-json-schema": "^3.25.1"
|
|
192
200
|
},
|
|
193
201
|
"peerDependencies": {
|
|
194
202
|
"hono": "^4.0.0",
|
|
@@ -208,14 +216,7 @@
|
|
|
208
216
|
"optional": true
|
|
209
217
|
}
|
|
210
218
|
},
|
|
211
|
-
"dependencies": {
|
|
212
|
-
"@hono/graphql-server": "^0.7.0",
|
|
213
|
-
"better-auth": "^1.5.5",
|
|
214
|
-
"graphql": "^16.13.1",
|
|
215
|
-
"hono-rate-limiter": "^0.5.3",
|
|
216
|
-
"kysely": "^0.28.11",
|
|
217
|
-
"zod-to-json-schema": "^3.25.1"
|
|
218
|
-
},
|
|
219
|
+
"dependencies": {},
|
|
219
220
|
"files": [
|
|
220
221
|
"dist"
|
|
221
222
|
]
|
package/dist/chunk-fatyf6f7.js
DELETED
|
@@ -1,221 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
require_picocolors
|
|
3
|
-
} from "./chunk-rwqwsanx.js";
|
|
4
|
-
import {
|
|
5
|
-
Ct,
|
|
6
|
-
Gt,
|
|
7
|
-
Jt,
|
|
8
|
-
Nt,
|
|
9
|
-
Rt,
|
|
10
|
-
Vt,
|
|
11
|
-
Wt,
|
|
12
|
-
Zt,
|
|
13
|
-
be
|
|
14
|
-
} from "./chunk-ec4jhybj.js";
|
|
15
|
-
import {
|
|
16
|
-
defineCommand
|
|
17
|
-
} from "./chunk-1qm0m8r8.js";
|
|
18
|
-
import {
|
|
19
|
-
__toESM
|
|
20
|
-
} from "./chunk-6bywt602.js";
|
|
21
|
-
|
|
22
|
-
// src/cli/commands/init.ts
|
|
23
|
-
import fs from "node:fs";
|
|
24
|
-
import { resolve } from "node:path";
|
|
25
|
-
var import_picocolors = __toESM(require_picocolors(), 1);
|
|
26
|
-
var init_default = defineCommand({
|
|
27
|
-
meta: {
|
|
28
|
-
name: "init",
|
|
29
|
-
description: "Initialize a new OpacaCMS project"
|
|
30
|
-
},
|
|
31
|
-
args: {
|
|
32
|
-
target: {
|
|
33
|
-
type: "positional",
|
|
34
|
-
description: "Target directory name",
|
|
35
|
-
required: false
|
|
36
|
-
},
|
|
37
|
-
example: {
|
|
38
|
-
type: "string",
|
|
39
|
-
alias: "e",
|
|
40
|
-
description: "Use an example template"
|
|
41
|
-
}
|
|
42
|
-
},
|
|
43
|
-
async run({ args }) {
|
|
44
|
-
console.log();
|
|
45
|
-
Wt(import_picocolors.default.bgBlue(import_picocolors.default.white(" Welcome to OpacaCMS! ")));
|
|
46
|
-
let target = args.target;
|
|
47
|
-
if (!target) {
|
|
48
|
-
const response = await Zt({
|
|
49
|
-
message: "Where should we create your project?",
|
|
50
|
-
placeholder: "my-opaca-app",
|
|
51
|
-
defaultValue: "my-opaca-app"
|
|
52
|
-
});
|
|
53
|
-
if (Ct(response)) {
|
|
54
|
-
Nt("Operation cancelled.");
|
|
55
|
-
process.exit(0);
|
|
56
|
-
}
|
|
57
|
-
target = response;
|
|
58
|
-
}
|
|
59
|
-
if (args.example) {
|
|
60
|
-
const s2 = be();
|
|
61
|
-
s2.start(`Using example template: ${args.example}`);
|
|
62
|
-
let currentDir = resolve(import.meta.dirname);
|
|
63
|
-
let exampleDir = "";
|
|
64
|
-
const localExample = resolve(process.cwd(), "examples", args.example);
|
|
65
|
-
if (fs.existsSync(localExample)) {
|
|
66
|
-
exampleDir = localExample;
|
|
67
|
-
} else {
|
|
68
|
-
while (currentDir !== resolve(currentDir, "..")) {
|
|
69
|
-
const potential = resolve(currentDir, "examples", args.example);
|
|
70
|
-
if (fs.existsSync(potential)) {
|
|
71
|
-
exampleDir = potential;
|
|
72
|
-
break;
|
|
73
|
-
}
|
|
74
|
-
currentDir = resolve(currentDir, "..");
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
if (!exampleDir) {
|
|
78
|
-
s2.stop(`Example ${args.example} not found.`);
|
|
79
|
-
process.exit(1);
|
|
80
|
-
}
|
|
81
|
-
fs.cpSync(exampleDir, resolve(process.cwd(), target), { recursive: true });
|
|
82
|
-
s2.stop(`Copied example ${args.example} to ${target}!`);
|
|
83
|
-
Gt(`Run ${import_picocolors.default.cyan(`cd ${target} && bun install`)} to get started.`);
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
const dbType = await Jt({
|
|
87
|
-
message: "Which database would you like to use?",
|
|
88
|
-
options: [
|
|
89
|
-
{ value: "sqlite", label: "SQLite (Local/Bun)" },
|
|
90
|
-
{ value: "d1", label: "Cloudflare D1" },
|
|
91
|
-
{ value: "postgres", label: "PostgreSQL" }
|
|
92
|
-
],
|
|
93
|
-
initialValue: "sqlite"
|
|
94
|
-
});
|
|
95
|
-
if (Ct(dbType)) {
|
|
96
|
-
Nt("Operation cancelled.");
|
|
97
|
-
process.exit(0);
|
|
98
|
-
}
|
|
99
|
-
const useAuth = await Rt({
|
|
100
|
-
message: "Enable Authentication (Better Auth)?",
|
|
101
|
-
initialValue: true
|
|
102
|
-
});
|
|
103
|
-
if (Ct(useAuth)) {
|
|
104
|
-
Nt("Operation cancelled.");
|
|
105
|
-
process.exit(0);
|
|
106
|
-
}
|
|
107
|
-
const s = be();
|
|
108
|
-
s.start(`Generating boilerplate in ./${target}...`);
|
|
109
|
-
fs.mkdirSync(resolve(process.cwd(), target), { recursive: true });
|
|
110
|
-
let dbImport = "";
|
|
111
|
-
let dbInit = "";
|
|
112
|
-
if (dbType === "sqlite") {
|
|
113
|
-
dbImport = `import { createSQLiteAdapter } from 'opacacms/db/sqlite';`;
|
|
114
|
-
dbInit = `createSQLiteAdapter('local.db')`;
|
|
115
|
-
} else if (dbType === "d1") {
|
|
116
|
-
dbImport = `import { createD1Adapter } from 'opacacms/db/d1';`;
|
|
117
|
-
dbInit = `createD1Adapter(env.DB)`;
|
|
118
|
-
} else if (dbType === "postgres") {
|
|
119
|
-
dbImport = `import { createPostgresAdapter } from 'opacacms/db/postgres';`;
|
|
120
|
-
dbInit = `createPostgresAdapter(process.env.DATABASE_URL!)`;
|
|
121
|
-
}
|
|
122
|
-
let authConfig = "";
|
|
123
|
-
if (useAuth) {
|
|
124
|
-
authConfig = `
|
|
125
|
-
auth: {
|
|
126
|
-
strategies: { emailPassword: true },
|
|
127
|
-
features: {
|
|
128
|
-
apiKeys: { enabled: true }
|
|
129
|
-
}
|
|
130
|
-
},`;
|
|
131
|
-
}
|
|
132
|
-
let configCode = `import { defineConfig } from 'opacacms/config';
|
|
133
|
-
import { z, defineCollection } from 'opacacms/schema';
|
|
134
|
-
${dbImport}
|
|
135
|
-
|
|
136
|
-
const posts = defineCollection({
|
|
137
|
-
slug: 'posts',
|
|
138
|
-
schema: z.object({
|
|
139
|
-
id: z.text().default(() => crypto.randomUUID()),
|
|
140
|
-
title: z.text().required(),
|
|
141
|
-
content: z.richText(),
|
|
142
|
-
})
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
export default defineConfig({
|
|
146
|
-
appName: "My OpacaCMS App",
|
|
147
|
-
serverURL: "http://localhost:3000",
|
|
148
|
-
secret: "my-super-secret-key-change-me",
|
|
149
|
-
db: ${dbInit},
|
|
150
|
-
runMigrationsOnStartup: true,${authConfig}
|
|
151
|
-
collections: [posts]
|
|
152
|
-
});
|
|
153
|
-
`;
|
|
154
|
-
if (dbType === "d1") {
|
|
155
|
-
configCode = `import { defineConfig } from 'opacacms/config';
|
|
156
|
-
import { z, defineCollection } from 'opacacms/schema';
|
|
157
|
-
${dbImport}
|
|
158
|
-
|
|
159
|
-
const posts = defineCollection({
|
|
160
|
-
slug: 'posts',
|
|
161
|
-
schema: z.object({
|
|
162
|
-
id: z.text().default(() => crypto.randomUUID()),
|
|
163
|
-
title: z.text().required(),
|
|
164
|
-
content: z.richText(),
|
|
165
|
-
})
|
|
166
|
-
});
|
|
167
|
-
|
|
168
|
-
const getConfig = (env: any, request: Request) => defineConfig({
|
|
169
|
-
appName: "My Edge App",
|
|
170
|
-
serverURL: new URL(request.url).origin,
|
|
171
|
-
secret: env.OPACA_SECRET,
|
|
172
|
-
db: ${dbInit},
|
|
173
|
-
runMigrationsOnStartup: true,${authConfig}
|
|
174
|
-
collections: [posts]
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
export default getConfig;
|
|
178
|
-
`;
|
|
179
|
-
}
|
|
180
|
-
fs.writeFileSync(resolve(process.cwd(), target, "opacacms.config.ts"), configCode);
|
|
181
|
-
let serverCode = "";
|
|
182
|
-
if (dbType === "d1") {
|
|
183
|
-
serverCode = `import { createCloudflareWorkersHandler } from 'opacacms/runtimes/cloudflare-workers';
|
|
184
|
-
import config from './opacacms.config';
|
|
185
|
-
|
|
186
|
-
const app = createCloudflareWorkersHandler(config);
|
|
187
|
-
|
|
188
|
-
export default app;
|
|
189
|
-
`;
|
|
190
|
-
} else {
|
|
191
|
-
serverCode = `import { createBunHandler } from 'opacacms/runtimes/bun';
|
|
192
|
-
import config from './opacacms.config';
|
|
193
|
-
|
|
194
|
-
const { app, init } = createBunHandler(config, { port: 3000 });
|
|
195
|
-
|
|
196
|
-
await init(); // Connects DB, runs migrations, starts server
|
|
197
|
-
console.log('\uD83D\uDE80 Listening on http://localhost:3000');
|
|
198
|
-
`;
|
|
199
|
-
}
|
|
200
|
-
fs.writeFileSync(resolve(process.cwd(), target, "index.ts"), serverCode);
|
|
201
|
-
const pkgJson = {
|
|
202
|
-
name: target,
|
|
203
|
-
type: "module",
|
|
204
|
-
scripts: {
|
|
205
|
-
dev: dbType === "d1" ? "wrangler dev" : "bun run --watch index.ts"
|
|
206
|
-
},
|
|
207
|
-
dependencies: {
|
|
208
|
-
opacacms: "latest"
|
|
209
|
-
}
|
|
210
|
-
};
|
|
211
|
-
fs.writeFileSync(resolve(process.cwd(), target, "package.json"), JSON.stringify(pkgJson, null, 2));
|
|
212
|
-
s.stop(`Project created successfully in ${import_picocolors.default.green(`./${target}`)}!`);
|
|
213
|
-
Vt(`cd ${target}
|
|
214
|
-
bun install
|
|
215
|
-
bun run dev`, "Next Steps");
|
|
216
|
-
Gt(`Build something awesome! \uD83C\uDF88`);
|
|
217
|
-
}
|
|
218
|
-
});
|
|
219
|
-
export {
|
|
220
|
-
init_default as default
|
|
221
|
-
};
|