@10x-media/form-builder 0.1.0-beta.3 → 0.1.0-beta.5

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 (406) hide show
  1. package/CHANGELOG.md +125 -0
  2. package/README.md +4 -4
  3. package/dist/actions/body/serializeBody.d.ts +22 -4
  4. package/dist/actions/body/serializeBody.js +3 -1
  5. package/dist/actions/body/serializeBody.js.map +1 -1
  6. package/dist/actions/body/textOfBody.d.ts +13 -0
  7. package/dist/actions/body/textOfBody.js +35 -0
  8. package/dist/actions/body/textOfBody.js.map +1 -0
  9. package/dist/actions/builtin/confirmation.js +51 -12
  10. package/dist/actions/builtin/confirmation.js.map +1 -1
  11. package/dist/actions/builtin/emailTeam.js +82 -34
  12. package/dist/actions/builtin/emailTeam.js.map +1 -1
  13. package/dist/actions/builtin/index.d.ts +18 -1
  14. package/dist/actions/builtin/index.js +21 -7
  15. package/dist/actions/builtin/index.js.map +1 -1
  16. package/dist/actions/builtin/signedWebhook.js +2 -16
  17. package/dist/actions/builtin/signedWebhook.js.map +1 -1
  18. package/dist/actions/defineAction.d.ts +1 -1
  19. package/dist/actions/fromAddresses.d.ts +21 -0
  20. package/dist/actions/fromAddresses.js +74 -0
  21. package/dist/actions/fromAddresses.js.map +1 -0
  22. package/dist/actions/runActions.js +2 -0
  23. package/dist/actions/runActions.js.map +1 -1
  24. package/dist/actions/task.js +9 -8
  25. package/dist/actions/task.js.map +1 -1
  26. package/dist/aggregation/aggregateResponses.d.ts +9 -0
  27. package/dist/aggregation/aggregateResponses.js +8 -14
  28. package/dist/aggregation/aggregateResponses.js.map +1 -1
  29. package/dist/aggregation/resolveResultsRequest.d.ts +35 -6
  30. package/dist/aggregation/resolveResultsRequest.js +68 -11
  31. package/dist/aggregation/resolveResultsRequest.js.map +1 -1
  32. package/dist/calc/computeCalcFields.js +2 -1
  33. package/dist/calc/computeCalcFields.js.map +1 -1
  34. package/dist/client/ByteSizeField.d.ts +8 -0
  35. package/dist/client/ByteSizeField.js +3 -1
  36. package/dist/client/ByteSizeField.js.map +1 -1
  37. package/dist/client/ClosePollButton.d.ts +15 -0
  38. package/dist/client/ClosePollButton.js +80 -0
  39. package/dist/client/ClosePollButton.js.map +1 -0
  40. package/dist/client/CondensedArray.d.ts +15 -0
  41. package/dist/client/CondensedArray.js +97 -0
  42. package/dist/client/CondensedArray.js.map +1 -0
  43. package/dist/client/EndpointOptionsSelect.d.ts +45 -0
  44. package/dist/client/EndpointOptionsSelect.js +103 -0
  45. package/dist/client/EndpointOptionsSelect.js.map +1 -0
  46. package/dist/client/FieldBlockLabel.d.ts +18 -0
  47. package/dist/client/FieldBlockLabel.js +34 -0
  48. package/dist/client/FieldBlockLabel.js.map +1 -0
  49. package/dist/client/FieldNameSelect.d.ts +20 -4
  50. package/dist/client/FieldNameSelect.js +25 -14
  51. package/dist/client/FieldNameSelect.js.map +1 -1
  52. package/dist/client/FlowBuilder.d.ts +2 -1
  53. package/dist/client/FlowBuilder.js +134 -83
  54. package/dist/client/FlowBuilder.js.map +1 -1
  55. package/dist/client/RuleDescription.d.ts +21 -0
  56. package/dist/client/RuleDescription.js +19 -0
  57. package/dist/client/RuleDescription.js.map +1 -0
  58. package/dist/client/admin.css +83 -5
  59. package/dist/client/endpointOptions.js +29 -0
  60. package/dist/client/endpointOptions.js.map +1 -0
  61. package/dist/client/flowAuthoring.js +142 -0
  62. package/dist/client/flowAuthoring.js.map +1 -0
  63. package/dist/client/synthesizeClientField.js +21 -10
  64. package/dist/client/synthesizeClientField.js.map +1 -1
  65. package/dist/collections/buttonFields.d.ts +34 -0
  66. package/dist/collections/buttonFields.js +35 -0
  67. package/dist/collections/buttonFields.js.map +1 -0
  68. package/dist/collections/cells/FieldCountCell.d.ts +15 -0
  69. package/dist/collections/cells/FieldCountCell.js +18 -0
  70. package/dist/collections/cells/FieldCountCell.js.map +1 -0
  71. package/dist/collections/cells/FlowStepsCell.d.ts +14 -0
  72. package/dist/collections/cells/FlowStepsCell.js +17 -0
  73. package/dist/collections/cells/FlowStepsCell.js.map +1 -0
  74. package/dist/collections/formSubmissions.js +55 -12
  75. package/dist/collections/formSubmissions.js.map +1 -1
  76. package/dist/collections/forms.js +376 -57
  77. package/dist/collections/forms.js.map +1 -1
  78. package/dist/collections/redirectFields.d.ts +29 -0
  79. package/dist/conditions/conditionType.js +9 -2
  80. package/dist/conditions/conditionType.js.map +1 -1
  81. package/dist/conditions/normalizeConditions.js +2 -1
  82. package/dist/conditions/normalizeConditions.js.map +1 -1
  83. package/dist/consent/applyConsentStatements.d.ts +14 -0
  84. package/dist/consent/applyConsentStatements.js +17 -0
  85. package/dist/consent/applyConsentStatements.js.map +1 -0
  86. package/dist/consent/captureConsent.d.ts +19 -8
  87. package/dist/consent/captureConsent.js +34 -11
  88. package/dist/consent/captureConsent.js.map +1 -1
  89. package/dist/consent/consentSourcesField.d.ts +58 -0
  90. package/dist/consent/consentSourcesField.js +79 -0
  91. package/dist/consent/consentSourcesField.js.map +1 -0
  92. package/dist/consent/resolveConsentEntries.d.ts +24 -0
  93. package/dist/consent/resolveConsentEntries.js +43 -0
  94. package/dist/consent/resolveConsentEntries.js.map +1 -0
  95. package/dist/consent/resolveConsentSourcesRequest.d.ts +37 -0
  96. package/dist/consent/resolveConsentSourcesRequest.js +55 -0
  97. package/dist/consent/resolveConsentSourcesRequest.js.map +1 -0
  98. package/dist/consent/resolveConsentStatements.d.ts +45 -0
  99. package/dist/consent/resolveConsentStatements.js +44 -0
  100. package/dist/consent/resolveConsentStatements.js.map +1 -0
  101. package/dist/consent/resolvePublishedVersionRef.d.ts +17 -11
  102. package/dist/consent/resolvePublishedVersionRef.js +13 -10
  103. package/dist/consent/resolvePublishedVersionRef.js.map +1 -1
  104. package/dist/consent/types.d.ts +49 -0
  105. package/dist/email/departments.d.ts +55 -0
  106. package/dist/email/departments.js +130 -0
  107. package/dist/email/departments.js.map +1 -0
  108. package/dist/email/departmentsField.d.ts +49 -0
  109. package/dist/email/departmentsField.js +69 -0
  110. package/dist/email/departmentsField.js.map +1 -0
  111. package/dist/exports/client.d.ts +8 -1
  112. package/dist/exports/client.js +8 -1
  113. package/dist/exports/react.d.ts +15 -6
  114. package/dist/exports/react.js +11 -3
  115. package/dist/exports/rsc.d.ts +8 -1
  116. package/dist/exports/rsc.js +8 -1
  117. package/dist/exports/types.d.ts +18 -10
  118. package/dist/fields/buildFieldBlocks.js +43 -19
  119. package/dist/fields/buildFieldBlocks.js.map +1 -1
  120. package/dist/fields/builtin/calculation.js +7 -0
  121. package/dist/fields/builtin/calculation.js.map +1 -1
  122. package/dist/fields/builtin/checkbox.js +8 -0
  123. package/dist/fields/builtin/checkbox.js.map +1 -1
  124. package/dist/fields/builtin/consent.js +25 -15
  125. package/dist/fields/builtin/consent.js.map +1 -1
  126. package/dist/fields/builtin/country.d.ts +13 -0
  127. package/dist/fields/builtin/country.js +30 -0
  128. package/dist/fields/builtin/country.js.map +1 -0
  129. package/dist/fields/builtin/date.js +2 -0
  130. package/dist/fields/builtin/date.js.map +1 -1
  131. package/dist/fields/builtin/file.js +13 -8
  132. package/dist/fields/builtin/file.js.map +1 -1
  133. package/dist/fields/builtin/index.d.ts +13 -1
  134. package/dist/fields/builtin/index.js +20 -7
  135. package/dist/fields/builtin/index.js.map +1 -1
  136. package/dist/fields/builtin/message.js +30 -0
  137. package/dist/fields/builtin/message.js.map +1 -0
  138. package/dist/fields/builtin/repeater.js +8 -3
  139. package/dist/fields/builtin/repeater.js.map +1 -1
  140. package/dist/fields/builtin/select.js +8 -3
  141. package/dist/fields/builtin/select.js.map +1 -1
  142. package/dist/fields/builtin/state.d.ts +13 -0
  143. package/dist/fields/builtin/state.js +30 -0
  144. package/dist/fields/builtin/state.js.map +1 -0
  145. package/dist/fields/data/regions.d.ts +21 -0
  146. package/dist/fields/data/regions.js +1238 -0
  147. package/dist/fields/data/regions.js.map +1 -0
  148. package/dist/fields/fieldKey.d.ts +15 -0
  149. package/dist/fields/fieldKey.js +16 -0
  150. package/dist/fields/fieldKey.js.map +1 -0
  151. package/dist/fields/fieldNamesOfType.js +13 -8
  152. package/dist/fields/fieldNamesOfType.js.map +1 -1
  153. package/dist/fields/instanceOptions.js +20 -0
  154. package/dist/fields/instanceOptions.js.map +1 -0
  155. package/dist/fields/localizedIf.d.ts +13 -0
  156. package/dist/fields/localizedIf.js +12 -0
  157. package/dist/fields/localizedIf.js.map +1 -0
  158. package/dist/fields/registry.d.ts +1 -0
  159. package/dist/fields/registry.js +21 -2
  160. package/dist/fields/registry.js.map +1 -1
  161. package/dist/fields/sharedConfig.js +101 -51
  162. package/dist/fields/sharedConfig.js.map +1 -1
  163. package/dist/fields/types.d.ts +61 -5
  164. package/dist/flow/engine.d.ts +6 -4
  165. package/dist/flow/engine.js +11 -6
  166. package/dist/flow/engine.js.map +1 -1
  167. package/dist/flow/normalizeFlow.js +22 -7
  168. package/dist/flow/normalizeFlow.js.map +1 -1
  169. package/dist/flow/stepLabel.js +15 -0
  170. package/dist/flow/stepLabel.js.map +1 -0
  171. package/dist/flow/types.d.ts +12 -3
  172. package/dist/flow/types.js +11 -0
  173. package/dist/flow/types.js.map +1 -0
  174. package/dist/form/pollState.d.ts +22 -0
  175. package/dist/form/pollState.js +17 -0
  176. package/dist/form/pollState.js.map +1 -0
  177. package/dist/form/toFormDocument.d.ts +85 -0
  178. package/dist/form/toFormDocument.js +75 -0
  179. package/dist/form/toFormDocument.js.map +1 -0
  180. package/dist/form/types.d.ts +65 -0
  181. package/dist/index.d.ts +193 -27
  182. package/dist/index.js +59 -19
  183. package/dist/index.js.map +1 -1
  184. package/dist/plugin/customState.js +26 -0
  185. package/dist/plugin/customState.js.map +1 -0
  186. package/dist/plugin/registerCollections.js +33 -44
  187. package/dist/plugin/registerCollections.js.map +1 -1
  188. package/dist/plugin/uploadsCollection.d.ts +13 -0
  189. package/dist/plugin/uploadsCollection.js +44 -0
  190. package/dist/plugin/uploadsCollection.js.map +1 -0
  191. package/dist/poll/applyPollOptions.js +18 -0
  192. package/dist/poll/applyPollOptions.js.map +1 -0
  193. package/dist/poll/buildPollOptionSourceFields.js +50 -0
  194. package/dist/poll/buildPollOptionSourceFields.js.map +1 -0
  195. package/dist/poll/closeJob.d.ts +52 -0
  196. package/dist/poll/closeJob.js +119 -0
  197. package/dist/poll/closeJob.js.map +1 -0
  198. package/dist/poll/definePollOptionSource.d.ts +44 -0
  199. package/dist/poll/definePollOptionSource.js +6 -0
  200. package/dist/poll/definePollOptionSource.js.map +1 -0
  201. package/dist/poll/definePollType.d.ts +34 -0
  202. package/dist/poll/definePollType.js +6 -0
  203. package/dist/poll/definePollType.js.map +1 -0
  204. package/dist/poll/effectivePollOptions.d.ts +38 -0
  205. package/dist/poll/effectivePollOptions.js +64 -0
  206. package/dist/poll/effectivePollOptions.js.map +1 -0
  207. package/dist/poll/mostVoted.d.ts +21 -0
  208. package/dist/poll/mostVoted.js +32 -0
  209. package/dist/poll/mostVoted.js.map +1 -0
  210. package/dist/poll/outcomeBeforeChange.js +91 -0
  211. package/dist/poll/outcomeBeforeChange.js.map +1 -0
  212. package/dist/poll/outcomeFields.d.ts +38 -0
  213. package/dist/poll/outcomeFields.js +52 -0
  214. package/dist/poll/outcomeFields.js.map +1 -0
  215. package/dist/poll/pollTypeRegistry.d.ts +34 -0
  216. package/dist/poll/pollTypeRegistry.js +71 -0
  217. package/dist/poll/pollTypeRegistry.js.map +1 -0
  218. package/dist/poll/registry.d.ts +16 -0
  219. package/dist/poll/registry.js +16 -0
  220. package/dist/poll/registry.js.map +1 -0
  221. package/dist/poll/resolvePollCloseRequest.js +105 -0
  222. package/dist/poll/resolvePollCloseRequest.js.map +1 -0
  223. package/dist/poll/resolvePollOptions.d.ts +29 -0
  224. package/dist/poll/resolvePollOptions.js +52 -0
  225. package/dist/poll/resolvePollOptions.js.map +1 -0
  226. package/dist/poll/resolvePollOptionsRequest.js +51 -0
  227. package/dist/poll/resolvePollOptionsRequest.js.map +1 -0
  228. package/dist/poll/resolvePollOutcome.d.ts +34 -0
  229. package/dist/poll/resolvePollOutcome.js +76 -0
  230. package/dist/poll/resolvePollOutcome.js.map +1 -0
  231. package/dist/poll/resultsField.js +21 -0
  232. package/dist/poll/resultsField.js.map +1 -0
  233. package/dist/prefill/valuesFromSearchParams.js +3 -2
  234. package/dist/prefill/valuesFromSearchParams.js.map +1 -1
  235. package/dist/presentations/types.d.ts +3 -2
  236. package/dist/react/Form.d.ts +15 -33
  237. package/dist/react/Form.js +144 -119
  238. package/dist/react/Form.js.map +1 -1
  239. package/dist/react/FormContext.d.ts +37 -1
  240. package/dist/react/FormContext.js.map +1 -1
  241. package/dist/react/FormControls.d.ts +55 -0
  242. package/dist/react/FormControls.js +56 -0
  243. package/dist/react/FormControls.js.map +1 -0
  244. package/dist/react/FormResults.d.ts +6 -3
  245. package/dist/react/FormResults.js +37 -29
  246. package/dist/react/FormResults.js.map +1 -1
  247. package/dist/react/FormSteps.d.ts +17 -0
  248. package/dist/react/FormSteps.js +35 -0
  249. package/dist/react/FormSteps.js.map +1 -0
  250. package/dist/react/Poll.d.ts +17 -6
  251. package/dist/react/Poll.js +66 -18
  252. package/dist/react/Poll.js.map +1 -1
  253. package/dist/react/contract.d.ts +2 -3
  254. package/dist/react/contract.js.map +1 -1
  255. package/dist/react/fetchResults.d.ts +1 -1
  256. package/dist/react/fetchResults.js +1 -1
  257. package/dist/react/fetchResults.js.map +1 -1
  258. package/dist/react/primitives/Checkbox.d.ts +4 -2
  259. package/dist/react/primitives/Checkbox.js +2 -1
  260. package/dist/react/primitives/Checkbox.js.map +1 -1
  261. package/dist/react/primitives/FieldShell.d.ts +2 -4
  262. package/dist/react/primitives/FieldShell.js +12 -19
  263. package/dist/react/primitives/FieldShell.js.map +1 -1
  264. package/dist/react/renderers/calculation.js +1 -2
  265. package/dist/react/renderers/calculation.js.map +1 -1
  266. package/dist/react/renderers/checkbox.js +1 -2
  267. package/dist/react/renderers/checkbox.js.map +1 -1
  268. package/dist/react/renderers/consent.js +78 -34
  269. package/dist/react/renderers/consent.js.map +1 -1
  270. package/dist/react/renderers/date.js +1 -3
  271. package/dist/react/renderers/date.js.map +1 -1
  272. package/dist/react/renderers/email.js +1 -2
  273. package/dist/react/renderers/email.js.map +1 -1
  274. package/dist/react/renderers/file.js +6 -3
  275. package/dist/react/renderers/file.js.map +1 -1
  276. package/dist/react/renderers/index.js +5 -0
  277. package/dist/react/renderers/index.js.map +1 -1
  278. package/dist/react/renderers/message.js +35 -0
  279. package/dist/react/renderers/message.js.map +1 -0
  280. package/dist/react/renderers/number.js +1 -2
  281. package/dist/react/renderers/number.js.map +1 -1
  282. package/dist/react/renderers/region.js +45 -0
  283. package/dist/react/renderers/region.js.map +1 -0
  284. package/dist/react/renderers/repeater.js +7 -10
  285. package/dist/react/renderers/repeater.js.map +1 -1
  286. package/dist/react/renderers/select.js +1 -2
  287. package/dist/react/renderers/select.js.map +1 -1
  288. package/dist/react/renderers/text.js +1 -2
  289. package/dist/react/renderers/text.js.map +1 -1
  290. package/dist/react/renderers/textarea.js +1 -2
  291. package/dist/react/renderers/textarea.js.map +1 -1
  292. package/dist/react/state.d.ts +23 -2
  293. package/dist/react/state.js +16 -7
  294. package/dist/react/state.js.map +1 -1
  295. package/dist/react/uploadFile.d.ts +2 -2
  296. package/dist/react/uploadFile.js +1 -1
  297. package/dist/react/uploadFile.js.map +1 -1
  298. package/dist/react/useField.d.ts +0 -1
  299. package/dist/react/useField.js +0 -1
  300. package/dist/react/useField.js.map +1 -1
  301. package/dist/react/useFormState.d.ts +1 -1
  302. package/dist/react/useFormState.js +1 -1
  303. package/dist/react/useFormState.js.map +1 -1
  304. package/dist/react/validateField.js +3 -6
  305. package/dist/react/validateField.js.map +1 -1
  306. package/dist/recall/interpolate.d.ts +4 -3
  307. package/dist/recall/interpolate.js +5 -4
  308. package/dist/recall/interpolate.js.map +1 -1
  309. package/dist/recall/resolver.d.ts +1 -1
  310. package/dist/recall/resolver.js +14 -2
  311. package/dist/recall/resolver.js.map +1 -1
  312. package/dist/spam/captcha.d.ts +1 -1
  313. package/dist/spam/captcha.js +1 -1
  314. package/dist/spam/captcha.js.map +1 -1
  315. package/dist/submissions/SubmissionAnswers.js +6 -2
  316. package/dist/submissions/SubmissionAnswers.js.map +1 -1
  317. package/dist/submissions/SubmissionAnswersClient.js +91 -62
  318. package/dist/submissions/SubmissionAnswersClient.js.map +1 -1
  319. package/dist/submissions/createSubmission.d.ts +36 -0
  320. package/dist/submissions/createSubmission.js +26 -0
  321. package/dist/submissions/createSubmission.js.map +1 -0
  322. package/dist/submissions/runSubmission.d.ts +10 -0
  323. package/dist/submissions/runSubmission.js +92 -44
  324. package/dist/submissions/runSubmission.js.map +1 -1
  325. package/dist/submissions/types.d.ts +11 -4
  326. package/dist/submissions/validateSubmission.js +59 -10
  327. package/dist/submissions/validateSubmission.js.map +1 -1
  328. package/dist/submissions/votedCookie.d.ts +13 -0
  329. package/dist/submissions/votedCookie.js +27 -0
  330. package/dist/submissions/votedCookie.js.map +1 -0
  331. package/dist/translations/de.js +295 -0
  332. package/dist/translations/de.js.map +1 -0
  333. package/dist/translations/en.js +138 -23
  334. package/dist/translations/en.js.map +1 -1
  335. package/dist/translations/index.d.ts +2 -1
  336. package/dist/translations/index.js +6 -2
  337. package/dist/translations/index.js.map +1 -1
  338. package/dist/translations/keys.d.ts +134 -19
  339. package/dist/translations/keys.js +135 -20
  340. package/dist/translations/keys.js.map +1 -1
  341. package/dist/uploads/types.d.ts +1 -2
  342. package/dist/validation/buildRuleBlocks.js +18 -17
  343. package/dist/validation/buildRuleBlocks.js.map +1 -1
  344. package/dist/validation/builtin/email.js +1 -0
  345. package/dist/validation/builtin/email.js.map +1 -1
  346. package/dist/validation/builtin/matchesField.js +3 -7
  347. package/dist/validation/builtin/matchesField.js.map +1 -1
  348. package/dist/validation/builtin/max.js +1 -0
  349. package/dist/validation/builtin/max.js.map +1 -1
  350. package/dist/validation/builtin/maxDate.js +1 -0
  351. package/dist/validation/builtin/maxDate.js.map +1 -1
  352. package/dist/validation/builtin/maxLength.js +1 -0
  353. package/dist/validation/builtin/maxLength.js.map +1 -1
  354. package/dist/validation/builtin/min.js +1 -0
  355. package/dist/validation/builtin/min.js.map +1 -1
  356. package/dist/validation/builtin/minDate.js +1 -0
  357. package/dist/validation/builtin/minDate.js.map +1 -1
  358. package/dist/validation/builtin/minLength.js +1 -0
  359. package/dist/validation/builtin/minLength.js.map +1 -1
  360. package/dist/validation/builtin/notAlreadySubmitted.js +1 -0
  361. package/dist/validation/builtin/notAlreadySubmitted.js.map +1 -1
  362. package/dist/validation/builtin/oneOf.js +1 -0
  363. package/dist/validation/builtin/oneOf.js.map +1 -1
  364. package/dist/validation/builtin/pattern.js +11 -2
  365. package/dist/validation/builtin/pattern.js.map +1 -1
  366. package/dist/validation/builtin/url.js +1 -0
  367. package/dist/validation/builtin/url.js.map +1 -1
  368. package/dist/validation/builtin/validateRegexParams.js +44 -0
  369. package/dist/validation/builtin/validateRegexParams.js.map +1 -0
  370. package/dist/validation/fieldTargetParam.d.ts +22 -0
  371. package/dist/validation/fieldTargetParam.js +38 -0
  372. package/dist/validation/fieldTargetParam.js.map +1 -0
  373. package/dist/validation/runValidation.js +8 -29
  374. package/dist/validation/runValidation.js.map +1 -1
  375. package/dist/validation/types.d.ts +5 -11
  376. package/dist/validation/validateUrl.js +22 -0
  377. package/dist/validation/validateUrl.js.map +1 -0
  378. package/package.json +7 -6
  379. package/styles/form-builder.css +10 -0
  380. package/dist/collections/uploads.d.ts +0 -30
  381. package/dist/collections/uploads.js +0 -55
  382. package/dist/collections/uploads.js.map +0 -1
  383. package/dist/consent/buildConsentSourceConfig.js +0 -49
  384. package/dist/consent/buildConsentSourceConfig.js.map +0 -1
  385. package/dist/consent/builtin/index.d.ts +0 -7
  386. package/dist/consent/builtin/index.js +0 -11
  387. package/dist/consent/builtin/index.js.map +0 -1
  388. package/dist/consent/builtin/pageReference.js +0 -75
  389. package/dist/consent/builtin/pageReference.js.map +0 -1
  390. package/dist/consent/builtin/static.js +0 -44
  391. package/dist/consent/builtin/static.js.map +0 -1
  392. package/dist/consent/defineConsentSource.d.ts +0 -35
  393. package/dist/consent/defineConsentSource.js +0 -6
  394. package/dist/consent/defineConsentSource.js.map +0 -1
  395. package/dist/consent/registry.d.ts +0 -16
  396. package/dist/consent/registry.js +0 -16
  397. package/dist/consent/registry.js.map +0 -1
  398. package/dist/consent/resolveConsentLinks.d.ts +0 -19
  399. package/dist/consent/resolveConsentLinks.js +0 -26
  400. package/dist/consent/resolveConsentLinks.js.map +0 -1
  401. package/dist/presentations/registry.d.ts +0 -15
  402. package/dist/presentations/registry.js +0 -15
  403. package/dist/presentations/registry.js.map +0 -1
  404. package/dist/react/toFormDocument.d.ts +0 -24
  405. package/dist/react/toFormDocument.js +0 -22
  406. package/dist/react/toFormDocument.js.map +0 -1
@@ -1,23 +1,60 @@
1
+ import { fieldNamesOfType } from "../fields/fieldNamesOfType.js";
2
+ import { localizedIf } from "../fields/localizedIf.js";
1
3
  import { keys } from "../translations/keys.js";
2
- import { labelFor, labelForKey } from "../translations/server.js";
3
- import { isLoggedIn } from "../plugin/access.js";
4
+ import { asTranslate, labelFor, labelForKey } from "../translations/server.js";
5
+ import { resolveFromAddressesRequest } from "../actions/fromAddresses.js";
6
+ import { resolveDepartmentsRequest } from "../email/departments.js";
7
+ import { validateUrl } from "../validation/validateUrl.js";
4
8
  import { normalizeCalc } from "../calc/normalizeCalc.js";
9
+ import { isLoggedIn } from "../plugin/access.js";
5
10
  import { buildActionBlocks } from "../actions/buildActionBlocks.js";
11
+ import { resolvePollTypes } from "../poll/pollTypeRegistry.js";
12
+ import { enqueuePollClose } from "../poll/closeJob.js";
6
13
  import { resolveFormResultsRequest } from "../aggregation/resolveResultsRequest.js";
7
14
  import { buildConditionTypeMap } from "../conditions/conditionType.js";
8
15
  import { normalizeFormConditions } from "../conditions/normalizeConditions.js";
16
+ import { resolveConsentSourcesRequest } from "../consent/resolveConsentSourcesRequest.js";
9
17
  import { buildFieldBlocks } from "../fields/buildFieldBlocks.js";
10
18
  import { normalizeFlow } from "../flow/normalizeFlow.js";
11
- import { DEFAULT_PRESENTATION_NAME, defaultPresentationDescriptors } from "../presentations/defaults.js";
19
+ import { END_OF_FORM } from "../flow/types.js";
20
+ import { buildPollOptionSourceFields } from "../poll/buildPollOptionSourceFields.js";
21
+ import { pollOutcomeBeforeChange } from "../poll/outcomeBeforeChange.js";
22
+ import { buildDefaultOutcomeFields } from "../poll/outcomeFields.js";
23
+ import { resolvePollCloseRequest } from "../poll/resolvePollCloseRequest.js";
24
+ import { resolvePollOptionsRequest } from "../poll/resolvePollOptionsRequest.js";
25
+ import { buildValidateResultsField, pollEligibleTypes } from "../poll/resultsField.js";
26
+ import { buildDefaultButtonFields } from "./buttonFields.js";
12
27
  import { ValidationError } from "payload";
13
28
  //#region src/collections/forms.ts
14
29
  const FORMS_SLUG = "forms";
30
+ /**
31
+ * Require the title in the default locale (and on hosts without localization), but let it be empty in
32
+ * other locales so a localized form falls back to the default-locale title rather than forcing a
33
+ * translation for every locale. Payload's field-level `required` cannot express this: it enforces per
34
+ * write-locale, which would make a title mandatory in every locale and break the documented fallback.
35
+ */
36
+ const validateFormTitle = (value, { req }) => {
37
+ const localization = req.payload.config.localization;
38
+ const defaultLocale = localization ? localization.defaultLocale : void 0;
39
+ if ((defaultLocale === void 0 || req.locale === void 0 || req.locale === defaultLocale) && (typeof value !== "string" || value.trim().length === 0)) return req.t("validation:required");
40
+ return true;
41
+ };
42
+ /**
43
+ * Field-level validation for the raw flow JSON: step ids must be non-empty, unique, and not the
44
+ * reserved `END_OF_FORM` sentinel, and every explicit step-id reference (a string `next`, a
45
+ * transition `to`) must resolve to a known step. `next: null` (explicit end of form) and an
46
+ * absent `next` (fall through to the next step in array order) are always valid. On full-document
47
+ * saves the beforeValidate pass has already run `normalizeFlow` and laundered dangling
48
+ * references, so the unknown-target checks mainly protect partial API updates that send `flow`
49
+ * without `fields`.
50
+ */
15
51
  const validateFlow = (raw) => {
16
52
  if (raw === null || raw === void 0) return true;
17
53
  const r = raw;
18
54
  if (!Array.isArray(r.steps)) return true;
19
55
  const steps = r.steps;
20
56
  if (steps.find((s) => typeof s?.id !== "string" || s.id.length === 0)) return "Flow: every step must have a non-empty ID";
57
+ if (steps.some((s) => s.id === "__end__")) return `Flow: step ID "${END_OF_FORM}" is reserved`;
21
58
  const ids = steps.map((s) => s.id);
22
59
  if (new Set(ids).size !== ids.length) return "Flow: duplicate step IDs found";
23
60
  const idSet = new Set(ids);
@@ -36,41 +73,109 @@ const providedFlowStepCount = (raw) => {
36
73
  const steps = raw.steps;
37
74
  return Array.isArray(steps) ? steps.length : 0;
38
75
  };
39
- const buildFormsCollection = ({ overrides, registry, ruleRegistry, consentRegistry, presentationRegistry = new Map(Object.entries(defaultPresentationDescriptors)), actionRegistry = /* @__PURE__ */ new Map() }) => {
76
+ /**
77
+ * Stamp the configured uploads collection slug onto every `file` block (including repeater
78
+ * sub-fields) on each save. The block carries a hidden `uploadsCollection` field so the slug
79
+ * reaches the client renderer through the form document; the server always overwrites it from
80
+ * plugin config, so the stored value is never author- or client-controlled.
81
+ */
82
+ const stampFileCollections = (rows, slug) => {
83
+ for (const row of rows) {
84
+ if (row.blockType === "file") row.uploadsCollection = slug;
85
+ const subFields = row.subFields;
86
+ if (Array.isArray(subFields)) stampFileCollections(subFields, slug);
87
+ }
88
+ };
89
+ const buildFormsCollection = ({ overrides, registry, ruleRegistry, consentSources, actionRegistry = /* @__PURE__ */ new Map(), localizeContent = true, richText, uploadsCollectionSlug, resultsAccess, pollSourceRegistry, pollTypeRegistry, outcomeFields, buttons, response, fromAddresses, departments, redirectRelationships }) => {
40
90
  const conditionTypes = buildConditionTypeMap(registry);
91
+ const pollTypes = pollTypeRegistry ?? resolvePollTypes();
92
+ const pollResultsTypes = pollEligibleTypes(registry);
93
+ const bareTypes = new Set([...registry.values()].filter((d) => d.bare === true).map((d) => d.type));
94
+ const bareTypeLabels = Object.fromEntries([...registry.values()].filter((d) => d.bare === true).map((d) => [d.type, d.label]));
41
95
  const FLOW_BUILDER_REF = "@10x-media/form-builder/client#FlowBuilder";
96
+ const FIELD_NAME_SELECT_REF = "@10x-media/form-builder/client#FieldNameSelect";
97
+ const FLOW_STEPS_CELL_REF = "@10x-media/form-builder/client#FlowStepsCell";
98
+ const FIELD_COUNT_CELL_REF = "@10x-media/form-builder/client#FieldCountCell";
99
+ const CLOSE_POLL_BUTTON_REF = "@10x-media/form-builder/client#ClosePollButton";
100
+ const hasOptionSources = (pollSourceRegistry?.size ?? 0) > 0;
101
+ const orderedPollTypes = [...[...pollTypes.values()].filter((strategy) => strategy.type === "mostVoted"), ...[...pollTypes.values()].filter((strategy) => strategy.type !== "mostVoted")];
42
102
  const beforeValidate = ({ data, req }) => {
43
- if (data && typeof data.defaultPresentation === "string" && !presentationRegistry.has(data.defaultPresentation)) data.defaultPresentation = DEFAULT_PRESENTATION_NAME;
44
103
  if (data && Array.isArray(data.fields)) {
45
104
  const normalized = normalizeFormConditions(data.fields, conditionTypes);
46
105
  for (const field of normalized) if ("expression" in field) field.expression = normalizeCalc(field.expression);
106
+ if (uploadsCollectionSlug) stampFileCollections(normalized, uploadsCollectionSlug);
47
107
  data.fields = normalized;
48
- const fieldNames = normalized.map((field) => typeof field.name === "string" ? field.name : void 0).filter((name) => name !== void 0);
49
- const normalizedFlow = normalizeFlow(data.flow, fieldNames);
108
+ const fieldKeys = normalized.map((field) => {
109
+ if (typeof field.name === "string" && field.name.length > 0) return field.name;
110
+ return bareTypes.has(field.blockType) && field.id != null ? String(field.id) : void 0;
111
+ }).filter((key) => key !== void 0);
112
+ const normalizedFlow = normalizeFlow(data.flow, fieldKeys);
50
113
  if (providedFlowStepCount(data.flow) > 0 && normalizedFlow === void 0) throw new ValidationError({
51
114
  collection: FORMS_SLUG,
52
115
  errors: [{
53
116
  path: "flow",
54
- message: "A flow needs at least two steps with unique, non-empty IDs. Add another step or remove the flow."
117
+ message: "A flow needs at least two steps. Add another step or remove the flow."
55
118
  }]
56
119
  }, req.t);
57
120
  data.flow = normalizedFlow;
121
+ if (data.pollEnabled === true) {
122
+ const poll = data.poll != null && typeof data.poll === "object" ? data.poll : {};
123
+ const resultsField = typeof poll.resultsField === "string" ? poll.resultsField.trim() : "";
124
+ const sourceDriven = (typeof poll.optionSource === "string" ? poll.optionSource.trim() : "").length > 0 || poll.type === "source";
125
+ if (resultsField.length === 0 && !sourceDriven) {
126
+ const eligible = fieldNamesOfType(data.fields, pollResultsTypes);
127
+ if (eligible.length === 1) data.poll = {
128
+ ...poll,
129
+ resultsField: eligible[0]
130
+ };
131
+ else {
132
+ const messageKey = eligible.length > 1 ? keys.pollVoteFieldChoose : keys.pollVoteFieldMissing;
133
+ throw new ValidationError({
134
+ collection: FORMS_SLUG,
135
+ errors: [{
136
+ path: "poll.resultsField",
137
+ message: asTranslate(req.t)(messageKey)
138
+ }]
139
+ }, req.t);
140
+ }
141
+ }
142
+ }
58
143
  }
59
144
  return data;
60
145
  };
146
+ const pollCloseAfterChange = async ({ doc, req }) => {
147
+ await enqueuePollClose({
148
+ payload: req.payload,
149
+ form: doc,
150
+ req
151
+ });
152
+ return doc;
153
+ };
154
+ const pollTypeOptionLabel = (label) => typeof label === "string" ? labelFor(label) : label;
61
155
  const fieldsField = {
62
156
  name: "fields",
63
157
  type: "blocks",
64
- blocks: buildFieldBlocks(registry, ruleRegistry, consentRegistry)
158
+ blocks: buildFieldBlocks({
159
+ registry,
160
+ ruleRegistry,
161
+ localize: localizeContent
162
+ }),
163
+ admin: { components: { Cell: FIELD_COUNT_CELL_REF } }
65
164
  };
66
165
  const flowField = {
67
166
  name: "flow",
68
167
  type: "json",
69
168
  validate: validateFlow,
70
- admin: { components: { Field: {
71
- path: FLOW_BUILDER_REF,
72
- clientProps: { conditionTypes }
73
- } } },
169
+ admin: { components: {
170
+ Cell: FLOW_STEPS_CELL_REF,
171
+ Field: {
172
+ path: FLOW_BUILDER_REF,
173
+ clientProps: {
174
+ conditionTypes,
175
+ bareTypeLabels
176
+ }
177
+ }
178
+ } },
74
179
  typescriptSchema: [() => ({
75
180
  type: "object",
76
181
  required: ["steps"],
@@ -88,7 +193,7 @@ const buildFormsCollection = ({ overrides, registry, ruleRegistry, consentRegist
88
193
  type: "array",
89
194
  items: { type: "string" }
90
195
  },
91
- next: { type: "string" },
196
+ next: { type: ["string", "null"] },
92
197
  transitions: {
93
198
  type: "array",
94
199
  items: {
@@ -116,74 +221,279 @@ const buildFormsCollection = ({ overrides, registry, ruleRegistry, consentRegist
116
221
  label: labelForKey(keys.configActions),
117
222
  access: { read: isLoggedIn }
118
223
  };
224
+ const redirectReferenceField = redirectRelationships && redirectRelationships.length > 0 ? [{
225
+ name: "reference",
226
+ type: "relationship",
227
+ relationTo: redirectRelationships,
228
+ label: labelForKey(keys.responseRedirectReference),
229
+ admin: { description: labelForKey(keys.responseRedirectReferenceDescription) }
230
+ }] : [];
231
+ const defaultRedirectFields = [{
232
+ name: "url",
233
+ type: "text",
234
+ label: labelForKey(keys.responseUrl),
235
+ validate: validateUrl
236
+ }, ...redirectReferenceField];
237
+ const redirectFields = response?.redirect?.fields ? response.redirect.fields({ defaultFields: defaultRedirectFields }) : defaultRedirectFields;
238
+ const responseField = {
239
+ name: "response",
240
+ type: "group",
241
+ fields: [
242
+ {
243
+ name: "type",
244
+ type: "select",
245
+ defaultValue: "message",
246
+ label: labelForKey(keys.responseType),
247
+ admin: { isClearable: false },
248
+ options: [{
249
+ label: labelForKey(keys.responseTypeMessage),
250
+ value: "message"
251
+ }, {
252
+ label: labelForKey(keys.responseTypeRedirect),
253
+ value: "redirect"
254
+ }]
255
+ },
256
+ {
257
+ name: "message",
258
+ type: "richText",
259
+ label: labelForKey(keys.responseMessage),
260
+ admin: { condition: (_data, siblingData) => siblingData?.type !== "redirect" },
261
+ ...richText?.editor ? { editor: richText.editor } : {},
262
+ ...localizedIf(localizeContent)
263
+ },
264
+ {
265
+ name: "redirect",
266
+ type: "group",
267
+ label: labelForKey(keys.responseRedirect),
268
+ admin: {
269
+ condition: (_data, siblingData) => siblingData?.type === "redirect",
270
+ hideGutter: true
271
+ },
272
+ fields: redirectFields
273
+ }
274
+ ]
275
+ };
276
+ const defaultOutcomeFields = buildDefaultOutcomeFields();
277
+ const defaultButtonFields = buildDefaultButtonFields(localizeContent);
278
+ const halfWidth = (field) => ({
279
+ ...field,
280
+ admin: {
281
+ ...field.admin,
282
+ width: "50%"
283
+ }
284
+ });
285
+ const composedButtons = buttons?.fields ? buttons.fields({ defaultFields: defaultButtonFields }) : defaultButtonFields;
286
+ const submitField = composedButtons.submit;
287
+ const prevNextRow = {
288
+ type: "row",
289
+ admin: { condition: (data) => {
290
+ const steps = data?.flow?.steps;
291
+ return Array.isArray(steps) && steps.length >= 1;
292
+ } },
293
+ fields: [halfWidth(composedButtons.prev), halfWidth(composedButtons.next)]
294
+ };
295
+ const pollGroupField = {
296
+ name: "poll",
297
+ type: "group",
298
+ label: false,
299
+ fields: [
300
+ {
301
+ name: "resultsField",
302
+ type: "text",
303
+ label: labelForKey(keys.pollResultsField),
304
+ validate: buildValidateResultsField(pollResultsTypes),
305
+ admin: { components: { Field: {
306
+ path: FIELD_NAME_SELECT_REF,
307
+ clientProps: {
308
+ types: pollResultsTypes,
309
+ descriptionKey: keys.pollResultsFieldDescription
310
+ }
311
+ } } }
312
+ },
313
+ {
314
+ name: "type",
315
+ type: "select",
316
+ defaultValue: "mostVoted",
317
+ label: labelForKey(keys.pollType),
318
+ admin: {
319
+ isClearable: false,
320
+ description: labelForKey(keys.pollTypeDescription)
321
+ },
322
+ options: orderedPollTypes.filter((strategy) => strategy.type !== "source" || hasOptionSources).map((strategy) => ({
323
+ label: pollTypeOptionLabel(strategy.label),
324
+ value: strategy.type
325
+ }))
326
+ },
327
+ {
328
+ name: "resultsVisibility",
329
+ type: "select",
330
+ defaultValue: "afterVote",
331
+ label: labelForKey(keys.pollResultsVisibility),
332
+ admin: { isClearable: false },
333
+ options: [{
334
+ label: labelForKey(keys.pollVisibilityAfterVote),
335
+ value: "afterVote"
336
+ }, {
337
+ label: labelForKey(keys.pollVisibilityAfterClose),
338
+ value: "afterClose"
339
+ }]
340
+ },
341
+ {
342
+ name: "closesAt",
343
+ type: "date",
344
+ label: labelForKey(keys.pollClosesAt),
345
+ admin: { date: { pickerAppearance: "dayAndTime" } }
346
+ },
347
+ {
348
+ name: "closePoll",
349
+ type: "ui",
350
+ admin: { components: { Field: CLOSE_POLL_BUTTON_REF } }
351
+ },
352
+ ...buildPollOptionSourceFields(pollSourceRegistry ?? /* @__PURE__ */ new Map()),
353
+ {
354
+ name: "outcome",
355
+ type: "group",
356
+ label: labelForKey(keys.pollOutcome),
357
+ admin: { hideGutter: true },
358
+ fields: outcomeFields ? outcomeFields({ defaultFields: defaultOutcomeFields }) : [defaultOutcomeFields.winningValues, defaultOutcomeFields.resolvedAt]
359
+ }
360
+ ]
361
+ };
119
362
  const defaultFields = [
120
363
  {
121
364
  name: "title",
122
365
  type: "text",
123
- required: true,
124
- label: labelForKey(keys.fieldTitle)
366
+ label: labelForKey(keys.fieldTitle),
367
+ ...localizedIf(localizeContent),
368
+ validate: validateFormTitle
369
+ },
370
+ {
371
+ type: "row",
372
+ fields: [{
373
+ name: "multistep",
374
+ type: "checkbox",
375
+ defaultValue: false,
376
+ label: labelForKey(keys.formMultistep),
377
+ admin: { width: "50%" }
378
+ }, {
379
+ name: "pollEnabled",
380
+ type: "checkbox",
381
+ defaultValue: false,
382
+ label: labelForKey(keys.formPollEnabled),
383
+ admin: { width: "50%" }
384
+ }]
125
385
  },
126
386
  {
127
387
  type: "tabs",
128
388
  tabs: [
129
389
  {
130
390
  label: labelForKey(keys.tabFields),
131
- fields: [fieldsField]
391
+ fields: [fieldsField, submitField]
132
392
  },
133
393
  {
134
394
  label: labelForKey(keys.tabFlow),
135
- fields: [flowField]
395
+ admin: { condition: (_data, siblingData) => siblingData?.multistep === true },
396
+ fields: [flowField, prevNextRow]
397
+ },
398
+ {
399
+ label: labelForKey(keys.pollGroup),
400
+ admin: { condition: (_data, siblingData) => siblingData?.pollEnabled === true },
401
+ fields: [pollGroupField]
136
402
  },
137
403
  {
138
404
  label: labelForKey(keys.tabActions),
139
405
  fields: [actionsField]
406
+ },
407
+ {
408
+ label: labelForKey(keys.tabResponse),
409
+ fields: [responseField]
140
410
  }
141
411
  ]
142
- },
412
+ }
413
+ ];
414
+ const defaultEndpoints = [
143
415
  {
144
- name: "defaultPresentation",
145
- type: "select",
146
- defaultValue: DEFAULT_PRESENTATION_NAME,
147
- options: [...presentationRegistry.values()].map((descriptor) => ({
148
- label: labelFor(descriptor.label),
149
- value: descriptor.name
150
- })),
151
- label: labelForKey(keys.configDefaultPresentation),
152
- admin: { position: "sidebar" }
416
+ path: "/:id/results",
417
+ method: "get",
418
+ handler: async (req) => {
419
+ const field = typeof req.query?.field === "string" ? req.query.field : void 0;
420
+ const { status, body } = await resolveFormResultsRequest({
421
+ payload: req.payload,
422
+ formId: req.routeParams?.id,
423
+ field,
424
+ isAuthed: Boolean(req.user),
425
+ req,
426
+ access: resultsAccess,
427
+ eligibleTypes: pollResultsTypes
428
+ });
429
+ return Response.json(body, { status });
430
+ }
153
431
  },
154
432
  {
155
- name: "showResults",
156
- type: "checkbox",
157
- defaultValue: false,
158
- label: labelForKey(keys.configShowResults),
159
- admin: { position: "sidebar" }
433
+ path: "/:id/poll-options",
434
+ method: "get",
435
+ handler: async (req) => {
436
+ const { status, body } = await resolvePollOptionsRequest({
437
+ payload: req.payload,
438
+ formId: req.routeParams?.id,
439
+ isAuthed: Boolean(req.user),
440
+ req
441
+ });
442
+ return Response.json(body, { status });
443
+ }
160
444
  },
161
445
  {
162
- name: "resultsField",
163
- type: "text",
164
- label: labelForKey(keys.configResultsField),
165
- admin: {
166
- position: "sidebar",
167
- description: "Field whose aggregate results are public when \"Show results publicly\" is on. Use a choice field, never a free-text or PII field.",
168
- condition: (data) => Boolean(data?.showResults)
446
+ path: "/:id/close",
447
+ method: "post",
448
+ handler: async (req) => {
449
+ const { status, body } = await resolvePollCloseRequest({
450
+ payload: req.payload,
451
+ formId: req.routeParams?.id,
452
+ isAuthed: Boolean(req.user),
453
+ req
454
+ });
455
+ return Response.json(body, { status });
169
456
  }
170
- }
457
+ },
458
+ ...consentSources ? [{
459
+ path: "/:id/consent-sources",
460
+ method: "get",
461
+ handler: async (req) => {
462
+ const { status, body } = await resolveConsentSourcesRequest({
463
+ payload: req.payload,
464
+ formId: req.routeParams?.id,
465
+ isAuthed: Boolean(req.user),
466
+ req,
467
+ resolver: consentSources
468
+ });
469
+ return Response.json(body, { status });
470
+ }
471
+ }] : [],
472
+ ...fromAddresses ? [{
473
+ path: "/:id/from-addresses",
474
+ method: "get",
475
+ handler: async (req) => {
476
+ const { status, body } = await resolveFromAddressesRequest({
477
+ isAuthed: Boolean(req.user),
478
+ req,
479
+ resolver: fromAddresses
480
+ });
481
+ return Response.json(body, { status });
482
+ }
483
+ }] : [],
484
+ ...departments ? [{
485
+ path: "/:id/departments",
486
+ method: "get",
487
+ handler: async (req) => {
488
+ const { status, body } = await resolveDepartmentsRequest({
489
+ isAuthed: Boolean(req.user),
490
+ req,
491
+ resolver: departments
492
+ });
493
+ return Response.json(body, { status });
494
+ }
495
+ }] : []
171
496
  ];
172
- const defaultEndpoints = [{
173
- path: "/:id/results",
174
- method: "get",
175
- handler: async (req) => {
176
- const field = typeof req.query?.field === "string" ? req.query.field : void 0;
177
- const { status, body } = await resolveFormResultsRequest({
178
- payload: req.payload,
179
- formId: req.routeParams?.id,
180
- field,
181
- isAuthed: Boolean(req.user),
182
- req
183
- });
184
- return Response.json(body, { status });
185
- }
186
- }];
187
497
  return {
188
498
  ...overrides ?? {},
189
499
  slug: FORMS_SLUG,
@@ -195,6 +505,13 @@ const buildFormsCollection = ({ overrides, registry, ruleRegistry, consentRegist
195
505
  admin: {
196
506
  group: "Forms",
197
507
  useAsTitle: "title",
508
+ defaultColumns: [
509
+ "title",
510
+ "fields",
511
+ "flow",
512
+ "pollEnabled",
513
+ "updatedAt"
514
+ ],
198
515
  ...overrides?.admin ?? {}
199
516
  },
200
517
  access: {
@@ -203,7 +520,9 @@ const buildFormsCollection = ({ overrides, registry, ruleRegistry, consentRegist
203
520
  },
204
521
  hooks: {
205
522
  ...overrides?.hooks ?? {},
206
- beforeValidate: [beforeValidate, ...overrides?.hooks?.beforeValidate ?? []]
523
+ beforeValidate: [beforeValidate, ...overrides?.hooks?.beforeValidate ?? []],
524
+ beforeChange: [pollOutcomeBeforeChange, ...overrides?.hooks?.beforeChange ?? []],
525
+ afterChange: [pollCloseAfterChange, ...overrides?.hooks?.afterChange ?? []]
207
526
  },
208
527
  endpoints: [...defaultEndpoints, ...Array.isArray(overrides?.endpoints) ? overrides.endpoints : []],
209
528
  fields: overrides?.fields ? overrides.fields({ defaultFields }) : defaultFields