@verbb/formie-browser 1.0.12 → 1.0.14

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 (383) hide show
  1. package/CHANGELOG.md +57 -0
  2. package/dist/chunks/{address-country-Rx6GQTND.js → address-country-Dn71jroa.js} +10 -4
  3. package/dist/chunks/{address-finder-k7_BXaRe.js → address-finder-O49uDRoR.js} +2 -2
  4. package/dist/chunks/{address-state-BwE01m2_.js → address-state-ByYatUur.js} +154 -143
  5. package/dist/chunks/{api-DqpfkZWL.js → api-D6kJ7kXZ.js} +183 -179
  6. package/dist/chunks/{api-BUb6P-xu.js → api-DYYsVIub.js} +77 -47
  7. package/dist/chunks/{api-sPqGbOww.js → api-ghNr2uxX.js} +15 -9
  8. package/dist/chunks/{bpoint-Dlq34XH1.js → bpoint-D0RKFM4F.js} +3 -3
  9. package/dist/chunks/calculations-YEoVCG2q.js +310 -0
  10. package/dist/chunks/{captcha-eu-CGm8Lbrj.js → captcha-eu-DERJbXnH.js} +5 -4
  11. package/dist/chunks/{checkbox-radio-BY2aTCOG.js → checkbox-radio-gsm8QPJg.js} +74 -75
  12. package/dist/chunks/{combobox-C0EuExSI.js → combobox-CWNdx4Fk.js} +290 -279
  13. package/dist/chunks/conditions-DqNHLTbN.js +464 -0
  14. package/dist/chunks/country-from-ip-DDj_mFki.js +29 -0
  15. package/dist/chunks/csrf-DxHg_ZYt.js +61 -0
  16. package/dist/chunks/{custom-google-maps-BsaSirEZ.js → custom-google-maps-C4l2S3GO.js} +9 -3
  17. package/dist/chunks/{custom-link-CJ1-FjEM.js → custom-link-CLazgKYH.js} +8 -2
  18. package/dist/chunks/{custom-maps-DYW_pBid.js → custom-maps-DqcAlD0v.js} +10 -4
  19. package/dist/chunks/{date-picker-5CA_-zGb.js → date-picker-RUnevF7l.js} +456 -430
  20. package/dist/chunks/{dist-BdUy8m_p.js → dist-ZLeW0zZ3.js} +1280 -452
  21. package/dist/chunks/{eway-D9_m8ooj.js → eway-or6dtjoT.js} +3 -3
  22. package/dist/chunks/field-references.resolver-Ca8MguFv.js +104 -0
  23. package/dist/chunks/{file-upload-rqfZNqlH.js → file-upload-Bm-TXyNB.js} +104 -96
  24. package/dist/chunks/friendly-captcha-v1-GFqCt1Mh.js +34 -0
  25. package/dist/chunks/{friendly-captcha-v2-CLSAbkqx.js → friendly-captcha-v2-WoW246JG.js} +6 -5
  26. package/dist/chunks/{friendly-challenge-8uPatWqk.js → friendly-challenge-DPG9MJb1.js} +111 -102
  27. package/dist/chunks/{go-cardless-DAT3ZaQf.js → go-cardless-DzJ-0FKg.js} +2 -2
  28. package/dist/chunks/google-address-C1P1nTDM.js +163 -0
  29. package/dist/chunks/{hcaptcha-CGLAmgjO.js → hcaptcha-D0T8aIHz.js} +3 -3
  30. package/dist/chunks/{hidden-D7_Ch-QN.js → hidden-BZhXnNPe.js} +8 -2
  31. package/dist/chunks/http-C2QdHuWO.js +27 -0
  32. package/dist/chunks/{leaflet-src-j-lHNmhR.js → leaflet-src-DE6rv6M-.js} +42 -46
  33. package/dist/chunks/{loqate-CJPzBmSm.js → loqate-DD1S7PY9.js} +2 -2
  34. package/dist/chunks/{mollie-Bibhl67p.js → mollie-DG8Ju83x.js} +2 -2
  35. package/dist/chunks/{moneris-H2wSqk9h.js → moneris-C8m3Fvqu.js} +3 -3
  36. package/dist/chunks/opayo-B3EvrVxw.js +188 -0
  37. package/dist/chunks/{paddle-DkvIxQdG.js → paddle-BIYR9Um3.js} +3 -3
  38. package/dist/chunks/{password-validation-T0vDQPCr.js → password-validation-C8_uO_c_.js} +18 -12
  39. package/dist/chunks/{paypal-CQpAF7Ua.js → paypal-B_yxIo2d.js} +7 -5
  40. package/dist/chunks/{payway-CwDkC7YZ.js → payway-CeOzS0sL.js} +3 -3
  41. package/dist/chunks/{phone-country-D3ayr60L.js → phone-country-bAqje17P.js} +80 -63
  42. package/dist/chunks/{place-kit-BGHklIZ-.js → place-kit-BE5gi3vo.js} +3 -3
  43. package/dist/chunks/{placekit-autocomplete.esm-DWVabQlq.js → placekit-autocomplete.esm-CZZERYur.js} +11 -15
  44. package/dist/chunks/{recaptcha-enterprise-XPId5-bS.js → recaptcha-enterprise-CruXddZq.js} +4 -4
  45. package/dist/chunks/{recaptcha-shared-CLYJvojk.js → recaptcha-shared-AQRMDMme.js} +1 -1
  46. package/dist/chunks/{recaptcha-v2-checkbox-Cy-0PEPc.js → recaptcha-v2-checkbox-CCnJYCnG.js} +4 -4
  47. package/dist/chunks/{recaptcha-v2-invisible-BwRH540O.js → recaptcha-v2-invisible-BuVqRRYn.js} +4 -4
  48. package/dist/chunks/{recaptcha-v3-No4Ykrhk.js → recaptcha-v3-CloqhO2A.js} +4 -4
  49. package/dist/chunks/{repeater-BVnPUqTj.js → repeater-DwE27jI1.js} +25 -19
  50. package/dist/chunks/request-profile-DhwkeCpS.js +10 -0
  51. package/dist/chunks/rich-text-uV4o_pGk.js +361 -0
  52. package/dist/chunks/{chunk-3b4jIN3o.js → rolldown-runtime-DtPi1Y-2.js} +2 -2
  53. package/dist/chunks/{sdk-BhHAYgga.js → sdk-lkwSvlpM.js} +282 -234
  54. package/dist/chunks/{shared-Bx9s0i0P.js → shared-OKhSay59.js} +27 -21
  55. package/dist/chunks/{signature-xz4QO7CR.js → signature-7cldFbqj.js} +160 -112
  56. package/dist/chunks/{snaptcha-DKx98oon.js → snaptcha-C04kNGYQ.js} +2 -2
  57. package/dist/chunks/{square-DwdcOI1G.js → square-DEzxv9D9.js} +8 -6
  58. package/dist/chunks/{stripe-DaoG2FT1.js → stripe-CVPQGDz3.js} +10 -11
  59. package/dist/chunks/{summary-Dks0gXS3.js → summary-BF_8mrXI.js} +47 -45
  60. package/dist/chunks/{survey-likert-DkE6bR7B.js → survey-likert-fk1hUPff.js} +7 -1
  61. package/dist/chunks/{survey-rank-DN6x4IZM.js → survey-rank-BsLGl2LX.js} +37 -25
  62. package/dist/chunks/{survey-rating-BnsNL9U5.js → survey-rating-DVS6e6fM.js} +17 -5
  63. package/dist/chunks/{table-CAjCJHrL.js → table-DnIBdeKF.js} +21 -15
  64. package/dist/chunks/{text-limit-Bn18WrPU.js → text-limit-LGMPhFuC.js} +40 -34
  65. package/dist/chunks/{theme-classes-Tv7q7ToE.js → theme-classes-DAQuEqdP.js} +1 -1
  66. package/dist/chunks/{turnstile-DJakPzQD.js → turnstile-n9DNyPxi.js} +3 -3
  67. package/dist/chunks/{upload-manager-W-QDgxKD.js → upload-manager-BbiUosZq.js} +410 -350
  68. package/dist/chunks/{utils-Vqp8i_RM.js → utils-DpUBPadZ.js} +20 -14
  69. package/dist/css/formie-base.css +104 -1
  70. package/dist/css/theme/_messages.css +2 -0
  71. package/dist/css/theme/_tokens.css +31 -25
  72. package/dist/css/theme/fields/_signature.css +2 -1
  73. package/dist/css/theme/forms/_form.css +5 -1
  74. package/dist/index.d.ts +5 -4
  75. package/dist/index.d.ts.map +1 -1
  76. package/dist/index.js +1778 -1425
  77. package/dist/js/contracts/client.d.ts +5 -3
  78. package/dist/js/contracts/client.d.ts.map +1 -1
  79. package/dist/js/contracts/common.d.ts +2 -2
  80. package/dist/js/contracts/common.d.ts.map +1 -1
  81. package/dist/js/contracts/modules.d.ts +37 -12
  82. package/dist/js/contracts/modules.d.ts.map +1 -1
  83. package/dist/js/contracts/schema.d.ts +20 -38
  84. package/dist/js/contracts/schema.d.ts.map +1 -1
  85. package/dist/js/contracts/theme.d.ts +4 -1
  86. package/dist/js/contracts/theme.d.ts.map +1 -1
  87. package/dist/js/core/client-rendered-modules.d.ts +17 -0
  88. package/dist/js/core/client-rendered-modules.d.ts.map +1 -0
  89. package/dist/js/core/create-formie-client.d.ts.map +1 -1
  90. package/dist/js/core/field-error-aria.d.ts +23 -0
  91. package/dist/js/core/field-error-aria.d.ts.map +1 -0
  92. package/dist/js/core/hydrate-modules.d.ts +10 -8
  93. package/dist/js/core/hydrate-modules.d.ts.map +1 -1
  94. package/dist/js/core/submit-result-state.d.ts.map +1 -1
  95. package/dist/js/core/submit-result-ui.d.ts.map +1 -1
  96. package/dist/js/core/validation-focus.d.ts.map +1 -1
  97. package/dist/js/modules/address/address-finder.d.ts +1 -1
  98. package/dist/js/modules/address/address-finder.d.ts.map +1 -1
  99. package/dist/js/modules/address/factories.d.ts +3 -3
  100. package/dist/js/modules/address/factories.d.ts.map +1 -1
  101. package/dist/js/modules/address/google-address.d.ts +2 -1
  102. package/dist/js/modules/address/google-address.d.ts.map +1 -1
  103. package/dist/js/modules/address/index.d.ts +2 -2
  104. package/dist/js/modules/address/index.d.ts.map +1 -1
  105. package/dist/js/modules/address/loqate.d.ts +1 -1
  106. package/dist/js/modules/address/loqate.d.ts.map +1 -1
  107. package/dist/js/modules/address/place-kit.d.ts +1 -1
  108. package/dist/js/modules/address/place-kit.d.ts.map +1 -1
  109. package/dist/js/modules/captchas/captcha-eu.d.ts +1 -1
  110. package/dist/js/modules/captchas/captcha-eu.d.ts.map +1 -1
  111. package/dist/js/modules/captchas/factories.d.ts +11 -11
  112. package/dist/js/modules/captchas/factories.d.ts.map +1 -1
  113. package/dist/js/modules/captchas/friendly-captcha-v1.d.ts +1 -1
  114. package/dist/js/modules/captchas/friendly-captcha-v1.d.ts.map +1 -1
  115. package/dist/js/modules/captchas/friendly-captcha-v2.d.ts +1 -1
  116. package/dist/js/modules/captchas/friendly-captcha-v2.d.ts.map +1 -1
  117. package/dist/js/modules/captchas/hcaptcha.d.ts +1 -1
  118. package/dist/js/modules/captchas/hcaptcha.d.ts.map +1 -1
  119. package/dist/js/modules/captchas/index.d.ts +2 -2
  120. package/dist/js/modules/captchas/index.d.ts.map +1 -1
  121. package/dist/js/modules/captchas/recaptcha-enterprise.d.ts +1 -1
  122. package/dist/js/modules/captchas/recaptcha-enterprise.d.ts.map +1 -1
  123. package/dist/js/modules/captchas/recaptcha-v2-checkbox.d.ts +1 -1
  124. package/dist/js/modules/captchas/recaptcha-v2-checkbox.d.ts.map +1 -1
  125. package/dist/js/modules/captchas/recaptcha-v2-invisible.d.ts +1 -1
  126. package/dist/js/modules/captchas/recaptcha-v2-invisible.d.ts.map +1 -1
  127. package/dist/js/modules/captchas/recaptcha-v3.d.ts +1 -1
  128. package/dist/js/modules/captchas/recaptcha-v3.d.ts.map +1 -1
  129. package/dist/js/modules/captchas/snaptcha.d.ts +1 -1
  130. package/dist/js/modules/captchas/snaptcha.d.ts.map +1 -1
  131. package/dist/js/modules/captchas/turnstile.d.ts +1 -1
  132. package/dist/js/modules/captchas/turnstile.d.ts.map +1 -1
  133. package/dist/js/modules/fields/address-country.d.ts +2 -2
  134. package/dist/js/modules/fields/address-country.d.ts.map +1 -1
  135. package/dist/js/modules/fields/address-state.d.ts +2 -2
  136. package/dist/js/modules/fields/address-state.d.ts.map +1 -1
  137. package/dist/js/modules/fields/calculations.d.ts +2 -2
  138. package/dist/js/modules/fields/calculations.d.ts.map +1 -1
  139. package/dist/js/modules/fields/checkbox-radio.d.ts +2 -2
  140. package/dist/js/modules/fields/checkbox-radio.d.ts.map +1 -1
  141. package/dist/js/modules/fields/combobox.d.ts +2 -2
  142. package/dist/js/modules/fields/combobox.d.ts.map +1 -1
  143. package/dist/js/modules/fields/conditions/config.d.ts.map +1 -1
  144. package/dist/js/modules/fields/conditions/effects.d.ts +1 -0
  145. package/dist/js/modules/fields/conditions/effects.d.ts.map +1 -1
  146. package/dist/js/modules/fields/conditions/evaluator.d.ts +4 -1
  147. package/dist/js/modules/fields/conditions/evaluator.d.ts.map +1 -1
  148. package/dist/js/modules/fields/conditions/references.d.ts.map +1 -1
  149. package/dist/js/modules/fields/conditions/submission-context.d.ts +15 -0
  150. package/dist/js/modules/fields/conditions/submission-context.d.ts.map +1 -0
  151. package/dist/js/modules/fields/conditions/types.d.ts +3 -1
  152. package/dist/js/modules/fields/conditions/types.d.ts.map +1 -1
  153. package/dist/js/modules/fields/conditions/values.d.ts +1 -1
  154. package/dist/js/modules/fields/conditions/values.d.ts.map +1 -1
  155. package/dist/js/modules/fields/conditions.d.ts +2 -2
  156. package/dist/js/modules/fields/conditions.d.ts.map +1 -1
  157. package/dist/js/modules/fields/custom-google-maps.d.ts +2 -2
  158. package/dist/js/modules/fields/custom-google-maps.d.ts.map +1 -1
  159. package/dist/js/modules/fields/custom-link.d.ts +2 -2
  160. package/dist/js/modules/fields/custom-link.d.ts.map +1 -1
  161. package/dist/js/modules/fields/custom-maps.d.ts +2 -2
  162. package/dist/js/modules/fields/custom-maps.d.ts.map +1 -1
  163. package/dist/js/modules/fields/date-picker.d.ts +2 -2
  164. package/dist/js/modules/fields/date-picker.d.ts.map +1 -1
  165. package/dist/js/modules/fields/file-upload.d.ts +2 -2
  166. package/dist/js/modules/fields/file-upload.d.ts.map +1 -1
  167. package/dist/js/modules/fields/hidden.d.ts +2 -2
  168. package/dist/js/modules/fields/hidden.d.ts.map +1 -1
  169. package/dist/js/modules/fields/index.d.ts +2 -2
  170. package/dist/js/modules/fields/index.d.ts.map +1 -1
  171. package/dist/js/modules/fields/password-validation.d.ts +2 -2
  172. package/dist/js/modules/fields/password-validation.d.ts.map +1 -1
  173. package/dist/js/modules/fields/phone-country.d.ts +2 -2
  174. package/dist/js/modules/fields/phone-country.d.ts.map +1 -1
  175. package/dist/js/modules/fields/repeater.d.ts +2 -2
  176. package/dist/js/modules/fields/repeater.d.ts.map +1 -1
  177. package/dist/js/modules/fields/rich-text.d.ts +2 -2
  178. package/dist/js/modules/fields/rich-text.d.ts.map +1 -1
  179. package/dist/js/modules/fields/shared.d.ts +1 -0
  180. package/dist/js/modules/fields/shared.d.ts.map +1 -1
  181. package/dist/js/modules/fields/signature.d.ts +2 -2
  182. package/dist/js/modules/fields/signature.d.ts.map +1 -1
  183. package/dist/js/modules/fields/summary.d.ts +2 -2
  184. package/dist/js/modules/fields/summary.d.ts.map +1 -1
  185. package/dist/js/modules/fields/survey-likert.d.ts +2 -2
  186. package/dist/js/modules/fields/survey-likert.d.ts.map +1 -1
  187. package/dist/js/modules/fields/survey-rank.d.ts +2 -2
  188. package/dist/js/modules/fields/survey-rank.d.ts.map +1 -1
  189. package/dist/js/modules/fields/survey-rating.d.ts +2 -2
  190. package/dist/js/modules/fields/survey-rating.d.ts.map +1 -1
  191. package/dist/js/modules/fields/table.d.ts +2 -2
  192. package/dist/js/modules/fields/table.d.ts.map +1 -1
  193. package/dist/js/modules/fields/text-limit.d.ts +2 -2
  194. package/dist/js/modules/fields/text-limit.d.ts.map +1 -1
  195. package/dist/js/modules/fields/upload-manager.d.ts +2 -2
  196. package/dist/js/modules/fields/upload-manager.d.ts.map +1 -1
  197. package/dist/js/modules/loader.d.ts +10 -4
  198. package/dist/js/modules/loader.d.ts.map +1 -1
  199. package/dist/js/modules/payments/bpoint.d.ts +1 -1
  200. package/dist/js/modules/payments/bpoint.d.ts.map +1 -1
  201. package/dist/js/modules/payments/eway.d.ts +1 -1
  202. package/dist/js/modules/payments/eway.d.ts.map +1 -1
  203. package/dist/js/modules/payments/factories.d.ts +7 -7
  204. package/dist/js/modules/payments/factories.d.ts.map +1 -1
  205. package/dist/js/modules/payments/go-cardless.d.ts +1 -1
  206. package/dist/js/modules/payments/go-cardless.d.ts.map +1 -1
  207. package/dist/js/modules/payments/index.d.ts +2 -2
  208. package/dist/js/modules/payments/index.d.ts.map +1 -1
  209. package/dist/js/modules/payments/mollie.d.ts +1 -1
  210. package/dist/js/modules/payments/mollie.d.ts.map +1 -1
  211. package/dist/js/modules/payments/moneris.d.ts +1 -1
  212. package/dist/js/modules/payments/moneris.d.ts.map +1 -1
  213. package/dist/js/modules/payments/opayo.d.ts +1 -1
  214. package/dist/js/modules/payments/opayo.d.ts.map +1 -1
  215. package/dist/js/modules/payments/paddle.d.ts +1 -1
  216. package/dist/js/modules/payments/paddle.d.ts.map +1 -1
  217. package/dist/js/modules/payments/paypal.d.ts +1 -1
  218. package/dist/js/modules/payments/paypal.d.ts.map +1 -1
  219. package/dist/js/modules/payments/payway.d.ts +1 -1
  220. package/dist/js/modules/payments/payway.d.ts.map +1 -1
  221. package/dist/js/modules/payments/square.d.ts +1 -1
  222. package/dist/js/modules/payments/square.d.ts.map +1 -1
  223. package/dist/js/modules/payments/stripe.d.ts +1 -1
  224. package/dist/js/modules/payments/stripe.d.ts.map +1 -1
  225. package/dist/js/modules/payments/utils.d.ts +6 -0
  226. package/dist/js/modules/payments/utils.d.ts.map +1 -1
  227. package/dist/js/modules/registry.d.ts +6 -4
  228. package/dist/js/modules/registry.d.ts.map +1 -1
  229. package/dist/js/submit/pipeline.d.ts.map +1 -1
  230. package/dist/js/theme/browser-theme-state.generated.d.ts +24 -0
  231. package/dist/js/theme/browser-theme-state.generated.d.ts.map +1 -0
  232. package/dist/js/theme/theme-classes.d.ts +3 -3
  233. package/dist/js/theme/theme-classes.d.ts.map +1 -1
  234. package/dist/js/transport/forms-api.d.ts +5 -3
  235. package/dist/js/transport/forms-api.d.ts.map +1 -1
  236. package/dist/js/utils/country-from-ip.d.ts +2 -2
  237. package/dist/js/utils/country-from-ip.d.ts.map +1 -1
  238. package/dist/js/utils/csrf.d.ts +17 -0
  239. package/dist/js/utils/csrf.d.ts.map +1 -0
  240. package/dist/js/utils/field-references.parser.d.ts +1 -0
  241. package/dist/js/utils/field-references.parser.d.ts.map +1 -1
  242. package/dist/js/utils/field-references.resolver.d.ts.map +1 -1
  243. package/dist/js/utils/field-references.types.d.ts +1 -0
  244. package/dist/js/utils/field-references.types.d.ts.map +1 -1
  245. package/dist/js/utils/http.d.ts +3 -1
  246. package/dist/js/utils/http.d.ts.map +1 -1
  247. package/dist/js/utils/request-profile.d.ts +4 -0
  248. package/dist/js/utils/request-profile.d.ts.map +1 -0
  249. package/dist/js/utils/unload-warning.d.ts.map +1 -1
  250. package/dist/js/validation/rules/email.d.ts.map +1 -1
  251. package/dist/js/validation/rules/match.d.ts.map +1 -1
  252. package/dist/js/validation/rules/number.d.ts.map +1 -1
  253. package/dist/js/validation/rules/required.d.ts.map +1 -1
  254. package/dist/js/validation/rules/shared.d.ts.map +1 -1
  255. package/dist/js/validation/rules/url.d.ts.map +1 -1
  256. package/dist/js/validation/skip.d.ts +7 -0
  257. package/dist/js/validation/skip.d.ts.map +1 -0
  258. package/dist/js/validation/submit-readiness.d.ts.map +1 -1
  259. package/dist/js/validation/validator.d.ts.map +1 -1
  260. package/package.json +43 -12
  261. package/src/css/formie-base.css +104 -1
  262. package/src/css/theme/_messages.css +2 -0
  263. package/src/css/theme/_tokens.css +31 -25
  264. package/src/css/theme/fields/_signature.css +2 -1
  265. package/src/css/theme/forms/_form.css +5 -1
  266. package/src/index.ts +13 -8
  267. package/src/js/contracts/client.ts +5 -3
  268. package/src/js/contracts/common.ts +5 -6
  269. package/src/js/contracts/modules.ts +41 -12
  270. package/src/js/contracts/schema.ts +21 -43
  271. package/src/js/contracts/theme.ts +6 -1
  272. package/src/js/core/client-rendered-modules.ts +69 -0
  273. package/src/js/core/create-formie-client.ts +119 -73
  274. package/src/js/core/field-error-aria.ts +93 -0
  275. package/src/js/core/hydrate-modules.ts +54 -29
  276. package/src/js/core/submit-result-state.ts +34 -45
  277. package/src/js/core/submit-result-ui.ts +21 -65
  278. package/src/js/core/validation-focus.ts +20 -20
  279. package/src/js/modules/address/address-finder.ts +1 -1
  280. package/src/js/modules/address/factories.ts +15 -13
  281. package/src/js/modules/address/google-address.ts +10 -6
  282. package/src/js/modules/address/index.ts +2 -2
  283. package/src/js/modules/address/loqate.ts +1 -1
  284. package/src/js/modules/address/place-kit.ts +1 -1
  285. package/src/js/modules/captchas/captcha-eu.ts +2 -2
  286. package/src/js/modules/captchas/factories.ts +66 -42
  287. package/src/js/modules/captchas/friendly-captcha-v1.ts +12 -2
  288. package/src/js/modules/captchas/friendly-captcha-v2.ts +4 -2
  289. package/src/js/modules/captchas/hcaptcha.ts +5 -5
  290. package/src/js/modules/captchas/index.ts +2 -2
  291. package/src/js/modules/captchas/recaptcha-enterprise.ts +2 -2
  292. package/src/js/modules/captchas/recaptcha-v2-checkbox.ts +3 -3
  293. package/src/js/modules/captchas/recaptcha-v2-invisible.ts +2 -2
  294. package/src/js/modules/captchas/recaptcha-v3.ts +2 -2
  295. package/src/js/modules/captchas/snaptcha.ts +1 -1
  296. package/src/js/modules/captchas/turnstile.ts +3 -3
  297. package/src/js/modules/fields/address-country.ts +6 -4
  298. package/src/js/modules/fields/address-state.ts +20 -12
  299. package/src/js/modules/fields/calculations.ts +5 -3
  300. package/src/js/modules/fields/checkbox-radio.ts +24 -42
  301. package/src/js/modules/fields/combobox.ts +25 -9
  302. package/src/js/modules/fields/conditions/config.ts +17 -20
  303. package/src/js/modules/fields/conditions/effects.ts +23 -26
  304. package/src/js/modules/fields/conditions/evaluator.ts +21 -29
  305. package/src/js/modules/fields/conditions/references.ts +16 -5
  306. package/src/js/modules/fields/conditions/submission-context.ts +80 -0
  307. package/src/js/modules/fields/conditions/types.ts +3 -1
  308. package/src/js/modules/fields/conditions/values.ts +31 -6
  309. package/src/js/modules/fields/conditions.ts +59 -18
  310. package/src/js/modules/fields/custom-google-maps.ts +5 -3
  311. package/src/js/modules/fields/custom-link.ts +5 -3
  312. package/src/js/modules/fields/custom-maps.ts +5 -3
  313. package/src/js/modules/fields/date-picker.ts +40 -4
  314. package/src/js/modules/fields/file-upload.ts +19 -10
  315. package/src/js/modules/fields/hidden.ts +5 -3
  316. package/src/js/modules/fields/index.ts +2 -2
  317. package/src/js/modules/fields/password-validation.ts +5 -3
  318. package/src/js/modules/fields/phone-country.ts +33 -6
  319. package/src/js/modules/fields/repeater.ts +5 -3
  320. package/src/js/modules/fields/rich-text.ts +20 -4
  321. package/src/js/modules/fields/shared.ts +13 -0
  322. package/src/js/modules/fields/signature.ts +64 -6
  323. package/src/js/modules/fields/summary.ts +8 -20
  324. package/src/js/modules/fields/survey-likert.ts +5 -3
  325. package/src/js/modules/fields/survey-rank.ts +21 -3
  326. package/src/js/modules/fields/survey-rating.ts +17 -3
  327. package/src/js/modules/fields/table.ts +5 -3
  328. package/src/js/modules/fields/text-limit.ts +5 -3
  329. package/src/js/modules/fields/upload-manager.ts +190 -49
  330. package/src/js/modules/loader.ts +345 -281
  331. package/src/js/modules/payments/bpoint.ts +2 -2
  332. package/src/js/modules/payments/eway.ts +2 -2
  333. package/src/js/modules/payments/factories.ts +53 -52
  334. package/src/js/modules/payments/go-cardless.ts +1 -1
  335. package/src/js/modules/payments/index.ts +2 -2
  336. package/src/js/modules/payments/mollie.ts +1 -1
  337. package/src/js/modules/payments/moneris.ts +2 -2
  338. package/src/js/modules/payments/opayo.ts +21 -8
  339. package/src/js/modules/payments/paddle.ts +10 -6
  340. package/src/js/modules/payments/payment.ts +22 -18
  341. package/src/js/modules/payments/paypal.ts +1 -1
  342. package/src/js/modules/payments/payway.ts +2 -2
  343. package/src/js/modules/payments/square.ts +2 -2
  344. package/src/js/modules/payments/stripe.ts +5 -5
  345. package/src/js/modules/payments/utils.ts +14 -0
  346. package/src/js/modules/registry.ts +19 -11
  347. package/src/js/submit/pipeline.ts +10 -11
  348. package/src/js/theme/browser-theme-state.generated.ts +25 -0
  349. package/src/js/theme/theme-classes.ts +3 -3
  350. package/src/js/transport/forms-api.ts +66 -67
  351. package/src/js/utils/country-from-ip.ts +14 -9
  352. package/src/js/utils/csrf.ts +136 -0
  353. package/src/js/utils/field-references.parser.ts +13 -113
  354. package/src/js/utils/field-references.resolver.ts +27 -64
  355. package/src/js/utils/field-references.row-scope.ts +1 -1
  356. package/src/js/utils/field-references.types.ts +1 -0
  357. package/src/js/utils/http.ts +5 -5
  358. package/src/js/utils/request-profile.ts +10 -0
  359. package/src/js/utils/unload-warning.ts +12 -4
  360. package/src/js/validation/rules/email.ts +3 -5
  361. package/src/js/validation/rules/match.ts +2 -1
  362. package/src/js/validation/rules/minmax.ts +4 -43
  363. package/src/js/validation/rules/number.ts +3 -47
  364. package/src/js/validation/rules/pattern.ts +3 -8
  365. package/src/js/validation/rules/required.ts +2 -1
  366. package/src/js/validation/rules/shared.ts +5 -1
  367. package/src/js/validation/rules/url.ts +3 -10
  368. package/src/js/validation/skip.ts +9 -0
  369. package/src/js/validation/submit-readiness.ts +9 -2
  370. package/src/js/validation/validator.ts +35 -59
  371. package/dist/chunks/calculations-DERi2xaC.js +0 -299
  372. package/dist/chunks/conditions-65kBcFWW.js +0 -424
  373. package/dist/chunks/country-from-ip-BwxKaBuJ.js +0 -26
  374. package/dist/chunks/field-references.resolver-CHwn0G0L.js +0 -145
  375. package/dist/chunks/friendly-captcha-v1-C_2reOXr.js +0 -31
  376. package/dist/chunks/google-address-BH3Zhi06.js +0 -161
  377. package/dist/chunks/http-D-JExro7.js +0 -27
  378. package/dist/chunks/opayo-CR0DtsLa.js +0 -179
  379. package/dist/chunks/rich-text-Bg_--4TG.js +0 -349
  380. package/dist/js/modules/fields/conditions/transforms.d.ts +0 -3
  381. package/dist/js/modules/fields/conditions/transforms.d.ts.map +0 -1
  382. package/src/js/modules/fields/conditions/transforms.ts +0 -206
  383. package/src/js/modules/payments/stub-payment-module.ts +0 -87
@@ -8,12 +8,12 @@ type BpointCardData = {
8
8
  };
9
9
 
10
10
  export const bpointModule = definePaymentModule<Record<string, never>, null, null>({
11
- id: 'bpoint',
11
+ moduleId: 'formie:bpoint',
12
12
  defaultRequiredInputSuffixes: ['bpointToken'],
13
13
  load: async() => {
14
14
  return null;
15
15
  },
16
- onBeforeAuthorize: async({ field, services }) => {
16
+ onBeforePayment: async({ field, services }) => {
17
17
  const existingValue = (field.querySelector('input[name$="[bpointToken]"]') as HTMLInputElement | null)?.value || '';
18
18
  if (existingValue.trim() !== '') {
19
19
  return true;
@@ -69,7 +69,7 @@ async function ensureEwayEncryptApi(): Promise<EwayEncryptApi> {
69
69
  }
70
70
 
71
71
  export const ewayModule = definePaymentModule<EwayProviderOptions, EwayEncryptApi | null, null>({
72
- id: 'eway',
72
+ moduleId: 'formie:eway',
73
73
  defaultRequiredInputSuffixes: ['ewayTokenData'],
74
74
  load: async(ctx) => {
75
75
  const { provider } = ctx.options;
@@ -82,7 +82,7 @@ export const ewayModule = definePaymentModule<EwayProviderOptions, EwayEncryptAp
82
82
 
83
83
  return ensureEwayEncryptApi();
84
84
  },
85
- onBeforeAuthorize: async(args) => {
85
+ onBeforePayment: async(args) => {
86
86
  const { field, services, provider, api } = args;
87
87
  const cseKey = provider.cseKey as string | undefined;
88
88
 
@@ -1,6 +1,6 @@
1
1
  import type {
2
- FormieModuleDefinition,
3
- FormieModuleInstance,
2
+ BrowserModuleDefinition,
3
+ BrowserModuleInstance,
4
4
  ModuleSetupContext,
5
5
  } from '#contracts/modules';
6
6
  import { DEFAULT_REQUIRED_INPUT_SUFFIXES } from '#modules/payments/constants';
@@ -10,19 +10,13 @@ import {
10
10
  type PaymentHostServices,
11
11
  normalizePaymentModuleOptions,
12
12
  } from '#modules/payments/host';
13
- import { waitForRequiredPaymentInputs } from '#modules/payments/utils';
13
+ import { isPaymentFieldActive, waitForRequiredPaymentInputs } from '#modules/payments/utils';
14
14
  import { createDebug } from '#utils/debug';
15
15
 
16
16
  type Cleanup = () => void;
17
17
  type PaymentModuleRegistry = Record<string, { destroy: () => Promise<void> }>;
18
18
  const debug = createDebug('payments');
19
19
 
20
- function isTargetVisible(element: Element): boolean {
21
- const node = element as HTMLElement;
22
-
23
- return !node.closest('[data-formie-page-hidden]') && !node.closest('[hidden]');
24
- }
25
-
26
20
  export type PaymentModuleSetupContext<TProvider extends Record<string, unknown>> = Omit<ModuleSetupContext, 'options'> & {
27
21
  options: NormalizedPaymentModuleOptions<TProvider>;
28
22
  services: PaymentHostServices;
@@ -30,7 +24,7 @@ export type PaymentModuleSetupContext<TProvider extends Record<string, unknown>>
30
24
 
31
25
  type PaymentSetupResult = {
32
26
  destroy?: () => void | Promise<void>;
33
- onBeforeStage?: (stageCtx: import('#contracts/modules').SubmitHookContext) => void | Promise<void>;
27
+ beforeSubmit?: (stageCtx: import('#contracts/modules').BeforeSubmitContext) => void | Promise<void>;
34
28
  };
35
29
 
36
30
  export type PaymentAfterSubmitResult = {
@@ -43,7 +37,7 @@ export type ManagedPaymentModuleAdapter<
43
37
  TApi,
44
38
  TWidget,
45
39
  > = {
46
- id: string;
40
+ moduleId: string;
47
41
  defaultRequiredInputSuffixes?: string[];
48
42
  load: (ctx: PaymentModuleSetupContext<TProvider>) => Promise<TApi>;
49
43
  /** Redirect-only providers (Mollie, GoCardless): attach listeners, return destroy. No mount needed. */
@@ -63,16 +57,16 @@ export type ManagedPaymentModuleAdapter<
63
57
  options: NormalizedPaymentModuleOptions<TProvider>;
64
58
  provider: TProvider;
65
59
  }) => Promise<void> | void;
66
- onBeforeAuthorize?: (args: {
60
+ onBeforePayment?: (args: {
67
61
  api: TApi;
68
62
  widget: TWidget | null;
69
63
  field: Element;
70
64
  services: PaymentHostServices;
71
65
  options: NormalizedPaymentModuleOptions<TProvider>;
72
66
  provider: TProvider;
73
- stageCtx: import('#contracts/modules').SubmitHookContext;
67
+ stageCtx: import('#contracts/modules').BeforeSubmitContext;
74
68
  }) => Promise<boolean> | boolean;
75
- /** Called after dispatch (on any result) to reset hidden inputs, clear UI, etc. */
69
+ /** Called after send (on any result) to reset hidden inputs, clear UI, etc. */
76
70
  onAfterSubmit?: (args: {
77
71
  field: Element;
78
72
  services: PaymentHostServices;
@@ -86,13 +80,15 @@ export function createManagedPaymentModule<
86
80
  TProvider extends Record<string, unknown>,
87
81
  TApi,
88
82
  TWidget,
89
- >(adapter: ManagedPaymentModuleAdapter<TProvider, TApi, TWidget>): FormieModuleDefinition {
83
+ >(adapter: ManagedPaymentModuleAdapter<TProvider, TApi, TWidget>): BrowserModuleDefinition {
90
84
  const defaultSuffixes = adapter.defaultRequiredInputSuffixes
91
- ?? DEFAULT_REQUIRED_INPUT_SUFFIXES[adapter.id]
85
+ ?? DEFAULT_REQUIRED_INPUT_SUFFIXES[adapter.moduleId.split(':')[1]]
92
86
  ?? [];
93
87
 
94
88
  return {
95
- id: adapter.id,
89
+ moduleId: adapter.moduleId,
90
+ version: 2,
91
+ surfaces: ['server-rendered', 'client-rendered'],
96
92
  kind: 'payment',
97
93
  match: (ctx) => {
98
94
  return !!(ctx.target.querySelector('[data-formie-field-type="payment"]')
@@ -104,12 +100,12 @@ export function createManagedPaymentModule<
104
100
  const registry = fieldWithRegistry.__formiePaymentModuleRegistry || {};
105
101
  fieldWithRegistry.__formiePaymentModuleRegistry = registry;
106
102
 
107
- // Defensive singleton guard per field/provider: if this module somehow
108
- // gets initialized again without teardown, clean the previous instance first.
109
- const previous = registry[adapter.id];
103
+ // Each configured occurrence owns its provider state independently.
104
+ const occurrenceKey = ctx.entryKey ?? adapter.moduleId;
105
+ const previous = registry[occurrenceKey];
110
106
  if (previous?.destroy) {
111
107
  debug.warn('Found stale payment module instance; destroying previous.', {
112
- moduleId: adapter.id,
108
+ moduleId: adapter.moduleId,
113
109
  });
114
110
  try {
115
111
  await previous.destroy();
@@ -119,7 +115,7 @@ export function createManagedPaymentModule<
119
115
  }
120
116
 
121
117
  const options = normalizePaymentModuleOptions<TProvider>(
122
- adapter.id,
118
+ adapter.moduleId.split(':')[1],
123
119
  ctx.options || {},
124
120
  {
125
121
  defaultRequiredInputSuffixes: defaultSuffixes,
@@ -141,7 +137,7 @@ export function createManagedPaymentModule<
141
137
 
142
138
  const getApi = async(): Promise<TApi> => {
143
139
  if (!apiPromise) {
144
- debug.log('Loading payment provider API.', { moduleId: adapter.id });
140
+ debug.log('Loading payment provider API.', { moduleId: adapter.moduleId });
145
141
  apiPromise = adapter.load(setupCtx);
146
142
  }
147
143
 
@@ -149,7 +145,7 @@ export function createManagedPaymentModule<
149
145
  };
150
146
 
151
147
  const ensureMounted = async() => {
152
- if (!adapter.mount || widget || !isTargetVisible(ctx.target)) {
148
+ if (!adapter.mount || widget || !isPaymentFieldActive(ctx.target)) {
153
149
  return;
154
150
  }
155
151
 
@@ -164,15 +160,16 @@ export function createManagedPaymentModule<
164
160
  provider: options.provider,
165
161
  });
166
162
  debug.log('Payment widget mounted.', {
167
- moduleId: adapter.id,
163
+ moduleId: adapter.moduleId,
168
164
  handle: options.handle,
169
165
  });
170
- } catch {
171
- // Mount failed; widget stays null
166
+ } catch (error) {
167
+ // Propagate initialization failure to the required/optional policy.
172
168
  debug.warn('Payment widget mount failed.', {
173
- moduleId: adapter.id,
169
+ moduleId: adapter.moduleId,
174
170
  handle: options.handle,
175
171
  });
172
+ throw error;
176
173
  }
177
174
  };
178
175
 
@@ -190,10 +187,11 @@ export function createManagedPaymentModule<
190
187
  }
191
188
  }
192
189
 
193
- if (adapter.mount && isTargetVisible(ctx.target)) {
190
+ if (adapter.mount && isPaymentFieldActive(ctx.target)) {
194
191
  await ensureMounted();
195
192
  }
196
193
 
194
+ // Remount when page flow or field conditions reveal this payment field.
197
195
  const visibilityEvents = ['formie:page:navigate:after', 'formie:submit:result'];
198
196
  visibilityEvents.forEach((eventName) => {
199
197
  const handleVisibility = () => {
@@ -206,9 +204,14 @@ export function createManagedPaymentModule<
206
204
  });
207
205
  });
208
206
 
207
+ // Conditions emit on the module bus (not only as page-nav DOM events).
208
+ cleanups.push(ctx.on('formie:conditions:evaluated', () => {
209
+ void ensureMounted();
210
+ }));
211
+
209
212
  const destroy = async() => {
210
213
  debug.log('Destroying payment module.', {
211
- moduleId: adapter.id,
214
+ moduleId: adapter.moduleId,
212
215
  handle: options.handle,
213
216
  });
214
217
  cleanups.forEach((c) => c());
@@ -225,50 +228,48 @@ export function createManagedPaymentModule<
225
228
  provider: options.provider,
226
229
  });
227
230
  debug.log('Payment widget unmounted.', {
228
- moduleId: adapter.id,
231
+ moduleId: adapter.moduleId,
229
232
  handle: options.handle,
230
233
  });
231
234
  }
232
235
 
233
- if (registry[adapter.id]?.destroy === destroy) {
234
- delete registry[adapter.id];
236
+ if (registry[occurrenceKey]?.destroy === destroy) {
237
+ delete registry[occurrenceKey];
235
238
  }
236
239
  debug.log('Payment module destroy complete.', {
237
- moduleId: adapter.id,
240
+ moduleId: adapter.moduleId,
238
241
  handle: options.handle,
239
242
  });
240
243
  };
241
244
 
242
- registry[adapter.id] = { destroy };
245
+ registry[occurrenceKey] = { destroy };
243
246
 
244
247
  return {
245
248
  destroy,
246
- onBeforeStage: async(stageCtx) => {
247
- if (customSetupResult?.onBeforeStage) {
248
- await customSetupResult.onBeforeStage(stageCtx);
249
+ beforeSubmit: async(stageCtx) => {
250
+ if (customSetupResult?.beforeSubmit) {
251
+ await customSetupResult.beforeSubmit(stageCtx);
249
252
  return;
250
253
  }
251
254
 
252
- if (stageCtx.stage !== 'authorize' || stageCtx.action !== 'submit') {
255
+ if (stageCtx.action !== 'submit') {
253
256
  return;
254
257
  }
255
258
 
256
- // Multi-page forms can mount payment modules for fields on
257
- // hidden pages. Only enforce authorize checks for payment
258
- // fields on the active/visible page.
259
- const fieldElement = ctx.target as HTMLElement;
260
- const page = fieldElement.closest('[data-formie-page]') as HTMLElement | null;
261
- if (page?.hasAttribute('data-formie-page-hidden')) {
259
+ // Skip authorize when the field is hidden by page flow or
260
+ // conditional logic (e.g. Stripe vs bank-transfer choice).
261
+ // Server-side payment tasks already skip these fields.
262
+ if (!isPaymentFieldActive(ctx.target)) {
262
263
  return;
263
264
  }
264
265
 
265
266
  await ensureMounted();
266
267
  const api = await getApi();
267
268
 
268
- if (adapter.onBeforeAuthorize) {
269
+ if (adapter.onBeforePayment) {
269
270
  if (!authorizeInFlight) {
270
271
  authorizeInFlight = (async() => {
271
- return adapter.onBeforeAuthorize!({
272
+ return adapter.onBeforePayment!({
272
273
  api,
273
274
  widget,
274
275
  field: ctx.target,
@@ -283,8 +284,8 @@ export function createManagedPaymentModule<
283
284
  }
284
285
 
285
286
  const ok = await authorizeInFlight;
286
- debug.log('onBeforeAuthorize resolved.', {
287
- moduleId: adapter.id,
287
+ debug.log('onBeforePayment resolved.', {
288
+ moduleId: adapter.moduleId,
288
289
  handle: options.handle,
289
290
  ok,
290
291
  });
@@ -311,15 +312,15 @@ export function createManagedPaymentModule<
311
312
 
312
313
  if (!result.ok) {
313
314
  debug.warn('Required payment input(s) missing.', {
314
- moduleId: adapter.id,
315
+ moduleId: adapter.moduleId,
315
316
  handle: options.handle,
316
317
  missingSuffix: result.missingSuffix,
317
318
  });
318
319
  stageCtx.abort(options.transport.errorMessage);
319
320
  }
320
321
  },
321
- onAfterStage: async(stagePayload, result) => {
322
- if (stagePayload.stage !== 'dispatch' || !adapter.onAfterSubmit) {
322
+ afterSubmit: async(stagePayload, result) => {
323
+ if (!adapter.onAfterSubmit) {
323
324
  return;
324
325
  }
325
326
 
@@ -9,7 +9,7 @@ type GoCardlessProviderOptions = {
9
9
  const REDIRECT_EVENT = getPaymentProviderActionEventName('go-cardless', 'redirect');
10
10
 
11
11
  export const goCardlessModule = definePaymentModule<GoCardlessProviderOptions, null, null>({
12
- id: 'go-cardless',
12
+ moduleId: 'formie:go-cardless',
13
13
  defaultRequiredInputSuffixes: [],
14
14
  load: async() => null,
15
15
  setup: async({ services, root }) => {
@@ -1,6 +1,6 @@
1
- import type { FormieModuleDefinition } from '#contracts/modules';
1
+ import type { BrowserModuleDefinition } from '#contracts/modules';
2
2
 
3
- export const builtinPaymentModuleLoaders: Record<string, () => Promise<FormieModuleDefinition>> = {
3
+ export const builtinPaymentModuleLoaders: Record<string, () => Promise<BrowserModuleDefinition>> = {
4
4
  // Keep payment providers lazy and separately addressable so forms only ship
5
5
  // the payment SDK wrapper code they actually declare in their manifest.
6
6
  'bpoint': () => import('#modules/payments/bpoint').then((module) => module.bpointModule),
@@ -10,7 +10,7 @@ type MollieProviderOptions = {
10
10
  const REDIRECT_EVENT = getPaymentProviderActionEventName('mollie', 'redirect');
11
11
 
12
12
  export const mollieModule = definePaymentModule<MollieProviderOptions, null, null>({
13
- id: 'mollie',
13
+ moduleId: 'formie:mollie',
14
14
  defaultRequiredInputSuffixes: [],
15
15
  load: async() => null,
16
16
  setup: async({ services, root }) => {
@@ -96,10 +96,10 @@ const extractMonerisToken = (payload: unknown): MonerisTokenResult => {
96
96
  };
97
97
 
98
98
  export const monerisModule = definePaymentModule<MonerisProviderOptions, null, null>({
99
- id: 'moneris',
99
+ moduleId: 'formie:moneris',
100
100
  defaultRequiredInputSuffixes: ['monerisTokenId'],
101
101
  load: async() => null,
102
- onBeforeAuthorize: async(args) => {
102
+ onBeforePayment: async(args) => {
103
103
  const { field, services, options } = args;
104
104
  const fieldState = field as MonerisFieldState;
105
105
  const provider = options.provider as MonerisProviderOptions;
@@ -1,8 +1,12 @@
1
+ import { getFormBrowserRequestOptions } from '#utils/request-profile';
2
+ import { browserRequest, type BrowserRequestOptions } from '@verbb/formie-core';
1
3
  import opayoCss from '#theme-css/integrations/_opayo.css?inline';
2
4
 
3
5
  import { definePaymentModule } from '#modules/payments/api';
4
6
  import { ensureModuleStyles } from '#modules/styles';
7
+ import { toggleThemeClasses } from '#theme/theme-classes';
5
8
  import { createDebug } from '#utils/debug';
9
+ import { appendFormCsrfToFormData } from '#utils/csrf';
6
10
  import { getPaymentProviderActionEventName } from '#utils/event-names';
7
11
  import { loadScriptAndEnsureGlobal } from '#utils/scripts';
8
12
 
@@ -50,6 +54,7 @@ type OpayoProviderOptions = {
50
54
  useSandbox?: boolean;
51
55
  handle?: string;
52
56
  sessionToken?: string | null;
57
+ sessionEndpoint?: string;
53
58
  checkoutMode?: OpayoCheckoutMode;
54
59
  };
55
60
 
@@ -76,22 +81,23 @@ async function requestMerchantSessionKey(args: {
76
81
  form: HTMLFormElement;
77
82
  handle: string;
78
83
  sessionToken: string;
84
+ sessionEndpoint?: string;
79
85
  services: {
80
86
  addError: (message: string) => void;
81
87
  };
82
88
  }): Promise<string | null> {
83
89
  const { form, handle, sessionToken, services } = args;
84
90
  const formData = new FormData();
85
- formData.append('action', 'formie/payment-webhooks/process-callback');
86
- formData.append('merchantSessionKey', 'true');
91
+ appendFormCsrfToFormData(formData, form);
92
+ formData.set('action', 'formie/payment-sessions/initialize');
87
93
  formData.append('handle', handle);
88
94
  formData.append('sessionToken', sessionToken);
89
95
 
90
96
  try {
91
- const res = await fetch(form.action, {
97
+ const res = await browserRequest(args.sessionEndpoint || form.action, {
92
98
  method: 'POST',
93
99
  body: formData,
94
- });
100
+ }, getFormBrowserRequestOptions(form));
95
101
 
96
102
  if (res.status < 200 || res.status >= 300) {
97
103
  services.addError(`${res.status}: ${res.statusText}`);
@@ -108,7 +114,7 @@ async function requestMerchantSessionKey(args: {
108
114
 
109
115
  if (!merchantSessionKey) {
110
116
  services.addError('Unable to get merchant session.');
111
- debug.warn('merchantSessionKey missing in callback response.');
117
+ debug.warn('merchantSessionKey missing in session response.');
112
118
 
113
119
  return null;
114
120
  }
@@ -131,7 +137,7 @@ function ensureDropInContainerId(container: HTMLElement): string {
131
137
  }
132
138
 
133
139
  export const opayoModule = definePaymentModule<OpayoProviderOptions, null, OpayoDropInWidget | null>({
134
- id: 'opayo',
140
+ moduleId: 'formie:opayo',
135
141
  defaultRequiredInputSuffixes: ['opayoTokenId'],
136
142
  load: async(ctx) => {
137
143
  const { provider } = ctx.options;
@@ -182,6 +188,7 @@ export const opayoModule = definePaymentModule<OpayoProviderOptions, null, Opayo
182
188
  form,
183
189
  handle,
184
190
  sessionToken: provider.sessionToken || '',
191
+ sessionEndpoint: provider.sessionEndpoint,
185
192
  services,
186
193
  });
187
194
 
@@ -226,6 +233,7 @@ export const opayoModule = definePaymentModule<OpayoProviderOptions, null, Opayo
226
233
  form,
227
234
  handle,
228
235
  sessionToken: provider.sessionToken || '',
236
+ sessionEndpoint: provider.sessionEndpoint,
229
237
  services,
230
238
  }).then((newMerchantSessionKey) => {
231
239
  if (!newMerchantSessionKey) {
@@ -257,7 +265,7 @@ export const opayoModule = definePaymentModule<OpayoProviderOptions, null, Opayo
257
265
  unmount: async({ widget }) => {
258
266
  widget?.checkout?.destroy?.();
259
267
  },
260
- onBeforeAuthorize: async(args) => {
268
+ onBeforePayment: async(args) => {
261
269
  const { field, services, options, provider, widget } = args;
262
270
  const handle = (provider.handle || 'opayo') as string;
263
271
  const form = services.form;
@@ -306,6 +314,7 @@ export const opayoModule = definePaymentModule<OpayoProviderOptions, null, Opayo
306
314
  form,
307
315
  handle,
308
316
  sessionToken: provider.sessionToken || '',
317
+ sessionEndpoint: provider.sessionEndpoint,
309
318
  services,
310
319
  });
311
320
 
@@ -381,10 +390,14 @@ export const opayoModule = definePaymentModule<OpayoProviderOptions, null, Opayo
381
390
  dialog.innerHTML = `
382
391
  <div class="formie-modal-backdrop" data-dialog-close></div>
383
392
  <div class="formie-modal-content">
384
- <div class="formie-loading formie-loading-large" style="--formie-loading-width: 3rem; --formie-loading-height: 3rem; top: 50%; margin-top: -1.5rem;"></div>
393
+ <div data-formie-opayo-loading style="--formie-loading-width: 3rem; --formie-loading-height: 3rem; top: 50%; margin-top: -1.5rem;"></div>
385
394
  <iframe width="100%" height="100%" style="width: 100%; height: 100%; position: relative; z-index: 1;"></iframe>
386
395
  </div>
387
396
  `;
397
+ const loading = dialog.querySelector<HTMLElement>('[data-formie-opayo-loading]');
398
+ if (loading) {
399
+ toggleThemeClasses(loading, form, 'loading', true);
400
+ }
388
401
  const iframe = dialog.querySelector('iframe');
389
402
  const esc = (s: string) => s.replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/</g, '&lt;');
390
403
  const callbackUrl = data.returnUrl || data.redirectUrl || '';
@@ -10,11 +10,15 @@ type PaddleGlobal = {
10
10
  eventCallback?: (e: { name: string; data?: unknown }) => void;
11
11
  }) => void;
12
12
  Checkout: {
13
- open: (data: { items?: unknown[] }) => void;
13
+ open: (data: PaddleCheckout) => void;
14
14
  close: () => void;
15
15
  };
16
16
  };
17
17
 
18
+ type PaddleCheckout = {
19
+ transactionId?: string;
20
+ };
21
+
18
22
  type PaddleProviderOptions = {
19
23
  clientSideToken?: string;
20
24
  environment?: string;
@@ -25,7 +29,7 @@ const SCRIPT_ID = 'FORMIE_PADDLE_SCRIPT';
25
29
  const CHECKOUT_EVENT = getPaymentProviderActionEventName('paddle', 'initialize');
26
30
 
27
31
  export const paddleModule = definePaymentModule<PaddleProviderOptions, null, null>({
28
- id: 'paddle',
32
+ moduleId: 'formie:paddle',
29
33
  defaultRequiredInputSuffixes: ['paddleCheckoutData'],
30
34
  load: async() => null,
31
35
  setup: async(ctx) => {
@@ -74,9 +78,9 @@ export const paddleModule = definePaymentModule<PaddleProviderOptions, null, nul
74
78
  },
75
79
  });
76
80
 
77
- const openCheckout = (data?: { items?: unknown[] }) => {
78
- if (!data?.items) {
79
- services.addError('Missing Paddle checkout items.');
81
+ const openCheckout = (data?: PaddleCheckout) => {
82
+ if (!data?.transactionId) {
83
+ services.addError('Missing Paddle checkout transaction.');
80
84
 
81
85
  return false;
82
86
  }
@@ -94,7 +98,7 @@ export const paddleModule = definePaymentModule<PaddleProviderOptions, null, nul
94
98
  return true;
95
99
  };
96
100
 
97
- const unbindCheckout = services.events.onForm(CHECKOUT_EVENT, ((event: CustomEvent<{ data?: { items?: unknown[] } }>) => {
101
+ const unbindCheckout = services.events.onForm(CHECKOUT_EVENT, ((event: CustomEvent<{ data?: PaddleCheckout }>) => {
98
102
  openCheckout(event.detail?.data);
99
103
  }) as EventListener);
100
104
 
@@ -1,4 +1,5 @@
1
- import type { FormieModuleDefinition } from '#contracts/modules';
1
+ import type { BrowserModuleDefinition } from '#contracts/modules';
2
+ import { isPaymentFieldActive } from '#modules/payments/utils';
2
3
 
3
4
  type PaymentProviderConfig = {
4
5
  handle: string;
@@ -93,8 +94,10 @@ async function waitForRequiredInputs(root: Element, requiredInputSuffixes: strin
93
94
  return hasAllRequiredInputs(root, requiredInputSuffixes);
94
95
  }
95
96
 
96
- export const paymentModule: FormieModuleDefinition = {
97
- id: 'payment',
97
+ export const paymentModule: BrowserModuleDefinition = {
98
+ moduleId: 'formie:payment',
99
+ version: 2,
100
+ surfaces: ['server-rendered', 'client-rendered', 'cp-edit'],
98
101
  kind: 'payment',
99
102
  match: () => true,
100
103
  setup: async(ctx) => {
@@ -110,25 +113,30 @@ export const paymentModule: FormieModuleDefinition = {
110
113
  destroy: () => {
111
114
  void ctx.emit('formie:module:payment:destroy', {});
112
115
  },
113
- onBeforeStage: async(stageCtx) => {
114
- if (stageCtx.stage !== 'authorize') {
116
+ beforeSubmit: async(stageCtx) => {
117
+ if (stageCtx.action !== 'submit') {
115
118
  return;
116
119
  }
117
120
 
118
- if (stageCtx.action !== 'submit') {
121
+ if (!hasPaymentField) {
119
122
  return;
120
123
  }
121
124
 
122
- if (!hasPaymentField) {
125
+ // Same rule as managed payment modules: do not require tokens
126
+ // when every payment field is hidden by conditions or page flow.
127
+ const paymentFields = Array.from(
128
+ targetRoot.querySelectorAll('[data-formie-field-type="payment"]'),
129
+ );
130
+ if (paymentFields.length > 0 && paymentFields.every((field) => !isPaymentFieldActive(field))) {
123
131
  return;
124
132
  }
125
133
 
126
- await ctx.emit('formie:payment:authorize:before', {
134
+ await ctx.emit('formie:payment:payment:before', {
127
135
  action: stageCtx.action,
128
136
  });
129
137
 
130
138
  for (const provider of providers) {
131
- await ctx.emit('formie:payment:provider:authorize:before', {
139
+ await ctx.emit('formie:payment:provider:payment:before', {
132
140
  provider,
133
141
  action: stageCtx.action,
134
142
  });
@@ -145,14 +153,14 @@ export const paymentModule: FormieModuleDefinition = {
145
153
  const message = provider.errorMessage || 'Payment authorization is incomplete.';
146
154
  stageCtx.abort(message);
147
155
 
148
- await ctx.emit('formie:payment:provider:authorize:error', {
156
+ await ctx.emit('formie:payment:provider:payment:error', {
149
157
  reason: 'missing-payment-token',
150
158
  provider,
151
159
  action: stageCtx.action,
152
160
  missingSuffix: result.missingSuffix,
153
161
  });
154
162
 
155
- await ctx.emit('formie:payment:authorize:error', {
163
+ await ctx.emit('formie:payment:payment:error', {
156
164
  reason: 'missing-payment-token',
157
165
  providerHandle: provider.handle,
158
166
  missingSuffix: result.missingSuffix,
@@ -162,18 +170,14 @@ export const paymentModule: FormieModuleDefinition = {
162
170
  return;
163
171
  }
164
172
 
165
- await ctx.emit('formie:payment:provider:authorize:after', {
173
+ await ctx.emit('formie:payment:provider:payment:after', {
166
174
  provider,
167
175
  action: stageCtx.action,
168
176
  });
169
177
  }
170
178
  },
171
- onAfterStage: async(stageCtx, result) => {
172
- if (stageCtx.stage !== 'authorize') {
173
- return;
174
- }
175
-
176
- await ctx.emit('formie:payment:authorize:after', {
179
+ afterSubmit: async(stageCtx, result) => {
180
+ await ctx.emit('formie:payment:payment:after', {
177
181
  action: stageCtx.action,
178
182
  result,
179
183
  });
@@ -84,7 +84,7 @@ function getScriptUrl(clientId: string, currency: string): string {
84
84
  }
85
85
 
86
86
  export const paypalModule = definePaymentModule<PayPalProviderOptions, PayPalGlobal | null, PayPalButtonsInstance | null>({
87
- id: 'paypal',
87
+ moduleId: 'formie:paypal',
88
88
  defaultRequiredInputSuffixes: ['paypalOrderId', 'paypalAuthId'],
89
89
  load: async (ctx) => {
90
90
  const { provider } = ctx.options;
@@ -25,7 +25,7 @@ type PayWayProviderOptions = {
25
25
  const SCRIPT_ID = 'FORMIE_PAYWAY_SCRIPT';
26
26
 
27
27
  export const paywayModule = definePaymentModule<PayWayProviderOptions, null, PayWayFrame | null>({
28
- id: 'payway',
28
+ moduleId: 'formie:payway',
29
29
  defaultRequiredInputSuffixes: ['paywayTokenId'],
30
30
  load: async (ctx) => {
31
31
  const { provider } = ctx.options;
@@ -79,7 +79,7 @@ export const paywayModule = definePaymentModule<PayWayProviderOptions, null, Pay
79
79
  unmount: async (args) => {
80
80
  args.widget?.destroy();
81
81
  },
82
- onBeforeAuthorize: async (args) => {
82
+ onBeforePayment: async (args) => {
83
83
  const { widget, services } = args;
84
84
 
85
85
  if (!widget) {
@@ -23,7 +23,7 @@ type SquareProviderOptions = {
23
23
  const SCRIPT_ID = 'FORMIE_SQUARE_SCRIPT';
24
24
 
25
25
  export const squareModule = definePaymentModule<SquareProviderOptions, SquareGlobal | null, SquareCard | null>({
26
- id: 'square',
26
+ moduleId: 'formie:square',
27
27
  defaultRequiredInputSuffixes: ['squarePaymentId'],
28
28
  load: async(ctx) => {
29
29
  const { provider } = ctx.options;
@@ -73,7 +73,7 @@ export const squareModule = definePaymentModule<SquareProviderOptions, SquareGlo
73
73
  unmount: async() => {
74
74
  // Square card doesn't expose destroy, detach handled by removing element
75
75
  },
76
- onBeforeAuthorize: async(args) => {
76
+ onBeforePayment: async(args) => {
77
77
  const { widget, services } = args;
78
78
 
79
79
  if (!widget) {