@beechcms/api 0.6.0-preview.2 → 0.6.0-preview.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (375) hide show
  1. package/README.md +4 -4
  2. package/assets/dashboard/assets/chart-Cws4Yj6K.js +39 -0
  3. package/assets/dashboard/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
  4. package/assets/dashboard/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
  5. package/assets/dashboard/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
  6. package/assets/dashboard/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
  7. package/assets/dashboard/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
  8. package/assets/dashboard/assets/index-BjPpppHe.css +1 -0
  9. package/assets/dashboard/assets/index-CrW-zhkA.js +642 -0
  10. package/assets/dashboard/assets/lora-cyrillic-ext-wght-normal-YcVxMP-u.woff2 +0 -0
  11. package/assets/dashboard/assets/lora-cyrillic-wght-normal-UWPuZLjM.woff2 +0 -0
  12. package/assets/dashboard/assets/lora-latin-ext-wght-normal-C2Wlntb9.woff2 +0 -0
  13. package/assets/dashboard/assets/lora-latin-wght-normal-BiLcIKcI.woff2 +0 -0
  14. package/assets/dashboard/assets/lora-math-wght-normal-sOy7rEfW.woff2 +0 -0
  15. package/assets/dashboard/assets/lora-symbols-wght-normal-DQ5VrUkH.woff2 +0 -0
  16. package/assets/dashboard/assets/lora-vietnamese-wght-normal-CfJ7gtf3.woff2 +0 -0
  17. package/assets/dashboard/assets/pie-chart-recharts-CAxoDQp2.js +1 -0
  18. package/assets/dashboard/assets/timeseries-chart-recharts-CixDW-LM.js +1 -0
  19. package/assets/dashboard/index.html +2 -2
  20. package/dist/auth/__fixtures__/in-memory-hash-provider.d.ts +5 -0
  21. package/dist/auth/__fixtures__/static-token-service.d.ts +6 -0
  22. package/dist/auth/bcrypt-hash-provider.d.ts +8 -0
  23. package/dist/auth/constants.d.ts +10 -0
  24. package/dist/auth/jose-token-service.d.ts +14 -0
  25. package/dist/auth/login.d.ts +32 -0
  26. package/dist/auth/refresh.d.ts +1 -0
  27. package/dist/factory.d.ts +39 -0
  28. package/dist/features/automations/action-executors/create-entry.executor.d.ts +7 -0
  29. package/dist/features/automations/action-executors/edit-field.executor.d.ts +7 -0
  30. package/dist/features/automations/action-executors/index.d.ts +13 -0
  31. package/dist/features/automations/action-executors/send-mail.executor.d.ts +7 -0
  32. package/dist/features/automations/action-executors/set-variable.executor.d.ts +15 -0
  33. package/dist/features/automations/action-executors/webhook.executor.d.ts +7 -0
  34. package/dist/features/automations/automation-runner.d.ts +13 -0
  35. package/dist/features/automations/automation-runner.utils.d.ts +3 -0
  36. package/dist/features/automations/automations.handler.d.ts +7 -0
  37. package/dist/features/automations/automations.schema.d.ts +191 -0
  38. package/dist/features/automations/context-resolver.d.ts +8 -0
  39. package/dist/features/automations/cron-runner.d.ts +9 -0
  40. package/dist/features/automations/cron-runner.utils.d.ts +1 -0
  41. package/dist/features/automations/filter-translation.d.ts +9 -0
  42. package/dist/features/automations/index.d.ts +7 -0
  43. package/dist/features/automations/template-grammar.d.ts +73 -0
  44. package/dist/features/automations/var-access-resolver.d.ts +6 -0
  45. package/dist/features/automations/when-evaluator.d.ts +3 -0
  46. package/dist/features/automations/when-pushdown.d.ts +2 -0
  47. package/dist/features/backrefs/backrefs.handler.d.ts +3 -0
  48. package/dist/features/backrefs/d1-backref.repository.d.ts +17 -0
  49. package/dist/features/backrefs/index.d.ts +1 -0
  50. package/dist/features/content/constants.d.ts +12 -0
  51. package/dist/features/content/handlers/bulk.handler.d.ts +3 -0
  52. package/dist/features/content/handlers/create.d.ts +3 -0
  53. package/dist/features/content/handlers/delete.d.ts +3 -0
  54. package/dist/features/content/handlers/facets.d.ts +3 -0
  55. package/dist/features/content/handlers/get.d.ts +4 -0
  56. package/dist/features/content/handlers/helpers.d.ts +12 -0
  57. package/dist/features/content/handlers/list.d.ts +3 -0
  58. package/dist/features/content/handlers/update.d.ts +3 -0
  59. package/dist/features/content/index.d.ts +4 -0
  60. package/dist/features/dashboard-layout/dashboard-layout.handler.d.ts +7 -0
  61. package/dist/features/dashboard-layout/index.d.ts +1 -0
  62. package/dist/features/draft/draft.handler.d.ts +4 -0
  63. package/dist/features/draft/draft.middleware.d.ts +9 -0
  64. package/dist/features/draft/index.d.ts +1 -0
  65. package/{src/features/email/email.provider.ts → dist/features/email/email.provider.d.ts} +19 -24
  66. package/dist/features/email/email.service.d.ts +13 -0
  67. package/dist/features/email/email.types.d.ts +94 -0
  68. package/{src/features/email/index.ts → dist/features/email/index.d.ts} +3 -16
  69. package/dist/features/email/providers/resend.d.ts +36 -0
  70. package/dist/features/email/providers/smtp.d.ts +11 -0
  71. package/dist/features/email/templates/automation-mail.d.ts +8 -0
  72. package/dist/features/email/templates/password-changed.d.ts +15 -0
  73. package/dist/features/email/templates/password-reset.d.ts +18 -0
  74. package/dist/features/email/templates/shell.d.ts +58 -0
  75. package/dist/features/notifications/index.d.ts +1 -0
  76. package/dist/features/notifications/notifications.handler.d.ts +15 -0
  77. package/dist/features/password-reset/index.d.ts +6 -0
  78. package/dist/features/password-reset/request.d.ts +10 -0
  79. package/dist/features/password-reset/reset.d.ts +9 -0
  80. package/dist/features/rotate-field/index.d.ts +1 -0
  81. package/dist/features/rotate-field/rotate-field.handler.d.ts +7 -0
  82. package/dist/features/rotate-field/rotate-field.schema.d.ts +11 -0
  83. package/dist/features/schema/schema.handler.d.ts +7 -0
  84. package/dist/features/seeds/index.d.ts +1 -0
  85. package/dist/features/seeds/seeds.handler.d.ts +6 -0
  86. package/dist/features/settings/settings.handler.d.ts +7 -0
  87. package/dist/features/setup/index.d.ts +7 -0
  88. package/dist/features/stats/index.d.ts +1 -0
  89. package/dist/features/stats/stats.handler.d.ts +7 -0
  90. package/dist/features/webhooks/index.d.ts +3 -0
  91. package/dist/index.d.ts +6 -0
  92. package/dist/index.js +9666 -0
  93. package/dist/media-utils.d.ts +25 -0
  94. package/dist/middleware/auth-providers.middleware.d.ts +8 -0
  95. package/dist/middleware/observability.middleware.d.ts +20 -0
  96. package/dist/middleware/rate-limit.middleware.d.ts +9 -0
  97. package/dist/middleware/repository.middleware.d.ts +34 -0
  98. package/dist/middleware/seed-registry.middleware.d.ts +10 -0
  99. package/dist/middleware/storage.middleware.d.ts +7 -0
  100. package/dist/middleware.d.ts +11 -0
  101. package/dist/public/access-policy.d.ts +12 -0
  102. package/dist/public/api-key-middleware.d.ts +6 -0
  103. package/dist/public/cache-utils.d.ts +10 -0
  104. package/dist/public/entry-projection.d.ts +2 -0
  105. package/dist/public/idempotency.d.ts +9 -0
  106. package/dist/public/index.d.ts +11 -0
  107. package/dist/public/problem-details.d.ts +31 -0
  108. package/dist/public/public-add.d.ts +3 -0
  109. package/dist/public/public-edit.d.ts +5 -0
  110. package/dist/public/public-errors.d.ts +13 -0
  111. package/dist/public/public-read.d.ts +3 -0
  112. package/dist/public/public-routes.d.ts +3 -0
  113. package/dist/public/query-builder.d.ts +28 -0
  114. package/dist/public/rate-limit-middleware.d.ts +3 -0
  115. package/dist/public/read-list.d.ts +26 -0
  116. package/dist/public/read-single.d.ts +22 -0
  117. package/dist/public/response-builder.d.ts +22 -0
  118. package/dist/public/sanitize.d.ts +23 -0
  119. package/{src/public/slug-utils.ts → dist/public/slug-utils.d.ts} +3 -10
  120. package/dist/rate-limit/cloudflare-rate-limiter.d.ts +6 -0
  121. package/dist/rate-limit/in-memory-rate-limiter.d.ts +7 -0
  122. package/dist/rate-limit/no-op-rate-limiter.d.ts +4 -0
  123. package/dist/search-utils.d.ts +54 -0
  124. package/dist/search.d.ts +6 -0
  125. package/dist/shared/apply-policies.d.ts +10 -0
  126. package/dist/shared/automations.repository.d1.d.ts +12 -0
  127. package/dist/shared/background-notification-service.d.ts +18 -0
  128. package/dist/shared/base.repository.d1.d.ts +18 -0
  129. package/dist/shared/content-utils.d.ts +21 -0
  130. package/dist/shared/content.repository.d1.d.ts +68 -0
  131. package/dist/shared/d1-activity-log.repository.d.ts +13 -0
  132. package/dist/shared/d1-activity-logger.d.ts +20 -0
  133. package/dist/shared/d1-analytics.repository.d.ts +20 -0
  134. package/dist/shared/d1-content-scan.repository.d.ts +7 -0
  135. package/dist/shared/d1-notification.repository.d.ts +17 -0
  136. package/dist/shared/d1-password-reset-token.repository.d.ts +10 -0
  137. package/dist/shared/d1-search.repository.d.ts +14 -0
  138. package/dist/shared/d1-session.repository.d.ts +12 -0
  139. package/dist/shared/d1-setup-checklist.repository.d.ts +12 -0
  140. package/dist/shared/d1-user.repository.d.ts +18 -0
  141. package/dist/shared/d1-widget.repository.d.ts +31 -0
  142. package/dist/shared/dashboard-layout.repository.d1.d.ts +9 -0
  143. package/dist/shared/demo-data-sql.d.ts +1 -0
  144. package/dist/shared/demo-data.repository.d1.d.ts +6 -0
  145. package/dist/shared/execution-context-scheduler.d.ts +6 -0
  146. package/dist/shared/fixed-clock.d.ts +13 -0
  147. package/dist/shared/fts-sync.d.ts +1 -0
  148. package/dist/shared/idempotency.repository.d1.d.ts +16 -0
  149. package/dist/shared/in-memory-activity-logger.d.ts +11 -0
  150. package/dist/shared/in-memory-notification-service.d.ts +11 -0
  151. package/dist/shared/in-memory-seed.repository.d.ts +18 -0
  152. package/dist/shared/media.repository.d1.d.ts +35 -0
  153. package/dist/shared/qstash-notification-service.d.ts +18 -0
  154. package/dist/shared/query-utils.d.ts +36 -0
  155. package/dist/shared/request-utils.d.ts +13 -0
  156. package/dist/shared/schema-mutator.d1.d.ts +12 -0
  157. package/dist/shared/seed-layout.repository.d1.d.ts +9 -0
  158. package/dist/shared/seed-registry-cache.d.ts +12 -0
  159. package/dist/shared/seed.repository.d1.d.ts +13 -0
  160. package/dist/shared/sequential-id-generator.d.ts +13 -0
  161. package/dist/shared/site-settings.repository.d1.d.ts +7 -0
  162. package/dist/shared/storage/factory.d.ts +8 -0
  163. package/dist/shared/storage/s3-bucket.d.ts +43 -0
  164. package/dist/shared/storage-utils.d.ts +7 -0
  165. package/dist/shared/system-stats.repository.d1.d.ts +25 -0
  166. package/dist/types.d.ts +85 -0
  167. package/dist/upload.d.ts +16 -0
  168. package/dist/widget.d.ts +7 -0
  169. package/package.json +27 -18
  170. package/assets/dashboard/assets/chart-BrJFdsGZ.js +0 -39
  171. package/assets/dashboard/assets/index-CIaoMxuB.css +0 -1
  172. package/assets/dashboard/assets/index-wTKgygsg.js +0 -636
  173. package/assets/dashboard/assets/pie-chart-recharts-BEaE1FOE.js +0 -1
  174. package/assets/dashboard/assets/timeseries-chart-recharts-DmWM6imF.js +0 -1
  175. package/src/auth/__fixtures__/in-memory-hash-provider.ts +0 -17
  176. package/src/auth/__fixtures__/static-token-service.ts +0 -22
  177. package/src/auth/bcrypt-hash-provider.ts +0 -24
  178. package/src/auth/constants.ts +0 -14
  179. package/src/auth/generate-refresh-token.test.ts +0 -23
  180. package/src/auth/hash-provider.test.ts +0 -55
  181. package/src/auth/jose-token-service.ts +0 -62
  182. package/src/auth/jwt-claims-passthrough.test.ts +0 -87
  183. package/src/auth/login.test.ts +0 -100
  184. package/src/auth/login.ts +0 -78
  185. package/src/auth/refresh.ts +0 -11
  186. package/src/auth/token-service.test.ts +0 -90
  187. package/src/factory.ts +0 -370
  188. package/src/features/automations/__tests__/action-executors.test.ts +0 -255
  189. package/src/features/automations/__tests__/automation-runner.test.ts +0 -196
  190. package/src/features/automations/__tests__/automation-runner.utils.test.ts +0 -60
  191. package/src/features/automations/__tests__/automations.handler.test.ts +0 -264
  192. package/src/features/automations/__tests__/automations.repository.test.ts +0 -163
  193. package/src/features/automations/__tests__/automations.schema.test.ts +0 -224
  194. package/src/features/automations/__tests__/context-resolver.test.ts +0 -126
  195. package/src/features/automations/__tests__/cron-runner.test.ts +0 -267
  196. package/src/features/automations/__tests__/cron-runner.utils.test.ts +0 -144
  197. package/src/features/automations/__tests__/set-variable.executor.test.ts +0 -383
  198. package/src/features/automations/__tests__/template-grammar.test.ts +0 -308
  199. package/src/features/automations/__tests__/webhook.executor.test.ts +0 -142
  200. package/src/features/automations/__tests__/when-evaluator.test.ts +0 -274
  201. package/src/features/automations/__tests__/when-pushdown.test.ts +0 -281
  202. package/src/features/automations/action-executors/create-entry.executor.ts +0 -27
  203. package/src/features/automations/action-executors/edit-field.executor.ts +0 -26
  204. package/src/features/automations/action-executors/index.ts +0 -37
  205. package/src/features/automations/action-executors/send-mail.executor.ts +0 -53
  206. package/src/features/automations/action-executors/set-variable.executor.ts +0 -159
  207. package/src/features/automations/action-executors/webhook.executor.ts +0 -67
  208. package/src/features/automations/automation-runner.ts +0 -85
  209. package/src/features/automations/automation-runner.utils.ts +0 -47
  210. package/src/features/automations/automations.handler.ts +0 -197
  211. package/src/features/automations/automations.schema.ts +0 -177
  212. package/src/features/automations/context-resolver.ts +0 -152
  213. package/src/features/automations/cron-runner.ts +0 -140
  214. package/src/features/automations/cron-runner.utils.ts +0 -44
  215. package/src/features/automations/filter-translation.ts +0 -46
  216. package/src/features/automations/index.ts +0 -16
  217. package/src/features/automations/template-grammar.ts +0 -245
  218. package/src/features/automations/var-access-resolver.ts +0 -140
  219. package/src/features/automations/when-evaluator.ts +0 -87
  220. package/src/features/automations/when-pushdown.ts +0 -57
  221. package/src/features/backrefs/__tests__/backrefs.handler.test.ts +0 -359
  222. package/src/features/backrefs/backrefs.handler.ts +0 -168
  223. package/src/features/backrefs/d1-backref.repository.ts +0 -84
  224. package/src/features/backrefs/index.ts +0 -5
  225. package/src/features/content/constants.ts +0 -16
  226. package/src/features/content/handlers/bulk.handler.ts +0 -185
  227. package/src/features/content/handlers/create.ts +0 -129
  228. package/src/features/content/handlers/delete.ts +0 -62
  229. package/src/features/content/handlers/facets.ts +0 -49
  230. package/src/features/content/handlers/get.ts +0 -120
  231. package/src/features/content/handlers/helpers.test.ts +0 -180
  232. package/src/features/content/handlers/helpers.ts +0 -93
  233. package/src/features/content/handlers/list.ts +0 -174
  234. package/src/features/content/handlers/update.ts +0 -174
  235. package/src/features/content/index.ts +0 -26
  236. package/src/features/dashboard-layout/__tests__/dashboard-layout.handler.test.ts +0 -388
  237. package/src/features/dashboard-layout/dashboard-layout.handler.ts +0 -206
  238. package/src/features/dashboard-layout/index.ts +0 -5
  239. package/src/features/draft/draft.handler.ts +0 -195
  240. package/src/features/draft/draft.middleware.ts +0 -66
  241. package/src/features/draft/index.ts +0 -5
  242. package/src/features/email/email.service.ts +0 -98
  243. package/src/features/email/email.types.ts +0 -119
  244. package/src/features/email/providers/resend.ts +0 -67
  245. package/src/features/email/providers/smtp.ts +0 -55
  246. package/src/features/email/templates/automation-mail.ts +0 -19
  247. package/src/features/email/templates/password-changed.ts +0 -63
  248. package/src/features/email/templates/password-reset.ts +0 -68
  249. package/src/features/email/templates/shell.ts +0 -96
  250. package/src/features/notifications/index.ts +0 -5
  251. package/src/features/notifications/notifications.handler.ts +0 -105
  252. package/src/features/password-reset/index.ts +0 -19
  253. package/src/features/password-reset/request.ts +0 -92
  254. package/src/features/password-reset/reset.ts +0 -102
  255. package/src/features/rotate-field/index.ts +0 -5
  256. package/src/features/rotate-field/rotate-field.handler.ts +0 -132
  257. package/src/features/rotate-field/rotate-field.schema.ts +0 -17
  258. package/src/features/schema/schema.handler.ts +0 -131
  259. package/src/features/seeds/index.ts +0 -5
  260. package/src/features/seeds/seeds.handler.test.ts +0 -1199
  261. package/src/features/seeds/seeds.handler.ts +0 -558
  262. package/src/features/settings/__tests__/settings.handler.test.ts +0 -555
  263. package/src/features/settings/settings.handler.ts +0 -392
  264. package/src/features/setup/index.ts +0 -288
  265. package/src/features/stats/index.ts +0 -5
  266. package/src/features/stats/stats.handler.ts +0 -420
  267. package/src/features/webhooks/index.ts +0 -63
  268. package/src/index.ts +0 -65
  269. package/src/media-utils.ts +0 -82
  270. package/src/middleware/auth-providers.middleware.test.ts +0 -85
  271. package/src/middleware/auth-providers.middleware.ts +0 -45
  272. package/src/middleware/observability.middleware.test.ts +0 -93
  273. package/src/middleware/observability.middleware.ts +0 -70
  274. package/src/middleware/rate-limit.middleware.ts +0 -45
  275. package/src/middleware/repository.middleware.ts +0 -117
  276. package/src/middleware/seed-registry.middleware.test.ts +0 -97
  277. package/src/middleware/seed-registry.middleware.ts +0 -21
  278. package/src/middleware/storage.middleware.ts +0 -25
  279. package/src/middleware.ts +0 -45
  280. package/src/public/access-policy.ts +0 -27
  281. package/src/public/api-key-middleware.ts +0 -57
  282. package/src/public/cache-utils.ts +0 -38
  283. package/src/public/entry-projection.ts +0 -46
  284. package/src/public/idempotency.ts +0 -23
  285. package/src/public/index.ts +0 -16
  286. package/src/public/problem-details.ts +0 -124
  287. package/src/public/public-add.ts +0 -114
  288. package/src/public/public-edit.ts +0 -163
  289. package/src/public/public-errors.ts +0 -19
  290. package/src/public/public-read.ts +0 -63
  291. package/src/public/public-routes.ts +0 -88
  292. package/src/public/query-builder.test.ts +0 -224
  293. package/src/public/query-builder.ts +0 -156
  294. package/src/public/rate-limit-middleware.ts +0 -34
  295. package/src/public/read-list.ts +0 -54
  296. package/src/public/read-single.ts +0 -48
  297. package/src/public/response-builder.ts +0 -30
  298. package/src/public/sanitize.ts +0 -69
  299. package/src/rate-limit/cloudflare-rate-limiter.test.ts +0 -30
  300. package/src/rate-limit/cloudflare-rate-limiter.ts +0 -15
  301. package/src/rate-limit/in-memory-rate-limiter.test.ts +0 -37
  302. package/src/rate-limit/in-memory-rate-limiter.ts +0 -17
  303. package/src/rate-limit/no-op-rate-limiter.test.ts +0 -22
  304. package/src/rate-limit/no-op-rate-limiter.ts +0 -11
  305. package/src/search-utils.test.ts +0 -211
  306. package/src/search-utils.ts +0 -213
  307. package/src/search.ts +0 -65
  308. package/src/shared/apply-policies.test.ts +0 -81
  309. package/src/shared/apply-policies.ts +0 -67
  310. package/src/shared/automations.repository.d1.ts +0 -150
  311. package/src/shared/background-notification-service.test.ts +0 -62
  312. package/src/shared/background-notification-service.ts +0 -52
  313. package/src/shared/base.repository.d1.ts +0 -32
  314. package/src/shared/content-utils.test.ts +0 -165
  315. package/src/shared/content-utils.ts +0 -86
  316. package/src/shared/content.repository.d1.test.ts +0 -507
  317. package/src/shared/content.repository.d1.ts +0 -851
  318. package/src/shared/d1-activity-log.repository.test.ts +0 -140
  319. package/src/shared/d1-activity-log.repository.ts +0 -105
  320. package/src/shared/d1-activity-logger.test.ts +0 -86
  321. package/src/shared/d1-activity-logger.ts +0 -67
  322. package/src/shared/d1-analytics.repository.test.ts +0 -78
  323. package/src/shared/d1-analytics.repository.ts +0 -85
  324. package/src/shared/d1-content-scan.repository.test.ts +0 -80
  325. package/src/shared/d1-content-scan.repository.ts +0 -37
  326. package/src/shared/d1-notification.repository.test.ts +0 -128
  327. package/src/shared/d1-notification.repository.ts +0 -118
  328. package/src/shared/d1-password-reset-token.repository.test.ts +0 -81
  329. package/src/shared/d1-password-reset-token.repository.ts +0 -56
  330. package/src/shared/d1-search.repository.test.ts +0 -87
  331. package/src/shared/d1-search.repository.ts +0 -88
  332. package/src/shared/d1-session.repository.test.ts +0 -125
  333. package/src/shared/d1-session.repository.ts +0 -102
  334. package/src/shared/d1-setup-checklist.repository.ts +0 -36
  335. package/src/shared/d1-user.repository.test.ts +0 -151
  336. package/src/shared/d1-user.repository.ts +0 -119
  337. package/src/shared/d1-widget.repository.test.ts +0 -267
  338. package/src/shared/d1-widget.repository.ts +0 -385
  339. package/src/shared/dashboard-layout.repository.d1.test.ts +0 -135
  340. package/src/shared/dashboard-layout.repository.d1.ts +0 -58
  341. package/src/shared/demo-data-sql.ts +0 -216
  342. package/src/shared/demo-data.repository.d1.ts +0 -20
  343. package/src/shared/execution-context-scheduler.ts +0 -13
  344. package/src/shared/fixed-clock.ts +0 -25
  345. package/src/shared/fts-sync.ts +0 -8
  346. package/src/shared/idempotency.repository.d1.test.ts +0 -83
  347. package/src/shared/idempotency.repository.d1.ts +0 -60
  348. package/src/shared/in-memory-activity-logger.ts +0 -19
  349. package/src/shared/in-memory-notification-service.ts +0 -19
  350. package/src/shared/in-memory-seed.repository.ts +0 -58
  351. package/src/shared/media.repository.d1.test.ts +0 -107
  352. package/src/shared/media.repository.d1.ts +0 -68
  353. package/src/shared/qstash-notification-service.test.ts +0 -67
  354. package/src/shared/qstash-notification-service.ts +0 -55
  355. package/src/shared/query-utils.ts +0 -141
  356. package/src/shared/request-utils.ts +0 -26
  357. package/src/shared/schema-mutator.d1.test.ts +0 -142
  358. package/src/shared/schema-mutator.d1.ts +0 -64
  359. package/src/shared/seed-layout.repository.d1.test.ts +0 -114
  360. package/src/shared/seed-layout.repository.d1.ts +0 -62
  361. package/src/shared/seed-registry-cache.test.ts +0 -68
  362. package/src/shared/seed-registry-cache.ts +0 -49
  363. package/src/shared/seed.repository.d1.test.ts +0 -143
  364. package/src/shared/seed.repository.d1.ts +0 -98
  365. package/src/shared/sequential-id-generator.ts +0 -33
  366. package/src/shared/site-settings.repository.d1.ts +0 -53
  367. package/src/shared/storage/factory.ts +0 -41
  368. package/src/shared/storage/s3-bucket.ts +0 -195
  369. package/src/shared/storage-utils.ts +0 -40
  370. package/src/shared/system-stats.repository.d1.test.ts +0 -58
  371. package/src/shared/system-stats.repository.d1.ts +0 -48
  372. package/src/types.ts +0 -90
  373. package/src/upload.ts +0 -198
  374. package/src/widget.test.ts +0 -85
  375. package/src/widget.ts +0 -251
@@ -1,180 +0,0 @@
1
- import { describe, it, expect, vi } from 'vitest'
2
- import { Context } from 'hono'
3
- import { EntryNotFoundError, SlugConflictError } from '@beechcms/core'
4
- import { normalizeBody, contentValidationProblem, logContentActivity, dispatchContentAutomation, handleContentDatabaseError } from './helpers'
5
- import { CONTENT_ERRORS } from '../constants'
6
-
7
- // Mock dependencies
8
- vi.mock('../../../public/problem-details', () => ({
9
- publicProblem: vi.fn((_ctx, details) => ({ mockProblem: true, ...details })),
10
- fkProblemOrNull: vi.fn((_ctx, err, method) => {
11
- if (err instanceof Error && err.message === 'FK_ERROR') return { mockFkProblem: true }
12
- return null
13
- }),
14
- }))
15
-
16
- describe('content handlers helpers', () => {
17
- describe('normalizeBody', () => {
18
- it('returns the object when input is an object', () => {
19
- const obj = { a: 1 }
20
- expect(normalizeBody(obj)).toBe(obj)
21
- })
22
-
23
- it('returns an empty object when input is null', () => {
24
- expect(normalizeBody(null)).toEqual({})
25
- })
26
-
27
- it('returns an empty object when input is a primitive', () => {
28
- expect(normalizeBody('string')).toEqual({})
29
- expect(normalizeBody(123)).toEqual({})
30
- expect(normalizeBody(true)).toEqual({})
31
- })
32
- })
33
-
34
- describe('contentValidationProblem', () => {
35
- it('calls publicProblem with correct parameters', () => {
36
- const ctx = {} as Context
37
- const errors = [{ field: 'title', expected: 'string', received: 'number', message: 'Wrong type' }]
38
- const result = contentValidationProblem(ctx, errors)
39
-
40
- expect(result).toEqual({
41
- mockProblem: true,
42
- type: 'content-validation-failed',
43
- title: 'Bad Request',
44
- status: 400,
45
- detail: 'Validation failed',
46
- errors,
47
- })
48
- })
49
- })
50
-
51
- describe('logContentActivity', () => {
52
- it('logs activity with correct payload', () => {
53
- const mockLog = vi.fn()
54
- const ctx = {
55
- get: vi.fn((key) => {
56
- if (key === 'jwtPayload') return { sub: 'user-1', email: 'test@test.com', name: 'John', surname: 'Doe' }
57
- if (key === 'activityLogger') return { log: mockLog }
58
- })
59
- } as unknown as Context<any>
60
-
61
- logContentActivity(ctx, 'create', 'entry-1', 'test-slug', 'Test Title')
62
-
63
- expect(mockLog).toHaveBeenCalledWith({
64
- action: 'create',
65
- entityType: 'content',
66
- entityId: 'entry-1',
67
- entitySlug: 'test-slug',
68
- details: { title: 'Test Title' },
69
- actor: {
70
- id: 'user-1',
71
- email: 'test@test.com',
72
- name: 'John Doe',
73
- },
74
- })
75
- })
76
-
77
- it('handles missing name and surname', () => {
78
- const mockLog = vi.fn()
79
- const ctx = {
80
- get: vi.fn((key) => {
81
- if (key === 'jwtPayload') return { sub: 'user-1' } // Missing name, surname, email
82
- if (key === 'activityLogger') return { log: mockLog }
83
- })
84
- } as unknown as Context<any>
85
-
86
- logContentActivity(ctx, 'update', 'entry-1', 'test-slug', 'Test Title')
87
-
88
- expect(mockLog).toHaveBeenCalledWith({
89
- action: 'update',
90
- entityType: 'content',
91
- entityId: 'entry-1',
92
- entitySlug: 'test-slug',
93
- details: { title: 'Test Title' },
94
- actor: {
95
- id: 'user-1',
96
- email: 'unknown',
97
- name: null,
98
- },
99
- })
100
- })
101
- })
102
-
103
- describe('dispatchContentAutomation', () => {
104
- it('schedules automation run', () => {
105
- const mockWaitUntil = vi.fn()
106
- const mockRun = vi.fn().mockReturnValue('mock-promise')
107
- const ctx = {
108
- get: vi.fn((key) => {
109
- if (key === 'scheduler') return { waitUntil: mockWaitUntil }
110
- if (key === 'automationRunner') return { run: mockRun }
111
- })
112
- } as unknown as Context<any>
113
-
114
- const entry = { id: 1 }
115
- dispatchContentAutomation(ctx, 'posts', 'create', entry)
116
-
117
- expect(mockRun).toHaveBeenCalledWith({
118
- seedSlug: 'posts',
119
- event: 'create',
120
- entry,
121
- })
122
- expect(mockWaitUntil).toHaveBeenCalledWith('mock-promise')
123
- })
124
- })
125
-
126
- describe('handleContentDatabaseError', () => {
127
- it('handles EntryNotFoundError', () => {
128
- const ctx = {} as Context<any>
129
- const error = new EntryNotFoundError('Not found')
130
- const result = handleContentDatabaseError(ctx, error)
131
-
132
- expect(result).toEqual({
133
- mockProblem: true,
134
- type: 'content-not-found',
135
- title: 'Not Found',
136
- status: 404,
137
- detail: CONTENT_ERRORS.NOT_FOUND,
138
- })
139
- })
140
-
141
- it('handles SlugConflictError', () => {
142
- const ctx = {} as Context<any>
143
- const error = new SlugConflictError('Conflict', 'slug')
144
- const result = handleContentDatabaseError(ctx, error)
145
-
146
- expect(result).toEqual({
147
- mockProblem: true,
148
- type: 'content-slug-conflict',
149
- title: 'Conflict',
150
- status: 409,
151
- detail: CONTENT_ERRORS.SLUG_CONFLICT,
152
- })
153
- })
154
-
155
- it('handles foreign key error', () => {
156
- const ctx = { req: { method: 'POST' } } as unknown as Context<any>
157
- const error = new Error('FK_ERROR')
158
- const result = handleContentDatabaseError(ctx, error)
159
-
160
- expect(result).toEqual({ mockFkProblem: true })
161
- })
162
-
163
- it('handles generic errors as 500', () => {
164
- const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {})
165
- const ctx = { req: { method: 'POST' } } as unknown as Context<any>
166
- const error = new Error('Some db error')
167
- const result = handleContentDatabaseError(ctx, error)
168
-
169
- expect(result).toEqual({
170
- mockProblem: true,
171
- type: 'content-database-error',
172
- title: 'Internal Server Error',
173
- status: 500,
174
- detail: CONTENT_ERRORS.DATABASE_ERROR,
175
- })
176
- expect(consoleSpy).toHaveBeenCalledWith('Content database error:', error)
177
- consoleSpy.mockRestore()
178
- })
179
- })
180
- })
@@ -1,93 +0,0 @@
1
- // SPDX-License-Identifier: BUSL-1.1
2
- // Copyright (c) 2024–2026 Flavio De Musso. All rights reserved.
3
- // See LICENSE in the repository root for license terms.
4
-
5
- import { Context } from 'hono'
6
- import { EntryNotFoundError, SlugConflictError } from '@beechcms/core'
7
- import { publicProblem, fkProblemOrNull } from '../../../public/problem-details'
8
- import { CONTENT_ERRORS } from '../constants'
9
- import { AppEnv } from '../../../types'
10
-
11
- export function normalizeBody(raw: unknown): Record<string, unknown> {
12
- return typeof raw === 'object' && raw !== null ? (raw as Record<string, unknown>) : {}
13
- }
14
-
15
- export function contentValidationProblem(
16
- context: Context,
17
- details: Array<{ field: string; expected: string; received: string; message: string }>
18
- ) {
19
- return publicProblem(context, {
20
- type: 'content-validation-failed',
21
- title: 'Bad Request',
22
- status: 400,
23
- detail: 'Validation failed',
24
- errors: details
25
- })
26
- }
27
-
28
- export function logContentActivity(
29
- context: Context<AppEnv>,
30
- action: 'create' | 'update' | 'delete',
31
- id: string,
32
- slug: string,
33
- title: string
34
- ) {
35
- const jwtPayload = context.get('jwtPayload')
36
- context.get('activityLogger').log({
37
- action,
38
- entityType: 'content',
39
- entityId: id,
40
- entitySlug: slug,
41
- details: { title },
42
- actor: {
43
- id: jwtPayload.sub,
44
- email: jwtPayload.email ?? 'unknown',
45
- name: [jwtPayload.name, jwtPayload.surname].filter(Boolean).join(' ') || null,
46
- },
47
- })
48
- }
49
-
50
- export function dispatchContentAutomation(
51
- context: Context<AppEnv>,
52
- seedSlug: string,
53
- event: 'create' | 'update' | 'delete',
54
- entry: Record<string, unknown>
55
- ) {
56
- context.get('scheduler').waitUntil(
57
- context.get('automationRunner').run({
58
- seedSlug,
59
- event,
60
- entry,
61
- }),
62
- )
63
- }
64
-
65
- export function handleContentDatabaseError(context: Context<AppEnv>, error: unknown) {
66
- if (error instanceof EntryNotFoundError) {
67
- return publicProblem(context, {
68
- type: 'content-not-found',
69
- title: 'Not Found',
70
- status: 404,
71
- detail: CONTENT_ERRORS.NOT_FOUND
72
- })
73
- }
74
- if (error instanceof SlugConflictError) {
75
- return publicProblem(context, {
76
- type: 'content-slug-conflict',
77
- title: 'Conflict',
78
- status: 409,
79
- detail: CONTENT_ERRORS.SLUG_CONFLICT,
80
- })
81
- }
82
-
83
- const fkResponse = fkProblemOrNull(context, error, context.req.method)
84
- if (fkResponse) return fkResponse
85
-
86
- console.error('Content database error:', error)
87
- return publicProblem(context, {
88
- type: 'content-database-error',
89
- title: 'Internal Server Error',
90
- status: 500,
91
- detail: CONTENT_ERRORS.DATABASE_ERROR,
92
- })
93
- }
@@ -1,174 +0,0 @@
1
- // SPDX-License-Identifier: BUSL-1.1
2
- // Copyright (c) 2024–2026 Flavio De Musso. All rights reserved.
3
- // See LICENSE in the repository root for license terms.
4
-
5
- import { Context } from 'hono'
6
- import { parsePositiveInt, parseQueryFilters, cleanStr, toEngineFilters } from '../../../shared/query-utils'
7
- import { applyVisibility } from '../../../shared/apply-policies'
8
- import { publicProblem } from '../../../public/problem-details'
9
- import { CONTENT_ERRORS } from '../constants'
10
- import { AppEnv } from '../../../types'
11
-
12
- /**
13
- * Builds a compact `relations` map for the list response.
14
- * For each relation branch in the seed, collects non-null referenced ids from
15
- * the page items, then fires ONE batched query per target seed to retrieve
16
- * only the label column. This is O(R) extra queries per page (R = # relation
17
- * branches) instead of O(N*R) per-row fetches.
18
- *
19
- * Shape: { [branchAlias]: { [targetId]: labelString } }
20
- */
21
- async function buildRelationsMap(
22
- context: Context<AppEnv>,
23
- seed: Parameters<typeof applyVisibility>[1],
24
- entries: Record<string, unknown>[]
25
- ): Promise<Record<string, Record<string, string>>> {
26
- const relationBranches = seed.branches.filter(
27
- (b: { type: string }) => b.type === 'relation'
28
- ) as Array<{ alias: string; targetSeed?: string }>
29
-
30
- if (relationBranches.length === 0) return {}
31
-
32
- const relations: Record<string, Record<string, string>> = {}
33
- const repository = context.get('repository')
34
- const seedRegistry = context.get('seedRegistry')
35
-
36
- for (const branch of relationBranches) {
37
- const targetSlug = branch.targetSeed
38
- if (!targetSlug) continue
39
-
40
- const targetSeedDef = seedRegistry.get(targetSlug)
41
- if (!targetSeedDef) continue
42
-
43
- const labelAlias = targetSeedDef.displayNameAlias ?? 'title'
44
-
45
- // Collect unique non-null ids referenced by this branch
46
- const ids = Array.from(
47
- new Set(
48
- entries
49
- .map((entry) => {
50
- const data = entry.data as Record<string, unknown>
51
- return typeof data[branch.alias] === 'string' && data[branch.alias]
52
- ? (data[branch.alias] as string)
53
- : null
54
- })
55
- .filter((id): id is string => id !== null)
56
- )
57
- )
58
-
59
- if (ids.length === 0) continue
60
-
61
- try {
62
- const { items } = await repository.findMany(targetSeedDef, {
63
- filters: [
64
- {
65
- column: 'id',
66
- type: 'system' as const,
67
- conditions: [{ op: 'in' as const, value: ids }],
68
- },
69
- ],
70
- fields: ['id', labelAlias],
71
- pagination: { limit: ids.length, offset: 0 },
72
- })
73
-
74
- const map: Record<string, string> = {}
75
- for (const item of items) {
76
- const id = (item as Record<string, unknown>).id as string
77
- const data = (item as Record<string, unknown>).data as Record<string, unknown>
78
- const label = data[labelAlias]
79
- map[id] = label != null && label !== '' ? String(label) : id
80
- }
81
-
82
- relations[branch.alias] = map
83
- } catch {
84
- // Non-fatal: if the target seed table doesn't exist yet, skip
85
- }
86
- }
87
-
88
- return relations
89
- }
90
-
91
- export async function listHandler(context: Context<AppEnv>) {
92
- const slug = context.req.param('slug')
93
- if (!slug) {
94
- return publicProblem(context, {
95
- type: 'content-invalid-slug',
96
- title: 'Bad Request',
97
- status: 400,
98
- detail: CONTENT_ERRORS.INVALID_SLUG
99
- })
100
- }
101
-
102
- const seed = context.get('getSeed')(slug)
103
- if (!seed) {
104
- return publicProblem(context, {
105
- type: 'content-seed-not-found',
106
- title: 'Not Found',
107
- status: 404,
108
- detail: CONTENT_ERRORS.SEED_NOT_FOUND
109
- })
110
- }
111
-
112
- try {
113
- const query = context.req.query()
114
- const search = cleanStr(query.search) ?? ''
115
- const sortBy = cleanStr(query.sortBy) ?? ''
116
- const sortDirRaw = cleanStr(query.sortDir)?.toLowerCase() ?? 'asc'
117
- const rawFilters = parseQueryFilters(query.filters)
118
- const engineFilters = toEngineFilters(rawFilters)
119
-
120
- // Note: repository doesn't yet support has_pending_draft filter/column natively
121
- // in findMany without SQL manipulation. We'll stick to basic findMany for now
122
- // and might need to enhance the repository if this feature is critical for v1 of this refactor.
123
- // The legacy code was doing a lot of SQL injection here.
124
-
125
- const page = parsePositiveInt(query.page, 1)
126
- const limit = Math.min(parsePositiveInt(query.limit, 25), 100)
127
- const offset = (page - 1) * limit
128
-
129
- const orderBy = sortBy
130
- ? { column: sortBy, dir: (sortDirRaw === 'desc' ? 'DESC' : 'ASC') as 'ASC' | 'DESC' }
131
- : undefined
132
-
133
- const repository = context.get('repository')
134
- const { items, total } = await repository.findMany(seed, {
135
- filters: engineFilters,
136
- orderBy,
137
- search: search || undefined,
138
- pagination: { limit, offset },
139
- })
140
-
141
- const entries = await Promise.all(items.map(async (item) => {
142
- // Check for pending draft if allowed
143
- let hasPendingDraft = false
144
- if (seed.allowDrafts) {
145
- hasPendingDraft = await repository.hasDraft(seed, item.id)
146
- }
147
-
148
- return {
149
- ...item,
150
- has_pending_draft: hasPendingDraft,
151
- data: applyVisibility(item, seed) // Repository returns "pure" data including system fields
152
- }
153
- }))
154
-
155
- // If no query params (except slug), return array directly (legacy compatibility)
156
- const hasQueryParams = Boolean(search) || Boolean(sortBy) || Boolean(query.filters) || query.page !== undefined || query.limit !== undefined
157
- if (!hasQueryParams) {
158
- return context.json(entries)
159
- }
160
-
161
- // Build compact relation labels map for N+1 mitigation
162
- const relations = await buildRelationsMap(context, seed, entries)
163
-
164
- return context.json({ items: entries, total, page, limit, relations })
165
- } catch (error) {
166
- console.error('Content list error:', error)
167
- return publicProblem(context, {
168
- type: 'content-database-error',
169
- title: 'Internal Server Error',
170
- status: 500,
171
- detail: CONTENT_ERRORS.DATABASE_ERROR
172
- })
173
- }
174
- }
@@ -1,174 +0,0 @@
1
- // SPDX-License-Identifier: BUSL-1.1
2
- // Copyright (c) 2024–2026 Flavio De Musso. All rights reserved.
3
- // See LICENSE in the repository root for license terms.
4
-
5
- import { Context } from 'hono'
6
- import {
7
- slugify,
8
- isValidContentStatus,
9
- validateAndSanitizeSeedPayload,
10
- resolvePolicies
11
- } from '@beechcms/core'
12
- import { applyPrivacy, PrivacyPolicyError } from '../../../shared/apply-policies'
13
- import { publicProblem } from '../../../public/problem-details'
14
- import {
15
- normalizeBody,
16
- contentValidationProblem,
17
- logContentActivity,
18
- dispatchContentAutomation,
19
- handleContentDatabaseError
20
- } from './helpers'
21
- import { CONTENT_ERRORS } from '../constants'
22
- import { cleanStr } from '../../../shared/query-utils'
23
- import { AppEnv } from '../../../types'
24
-
25
-
26
-
27
- export async function updateHandler(context: Context<AppEnv>) {
28
- const slug = context.req.param('slug')
29
- const id = context.req.param('id')
30
- if (!slug || !id) {
31
- return publicProblem(context, {
32
- type: 'content-invalid-slug-or-id',
33
- title: 'Bad Request',
34
- status: 400,
35
- detail: CONTENT_ERRORS.INVALID_SLUG_OR_ID
36
- })
37
- }
38
-
39
- const seed = context.get('getSeed')(slug)
40
- if (!seed) {
41
- return publicProblem(context, {
42
- type: 'content-seed-not-found',
43
- title: 'Not Found',
44
- status: 404,
45
- detail: CONTENT_ERRORS.SEED_NOT_FOUND
46
- })
47
- }
48
-
49
- let body: Record<string, unknown>
50
- try {
51
- body = normalizeBody(await context.req.json<unknown>())
52
- } catch {
53
- return publicProblem(context, {
54
- type: 'content-invalid-json',
55
- title: 'Bad Request',
56
- status: 400,
57
- detail: CONTENT_ERRORS.INVALID_JSON_BODY
58
- })
59
- }
60
-
61
- const bodyForData = { ...body }
62
- delete bodyForData.slug
63
- delete bodyForData.status
64
-
65
- try {
66
- const repository = context.get('repository')
67
- // We need current data to handle slug and status if not provided,
68
- // and to verify existence.
69
- const current = await repository.findById(seed, id)
70
-
71
- const newSlug = body.slug !== undefined ? slugify(String(body.slug)) : (current.slug as string)
72
- const newStatus = body.status !== undefined ? (cleanStr(body.status) ?? current.status as string) : current.status as string
73
-
74
- if (!isValidContentStatus(newStatus)) {
75
- return publicProblem(context, {
76
- type: 'content-invalid-status',
77
- title: 'Bad Request',
78
- status: 400,
79
- detail: 'Invalid status. Allowed values are: draft, review, published'
80
- })
81
- }
82
-
83
- if (!newSlug) {
84
- return publicProblem(context, {
85
- type: 'content-missing-slug',
86
- title: 'Bad Request',
87
- status: 400,
88
- detail: 'Missing required field: slug'
89
- })
90
- }
91
-
92
- let mergedData: Record<string, unknown> = {}
93
-
94
- if (Object.keys(bodyForData).length > 0) {
95
- const sensitiveAliases = Object.keys(bodyForData).filter((alias) => {
96
- const branch = seed.branches.find((b) => b.alias === alias)
97
- return branch != null && resolvePolicies(branch).privacy !== 'plain'
98
- })
99
-
100
- if (sensitiveAliases.length > 0) {
101
- return publicProblem(context, {
102
- type: 'content-sensitive-field-edit',
103
- title: 'Unprocessable Entity',
104
- status: 422,
105
- detail: `${CONTENT_ERRORS.SENSITIVE_FIELD_EDIT}: ${sensitiveAliases.join(', ')}`
106
- })
107
- }
108
-
109
- const validation = validateAndSanitizeSeedPayload(seed, bodyForData, {
110
- operation: 'update',
111
- allowNull: true,
112
- requireAtLeastOneValidField: true,
113
- enforceRequiredFields: true,
114
- idGenerator: context.get('idGenerator'),
115
- })
116
-
117
- if (validation.dangerousFields.length > 0) {
118
- return publicProblem(context, {
119
- type: 'content-dangerous-content',
120
- title: 'Unprocessable Entity',
121
- status: 422,
122
- detail: `Content rejected: dangerous markup detected in field '${validation.dangerousFields[0]}'`
123
- })
124
- }
125
-
126
- if (validation.details.length > 0) return contentValidationProblem(context, validation.details)
127
-
128
- let privacyPatch: Record<string, unknown>
129
- try {
130
- privacyPatch = await applyPrivacy(validation.data, seed)
131
- } catch (error) {
132
- if (error instanceof PrivacyPolicyError) {
133
- return publicProblem(context, {
134
- type: 'content-policy-not-implemented',
135
- title: 'Not Implemented',
136
- status: 501,
137
- detail: error.message
138
- })
139
- }
140
- throw error
141
- }
142
-
143
- // Remove null values from patch (patch semantics: null = leave unchanged)
144
- for (const [k, v] of Object.entries(privacyPatch)) {
145
- if (v !== null) mergedData[k] = v
146
- }
147
- }
148
-
149
- if (newSlug !== current.slug) {
150
- if (await repository.existsSlug(seed, newSlug, id)) {
151
- return publicProblem(context, {
152
- type: 'content-slug-conflict',
153
- title: 'Conflict',
154
- status: 409,
155
- detail: CONTENT_ERRORS.SLUG_CONFLICT
156
- })
157
- }
158
- // Add slug to mergedData if changed
159
- mergedData.slug = newSlug
160
- }
161
-
162
- await repository.update(seed, id, mergedData, newStatus)
163
-
164
- const jwtPayload = context.get('jwtPayload')
165
- const title = mergedData.title || mergedData.name || newSlug
166
-
167
- logContentActivity(context, 'update', id, slug, String(title))
168
- dispatchContentAutomation(context, slug, 'update', { ...current, ...mergedData, id, status: newStatus })
169
-
170
- return context.json({ success: true })
171
- } catch (error) {
172
- return handleContentDatabaseError(context, error)
173
- }
174
- }
@@ -1,26 +0,0 @@
1
- // SPDX-License-Identifier: BUSL-1.1
2
- // Copyright (c) 2024–2026 Flavio De Musso. All rights reserved.
3
- // See LICENSE in the repository root for license terms.
4
-
5
- import { Hono } from 'hono'
6
- import { AppEnv } from '../../types'
7
- import { listHandler } from './handlers/list'
8
- import { getByIdHandler, getBySlugHandler } from './handlers/get'
9
- import { createHandler } from './handlers/create'
10
- import { updateHandler } from './handlers/update'
11
- import { deleteHandler } from './handlers/delete'
12
- import { facetsHandler } from './handlers/facets'
13
- import { bulkHandler } from './handlers/bulk.handler'
14
-
15
- const content = new Hono<AppEnv>()
16
-
17
- content.get('/:slug', listHandler)
18
- content.get('/:slug/facets', facetsHandler)
19
- content.get('/:schema_slug/by-slug/:entry_slug', getBySlugHandler)
20
- content.get('/:slug/:id', getByIdHandler)
21
- content.post('/:slug', createHandler)
22
- content.patch('/:slug/bulk', bulkHandler)
23
- content.put('/:slug/:id', updateHandler)
24
- content.delete('/:slug/:id', deleteHandler)
25
-
26
- export default content