opacacms 0.3.1 → 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.
Files changed (59) hide show
  1. package/dist/admin/auth-client.d.ts +41 -41
  2. package/dist/admin/index.js +1 -1
  3. package/dist/admin/react.js +1 -1
  4. package/dist/admin/vue.js +1 -1
  5. package/dist/auth/index.d.ts +43 -48
  6. package/dist/{chunk-g9bxb6h0.js → chunk-2fm4kv2q.js} +1 -1
  7. package/dist/chunk-2vbfc4q8.js +6 -0
  8. package/dist/{chunk-adq2b75c.js → chunk-40tky6qh.js} +2 -2
  9. package/dist/{chunk-e0g6gn7n.js → chunk-49e16hjg.js} +3 -3
  10. package/dist/{chunk-fnsf1dfm.js → chunk-526a3gqx.js} +1 -1
  11. package/dist/{chunk-sqsfk9p4.js → chunk-6m1jhxmd.js} +1 -1
  12. package/dist/{chunk-6bywt602.js → chunk-8sqjbsgt.js} +1 -26
  13. package/dist/{chunk-n1twhqmf.js → chunk-acghejk8.js} +1 -1
  14. package/dist/{chunk-m24yqkeq.js → chunk-b1g8jmth.js} +3 -3
  15. package/dist/{chunk-5422w4eq.js → chunk-cm5rvcnn.js} +5 -5
  16. package/dist/{chunk-941zxavt.js → chunk-h2y2t07h.js} +4 -4
  17. package/dist/{chunk-6qs0g65f.js → chunk-h8v093av.js} +1 -1
  18. package/dist/{chunk-m5ems3hh.js → chunk-hthm9srb.js} +1 -1
  19. package/dist/{chunk-2k3ysje3.js → chunk-nch158fe.js} +1 -1
  20. package/dist/{chunk-naqcqj8n.js → chunk-pj31j6j0.js} +4 -4
  21. package/dist/{chunk-qsh2nqz3.js → chunk-pw2a9war.js} +3 -3
  22. package/dist/{chunk-j8js1y0h.js → chunk-r5k7jw66.js} +1 -1
  23. package/dist/{chunk-48ywpd0a.js → chunk-vmz9ncf1.js} +1 -1
  24. package/dist/{chunk-qhdsjek6.js → chunk-wry3rqh0.js} +3 -3
  25. package/dist/cli/commands/init.d.ts +1 -6
  26. package/dist/cli/index.js +6793 -6
  27. package/dist/client.js +3 -3
  28. package/dist/db/better-sqlite.js +4 -4
  29. package/dist/db/bun-sqlite.js +4 -4
  30. package/dist/db/d1.js +4 -4
  31. package/dist/db/index.js +8 -8
  32. package/dist/db/postgres.js +4 -4
  33. package/dist/db/sqlite.js +4 -4
  34. package/dist/index.js +7 -7
  35. package/dist/runtimes/bun.js +6 -6
  36. package/dist/runtimes/cloudflare-workers.js +6 -6
  37. package/dist/runtimes/next.js +6 -6
  38. package/dist/runtimes/node.js +6 -6
  39. package/dist/schema/index.js +3 -3
  40. package/dist/server.js +6 -6
  41. package/dist/storage/index.js +1 -1
  42. package/package.json +4 -2
  43. package/dist/chunk-1qm0m8r8.js +0 -413
  44. package/dist/chunk-3j9zjfmn.js +0 -376
  45. package/dist/chunk-56n342hs.js +0 -95
  46. package/dist/chunk-5b8r0v8c.js +0 -47
  47. package/dist/chunk-63yg00vx.js +0 -263
  48. package/dist/chunk-7rr5p01g.js +0 -581
  49. package/dist/chunk-d0tb1xjw.js +0 -93
  50. package/dist/chunk-d7cgd6vn.js +0 -318
  51. package/dist/chunk-ec4jhybj.js +0 -1137
  52. package/dist/chunk-fatyf6f7.js +0 -221
  53. package/dist/chunk-gyaf5kgf.js +0 -10
  54. package/dist/chunk-h6dhexzr.js +0 -94
  55. package/dist/chunk-majsbncm.js +0 -98
  56. package/dist/chunk-mp2gt9yh.js +0 -237
  57. package/dist/chunk-r0ms5tk1.js +0 -76
  58. package/dist/chunk-rwqwsanx.js +0 -75
  59. package/dist/chunk-x7bnzswh.js +0 -174
@@ -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
- };
@@ -1,10 +0,0 @@
1
- import {
2
- generateDiffCode
3
- } from "./chunk-7rr5p01g.js";
4
- import"./chunk-ec4jhybj.js";
5
- import"./chunk-qxt9vge8.js";
6
- import"./chunk-6qs0g65f.js";
7
- import"./chunk-6bywt602.js";
8
- export {
9
- generateDiffCode
10
- };
@@ -1,94 +0,0 @@
1
- import"./chunk-6bywt602.js";
2
-
3
- // src/cli/core/mocks/d1-mock.ts
4
- import { Database } from "bun:sqlite";
5
- import fs from "node:fs";
6
- import path from "node:path";
7
- function createD1Mock(dbPath = ".opaca/local-d1.db") {
8
- const wranglerD1Dir = path.resolve(process.cwd(), ".wrangler/state/v3/d1/miniflare-D1DatabaseObject");
9
- if (fs.existsSync(wranglerD1Dir)) {
10
- const files = fs.readdirSync(wranglerD1Dir);
11
- const sqliteFile = files.find((f) => f.endsWith(".sqlite"));
12
- if (sqliteFile) {
13
- const wranglerPath = path.join(wranglerD1Dir, sqliteFile);
14
- try {
15
- const sqlite = new Database(wranglerPath);
16
- console.log(`[OpacaCMS] Using Wrangler D1 local state: ${sqliteFile}`);
17
- return wrapSqlite(sqlite);
18
- } catch (e) {
19
- console.warn(`[OpacaCMS] Failed to open Wrangler D1 state at ${wranglerPath}. Falling back...`);
20
- }
21
- }
22
- }
23
- let finalPath = dbPath;
24
- if (!finalPath) {
25
- finalPath = ":memory:";
26
- console.log("[OpacaCMS] Using in-memory D1 mock (no -c/--config provided)");
27
- }
28
- const absolutePath = finalPath === ":memory:" ? finalPath : path.isAbsolute(finalPath) ? finalPath : path.resolve(process.cwd(), finalPath);
29
- try {
30
- if (absolutePath !== ":memory:") {
31
- const dir = path.dirname(absolutePath);
32
- if (!fs.existsSync(dir)) {
33
- fs.mkdirSync(dir, { recursive: true });
34
- }
35
- }
36
- const sqlite = new Database(absolutePath);
37
- if (absolutePath !== ":memory:") {
38
- console.log(`[OpacaCMS] Using local CLI database: ${absolutePath}`);
39
- }
40
- return wrapSqlite(sqlite);
41
- } catch (err) {
42
- console.warn(`[OpacaCMS] Warning: Could not open database at ${absolutePath}. Using memory database.`);
43
- return wrapSqlite(new Database(":memory:"));
44
- }
45
- }
46
- function wrapSqlite(sqlite) {
47
- return {
48
- prepare(query) {
49
- const stmt = sqlite.prepare(query);
50
- const bridge = {
51
- bind(...params) {
52
- bridge._params = params;
53
- return bridge;
54
- },
55
- async first() {
56
- const params = bridge._params || [];
57
- return stmt.get(...params);
58
- },
59
- async all() {
60
- const params = bridge._params || [];
61
- const results = stmt.all(...params);
62
- return { results, success: true, meta: {} };
63
- },
64
- async run() {
65
- const params = bridge._params || [];
66
- const result = stmt.run(...params);
67
- return {
68
- success: true,
69
- meta: { changes: result.changes, last_row_id: result.lastInsertRowid }
70
- };
71
- },
72
- async raw() {
73
- const params = bridge._params || [];
74
- return stmt.all(...params);
75
- }
76
- };
77
- return bridge;
78
- },
79
- async batch(statements) {
80
- const results = [];
81
- for (const stmt of statements) {
82
- results.push(await stmt.all());
83
- }
84
- return results;
85
- },
86
- async exec(query) {
87
- sqlite.exec(query);
88
- return { count: 0, duration: 0 };
89
- }
90
- };
91
- }
92
- export {
93
- createD1Mock
94
- };
@@ -1,98 +0,0 @@
1
- import {
2
- defineCommand,
3
- runMain
4
- } from "./chunk-1qm0m8r8.js";
5
- import {
6
- __require
7
- } from "./chunk-6bywt602.js";
8
-
9
- // src/cli/index.ts
10
- import fs from "node:fs";
11
- import { resolve } from "node:path";
12
- import { pathToFileURL } from "node:url";
13
- async function loadConfig(configPath) {
14
- if (!fs.existsSync(configPath)) {
15
- throw new Error(`Config file not found at ${configPath}`);
16
- }
17
- const configUrl = pathToFileURL(configPath).href;
18
- const mod = await import(configUrl);
19
- if (!mod.default) {
20
- throw new Error(`The configuration file at ${configPath} must have a 'default' export.`);
21
- }
22
- const namedExports = Object.keys(mod).filter((k) => k !== "default" && k !== "__esModule");
23
- if (namedExports.length > 0) {
24
- throw new Error(`Named exports are not allowed in the configuration file. Found: ${namedExports.join(", ")}.`);
25
- }
26
- let opaca = mod.default;
27
- if (typeof opaca === "function") {
28
- const { createD1Mock } = await import("./chunk-h6dhexzr.js");
29
- const { createR2Mock } = await import("./chunk-x7bnzswh.js");
30
- const mockDb = createD1Mock();
31
- const mockBucket = createR2Mock();
32
- const mockSecureBucket = createR2Mock();
33
- opaca = await opaca({
34
- DB: mockDb,
35
- BUCKET: mockBucket,
36
- SECURE_BUCKET: mockSecureBucket,
37
- OPACA_SECRET: "cli-secret"
38
- }, { url: "http://localhost:3000" });
39
- }
40
- if (opaca?.fetch) {
41
- throw new Error("Default export is a Hono application. The CLI requires the configuration object.");
42
- }
43
- if (!opaca.db) {
44
- throw new Error("No database adapter found in config");
45
- }
46
- return opaca;
47
- }
48
- function resolveConfigPath(explicitPath) {
49
- let configPath = explicitPath ? resolve(process.cwd(), explicitPath) : "";
50
- if (!configPath) {
51
- const defaults = [
52
- "opaca.config.ts",
53
- "opaca.config.js",
54
- "opacacms.config.ts",
55
- "opacacms.config.js",
56
- "src/opaca.config.ts",
57
- "src/opacacms.config.js"
58
- ];
59
- for (const d of defaults) {
60
- if (fs.existsSync(resolve(process.cwd(), d))) {
61
- configPath = resolve(process.cwd(), d);
62
- break;
63
- }
64
- }
65
- }
66
- if (!configPath || !fs.existsSync(configPath)) {
67
- throw new Error("Config file not found. Use -c or --config to specify path.");
68
- }
69
- return configPath;
70
- }
71
- var mainCommand = defineCommand({
72
- meta: {
73
- name: "opacacms",
74
- version: "0.1.0",
75
- description: "OpacaCMS CLI - The Headless CMS that doesn't get in your way."
76
- },
77
- args: {
78
- config: {
79
- type: "string",
80
- alias: "c",
81
- description: "Path to the OpacaCMS configuration file"
82
- }
83
- },
84
- subCommands: {
85
- init: () => import("./chunk-fatyf6f7.js").then((m) => m.default),
86
- migrate: () => import("./chunk-d7cgd6vn.js").then((m) => m.default),
87
- seed: () => import("./chunk-d0tb1xjw.js").then((m) => m.default),
88
- generate: () => import("./chunk-mp2gt9yh.js").then((m) => m.default),
89
- plugin: () => import("./chunk-63yg00vx.js").then((m) => m.default),
90
- doctor: () => import("./chunk-56n342hs.js").then((m) => m.default),
91
- dev: () => import("./chunk-r0ms5tk1.js").then((m) => m.default)
92
- }
93
- });
94
- if (__require.main == __require.module) {
95
- runMain(mainCommand);
96
- }
97
-
98
- export { loadConfig, resolveConfigPath };
@@ -1,237 +0,0 @@
1
- import {
2
- require_picocolors
3
- } from "./chunk-rwqwsanx.js";
4
- import {
5
- Ct,
6
- Nt,
7
- R,
8
- Vt,
9
- Zt
10
- } from "./chunk-ec4jhybj.js";
11
- import {
12
- defineCommand
13
- } from "./chunk-1qm0m8r8.js";
14
- import {
15
- __toESM
16
- } from "./chunk-6bywt602.js";
17
-
18
- // src/cli/commands/generate.ts
19
- import fs2 from "node:fs";
20
- import { resolve as resolve2 } from "node:path";
21
- var import_picocolors = __toESM(require_picocolors(), 1);
22
-
23
- // src/cli/core/types/generate-types.ts
24
- import fs from "node:fs";
25
- import { resolve } from "node:path";
26
- async function generateTypesCommand(url, token, out) {
27
- console.log(`[OpacaCMS] Fetching metadata from ${url}/api/__admin/metadata...`);
28
- let data;
29
- try {
30
- const res = await fetch(`${url.replace(/\/$/, "")}/api/__admin/metadata`, {
31
- headers: {
32
- Authorization: `Bearer ${token}`
33
- }
34
- });
35
- if (!res.ok) {
36
- if (res.status === 401 || res.status === 403) {
37
- throw new Error("Authentication failed. Ensure your API Key is correct and has the necessary permissions.");
38
- }
39
- const errorText = await res.text().catch(() => "Unknown error");
40
- throw new Error(`Server responded with ${res.status}: ${errorText}`);
41
- }
42
- data = await res.json();
43
- } catch (err) {
44
- console.error(`[OpacaCMS] Failed to fetch metadata: ${err.message}`);
45
- process.exit(1);
46
- }
47
- console.log(`[OpacaCMS] Successfully fetched metadata for ${data.collections.length} collections and ${data.globals?.length || 0} globals.`);
48
- let dtsContent = `// Automatically generated by OpacaCMS CLI
49
- // Do not edit this file manually
50
-
51
- export interface OpacaAsset {
52
- assetId: string;
53
- url: string;
54
- filename: string;
55
- mime_type: string;
56
- filesize: number;
57
- meta?: Record<string, any>;
58
- }
59
-
60
- export interface OpacaCollections {
61
- collections: {
62
- `;
63
- for (const collection of data.collections) {
64
- dtsContent += ` "${collection.slug}": {
65
- `;
66
- dtsContent += ` id: string | number;
67
- `;
68
- for (const field of collection.fields) {
69
- const typeStr = mapFieldToTsType(field.type);
70
- const isOptional = field.required ? "" : "?";
71
- dtsContent += ` ${field.name}${isOptional}: ${typeStr};
72
- `;
73
- }
74
- if (collection.timestamps) {
75
- dtsContent += ` createdAt: string;
76
- `;
77
- dtsContent += ` updatedAt: string;
78
- `;
79
- }
80
- dtsContent += ` };
81
- `;
82
- }
83
- dtsContent += ` };
84
- `;
85
- if (data.globals && data.globals.length > 0) {
86
- dtsContent += ` globals: {
87
- `;
88
- for (const globalConf of data.globals) {
89
- dtsContent += ` "${globalConf.slug}": {
90
- `;
91
- for (const field of globalConf.fields) {
92
- const typeStr = mapFieldToTsType(field.type);
93
- const isOptional = field.required ? "" : "?";
94
- dtsContent += ` ${field.name}${isOptional}: ${typeStr};
95
- `;
96
- }
97
- dtsContent += ` };
98
- `;
99
- }
100
- dtsContent += ` };
101
- `;
102
- } else {
103
- dtsContent += ` globals: Record<string, any>;
104
- `;
105
- }
106
- dtsContent += `}
107
- `;
108
- const outputPath = resolve(process.cwd(), out || "opaca.d.ts");
109
- fs.writeFileSync(outputPath, dtsContent);
110
- console.log(`[OpacaCMS] Types successfully generated at ${outputPath}`);
111
- }
112
- function mapFieldToTsType(type) {
113
- switch (type) {
114
- case "text":
115
- case "textarea":
116
- case "richtext":
117
- case "select":
118
- case "date":
119
- return "string";
120
- case "number":
121
- return "number";
122
- case "boolean":
123
- return "boolean";
124
- case "json":
125
- return "any | any[]";
126
- case "file":
127
- return "OpacaAsset";
128
- case "relationship":
129
- return "string | number | any";
130
- default:
131
- return "any";
132
- }
133
- }
134
-
135
- // src/cli/commands/generate.ts
136
- var generate_default = defineCommand({
137
- meta: {
138
- name: "generate",
139
- description: "Generate boilerplates (collections/globals) or TypeScript definitions"
140
- },
141
- args: {
142
- type: {
143
- type: "positional",
144
- description: "What to generate: 'types', 'collection', or 'global'",
145
- required: true
146
- },
147
- name: {
148
- type: "positional",
149
- description: "The name of the collection or global to generate (if applicable)",
150
- required: false
151
- },
152
- url: {
153
- type: "string",
154
- description: "The URL of the OpacaCMS instance (for 'types')"
155
- },
156
- token: {
157
- type: "string",
158
- description: "The API Key to use for fetching metadata (for 'types')"
159
- },
160
- out: {
161
- type: "string",
162
- alias: "o",
163
- description: "The output file path (for 'types')"
164
- }
165
- },
166
- async run({ args }) {
167
- if (args.type === "types") {
168
- if (!args.url || !args.token) {
169
- R.error(import_picocolors.default.red("URL and Token are required to generate types from a remote instance."));
170
- R.info("Usage: opacacms generate types --url <url> --token <token> [--out <file>]");
171
- process.exit(1);
172
- }
173
- await generateTypesCommand(args.url, args.token, args.out || "opaca.d.ts");
174
- return;
175
- }
176
- if (args.type === "collection" || args.type === "global") {
177
- let name = args.name;
178
- if (!name) {
179
- const response = await Zt({
180
- message: `What should we name your ${args.type}? (e.g. ${args.type === "collection" ? "posts" : "site-settings"})`
181
- });
182
- if (Ct(response)) {
183
- Nt("Operation cancelled.");
184
- process.exit(0);
185
- }
186
- name = response;
187
- }
188
- const isCollection = args.type === "collection";
189
- const folderName = isCollection ? "collections" : "globals";
190
- const fileName = `${name}.ts`;
191
- const filePath = resolve2(process.cwd(), folderName, fileName);
192
- if (fs2.existsSync(filePath)) {
193
- R.error(import_picocolors.default.red(`File already exists at ${folderName}/${fileName}`));
194
- process.exit(1);
195
- }
196
- fs2.mkdirSync(resolve2(process.cwd(), folderName), { recursive: true });
197
- const template = isCollection ? `import { z, defineCollection } from 'opacacms/schema';
198
-
199
- export const ${name} = defineCollection({
200
- slug: '${name}',
201
- label: '${name.charAt(0).toUpperCase() + name.slice(1)}',
202
- admin: {
203
- useAsTitle: 'title',
204
- icon: 'FileText'
205
- },
206
- schema: z.object({
207
- id: z.text().default(() => crypto.randomUUID()),
208
- title: z.text({ label: 'Title' }).required(),
209
- content: z.richText({ label: 'Content' }),
210
- })
211
- });
212
- ` : `import { z, defineGlobal } from 'opacacms/schema';
213
-
214
- export const ${name} = defineGlobal({
215
- slug: '${name}',
216
- label: '${name.charAt(0).toUpperCase() + name.slice(1)}',
217
- admin: {
218
- icon: 'Settings'
219
- },
220
- schema: z.object({
221
- siteName: z.text({ label: 'Site Name' }).required(),
222
- description: z.textarea({ label: 'Description' }),
223
- })
224
- });
225
- `;
226
- fs2.writeFileSync(filePath, template);
227
- R.success(import_picocolors.default.green(`Successfully generated ${args.type} at ./${folderName}/${fileName}`));
228
- Vt(`Don't forget to import it into your opacacms.config.ts and add it to the '${folderName}' array!`, "Reminder");
229
- return;
230
- }
231
- R.error(import_picocolors.default.red(`Unknown generation type: ${args.type}. Use 'types', 'collection', or 'global'.`));
232
- process.exit(1);
233
- }
234
- });
235
- export {
236
- generate_default as default
237
- };