@btst/stack 1.5.2 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (241) hide show
  1. package/dist/api/index.cjs +7 -1
  2. package/dist/api/index.d.cts +2 -2
  3. package/dist/api/index.d.mts +2 -2
  4. package/dist/api/index.d.ts +2 -2
  5. package/dist/api/index.mjs +7 -1
  6. package/dist/client/index.d.cts +1 -1
  7. package/dist/client/index.d.mts +1 -1
  8. package/dist/client/index.d.ts +1 -1
  9. package/dist/index.d.cts +1 -1
  10. package/dist/index.d.mts +1 -1
  11. package/dist/index.d.ts +1 -1
  12. package/dist/node_modules/.pnpm/@dnd-kit_accessibility@3.1.1_react@19.2.0/node_modules/@dnd-kit/accessibility/dist/accessibility.esm.cjs +68 -0
  13. package/dist/node_modules/.pnpm/@dnd-kit_accessibility@3.1.1_react@19.2.0/node_modules/@dnd-kit/accessibility/dist/accessibility.esm.mjs +60 -0
  14. package/dist/node_modules/.pnpm/@dnd-kit_core@6.3.1_react-dom@19.2.0_react@19.2.0__react@19.2.0/node_modules/@dnd-kit/core/dist/core.esm.cjs +3937 -0
  15. package/dist/node_modules/.pnpm/@dnd-kit_core@6.3.1_react-dom@19.2.0_react@19.2.0__react@19.2.0/node_modules/@dnd-kit/core/dist/core.esm.mjs +3907 -0
  16. package/dist/node_modules/.pnpm/@dnd-kit_modifiers@9.0.0_@dnd-kit_core@6.3.1_react-dom@19.2.0_react@19.2.0__react@19.2.0__react@19.2.0/node_modules/@dnd-kit/modifiers/dist/modifiers.esm.cjs +30 -0
  17. package/dist/node_modules/.pnpm/@dnd-kit_modifiers@9.0.0_@dnd-kit_core@6.3.1_react-dom@19.2.0_react@19.2.0__react@19.2.0__react@19.2.0/node_modules/@dnd-kit/modifiers/dist/modifiers.esm.mjs +28 -0
  18. package/dist/node_modules/.pnpm/@dnd-kit_sortable@10.0.0_@dnd-kit_core@6.3.1_react-dom@19.2.0_react@19.2.0__react@19.2.0__react@19.2.0/node_modules/@dnd-kit/sortable/dist/sortable.esm.cjs +675 -0
  19. package/dist/node_modules/.pnpm/@dnd-kit_sortable@10.0.0_@dnd-kit_core@6.3.1_react-dom@19.2.0_react@19.2.0__react@19.2.0__react@19.2.0/node_modules/@dnd-kit/sortable/dist/sortable.esm.mjs +661 -0
  20. package/dist/node_modules/.pnpm/@dnd-kit_utilities@3.2.2_react@19.2.0/node_modules/@dnd-kit/utilities/dist/utilities.esm.cjs +358 -0
  21. package/dist/node_modules/.pnpm/@dnd-kit_utilities@3.2.2_react@19.2.0/node_modules/@dnd-kit/utilities/dist/utilities.esm.mjs +332 -0
  22. package/dist/node_modules/.pnpm/@radix-ui_react-tabs@1.1.13_@types_react-dom@19.2.3_@types_react@19.2.6__@types_react@1_865f042350eb43f3338b0fffb33f6246/node_modules/@radix-ui/react-tabs/dist/index.cjs +211 -0
  23. package/dist/node_modules/.pnpm/@radix-ui_react-tabs@1.1.13_@types_react-dom@19.2.3_@types_react@19.2.6__@types_react@1_865f042350eb43f3338b0fffb33f6246/node_modules/@radix-ui/react-tabs/dist/index.mjs +188 -0
  24. package/dist/packages/better-stack/src/plugins/cms/api/plugin.cjs +3 -2
  25. package/dist/packages/better-stack/src/plugins/cms/api/plugin.mjs +3 -2
  26. package/dist/packages/better-stack/src/plugins/cms/client/components/forms/content-form.cjs +15 -15
  27. package/dist/packages/better-stack/src/plugins/cms/client/components/forms/content-form.mjs +16 -16
  28. package/dist/packages/better-stack/src/plugins/form-builder/api/plugin.cjs +588 -0
  29. package/dist/packages/better-stack/src/plugins/form-builder/api/plugin.mjs +586 -0
  30. package/dist/packages/better-stack/src/plugins/form-builder/client/components/forms/form-renderer.cjs +131 -0
  31. package/dist/packages/better-stack/src/plugins/form-builder/client/components/forms/form-renderer.mjs +129 -0
  32. package/dist/packages/better-stack/src/plugins/form-builder/client/components/loading/form-builder-skeleton.cjs +32 -0
  33. package/dist/packages/better-stack/src/plugins/form-builder/client/components/loading/form-builder-skeleton.mjs +30 -0
  34. package/dist/packages/better-stack/src/plugins/form-builder/client/components/loading/form-list-skeleton.cjs +21 -0
  35. package/dist/packages/better-stack/src/plugins/form-builder/client/components/loading/form-list-skeleton.mjs +19 -0
  36. package/dist/packages/better-stack/src/plugins/form-builder/client/components/loading/submissions-skeleton.cjs +34 -0
  37. package/dist/packages/better-stack/src/plugins/form-builder/client/components/loading/submissions-skeleton.mjs +32 -0
  38. package/dist/packages/better-stack/src/plugins/form-builder/client/components/pages/404-page.cjs +20 -0
  39. package/dist/packages/better-stack/src/plugins/form-builder/client/components/pages/404-page.mjs +18 -0
  40. package/dist/packages/better-stack/src/plugins/form-builder/client/components/pages/form-builder-page.cjs +19 -0
  41. package/dist/packages/better-stack/src/plugins/form-builder/client/components/pages/form-builder-page.internal.cjs +186 -0
  42. package/dist/packages/better-stack/src/plugins/form-builder/client/components/pages/form-builder-page.internal.mjs +184 -0
  43. package/dist/packages/better-stack/src/plugins/form-builder/client/components/pages/form-builder-page.mjs +17 -0
  44. package/dist/packages/better-stack/src/plugins/form-builder/client/components/pages/form-list-page.cjs +19 -0
  45. package/dist/packages/better-stack/src/plugins/form-builder/client/components/pages/form-list-page.internal.cjs +165 -0
  46. package/dist/packages/better-stack/src/plugins/form-builder/client/components/pages/form-list-page.internal.mjs +163 -0
  47. package/dist/packages/better-stack/src/plugins/form-builder/client/components/pages/form-list-page.mjs +17 -0
  48. package/dist/packages/better-stack/src/plugins/form-builder/client/components/pages/submissions-page.cjs +19 -0
  49. package/dist/packages/better-stack/src/plugins/form-builder/client/components/pages/submissions-page.internal.cjs +177 -0
  50. package/dist/packages/better-stack/src/plugins/form-builder/client/components/pages/submissions-page.internal.mjs +175 -0
  51. package/dist/packages/better-stack/src/plugins/form-builder/client/components/pages/submissions-page.mjs +17 -0
  52. package/dist/packages/better-stack/src/plugins/form-builder/client/components/shared/default-error.cjs +17 -0
  53. package/dist/packages/better-stack/src/plugins/form-builder/client/components/shared/default-error.mjs +15 -0
  54. package/dist/packages/better-stack/src/plugins/form-builder/client/components/shared/empty-state.cjs +16 -0
  55. package/dist/packages/better-stack/src/plugins/form-builder/client/components/shared/empty-state.mjs +14 -0
  56. package/dist/packages/better-stack/src/plugins/form-builder/client/components/shared/page-wrapper.cjs +27 -0
  57. package/dist/packages/better-stack/src/plugins/form-builder/client/components/shared/page-wrapper.mjs +25 -0
  58. package/dist/packages/better-stack/src/plugins/form-builder/client/components/shared/pagination.cjs +39 -0
  59. package/dist/packages/better-stack/src/plugins/form-builder/client/components/shared/pagination.mjs +37 -0
  60. package/dist/packages/better-stack/src/plugins/form-builder/client/hooks/form-builder-hooks.cjs +551 -0
  61. package/dist/packages/better-stack/src/plugins/form-builder/client/hooks/form-builder-hooks.mjs +537 -0
  62. package/dist/packages/better-stack/src/plugins/form-builder/client/localization/form-builder-common.cjs +36 -0
  63. package/dist/packages/better-stack/src/plugins/form-builder/client/localization/form-builder-common.mjs +34 -0
  64. package/dist/packages/better-stack/src/plugins/form-builder/client/localization/form-builder-editor.cjs +19 -0
  65. package/dist/packages/better-stack/src/plugins/form-builder/client/localization/form-builder-editor.mjs +17 -0
  66. package/dist/packages/better-stack/src/plugins/form-builder/client/localization/form-builder-list.cjs +21 -0
  67. package/dist/packages/better-stack/src/plugins/form-builder/client/localization/form-builder-list.mjs +19 -0
  68. package/dist/packages/better-stack/src/plugins/form-builder/client/localization/form-builder-submissions.cjs +19 -0
  69. package/dist/packages/better-stack/src/plugins/form-builder/client/localization/form-builder-submissions.mjs +17 -0
  70. package/dist/packages/better-stack/src/plugins/form-builder/client/localization/form-builder-toasts.cjs +14 -0
  71. package/dist/packages/better-stack/src/plugins/form-builder/client/localization/form-builder-toasts.mjs +12 -0
  72. package/dist/packages/better-stack/src/plugins/form-builder/client/localization/index.cjs +17 -0
  73. package/dist/packages/better-stack/src/plugins/form-builder/client/localization/index.mjs +15 -0
  74. package/dist/packages/better-stack/src/plugins/form-builder/client/plugin.cjs +278 -0
  75. package/dist/packages/better-stack/src/plugins/form-builder/client/plugin.mjs +276 -0
  76. package/dist/packages/better-stack/src/plugins/form-builder/db.cjs +99 -0
  77. package/dist/packages/better-stack/src/plugins/form-builder/db.mjs +97 -0
  78. package/dist/packages/better-stack/src/plugins/form-builder/schemas.cjs +82 -0
  79. package/dist/packages/better-stack/src/plugins/form-builder/schemas.mjs +74 -0
  80. package/dist/packages/better-stack/src/plugins/form-builder/utils.cjs +37 -0
  81. package/dist/packages/better-stack/src/plugins/form-builder/utils.mjs +29 -0
  82. package/dist/packages/better-stack/src/plugins/open-api/api/generator.cjs +300 -0
  83. package/dist/packages/better-stack/src/plugins/open-api/api/generator.mjs +284 -0
  84. package/dist/packages/better-stack/src/plugins/open-api/api/plugin.cjs +115 -0
  85. package/dist/packages/better-stack/src/plugins/open-api/api/plugin.mjs +113 -0
  86. package/dist/packages/better-stack/src/plugins/open-api/db.cjs +7 -0
  87. package/dist/packages/better-stack/src/plugins/open-api/db.mjs +5 -0
  88. package/dist/packages/better-stack/src/plugins/open-api/logo.cjs +8 -0
  89. package/dist/packages/better-stack/src/plugins/open-api/logo.mjs +6 -0
  90. package/dist/packages/ui/src/components/auto-form/index.cjs +2 -12
  91. package/dist/packages/ui/src/components/auto-form/index.mjs +2 -9
  92. package/dist/packages/ui/src/components/auto-form/stepped-auto-form.cjs +377 -0
  93. package/dist/packages/ui/src/components/auto-form/stepped-auto-form.mjs +368 -0
  94. package/dist/packages/ui/src/components/auto-form/utils.cjs +1 -56
  95. package/dist/packages/ui/src/components/auto-form/utils.mjs +2 -56
  96. package/dist/packages/ui/src/components/form-builder/canvas.cjs +111 -0
  97. package/dist/packages/ui/src/components/form-builder/canvas.mjs +109 -0
  98. package/dist/packages/ui/src/components/form-builder/components/index.cjs +570 -0
  99. package/dist/packages/ui/src/components/form-builder/components/index.mjs +553 -0
  100. package/dist/packages/ui/src/components/form-builder/edit-field-dialog.cjs +131 -0
  101. package/dist/packages/ui/src/components/form-builder/edit-field-dialog.mjs +129 -0
  102. package/dist/packages/ui/src/components/form-builder/form-preview.cjs +73 -0
  103. package/dist/packages/ui/src/components/form-builder/form-preview.mjs +71 -0
  104. package/dist/packages/ui/src/components/form-builder/index.cjs +353 -0
  105. package/dist/packages/ui/src/components/form-builder/index.mjs +344 -0
  106. package/dist/packages/ui/src/components/form-builder/nested-field-editor-dialog.cjs +263 -0
  107. package/dist/packages/ui/src/components/form-builder/nested-field-editor-dialog.mjs +261 -0
  108. package/dist/packages/ui/src/components/form-builder/palette.cjs +52 -0
  109. package/dist/packages/ui/src/components/form-builder/palette.mjs +49 -0
  110. package/dist/packages/ui/src/components/form-builder/schema-utils.cjs +120 -0
  111. package/dist/packages/ui/src/components/form-builder/schema-utils.mjs +114 -0
  112. package/dist/packages/ui/src/components/form-builder/sortable-field.cjs +151 -0
  113. package/dist/packages/ui/src/components/form-builder/sortable-field.mjs +148 -0
  114. package/dist/packages/ui/src/components/form-builder/step-tabs.cjs +180 -0
  115. package/dist/packages/ui/src/components/form-builder/step-tabs.mjs +178 -0
  116. package/dist/packages/ui/src/components/form-builder/types.cjs +7 -0
  117. package/dist/packages/ui/src/components/form-builder/types.mjs +5 -0
  118. package/dist/packages/ui/src/components/form-builder/validation-schemas.cjs +67 -0
  119. package/dist/packages/ui/src/components/form-builder/validation-schemas.mjs +56 -0
  120. package/dist/packages/ui/src/components/tabs.cjs +70 -0
  121. package/dist/packages/ui/src/components/tabs.mjs +65 -0
  122. package/dist/packages/ui/src/lib/schema-converter.cjs +130 -0
  123. package/dist/packages/ui/src/lib/schema-converter.mjs +124 -0
  124. package/dist/plugins/api/index.d.cts +2 -2
  125. package/dist/plugins/api/index.d.mts +2 -2
  126. package/dist/plugins/api/index.d.ts +2 -2
  127. package/dist/plugins/blog/api/index.d.cts +1 -1
  128. package/dist/plugins/blog/api/index.d.mts +1 -1
  129. package/dist/plugins/blog/api/index.d.ts +1 -1
  130. package/dist/plugins/blog/client/hooks/index.d.cts +2 -2
  131. package/dist/plugins/blog/client/hooks/index.d.mts +2 -2
  132. package/dist/plugins/blog/client/hooks/index.d.ts +2 -2
  133. package/dist/plugins/blog/client/index.d.cts +1 -1
  134. package/dist/plugins/blog/client/index.d.mts +1 -1
  135. package/dist/plugins/blog/client/index.d.ts +1 -1
  136. package/dist/plugins/blog/query-keys.d.cts +2 -2
  137. package/dist/plugins/blog/query-keys.d.mts +2 -2
  138. package/dist/plugins/blog/query-keys.d.ts +2 -2
  139. package/dist/plugins/client/index.d.cts +2 -2
  140. package/dist/plugins/client/index.d.mts +2 -2
  141. package/dist/plugins/client/index.d.ts +2 -2
  142. package/dist/plugins/cms/client/index.cjs +6 -0
  143. package/dist/plugins/cms/client/index.d.cts +6 -113
  144. package/dist/plugins/cms/client/index.d.mts +6 -113
  145. package/dist/plugins/cms/client/index.d.ts +6 -113
  146. package/dist/plugins/cms/client/index.mjs +1 -0
  147. package/dist/plugins/form-builder/api/index.cjs +7 -0
  148. package/dist/plugins/form-builder/api/index.d.cts +141 -0
  149. package/dist/plugins/form-builder/api/index.d.mts +141 -0
  150. package/dist/plugins/form-builder/api/index.d.ts +141 -0
  151. package/dist/plugins/form-builder/api/index.mjs +1 -0
  152. package/dist/plugins/form-builder/client/components/index.cjs +29 -0
  153. package/dist/plugins/form-builder/client/components/index.d.cts +93 -0
  154. package/dist/plugins/form-builder/client/components/index.d.mts +93 -0
  155. package/dist/plugins/form-builder/client/components/index.d.ts +93 -0
  156. package/dist/plugins/form-builder/client/components/index.mjs +18 -0
  157. package/dist/plugins/form-builder/client/hooks/index.cjs +19 -0
  158. package/dist/plugins/form-builder/client/hooks/index.d.cts +154 -0
  159. package/dist/plugins/form-builder/client/hooks/index.d.mts +154 -0
  160. package/dist/plugins/form-builder/client/hooks/index.d.ts +154 -0
  161. package/dist/plugins/form-builder/client/hooks/index.mjs +1 -0
  162. package/dist/plugins/form-builder/client/index.cjs +13 -0
  163. package/dist/plugins/form-builder/client/index.d.cts +381 -0
  164. package/dist/plugins/form-builder/client/index.d.mts +381 -0
  165. package/dist/plugins/form-builder/client/index.d.ts +381 -0
  166. package/dist/plugins/form-builder/client/index.mjs +2 -0
  167. package/dist/plugins/form-builder/client.css +3 -0
  168. package/dist/plugins/form-builder/query-keys.cjs +143 -0
  169. package/dist/plugins/form-builder/query-keys.d.cts +74 -0
  170. package/dist/plugins/form-builder/query-keys.d.mts +74 -0
  171. package/dist/plugins/form-builder/query-keys.d.ts +74 -0
  172. package/dist/plugins/form-builder/query-keys.mjs +141 -0
  173. package/dist/plugins/form-builder/style.css +19 -0
  174. package/dist/plugins/open-api/api/index.cjs +9 -0
  175. package/dist/plugins/open-api/api/index.d.cts +95 -0
  176. package/dist/plugins/open-api/api/index.d.mts +95 -0
  177. package/dist/plugins/open-api/api/index.d.ts +95 -0
  178. package/dist/plugins/open-api/api/index.mjs +2 -0
  179. package/dist/shared/stack.AX5nZ6A3.d.cts +86 -0
  180. package/dist/shared/stack.AX5nZ6A3.d.mts +86 -0
  181. package/dist/shared/stack.AX5nZ6A3.d.ts +86 -0
  182. package/dist/shared/stack.BIh2AXaW.d.cts +123 -0
  183. package/dist/shared/stack.BIh2AXaW.d.mts +123 -0
  184. package/dist/shared/stack.BIh2AXaW.d.ts +123 -0
  185. package/dist/shared/{stack.ByOugz9d.d.cts → stack.CSce37mX.d.cts} +15 -2
  186. package/dist/shared/{stack.ByOugz9d.d.mts → stack.CSce37mX.d.mts} +15 -2
  187. package/dist/shared/{stack.ByOugz9d.d.ts → stack.CSce37mX.d.ts} +15 -2
  188. package/dist/shared/stack.DzH_wcvr.d.cts +195 -0
  189. package/dist/shared/stack.DzH_wcvr.d.mts +195 -0
  190. package/dist/shared/stack.DzH_wcvr.d.ts +195 -0
  191. package/package.json +67 -1
  192. package/src/api/index.ts +14 -2
  193. package/src/plugins/cms/api/plugin.ts +9 -4
  194. package/src/plugins/cms/client/components/forms/content-form.tsx +23 -25
  195. package/src/plugins/cms/client/index.ts +11 -0
  196. package/src/plugins/form-builder/api/index.ts +1 -0
  197. package/src/plugins/form-builder/api/plugin.ts +776 -0
  198. package/src/plugins/form-builder/client/components/forms/form-renderer.tsx +253 -0
  199. package/src/plugins/form-builder/client/components/index.tsx +24 -0
  200. package/src/plugins/form-builder/client/components/loading/form-builder-skeleton.tsx +42 -0
  201. package/src/plugins/form-builder/client/components/loading/form-list-skeleton.tsx +25 -0
  202. package/src/plugins/form-builder/client/components/loading/index.tsx +3 -0
  203. package/src/plugins/form-builder/client/components/loading/submissions-skeleton.tsx +40 -0
  204. package/src/plugins/form-builder/client/components/pages/404-page.tsx +28 -0
  205. package/src/plugins/form-builder/client/components/pages/form-builder-page.internal.tsx +253 -0
  206. package/src/plugins/form-builder/client/components/pages/form-builder-page.tsx +26 -0
  207. package/src/plugins/form-builder/client/components/pages/form-list-page.internal.tsx +231 -0
  208. package/src/plugins/form-builder/client/components/pages/form-list-page.tsx +22 -0
  209. package/src/plugins/form-builder/client/components/pages/submissions-page.internal.tsx +268 -0
  210. package/src/plugins/form-builder/client/components/pages/submissions-page.tsx +26 -0
  211. package/src/plugins/form-builder/client/components/shared/default-error.tsx +30 -0
  212. package/src/plugins/form-builder/client/components/shared/empty-state.tsx +26 -0
  213. package/src/plugins/form-builder/client/components/shared/page-wrapper.tsx +32 -0
  214. package/src/plugins/form-builder/client/components/shared/pagination.tsx +52 -0
  215. package/src/plugins/form-builder/client/hooks/form-builder-hooks.tsx +799 -0
  216. package/src/plugins/form-builder/client/hooks/index.tsx +1 -0
  217. package/src/plugins/form-builder/client/index.ts +22 -0
  218. package/src/plugins/form-builder/client/localization/form-builder-common.ts +36 -0
  219. package/src/plugins/form-builder/client/localization/form-builder-editor.ts +18 -0
  220. package/src/plugins/form-builder/client/localization/form-builder-list.ts +17 -0
  221. package/src/plugins/form-builder/client/localization/form-builder-submissions.ts +17 -0
  222. package/src/plugins/form-builder/client/localization/form-builder-toasts.ts +10 -0
  223. package/src/plugins/form-builder/client/localization/index.ts +15 -0
  224. package/src/plugins/form-builder/client/overrides.ts +146 -0
  225. package/src/plugins/form-builder/client/plugin.tsx +488 -0
  226. package/src/plugins/form-builder/client.css +3 -0
  227. package/src/plugins/form-builder/db.ts +99 -0
  228. package/src/plugins/form-builder/query-keys.ts +198 -0
  229. package/src/plugins/form-builder/schemas.ts +122 -0
  230. package/src/plugins/form-builder/style.css +19 -0
  231. package/src/plugins/form-builder/types.ts +317 -0
  232. package/src/plugins/form-builder/utils.ts +63 -0
  233. package/src/plugins/open-api/api/generator.ts +433 -0
  234. package/src/plugins/open-api/api/index.ts +8 -0
  235. package/src/plugins/open-api/api/plugin.ts +243 -0
  236. package/src/plugins/open-api/db.ts +7 -0
  237. package/src/plugins/open-api/logo.ts +7 -0
  238. package/src/types.ts +15 -1
  239. package/dist/shared/{stack.DLhzx1-D.d.mts → stack.CcI4sYJP.d.cts} +1 -1
  240. package/dist/shared/{stack.DLhzx1-D.d.ts → stack.CcI4sYJP.d.mts} +1 -1
  241. package/dist/shared/{stack.DLhzx1-D.d.cts → stack.CcI4sYJP.d.ts} +1 -1
@@ -0,0 +1,588 @@
1
+ 'use strict';
2
+
3
+ const api = require('@btst/stack/plugins/api');
4
+ const z = require('zod');
5
+ const schemaConverter = require('../../../../../ui/src/lib/schema-converter.cjs');
6
+ const db = require('../db.cjs');
7
+ const schemas = require('../schemas.cjs');
8
+ const utils = require('../utils.cjs');
9
+
10
+ function serializeForm(form) {
11
+ return {
12
+ id: form.id,
13
+ name: form.name,
14
+ slug: form.slug,
15
+ description: form.description,
16
+ schema: form.schema,
17
+ successMessage: form.successMessage,
18
+ redirectUrl: form.redirectUrl,
19
+ status: form.status,
20
+ createdBy: form.createdBy,
21
+ createdAt: form.createdAt.toISOString(),
22
+ updatedAt: form.updatedAt.toISOString()
23
+ };
24
+ }
25
+ function serializeFormSubmission(submission) {
26
+ return {
27
+ ...submission,
28
+ submittedAt: submission.submittedAt.toISOString()
29
+ };
30
+ }
31
+ function serializeFormSubmissionWithData(submission) {
32
+ return {
33
+ ...serializeFormSubmission(submission),
34
+ parsedData: JSON.parse(submission.data),
35
+ form: submission.form ? serializeForm(submission.form) : void 0
36
+ };
37
+ }
38
+ const formBuilderBackendPlugin = (config = {}) => api.defineBackendPlugin({
39
+ name: "form-builder",
40
+ dbPlugin: db.formBuilderSchema,
41
+ routes: (adapter) => {
42
+ const createContext = (headers) => ({
43
+ headers,
44
+ ipAddress: utils.extractIpAddress(headers),
45
+ userAgent: utils.extractUserAgent(headers)
46
+ });
47
+ const createSubmissionContext = (formSlug, formId, headers) => ({
48
+ ...createContext(headers),
49
+ formSlug,
50
+ formId
51
+ });
52
+ const listForms = api.createEndpoint(
53
+ "/forms",
54
+ {
55
+ method: "GET",
56
+ query: schemas.listFormsQuerySchema
57
+ },
58
+ async (ctx) => {
59
+ const { status, limit, offset } = ctx.query;
60
+ const context = createContext(ctx.headers);
61
+ if (config.hooks?.onBeforeListForms) {
62
+ const canList = await config.hooks.onBeforeListForms(context);
63
+ if (!canList) {
64
+ throw ctx.error(403, { message: "Access denied" });
65
+ }
66
+ }
67
+ const whereConditions = [];
68
+ if (status) {
69
+ whereConditions.push({
70
+ field: "status",
71
+ value: status,
72
+ operator: "eq"
73
+ });
74
+ }
75
+ const allForms = await adapter.findMany({
76
+ model: "form",
77
+ where: whereConditions.length > 0 ? whereConditions : void 0
78
+ });
79
+ const total = allForms.length;
80
+ const forms = await adapter.findMany({
81
+ model: "form",
82
+ where: whereConditions.length > 0 ? whereConditions : void 0,
83
+ limit,
84
+ offset,
85
+ sortBy: { field: "createdAt", direction: "desc" }
86
+ });
87
+ return {
88
+ items: forms.map(serializeForm),
89
+ total,
90
+ limit,
91
+ offset
92
+ };
93
+ }
94
+ );
95
+ const getFormBySlug = api.createEndpoint(
96
+ "/forms/:slug",
97
+ {
98
+ method: "GET",
99
+ params: z.z.object({ slug: z.z.string() })
100
+ },
101
+ async (ctx) => {
102
+ const { slug } = ctx.params;
103
+ const context = createContext(ctx.headers);
104
+ if (config.hooks?.onBeforeGetForm) {
105
+ const canGet = await config.hooks.onBeforeGetForm(slug, context);
106
+ if (!canGet) {
107
+ throw ctx.error(403, { message: "Access denied" });
108
+ }
109
+ }
110
+ const form = await adapter.findOne({
111
+ model: "form",
112
+ where: [{ field: "slug", value: slug, operator: "eq" }]
113
+ });
114
+ if (!form) {
115
+ throw ctx.error(404, { message: "Form not found" });
116
+ }
117
+ return serializeForm(form);
118
+ }
119
+ );
120
+ const getFormById = api.createEndpoint(
121
+ "/forms/id/:id",
122
+ {
123
+ method: "GET",
124
+ params: z.z.object({ id: z.z.string() })
125
+ },
126
+ async (ctx) => {
127
+ const { id } = ctx.params;
128
+ const context = createContext(ctx.headers);
129
+ if (config.hooks?.onBeforeGetForm) {
130
+ const canGet = await config.hooks.onBeforeGetForm(id, context);
131
+ if (!canGet) {
132
+ throw ctx.error(403, { message: "Access denied" });
133
+ }
134
+ }
135
+ const form = await adapter.findOne({
136
+ model: "form",
137
+ where: [{ field: "id", value: id, operator: "eq" }]
138
+ });
139
+ if (!form) {
140
+ throw ctx.error(404, { message: "Form not found" });
141
+ }
142
+ return serializeForm(form);
143
+ }
144
+ );
145
+ const createForm = api.createEndpoint(
146
+ "/forms",
147
+ {
148
+ method: "POST",
149
+ body: schemas.createFormSchema
150
+ },
151
+ async (ctx) => {
152
+ const body = ctx.body;
153
+ const context = createContext(ctx.headers);
154
+ const slug = utils.slugify(body.slug);
155
+ if (!slug) {
156
+ throw ctx.error(400, {
157
+ message: "Invalid slug: must contain at least one alphanumeric character"
158
+ });
159
+ }
160
+ const existing = await adapter.findOne({
161
+ model: "form",
162
+ where: [{ field: "slug", value: slug, operator: "eq" }]
163
+ });
164
+ if (existing) {
165
+ throw ctx.error(409, {
166
+ message: "Form with this slug already exists"
167
+ });
168
+ }
169
+ try {
170
+ JSON.parse(body.schema);
171
+ } catch {
172
+ throw ctx.error(400, { message: "Invalid JSON Schema" });
173
+ }
174
+ let formInput = {
175
+ name: body.name,
176
+ slug,
177
+ description: body.description,
178
+ schema: body.schema,
179
+ successMessage: body.successMessage,
180
+ redirectUrl: body.redirectUrl || void 0,
181
+ status: body.status
182
+ };
183
+ if (config.hooks?.onBeforeFormCreated) {
184
+ const result = await config.hooks.onBeforeFormCreated(
185
+ formInput,
186
+ context
187
+ );
188
+ if (result === false) {
189
+ throw ctx.error(403, { message: "Create operation denied" });
190
+ }
191
+ if (result && typeof result === "object") {
192
+ formInput = result;
193
+ }
194
+ }
195
+ const form = await adapter.create({
196
+ model: "form",
197
+ data: {
198
+ name: formInput.name,
199
+ slug: formInput.slug,
200
+ description: formInput.description,
201
+ schema: formInput.schema,
202
+ successMessage: formInput.successMessage,
203
+ redirectUrl: formInput.redirectUrl,
204
+ status: formInput.status || "active",
205
+ createdBy: formInput.createdBy,
206
+ createdAt: /* @__PURE__ */ new Date(),
207
+ updatedAt: /* @__PURE__ */ new Date()
208
+ }
209
+ });
210
+ const serialized = serializeForm(form);
211
+ if (config.hooks?.onAfterFormCreated) {
212
+ await config.hooks.onAfterFormCreated(serialized, context);
213
+ }
214
+ return serialized;
215
+ }
216
+ );
217
+ const updateForm = api.createEndpoint(
218
+ "/forms/:id",
219
+ {
220
+ method: "PUT",
221
+ params: z.z.object({ id: z.z.string() }),
222
+ body: schemas.updateFormSchema
223
+ },
224
+ async (ctx) => {
225
+ const { id } = ctx.params;
226
+ const body = ctx.body;
227
+ const context = createContext(ctx.headers);
228
+ const existing = await adapter.findOne({
229
+ model: "form",
230
+ where: [{ field: "id", value: id, operator: "eq" }]
231
+ });
232
+ if (!existing) {
233
+ throw ctx.error(404, { message: "Form not found" });
234
+ }
235
+ let slug;
236
+ if (body.slug) {
237
+ slug = utils.slugify(body.slug);
238
+ if (!slug) {
239
+ throw ctx.error(400, {
240
+ message: "Invalid slug: must contain at least one alphanumeric character"
241
+ });
242
+ }
243
+ if (slug !== existing.slug) {
244
+ const duplicate = await adapter.findOne({
245
+ model: "form",
246
+ where: [
247
+ { field: "slug", value: slug, operator: "eq" }
248
+ ]
249
+ });
250
+ if (duplicate) {
251
+ throw ctx.error(409, {
252
+ message: "Form with this slug already exists"
253
+ });
254
+ }
255
+ }
256
+ }
257
+ if (body.schema) {
258
+ try {
259
+ JSON.parse(body.schema);
260
+ } catch {
261
+ throw ctx.error(400, { message: "Invalid JSON Schema" });
262
+ }
263
+ }
264
+ let updateInput = {
265
+ name: body.name,
266
+ slug,
267
+ description: body.description,
268
+ schema: body.schema,
269
+ successMessage: body.successMessage,
270
+ redirectUrl: body.redirectUrl,
271
+ status: body.status
272
+ };
273
+ if (config.hooks?.onBeforeFormUpdated) {
274
+ const result = await config.hooks.onBeforeFormUpdated(
275
+ id,
276
+ updateInput,
277
+ context
278
+ );
279
+ if (result === false) {
280
+ throw ctx.error(403, { message: "Update operation denied" });
281
+ }
282
+ if (result && typeof result === "object") {
283
+ updateInput = result;
284
+ }
285
+ }
286
+ const updateData = {
287
+ updatedAt: /* @__PURE__ */ new Date()
288
+ };
289
+ if (updateInput.name) updateData.name = updateInput.name;
290
+ if (updateInput.slug) updateData.slug = updateInput.slug;
291
+ if (updateInput.description !== void 0)
292
+ updateData.description = updateInput.description;
293
+ if (updateInput.schema) updateData.schema = updateInput.schema;
294
+ if (updateInput.successMessage !== void 0)
295
+ updateData.successMessage = updateInput.successMessage;
296
+ if (updateInput.redirectUrl !== void 0)
297
+ updateData.redirectUrl = updateInput.redirectUrl;
298
+ if (updateInput.status) updateData.status = updateInput.status;
299
+ await adapter.update({
300
+ model: "form",
301
+ where: [{ field: "id", value: id, operator: "eq" }],
302
+ update: updateData
303
+ });
304
+ const updated = await adapter.findOne({
305
+ model: "form",
306
+ where: [{ field: "id", value: id, operator: "eq" }]
307
+ });
308
+ if (!updated) {
309
+ throw ctx.error(500, { message: "Failed to fetch updated form" });
310
+ }
311
+ const serialized = serializeForm(updated);
312
+ if (config.hooks?.onAfterFormUpdated) {
313
+ await config.hooks.onAfterFormUpdated(serialized, context);
314
+ }
315
+ return serialized;
316
+ }
317
+ );
318
+ const deleteForm = api.createEndpoint(
319
+ "/forms/:id",
320
+ {
321
+ method: "DELETE",
322
+ params: z.z.object({ id: z.z.string() })
323
+ },
324
+ async (ctx) => {
325
+ const { id } = ctx.params;
326
+ const context = createContext(ctx.headers);
327
+ const existing = await adapter.findOne({
328
+ model: "form",
329
+ where: [{ field: "id", value: id, operator: "eq" }]
330
+ });
331
+ if (!existing) {
332
+ throw ctx.error(404, { message: "Form not found" });
333
+ }
334
+ if (config.hooks?.onBeforeFormDeleted) {
335
+ const canDelete = await config.hooks.onBeforeFormDeleted(
336
+ id,
337
+ context
338
+ );
339
+ if (!canDelete) {
340
+ throw ctx.error(403, { message: "Delete operation denied" });
341
+ }
342
+ }
343
+ await adapter.delete({
344
+ model: "formSubmission",
345
+ where: [{ field: "formId", value: id, operator: "eq" }]
346
+ });
347
+ await adapter.delete({
348
+ model: "form",
349
+ where: [{ field: "id", value: id, operator: "eq" }]
350
+ });
351
+ if (config.hooks?.onAfterFormDeleted) {
352
+ await config.hooks.onAfterFormDeleted(id, context);
353
+ }
354
+ return { success: true };
355
+ }
356
+ );
357
+ const submitForm = api.createEndpoint(
358
+ "/forms/:slug/submit",
359
+ {
360
+ method: "POST",
361
+ params: z.z.object({ slug: z.z.string() }),
362
+ body: z.z.object({
363
+ // Use passthrough object for dynamic form data
364
+ data: z.z.object({}).passthrough()
365
+ })
366
+ },
367
+ async (ctx) => {
368
+ const { slug } = ctx.params;
369
+ const { data } = ctx.body;
370
+ const baseContext = createContext(ctx.headers);
371
+ const form = await adapter.findOne({
372
+ model: "form",
373
+ where: [{ field: "slug", value: slug, operator: "eq" }]
374
+ });
375
+ if (!form) {
376
+ throw ctx.error(404, { message: "Form not found" });
377
+ }
378
+ if (form.status !== "active") {
379
+ throw ctx.error(400, {
380
+ message: "Form is not accepting submissions"
381
+ });
382
+ }
383
+ const submissionContext = createSubmissionContext(
384
+ slug,
385
+ form.id,
386
+ ctx.headers
387
+ );
388
+ try {
389
+ const jsonSchema = JSON.parse(form.schema);
390
+ const zodSchema = schemaConverter.formSchemaToZod(jsonSchema);
391
+ const validation = zodSchema.safeParse(data);
392
+ if (!validation.success) {
393
+ throw ctx.error(400, {
394
+ message: "Validation failed",
395
+ errors: validation.error.issues
396
+ });
397
+ }
398
+ } catch (error) {
399
+ if (error && typeof error === "object" && "code" in error) {
400
+ throw error;
401
+ }
402
+ throw ctx.error(400, { message: "Invalid form data" });
403
+ }
404
+ let finalData = data;
405
+ if (config.hooks?.onBeforeSubmission) {
406
+ try {
407
+ const result = await config.hooks.onBeforeSubmission(
408
+ slug,
409
+ data,
410
+ submissionContext
411
+ );
412
+ if (result === false) {
413
+ throw ctx.error(400, { message: "Submission rejected" });
414
+ }
415
+ if (result && typeof result === "object") {
416
+ finalData = result;
417
+ }
418
+ } catch (error) {
419
+ if (config.hooks?.onSubmissionError) {
420
+ await config.hooks.onSubmissionError(
421
+ error,
422
+ slug,
423
+ data,
424
+ submissionContext
425
+ );
426
+ }
427
+ throw error;
428
+ }
429
+ }
430
+ const submission = await adapter.create({
431
+ model: "formSubmission",
432
+ data: {
433
+ formId: form.id,
434
+ data: JSON.stringify(finalData),
435
+ submittedAt: /* @__PURE__ */ new Date(),
436
+ ipAddress: baseContext.ipAddress,
437
+ userAgent: baseContext.userAgent
438
+ }
439
+ });
440
+ const serialized = serializeFormSubmission(submission);
441
+ if (config.hooks?.onAfterSubmission) {
442
+ await config.hooks.onAfterSubmission(
443
+ serialized,
444
+ serializeForm(form),
445
+ submissionContext
446
+ );
447
+ }
448
+ return {
449
+ ...serialized,
450
+ form: {
451
+ successMessage: form.successMessage,
452
+ redirectUrl: form.redirectUrl
453
+ }
454
+ };
455
+ }
456
+ );
457
+ const listSubmissions = api.createEndpoint(
458
+ "/forms/:formId/submissions",
459
+ {
460
+ method: "GET",
461
+ params: z.z.object({ formId: z.z.string() }),
462
+ query: schemas.listSubmissionsQuerySchema
463
+ },
464
+ async (ctx) => {
465
+ const { formId } = ctx.params;
466
+ const { limit, offset } = ctx.query;
467
+ const context = createContext(ctx.headers);
468
+ const form = await adapter.findOne({
469
+ model: "form",
470
+ where: [{ field: "id", value: formId, operator: "eq" }]
471
+ });
472
+ if (!form) {
473
+ throw ctx.error(404, { message: "Form not found" });
474
+ }
475
+ if (config.hooks?.onBeforeListSubmissions) {
476
+ const canList = await config.hooks.onBeforeListSubmissions(
477
+ formId,
478
+ context
479
+ );
480
+ if (!canList) {
481
+ throw ctx.error(403, { message: "Access denied" });
482
+ }
483
+ }
484
+ const allSubmissions = await adapter.findMany({
485
+ model: "formSubmission",
486
+ where: [
487
+ { field: "formId", value: formId, operator: "eq" }
488
+ ]
489
+ });
490
+ const total = allSubmissions.length;
491
+ const submissions = await adapter.findMany({
492
+ model: "formSubmission",
493
+ where: [
494
+ { field: "formId", value: formId, operator: "eq" }
495
+ ],
496
+ limit,
497
+ offset,
498
+ sortBy: { field: "submittedAt", direction: "desc" },
499
+ join: { form: true }
500
+ });
501
+ return {
502
+ items: submissions.map(serializeFormSubmissionWithData),
503
+ total,
504
+ limit,
505
+ offset
506
+ };
507
+ }
508
+ );
509
+ const getSubmission = api.createEndpoint(
510
+ "/forms/:formId/submissions/:subId",
511
+ {
512
+ method: "GET",
513
+ params: z.z.object({ formId: z.z.string(), subId: z.z.string() })
514
+ },
515
+ async (ctx) => {
516
+ const { formId, subId } = ctx.params;
517
+ const context = createContext(ctx.headers);
518
+ if (config.hooks?.onBeforeGetSubmission) {
519
+ const canGet = await config.hooks.onBeforeGetSubmission(
520
+ subId,
521
+ context
522
+ );
523
+ if (!canGet) {
524
+ throw ctx.error(403, { message: "Access denied" });
525
+ }
526
+ }
527
+ const submission = await adapter.findOne({
528
+ model: "formSubmission",
529
+ where: [{ field: "id", value: subId, operator: "eq" }],
530
+ join: { form: true }
531
+ });
532
+ if (!submission || submission.formId !== formId) {
533
+ throw ctx.error(404, { message: "Submission not found" });
534
+ }
535
+ return serializeFormSubmissionWithData(submission);
536
+ }
537
+ );
538
+ const deleteSubmission = api.createEndpoint(
539
+ "/forms/:formId/submissions/:subId",
540
+ {
541
+ method: "DELETE",
542
+ params: z.z.object({ formId: z.z.string(), subId: z.z.string() })
543
+ },
544
+ async (ctx) => {
545
+ const { formId, subId } = ctx.params;
546
+ const context = createContext(ctx.headers);
547
+ const existing = await adapter.findOne({
548
+ model: "formSubmission",
549
+ where: [{ field: "id", value: subId, operator: "eq" }]
550
+ });
551
+ if (!existing || existing.formId !== formId) {
552
+ throw ctx.error(404, { message: "Submission not found" });
553
+ }
554
+ if (config.hooks?.onBeforeSubmissionDeleted) {
555
+ const canDelete = await config.hooks.onBeforeSubmissionDeleted(
556
+ subId,
557
+ context
558
+ );
559
+ if (!canDelete) {
560
+ throw ctx.error(403, { message: "Delete operation denied" });
561
+ }
562
+ }
563
+ await adapter.delete({
564
+ model: "formSubmission",
565
+ where: [{ field: "id", value: subId, operator: "eq" }]
566
+ });
567
+ if (config.hooks?.onAfterSubmissionDeleted) {
568
+ await config.hooks.onAfterSubmissionDeleted(subId, context);
569
+ }
570
+ return { success: true };
571
+ }
572
+ );
573
+ return {
574
+ listForms,
575
+ getFormBySlug,
576
+ getFormById,
577
+ createForm,
578
+ updateForm,
579
+ deleteForm,
580
+ submitForm,
581
+ listSubmissions,
582
+ getSubmission,
583
+ deleteSubmission
584
+ };
585
+ }
586
+ });
587
+
588
+ exports.formBuilderBackendPlugin = formBuilderBackendPlugin;