opacacms 0.1.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 (399) hide show
  1. package/bun.lock +34 -0
  2. package/dist/admin/api-client.d.ts +8 -0
  3. package/dist/admin/auth-client.d.ts +940 -0
  4. package/dist/admin/custom-field.d.ts +71 -0
  5. package/dist/admin/index.d.ts +11 -0
  6. package/dist/admin/react.d.ts +3 -0
  7. package/dist/admin/router.d.ts +7 -0
  8. package/dist/admin/stores/admin-queries.d.ts +32 -0
  9. package/dist/admin/stores/auth.d.ts +33 -0
  10. package/dist/admin/stores/column-visibility.d.ts +21 -0
  11. package/dist/admin/stores/config.d.ts +7 -0
  12. package/dist/admin/stores/media.d.ts +44 -0
  13. package/dist/admin/stores/query.d.ts +4 -0
  14. package/dist/admin/stores/ui.d.ts +11 -0
  15. package/dist/admin/ui/admin-client.d.ts +7 -0
  16. package/dist/admin/ui/admin-layout.d.ts +14 -0
  17. package/dist/admin/ui/components/ColumnVisibilityToggle.d.ts +10 -0
  18. package/dist/admin/ui/components/DataDetailSheet.d.ts +13 -0
  19. package/dist/admin/ui/components/DataDetailView.d.ts +9 -0
  20. package/dist/admin/ui/components/Table.d.ts +10 -0
  21. package/dist/admin/ui/components/fields/ArrayField.d.ts +13 -0
  22. package/dist/admin/ui/components/fields/BlocksField.d.ts +17 -0
  23. package/dist/admin/ui/components/fields/BooleanField.d.ts +13 -0
  24. package/dist/admin/ui/components/fields/CollapsibleField.d.ts +16 -0
  25. package/dist/admin/ui/components/fields/DateField.d.ts +13 -0
  26. package/dist/admin/ui/components/fields/FileField.d.ts +23 -0
  27. package/dist/admin/ui/components/fields/GroupField.d.ts +13 -0
  28. package/dist/admin/ui/components/fields/JoinField.d.ts +15 -0
  29. package/dist/admin/ui/components/fields/NumberField.d.ts +14 -0
  30. package/dist/admin/ui/components/fields/RadioField.d.ts +17 -0
  31. package/dist/admin/ui/components/fields/RelationshipField.d.ts +16 -0
  32. package/dist/admin/ui/components/fields/RowField.d.ts +12 -0
  33. package/dist/admin/ui/components/fields/SelectField.d.ts +18 -0
  34. package/dist/admin/ui/components/fields/TabsField.d.ts +15 -0
  35. package/dist/admin/ui/components/fields/TextAreaField.d.ts +14 -0
  36. package/dist/admin/ui/components/fields/TextField.d.ts +14 -0
  37. package/dist/admin/ui/components/fields/VirtualField.d.ts +8 -0
  38. package/dist/admin/ui/components/fields/index.d.ts +28 -0
  39. package/dist/admin/ui/components/fields/richtext-editor/index.d.ts +10 -0
  40. package/dist/admin/ui/components/fields/richtext-editor/nodes/ImageComponent.d.ts +7 -0
  41. package/dist/admin/ui/components/fields/richtext-editor/nodes/ImageNode.d.ts +27 -0
  42. package/dist/admin/ui/components/fields/richtext-editor/plugins/ComponentPickerPlugin.d.ts +1 -0
  43. package/dist/admin/ui/components/fields/richtext-editor/plugins/EditableSyncPlugin.d.ts +5 -0
  44. package/dist/admin/ui/components/fields/richtext-editor/plugins/NotionToolbarPlugin.d.ts +1 -0
  45. package/dist/admin/ui/components/fields/richtext-editor/plugins/SimpleToolbarPlugin.d.ts +1 -0
  46. package/dist/admin/ui/components/fields/richtext-editor/plugins/ValueSyncPlugin.d.ts +5 -0
  47. package/dist/admin/ui/components/fields/utils.d.ts +1 -0
  48. package/dist/admin/ui/components/link.d.ts +8 -0
  49. package/dist/admin/ui/components/media/AssetManagerModal.d.ts +17 -0
  50. package/dist/admin/ui/components/toast.d.ts +10 -0
  51. package/dist/admin/ui/components/ui/accordion.d.ts +11 -0
  52. package/dist/admin/ui/components/ui/alert-dialog.d.ts +12 -0
  53. package/dist/admin/ui/components/ui/blocks.d.ts +5 -0
  54. package/dist/admin/ui/components/ui/breadcrumbs.d.ts +7 -0
  55. package/dist/admin/ui/components/ui/button.d.ts +7 -0
  56. package/dist/admin/ui/components/ui/collapsible.d.ts +16 -0
  57. package/dist/admin/ui/components/ui/dialog.d.ts +27 -0
  58. package/dist/admin/ui/components/ui/group.d.ts +6 -0
  59. package/dist/admin/ui/components/ui/index.d.ts +17 -0
  60. package/dist/admin/ui/components/ui/input.d.ts +5 -0
  61. package/dist/admin/ui/components/ui/join.d.ts +7 -0
  62. package/dist/admin/ui/components/ui/label.d.ts +3 -0
  63. package/dist/admin/ui/components/ui/radio-group.d.ts +13 -0
  64. package/dist/admin/ui/components/ui/relationship-detail-sheet.d.ts +9 -0
  65. package/dist/admin/ui/components/ui/relationship.d.ts +8 -0
  66. package/dist/admin/ui/components/ui/scroll-area.d.ts +7 -0
  67. package/dist/admin/ui/components/ui/select.d.ts +37 -0
  68. package/dist/admin/ui/components/ui/separator.d.ts +8 -0
  69. package/dist/admin/ui/components/ui/sheet.d.ts +28 -0
  70. package/dist/admin/ui/components/ui/tabs.d.ts +17 -0
  71. package/dist/admin/ui/components/ui/utils.d.ts +1 -0
  72. package/dist/admin/ui/hooks/use-debounce.d.ts +1 -0
  73. package/dist/admin/ui/views/collection-list-view.d.ts +5 -0
  74. package/dist/admin/ui/views/dashboard-view.d.ts +10 -0
  75. package/dist/admin/ui/views/document-edit-view.d.ts +7 -0
  76. package/dist/admin/ui/views/global-edit-view.d.ts +19 -0
  77. package/dist/admin/ui/views/init-view.d.ts +4 -0
  78. package/dist/admin/ui/views/login-view.d.ts +4 -0
  79. package/dist/admin/ui/views/media-registry-view.d.ts +7 -0
  80. package/dist/admin/ui/views/settings-view.d.ts +7 -0
  81. package/dist/admin/webcomponent.d.ts +1 -0
  82. package/dist/api.d.ts +6 -0
  83. package/dist/auth/index.d.ts +2107 -0
  84. package/dist/auth/migrations.d.ts +5 -0
  85. package/dist/auth/premissions.d.ts +6 -0
  86. package/dist/chunk-16vgcf3k.js +88 -0
  87. package/dist/chunk-2zm8cy1w.js +9482 -0
  88. package/dist/chunk-5gvbp2qa.js +167 -0
  89. package/dist/chunk-62ev8gnc.js +41 -0
  90. package/dist/chunk-6dhs73zq.js +126 -0
  91. package/dist/chunk-6ew02s0c.js +472 -0
  92. package/dist/chunk-7a9kn0np.js +116 -0
  93. package/dist/chunk-8gkhn1d4.js +309 -0
  94. package/dist/chunk-8sqjbsgt.js +42 -0
  95. package/dist/chunk-9kxpbcb1.js +85 -0
  96. package/dist/chunk-cvdd4eqh.js +110 -0
  97. package/dist/chunk-d3ffeqp9.js +87 -0
  98. package/dist/chunk-dy5t83hr.js +261 -0
  99. package/dist/chunk-f3nvxn63.js +17 -0
  100. package/dist/chunk-hmhcense.js +1352 -0
  101. package/dist/chunk-j4d50hrx.js +20 -0
  102. package/dist/chunk-jwjk85ze.js +15 -0
  103. package/dist/chunk-kwp83w8b.js +250 -0
  104. package/dist/chunk-s8mqwnm1.js +14 -0
  105. package/dist/chunk-srsac177.js +85 -0
  106. package/dist/chunk-v521d72w.js +10 -0
  107. package/dist/chunk-xa7rjsn2.js +20 -0
  108. package/dist/chunk-xg35h5a3.js +15 -0
  109. package/dist/chunk-ybbbqj63.js +130 -0
  110. package/dist/chunk-zvwb67nd.js +332 -0
  111. package/dist/cli/commands/generate-types.d.ts +1 -0
  112. package/dist/cli/commands/init.d.ts +1 -0
  113. package/dist/cli/commands/migrate-commands.d.ts +5 -0
  114. package/dist/cli/commands/seed-command.d.ts +2 -0
  115. package/dist/cli/d1-mock.d.ts +30 -0
  116. package/dist/cli/index.d.ts +5 -0
  117. package/dist/cli/index.test.d.ts +1 -0
  118. package/dist/cli/r2-mock.d.ts +46 -0
  119. package/dist/cli/seeding.d.ts +17 -0
  120. package/dist/client.d.ts +51 -0
  121. package/dist/config-utils.d.ts +6 -0
  122. package/dist/config.d.ts +10 -0
  123. package/dist/db/adapter.d.ts +34 -0
  124. package/dist/db/better-sqlite.d.ts +40 -0
  125. package/dist/db/bun-sqlite.d.ts +40 -0
  126. package/dist/db/d1.d.ts +42 -0
  127. package/dist/db/kysely/data-mapper.d.ts +6 -0
  128. package/dist/db/kysely/field-mapper.d.ts +22 -0
  129. package/dist/db/kysely/migration-generator.d.ts +9 -0
  130. package/dist/db/kysely/query-builder.d.ts +9 -0
  131. package/dist/db/kysely/schema-builder.d.ts +15 -0
  132. package/dist/db/kysely/sql-utils.d.ts +1 -0
  133. package/dist/db/postgres.d.ts +51 -0
  134. package/dist/db/sqlite.d.ts +41 -0
  135. package/dist/db/system-schema.d.ts +2 -0
  136. package/dist/index.d.ts +6 -0
  137. package/dist/runtimes/bun.d.ts +17 -0
  138. package/dist/runtimes/cloudflare-workers.d.ts +10 -0
  139. package/dist/runtimes/next.d.ts +16 -0
  140. package/dist/runtimes/node.d.ts +18 -0
  141. package/dist/schema/collection.d.ts +100 -0
  142. package/dist/schema/fields/base.d.ts +83 -0
  143. package/dist/schema/fields/index.d.ts +135 -0
  144. package/dist/schema/global.d.ts +82 -0
  145. package/dist/schema/index.d.ts +4 -0
  146. package/dist/schema/infer.d.ts +55 -0
  147. package/dist/server/admin-router.d.ts +9 -0
  148. package/dist/server/admin.d.ts +18 -0
  149. package/dist/server/assets.d.ts +47 -0
  150. package/dist/server/collection-router.d.ts +14 -0
  151. package/dist/server/handlers.d.ts +76 -0
  152. package/dist/server/middlewares/admin.d.ts +6 -0
  153. package/dist/server/middlewares/auth.d.ts +16 -0
  154. package/dist/server/middlewares/context.d.ts +9 -0
  155. package/dist/server/middlewares/cors.d.ts +3 -0
  156. package/dist/server/middlewares/database-init.d.ts +11 -0
  157. package/dist/server/middlewares/rate-limit.d.ts +3 -0
  158. package/dist/server/router.d.ts +7 -0
  159. package/dist/server/setup-middlewares.d.ts +17 -0
  160. package/dist/server/system-router.d.ts +9 -0
  161. package/dist/server.d.ts +6 -0
  162. package/dist/src/admin/index.css +47 -0
  163. package/dist/src/admin/index.js +176 -0
  164. package/dist/src/admin/webcomponent.js +19 -0
  165. package/dist/src/api.js +27 -0
  166. package/dist/src/cli/index.js +157 -0
  167. package/dist/src/client.js +9 -0
  168. package/dist/src/db/bun-sqlite.js +523 -0
  169. package/dist/src/db/d1.js +568 -0
  170. package/dist/src/db/postgres.js +520 -0
  171. package/dist/src/db/sqlite.js +534 -0
  172. package/dist/src/index.js +20 -0
  173. package/dist/src/runtimes/bun.js +36 -0
  174. package/dist/src/runtimes/cloudflare-workers.js +29 -0
  175. package/dist/src/runtimes/next.js +26 -0
  176. package/dist/src/runtimes/node.js +38 -0
  177. package/dist/src/server.js +27 -0
  178. package/dist/src/storage/index.js +355 -0
  179. package/dist/storage/adapters/cloudflare-r2.d.ts +6 -0
  180. package/dist/storage/adapters/local.d.ts +6 -0
  181. package/dist/storage/adapters/s3.d.ts +13 -0
  182. package/dist/storage/errors.d.ts +12 -0
  183. package/dist/storage/index.d.ts +5 -0
  184. package/dist/storage/types.d.ts +31 -0
  185. package/dist/types.d.ts +484 -0
  186. package/dist/utils/lexical.d.ts +5 -0
  187. package/dist/utils/logger.d.ts +35 -0
  188. package/dist/validation.d.ts +300 -0
  189. package/dist/validator.d.ts +9 -0
  190. package/global.d.ts +11 -0
  191. package/package.json +151 -0
  192. package/src/admin/api-client.ts +63 -0
  193. package/src/admin/auth-client.ts +40 -0
  194. package/src/admin/custom-field.ts +179 -0
  195. package/src/admin/index.ts +15 -0
  196. package/src/admin/react.tsx +72 -0
  197. package/src/admin/router.ts +9 -0
  198. package/src/admin/stores/admin-queries.ts +121 -0
  199. package/src/admin/stores/auth.ts +61 -0
  200. package/src/admin/stores/column-visibility.ts +67 -0
  201. package/src/admin/stores/config.ts +15 -0
  202. package/src/admin/stores/media.ts +95 -0
  203. package/src/admin/stores/query.ts +13 -0
  204. package/src/admin/stores/ui.ts +29 -0
  205. package/src/admin/ui/admin-client.tsx +283 -0
  206. package/src/admin/ui/admin-layout.tsx +276 -0
  207. package/src/admin/ui/components/ColumnVisibilityToggle.tsx +141 -0
  208. package/src/admin/ui/components/DataDetailSheet.tsx +141 -0
  209. package/src/admin/ui/components/DataDetailView.tsx +175 -0
  210. package/src/admin/ui/components/Table.tsx +67 -0
  211. package/src/admin/ui/components/fields/ArrayField.tsx +166 -0
  212. package/src/admin/ui/components/fields/BlocksField.tsx +202 -0
  213. package/src/admin/ui/components/fields/BooleanField.tsx +50 -0
  214. package/src/admin/ui/components/fields/CollapsibleField.tsx +75 -0
  215. package/src/admin/ui/components/fields/DateField.tsx +45 -0
  216. package/src/admin/ui/components/fields/FileField.tsx +322 -0
  217. package/src/admin/ui/components/fields/GroupField.tsx +50 -0
  218. package/src/admin/ui/components/fields/JoinField.tsx +23 -0
  219. package/src/admin/ui/components/fields/NumberField.tsx +46 -0
  220. package/src/admin/ui/components/fields/RadioField.tsx +62 -0
  221. package/src/admin/ui/components/fields/RelationshipField.tsx +278 -0
  222. package/src/admin/ui/components/fields/RowField.tsx +40 -0
  223. package/src/admin/ui/components/fields/SelectField.tsx +59 -0
  224. package/src/admin/ui/components/fields/TabsField.tsx +101 -0
  225. package/src/admin/ui/components/fields/TextAreaField.tsx +54 -0
  226. package/src/admin/ui/components/fields/TextField.tsx +49 -0
  227. package/src/admin/ui/components/fields/VirtualField.tsx +53 -0
  228. package/src/admin/ui/components/fields/index.tsx +371 -0
  229. package/src/admin/ui/components/fields/richtext-editor/index.tsx +211 -0
  230. package/src/admin/ui/components/fields/richtext-editor/nodes/ImageComponent.tsx +142 -0
  231. package/src/admin/ui/components/fields/richtext-editor/nodes/ImageNode.tsx +95 -0
  232. package/src/admin/ui/components/fields/richtext-editor/plugins/ComponentPickerPlugin.tsx +226 -0
  233. package/src/admin/ui/components/fields/richtext-editor/plugins/EditableSyncPlugin.tsx +16 -0
  234. package/src/admin/ui/components/fields/richtext-editor/plugins/NotionToolbarPlugin.tsx +184 -0
  235. package/src/admin/ui/components/fields/richtext-editor/plugins/SimpleToolbarPlugin.tsx +240 -0
  236. package/src/admin/ui/components/fields/richtext-editor/plugins/ValueSyncPlugin.tsx +40 -0
  237. package/src/admin/ui/components/fields/utils.ts +1 -0
  238. package/src/admin/ui/components/link.tsx +41 -0
  239. package/src/admin/ui/components/media/AssetManagerModal.tsx +334 -0
  240. package/src/admin/ui/components/toast.tsx +72 -0
  241. package/src/admin/ui/components/ui/accordion.tsx +51 -0
  242. package/src/admin/ui/components/ui/alert-dialog.tsx +98 -0
  243. package/src/admin/ui/components/ui/blocks.tsx +32 -0
  244. package/src/admin/ui/components/ui/breadcrumbs.tsx +59 -0
  245. package/src/admin/ui/components/ui/button.tsx +26 -0
  246. package/src/admin/ui/components/ui/collapsible.tsx +124 -0
  247. package/src/admin/ui/components/ui/dialog.tsx +79 -0
  248. package/src/admin/ui/components/ui/group.tsx +20 -0
  249. package/src/admin/ui/components/ui/index.ts +17 -0
  250. package/src/admin/ui/components/ui/input.tsx +12 -0
  251. package/src/admin/ui/components/ui/join.tsx +53 -0
  252. package/src/admin/ui/components/ui/label.tsx +11 -0
  253. package/src/admin/ui/components/ui/radio-group.tsx +75 -0
  254. package/src/admin/ui/components/ui/relationship-detail-sheet.tsx +122 -0
  255. package/src/admin/ui/components/ui/relationship.tsx +58 -0
  256. package/src/admin/ui/components/ui/scroll-area.tsx +19 -0
  257. package/src/admin/ui/components/ui/select.tsx +187 -0
  258. package/src/admin/ui/components/ui/separator.tsx +21 -0
  259. package/src/admin/ui/components/ui/sheet.tsx +106 -0
  260. package/src/admin/ui/components/ui/tabs.tsx +116 -0
  261. package/src/admin/ui/components/ui/utils.ts +3 -0
  262. package/src/admin/ui/hooks/use-debounce.ts +15 -0
  263. package/src/admin/ui/styles/_locale-switcher.scss +33 -0
  264. package/src/admin/ui/styles/accordion.scss +60 -0
  265. package/src/admin/ui/styles/animations.scss +41 -0
  266. package/src/admin/ui/styles/asset-manager.scss +547 -0
  267. package/src/admin/ui/styles/badge.scss +13 -0
  268. package/src/admin/ui/styles/base.scss +22 -0
  269. package/src/admin/ui/styles/button.scss +161 -0
  270. package/src/admin/ui/styles/card.scss +13 -0
  271. package/src/admin/ui/styles/collapsible.scss +75 -0
  272. package/src/admin/ui/styles/data-detail.scss +92 -0
  273. package/src/admin/ui/styles/dialog.scss +102 -0
  274. package/src/admin/ui/styles/empty-state.scss +22 -0
  275. package/src/admin/ui/styles/group.scss +19 -0
  276. package/src/admin/ui/styles/index.scss +33 -0
  277. package/src/admin/ui/styles/input.scss +80 -0
  278. package/src/admin/ui/styles/label.scss +12 -0
  279. package/src/admin/ui/styles/layout.scss +56 -0
  280. package/src/admin/ui/styles/lexical.scss +469 -0
  281. package/src/admin/ui/styles/loading.scss +102 -0
  282. package/src/admin/ui/styles/media-registry.scss +597 -0
  283. package/src/admin/ui/styles/pagination.scss +20 -0
  284. package/src/admin/ui/styles/radio-group.scss +66 -0
  285. package/src/admin/ui/styles/row.scss +17 -0
  286. package/src/admin/ui/styles/scrollbar.scss +36 -0
  287. package/src/admin/ui/styles/select.scss +121 -0
  288. package/src/admin/ui/styles/separator.scss +14 -0
  289. package/src/admin/ui/styles/sheet.scss +152 -0
  290. package/src/admin/ui/styles/sidebar.scss +148 -0
  291. package/src/admin/ui/styles/switch.scss +59 -0
  292. package/src/admin/ui/styles/table.scss +207 -0
  293. package/src/admin/ui/styles/tabs.scss +62 -0
  294. package/src/admin/ui/styles/toast.scss +45 -0
  295. package/src/admin/ui/styles/variables.scss +24 -0
  296. package/src/admin/ui/views/collection-list-view.tsx +720 -0
  297. package/src/admin/ui/views/dashboard-view.tsx +263 -0
  298. package/src/admin/ui/views/document-edit-view.tsx +384 -0
  299. package/src/admin/ui/views/global-edit-view.tsx +226 -0
  300. package/src/admin/ui/views/init-view.tsx +182 -0
  301. package/src/admin/ui/views/login-view.tsx +123 -0
  302. package/src/admin/ui/views/media-registry-view.tsx +1104 -0
  303. package/src/admin/ui/views/settings-view.tsx +729 -0
  304. package/src/admin/webcomponent.tsx +15 -0
  305. package/src/api.ts +9 -0
  306. package/src/auth/index.ts +194 -0
  307. package/src/auth/migrations.ts +87 -0
  308. package/src/auth/premissions.ts +46 -0
  309. package/src/cli/commands/generate-types.ts +116 -0
  310. package/src/cli/commands/init.ts +95 -0
  311. package/src/cli/commands/migrate-commands.ts +160 -0
  312. package/src/cli/commands/seed-command.ts +11 -0
  313. package/src/cli/d1-mock.ts +101 -0
  314. package/src/cli/index.test.ts +84 -0
  315. package/src/cli/index.ts +183 -0
  316. package/src/cli/r2-mock.ts +217 -0
  317. package/src/cli/seeding.ts +405 -0
  318. package/src/client.ts +181 -0
  319. package/src/config-utils.ts +102 -0
  320. package/src/config.ts +49 -0
  321. package/src/db/adapter.ts +53 -0
  322. package/src/db/better-sqlite.ts +630 -0
  323. package/src/db/bun-sqlite.ts +646 -0
  324. package/src/db/d1.ts +711 -0
  325. package/src/db/kysely/data-mapper.ts +142 -0
  326. package/src/db/kysely/field-mapper.ts +148 -0
  327. package/src/db/kysely/migration-generator.ts +223 -0
  328. package/src/db/kysely/query-builder.ts +92 -0
  329. package/src/db/kysely/schema-builder.ts +439 -0
  330. package/src/db/kysely/sql-utils.ts +13 -0
  331. package/src/db/postgres.ts +621 -0
  332. package/src/db/sqlite.ts +658 -0
  333. package/src/db/system-schema.ts +121 -0
  334. package/src/index.ts +13 -0
  335. package/src/runtimes/README.md +59 -0
  336. package/src/runtimes/bun.ts +49 -0
  337. package/src/runtimes/cloudflare-workers.ts +38 -0
  338. package/src/runtimes/next.ts +26 -0
  339. package/src/runtimes/node.ts +52 -0
  340. package/src/schema/collection.ts +184 -0
  341. package/src/schema/fields/base.ts +164 -0
  342. package/src/schema/fields/index.ts +427 -0
  343. package/src/schema/global.ts +145 -0
  344. package/src/schema/index.ts +4 -0
  345. package/src/schema/infer.ts +72 -0
  346. package/src/server/admin-router.ts +20 -0
  347. package/src/server/admin.ts +142 -0
  348. package/src/server/assets.ts +306 -0
  349. package/src/server/collection-router.ts +55 -0
  350. package/src/server/handlers.ts +722 -0
  351. package/src/server/middlewares/admin.ts +27 -0
  352. package/src/server/middlewares/auth.ts +89 -0
  353. package/src/server/middlewares/context.ts +17 -0
  354. package/src/server/middlewares/cors.ts +24 -0
  355. package/src/server/middlewares/database-init.ts +74 -0
  356. package/src/server/middlewares/rate-limit.ts +71 -0
  357. package/src/server/router.ts +47 -0
  358. package/src/server/setup-middlewares.ts +58 -0
  359. package/src/server/system-router.ts +35 -0
  360. package/src/server.ts +9 -0
  361. package/src/storage/adapters/cloudflare-r2.ts +136 -0
  362. package/src/storage/adapters/local.ts +146 -0
  363. package/src/storage/adapters/s3.ts +186 -0
  364. package/src/storage/errors.ts +46 -0
  365. package/src/storage/index.ts +5 -0
  366. package/src/storage/types.ts +39 -0
  367. package/src/types.ts +577 -0
  368. package/src/utils/lexical.ts +37 -0
  369. package/src/utils/logger.ts +73 -0
  370. package/src/validation.ts +429 -0
  371. package/src/validator.ts +179 -0
  372. package/test/admin-custom-field.test.ts +162 -0
  373. package/test/admin-react-field.test.tsx +134 -0
  374. package/test/api-features.test.ts +78 -0
  375. package/test/api.test.ts +178 -0
  376. package/test/auth.test.ts +62 -0
  377. package/test/cli-integration.test.ts +146 -0
  378. package/test/cli.test.ts +25 -0
  379. package/test/db/postgres.test.ts +95 -0
  380. package/test/db/sqlite-filter.test.ts +53 -0
  381. package/test/db/sqlite.test.ts +82 -0
  382. package/test/engine-features.test.ts +79 -0
  383. package/test/globals.test.ts +74 -0
  384. package/test/integration-tmp/db-app/opacacms.config.ts +15 -0
  385. package/test/integration-tmp/my-sqlite-app/opacacms.config.ts +25 -0
  386. package/test/integration-tmp/my-test-app/index.ts +8 -0
  387. package/test/integration-tmp/my-test-app/opacacms.config.ts +16 -0
  388. package/test/integration-tmp/my-test-app/package.json +12 -0
  389. package/test/populate.test.ts +79 -0
  390. package/test/runtimes.test.ts +43 -0
  391. package/test/schema-builder.test.ts +107 -0
  392. package/test/schema-features.test.ts +63 -0
  393. package/test/seeding.test.ts +68 -0
  394. package/test/storage/local.test.ts +72 -0
  395. package/test/storage/s3.test.ts +60 -0
  396. package/test/structural-data.test.ts +100 -0
  397. package/test/test-setup.ts +11 -0
  398. package/test/validation.test.ts +162 -0
  399. package/tsconfig.json +42 -0
@@ -0,0 +1,121 @@
1
+ import type { Collection } from "../types";
2
+
3
+ export const getSystemCollections = (): Collection[] => [
4
+ {
5
+ slug: "_opaca_assets",
6
+ label: "Assets",
7
+ apiPath: "assets",
8
+ fields: [
9
+ { name: "id", type: "text", required: true },
10
+ { name: "key", type: "text", required: true },
11
+ { name: "filename", type: "text", required: true },
12
+ { name: "originalFilename", type: "text", required: true },
13
+ { name: "mimeType", type: "text", required: true },
14
+ { name: "filesize", type: "number", required: true },
15
+ { name: "bucket", type: "text", required: true },
16
+ { name: "folder", type: "text" },
17
+ { name: "altText", type: "text" },
18
+ { name: "caption", type: "text" },
19
+ { name: "uploadedBy", type: "text" },
20
+ ],
21
+ timestamps: true,
22
+ },
23
+
24
+ // AUTH
25
+ {
26
+ slug: "_users",
27
+ apiPath: "users",
28
+ fields: [
29
+ { name: "id", type: "text", required: true },
30
+ { name: "name", type: "text", required: true },
31
+ { name: "email", type: "text", required: true, unique: true },
32
+ { name: "emailVerified", type: "boolean", required: true, defaultValue: false },
33
+ { name: "image", type: "text" },
34
+ { name: "role", type: "text" },
35
+ { name: "banned", type: "boolean" },
36
+ { name: "banReason", type: "text" },
37
+ { name: "banExpires", type: "date" },
38
+ ],
39
+ timestamps: true,
40
+ },
41
+ {
42
+ slug: "_sessions",
43
+ fields: [
44
+ { name: "id", type: "text", required: true },
45
+ { name: "expiresAt", type: "date", required: true },
46
+ { name: "token", type: "text", required: true, unique: true },
47
+ { name: "ipAddress", type: "text" },
48
+ { name: "userAgent", type: "text" },
49
+ {
50
+ name: "userId",
51
+ type: "text",
52
+ required: true,
53
+ references: { table: "_users", column: "id", onDelete: "cascade" },
54
+ },
55
+ { name: "impersonatedBy", type: "text" },
56
+ ],
57
+ timestamps: true,
58
+ hidden: true,
59
+ },
60
+ {
61
+ slug: "_accounts",
62
+ fields: [
63
+ { name: "id", type: "text", required: true },
64
+ { name: "accountId", type: "text", required: true },
65
+ { name: "providerId", type: "text", required: true },
66
+ {
67
+ name: "userId",
68
+ type: "text",
69
+ required: true,
70
+ references: { table: "_users", column: "id", onDelete: "cascade" },
71
+ },
72
+ { name: "accessToken", type: "text" },
73
+ { name: "refreshToken", type: "text" },
74
+ { name: "idToken", type: "text" },
75
+ { name: "accessTokenExpiresAt", type: "date" },
76
+ { name: "refreshTokenExpiresAt", type: "date" },
77
+ { name: "scope", type: "text" },
78
+ { name: "password", type: "text" },
79
+ ],
80
+ timestamps: true,
81
+ hidden: true,
82
+ },
83
+ {
84
+ slug: "_verifications",
85
+ fields: [
86
+ { name: "id", type: "text", required: true },
87
+ { name: "identifier", type: "text", required: true },
88
+ { name: "value", type: "text", required: true },
89
+ { name: "expiresAt", type: "date", required: true },
90
+ ],
91
+ timestamps: true,
92
+ hidden: true,
93
+ },
94
+ {
95
+ slug: "_api_keys",
96
+ fields: [
97
+ { name: "id", type: "text", required: true },
98
+ { name: "configId", type: "text", required: true },
99
+ { name: "name", type: "text" },
100
+ { name: "start", type: "text" },
101
+ { name: "prefix", type: "text" },
102
+ { name: "key", type: "text", required: true },
103
+ { name: "referenceId", type: "text", required: true },
104
+ { name: "refillInterval", type: "number" },
105
+ { name: "refillAmount", type: "number" },
106
+ { name: "lastRefillAt", type: "date" },
107
+ { name: "enabled", type: "boolean", required: true },
108
+ { name: "rateLimitEnabled", type: "boolean", required: true },
109
+ { name: "rateLimitTimeWindow", type: "number" },
110
+ { name: "rateLimitMax", type: "number" },
111
+ { name: "requestCount", type: "number", required: true },
112
+ { name: "remaining", type: "number" },
113
+ { name: "lastRequest", type: "date" },
114
+ { name: "expiresAt", type: "date" },
115
+ { name: "permissions", type: "text" },
116
+ { name: "metadata", type: "text" },
117
+ ],
118
+ timestamps: { createdAt: "createdAt", updatedAt: "updatedAt" },
119
+ hidden: true,
120
+ },
121
+ ];
package/src/index.ts ADDED
@@ -0,0 +1,13 @@
1
+ // Client-friendly index (safe for browser)
2
+
3
+ export * from "./auth";
4
+ export * from "./client";
5
+ export * from "./config";
6
+ export * from "./config-utils";
7
+ export * from "./types";
8
+ // Export everything from validation EXCEPT what conflicts with types
9
+ export type {
10
+ AdminConfig,
11
+ CollectionHooks,
12
+ FieldType,
13
+ } from "./validation";
@@ -0,0 +1,59 @@
1
+ # OpacaCMS Runtimes
2
+
3
+ The `runtimes` directory contains adapters for different JavaScript environments where you can deploy your OpacaCMS project.
4
+
5
+ Since OpacaCMS is built on top of [Hono](https://hono.dev), it is highly portable and can run anywhere Hono can run. Instead of writing boilerplate code to mount the OpacaCMS router (`createAPIRouter`) into your preferred framework or runtime, we provide pre-configured handlers here to keep your setup clean and simple.
6
+
7
+ This approach ensures zero redundancy. The core logic lives in our internal router, while these runtime handlers simply wrap the router with the specific bindings needed for their environment.
8
+
9
+ ## Available Runtimes
10
+
11
+ ### 1. Next.js (`next.ts`)
12
+ Creates an App Router compatible Route Handler. It leverages `hono/vercel` to wrap the API natively for Vercel's Node or Edge runtimes.
13
+
14
+ **Usage (`app/api/[[...route]]/route.ts`):**
15
+ ```ts
16
+ import opacaConfig from "@opacacms-config";
17
+ import { createNextHandler } from "opacacms/runtimes/next";
18
+
19
+ export const { GET, POST, PUT, DELETE, PATCH, OPTIONS } = createNextHandler(opacaConfig);
20
+ ```
21
+
22
+ ### 2. Bun (`bun.ts`)
23
+ Creates a native, ultra-fast server using `Bun.serve()`. Best for standalone deployments running natively with Bun.
24
+
25
+ **Usage (`server.ts`):**
26
+ ```ts
27
+ import opacaConfig from "./opacacms.config";
28
+ import { createBunHandler } from "opacacms/runtimes/bun";
29
+
30
+ const { init } = createBunHandler(opacaConfig, { port: 3000 });
31
+ init(); // Connects DB, runs migrations, and starts the server
32
+ ```
33
+
34
+ ### 3. Node.js (`node.ts`)
35
+ Creates a standard Node.js standalone server using `@hono/node-server`. Use this if you want to deploy as a vanilla Node.js application (e.g. on Render, Railway, AWS EC2).
36
+
37
+ **Usage (`server.js` / `server.ts`):**
38
+ ```ts
39
+ import opacaConfig from "./opacacms.config";
40
+ import { createNodeHandler } from "opacacms/runtimes/node";
41
+
42
+ const { init } = createNodeHandler(opacaConfig, { port: 3000 });
43
+ init(); // Connects DB, runs migrations, and starts the server
44
+ ```
45
+
46
+ ### 4. Cloudflare Workers (`cloudflare-workers.ts`)
47
+ Provides a native `fetch` handler optimized for Cloudflare Workers. It injects Cloudflare's `env` and `ctx` directly into the Hono instance.
48
+
49
+ **Usage (`src/index.ts`):**
50
+ ```ts
51
+ import opacaConfig from "./opacacms.config";
52
+ import { createCloudflareWorkersHandler } from "opacacms/runtimes/cloudflare-workers";
53
+
54
+ export default createCloudflareWorkersHandler(opacaConfig);
55
+ ```
56
+
57
+ ---
58
+
59
+ *Need support for another environment like Deno, AWS Lambda, or Netlify? Check out the [Hono Adapters Documentation](https://hono.dev/docs/getting-started/basic) and feel free to contribute!*
@@ -0,0 +1,49 @@
1
+ import { Hono } from "hono";
2
+ import { createAPIRouter } from "../server/router";
3
+ import type { OpacaConfig } from "../types";
4
+
5
+ export interface BunServerOptions {
6
+ port?: number;
7
+ }
8
+
9
+ /**
10
+ * Creates a standalone Bun server running OpacaCMS.
11
+ * Bun has native support for the `fetch` API, making it extremely fast.
12
+ *
13
+ * @param config - The OpacaCMS configuration object.
14
+ * @param options - Options for the Bun server (e.g., port).
15
+ * @returns The Hono application instance and an `init` function to start the server.
16
+ */
17
+ export function createBunHandler(config: OpacaConfig, options?: BunServerOptions) {
18
+ const app = new Hono();
19
+
20
+ // Base router
21
+ const apiRouter = createAPIRouter(config);
22
+ app.route("/api", apiRouter);
23
+
24
+ const init = async () => {
25
+ console.log("🚀 Initializing OpacaCMS (Bun runtime)...");
26
+
27
+ if (config.db) {
28
+ await config.db.connect();
29
+ console.log(`📦 Database "${config.db.name}" connected`);
30
+
31
+ await config.db.migrate(config.collections);
32
+ console.log("✅ Migrations completed");
33
+ }
34
+
35
+ const port = options?.port || 3000;
36
+
37
+ // Using Bun's global server
38
+ Bun.serve({
39
+ fetch: app.fetch,
40
+ port,
41
+ });
42
+
43
+ console.log(`Listening on http://localhost:${port}`);
44
+
45
+ return app;
46
+ };
47
+
48
+ return { app, init };
49
+ }
@@ -0,0 +1,38 @@
1
+ import { Hono } from "hono";
2
+ import { createAPIRouter } from "../server/router";
3
+ import type { OpacaConfig } from "../types";
4
+
5
+ let cachedApp: Hono | undefined;
6
+
7
+ /**
8
+ * Creates a Cloudflare Workers compatible handler for OpacaCMS.
9
+ * Returns an object with a `fetch` method, perfectly matched for CF Workers.
10
+ *
11
+ * @param configOrFactory - Either the OpacaCMS configuration object or a function that returns it.
12
+ * @returns An object with a standard `fetch` method signature.
13
+ */
14
+ export function createCloudflareWorkersHandler(
15
+ configOrFactory:
16
+ | OpacaConfig
17
+ | ((env: any, request: Request) => OpacaConfig | Promise<OpacaConfig>),
18
+ ) {
19
+ const app = new Hono();
20
+
21
+ app.use("/api/*", async (c, next) => {
22
+ if (cachedApp) return cachedApp.fetch(c.req.raw, c.env, c.executionCtx);
23
+
24
+ const config =
25
+ typeof configOrFactory === "function"
26
+ ? await configOrFactory(c.env, c.req.raw)
27
+ : configOrFactory;
28
+
29
+ const apiRouter = createAPIRouter(config);
30
+ const innerApp = new Hono();
31
+ innerApp.route("/", apiRouter);
32
+ cachedApp = innerApp;
33
+
34
+ return cachedApp.fetch(c.req.raw, c.env, c.executionCtx);
35
+ });
36
+
37
+ return app;
38
+ }
@@ -0,0 +1,26 @@
1
+ import { handle } from "hono/vercel";
2
+ import { createAPIRouter } from "../server/router";
3
+ import type { OpacaConfig } from "../types";
4
+
5
+ /**
6
+ * Creates a Next.js App Router compatible route handler for OpacaCMS.
7
+ * Wraps the internal Hono router using `hono/vercel`.
8
+ *
9
+ * @param config - The OpacaCMS configuration object.
10
+ * @returns An object containing the HTTP methods to be exported in `app/api/[[...route]]/route.ts`.
11
+ */
12
+ export function createNextHandler(config: OpacaConfig) {
13
+ const app = createAPIRouter(config);
14
+
15
+ // Vercel's edge/node runtime handles all these methods natively via `handle`
16
+ const handler = handle(app);
17
+
18
+ return {
19
+ GET: handler,
20
+ POST: handler,
21
+ PUT: handler,
22
+ DELETE: handler,
23
+ PATCH: handler,
24
+ OPTIONS: handler,
25
+ };
26
+ }
@@ -0,0 +1,52 @@
1
+ import { serve } from "@hono/node-server";
2
+ import { Hono } from "hono";
3
+ import { createAPIRouter } from "../server/router";
4
+ import type { OpacaConfig } from "../types";
5
+
6
+ export interface NodeServerOptions {
7
+ port?: number;
8
+ fetch?: (request: Request) => Promise<Response>;
9
+ }
10
+
11
+ /**
12
+ * Creates a standalone Node.js server running OpacaCMS.
13
+ * Uses `@hono/node-server` to serve the API.
14
+ *
15
+ * @param config - The OpacaCMS configuration object.
16
+ * @param options - Options for the Node server (e.g., port).
17
+ * @returns The Hono application instance and an `init` function to start the server.
18
+ */
19
+ export function createNodeHandler(config: OpacaConfig, options?: NodeServerOptions) {
20
+ const app = new Hono();
21
+
22
+ // Base router
23
+ const apiRouter = createAPIRouter(config);
24
+ app.route("/api", apiRouter);
25
+
26
+ const init = async () => {
27
+ console.log("🚀 Initializing OpacaCMS (Node.js runtime)...");
28
+
29
+ if (config.db) {
30
+ await config.db.connect();
31
+ console.log(`📦 Database "${config.db.name}" connected`);
32
+
33
+ await config.db.migrate(config.collections);
34
+ console.log("✅ Migrations completed");
35
+ }
36
+
37
+ const port = options?.port || 3000;
38
+ serve(
39
+ {
40
+ fetch: app.fetch,
41
+ port,
42
+ },
43
+ (info) => {
44
+ console.log(`Listening on http://localhost:${info.port}`);
45
+ },
46
+ );
47
+
48
+ return app;
49
+ };
50
+
51
+ return { app, init };
52
+ }
@@ -0,0 +1,184 @@
1
+ import { icons } from "lucide-react";
2
+ import type { Collection as BaseCollection, IconName } from "../types";
3
+ import { type FieldBuilder, VirtualFieldBuilder } from "./fields";
4
+ import type { AccessRules, InferFields } from "./infer";
5
+
6
+ /**
7
+ * The Fluent API Collection Builder.
8
+ */
9
+ export class CollectionBuilder<TFields extends Record<string, any> = {}> {
10
+ private config: Partial<BaseCollection> = {
11
+ fields: [],
12
+ timestamps: true,
13
+ };
14
+
15
+ private fieldBuilders: FieldBuilder<any, any>[] = [];
16
+
17
+ constructor(public readonly slug: string) {
18
+ this.config.slug = slug;
19
+ }
20
+
21
+ /**
22
+ * Sets the user-friendly label for the Collection.
23
+ */
24
+ public label(label: string): this {
25
+ this.config.label = label;
26
+ return this;
27
+ }
28
+
29
+ /**
30
+ * Sets the Lucide icon for this collection.
31
+ */
32
+ public icon(iconName: IconName): this {
33
+ this.config.icon = iconName;
34
+ return this;
35
+ }
36
+
37
+ /**
38
+ * Defines which field should be used as the title in the Admin UI.
39
+ */
40
+ public useAsTitle(fieldName: keyof TFields | (string & {})): this {
41
+ this._ensureAdmin();
42
+ (this.config.admin as any).useAsTitle = fieldName;
43
+ return this;
44
+ }
45
+
46
+ /**
47
+ * Enables or disables automatic timestamps (createdAt, updatedAt).
48
+ */
49
+ public timestamps(val = true): this {
50
+ this.config.timestamps = val;
51
+ return this;
52
+ }
53
+
54
+ /**
55
+ * Defines the fields for this Collection.
56
+ * Re-instantiates the builder to capture the strong types of the fields.
57
+ */
58
+ public fields<T extends readonly any[]>(fields: [...T]): CollectionBuilder<InferFields<T>> {
59
+ // We clone the current builder state to a newly typed instance.
60
+ const nextBuilder = new CollectionBuilder<InferFields<T>>(this.config.slug!);
61
+ nextBuilder.config = { ...this.config };
62
+ nextBuilder.fieldBuilders = [...fields];
63
+ return nextBuilder;
64
+ }
65
+
66
+ /**
67
+ * Type-safe access control rules.
68
+ */
69
+ public access(rules: AccessRules<TFields>): this {
70
+ this.config.access = rules as any;
71
+ return this;
72
+ }
73
+
74
+ /**
75
+ * Defines a virtual/computed field with full type inference of the current collection data.
76
+ */
77
+ public virtual<TName extends string, TReturn = any>(
78
+ name: TName,
79
+ options: {
80
+ label?: string;
81
+ resolve: (args: {
82
+ data: TFields;
83
+ req: any;
84
+ user: any;
85
+ session: any;
86
+ apiKey?: any;
87
+ }) => TReturn | Promise<TReturn>;
88
+ returnType?: "string" | "number" | "boolean" | "json";
89
+ },
90
+ ): CollectionBuilder<TFields & { [K in TName]: TReturn }> {
91
+ const builder = new VirtualFieldBuilder<TName, TFields>(name);
92
+ if (options.label) builder.label(options.label);
93
+ if (options.resolve) builder.resolve(options.resolve as any);
94
+ if (options.returnType) builder.returnType(options.returnType);
95
+
96
+ const nextBuilder = new CollectionBuilder<TFields & { [K in TName]: TReturn }>(
97
+ this.config.slug!,
98
+ );
99
+ nextBuilder.config = { ...this.config };
100
+ nextBuilder.fieldBuilders = [...this.fieldBuilders, builder];
101
+ return nextBuilder;
102
+ }
103
+
104
+ /**
105
+ * Alias for .virtual()
106
+ */
107
+ public computed<TName extends string, TReturn = any>(
108
+ name: TName,
109
+ options: {
110
+ label?: string;
111
+ resolve: (args: {
112
+ data: TFields;
113
+ req: any;
114
+ user: any;
115
+ session: any;
116
+ apiKey?: any;
117
+ }) => TReturn | Promise<TReturn>;
118
+ returnType?: "string" | "number" | "boolean" | "json";
119
+ },
120
+ ): CollectionBuilder<TFields & { [K in TName]: TReturn }> {
121
+ return this.virtual<TName, TReturn>(name, options);
122
+ }
123
+
124
+ /**
125
+ * Advanced Admin UI configuration.
126
+ */
127
+ public admin(opts: BaseCollection["admin"]): this {
128
+ if (typeof opts === "boolean") {
129
+ this.config.admin = opts;
130
+ } else {
131
+ this.config.admin = { ...(this.config.admin as object), ...opts };
132
+ }
133
+ return this;
134
+ }
135
+
136
+ /**
137
+ * Adds automated versioning and drafts.
138
+ */
139
+ public versions(opts: { drafts?: boolean; maxRevisions?: number; autosave?: boolean }): this {
140
+ this.config.versions = opts;
141
+ return this;
142
+ }
143
+
144
+ /**
145
+ * Adds webhooks to be triggered on document lifecycle events.
146
+ */
147
+ public webhooks(
148
+ webhooks: { events: string[]; url: string; headers?: Record<string, string> }[],
149
+ ): this {
150
+ this.config.webhooks = webhooks;
151
+ return this;
152
+ }
153
+
154
+ /**
155
+ * Spreads configuration from presets (Proposed Feature stub)
156
+ */
157
+ public extend(preset: any): this {
158
+ // Deep merge logic would go here
159
+ return this;
160
+ }
161
+
162
+ protected _ensureAdmin() {
163
+ if (!this.config.admin || typeof this.config.admin === "boolean") {
164
+ this.config.admin = {};
165
+ }
166
+ }
167
+
168
+ /**
169
+ * Compiles the collection builder down into the raw Object structure expected by OpacaCMS.
170
+ */
171
+ public build(): BaseCollection {
172
+ // Build all fields into raw JSON objects
173
+ const compiledFields = this.fieldBuilders.map((builder) => builder.build());
174
+
175
+ return {
176
+ ...this.config,
177
+ fields: compiledFields,
178
+ } as BaseCollection;
179
+ }
180
+ }
181
+
182
+ export const Collection = {
183
+ create: (slug: string) => new CollectionBuilder(slug),
184
+ };