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,534 @@
1
+ import {
2
+ buildKyselyWhere,
3
+ flattenPayload,
4
+ pushSchema,
5
+ unflattenRow
6
+ } from "../../chunk-6ew02s0c.js";
7
+ import {
8
+ BaseDatabaseAdapter
9
+ } from "../../chunk-s8mqwnm1.js";
10
+ import {
11
+ logger
12
+ } from "../../chunk-62ev8gnc.js";
13
+ import {
14
+ flattenFields,
15
+ getRelationalFields,
16
+ toSnakeCase
17
+ } from "../../chunk-cvdd4eqh.js";
18
+ import"../../chunk-ybbbqj63.js";
19
+ import"../../chunk-8sqjbsgt.js";
20
+
21
+ // src/db/sqlite.ts
22
+ import fs from "node:fs/promises";
23
+ import path from "node:path";
24
+ import Database from "better-sqlite3";
25
+ import { CompiledQuery, FileMigrationProvider, Kysely, Migrator, SqliteDialect } from "kysely";
26
+ class SQLiteAdapter extends BaseDatabaseAdapter {
27
+ name = "sqlite";
28
+ _rawDb;
29
+ _db;
30
+ _collections = [];
31
+ _globals = [];
32
+ push;
33
+ migrationDir;
34
+ pushDestructive;
35
+ get raw() {
36
+ return this._rawDb;
37
+ }
38
+ get db() {
39
+ return this._db;
40
+ }
41
+ constructor(path2, options) {
42
+ super();
43
+ this._rawDb = new Database(path2);
44
+ this._db = new Kysely({
45
+ dialect: new SqliteDialect({
46
+ database: this._rawDb
47
+ })
48
+ });
49
+ this.push = options?.push ?? true;
50
+ this.pushDestructive = options?.pushDestructive ?? false;
51
+ this.migrationDir = options?.migrationDir ?? "./migrations";
52
+ }
53
+ async connect() {}
54
+ async disconnect() {
55
+ await this._db.destroy();
56
+ }
57
+ async unsafe(query, params) {
58
+ const compiled = CompiledQuery.raw(query, params || []);
59
+ const result = await this._db.executeQuery(compiled);
60
+ return result.rows;
61
+ }
62
+ async coerceData(collection, data) {
63
+ const colDef = this._collections.find((c) => c.slug === collection);
64
+ if (!colDef)
65
+ return data;
66
+ const result = { ...data };
67
+ const allFields = flattenFields(colDef.fields);
68
+ for (const field of allFields) {
69
+ const colName = toSnakeCase(field.name);
70
+ if (!(colName in result))
71
+ continue;
72
+ const value = result[colName];
73
+ if (value === undefined || value === null)
74
+ continue;
75
+ switch (field.type) {
76
+ case "boolean":
77
+ result[colName] = value ? 1 : 0;
78
+ break;
79
+ case "number":
80
+ result[colName] = Number(value);
81
+ break;
82
+ case "date":
83
+ if (value instanceof Date) {
84
+ result[colName] = value.toISOString();
85
+ } else if (typeof value === "string") {
86
+ result[colName] = new Date(value).toISOString();
87
+ }
88
+ break;
89
+ case "richtext":
90
+ case "json":
91
+ case "file":
92
+ if (typeof value === "object") {
93
+ result[colName] = JSON.stringify(value);
94
+ }
95
+ break;
96
+ }
97
+ }
98
+ return result;
99
+ }
100
+ async count(collection, query) {
101
+ let qb = this._db.selectFrom(collection).select((eb) => eb.fn.count("id").as("count"));
102
+ if (query && Object.keys(query).length > 0) {
103
+ qb = qb.where((eb) => buildKyselyWhere(eb, query) || eb.val(true));
104
+ }
105
+ const result = await qb.executeTakeFirst();
106
+ return Number(result?.count || 0);
107
+ }
108
+ async create(collection, data) {
109
+ return this._db.transaction().execute(async (tx) => {
110
+ const colDef = this._collections.find((c) => c.slug === collection);
111
+ const jsonFields = colDef?.fields.filter((f) => f.name && (["richtext", "json", "file"].includes(f.type) || f.localized)).map((f) => f.name) || [];
112
+ const flatData = flattenPayload(data, "", jsonFields);
113
+ const relationalFields = getRelationalFields(colDef?.fields || []);
114
+ const hasManyData = {};
115
+ const blocksData = {};
116
+ for (const field of relationalFields) {
117
+ const key = field.name;
118
+ if (Array.isArray(flatData[key])) {
119
+ if (field.type === "relationship" && "hasMany" in field && field.hasMany) {
120
+ hasManyData[key] = flatData[key];
121
+ } else if (field.type === "blocks") {
122
+ blocksData[key] = flatData[key];
123
+ }
124
+ delete flatData[key];
125
+ }
126
+ }
127
+ if (!flatData.id)
128
+ flatData.id = crypto.randomUUID();
129
+ const dbFields = flattenFields(colDef?.fields || []);
130
+ const validCols = new Set(dbFields.map((f) => toSnakeCase(f.name)));
131
+ validCols.add("id");
132
+ const ts = colDef?.timestamps !== false;
133
+ if (ts) {
134
+ const config = typeof colDef?.timestamps === "object" ? colDef.timestamps : {};
135
+ const updatedField = toSnakeCase(config.updatedAt || "updatedAt");
136
+ const createdField = toSnakeCase(config.createdAt || "createdAt");
137
+ validCols.add(createdField);
138
+ validCols.add(updatedField);
139
+ if (!flatData[createdField])
140
+ flatData[createdField] = new Date().toISOString();
141
+ if (!flatData[updatedField])
142
+ flatData[updatedField] = new Date().toISOString();
143
+ }
144
+ const filteredData = {};
145
+ for (const col of Object.keys(flatData)) {
146
+ if (validCols.has(col)) {
147
+ filteredData[col] = flatData[col];
148
+ }
149
+ }
150
+ const coercedData = await this.coerceData(collection, filteredData);
151
+ await tx.insertInto(collection).values(coercedData).execute();
152
+ for (const [key, values] of Object.entries(hasManyData)) {
153
+ const joinTableName = `${collection}_${toSnakeCase(key)}_relations`.toLowerCase();
154
+ if (values.length > 0) {
155
+ const joinData = values.map((val, idx) => {
156
+ const tId = typeof val === "object" ? val.id : val;
157
+ return { id: crypto.randomUUID(), source_id: flatData.id, target_id: tId, order: idx };
158
+ });
159
+ await tx.insertInto(joinTableName).values(joinData).execute();
160
+ }
161
+ }
162
+ for (const [key, blocks] of Object.entries(blocksData)) {
163
+ for (let i = 0;i < blocks.length; i++) {
164
+ const block = blocks[i];
165
+ if (!block.blockType)
166
+ continue;
167
+ const blockTableName = `${collection}_${toSnakeCase(key)}_${toSnakeCase(block.blockType)}`.toLowerCase();
168
+ const bId = block.id || crypto.randomUUID();
169
+ const blockDef = relationalFields.find((f) => f.name === key && f.type === "blocks");
170
+ const blockConfig = blockDef?.blocks?.find((b) => b.slug === block.blockType);
171
+ const blockJsonFields = blockConfig?.fields.filter((f) => ["richtext", "json", "file"].includes(f.type)).map((f) => f.name) || [];
172
+ const blockFlatData = flattenPayload({ ...block, id: bId }, "", blockJsonFields);
173
+ for (const f of blockJsonFields) {
174
+ if (blockFlatData[f] && typeof blockFlatData[f] === "object") {
175
+ blockFlatData[f] = JSON.stringify(blockFlatData[f]);
176
+ }
177
+ }
178
+ delete blockFlatData.blockType;
179
+ const coercedBlockData = await this.coerceData(blockTableName, {
180
+ ...blockFlatData,
181
+ _parent_id: flatData.id,
182
+ _order: i,
183
+ block_type: block.blockType
184
+ });
185
+ await tx.insertInto(blockTableName).values(coercedBlockData).execute();
186
+ }
187
+ }
188
+ return this.findOne(collection, { id: flatData.id }, tx);
189
+ });
190
+ }
191
+ async findOne(collection, query, tx) {
192
+ const executor = tx || this._db;
193
+ let qb = executor.selectFrom(collection).selectAll();
194
+ if (query && Object.keys(query).length > 0) {
195
+ qb = qb.where((eb) => buildKyselyWhere(eb, query) || eb.val(true));
196
+ }
197
+ const row = await qb.executeTakeFirst();
198
+ if (!row)
199
+ return null;
200
+ const unflattened = unflattenRow(row);
201
+ const colDef = this._collections.find((c) => c.slug === collection);
202
+ if (colDef) {
203
+ const relationalFields = getRelationalFields(colDef.fields);
204
+ for (const field of relationalFields) {
205
+ if (!field.name)
206
+ continue;
207
+ const snakeName = toSnakeCase(field.name);
208
+ if (field.type === "relationship" && "hasMany" in field && field.hasMany) {
209
+ const joinTableName = `${collection}_${snakeName}_relations`.toLowerCase();
210
+ try {
211
+ const relations = await executor.selectFrom(joinTableName).selectAll().where("source_id", "=", row.id).orderBy("order", "asc").execute();
212
+ const parts = field.name.split("__");
213
+ let current = unflattened;
214
+ for (let i = 0;i < parts.length - 1; i++) {
215
+ if (!current[parts[i]])
216
+ current[parts[i]] = {};
217
+ current = current[parts[i]];
218
+ }
219
+ current[parts[parts.length - 1]] = relations.map((r) => r.target_id);
220
+ } catch (e) {}
221
+ } else if (field.type === "blocks" && field.blocks) {
222
+ const blockData = [];
223
+ for (const b of field.blocks) {
224
+ const blockTableName = `${collection}_${snakeName}_${toSnakeCase(b.slug)}`.toLowerCase();
225
+ try {
226
+ const blocks = await executor.selectFrom(blockTableName).selectAll().where("_parent_id", "=", row.id).execute();
227
+ for (const blk of blocks) {
228
+ const uf = unflattenRow(blk);
229
+ uf.blockType = blk.block_type;
230
+ blockData.push(uf);
231
+ }
232
+ } catch (e) {}
233
+ }
234
+ blockData.sort((a, b) => a._order - b._order);
235
+ blockData.forEach((b) => {
236
+ delete b._order;
237
+ delete b._parent_id;
238
+ });
239
+ const parts = field.name.split("__");
240
+ let current = unflattened;
241
+ for (let i = 0;i < parts.length - 1; i++) {
242
+ if (!current[parts[i]])
243
+ current[parts[i]] = {};
244
+ current = current[parts[i]];
245
+ }
246
+ current[parts[parts.length - 1]] = blockData;
247
+ }
248
+ }
249
+ }
250
+ return unflattened;
251
+ }
252
+ async find(collection, query, options) {
253
+ const page = options?.page || 1;
254
+ const limit = options?.limit || 10;
255
+ const offset = (page - 1) * limit;
256
+ const total = await this.count(collection, query);
257
+ let qb = this._db.selectFrom(collection).selectAll().limit(limit).offset(offset);
258
+ if (query && Object.keys(query).length > 0) {
259
+ qb = qb.where((eb) => buildKyselyWhere(eb, query) || eb.val(true));
260
+ }
261
+ if (options?.sort) {
262
+ const [col, dir] = (options.sort ?? "").split(":");
263
+ if (col) {
264
+ qb = qb.orderBy(col, dir === "desc" ? "desc" : "asc");
265
+ }
266
+ } else {
267
+ qb = qb.orderBy("created_at", "desc");
268
+ }
269
+ const rows = await qb.execute();
270
+ const docs = await Promise.all(rows.map((row) => this.findOne(collection, { id: row.id })));
271
+ const totalPages = Math.ceil(total / limit);
272
+ return {
273
+ docs: docs.filter(Boolean),
274
+ totalDocs: total,
275
+ limit,
276
+ totalPages,
277
+ page,
278
+ pagingCounter: offset + 1,
279
+ hasNextPage: page * limit < total,
280
+ hasPrevPage: page > 1,
281
+ prevPage: page > 1 ? page - 1 : null,
282
+ nextPage: page < totalPages ? page + 1 : null
283
+ };
284
+ }
285
+ async update(collection, query, data) {
286
+ return this._db.transaction().execute(async (tx) => {
287
+ let normalizedQuery = query;
288
+ if (typeof query !== "object" || query === null) {
289
+ normalizedQuery = { id: query };
290
+ }
291
+ const current = await this.findOne(collection, normalizedQuery, tx);
292
+ if (!current)
293
+ throw new Error("Document not found");
294
+ const colDef = this._collections.find((c) => c.slug === collection);
295
+ const jsonFields = colDef?.fields.filter((f) => f.name && (["richtext", "json", "file"].includes(f.type) || f.localized)).map((f) => f.name) || [];
296
+ const flatData = flattenPayload(data, "", jsonFields);
297
+ const relationalFields = getRelationalFields(colDef?.fields || []);
298
+ const hasManyData = {};
299
+ const blocksData = {};
300
+ for (const field of relationalFields) {
301
+ const key = field.name;
302
+ if (Array.isArray(flatData[key])) {
303
+ if (field.type === "relationship" && "hasMany" in field && field.hasMany) {
304
+ hasManyData[key] = flatData[key];
305
+ } else if (field.type === "blocks") {
306
+ blocksData[key] = flatData[key];
307
+ }
308
+ delete flatData[key];
309
+ }
310
+ }
311
+ const ts = colDef?.timestamps !== false;
312
+ if (ts) {
313
+ const config = typeof colDef?.timestamps === "object" ? colDef.timestamps : {};
314
+ const updatedField = toSnakeCase(config.updatedAt || "updatedAt");
315
+ flatData[updatedField] = new Date().toISOString();
316
+ }
317
+ if (Object.keys(flatData).length > 0) {
318
+ const coercedData = await this.coerceData(collection, flatData);
319
+ await tx.updateTable(collection).set(coercedData).where("id", "=", current.id).execute();
320
+ }
321
+ for (const [key, values] of Object.entries(hasManyData)) {
322
+ const joinTableName = `${collection}_${toSnakeCase(key)}_relations`.toLowerCase();
323
+ await tx.deleteFrom(joinTableName).where("source_id", "=", current.id).execute();
324
+ if (values.length > 0) {
325
+ const joinData = values.map((val, idx) => {
326
+ const tId = typeof val === "object" ? val.id : val;
327
+ return { id: crypto.randomUUID(), source_id: current.id, target_id: tId, order: idx };
328
+ });
329
+ await tx.insertInto(joinTableName).values(joinData).execute();
330
+ }
331
+ }
332
+ for (const [key, blocks] of Object.entries(blocksData)) {
333
+ const fieldDef = relationalFields.find((f) => f.name === key && f.type === "blocks");
334
+ if (fieldDef?.type === "blocks" && fieldDef.blocks) {
335
+ for (const b of fieldDef.blocks) {
336
+ const blockTableName = `${collection}_${toSnakeCase(key)}_${toSnakeCase(b.slug)}`.toLowerCase();
337
+ try {
338
+ await tx.deleteFrom(blockTableName).where("_parent_id", "=", current.id).execute();
339
+ } catch (e) {}
340
+ }
341
+ }
342
+ for (let i = 0;i < blocks.length; i++) {
343
+ const block = blocks[i];
344
+ if (!block.blockType)
345
+ continue;
346
+ const blockTableName = `${collection}_${toSnakeCase(key)}_${toSnakeCase(block.blockType)}`.toLowerCase();
347
+ const bId = block.id || crypto.randomUUID();
348
+ const blockConfig = fieldDef?.blocks?.find((b) => b.slug === block.blockType);
349
+ const blockJsonFields = blockConfig?.fields.filter((f) => ["richtext", "json", "file"].includes(f.type)).map((f) => f.name) || [];
350
+ const blockFlatData = flattenPayload({ ...block, id: bId }, "", blockJsonFields);
351
+ for (const f of blockJsonFields) {
352
+ if (blockFlatData[f] && typeof blockFlatData[f] === "object") {
353
+ blockFlatData[f] = JSON.stringify(blockFlatData[f]);
354
+ }
355
+ }
356
+ delete blockFlatData.blockType;
357
+ const coercedBlockData = await this.coerceData(blockTableName, {
358
+ ...blockFlatData,
359
+ _parent_id: current.id,
360
+ _order: i,
361
+ block_type: block.blockType
362
+ });
363
+ await tx.insertInto(blockTableName).values(coercedBlockData).execute();
364
+ }
365
+ }
366
+ return this.findOne(collection, { id: current.id }, tx);
367
+ });
368
+ }
369
+ async delete(collection, query) {
370
+ let normalizedQuery = query;
371
+ if (typeof query !== "object" || query === null) {
372
+ normalizedQuery = { id: query };
373
+ }
374
+ const current = await this.findOne(collection, normalizedQuery);
375
+ if (!current)
376
+ return false;
377
+ await this._db.transaction().execute(async (tx) => {
378
+ const colDef = this._collections.find((c) => c.slug === collection);
379
+ if (colDef) {
380
+ const relationalFields = getRelationalFields(colDef.fields);
381
+ for (const field of relationalFields) {
382
+ if (!field.name)
383
+ continue;
384
+ const snakeName = toSnakeCase(field.name);
385
+ if (field.type === "relationship" && "hasMany" in field && field.hasMany) {
386
+ const joinTableName = `${collection}_${snakeName}_relations`.toLowerCase();
387
+ try {
388
+ await tx.deleteFrom(joinTableName).where("source_id", "=", current.id).execute();
389
+ } catch (e) {}
390
+ } else if (field.type === "blocks" && field.blocks) {
391
+ for (const b of field.blocks) {
392
+ const blockTableName = `${collection}_${snakeName}_${toSnakeCase(b.slug)}`.toLowerCase();
393
+ try {
394
+ await tx.deleteFrom(blockTableName).where("_parent_id", "=", current.id).execute();
395
+ } catch (e) {}
396
+ }
397
+ }
398
+ }
399
+ }
400
+ await tx.deleteFrom(collection).where("id", "=", current.id).execute();
401
+ });
402
+ return true;
403
+ }
404
+ async updateMany(collection, query, data) {
405
+ return this._db.transaction().execute(async (tx) => {
406
+ let qb = tx.updateTable(collection);
407
+ if (query && Object.keys(query).length > 0) {
408
+ qb = qb.where((eb) => buildKyselyWhere(eb, query) || eb.val(true));
409
+ }
410
+ const colDef = this._collections.find((c) => c.slug === collection);
411
+ const jsonFields = colDef?.fields.filter((f) => f.name && (["richtext", "json", "file"].includes(f.type) || f.localized)).map((f) => f.name) || [];
412
+ const flatData = flattenPayload(data, "", jsonFields);
413
+ for (const key in flatData) {
414
+ if (Array.isArray(flatData[key])) {
415
+ delete flatData[key];
416
+ }
417
+ }
418
+ const ts = colDef?.timestamps !== false;
419
+ if (ts) {
420
+ const config = typeof colDef?.timestamps === "object" ? colDef.timestamps : {};
421
+ const updatedField = toSnakeCase(config.updatedAt || "updatedAt");
422
+ flatData[updatedField] = new Date().toISOString();
423
+ }
424
+ if (Object.keys(flatData).length > 0) {
425
+ const coercedData = await this.coerceData(collection, flatData);
426
+ const result = await qb.set(coercedData).executeTakeFirst();
427
+ return Number(result.numUpdatedRows || 0);
428
+ }
429
+ return 0;
430
+ });
431
+ }
432
+ async deleteMany(collection, query) {
433
+ return this._db.transaction().execute(async (tx) => {
434
+ let selectQb = tx.selectFrom(collection).select("id");
435
+ if (query && Object.keys(query).length > 0) {
436
+ selectQb = selectQb.where((eb) => buildKyselyWhere(eb, query) || eb.val(true));
437
+ }
438
+ const docs = await selectQb.execute();
439
+ if (docs.length === 0)
440
+ return 0;
441
+ const ids = docs.map((d) => d.id);
442
+ const colDef = this._collections.find((c) => c.slug === collection);
443
+ if (colDef) {
444
+ const relationalFields = getRelationalFields(colDef.fields);
445
+ for (const field of relationalFields) {
446
+ if (!field.name)
447
+ continue;
448
+ const snakeName = toSnakeCase(field.name);
449
+ if (field.type === "relationship" && "hasMany" in field && field.hasMany) {
450
+ const joinTableName = `${collection}_${snakeName}_relations`.toLowerCase();
451
+ try {
452
+ await tx.deleteFrom(joinTableName).where("source_id", "in", ids).execute();
453
+ } catch (e) {}
454
+ } else if (field.type === "blocks" && field.blocks) {
455
+ for (const b of field.blocks) {
456
+ const blockTableName = `${collection}_${snakeName}_${toSnakeCase(b.slug)}`.toLowerCase();
457
+ try {
458
+ await tx.deleteFrom(blockTableName).where("_parent_id", "in", ids).execute();
459
+ } catch (e) {}
460
+ }
461
+ }
462
+ }
463
+ }
464
+ const result = await tx.deleteFrom(collection).where("id", "in", ids).executeTakeFirst();
465
+ return Number(result.numDeletedRows || 0);
466
+ });
467
+ }
468
+ async findGlobal(slug) {
469
+ const row = await this._db.selectFrom(slug).selectAll().limit(1).executeTakeFirst();
470
+ return row ? unflattenRow(row) : null;
471
+ }
472
+ async updateGlobal(slug, data) {
473
+ const existing = await this.findGlobal(slug);
474
+ const flatData = flattenPayload(data);
475
+ const globalDef = this._globals.find((g) => g.slug === slug);
476
+ const ts = globalDef?.timestamps !== false;
477
+ if (ts) {
478
+ const config = typeof globalDef?.timestamps === "object" ? globalDef.timestamps : {};
479
+ const updatedField = toSnakeCase(config.updatedAt || "updatedAt");
480
+ flatData[updatedField] = new Date().toISOString();
481
+ }
482
+ if (!existing) {
483
+ if (!flatData.id)
484
+ flatData.id = "global";
485
+ if (ts) {
486
+ const config = typeof globalDef?.timestamps === "object" ? globalDef.timestamps : {};
487
+ const createdField = toSnakeCase(config.createdAt || "createdAt");
488
+ if (!flatData[createdField])
489
+ flatData[createdField] = flatData[toSnakeCase(config.updatedAt || "updatedAt")];
490
+ }
491
+ await this._db.insertInto(slug).values(flatData).execute();
492
+ } else {
493
+ await this._db.updateTable(slug).set(flatData).where("id", "=", existing.id).execute();
494
+ }
495
+ return this.findGlobal(slug);
496
+ }
497
+ async runMigrations() {
498
+ const migrator = new Migrator({
499
+ db: this._db,
500
+ provider: new FileMigrationProvider({
501
+ fs,
502
+ path,
503
+ migrationFolder: path.resolve(process.cwd(), this.migrationDir)
504
+ })
505
+ });
506
+ const { error, results } = await migrator.migrateToLatest();
507
+ results?.forEach((it) => {
508
+ if (it.status === "Success") {
509
+ logger.success(`\uD83D\uDE80 Migration "${it.migrationName}" was executed successfully`);
510
+ } else if (it.status === "Error") {
511
+ logger.error(`❌ Migration "${it.migrationName}" failed`);
512
+ }
513
+ });
514
+ if (error) {
515
+ throw error;
516
+ }
517
+ }
518
+ async migrate(collections, globals = []) {
519
+ this._collections = collections;
520
+ this._globals = globals;
521
+ if (this.push) {
522
+ await pushSchema(this._db, "sqlite", collections, globals, {
523
+ pushDestructive: this.pushDestructive
524
+ });
525
+ }
526
+ }
527
+ }
528
+ function createSQLiteAdapter(path2, options) {
529
+ return new SQLiteAdapter(path2, options);
530
+ }
531
+ export {
532
+ createSQLiteAdapter,
533
+ SQLiteAdapter
534
+ };
@@ -0,0 +1,20 @@
1
+ import {
2
+ OpacaError,
3
+ createClient
4
+ } from "../chunk-d3ffeqp9.js";
5
+ import {
6
+ defineConfig
7
+ } from "../chunk-zvwb67nd.js";
8
+ import {
9
+ createAuth,
10
+ sanitizeConfig
11
+ } from "../chunk-dy5t83hr.js";
12
+ import"../chunk-ybbbqj63.js";
13
+ import"../chunk-8sqjbsgt.js";
14
+ export {
15
+ sanitizeConfig,
16
+ defineConfig,
17
+ createClient,
18
+ createAuth,
19
+ OpacaError
20
+ };
@@ -0,0 +1,36 @@
1
+ import {
2
+ createAPIRouter
3
+ } from "../../chunk-hmhcense.js";
4
+ import"../../chunk-dy5t83hr.js";
5
+ import"../../chunk-62ev8gnc.js";
6
+ import"../../chunk-cvdd4eqh.js";
7
+ import"../../chunk-ybbbqj63.js";
8
+ import"../../chunk-8sqjbsgt.js";
9
+
10
+ // src/runtimes/bun.ts
11
+ import { Hono } from "hono";
12
+ function createBunHandler(config, options) {
13
+ const app = new Hono;
14
+ const apiRouter = createAPIRouter(config);
15
+ app.route("/api", apiRouter);
16
+ const init = async () => {
17
+ console.log("\uD83D\uDE80 Initializing OpacaCMS (Bun runtime)...");
18
+ if (config.db) {
19
+ await config.db.connect();
20
+ console.log(`\uD83D\uDCE6 Database "${config.db.name}" connected`);
21
+ await config.db.migrate(config.collections);
22
+ console.log("✅ Migrations completed");
23
+ }
24
+ const port = options?.port || 3000;
25
+ Bun.serve({
26
+ fetch: app.fetch,
27
+ port
28
+ });
29
+ console.log(`Listening on http://localhost:${port}`);
30
+ return app;
31
+ };
32
+ return { app, init };
33
+ }
34
+ export {
35
+ createBunHandler
36
+ };
@@ -0,0 +1,29 @@
1
+ import {
2
+ createAPIRouter
3
+ } from "../../chunk-hmhcense.js";
4
+ import"../../chunk-dy5t83hr.js";
5
+ import"../../chunk-62ev8gnc.js";
6
+ import"../../chunk-cvdd4eqh.js";
7
+ import"../../chunk-ybbbqj63.js";
8
+ import"../../chunk-8sqjbsgt.js";
9
+
10
+ // src/runtimes/cloudflare-workers.ts
11
+ import { Hono } from "hono";
12
+ var cachedApp;
13
+ function createCloudflareWorkersHandler(configOrFactory) {
14
+ const app = new Hono;
15
+ app.use("/api/*", async (c, next) => {
16
+ if (cachedApp)
17
+ return cachedApp.fetch(c.req.raw, c.env, c.executionCtx);
18
+ const config = typeof configOrFactory === "function" ? await configOrFactory(c.env, c.req.raw) : configOrFactory;
19
+ const apiRouter = createAPIRouter(config);
20
+ const innerApp = new Hono;
21
+ innerApp.route("/", apiRouter);
22
+ cachedApp = innerApp;
23
+ return cachedApp.fetch(c.req.raw, c.env, c.executionCtx);
24
+ });
25
+ return app;
26
+ }
27
+ export {
28
+ createCloudflareWorkersHandler
29
+ };
@@ -0,0 +1,26 @@
1
+ import {
2
+ createAPIRouter
3
+ } from "../../chunk-hmhcense.js";
4
+ import"../../chunk-dy5t83hr.js";
5
+ import"../../chunk-62ev8gnc.js";
6
+ import"../../chunk-cvdd4eqh.js";
7
+ import"../../chunk-ybbbqj63.js";
8
+ import"../../chunk-8sqjbsgt.js";
9
+
10
+ // src/runtimes/next.ts
11
+ import { handle } from "hono/vercel";
12
+ function createNextHandler(config) {
13
+ const app = createAPIRouter(config);
14
+ const handler = handle(app);
15
+ return {
16
+ GET: handler,
17
+ POST: handler,
18
+ PUT: handler,
19
+ DELETE: handler,
20
+ PATCH: handler,
21
+ OPTIONS: handler
22
+ };
23
+ }
24
+ export {
25
+ createNextHandler
26
+ };
@@ -0,0 +1,38 @@
1
+ import {
2
+ createAPIRouter
3
+ } from "../../chunk-hmhcense.js";
4
+ import"../../chunk-dy5t83hr.js";
5
+ import"../../chunk-62ev8gnc.js";
6
+ import"../../chunk-cvdd4eqh.js";
7
+ import"../../chunk-ybbbqj63.js";
8
+ import"../../chunk-8sqjbsgt.js";
9
+
10
+ // src/runtimes/node.ts
11
+ import { serve } from "@hono/node-server";
12
+ import { Hono } from "hono";
13
+ function createNodeHandler(config, options) {
14
+ const app = new Hono;
15
+ const apiRouter = createAPIRouter(config);
16
+ app.route("/api", apiRouter);
17
+ const init = async () => {
18
+ console.log("\uD83D\uDE80 Initializing OpacaCMS (Node.js runtime)...");
19
+ if (config.db) {
20
+ await config.db.connect();
21
+ console.log(`\uD83D\uDCE6 Database "${config.db.name}" connected`);
22
+ await config.db.migrate(config.collections);
23
+ console.log("✅ Migrations completed");
24
+ }
25
+ const port = options?.port || 3000;
26
+ serve({
27
+ fetch: app.fetch,
28
+ port
29
+ }, (info) => {
30
+ console.log(`Listening on http://localhost:${info.port}`);
31
+ });
32
+ return app;
33
+ };
34
+ return { app, init };
35
+ }
36
+ export {
37
+ createNodeHandler
38
+ };