@beechcms/api 0.6.0-preview.1 → 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 (373) hide show
  1. package/README.md +4 -4
  2. package/assets/dashboard/BeechLogo.svg +18 -18
  3. package/assets/dashboard/BeechLogoLIght.svg +48 -48
  4. package/assets/dashboard/assets/chart-Cws4Yj6K.js +39 -0
  5. package/assets/dashboard/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
  6. package/assets/dashboard/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
  7. package/assets/dashboard/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
  8. package/assets/dashboard/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
  9. package/assets/dashboard/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
  10. package/assets/dashboard/assets/index-BjPpppHe.css +1 -0
  11. package/assets/dashboard/assets/index-CrW-zhkA.js +642 -0
  12. package/assets/dashboard/assets/lora-cyrillic-ext-wght-normal-YcVxMP-u.woff2 +0 -0
  13. package/assets/dashboard/assets/lora-cyrillic-wght-normal-UWPuZLjM.woff2 +0 -0
  14. package/assets/dashboard/assets/lora-latin-ext-wght-normal-C2Wlntb9.woff2 +0 -0
  15. package/assets/dashboard/assets/lora-latin-wght-normal-BiLcIKcI.woff2 +0 -0
  16. package/assets/dashboard/assets/lora-math-wght-normal-sOy7rEfW.woff2 +0 -0
  17. package/assets/dashboard/assets/lora-symbols-wght-normal-DQ5VrUkH.woff2 +0 -0
  18. package/assets/dashboard/assets/lora-vietnamese-wght-normal-CfJ7gtf3.woff2 +0 -0
  19. package/assets/dashboard/assets/pie-chart-recharts-CAxoDQp2.js +1 -0
  20. package/assets/dashboard/assets/timeseries-chart-recharts-CixDW-LM.js +1 -0
  21. package/assets/dashboard/beechLogoDark.svg +48 -48
  22. package/assets/dashboard/index.html +18 -18
  23. package/assets/dashboard/noResult.svg +42 -42
  24. package/assets/dashboard/sol.svg +3 -3
  25. package/assets/dashboard/undraw_enter_nwx3.svg +36 -36
  26. package/dist/auth/__fixtures__/in-memory-hash-provider.d.ts +5 -0
  27. package/dist/auth/__fixtures__/static-token-service.d.ts +6 -0
  28. package/dist/auth/bcrypt-hash-provider.d.ts +8 -0
  29. package/dist/auth/constants.d.ts +10 -0
  30. package/dist/auth/jose-token-service.d.ts +14 -0
  31. package/dist/auth/login.d.ts +32 -0
  32. package/dist/auth/refresh.d.ts +1 -0
  33. package/dist/factory.d.ts +39 -0
  34. package/dist/features/automations/action-executors/create-entry.executor.d.ts +7 -0
  35. package/dist/features/automations/action-executors/edit-field.executor.d.ts +7 -0
  36. package/dist/features/automations/action-executors/index.d.ts +13 -0
  37. package/dist/features/automations/action-executors/send-mail.executor.d.ts +7 -0
  38. package/dist/features/automations/action-executors/set-variable.executor.d.ts +15 -0
  39. package/dist/features/automations/action-executors/webhook.executor.d.ts +7 -0
  40. package/dist/features/automations/automation-runner.d.ts +13 -0
  41. package/dist/features/automations/automation-runner.utils.d.ts +3 -0
  42. package/dist/features/automations/automations.handler.d.ts +7 -0
  43. package/dist/features/automations/automations.schema.d.ts +191 -0
  44. package/dist/features/automations/context-resolver.d.ts +8 -0
  45. package/dist/features/automations/cron-runner.d.ts +9 -0
  46. package/dist/features/automations/cron-runner.utils.d.ts +1 -0
  47. package/dist/features/automations/filter-translation.d.ts +9 -0
  48. package/dist/features/automations/index.d.ts +7 -0
  49. package/dist/features/automations/template-grammar.d.ts +73 -0
  50. package/dist/features/automations/var-access-resolver.d.ts +6 -0
  51. package/dist/features/automations/when-evaluator.d.ts +3 -0
  52. package/dist/features/automations/when-pushdown.d.ts +2 -0
  53. package/dist/features/backrefs/backrefs.handler.d.ts +3 -0
  54. package/dist/features/backrefs/d1-backref.repository.d.ts +17 -0
  55. package/dist/features/backrefs/index.d.ts +1 -0
  56. package/dist/features/content/constants.d.ts +12 -0
  57. package/dist/features/content/handlers/bulk.handler.d.ts +3 -0
  58. package/dist/features/content/handlers/create.d.ts +3 -0
  59. package/dist/features/content/handlers/delete.d.ts +3 -0
  60. package/dist/features/content/handlers/facets.d.ts +3 -0
  61. package/dist/features/content/handlers/get.d.ts +4 -0
  62. package/dist/features/content/handlers/helpers.d.ts +12 -0
  63. package/dist/features/content/handlers/list.d.ts +3 -0
  64. package/dist/features/content/handlers/update.d.ts +3 -0
  65. package/dist/features/content/index.d.ts +4 -0
  66. package/dist/features/dashboard-layout/dashboard-layout.handler.d.ts +7 -0
  67. package/dist/features/dashboard-layout/index.d.ts +1 -0
  68. package/dist/features/draft/draft.handler.d.ts +4 -0
  69. package/dist/features/draft/draft.middleware.d.ts +9 -0
  70. package/dist/features/draft/index.d.ts +1 -0
  71. package/{src/features/email/email.provider.ts → dist/features/email/email.provider.d.ts} +37 -42
  72. package/dist/features/email/email.service.d.ts +13 -0
  73. package/dist/features/email/email.types.d.ts +94 -0
  74. package/{src/features/email/index.ts → dist/features/email/index.d.ts} +20 -33
  75. package/dist/features/email/providers/resend.d.ts +36 -0
  76. package/dist/features/email/providers/smtp.d.ts +11 -0
  77. package/dist/features/email/templates/automation-mail.d.ts +8 -0
  78. package/dist/features/email/templates/password-changed.d.ts +15 -0
  79. package/dist/features/email/templates/password-reset.d.ts +18 -0
  80. package/dist/features/email/templates/shell.d.ts +58 -0
  81. package/dist/features/notifications/index.d.ts +1 -0
  82. package/dist/features/notifications/notifications.handler.d.ts +15 -0
  83. package/dist/features/password-reset/index.d.ts +6 -0
  84. package/dist/features/password-reset/request.d.ts +10 -0
  85. package/dist/features/password-reset/reset.d.ts +9 -0
  86. package/dist/features/rotate-field/index.d.ts +1 -0
  87. package/dist/features/rotate-field/rotate-field.handler.d.ts +7 -0
  88. package/dist/features/rotate-field/rotate-field.schema.d.ts +11 -0
  89. package/dist/features/schema/schema.handler.d.ts +7 -0
  90. package/dist/features/seeds/index.d.ts +1 -0
  91. package/dist/features/seeds/seeds.handler.d.ts +6 -0
  92. package/dist/features/settings/settings.handler.d.ts +7 -0
  93. package/dist/features/setup/index.d.ts +7 -0
  94. package/dist/features/stats/index.d.ts +1 -0
  95. package/dist/features/stats/stats.handler.d.ts +7 -0
  96. package/dist/features/webhooks/index.d.ts +3 -0
  97. package/dist/index.d.ts +6 -0
  98. package/dist/index.js +9666 -0
  99. package/dist/media-utils.d.ts +25 -0
  100. package/dist/middleware/auth-providers.middleware.d.ts +8 -0
  101. package/dist/middleware/observability.middleware.d.ts +20 -0
  102. package/dist/middleware/rate-limit.middleware.d.ts +9 -0
  103. package/dist/middleware/repository.middleware.d.ts +34 -0
  104. package/dist/middleware/seed-registry.middleware.d.ts +10 -0
  105. package/dist/middleware/storage.middleware.d.ts +7 -0
  106. package/dist/middleware.d.ts +11 -0
  107. package/dist/public/access-policy.d.ts +12 -0
  108. package/dist/public/api-key-middleware.d.ts +6 -0
  109. package/dist/public/cache-utils.d.ts +10 -0
  110. package/dist/public/entry-projection.d.ts +2 -0
  111. package/dist/public/idempotency.d.ts +9 -0
  112. package/dist/public/index.d.ts +11 -0
  113. package/dist/public/problem-details.d.ts +31 -0
  114. package/dist/public/public-add.d.ts +3 -0
  115. package/dist/public/public-edit.d.ts +5 -0
  116. package/dist/public/public-errors.d.ts +13 -0
  117. package/dist/public/public-read.d.ts +3 -0
  118. package/dist/public/public-routes.d.ts +3 -0
  119. package/dist/public/query-builder.d.ts +28 -0
  120. package/dist/public/rate-limit-middleware.d.ts +3 -0
  121. package/dist/public/read-list.d.ts +26 -0
  122. package/dist/public/read-single.d.ts +22 -0
  123. package/dist/public/response-builder.d.ts +22 -0
  124. package/dist/public/sanitize.d.ts +23 -0
  125. package/dist/public/slug-utils.d.ts +11 -0
  126. package/dist/rate-limit/cloudflare-rate-limiter.d.ts +6 -0
  127. package/dist/rate-limit/in-memory-rate-limiter.d.ts +7 -0
  128. package/dist/rate-limit/no-op-rate-limiter.d.ts +4 -0
  129. package/dist/search-utils.d.ts +54 -0
  130. package/dist/search.d.ts +6 -0
  131. package/dist/shared/apply-policies.d.ts +10 -0
  132. package/dist/shared/automations.repository.d1.d.ts +12 -0
  133. package/dist/shared/background-notification-service.d.ts +18 -0
  134. package/dist/shared/base.repository.d1.d.ts +18 -0
  135. package/dist/shared/content-utils.d.ts +21 -0
  136. package/dist/shared/content.repository.d1.d.ts +68 -0
  137. package/dist/shared/d1-activity-log.repository.d.ts +13 -0
  138. package/dist/shared/d1-activity-logger.d.ts +20 -0
  139. package/dist/shared/d1-analytics.repository.d.ts +20 -0
  140. package/dist/shared/d1-content-scan.repository.d.ts +7 -0
  141. package/dist/shared/d1-notification.repository.d.ts +17 -0
  142. package/dist/shared/d1-password-reset-token.repository.d.ts +10 -0
  143. package/dist/shared/d1-search.repository.d.ts +14 -0
  144. package/dist/shared/d1-session.repository.d.ts +12 -0
  145. package/dist/shared/d1-setup-checklist.repository.d.ts +12 -0
  146. package/dist/shared/d1-user.repository.d.ts +18 -0
  147. package/dist/shared/d1-widget.repository.d.ts +31 -0
  148. package/dist/shared/dashboard-layout.repository.d1.d.ts +9 -0
  149. package/dist/shared/demo-data-sql.d.ts +1 -0
  150. package/dist/shared/demo-data.repository.d1.d.ts +6 -0
  151. package/dist/shared/execution-context-scheduler.d.ts +6 -0
  152. package/dist/shared/fixed-clock.d.ts +13 -0
  153. package/dist/shared/fts-sync.d.ts +1 -0
  154. package/dist/shared/idempotency.repository.d1.d.ts +16 -0
  155. package/dist/shared/in-memory-activity-logger.d.ts +11 -0
  156. package/dist/shared/in-memory-notification-service.d.ts +11 -0
  157. package/dist/shared/in-memory-seed.repository.d.ts +18 -0
  158. package/dist/shared/media.repository.d1.d.ts +35 -0
  159. package/dist/shared/qstash-notification-service.d.ts +18 -0
  160. package/dist/shared/query-utils.d.ts +36 -0
  161. package/dist/shared/request-utils.d.ts +13 -0
  162. package/dist/shared/schema-mutator.d1.d.ts +12 -0
  163. package/dist/shared/seed-layout.repository.d1.d.ts +9 -0
  164. package/dist/shared/seed-registry-cache.d.ts +12 -0
  165. package/dist/shared/seed.repository.d1.d.ts +13 -0
  166. package/dist/shared/sequential-id-generator.d.ts +13 -0
  167. package/dist/shared/site-settings.repository.d1.d.ts +7 -0
  168. package/dist/shared/storage/factory.d.ts +8 -0
  169. package/dist/shared/storage/s3-bucket.d.ts +43 -0
  170. package/dist/shared/storage-utils.d.ts +7 -0
  171. package/dist/shared/system-stats.repository.d1.d.ts +25 -0
  172. package/dist/types.d.ts +85 -0
  173. package/dist/upload.d.ts +16 -0
  174. package/dist/widget.d.ts +7 -0
  175. package/migrations/0000_v040_base.sql +265 -265
  176. package/migrations/0029_automations.sql +14 -14
  177. package/migrations/0030_test_seeds.sql +125 -125
  178. package/package.json +27 -18
  179. package/assets/dashboard/assets/index-BSjk0Sx9.js +0 -634
  180. package/assets/dashboard/assets/index-kRCYVN2B.css +0 -1
  181. package/src/auth/__fixtures__/in-memory-hash-provider.ts +0 -17
  182. package/src/auth/__fixtures__/static-token-service.ts +0 -22
  183. package/src/auth/bcrypt-hash-provider.ts +0 -24
  184. package/src/auth/constants.ts +0 -14
  185. package/src/auth/generate-refresh-token.test.ts +0 -23
  186. package/src/auth/hash-provider.test.ts +0 -55
  187. package/src/auth/jose-token-service.ts +0 -62
  188. package/src/auth/jwt-claims-passthrough.test.ts +0 -87
  189. package/src/auth/login.test.ts +0 -100
  190. package/src/auth/login.ts +0 -78
  191. package/src/auth/refresh.ts +0 -11
  192. package/src/auth/token-service.test.ts +0 -90
  193. package/src/factory.ts +0 -368
  194. package/src/features/automations/__tests__/action-executors.test.ts +0 -255
  195. package/src/features/automations/__tests__/automation-runner.test.ts +0 -196
  196. package/src/features/automations/__tests__/automation-runner.utils.test.ts +0 -60
  197. package/src/features/automations/__tests__/automations.handler.test.ts +0 -264
  198. package/src/features/automations/__tests__/automations.repository.test.ts +0 -163
  199. package/src/features/automations/__tests__/automations.schema.test.ts +0 -224
  200. package/src/features/automations/__tests__/context-resolver.test.ts +0 -126
  201. package/src/features/automations/__tests__/cron-runner.test.ts +0 -267
  202. package/src/features/automations/__tests__/cron-runner.utils.test.ts +0 -144
  203. package/src/features/automations/__tests__/set-variable.executor.test.ts +0 -383
  204. package/src/features/automations/__tests__/template-grammar.test.ts +0 -308
  205. package/src/features/automations/__tests__/webhook.executor.test.ts +0 -142
  206. package/src/features/automations/__tests__/when-evaluator.test.ts +0 -274
  207. package/src/features/automations/__tests__/when-pushdown.test.ts +0 -281
  208. package/src/features/automations/action-executors/create-entry.executor.ts +0 -27
  209. package/src/features/automations/action-executors/edit-field.executor.ts +0 -26
  210. package/src/features/automations/action-executors/index.ts +0 -37
  211. package/src/features/automations/action-executors/send-mail.executor.ts +0 -53
  212. package/src/features/automations/action-executors/set-variable.executor.ts +0 -159
  213. package/src/features/automations/action-executors/webhook.executor.ts +0 -67
  214. package/src/features/automations/automation-runner.ts +0 -85
  215. package/src/features/automations/automation-runner.utils.ts +0 -47
  216. package/src/features/automations/automations.handler.ts +0 -197
  217. package/src/features/automations/automations.schema.ts +0 -177
  218. package/src/features/automations/context-resolver.ts +0 -152
  219. package/src/features/automations/cron-runner.ts +0 -140
  220. package/src/features/automations/cron-runner.utils.ts +0 -44
  221. package/src/features/automations/filter-translation.ts +0 -46
  222. package/src/features/automations/index.ts +0 -16
  223. package/src/features/automations/template-grammar.ts +0 -245
  224. package/src/features/automations/var-access-resolver.ts +0 -140
  225. package/src/features/automations/when-evaluator.ts +0 -87
  226. package/src/features/automations/when-pushdown.ts +0 -57
  227. package/src/features/backrefs/__tests__/backrefs.handler.test.ts +0 -359
  228. package/src/features/backrefs/backrefs.handler.ts +0 -168
  229. package/src/features/backrefs/d1-backref.repository.ts +0 -84
  230. package/src/features/backrefs/index.ts +0 -5
  231. package/src/features/content/constants.ts +0 -16
  232. package/src/features/content/handlers/bulk.handler.ts +0 -185
  233. package/src/features/content/handlers/create.ts +0 -129
  234. package/src/features/content/handlers/delete.ts +0 -62
  235. package/src/features/content/handlers/facets.ts +0 -49
  236. package/src/features/content/handlers/get.ts +0 -120
  237. package/src/features/content/handlers/helpers.test.ts +0 -180
  238. package/src/features/content/handlers/helpers.ts +0 -93
  239. package/src/features/content/handlers/list.ts +0 -174
  240. package/src/features/content/handlers/update.ts +0 -174
  241. package/src/features/content/index.ts +0 -26
  242. package/src/features/draft/draft.handler.ts +0 -195
  243. package/src/features/draft/draft.middleware.ts +0 -66
  244. package/src/features/draft/index.ts +0 -5
  245. package/src/features/email/email.service.ts +0 -98
  246. package/src/features/email/email.types.ts +0 -119
  247. package/src/features/email/providers/resend.ts +0 -67
  248. package/src/features/email/providers/smtp.ts +0 -55
  249. package/src/features/email/templates/automation-mail.ts +0 -19
  250. package/src/features/email/templates/password-changed.ts +0 -63
  251. package/src/features/email/templates/password-reset.ts +0 -68
  252. package/src/features/email/templates/shell.ts +0 -96
  253. package/src/features/notifications/index.ts +0 -5
  254. package/src/features/notifications/notifications.handler.ts +0 -105
  255. package/src/features/password-reset/index.ts +0 -19
  256. package/src/features/password-reset/request.ts +0 -92
  257. package/src/features/password-reset/reset.ts +0 -102
  258. package/src/features/rotate-field/index.ts +0 -5
  259. package/src/features/rotate-field/rotate-field.handler.ts +0 -132
  260. package/src/features/rotate-field/rotate-field.schema.ts +0 -17
  261. package/src/features/schema/schema.handler.ts +0 -131
  262. package/src/features/seeds/index.ts +0 -5
  263. package/src/features/seeds/seeds.handler.test.ts +0 -632
  264. package/src/features/seeds/seeds.handler.ts +0 -693
  265. package/src/features/settings/__tests__/settings.handler.test.ts +0 -555
  266. package/src/features/settings/settings.handler.ts +0 -392
  267. package/src/features/setup/index.ts +0 -204
  268. package/src/features/stats/index.ts +0 -5
  269. package/src/features/stats/stats.handler.ts +0 -420
  270. package/src/features/webhooks/index.ts +0 -63
  271. package/src/index.ts +0 -65
  272. package/src/media-utils.ts +0 -82
  273. package/src/middleware/auth-providers.middleware.ts +0 -45
  274. package/src/middleware/observability.middleware.ts +0 -70
  275. package/src/middleware/rate-limit.middleware.ts +0 -45
  276. package/src/middleware/repository.middleware.ts +0 -114
  277. package/src/middleware/seed-registry.middleware.test.ts +0 -97
  278. package/src/middleware/seed-registry.middleware.ts +0 -21
  279. package/src/middleware/storage.middleware.ts +0 -25
  280. package/src/middleware.ts +0 -45
  281. package/src/public/access-policy.ts +0 -27
  282. package/src/public/api-key-middleware.ts +0 -57
  283. package/src/public/cache-utils.ts +0 -38
  284. package/src/public/entry-projection.ts +0 -46
  285. package/src/public/idempotency.ts +0 -23
  286. package/src/public/index.ts +0 -16
  287. package/src/public/problem-details.ts +0 -124
  288. package/src/public/public-add.ts +0 -114
  289. package/src/public/public-edit.ts +0 -163
  290. package/src/public/public-errors.ts +0 -19
  291. package/src/public/public-read.ts +0 -63
  292. package/src/public/public-routes.ts +0 -88
  293. package/src/public/query-builder.test.ts +0 -224
  294. package/src/public/query-builder.ts +0 -156
  295. package/src/public/rate-limit-middleware.ts +0 -34
  296. package/src/public/read-list.ts +0 -54
  297. package/src/public/read-single.ts +0 -48
  298. package/src/public/response-builder.ts +0 -30
  299. package/src/public/sanitize.ts +0 -69
  300. package/src/public/slug-utils.ts +0 -18
  301. package/src/rate-limit/cloudflare-rate-limiter.test.ts +0 -30
  302. package/src/rate-limit/cloudflare-rate-limiter.ts +0 -15
  303. package/src/rate-limit/in-memory-rate-limiter.test.ts +0 -37
  304. package/src/rate-limit/in-memory-rate-limiter.ts +0 -17
  305. package/src/rate-limit/no-op-rate-limiter.test.ts +0 -22
  306. package/src/rate-limit/no-op-rate-limiter.ts +0 -11
  307. package/src/search-utils.test.ts +0 -211
  308. package/src/search-utils.ts +0 -213
  309. package/src/search.ts +0 -65
  310. package/src/shared/apply-policies.test.ts +0 -81
  311. package/src/shared/apply-policies.ts +0 -67
  312. package/src/shared/automations.repository.d1.ts +0 -150
  313. package/src/shared/background-notification-service.test.ts +0 -62
  314. package/src/shared/background-notification-service.ts +0 -52
  315. package/src/shared/base.repository.d1.ts +0 -32
  316. package/src/shared/content-utils.test.ts +0 -165
  317. package/src/shared/content-utils.ts +0 -86
  318. package/src/shared/content.repository.d1.test.ts +0 -458
  319. package/src/shared/content.repository.d1.ts +0 -851
  320. package/src/shared/d1-activity-log.repository.test.ts +0 -140
  321. package/src/shared/d1-activity-log.repository.ts +0 -105
  322. package/src/shared/d1-activity-logger.test.ts +0 -86
  323. package/src/shared/d1-activity-logger.ts +0 -67
  324. package/src/shared/d1-analytics.repository.test.ts +0 -78
  325. package/src/shared/d1-analytics.repository.ts +0 -85
  326. package/src/shared/d1-content-scan.repository.test.ts +0 -80
  327. package/src/shared/d1-content-scan.repository.ts +0 -37
  328. package/src/shared/d1-notification.repository.test.ts +0 -128
  329. package/src/shared/d1-notification.repository.ts +0 -118
  330. package/src/shared/d1-password-reset-token.repository.test.ts +0 -81
  331. package/src/shared/d1-password-reset-token.repository.ts +0 -56
  332. package/src/shared/d1-search.repository.test.ts +0 -87
  333. package/src/shared/d1-search.repository.ts +0 -88
  334. package/src/shared/d1-session.repository.test.ts +0 -125
  335. package/src/shared/d1-session.repository.ts +0 -102
  336. package/src/shared/d1-setup-checklist.repository.ts +0 -36
  337. package/src/shared/d1-user.repository.test.ts +0 -151
  338. package/src/shared/d1-user.repository.ts +0 -119
  339. package/src/shared/d1-widget.repository.test.ts +0 -221
  340. package/src/shared/d1-widget.repository.ts +0 -341
  341. package/src/shared/demo-data-sql.ts +0 -54
  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 -51
  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.ts +0 -64
  358. package/src/shared/seed-layout.repository.d1.test.ts +0 -114
  359. package/src/shared/seed-layout.repository.d1.ts +0 -62
  360. package/src/shared/seed-registry-cache.test.ts +0 -68
  361. package/src/shared/seed-registry-cache.ts +0 -49
  362. package/src/shared/seed.repository.d1.test.ts +0 -143
  363. package/src/shared/seed.repository.d1.ts +0 -98
  364. package/src/shared/sequential-id-generator.ts +0 -33
  365. package/src/shared/site-settings.repository.d1.ts +0 -53
  366. package/src/shared/storage/factory.ts +0 -41
  367. package/src/shared/storage/s3-bucket.ts +0 -195
  368. package/src/shared/storage-utils.ts +0 -40
  369. package/src/shared/system-stats.repository.d1.test.ts +0 -58
  370. package/src/shared/system-stats.repository.d1.ts +0 -48
  371. package/src/types.ts +0 -87
  372. package/src/upload.ts +0 -198
  373. package/src/widget.ts +0 -212
@@ -1,274 +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 { describe, it, expect } from 'vitest'
6
- import type { WhenNode } from '@beechcms/core'
7
- import { evaluateWhen } from '../when-evaluator'
8
- import type { ResolvedContext } from '../context-resolver'
9
- import { parseTemplateKey } from '../template-grammar'
10
-
11
- // ---------------------------------------------------------------------------
12
- // Minimal ResolvedContext builder for testing
13
- // ---------------------------------------------------------------------------
14
-
15
- function makeContext(entry: Record<string, unknown>): ResolvedContext {
16
- return {
17
- triggerEntry: entry,
18
- lookup(parsed, onMissing) {
19
- if (!parsed) return undefined
20
- if (parsed.kind === 'simple') {
21
- const parts = parsed.path.split('.')
22
- let cur: unknown = entry
23
- for (const p of parts) {
24
- cur = (cur as Record<string, unknown>)?.[p]
25
- }
26
- if (cur === undefined && onMissing) onMissing(parsed.path)
27
- return cur
28
- }
29
- if (parsed.kind === 'scoped' && parsed.scope === 'this' && parsed.op === 'field' && parsed.field) {
30
- return (entry as Record<string, unknown>)[parsed.field]
31
- }
32
- return undefined
33
- },
34
- }
35
- }
36
-
37
- const entry = { status: 'paid', total: 150, name: 'Alice', tag: 'gold' }
38
- const ctx = makeContext(entry)
39
-
40
- // ---------------------------------------------------------------------------
41
- // null / empty → true
42
- // ---------------------------------------------------------------------------
43
-
44
- describe('evaluateWhen — null/empty', () => {
45
- it('null node returns true', () => {
46
- expect(evaluateWhen(null, ctx)).toBe(true)
47
- })
48
-
49
- it('empty AND group returns true', () => {
50
- const node: WhenNode = { kind: 'group', op: 'AND', children: [] }
51
- expect(evaluateWhen(node, ctx)).toBe(true)
52
- })
53
-
54
- it('empty OR group returns false', () => {
55
- const node: WhenNode = { kind: 'group', op: 'OR', children: [] }
56
- expect(evaluateWhen(node, ctx)).toBe(false)
57
- })
58
- })
59
-
60
- // ---------------------------------------------------------------------------
61
- // Basic predicates
62
- // ---------------------------------------------------------------------------
63
-
64
- describe('evaluateWhen — predicates', () => {
65
- it('eq literal', () => {
66
- const node: WhenNode = {
67
- kind: 'predicate',
68
- left: { kind: 'ref', key: 'this.status' },
69
- op: 'eq',
70
- right: { kind: 'literal', value: 'paid' },
71
- }
72
- expect(evaluateWhen(node, ctx)).toBe(true)
73
- })
74
-
75
- it('eq literal fails', () => {
76
- const node: WhenNode = {
77
- kind: 'predicate',
78
- left: { kind: 'ref', key: 'this.status' },
79
- op: 'eq',
80
- right: { kind: 'literal', value: 'unpaid' },
81
- }
82
- expect(evaluateWhen(node, ctx)).toBe(false)
83
- })
84
-
85
- it('gt numeric', () => {
86
- const node: WhenNode = {
87
- kind: 'predicate',
88
- left: { kind: 'ref', key: 'this.total' },
89
- op: 'gt',
90
- right: { kind: 'literal', value: 100 },
91
- }
92
- expect(evaluateWhen(node, ctx)).toBe(true)
93
- })
94
-
95
- it('lte numeric', () => {
96
- const node: WhenNode = {
97
- kind: 'predicate',
98
- left: { kind: 'ref', key: 'this.total' },
99
- op: 'lte',
100
- right: { kind: 'literal', value: 150 },
101
- }
102
- expect(evaluateWhen(node, ctx)).toBe(true)
103
- })
104
-
105
- it('contains string', () => {
106
- const node: WhenNode = {
107
- kind: 'predicate',
108
- left: { kind: 'ref', key: 'this.name' },
109
- op: 'contains',
110
- right: { kind: 'literal', value: 'lic' },
111
- }
112
- expect(evaluateWhen(node, ctx)).toBe(true)
113
- })
114
-
115
- it('startswith', () => {
116
- const node: WhenNode = {
117
- kind: 'predicate',
118
- left: { kind: 'ref', key: 'this.name' },
119
- op: 'startswith',
120
- right: { kind: 'literal', value: 'Ali' },
121
- }
122
- expect(evaluateWhen(node, ctx)).toBe(true)
123
- })
124
-
125
- it('isempty — non-empty field', () => {
126
- const node: WhenNode = {
127
- kind: 'predicate',
128
- left: { kind: 'ref', key: 'this.status' },
129
- op: 'isempty',
130
- }
131
- expect(evaluateWhen(node, ctx)).toBe(false)
132
- })
133
-
134
- it('isnotempty — non-empty field', () => {
135
- const node: WhenNode = {
136
- kind: 'predicate',
137
- left: { kind: 'ref', key: 'this.status' },
138
- op: 'isnotempty',
139
- }
140
- expect(evaluateWhen(node, ctx)).toBe(true)
141
- })
142
-
143
- it('matches regex', () => {
144
- const node: WhenNode = {
145
- kind: 'predicate',
146
- left: { kind: 'ref', key: 'this.tag' },
147
- op: 'matches',
148
- right: { kind: 'literal', value: '^g' },
149
- }
150
- expect(evaluateWhen(node, ctx)).toBe(true)
151
- })
152
-
153
- it('literal-to-literal comparison', () => {
154
- const node: WhenNode = {
155
- kind: 'predicate',
156
- left: { kind: 'literal', value: 10 },
157
- op: 'lt',
158
- right: { kind: 'literal', value: 20 },
159
- }
160
- expect(evaluateWhen(node, ctx)).toBe(true)
161
- })
162
- })
163
-
164
- // ---------------------------------------------------------------------------
165
- // AND / OR groups with short-circuit
166
- // ---------------------------------------------------------------------------
167
-
168
- describe('evaluateWhen — groups', () => {
169
- it('AND group — all true', () => {
170
- const node: WhenNode = {
171
- kind: 'group',
172
- op: 'AND',
173
- children: [
174
- { kind: 'predicate', left: { kind: 'ref', key: 'this.status' }, op: 'eq', right: { kind: 'literal', value: 'paid' } },
175
- { kind: 'predicate', left: { kind: 'ref', key: 'this.total' }, op: 'gt', right: { kind: 'literal', value: 100 } },
176
- ],
177
- }
178
- expect(evaluateWhen(node, ctx)).toBe(true)
179
- })
180
-
181
- it('AND group — one false', () => {
182
- const node: WhenNode = {
183
- kind: 'group',
184
- op: 'AND',
185
- children: [
186
- { kind: 'predicate', left: { kind: 'ref', key: 'this.status' }, op: 'eq', right: { kind: 'literal', value: 'paid' } },
187
- { kind: 'predicate', left: { kind: 'ref', key: 'this.total' }, op: 'gt', right: { kind: 'literal', value: 200 } },
188
- ],
189
- }
190
- expect(evaluateWhen(node, ctx)).toBe(false)
191
- })
192
-
193
- it('OR group — first true short-circuits', () => {
194
- const node: WhenNode = {
195
- kind: 'group',
196
- op: 'OR',
197
- children: [
198
- { kind: 'predicate', left: { kind: 'ref', key: 'this.status' }, op: 'eq', right: { kind: 'literal', value: 'paid' } },
199
- { kind: 'predicate', left: { kind: 'ref', key: 'this.total' }, op: 'gt', right: { kind: 'literal', value: 200 } },
200
- ],
201
- }
202
- expect(evaluateWhen(node, ctx)).toBe(true)
203
- })
204
-
205
- it('negate wraps group result', () => {
206
- const node: WhenNode = {
207
- kind: 'group',
208
- op: 'AND',
209
- negate: true,
210
- children: [
211
- { kind: 'predicate', left: { kind: 'ref', key: 'this.status' }, op: 'eq', right: { kind: 'literal', value: 'paid' } },
212
- ],
213
- }
214
- expect(evaluateWhen(node, ctx)).toBe(false)
215
- })
216
-
217
- it('nested AND inside OR', () => {
218
- const node: WhenNode = {
219
- kind: 'group',
220
- op: 'AND',
221
- children: [
222
- { kind: 'predicate', left: { kind: 'ref', key: 'this.total' }, op: 'gt', right: { kind: 'literal', value: 100 } },
223
- {
224
- kind: 'group',
225
- op: 'OR',
226
- children: [
227
- { kind: 'predicate', left: { kind: 'ref', key: 'this.tag' }, op: 'eq', right: { kind: 'literal', value: 'gold' } },
228
- { kind: 'predicate', left: { kind: 'ref', key: 'this.total' }, op: 'gt', right: { kind: 'literal', value: 5000 } },
229
- ],
230
- },
231
- ],
232
- }
233
- expect(evaluateWhen(node, ctx)).toBe(true)
234
- })
235
- })
236
-
237
- // ---------------------------------------------------------------------------
238
- // null handling
239
- // ---------------------------------------------------------------------------
240
-
241
- describe('evaluateWhen — null operands', () => {
242
- const emptyCtx = makeContext({})
243
-
244
- it('null == null → eq true', () => {
245
- const node: WhenNode = {
246
- kind: 'predicate',
247
- left: { kind: 'ref', key: 'this.missing' },
248
- op: 'eq',
249
- right: { kind: 'literal', value: null },
250
- }
251
- expect(evaluateWhen(node, emptyCtx)).toBe(true)
252
- })
253
-
254
- it('null isempty → true', () => {
255
- const node: WhenNode = {
256
- kind: 'predicate',
257
- left: { kind: 'ref', key: 'this.missing' },
258
- op: 'isempty',
259
- }
260
- expect(evaluateWhen(node, emptyCtx)).toBe(true)
261
- })
262
-
263
- it('null gt 0 → false (no exception)', () => {
264
- const node: WhenNode = {
265
- kind: 'predicate',
266
- left: { kind: 'ref', key: 'this.missing' },
267
- op: 'gt',
268
- right: { kind: 'literal', value: 0 },
269
- }
270
- expect(() => evaluateWhen(node, emptyCtx)).not.toThrow()
271
- expect(evaluateWhen(node, emptyCtx)).toBe(false)
272
- })
273
- })
274
-
@@ -1,281 +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 { describe, it, expect } from 'vitest'
6
- import type { WhenNode, Seed } from '@beechcms/core'
7
- import { extractPushdownFilters } from '../when-pushdown'
8
-
9
- // ---------------------------------------------------------------------------
10
- // Minimal Seed
11
- // ---------------------------------------------------------------------------
12
-
13
- function makeSeed(aliases: string[] = []): Seed {
14
- return {
15
- slug: 'orders',
16
- label: 'Orders',
17
- displayNameAlias: aliases[0] ?? 'id',
18
- branches: aliases.map((alias, i) => ({ id: `br_0${i + 1}`, alias, label: alias, type: 'text' as const })),
19
- }
20
- }
21
-
22
- const seed = makeSeed(['status', 'total', 'name', 'tag'])
23
-
24
- // ---------------------------------------------------------------------------
25
- // null / empty
26
- // ---------------------------------------------------------------------------
27
-
28
- describe('extractPushdownFilters — null/empty', () => {
29
- it('null returns []', () => {
30
- expect(extractPushdownFilters(null, seed)).toEqual([])
31
- })
32
-
33
- it('empty AND group returns []', () => {
34
- const node: WhenNode = { kind: 'group', op: 'AND', children: [] }
35
- expect(extractPushdownFilters(node, seed)).toEqual([])
36
- })
37
-
38
- it('empty OR group returns []', () => {
39
- const node: WhenNode = { kind: 'group', op: 'OR', children: [] }
40
- expect(extractPushdownFilters(node, seed)).toEqual([])
41
- })
42
- })
43
-
44
- // ---------------------------------------------------------------------------
45
- // Safe single-predicate push-down
46
- // ---------------------------------------------------------------------------
47
-
48
- describe('extractPushdownFilters — safe predicates', () => {
49
- it('root eq predicate is pushed', () => {
50
- const node: WhenNode = {
51
- kind: 'predicate',
52
- left: { kind: 'ref', key: 'this.status' },
53
- op: 'eq',
54
- right: { kind: 'literal', value: 'paid' },
55
- }
56
- const result = extractPushdownFilters(node, seed)
57
- expect(result).toHaveLength(1)
58
- expect(result[0].column).toBe('status')
59
- expect(result[0].conditions[0].op).toBe('eq')
60
- expect(result[0].conditions[0].value).toBe('paid')
61
- })
62
-
63
- it('root neq predicate is pushed', () => {
64
- const node: WhenNode = {
65
- kind: 'predicate',
66
- left: { kind: 'ref', key: 'this.status' },
67
- op: 'neq',
68
- right: { kind: 'literal', value: 'cancelled' },
69
- }
70
- const result = extractPushdownFilters(node, seed)
71
- expect(result).toHaveLength(1)
72
- expect(result[0].conditions[0].op).toBe('neq')
73
- })
74
-
75
- it('root gt predicate is pushed', () => {
76
- const node: WhenNode = {
77
- kind: 'predicate',
78
- left: { kind: 'ref', key: 'this.total' },
79
- op: 'gt',
80
- right: { kind: 'literal', value: 100 },
81
- }
82
- const result = extractPushdownFilters(node, seed)
83
- expect(result).toHaveLength(1)
84
- expect(result[0].conditions[0].op).toBe('gt')
85
- })
86
-
87
- it('root lt predicate is pushed', () => {
88
- const node: WhenNode = {
89
- kind: 'predicate',
90
- left: { kind: 'ref', key: 'this.total' },
91
- op: 'lt',
92
- right: { kind: 'literal', value: 500 },
93
- }
94
- const result = extractPushdownFilters(node, seed)
95
- expect(result).toHaveLength(1)
96
- expect(result[0].conditions[0].op).toBe('lt')
97
- })
98
-
99
- it('root contains predicate is pushed', () => {
100
- const node: WhenNode = {
101
- kind: 'predicate',
102
- left: { kind: 'ref', key: 'this.name' },
103
- op: 'contains',
104
- right: { kind: 'literal', value: 'Alice' },
105
- }
106
- const result = extractPushdownFilters(node, seed)
107
- expect(result).toHaveLength(1)
108
- expect(result[0].conditions[0].op).toBe('contains')
109
- })
110
-
111
- it('root isempty predicate is pushed (no right operand)', () => {
112
- const node: WhenNode = {
113
- kind: 'predicate',
114
- left: { kind: 'ref', key: 'this.name' },
115
- op: 'isempty',
116
- }
117
- const result = extractPushdownFilters(node, seed)
118
- expect(result).toHaveLength(1)
119
- expect(result[0].conditions[0].op).toBe('is_empty')
120
- })
121
-
122
- it('root isnotempty predicate is pushed (no right operand)', () => {
123
- const node: WhenNode = {
124
- kind: 'predicate',
125
- left: { kind: 'ref', key: 'this.name' },
126
- op: 'isnotempty',
127
- }
128
- const result = extractPushdownFilters(node, seed)
129
- expect(result).toHaveLength(1)
130
- expect(result[0].conditions[0].op).toBe('is_not_empty')
131
- })
132
- })
133
-
134
- // ---------------------------------------------------------------------------
135
- // AND group — only direct safe predicate children are pushed
136
- // ---------------------------------------------------------------------------
137
-
138
- describe('extractPushdownFilters — AND group', () => {
139
- it('all safe AND children are pushed', () => {
140
- const node: WhenNode = {
141
- kind: 'group',
142
- op: 'AND',
143
- children: [
144
- { kind: 'predicate', left: { kind: 'ref', key: 'this.status' }, op: 'eq', right: { kind: 'literal', value: 'paid' } },
145
- { kind: 'predicate', left: { kind: 'ref', key: 'this.total' }, op: 'gt', right: { kind: 'literal', value: 100 } },
146
- ],
147
- }
148
- const result = extractPushdownFilters(node, seed)
149
- expect(result).toHaveLength(2)
150
- expect(result.map((r) => r.column)).toContain('status')
151
- expect(result.map((r) => r.column)).toContain('total')
152
- })
153
-
154
- it('mixed AND: unsafe children skipped, safe ones pushed', () => {
155
- const node: WhenNode = {
156
- kind: 'group',
157
- op: 'AND',
158
- children: [
159
- { kind: 'predicate', left: { kind: 'ref', key: 'this.status' }, op: 'eq', right: { kind: 'literal', value: 'paid' } },
160
- // gte is not in PUSHDOWN_OPS → skipped
161
- { kind: 'predicate', left: { kind: 'ref', key: 'this.total' }, op: 'gte', right: { kind: 'literal', value: 100 } },
162
- ],
163
- }
164
- const result = extractPushdownFilters(node, seed)
165
- expect(result).toHaveLength(1)
166
- expect(result[0].column).toBe('status')
167
- })
168
- })
169
-
170
- // ---------------------------------------------------------------------------
171
- // Unsafe operators stay in-memory
172
- // ---------------------------------------------------------------------------
173
-
174
- describe('extractPushdownFilters — unsafe operators stay in-memory', () => {
175
- for (const op of ['gte', 'lte', 'startswith', 'endswith', 'matches', 'in', 'notin'] as const) {
176
- it(`${op} is NOT pushed`, () => {
177
- const node: WhenNode = {
178
- kind: 'predicate',
179
- left: { kind: 'ref', key: 'this.status' },
180
- op,
181
- right: { kind: 'literal', value: 'x' },
182
- }
183
- expect(extractPushdownFilters(node, seed)).toHaveLength(0)
184
- })
185
- }
186
- })
187
-
188
- // ---------------------------------------------------------------------------
189
- // OR branches stay in-memory
190
- // ---------------------------------------------------------------------------
191
-
192
- describe('extractPushdownFilters — OR branches stay in-memory', () => {
193
- it('OR root group returns []', () => {
194
- const node: WhenNode = {
195
- kind: 'group',
196
- op: 'OR',
197
- children: [
198
- { kind: 'predicate', left: { kind: 'ref', key: 'this.status' }, op: 'eq', right: { kind: 'literal', value: 'paid' } },
199
- { kind: 'predicate', left: { kind: 'ref', key: 'this.total' }, op: 'gt', right: { kind: 'literal', value: 100 } },
200
- ],
201
- }
202
- expect(extractPushdownFilters(node, seed)).toHaveLength(0)
203
- })
204
-
205
- it('AND group with nested OR child: only direct predicate siblings are pushed', () => {
206
- const node: WhenNode = {
207
- kind: 'group',
208
- op: 'AND',
209
- children: [
210
- { kind: 'predicate', left: { kind: 'ref', key: 'this.status' }, op: 'eq', right: { kind: 'literal', value: 'paid' } },
211
- {
212
- kind: 'group',
213
- op: 'OR',
214
- children: [
215
- { kind: 'predicate', left: { kind: 'ref', key: 'this.total' }, op: 'gt', right: { kind: 'literal', value: 100 } },
216
- { kind: 'predicate', left: { kind: 'ref', key: 'this.tag' }, op: 'eq', right: { kind: 'literal', value: 'gold' } },
217
- ],
218
- },
219
- ],
220
- }
221
- const result = extractPushdownFilters(node, seed)
222
- // Only the direct 'status' predicate is pushed; the nested OR group is skipped
223
- expect(result).toHaveLength(1)
224
- expect(result[0].column).toBe('status')
225
- })
226
- })
227
-
228
- // ---------------------------------------------------------------------------
229
- // Negated group stays in-memory
230
- // ---------------------------------------------------------------------------
231
-
232
- describe('extractPushdownFilters — negated AND group stays in-memory', () => {
233
- it('negated AND root returns []', () => {
234
- const node: WhenNode = {
235
- kind: 'group',
236
- op: 'AND',
237
- negate: true,
238
- children: [
239
- { kind: 'predicate', left: { kind: 'ref', key: 'this.status' }, op: 'eq', right: { kind: 'literal', value: 'paid' } },
240
- ],
241
- }
242
- expect(extractPushdownFilters(node, seed)).toHaveLength(0)
243
- })
244
- })
245
-
246
- // ---------------------------------------------------------------------------
247
- // Cross-seed refs stay in-memory
248
- // ---------------------------------------------------------------------------
249
-
250
- describe('extractPushdownFilters — cross-seed refs stay in-memory', () => {
251
- it('ref not starting with this. is NOT pushed', () => {
252
- const node: WhenNode = {
253
- kind: 'predicate',
254
- left: { kind: 'ref', key: 'customers:lastone:status' },
255
- op: 'eq',
256
- right: { kind: 'literal', value: 'active' },
257
- }
258
- expect(extractPushdownFilters(node, seed)).toHaveLength(0)
259
- })
260
-
261
- it('right operand is a ref (not literal) → NOT pushed', () => {
262
- const node: WhenNode = {
263
- kind: 'predicate',
264
- left: { kind: 'ref', key: 'this.status' },
265
- op: 'eq',
266
- right: { kind: 'ref', key: 'customers:lastone:status' },
267
- }
268
- expect(extractPushdownFilters(node, seed)).toHaveLength(0)
269
- })
270
-
271
- it('literal left operand is NOT pushed', () => {
272
- const node: WhenNode = {
273
- kind: 'predicate',
274
- left: { kind: 'literal', value: 'paid' },
275
- op: 'eq',
276
- right: { kind: 'literal', value: 'paid' },
277
- }
278
- expect(extractPushdownFilters(node, seed)).toHaveLength(0)
279
- })
280
- })
281
-
@@ -1,27 +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 type { AutomationAction, ContentRepository, Seed, IIdGenerator } from '@beechcms/core'
6
-
7
- type CreateEntryAction = Extract<AutomationAction, { type: 'create_entry' }>
8
- type SeedResolver = (slug: string) => Seed | null
9
-
10
- export async function executeCreateEntry(
11
- action: CreateEntryAction,
12
- entry: Record<string, unknown>,
13
- repository: ContentRepository,
14
- getSeed: SeedResolver,
15
- idGenerator: IIdGenerator,
16
- ): Promise<void> {
17
- const targetSeed = getSeed(action.seed_slug)
18
- if (!targetSeed) throw new Error(`create_entry: unknown seed ${action.seed_slug}`)
19
-
20
- const payload: Record<string, unknown> = {}
21
- for (const [targetField, sourceField] of Object.entries(action.field_map)) {
22
- payload[targetField] = (sourceField as string) in entry ? entry[sourceField as string] : sourceField
23
- }
24
-
25
- const newId = idGenerator.uuid()
26
- await repository.create(targetSeed, newId, newId, 'draft', payload)
27
- }
@@ -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 type { AutomationAction, ContentRepository, Seed } from '@beechcms/core'
6
- import type { ResolvedContext } from '../context-resolver'
7
- import { interpolate } from '../automation-runner.utils'
8
-
9
- type EditFieldAction = Extract<AutomationAction, { type: 'edit_field' }>
10
-
11
- export async function executeEditField(
12
- action: EditFieldAction,
13
- entry: Record<string, unknown>,
14
- context: ResolvedContext,
15
- repository: ContentRepository,
16
- seed: Seed,
17
- ): Promise<void> {
18
- const id = entry.id
19
- if (typeof id !== 'string') {
20
- throw new Error('edit_field: entry.id missing')
21
- }
22
- const resolved = typeof action.value === 'string'
23
- ? interpolate(action.value, context)
24
- : action.value
25
- await repository.update(seed, id, { [action.field]: resolved })
26
- }
@@ -1,37 +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 type { AutomationAction, ContentRepository, Seed, IIdGenerator } from '@beechcms/core'
6
- import type { ResolvedContext } from '../context-resolver'
7
- import { executeWebhook } from './webhook.executor'
8
- import { executeSendMail } from './send-mail.executor'
9
- import { executeEditField } from './edit-field.executor'
10
- import { executeCreateEntry } from './create-entry.executor'
11
- import { executeSetVariable } from './set-variable.executor'
12
-
13
- export interface ActionContext {
14
- entry: Record<string, unknown>
15
- env: Record<string, string | undefined>
16
- repository: ContentRepository
17
- getSeed: (slug: string) => Seed | null
18
- seed: Seed
19
- idGenerator: IIdGenerator
20
- context: ResolvedContext
21
- variables: Record<string, unknown>
22
- // TODO Sprint 8: context will also power evaluateWhen() for per-action when-guards
23
- }
24
-
25
- export async function executeAction(action: AutomationAction, ctx: ActionContext): Promise<void> {
26
- switch (action.type) {
27
- case 'set_variable': return executeSetVariable(action, ctx)
28
- case 'webhook': return executeWebhook(action, ctx.context, ctx.env)
29
- case 'send_mail': return executeSendMail(action, ctx.context, ctx.env)
30
- case 'edit_field': return executeEditField(action, ctx.entry, ctx.context, ctx.repository, ctx.seed)
31
- case 'create_entry': return executeCreateEntry(action, ctx.entry, ctx.repository, ctx.getSeed, ctx.idGenerator)
32
- default: {
33
- const _exhaustive: never = action
34
- throw new Error(`unknown action type: ${(action as { type: string }).type}`)
35
- }
36
- }
37
- }