opacacms 0.1.20 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. package/README.md +638 -732
  2. package/dist/admin/auth-client.d.ts +39 -39
  3. package/dist/admin/index.d.ts +1 -0
  4. package/dist/admin/index.js +2397 -1405
  5. package/dist/admin/react.d.ts +1 -1
  6. package/dist/admin/react.js +8 -0
  7. package/dist/admin/router.d.ts +1 -0
  8. package/dist/admin/stores/ui.d.ts +10 -0
  9. package/dist/admin/ui/admin-layout.d.ts +4 -4
  10. package/dist/admin/ui/components/DataDetailView.d.ts +1 -1
  11. package/dist/admin/ui/components/DetailSheet.d.ts +19 -0
  12. package/dist/admin/ui/components/PluginSettingsForm.d.ts +11 -0
  13. package/dist/admin/ui/components/fields/BooleanField.d.ts +2 -1
  14. package/dist/admin/ui/components/fields/DateField.d.ts +1 -1
  15. package/dist/admin/ui/components/fields/FieldLabel.d.ts +11 -0
  16. package/dist/admin/ui/components/fields/FileField.d.ts +1 -1
  17. package/dist/admin/ui/components/fields/NumberField.d.ts +1 -1
  18. package/dist/admin/ui/components/fields/RadioField.d.ts +1 -1
  19. package/dist/admin/ui/components/fields/RelationshipField.d.ts +3 -1
  20. package/dist/admin/ui/components/fields/SelectField.d.ts +1 -1
  21. package/dist/admin/ui/components/fields/TextAreaField.d.ts +1 -1
  22. package/dist/admin/ui/components/fields/TextField.d.ts +1 -1
  23. package/dist/admin/ui/components/fields/VirtualField.d.ts +1 -0
  24. package/dist/admin/ui/components/fields/index.d.ts +16 -16
  25. package/dist/admin/ui/components/fields/richtext-editor/index.d.ts +1 -1
  26. package/dist/admin/ui/components/media/AssetManagerModal.d.ts +1 -1
  27. package/dist/admin/ui/components/toast.d.ts +1 -1
  28. package/dist/admin/ui/components/ui/accordion.d.ts +1 -1
  29. package/dist/admin/ui/components/ui/button.d.ts +1 -1
  30. package/dist/admin/ui/components/ui/collapsible.d.ts +1 -1
  31. package/dist/admin/ui/components/ui/dialog.d.ts +1 -1
  32. package/dist/admin/ui/components/ui/group.d.ts +1 -1
  33. package/dist/admin/ui/components/ui/index.d.ts +17 -17
  34. package/dist/admin/ui/components/ui/input.d.ts +1 -1
  35. package/dist/admin/ui/components/ui/label.d.ts +1 -1
  36. package/dist/admin/ui/components/ui/radio-group.d.ts +1 -1
  37. package/dist/admin/ui/components/ui/relationship.d.ts +4 -4
  38. package/dist/admin/ui/components/ui/select.d.ts +1 -1
  39. package/dist/admin/ui/components/ui/sheet.d.ts +1 -1
  40. package/dist/admin/ui/components/ui/tabs.d.ts +1 -1
  41. package/dist/admin/ui/components/versions-sheet.d.ts +11 -0
  42. package/dist/admin/ui/views/media-registry-view.d.ts +1 -1
  43. package/dist/admin/ui/views/settings-view.d.ts +2 -2
  44. package/dist/admin/vue.d.ts +17 -0
  45. package/dist/admin/vue.js +8 -0
  46. package/dist/admin/webcomponent.js +2 -2
  47. package/dist/admin.css +1 -1
  48. package/dist/auth/index.d.ts +101 -41
  49. package/dist/{chunk-qkn1ykrj.js → chunk-0bq155dy.js} +94 -31
  50. package/dist/{chunk-2z8wxx9g.js → chunk-0gtxnxmd.js} +98 -25
  51. package/dist/{chunk-v521d72w.js → chunk-3rdhbedb.js} +1 -1
  52. package/dist/chunk-51z3x7kq.js +20 -0
  53. package/dist/{chunk-7fyepksb.js → chunk-526a3gqx.js} +1 -1
  54. package/dist/{chunk-wmvjvn7b.js → chunk-6qq3ne6b.js} +39 -1
  55. package/dist/{chunk-0am1m47g.js → chunk-6v1fw7q7.js} +5 -5
  56. package/dist/{chunk-zvwb67nd.js → chunk-7y1nbmw6.js} +36 -5
  57. package/dist/chunk-8scgdznr.js +44 -0
  58. package/dist/{chunk-erh6x75p.js → chunk-b3kr8w41.js} +58 -7
  59. package/dist/chunk-bexcv7xe.js +36 -0
  60. package/dist/{chunk-16vgcf3k.js → chunk-byq8g0rd.js} +1 -1
  61. package/dist/{chunk-wq314kkx.js → chunk-d1asgtke.js} +94 -31
  62. package/dist/{chunk-xtwc125q.js → chunk-dykn5hr6.js} +8 -8
  63. package/dist/{chunk-pxh5encs.js → chunk-esrg9qj0.js} +102 -44
  64. package/dist/chunk-fj19qccp.js +78 -0
  65. package/dist/{chunk-x2ejaftz.js → chunk-gmee4mdc.js} +98 -27
  66. package/dist/{chunk-xa7rjsn2.js → chunk-j53pz21t.js} +2 -2
  67. package/dist/{chunk-9y3m1xkx.js → chunk-kc4jfnv7.js} +480 -85
  68. package/dist/chunk-mkn49zmy.js +102 -0
  69. package/dist/{chunk-n1xraw7j.js → chunk-qb6ztvw9.js} +1 -1
  70. package/dist/{chunk-2kyhqvhc.js → chunk-qxt9vge8.js} +1 -1
  71. package/dist/chunk-r39em4yj.js +29 -0
  72. package/dist/chunk-rqyjjqgy.js +91 -0
  73. package/dist/chunk-rsf0tpy1.js +8 -0
  74. package/dist/chunk-swtcpvhf.js +2442 -0
  75. package/dist/chunk-t0zg026p.js +71 -0
  76. package/dist/chunk-twpvxfce.js +64 -0
  77. package/dist/{chunk-ybbbqj63.js → chunk-v9z61v3g.js} +15 -0
  78. package/dist/{chunk-jwjk85ze.js → chunk-ywm4t2gm.js} +6 -2
  79. package/dist/cli/commands/plugin-build.d.ts +1 -0
  80. package/dist/cli/commands/plugin-init.d.ts +1 -0
  81. package/dist/cli/commands/plugin-sync.d.ts +1 -0
  82. package/dist/cli/index.js +24 -6
  83. package/dist/config-utils.d.ts +1 -1
  84. package/dist/config.d.ts +21 -4
  85. package/dist/db/better-sqlite.d.ts +1 -1
  86. package/dist/db/better-sqlite.js +5 -5
  87. package/dist/db/bun-sqlite.d.ts +1 -1
  88. package/dist/db/bun-sqlite.js +5 -5
  89. package/dist/db/d1.d.ts +1 -1
  90. package/dist/db/d1.js +5 -5
  91. package/dist/db/index.js +9 -9
  92. package/dist/db/postgres.d.ts +1 -1
  93. package/dist/db/postgres.js +5 -5
  94. package/dist/db/sqlite.d.ts +1 -1
  95. package/dist/db/sqlite.js +5 -5
  96. package/dist/index.js +4 -3
  97. package/dist/plugins/index.d.ts +1 -0
  98. package/dist/plugins/ui-bridge.d.ts +12 -0
  99. package/dist/plugins/utils.d.ts +5 -0
  100. package/dist/runtimes/bun.js +13 -7
  101. package/dist/runtimes/cloudflare-workers.js +5 -5
  102. package/dist/runtimes/next.js +5 -5
  103. package/dist/runtimes/node.js +13 -7
  104. package/dist/schema/collection.d.ts +9 -30
  105. package/dist/schema/fields/base.d.ts +3 -2
  106. package/dist/schema/fields/index.d.ts +12 -0
  107. package/dist/schema/fields/validation.test.d.ts +1 -0
  108. package/dist/schema/global.d.ts +10 -15
  109. package/dist/schema/index.js +22 -14
  110. package/dist/server/admin-router.d.ts +2 -2
  111. package/dist/server/admin.d.ts +2 -1
  112. package/dist/server/collection-router.d.ts +1 -1
  113. package/dist/server/handlers.d.ts +10 -0
  114. package/dist/server/middlewares/admin.d.ts +2 -2
  115. package/dist/server/middlewares/auth.d.ts +1 -1
  116. package/dist/server/middlewares/context.d.ts +2 -0
  117. package/dist/server/middlewares/rate-limit.d.ts +1 -1
  118. package/dist/server/openapi.d.ts +2 -0
  119. package/dist/server/plugins-loader.d.ts +6 -0
  120. package/dist/server/router.d.ts +3 -3
  121. package/dist/server/routers/admin.d.ts +2 -2
  122. package/dist/server/routers/auth.d.ts +1 -1
  123. package/dist/server/routers/collections.d.ts +1 -1
  124. package/dist/server/routers/plugins.d.ts +18 -0
  125. package/dist/server/setup-middlewares.d.ts +2 -2
  126. package/dist/server/system-router.d.ts +1 -1
  127. package/dist/server.js +11 -7
  128. package/dist/storage/adapters/local.d.ts +1 -1
  129. package/dist/storage/adapters/s3.d.ts +1 -1
  130. package/dist/types.d.ts +227 -12
  131. package/dist/utils/logger.d.ts +13 -35
  132. package/dist/validation.d.ts +60 -8
  133. package/dist/validator.d.ts +1 -1
  134. package/package.json +21 -7
  135. package/dist/admin/ui/components/DataDetailSheet.d.ts +0 -13
  136. package/dist/admin/ui/components/ui/relationship-detail-sheet.d.ts +0 -9
  137. package/dist/chunk-62ev8gnc.js +0 -41
  138. package/dist/chunk-j4d50hrx.js +0 -20
  139. package/dist/chunk-nb7ctdg8.js +0 -311
package/dist/types.d.ts CHANGED
@@ -1,8 +1,16 @@
1
- import type { Session, User } from "better-auth";
1
+ import type { z } from "zod";
2
+ import type { Session as BetterAuthSession, User as BetterAuthUser, Prettify } from "better-auth";
2
3
  import type { Context } from "hono";
3
4
  import type { icons } from "lucide-react";
4
- import type { AdminConfig, CollectionHooks, FieldType, AccessConfig as ValidationAccessConfig, Collection as ValidationCollection, Global as ValidationGlobal, OpacaConfig as ValidationOpacaConfig } from "./validation";
5
+ import type { AdminConfig, CollectionHooks, FieldType, AccessConfig as ValidationAccessConfig } from "./validation";
5
6
  export type { FieldType };
7
+ export type Session = BetterAuthSession;
8
+ export type User = Prettify<BetterAuthUser & {
9
+ role?: string;
10
+ banned?: boolean;
11
+ banReason?: string | null;
12
+ bannedUntil?: Date | null;
13
+ }>;
6
14
  export type IconName = keyof typeof icons;
7
15
  export interface BaseField {
8
16
  name: string;
@@ -12,7 +20,7 @@ export interface BaseField {
12
20
  unique?: boolean;
13
21
  localized?: boolean;
14
22
  defaultValue?: unknown;
15
- validate?: (value: unknown) => boolean | string;
23
+ validate?: ((value: unknown) => boolean | string) | z.ZodTypeAny;
16
24
  access?: FieldAccessConfig;
17
25
  admin?: {
18
26
  description?: string;
@@ -26,6 +34,7 @@ export interface BaseField {
26
34
  Field?: string;
27
35
  Cell?: string;
28
36
  };
37
+ customProps?: Record<string, unknown>;
29
38
  };
30
39
  references?: {
31
40
  table: string;
@@ -167,7 +176,10 @@ export interface VirtualField extends BaseField {
167
176
  }) => any | Promise<any>;
168
177
  returnType?: "string" | "number" | "boolean" | "json";
169
178
  }
170
- export type Field = TextField | SlugField | TextAreaField | NumberField | RichTextField | RelationshipField | SelectField | VirtualField | RadioField | DateField | BooleanField | JSONField | FileField | BlocksField | GroupField | RowField | CollapsibleField | TabsField | JoinField | ArrayField;
179
+ export interface UIField extends BaseField {
180
+ type: "ui";
181
+ }
182
+ export type Field = TextField | SlugField | TextAreaField | NumberField | RichTextField | RelationshipField | SelectField | VirtualField | RadioField | DateField | BooleanField | JSONField | FileField | BlocksField | GroupField | RowField | CollapsibleField | TabsField | JoinField | ArrayField | UIField;
171
183
  export interface ApiKey {
172
184
  id: string;
173
185
  name: string | null;
@@ -197,27 +209,45 @@ export interface AccessConfig extends Omit<ValidationAccessConfig, "read" | "cre
197
209
  delete?: boolean | ((args: AccessArgs) => boolean | Promise<boolean>);
198
210
  }
199
211
  export type { CollectionHooks };
200
- export interface Collection extends Omit<ValidationCollection, "fields" | "hooks" | "access" | "admin" | "apiPath" | "versions" | "webhooks"> {
201
- fields: Field[];
212
+ export interface Collection {
213
+ slug: string;
214
+ label?: string;
215
+ icon?: IconName;
202
216
  apiPath?: string;
217
+ fields: Field[];
203
218
  hooks?: CollectionHooks;
204
219
  access?: AccessConfig;
205
- icon?: IconName;
206
220
  versions?: {
207
221
  drafts?: boolean;
208
222
  maxRevisions?: number;
209
223
  autosave?: boolean;
210
224
  };
225
+ timestamps?: boolean | {
226
+ createdAt?: string;
227
+ updatedAt?: string;
228
+ };
211
229
  webhooks?: {
212
230
  events: string[];
213
231
  url: string;
214
232
  headers?: Record<string, string>;
215
233
  }[];
234
+ auth?: boolean;
216
235
  admin?: {
217
- defaultColumns?: string[];
236
+ /**
237
+ * If true, the collection's title will be used as a breadcrumb.
238
+ */
218
239
  useAsTitle?: string;
240
+ /**
241
+ * If true, the collection will be hidden from the Admin UI sidebar but still accessible via direct URL.
242
+ */
219
243
  hidden?: boolean;
244
+ /**
245
+ * If true, the collection will be completely disabled from the Admin UI (hidden from sidebar and blocked via direct URL).
246
+ */
220
247
  disableAdmin?: boolean;
248
+ /**
249
+ * Predefined filtered views for the collection list.
250
+ */
221
251
  views?: {
222
252
  name: string;
223
253
  filter: Record<string, any>;
@@ -231,17 +261,121 @@ export interface Collection extends Omit<ValidationCollection, "fields" | "hooks
231
261
  }) => Promise<unknown>;
232
262
  }[];
233
263
  } | boolean;
264
+ hidden?: boolean;
234
265
  }
235
- export interface Global extends Omit<ValidationGlobal, "fields" | "access"> {
266
+ export interface Global {
267
+ slug: string;
236
268
  fields: Field[];
237
269
  access?: AccessConfig;
238
270
  label?: string;
239
271
  icon?: IconName;
272
+ timestamps?: boolean | {
273
+ createdAt?: string;
274
+ updatedAt?: string;
275
+ };
276
+ }
277
+ export interface OpacaPluginContext {
278
+ config: OpacaConfig;
279
+ logger: typeof import("./utils/logger").logger;
280
+ settings?: Record<string, any>;
240
281
  }
241
- export interface OpacaConfig<Resource extends string = string> extends Omit<ValidationOpacaConfig, "collections" | "globals" | "admin" | "api" | "access" | "trustedOrigins" | "auth" | "i18n"> {
282
+ export interface OpacaPlugin {
283
+ /**
284
+ * Unique name/slug for the plugin (e.g. 'stripe')
285
+ */
286
+ name: string;
287
+ /**
288
+ * User-friendly label for the plugin
289
+ */
290
+ label?: string;
291
+ /**
292
+ * Short description of what the plugin does
293
+ */
294
+ description?: string;
295
+ /**
296
+ * Plugin version (e.g. '1.0.0')
297
+ */
298
+ version?: string;
299
+ /**
300
+ * Plugin author
301
+ */
302
+ author?: string;
303
+ /**
304
+ * Link to plugin documentation or homepage
305
+ */
306
+ homepage?: string;
307
+ /**
308
+ * Lucide icon name for the plugin
309
+ */
310
+ icon?: IconName;
311
+ /**
312
+ * Callback fired during OpacaCMS initialization.
313
+ * Use this to extend the schema (collections, globals).
314
+ */
315
+ onInit?: (context: OpacaPluginContext) => OpacaConfig | void;
316
+ /**
317
+ * Callback fired when the Hono router is initialized.
318
+ * Use this to add custom API routes.
319
+ */
320
+ onRouterInit?: (app: import("hono").Hono<any, any, any>, context: OpacaPluginContext) => void;
321
+ /**
322
+ * Callback fired after all plugins have been initialized.
323
+ */
324
+ onInitComplete?: (context: OpacaPluginContext) => void | Promise<void>;
325
+ /**
326
+ * Hook called on every CMS API request.
327
+ * Return false to block the request.
328
+ */
329
+ onRequest?: (c: import("hono").Context) => void | false | Promise<void | false>;
330
+ /**
331
+ * Hook for static site generation (SSG) output.
332
+ */
333
+ onExport?: (args: {
334
+ pages: any[];
335
+ outputDir: string;
336
+ }) => void | Promise<void | {
337
+ path: string;
338
+ content: string;
339
+ }[]>;
340
+ /**
341
+ * Callback fired when the CMS is shutting down.
342
+ */
343
+ onDestroy?: () => void | Promise<void>;
344
+ /**
345
+ * Defines UI assets (scripts, styles) to be loaded by the Admin UI.
346
+ */
347
+ adminAssets?: () => {
348
+ styles?: string[];
349
+ scripts?: string[];
350
+ };
351
+ /**
352
+ * Defines a configuration schema for the plugin.
353
+ * This will be used to generate a settings form in the Admin UI.
354
+ */
355
+ configSchema?: Field[];
356
+ /**
357
+ * Defines the administrative UI for the plugin.
358
+ * This can point to local files during development or contain inlined source for production.
359
+ */
360
+ adminUI?: {
361
+ /** The name of the custom element/component to render */
362
+ component?: string;
363
+ /** Absolute path to the source file (.tsx) - Used in dev/Node/Bun */
364
+ filePath?: string;
365
+ /** The inlined transpiled source code - Used in Workers/Production */
366
+ source?: string;
367
+ };
368
+ /** Runtime settings for the plugin */
369
+ settings?: Record<string, any>;
370
+ }
371
+ export interface OpacaConfig<Resource extends string = string> {
372
+ appName?: string;
373
+ serverURL?: string;
374
+ secret?: string;
375
+ db: DatabaseAdapter;
376
+ logger?: OpacaLoggerConfig;
242
377
  collections: Collection[];
243
378
  globals?: Global[];
244
- db: DatabaseAdapter;
245
379
  admin?: AdminConfig;
246
380
  api?: ApiConfig;
247
381
  access?: OpacaAccessConfig<Resource>;
@@ -251,6 +385,14 @@ export interface OpacaConfig<Resource extends string = string> extends Omit<Vali
251
385
  locales: string[];
252
386
  defaultLocale: string;
253
387
  };
388
+ storages?: Record<string, any>;
389
+ runMigrationsOnStartup?: boolean;
390
+ plugins?: OpacaPlugin[];
391
+ }
392
+ export interface OpacaLoggerConfig {
393
+ disabled?: boolean;
394
+ disableColors?: boolean;
395
+ level?: "debug" | "info" | "warn" | "error";
254
396
  }
255
397
  export interface OpacaAuthConfig {
256
398
  /**
@@ -319,6 +461,15 @@ export interface ApiConfig {
319
461
  provider?: (c: Context) => any;
320
462
  keyGenerator?: (c: Context) => string | Promise<string>;
321
463
  };
464
+ openAPI?: {
465
+ enabled?: boolean;
466
+ path?: string;
467
+ theme?: "alternate" | "default" | "moon" | "purple" | "solarized" | "bluePlanet" | "saturn" | "kepler" | "mars" | "deepSpace" | "none" | string;
468
+ layout?: "modern" | "classic" | string;
469
+ hideModels?: boolean;
470
+ hideDownloadButton?: boolean;
471
+ customCss?: string;
472
+ };
322
473
  }
323
474
  export type { AdminConfig };
324
475
  export interface FindOptions {
@@ -430,9 +581,21 @@ export interface SerializableCollection {
430
581
  auth?: boolean;
431
582
  admin?: {
432
583
  defaultColumns?: string[];
584
+ /**
585
+ * If true, the collection's title will be used as a breadcrumb.
586
+ */
433
587
  useAsTitle?: string;
588
+ /**
589
+ * If true, the collection will be hidden from the Admin UI sidebar but still accessible via direct URL.
590
+ */
434
591
  hidden?: boolean;
592
+ /**
593
+ * If true, the collection will be completely disabled from the Admin UI (hidden from sidebar and blocked via direct URL).
594
+ */
435
595
  disableAdmin?: boolean;
596
+ /**
597
+ * Predefined filtered views for the collection list.
598
+ */
436
599
  views?: {
437
600
  name: string;
438
601
  filter: Record<string, any>;
@@ -480,5 +643,57 @@ export interface SerializableConfig {
480
643
  }[];
481
644
  }[];
482
645
  needsInit?: boolean;
483
- storages?: Record<string, unknown>;
646
+ storages: Record<string, unknown>;
647
+ plugins?: {
648
+ /**
649
+ * Name of the plugin.
650
+ */
651
+ name: string;
652
+ /**
653
+ * Label to be used in the admin UI.
654
+ */
655
+ label?: string;
656
+ /**
657
+ * Description of the plugin.
658
+ */
659
+ description?: string;
660
+ /**
661
+ * Version of the plugin.
662
+ */
663
+ version?: string;
664
+ /**
665
+ * Author of the plugin.
666
+ */
667
+ author?: string;
668
+ /**
669
+ * Homepage of the plugin.
670
+ */
671
+ homepage?: string;
672
+ /**
673
+ * Icon to be used in the admin UI.
674
+ */
675
+ icon?: IconName;
676
+ /**
677
+ * Assets to be loaded in the admin UI.
678
+ */
679
+ adminAssets?: {
680
+ styles?: string[];
681
+ scripts?: string[];
682
+ };
683
+ /**
684
+ * Admin UI configuration.
685
+ */
686
+ adminUI?: {
687
+ /**
688
+ * The name of the custom element to register.
689
+ */
690
+ component?: string;
691
+ /**
692
+ * The inlined transpiled source code - Used in Workers/Production
693
+ */
694
+ source?: string;
695
+ };
696
+ settings?: Record<string, any>;
697
+ configSchema?: SerializableCollection["fields"];
698
+ }[];
484
699
  }
@@ -1,35 +1,13 @@
1
- /**
2
- * Core Logger Utility for OpacaCMS.
3
- * Standardizes console output across the package with ANSI colors and standard prefixes.
4
- */
5
- export declare const logger: {
6
- /**
7
- * General information logging.
8
- * Useful for successful operations, initialization steps, etc.
9
- */
10
- info: (message: string, ...args: any[]) => void;
11
- /**
12
- * Action logging. Usually highlighted in green.
13
- * e.g., "Created table users", "Connected to DB"
14
- */
15
- success: (message: string, ...args: any[]) => void;
16
- /**
17
- * Dim/Debug logging.
18
- * e.g., "Starting schema push...", "Syncing database..."
19
- */
20
- debug: (message: string, ...args: any[]) => void;
21
- /**
22
- * Warning logging.
23
- * For non-fatal errors or deprecated warnings.
24
- */
25
- warn: (message: string, ...args: any[]) => void;
26
- /**
27
- * Error logging.
28
- * For fatal errors, exceptions, and validation failures.
29
- */
30
- error: (message: string, ...args: any[]) => void;
31
- /**
32
- * Raw formatting function if manual concatenation is needed.
33
- */
34
- format: (color: "green" | "red" | "yellow" | "gray", msg: string) => string;
35
- };
1
+ import type { OpacaLoggerConfig } from "../types";
2
+ export declare class OpacaLogger {
3
+ private config;
4
+ constructor(config?: OpacaLoggerConfig);
5
+ private shouldLog;
6
+ info(message: string, ...args: any[]): void;
7
+ success(message: string, ...args: any[]): void;
8
+ debug(message: string, ...args: any[]): void;
9
+ warn(message: string, ...args: any[]): void;
10
+ error(message: string, ...args: any[]): void;
11
+ format(color: "green" | "red" | "yellow" | "gray", msg: string): string;
12
+ }
13
+ export declare const logger: OpacaLogger;
@@ -20,6 +20,7 @@ export declare const FieldTypeSchema: z.ZodEnum<{
20
20
  tabs: "tabs";
21
21
  array: "array";
22
22
  virtual: "virtual";
23
+ ui: "ui";
23
24
  }>;
24
25
  export type FieldType = z.infer<typeof FieldTypeSchema>;
25
26
  export declare const FieldSchema: z.ZodType<unknown>;
@@ -47,10 +48,13 @@ export declare const CollectionSchema: z.ZodObject<{
47
48
  icon: z.ZodOptional<z.ZodString>;
48
49
  apiPath: z.ZodOptional<z.ZodString>;
49
50
  fields: z.ZodArray<z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>;
50
- timestamps: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodObject<{
51
+ timestamps: z.ZodPipe<z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodObject<{
51
52
  createdAt: z.ZodOptional<z.ZodString>;
52
53
  updatedAt: z.ZodOptional<z.ZodString>;
53
- }, z.core.$strip>]>>;
54
+ }, z.core.$strip>]>>, z.ZodTransform<boolean, boolean | {
55
+ createdAt?: string | undefined;
56
+ updatedAt?: string | undefined;
57
+ } | undefined>>;
54
58
  auth: z.ZodOptional<z.ZodBoolean>;
55
59
  hooks: z.ZodOptional<z.ZodObject<{
56
60
  beforeCreate: z.ZodOptional<z.ZodFunction<z.core.$ZodFunctionArgs, z.core.$ZodFunctionOut>>;
@@ -100,10 +104,13 @@ export declare const GlobalSchema: z.ZodObject<{
100
104
  label: z.ZodOptional<z.ZodString>;
101
105
  icon: z.ZodOptional<z.ZodString>;
102
106
  fields: z.ZodArray<z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>;
103
- timestamps: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodObject<{
107
+ timestamps: z.ZodPipe<z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodObject<{
104
108
  createdAt: z.ZodOptional<z.ZodString>;
105
109
  updatedAt: z.ZodOptional<z.ZodString>;
106
- }, z.core.$strip>]>>;
110
+ }, z.core.$strip>]>>, z.ZodTransform<boolean, boolean | {
111
+ createdAt?: string | undefined;
112
+ updatedAt?: string | undefined;
113
+ } | undefined>>;
107
114
  access: z.ZodOptional<z.ZodObject<{
108
115
  read: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodFunction<z.core.$ZodFunctionArgs, z.core.$ZodFunctionOut>]>>;
109
116
  create: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodFunction<z.core.$ZodFunctionArgs, z.core.$ZodFunctionOut>]>>;
@@ -150,6 +157,16 @@ export declare const OpacaAuthConfigSchema: z.ZodObject<{
150
157
  issuer: z.ZodString;
151
158
  }, z.core.$strip>>;
152
159
  }, z.core.$strip>>;
160
+ logger: z.ZodOptional<z.ZodObject<{
161
+ disabled: z.ZodOptional<z.ZodBoolean>;
162
+ disableColors: z.ZodOptional<z.ZodBoolean>;
163
+ level: z.ZodOptional<z.ZodEnum<{
164
+ error: "error";
165
+ debug: "debug";
166
+ info: "info";
167
+ warn: "warn";
168
+ }>>;
169
+ }, z.core.$strip>>;
153
170
  }, z.core.$strip>;
154
171
  export declare const ApiConfigSchema: z.ZodObject<{
155
172
  maxLimit: z.ZodOptional<z.ZodNumber>;
@@ -161,19 +178,32 @@ export declare const ApiConfigSchema: z.ZodObject<{
161
178
  provider: z.ZodOptional<z.ZodFunction<z.core.$ZodFunctionArgs, z.core.$ZodFunctionOut>>;
162
179
  keyGenerator: z.ZodOptional<z.ZodFunction<z.core.$ZodFunctionArgs, z.core.$ZodFunctionOut>>;
163
180
  }, z.core.$strip>>;
181
+ openAPI: z.ZodOptional<z.ZodObject<{
182
+ enabled: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
183
+ path: z.ZodDefault<z.ZodOptional<z.ZodString>>;
184
+ theme: z.ZodOptional<z.ZodString>;
185
+ layout: z.ZodOptional<z.ZodString>;
186
+ hideModels: z.ZodOptional<z.ZodBoolean>;
187
+ hideDownloadButton: z.ZodOptional<z.ZodBoolean>;
188
+ customCss: z.ZodOptional<z.ZodString>;
189
+ }, z.core.$strip>>;
164
190
  }, z.core.$strip>;
165
191
  export type ApiConfig = z.infer<typeof ApiConfigSchema>;
166
192
  export declare const OpacaConfigSchema: z.ZodObject<{
193
+ plugins: z.ZodOptional<z.ZodArray<z.ZodAny>>;
167
194
  collections: z.ZodArray<z.ZodObject<{
168
195
  slug: z.ZodString;
169
196
  label: z.ZodOptional<z.ZodString>;
170
197
  icon: z.ZodOptional<z.ZodString>;
171
198
  apiPath: z.ZodOptional<z.ZodString>;
172
199
  fields: z.ZodArray<z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>;
173
- timestamps: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodObject<{
200
+ timestamps: z.ZodPipe<z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodObject<{
174
201
  createdAt: z.ZodOptional<z.ZodString>;
175
202
  updatedAt: z.ZodOptional<z.ZodString>;
176
- }, z.core.$strip>]>>;
203
+ }, z.core.$strip>]>>, z.ZodTransform<boolean, boolean | {
204
+ createdAt?: string | undefined;
205
+ updatedAt?: string | undefined;
206
+ } | undefined>>;
177
207
  auth: z.ZodOptional<z.ZodBoolean>;
178
208
  hooks: z.ZodOptional<z.ZodObject<{
179
209
  beforeCreate: z.ZodOptional<z.ZodFunction<z.core.$ZodFunctionArgs, z.core.$ZodFunctionOut>>;
@@ -222,10 +252,13 @@ export declare const OpacaConfigSchema: z.ZodObject<{
222
252
  label: z.ZodOptional<z.ZodString>;
223
253
  icon: z.ZodOptional<z.ZodString>;
224
254
  fields: z.ZodArray<z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>;
225
- timestamps: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodObject<{
255
+ timestamps: z.ZodPipe<z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodObject<{
226
256
  createdAt: z.ZodOptional<z.ZodString>;
227
257
  updatedAt: z.ZodOptional<z.ZodString>;
228
- }, z.core.$strip>]>>;
258
+ }, z.core.$strip>]>>, z.ZodTransform<boolean, boolean | {
259
+ createdAt?: string | undefined;
260
+ updatedAt?: string | undefined;
261
+ } | undefined>>;
229
262
  access: z.ZodOptional<z.ZodObject<{
230
263
  read: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodFunction<z.core.$ZodFunctionArgs, z.core.$ZodFunctionOut>]>>;
231
264
  create: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodFunction<z.core.$ZodFunctionArgs, z.core.$ZodFunctionOut>]>>;
@@ -277,6 +310,16 @@ export declare const OpacaConfigSchema: z.ZodObject<{
277
310
  issuer: z.ZodString;
278
311
  }, z.core.$strip>>;
279
312
  }, z.core.$strip>>;
313
+ logger: z.ZodOptional<z.ZodObject<{
314
+ disabled: z.ZodOptional<z.ZodBoolean>;
315
+ disableColors: z.ZodOptional<z.ZodBoolean>;
316
+ level: z.ZodOptional<z.ZodEnum<{
317
+ error: "error";
318
+ debug: "debug";
319
+ info: "info";
320
+ warn: "warn";
321
+ }>>;
322
+ }, z.core.$strip>>;
280
323
  }, z.core.$strip>>;
281
324
  api: z.ZodOptional<z.ZodObject<{
282
325
  maxLimit: z.ZodOptional<z.ZodNumber>;
@@ -288,6 +331,15 @@ export declare const OpacaConfigSchema: z.ZodObject<{
288
331
  provider: z.ZodOptional<z.ZodFunction<z.core.$ZodFunctionArgs, z.core.$ZodFunctionOut>>;
289
332
  keyGenerator: z.ZodOptional<z.ZodFunction<z.core.$ZodFunctionArgs, z.core.$ZodFunctionOut>>;
290
333
  }, z.core.$strip>>;
334
+ openAPI: z.ZodOptional<z.ZodObject<{
335
+ enabled: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
336
+ path: z.ZodDefault<z.ZodOptional<z.ZodString>>;
337
+ theme: z.ZodOptional<z.ZodString>;
338
+ layout: z.ZodOptional<z.ZodString>;
339
+ hideModels: z.ZodOptional<z.ZodBoolean>;
340
+ hideDownloadButton: z.ZodOptional<z.ZodBoolean>;
341
+ customCss: z.ZodOptional<z.ZodString>;
342
+ }, z.core.$strip>>;
291
343
  }, z.core.$strip>>;
292
344
  access: z.ZodOptional<z.ZodObject<{
293
345
  roles: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString>>>>;
@@ -4,6 +4,6 @@ export declare function generateSchemaForCollection(collection: {
4
4
  fields: Field[];
5
5
  versions?: any;
6
6
  timestamps?: any;
7
- }, isUpdate?: boolean): z.ZodObject<{
7
+ }, isUpdate?: boolean, forDocs?: boolean): z.ZodObject<{
8
8
  [x: string]: z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>;
9
9
  }, z.core.$strip>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opacacms",
3
- "version": "0.1.20",
3
+ "version": "0.2.0",
4
4
  "scripts": {
5
5
  "build": "bun run ../../scripts/build.ts && tsc --emitDeclarationOnly",
6
6
  "build:publish": "bun run ../../scripts/build.ts --publish && tsc --emitDeclarationOnly",
@@ -101,22 +101,39 @@
101
101
  "./schema": {
102
102
  "types": "./dist/schema/index.d.ts",
103
103
  "import": "./dist/schema/index.js"
104
+ },
105
+ "./config": {
106
+ "types": "./dist/config.d.ts",
107
+ "import": "./dist/config.js"
108
+ },
109
+ "./plugins": {
110
+ "types": "./dist/plugins/index.d.ts",
111
+ "import": "./dist/plugins/index.js"
104
112
  }
105
113
  },
106
114
  "devDependencies": {
107
115
  "@cloudflare/workers-types": "^4.20260313.1",
116
+ "@faker-js/faker": "^10.3.0",
108
117
  "@happy-dom/global-registrator": "^20.8.4",
118
+ "@hono/bun-transpiler": "^0.2.1",
119
+ "@hono/esbuild-transpiler": "^0.1.4",
109
120
  "@testing-library/dom": "^10.4.1",
110
121
  "@testing-library/react": "^16.3.2",
122
+ "@types/better-sqlite3": "^7.6.13",
111
123
  "@types/bun": "latest",
112
124
  "@types/react": "^19.2.14",
113
125
  "@types/react-dom": "^19.2.3",
114
126
  "bun-plugin-scss": "^1.0.0",
127
+ "dotenv": "^17.3.1",
115
128
  "drizzle-kit": "^0.31.9",
129
+ "esbuild": "^0.27.4",
130
+ "esbuild-wasm": "^0.27.4",
116
131
  "happy-dom": "^20.8.4",
117
132
  "sass": "^1.98.0"
118
133
  },
119
134
  "peerDependencies": {
135
+ "react": "^19.2.4",
136
+ "react-dom": "^19.2.4",
120
137
  "typescript": "^5.9.3"
121
138
  },
122
139
  "dependencies": {
@@ -124,7 +141,6 @@
124
141
  "@aws-sdk/s3-request-presigner": "^3.1009.0",
125
142
  "@better-auth/api-key": "^1.5.5",
126
143
  "@better-auth/core": "^1.5.5",
127
- "@faker-js/faker": "^10.3.0",
128
144
  "@hono-rate-limiter/cloudflare": "^0.2.2",
129
145
  "@hono/node-server": "^1.19.11",
130
146
  "@lexical/code": "^0.41.0",
@@ -142,11 +158,10 @@
142
158
  "@nanostores/react": "^1.0.0",
143
159
  "@nanostores/router": "^1.0.0",
144
160
  "@r2wc/react-to-web-component": "^2.1.1",
161
+ "@scalar/hono-api-reference": "^0.10.4",
145
162
  "@tanstack/react-form": "^1.28.5",
146
- "@types/better-sqlite3": "^7.6.13",
147
163
  "better-auth": "^1.5.5",
148
164
  "better-sqlite3": "^12.6.2",
149
- "dotenv": "^17.3.1",
150
165
  "drizzle-orm": "^0.45.1",
151
166
  "hono": "^4.12.7",
152
167
  "hono-rate-limiter": "^0.5.3",
@@ -159,9 +174,8 @@
159
174
  "lucide-react": "^0.577.0",
160
175
  "nanostores": "^1.1.1",
161
176
  "postgres": "^3.4.8",
162
- "react": "^19.2.4",
163
- "react-dom": "^19.2.4",
164
- "zod": "^4.3.6"
177
+ "zod": "^4.3.6",
178
+ "zod-to-json-schema": "^3.25.1"
165
179
  },
166
180
  "files": [
167
181
  "dist"
@@ -1,13 +0,0 @@
1
- import type React from "react";
2
- import "../styles/data-detail.scss";
3
- interface DataDetailSheetProps {
4
- open: boolean;
5
- onOpenChange: (open: boolean) => void;
6
- title: string;
7
- description?: string;
8
- data: any;
9
- onSave?: (updatedData: any) => void;
10
- field?: string;
11
- }
12
- export declare const DataDetailSheet: React.FC<DataDetailSheetProps>;
13
- export {};
@@ -1,9 +0,0 @@
1
- import type React from "react";
2
- interface RelationshipDetailSheetProps {
3
- isOpen: boolean;
4
- onOpenChange: (open: boolean) => void;
5
- relationTo: string;
6
- id: string | number;
7
- }
8
- export declare const RelationshipDetailSheet: React.FC<RelationshipDetailSheetProps>;
9
- export {};
@@ -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 };