@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.
- package/CHANGELOG.md +57 -0
- package/dist/chunks/{address-country-Rx6GQTND.js → address-country-Dn71jroa.js} +10 -4
- package/dist/chunks/{address-finder-k7_BXaRe.js → address-finder-O49uDRoR.js} +2 -2
- package/dist/chunks/{address-state-BwE01m2_.js → address-state-ByYatUur.js} +154 -143
- package/dist/chunks/{api-DqpfkZWL.js → api-D6kJ7kXZ.js} +183 -179
- package/dist/chunks/{api-BUb6P-xu.js → api-DYYsVIub.js} +77 -47
- package/dist/chunks/{api-sPqGbOww.js → api-ghNr2uxX.js} +15 -9
- package/dist/chunks/{bpoint-Dlq34XH1.js → bpoint-D0RKFM4F.js} +3 -3
- package/dist/chunks/calculations-YEoVCG2q.js +310 -0
- package/dist/chunks/{captcha-eu-CGm8Lbrj.js → captcha-eu-DERJbXnH.js} +5 -4
- package/dist/chunks/{checkbox-radio-BY2aTCOG.js → checkbox-radio-gsm8QPJg.js} +74 -75
- package/dist/chunks/{combobox-C0EuExSI.js → combobox-CWNdx4Fk.js} +290 -279
- package/dist/chunks/conditions-DqNHLTbN.js +464 -0
- package/dist/chunks/country-from-ip-DDj_mFki.js +29 -0
- package/dist/chunks/csrf-DxHg_ZYt.js +61 -0
- package/dist/chunks/{custom-google-maps-BsaSirEZ.js → custom-google-maps-C4l2S3GO.js} +9 -3
- package/dist/chunks/{custom-link-CJ1-FjEM.js → custom-link-CLazgKYH.js} +8 -2
- package/dist/chunks/{custom-maps-DYW_pBid.js → custom-maps-DqcAlD0v.js} +10 -4
- package/dist/chunks/{date-picker-5CA_-zGb.js → date-picker-RUnevF7l.js} +456 -430
- package/dist/chunks/{dist-BdUy8m_p.js → dist-ZLeW0zZ3.js} +1280 -452
- package/dist/chunks/{eway-D9_m8ooj.js → eway-or6dtjoT.js} +3 -3
- package/dist/chunks/field-references.resolver-Ca8MguFv.js +104 -0
- package/dist/chunks/{file-upload-rqfZNqlH.js → file-upload-Bm-TXyNB.js} +104 -96
- package/dist/chunks/friendly-captcha-v1-GFqCt1Mh.js +34 -0
- package/dist/chunks/{friendly-captcha-v2-CLSAbkqx.js → friendly-captcha-v2-WoW246JG.js} +6 -5
- package/dist/chunks/{friendly-challenge-8uPatWqk.js → friendly-challenge-DPG9MJb1.js} +111 -102
- package/dist/chunks/{go-cardless-DAT3ZaQf.js → go-cardless-DzJ-0FKg.js} +2 -2
- package/dist/chunks/google-address-C1P1nTDM.js +163 -0
- package/dist/chunks/{hcaptcha-CGLAmgjO.js → hcaptcha-D0T8aIHz.js} +3 -3
- package/dist/chunks/{hidden-D7_Ch-QN.js → hidden-BZhXnNPe.js} +8 -2
- package/dist/chunks/http-C2QdHuWO.js +27 -0
- package/dist/chunks/{leaflet-src-j-lHNmhR.js → leaflet-src-DE6rv6M-.js} +42 -46
- package/dist/chunks/{loqate-CJPzBmSm.js → loqate-DD1S7PY9.js} +2 -2
- package/dist/chunks/{mollie-Bibhl67p.js → mollie-DG8Ju83x.js} +2 -2
- package/dist/chunks/{moneris-H2wSqk9h.js → moneris-C8m3Fvqu.js} +3 -3
- package/dist/chunks/opayo-B3EvrVxw.js +188 -0
- package/dist/chunks/{paddle-DkvIxQdG.js → paddle-BIYR9Um3.js} +3 -3
- package/dist/chunks/{password-validation-T0vDQPCr.js → password-validation-C8_uO_c_.js} +18 -12
- package/dist/chunks/{paypal-CQpAF7Ua.js → paypal-B_yxIo2d.js} +7 -5
- package/dist/chunks/{payway-CwDkC7YZ.js → payway-CeOzS0sL.js} +3 -3
- package/dist/chunks/{phone-country-D3ayr60L.js → phone-country-bAqje17P.js} +80 -63
- package/dist/chunks/{place-kit-BGHklIZ-.js → place-kit-BE5gi3vo.js} +3 -3
- package/dist/chunks/{placekit-autocomplete.esm-DWVabQlq.js → placekit-autocomplete.esm-CZZERYur.js} +11 -15
- package/dist/chunks/{recaptcha-enterprise-XPId5-bS.js → recaptcha-enterprise-CruXddZq.js} +4 -4
- package/dist/chunks/{recaptcha-shared-CLYJvojk.js → recaptcha-shared-AQRMDMme.js} +1 -1
- package/dist/chunks/{recaptcha-v2-checkbox-Cy-0PEPc.js → recaptcha-v2-checkbox-CCnJYCnG.js} +4 -4
- package/dist/chunks/{recaptcha-v2-invisible-BwRH540O.js → recaptcha-v2-invisible-BuVqRRYn.js} +4 -4
- package/dist/chunks/{recaptcha-v3-No4Ykrhk.js → recaptcha-v3-CloqhO2A.js} +4 -4
- package/dist/chunks/{repeater-BVnPUqTj.js → repeater-DwE27jI1.js} +25 -19
- package/dist/chunks/request-profile-DhwkeCpS.js +10 -0
- package/dist/chunks/rich-text-uV4o_pGk.js +361 -0
- package/dist/chunks/{chunk-3b4jIN3o.js → rolldown-runtime-DtPi1Y-2.js} +2 -2
- package/dist/chunks/{sdk-BhHAYgga.js → sdk-lkwSvlpM.js} +282 -234
- package/dist/chunks/{shared-Bx9s0i0P.js → shared-OKhSay59.js} +27 -21
- package/dist/chunks/{signature-xz4QO7CR.js → signature-7cldFbqj.js} +160 -112
- package/dist/chunks/{snaptcha-DKx98oon.js → snaptcha-C04kNGYQ.js} +2 -2
- package/dist/chunks/{square-DwdcOI1G.js → square-DEzxv9D9.js} +8 -6
- package/dist/chunks/{stripe-DaoG2FT1.js → stripe-CVPQGDz3.js} +10 -11
- package/dist/chunks/{summary-Dks0gXS3.js → summary-BF_8mrXI.js} +47 -45
- package/dist/chunks/{survey-likert-DkE6bR7B.js → survey-likert-fk1hUPff.js} +7 -1
- package/dist/chunks/{survey-rank-DN6x4IZM.js → survey-rank-BsLGl2LX.js} +37 -25
- package/dist/chunks/{survey-rating-BnsNL9U5.js → survey-rating-DVS6e6fM.js} +17 -5
- package/dist/chunks/{table-CAjCJHrL.js → table-DnIBdeKF.js} +21 -15
- package/dist/chunks/{text-limit-Bn18WrPU.js → text-limit-LGMPhFuC.js} +40 -34
- package/dist/chunks/{theme-classes-Tv7q7ToE.js → theme-classes-DAQuEqdP.js} +1 -1
- package/dist/chunks/{turnstile-DJakPzQD.js → turnstile-n9DNyPxi.js} +3 -3
- package/dist/chunks/{upload-manager-W-QDgxKD.js → upload-manager-BbiUosZq.js} +410 -350
- package/dist/chunks/{utils-Vqp8i_RM.js → utils-DpUBPadZ.js} +20 -14
- package/dist/css/formie-base.css +104 -1
- package/dist/css/theme/_messages.css +2 -0
- package/dist/css/theme/_tokens.css +31 -25
- package/dist/css/theme/fields/_signature.css +2 -1
- package/dist/css/theme/forms/_form.css +5 -1
- package/dist/index.d.ts +5 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1778 -1425
- package/dist/js/contracts/client.d.ts +5 -3
- package/dist/js/contracts/client.d.ts.map +1 -1
- package/dist/js/contracts/common.d.ts +2 -2
- package/dist/js/contracts/common.d.ts.map +1 -1
- package/dist/js/contracts/modules.d.ts +37 -12
- package/dist/js/contracts/modules.d.ts.map +1 -1
- package/dist/js/contracts/schema.d.ts +20 -38
- package/dist/js/contracts/schema.d.ts.map +1 -1
- package/dist/js/contracts/theme.d.ts +4 -1
- package/dist/js/contracts/theme.d.ts.map +1 -1
- package/dist/js/core/client-rendered-modules.d.ts +17 -0
- package/dist/js/core/client-rendered-modules.d.ts.map +1 -0
- package/dist/js/core/create-formie-client.d.ts.map +1 -1
- package/dist/js/core/field-error-aria.d.ts +23 -0
- package/dist/js/core/field-error-aria.d.ts.map +1 -0
- package/dist/js/core/hydrate-modules.d.ts +10 -8
- package/dist/js/core/hydrate-modules.d.ts.map +1 -1
- package/dist/js/core/submit-result-state.d.ts.map +1 -1
- package/dist/js/core/submit-result-ui.d.ts.map +1 -1
- package/dist/js/core/validation-focus.d.ts.map +1 -1
- package/dist/js/modules/address/address-finder.d.ts +1 -1
- package/dist/js/modules/address/address-finder.d.ts.map +1 -1
- package/dist/js/modules/address/factories.d.ts +3 -3
- package/dist/js/modules/address/factories.d.ts.map +1 -1
- package/dist/js/modules/address/google-address.d.ts +2 -1
- package/dist/js/modules/address/google-address.d.ts.map +1 -1
- package/dist/js/modules/address/index.d.ts +2 -2
- package/dist/js/modules/address/index.d.ts.map +1 -1
- package/dist/js/modules/address/loqate.d.ts +1 -1
- package/dist/js/modules/address/loqate.d.ts.map +1 -1
- package/dist/js/modules/address/place-kit.d.ts +1 -1
- package/dist/js/modules/address/place-kit.d.ts.map +1 -1
- package/dist/js/modules/captchas/captcha-eu.d.ts +1 -1
- package/dist/js/modules/captchas/captcha-eu.d.ts.map +1 -1
- package/dist/js/modules/captchas/factories.d.ts +11 -11
- package/dist/js/modules/captchas/factories.d.ts.map +1 -1
- package/dist/js/modules/captchas/friendly-captcha-v1.d.ts +1 -1
- package/dist/js/modules/captchas/friendly-captcha-v1.d.ts.map +1 -1
- package/dist/js/modules/captchas/friendly-captcha-v2.d.ts +1 -1
- package/dist/js/modules/captchas/friendly-captcha-v2.d.ts.map +1 -1
- package/dist/js/modules/captchas/hcaptcha.d.ts +1 -1
- package/dist/js/modules/captchas/hcaptcha.d.ts.map +1 -1
- package/dist/js/modules/captchas/index.d.ts +2 -2
- package/dist/js/modules/captchas/index.d.ts.map +1 -1
- package/dist/js/modules/captchas/recaptcha-enterprise.d.ts +1 -1
- package/dist/js/modules/captchas/recaptcha-enterprise.d.ts.map +1 -1
- package/dist/js/modules/captchas/recaptcha-v2-checkbox.d.ts +1 -1
- package/dist/js/modules/captchas/recaptcha-v2-checkbox.d.ts.map +1 -1
- package/dist/js/modules/captchas/recaptcha-v2-invisible.d.ts +1 -1
- package/dist/js/modules/captchas/recaptcha-v2-invisible.d.ts.map +1 -1
- package/dist/js/modules/captchas/recaptcha-v3.d.ts +1 -1
- package/dist/js/modules/captchas/recaptcha-v3.d.ts.map +1 -1
- package/dist/js/modules/captchas/snaptcha.d.ts +1 -1
- package/dist/js/modules/captchas/snaptcha.d.ts.map +1 -1
- package/dist/js/modules/captchas/turnstile.d.ts +1 -1
- package/dist/js/modules/captchas/turnstile.d.ts.map +1 -1
- package/dist/js/modules/fields/address-country.d.ts +2 -2
- package/dist/js/modules/fields/address-country.d.ts.map +1 -1
- package/dist/js/modules/fields/address-state.d.ts +2 -2
- package/dist/js/modules/fields/address-state.d.ts.map +1 -1
- package/dist/js/modules/fields/calculations.d.ts +2 -2
- package/dist/js/modules/fields/calculations.d.ts.map +1 -1
- package/dist/js/modules/fields/checkbox-radio.d.ts +2 -2
- package/dist/js/modules/fields/checkbox-radio.d.ts.map +1 -1
- package/dist/js/modules/fields/combobox.d.ts +2 -2
- package/dist/js/modules/fields/combobox.d.ts.map +1 -1
- package/dist/js/modules/fields/conditions/config.d.ts.map +1 -1
- package/dist/js/modules/fields/conditions/effects.d.ts +1 -0
- package/dist/js/modules/fields/conditions/effects.d.ts.map +1 -1
- package/dist/js/modules/fields/conditions/evaluator.d.ts +4 -1
- package/dist/js/modules/fields/conditions/evaluator.d.ts.map +1 -1
- package/dist/js/modules/fields/conditions/references.d.ts.map +1 -1
- package/dist/js/modules/fields/conditions/submission-context.d.ts +15 -0
- package/dist/js/modules/fields/conditions/submission-context.d.ts.map +1 -0
- package/dist/js/modules/fields/conditions/types.d.ts +3 -1
- package/dist/js/modules/fields/conditions/types.d.ts.map +1 -1
- package/dist/js/modules/fields/conditions/values.d.ts +1 -1
- package/dist/js/modules/fields/conditions/values.d.ts.map +1 -1
- package/dist/js/modules/fields/conditions.d.ts +2 -2
- package/dist/js/modules/fields/conditions.d.ts.map +1 -1
- package/dist/js/modules/fields/custom-google-maps.d.ts +2 -2
- package/dist/js/modules/fields/custom-google-maps.d.ts.map +1 -1
- package/dist/js/modules/fields/custom-link.d.ts +2 -2
- package/dist/js/modules/fields/custom-link.d.ts.map +1 -1
- package/dist/js/modules/fields/custom-maps.d.ts +2 -2
- package/dist/js/modules/fields/custom-maps.d.ts.map +1 -1
- package/dist/js/modules/fields/date-picker.d.ts +2 -2
- package/dist/js/modules/fields/date-picker.d.ts.map +1 -1
- package/dist/js/modules/fields/file-upload.d.ts +2 -2
- package/dist/js/modules/fields/file-upload.d.ts.map +1 -1
- package/dist/js/modules/fields/hidden.d.ts +2 -2
- package/dist/js/modules/fields/hidden.d.ts.map +1 -1
- package/dist/js/modules/fields/index.d.ts +2 -2
- package/dist/js/modules/fields/index.d.ts.map +1 -1
- package/dist/js/modules/fields/password-validation.d.ts +2 -2
- package/dist/js/modules/fields/password-validation.d.ts.map +1 -1
- package/dist/js/modules/fields/phone-country.d.ts +2 -2
- package/dist/js/modules/fields/phone-country.d.ts.map +1 -1
- package/dist/js/modules/fields/repeater.d.ts +2 -2
- package/dist/js/modules/fields/repeater.d.ts.map +1 -1
- package/dist/js/modules/fields/rich-text.d.ts +2 -2
- package/dist/js/modules/fields/rich-text.d.ts.map +1 -1
- package/dist/js/modules/fields/shared.d.ts +1 -0
- package/dist/js/modules/fields/shared.d.ts.map +1 -1
- package/dist/js/modules/fields/signature.d.ts +2 -2
- package/dist/js/modules/fields/signature.d.ts.map +1 -1
- package/dist/js/modules/fields/summary.d.ts +2 -2
- package/dist/js/modules/fields/summary.d.ts.map +1 -1
- package/dist/js/modules/fields/survey-likert.d.ts +2 -2
- package/dist/js/modules/fields/survey-likert.d.ts.map +1 -1
- package/dist/js/modules/fields/survey-rank.d.ts +2 -2
- package/dist/js/modules/fields/survey-rank.d.ts.map +1 -1
- package/dist/js/modules/fields/survey-rating.d.ts +2 -2
- package/dist/js/modules/fields/survey-rating.d.ts.map +1 -1
- package/dist/js/modules/fields/table.d.ts +2 -2
- package/dist/js/modules/fields/table.d.ts.map +1 -1
- package/dist/js/modules/fields/text-limit.d.ts +2 -2
- package/dist/js/modules/fields/text-limit.d.ts.map +1 -1
- package/dist/js/modules/fields/upload-manager.d.ts +2 -2
- package/dist/js/modules/fields/upload-manager.d.ts.map +1 -1
- package/dist/js/modules/loader.d.ts +10 -4
- package/dist/js/modules/loader.d.ts.map +1 -1
- package/dist/js/modules/payments/bpoint.d.ts +1 -1
- package/dist/js/modules/payments/bpoint.d.ts.map +1 -1
- package/dist/js/modules/payments/eway.d.ts +1 -1
- package/dist/js/modules/payments/eway.d.ts.map +1 -1
- package/dist/js/modules/payments/factories.d.ts +7 -7
- package/dist/js/modules/payments/factories.d.ts.map +1 -1
- package/dist/js/modules/payments/go-cardless.d.ts +1 -1
- package/dist/js/modules/payments/go-cardless.d.ts.map +1 -1
- package/dist/js/modules/payments/index.d.ts +2 -2
- package/dist/js/modules/payments/index.d.ts.map +1 -1
- package/dist/js/modules/payments/mollie.d.ts +1 -1
- package/dist/js/modules/payments/mollie.d.ts.map +1 -1
- package/dist/js/modules/payments/moneris.d.ts +1 -1
- package/dist/js/modules/payments/moneris.d.ts.map +1 -1
- package/dist/js/modules/payments/opayo.d.ts +1 -1
- package/dist/js/modules/payments/opayo.d.ts.map +1 -1
- package/dist/js/modules/payments/paddle.d.ts +1 -1
- package/dist/js/modules/payments/paddle.d.ts.map +1 -1
- package/dist/js/modules/payments/paypal.d.ts +1 -1
- package/dist/js/modules/payments/paypal.d.ts.map +1 -1
- package/dist/js/modules/payments/payway.d.ts +1 -1
- package/dist/js/modules/payments/payway.d.ts.map +1 -1
- package/dist/js/modules/payments/square.d.ts +1 -1
- package/dist/js/modules/payments/square.d.ts.map +1 -1
- package/dist/js/modules/payments/stripe.d.ts +1 -1
- package/dist/js/modules/payments/stripe.d.ts.map +1 -1
- package/dist/js/modules/payments/utils.d.ts +6 -0
- package/dist/js/modules/payments/utils.d.ts.map +1 -1
- package/dist/js/modules/registry.d.ts +6 -4
- package/dist/js/modules/registry.d.ts.map +1 -1
- package/dist/js/submit/pipeline.d.ts.map +1 -1
- package/dist/js/theme/browser-theme-state.generated.d.ts +24 -0
- package/dist/js/theme/browser-theme-state.generated.d.ts.map +1 -0
- package/dist/js/theme/theme-classes.d.ts +3 -3
- package/dist/js/theme/theme-classes.d.ts.map +1 -1
- package/dist/js/transport/forms-api.d.ts +5 -3
- package/dist/js/transport/forms-api.d.ts.map +1 -1
- package/dist/js/utils/country-from-ip.d.ts +2 -2
- package/dist/js/utils/country-from-ip.d.ts.map +1 -1
- package/dist/js/utils/csrf.d.ts +17 -0
- package/dist/js/utils/csrf.d.ts.map +1 -0
- package/dist/js/utils/field-references.parser.d.ts +1 -0
- package/dist/js/utils/field-references.parser.d.ts.map +1 -1
- package/dist/js/utils/field-references.resolver.d.ts.map +1 -1
- package/dist/js/utils/field-references.types.d.ts +1 -0
- package/dist/js/utils/field-references.types.d.ts.map +1 -1
- package/dist/js/utils/http.d.ts +3 -1
- package/dist/js/utils/http.d.ts.map +1 -1
- package/dist/js/utils/request-profile.d.ts +4 -0
- package/dist/js/utils/request-profile.d.ts.map +1 -0
- package/dist/js/utils/unload-warning.d.ts.map +1 -1
- package/dist/js/validation/rules/email.d.ts.map +1 -1
- package/dist/js/validation/rules/match.d.ts.map +1 -1
- package/dist/js/validation/rules/number.d.ts.map +1 -1
- package/dist/js/validation/rules/required.d.ts.map +1 -1
- package/dist/js/validation/rules/shared.d.ts.map +1 -1
- package/dist/js/validation/rules/url.d.ts.map +1 -1
- package/dist/js/validation/skip.d.ts +7 -0
- package/dist/js/validation/skip.d.ts.map +1 -0
- package/dist/js/validation/submit-readiness.d.ts.map +1 -1
- package/dist/js/validation/validator.d.ts.map +1 -1
- package/package.json +43 -12
- package/src/css/formie-base.css +104 -1
- package/src/css/theme/_messages.css +2 -0
- package/src/css/theme/_tokens.css +31 -25
- package/src/css/theme/fields/_signature.css +2 -1
- package/src/css/theme/forms/_form.css +5 -1
- package/src/index.ts +13 -8
- package/src/js/contracts/client.ts +5 -3
- package/src/js/contracts/common.ts +5 -6
- package/src/js/contracts/modules.ts +41 -12
- package/src/js/contracts/schema.ts +21 -43
- package/src/js/contracts/theme.ts +6 -1
- package/src/js/core/client-rendered-modules.ts +69 -0
- package/src/js/core/create-formie-client.ts +119 -73
- package/src/js/core/field-error-aria.ts +93 -0
- package/src/js/core/hydrate-modules.ts +54 -29
- package/src/js/core/submit-result-state.ts +34 -45
- package/src/js/core/submit-result-ui.ts +21 -65
- package/src/js/core/validation-focus.ts +20 -20
- package/src/js/modules/address/address-finder.ts +1 -1
- package/src/js/modules/address/factories.ts +15 -13
- package/src/js/modules/address/google-address.ts +10 -6
- package/src/js/modules/address/index.ts +2 -2
- package/src/js/modules/address/loqate.ts +1 -1
- package/src/js/modules/address/place-kit.ts +1 -1
- package/src/js/modules/captchas/captcha-eu.ts +2 -2
- package/src/js/modules/captchas/factories.ts +66 -42
- package/src/js/modules/captchas/friendly-captcha-v1.ts +12 -2
- package/src/js/modules/captchas/friendly-captcha-v2.ts +4 -2
- package/src/js/modules/captchas/hcaptcha.ts +5 -5
- package/src/js/modules/captchas/index.ts +2 -2
- package/src/js/modules/captchas/recaptcha-enterprise.ts +2 -2
- package/src/js/modules/captchas/recaptcha-v2-checkbox.ts +3 -3
- package/src/js/modules/captchas/recaptcha-v2-invisible.ts +2 -2
- package/src/js/modules/captchas/recaptcha-v3.ts +2 -2
- package/src/js/modules/captchas/snaptcha.ts +1 -1
- package/src/js/modules/captchas/turnstile.ts +3 -3
- package/src/js/modules/fields/address-country.ts +6 -4
- package/src/js/modules/fields/address-state.ts +20 -12
- package/src/js/modules/fields/calculations.ts +5 -3
- package/src/js/modules/fields/checkbox-radio.ts +24 -42
- package/src/js/modules/fields/combobox.ts +25 -9
- package/src/js/modules/fields/conditions/config.ts +17 -20
- package/src/js/modules/fields/conditions/effects.ts +23 -26
- package/src/js/modules/fields/conditions/evaluator.ts +21 -29
- package/src/js/modules/fields/conditions/references.ts +16 -5
- package/src/js/modules/fields/conditions/submission-context.ts +80 -0
- package/src/js/modules/fields/conditions/types.ts +3 -1
- package/src/js/modules/fields/conditions/values.ts +31 -6
- package/src/js/modules/fields/conditions.ts +59 -18
- package/src/js/modules/fields/custom-google-maps.ts +5 -3
- package/src/js/modules/fields/custom-link.ts +5 -3
- package/src/js/modules/fields/custom-maps.ts +5 -3
- package/src/js/modules/fields/date-picker.ts +40 -4
- package/src/js/modules/fields/file-upload.ts +19 -10
- package/src/js/modules/fields/hidden.ts +5 -3
- package/src/js/modules/fields/index.ts +2 -2
- package/src/js/modules/fields/password-validation.ts +5 -3
- package/src/js/modules/fields/phone-country.ts +33 -6
- package/src/js/modules/fields/repeater.ts +5 -3
- package/src/js/modules/fields/rich-text.ts +20 -4
- package/src/js/modules/fields/shared.ts +13 -0
- package/src/js/modules/fields/signature.ts +64 -6
- package/src/js/modules/fields/summary.ts +8 -20
- package/src/js/modules/fields/survey-likert.ts +5 -3
- package/src/js/modules/fields/survey-rank.ts +21 -3
- package/src/js/modules/fields/survey-rating.ts +17 -3
- package/src/js/modules/fields/table.ts +5 -3
- package/src/js/modules/fields/text-limit.ts +5 -3
- package/src/js/modules/fields/upload-manager.ts +190 -49
- package/src/js/modules/loader.ts +345 -281
- package/src/js/modules/payments/bpoint.ts +2 -2
- package/src/js/modules/payments/eway.ts +2 -2
- package/src/js/modules/payments/factories.ts +53 -52
- package/src/js/modules/payments/go-cardless.ts +1 -1
- package/src/js/modules/payments/index.ts +2 -2
- package/src/js/modules/payments/mollie.ts +1 -1
- package/src/js/modules/payments/moneris.ts +2 -2
- package/src/js/modules/payments/opayo.ts +21 -8
- package/src/js/modules/payments/paddle.ts +10 -6
- package/src/js/modules/payments/payment.ts +22 -18
- package/src/js/modules/payments/paypal.ts +1 -1
- package/src/js/modules/payments/payway.ts +2 -2
- package/src/js/modules/payments/square.ts +2 -2
- package/src/js/modules/payments/stripe.ts +5 -5
- package/src/js/modules/payments/utils.ts +14 -0
- package/src/js/modules/registry.ts +19 -11
- package/src/js/submit/pipeline.ts +10 -11
- package/src/js/theme/browser-theme-state.generated.ts +25 -0
- package/src/js/theme/theme-classes.ts +3 -3
- package/src/js/transport/forms-api.ts +66 -67
- package/src/js/utils/country-from-ip.ts +14 -9
- package/src/js/utils/csrf.ts +136 -0
- package/src/js/utils/field-references.parser.ts +13 -113
- package/src/js/utils/field-references.resolver.ts +27 -64
- package/src/js/utils/field-references.row-scope.ts +1 -1
- package/src/js/utils/field-references.types.ts +1 -0
- package/src/js/utils/http.ts +5 -5
- package/src/js/utils/request-profile.ts +10 -0
- package/src/js/utils/unload-warning.ts +12 -4
- package/src/js/validation/rules/email.ts +3 -5
- package/src/js/validation/rules/match.ts +2 -1
- package/src/js/validation/rules/minmax.ts +4 -43
- package/src/js/validation/rules/number.ts +3 -47
- package/src/js/validation/rules/pattern.ts +3 -8
- package/src/js/validation/rules/required.ts +2 -1
- package/src/js/validation/rules/shared.ts +5 -1
- package/src/js/validation/rules/url.ts +3 -10
- package/src/js/validation/skip.ts +9 -0
- package/src/js/validation/submit-readiness.ts +9 -2
- package/src/js/validation/validator.ts +35 -59
- package/dist/chunks/calculations-DERi2xaC.js +0 -299
- package/dist/chunks/conditions-65kBcFWW.js +0 -424
- package/dist/chunks/country-from-ip-BwxKaBuJ.js +0 -26
- package/dist/chunks/field-references.resolver-CHwn0G0L.js +0 -145
- package/dist/chunks/friendly-captcha-v1-C_2reOXr.js +0 -31
- package/dist/chunks/google-address-BH3Zhi06.js +0 -161
- package/dist/chunks/http-D-JExro7.js +0 -27
- package/dist/chunks/opayo-CR0DtsLa.js +0 -179
- package/dist/chunks/rich-text-Bg_--4TG.js +0 -349
- package/dist/js/modules/fields/conditions/transforms.d.ts +0 -3
- package/dist/js/modules/fields/conditions/transforms.d.ts.map +0 -1
- package/src/js/modules/fields/conditions/transforms.ts +0 -206
- package/src/js/modules/payments/stub-payment-module.ts +0 -87
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import surveyPresentationsCss from '#theme-css/fields/_survey-presentations.css?inline';
|
|
2
2
|
|
|
3
|
-
import type {
|
|
3
|
+
import type { BrowserModuleDefinition } from '#contracts/modules';
|
|
4
4
|
import { dispatchFieldEvent } from '#modules/fields/shared';
|
|
5
5
|
import { ensureModuleStyles } from '#modules/styles';
|
|
6
6
|
import { createDebug } from '#utils/debug';
|
|
@@ -183,6 +183,8 @@ function bindRankField(field: HTMLElement): () => void {
|
|
|
183
183
|
return () => {};
|
|
184
184
|
}
|
|
185
185
|
|
|
186
|
+
const initialItems = getRankItems(list);
|
|
187
|
+
const form = field.closest('form');
|
|
186
188
|
let draggedItem: HTMLElement | null = null;
|
|
187
189
|
let placeholder: HTMLElement | null = null;
|
|
188
190
|
let ghostStyleSnapshot: GhostStyleSnapshot | null = null;
|
|
@@ -325,9 +327,23 @@ function bindRankField(field: HTMLElement): () => void {
|
|
|
325
327
|
});
|
|
326
328
|
});
|
|
327
329
|
|
|
330
|
+
const onReset = (event: Event) => {
|
|
331
|
+
queueMicrotask(() => {
|
|
332
|
+
if (!event.defaultPrevented) {
|
|
333
|
+
document.removeEventListener('pointermove', onPointerMove);
|
|
334
|
+
document.removeEventListener('pointerup', onPointerUp);
|
|
335
|
+
document.removeEventListener('pointercancel', onPointerUp);
|
|
336
|
+
finishDrag();
|
|
337
|
+
initialItems.forEach((item) => list.appendChild(item));
|
|
338
|
+
syncRankInputs(list);
|
|
339
|
+
}
|
|
340
|
+
});
|
|
341
|
+
};
|
|
342
|
+
form?.addEventListener('reset', onReset);
|
|
328
343
|
syncRankInputs(list);
|
|
329
344
|
|
|
330
345
|
return () => {
|
|
346
|
+
form?.removeEventListener('reset', onReset);
|
|
331
347
|
document.removeEventListener('pointermove', onPointerMove);
|
|
332
348
|
document.removeEventListener('pointerup', onPointerUp);
|
|
333
349
|
document.removeEventListener('pointercancel', onPointerUp);
|
|
@@ -338,8 +354,10 @@ function bindRankField(field: HTMLElement): () => void {
|
|
|
338
354
|
};
|
|
339
355
|
}
|
|
340
356
|
|
|
341
|
-
export const surveyRankModule:
|
|
342
|
-
|
|
357
|
+
export const surveyRankModule: BrowserModuleDefinition = {
|
|
358
|
+
moduleId: `formie:${MODULE_ID}`,
|
|
359
|
+
version: 2,
|
|
360
|
+
surfaces: ['server-rendered', 'client-rendered', 'cp-edit'],
|
|
343
361
|
kind: 'field',
|
|
344
362
|
match: (ctx) => {
|
|
345
363
|
return ctx.target instanceof HTMLElement && (
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import surveyPresentationsCss from '#theme-css/fields/_survey-presentations.css?inline';
|
|
2
2
|
|
|
3
|
-
import type {
|
|
3
|
+
import type { BrowserModuleDefinition } from '#contracts/modules';
|
|
4
4
|
import { dispatchFieldEvent } from '#modules/fields/shared';
|
|
5
5
|
import { ensureModuleStyles } from '#modules/styles';
|
|
6
6
|
import { createDebug } from '#utils/debug';
|
|
@@ -124,9 +124,21 @@ function bindRatingField(field: HTMLElement): () => void {
|
|
|
124
124
|
});
|
|
125
125
|
});
|
|
126
126
|
|
|
127
|
+
const form = field.closest('form');
|
|
128
|
+
const onReset = (event: Event) => {
|
|
129
|
+
queueMicrotask(() => {
|
|
130
|
+
if (!event.defaultPrevented) {
|
|
131
|
+
clearHover();
|
|
132
|
+
getRatingInputs(stars).forEach((input) => input.removeAttribute(PRESSED_WHILE_CHECKED));
|
|
133
|
+
updateRatingValue(stars);
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
};
|
|
137
|
+
form?.addEventListener('reset', onReset);
|
|
127
138
|
updateRatingValue(stars);
|
|
128
139
|
|
|
129
140
|
return () => {
|
|
141
|
+
form?.removeEventListener('reset', onReset);
|
|
130
142
|
cleanups.forEach((cleanup) => {
|
|
131
143
|
cleanup();
|
|
132
144
|
});
|
|
@@ -135,8 +147,10 @@ function bindRatingField(field: HTMLElement): () => void {
|
|
|
135
147
|
};
|
|
136
148
|
}
|
|
137
149
|
|
|
138
|
-
export const surveyRatingModule:
|
|
139
|
-
|
|
150
|
+
export const surveyRatingModule: BrowserModuleDefinition = {
|
|
151
|
+
moduleId: `formie:${MODULE_ID}`,
|
|
152
|
+
version: 2,
|
|
153
|
+
surfaces: ['server-rendered', 'client-rendered', 'cp-edit'],
|
|
140
154
|
kind: 'field',
|
|
141
155
|
match: (ctx) => {
|
|
142
156
|
return ctx.target instanceof HTMLElement && (
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import tableCss from '#theme-css/fields/_table.css?inline';
|
|
2
2
|
|
|
3
|
-
import type {
|
|
3
|
+
import type { BrowserModuleDefinition } from '#contracts/modules';
|
|
4
4
|
import { dispatchFieldEvent, getTemplateSource, getTemplateSourceHtml } from '#modules/fields/shared';
|
|
5
5
|
import { ensureModuleStyles } from '#modules/styles';
|
|
6
6
|
import { sleep } from '#utils/async';
|
|
@@ -156,8 +156,10 @@ function bindTableField(field: HTMLElement, options: TableOptions): () => void {
|
|
|
156
156
|
};
|
|
157
157
|
}
|
|
158
158
|
|
|
159
|
-
export const tableModule:
|
|
160
|
-
|
|
159
|
+
export const tableModule: BrowserModuleDefinition = {
|
|
160
|
+
moduleId: `formie:${MODULE_ID}`,
|
|
161
|
+
version: 2,
|
|
162
|
+
surfaces: ['server-rendered', 'client-rendered', 'cp-edit'],
|
|
161
163
|
kind: 'field',
|
|
162
164
|
match: (ctx) => {
|
|
163
165
|
return ctx.target instanceof HTMLElement && (
|
|
@@ -2,7 +2,7 @@ import textLimitCss from '#theme-css/fields/_text-limit.css?inline';
|
|
|
2
2
|
|
|
3
3
|
import { getTextLimitMetrics } from '@verbb/formie-core';
|
|
4
4
|
|
|
5
|
-
import type {
|
|
5
|
+
import type { BrowserModuleDefinition } from '#contracts/modules';
|
|
6
6
|
import { getModuleFieldTarget, releaseFormValidators, retainFormValidators } from '#modules/fields/shared';
|
|
7
7
|
import { ensureModuleStyles } from '#modules/styles';
|
|
8
8
|
import { t } from '#utils/i18n';
|
|
@@ -282,8 +282,10 @@ function updateCounter(input: HTMLInputElement | HTMLTextAreaElement): void {
|
|
|
282
282
|
}
|
|
283
283
|
}
|
|
284
284
|
|
|
285
|
-
export const textLimitModule:
|
|
286
|
-
|
|
285
|
+
export const textLimitModule: BrowserModuleDefinition = {
|
|
286
|
+
moduleId: 'formie:text-limit',
|
|
287
|
+
version: 2,
|
|
288
|
+
surfaces: ['server-rendered', 'client-rendered', 'cp-edit'],
|
|
287
289
|
kind: 'field',
|
|
288
290
|
match: (ctx) => {
|
|
289
291
|
return !!ctx.target.querySelector(INPUT_SELECTOR);
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
+
import { browserRequestHeaders, type BrowserRequestOptions } from '@verbb/formie-core';
|
|
1
2
|
import Uppy from '@uppy/core';
|
|
2
3
|
import XHRUpload from '@uppy/xhr-upload';
|
|
3
4
|
import uploadManagerCss from '#theme-css/fields/_upload-manager.css?inline';
|
|
4
5
|
|
|
5
|
-
import type {
|
|
6
|
+
import type { BrowserModuleDefinition } from '#contracts/modules';
|
|
6
7
|
import { dispatchFieldEvent, releaseFormValidators, retainFormValidators } from '#modules/fields/shared';
|
|
7
8
|
import { ensureModuleStyles } from '#modules/styles';
|
|
8
9
|
import { getFieldModuleEventName, getFormStateEventName } from '#utils/event-names';
|
|
10
|
+
import { applyFormCsrfToRecord, appendFormCsrfToFormData, getFormCsrfToken } from '#utils/csrf';
|
|
11
|
+
import { fieldKeyToInputName } from '#utils/field-references';
|
|
9
12
|
import { requestJson } from '#utils/http';
|
|
10
13
|
import { createDebug } from '#utils/debug';
|
|
11
14
|
|
|
@@ -20,6 +23,8 @@ const SORT_UP_SELECTOR = '[data-formie-upload-manager-sort="up"]';
|
|
|
20
23
|
const SORT_DOWN_SELECTOR = '[data-formie-upload-manager-sort="down"]';
|
|
21
24
|
const HIDDEN_INPUT_ANCHOR_ATTR = 'data-formie-file-upload-anchor';
|
|
22
25
|
const HIDDEN_INPUT_VALUE_ATTR = 'data-formie-file-upload-asset-id';
|
|
26
|
+
const HIDDEN_INPUT_TOKEN_ATTR = 'data-formie-file-upload-token';
|
|
27
|
+
const HIDDEN_INPUT_ENTRY_ATTR = 'data-formie-file-upload-entry';
|
|
23
28
|
const FORM_RESET_EVENT = getFormStateEventName('reset');
|
|
24
29
|
const REPEATER_INIT_ROW_EVENT = getFieldModuleEventName('repeater', 'init-row');
|
|
25
30
|
const MODULE_ID = 'upload-manager';
|
|
@@ -49,6 +54,10 @@ type UploadResponse = {
|
|
|
49
54
|
assetId?: number;
|
|
50
55
|
filename?: string;
|
|
51
56
|
url?: string | null;
|
|
57
|
+
uploadToken?: string | null;
|
|
58
|
+
deleteToken?: string | null;
|
|
59
|
+
uploadUid?: string | null;
|
|
60
|
+
attachToken?: string | null;
|
|
52
61
|
errors?: Record<string, string[]>;
|
|
53
62
|
};
|
|
54
63
|
|
|
@@ -62,11 +71,19 @@ type HydrateResponse = {
|
|
|
62
71
|
assetId?: number;
|
|
63
72
|
filename?: string;
|
|
64
73
|
url?: string | null;
|
|
74
|
+
uploadToken?: string | null;
|
|
75
|
+
deleteToken?: string | null;
|
|
76
|
+
uploadUid?: string | null;
|
|
77
|
+
attachToken?: string | null;
|
|
65
78
|
}>;
|
|
66
79
|
};
|
|
67
80
|
|
|
68
81
|
type ManagedFile = {
|
|
69
82
|
assetId: number | null;
|
|
83
|
+
uploadToken: string | null;
|
|
84
|
+
deleteToken?: string | null;
|
|
85
|
+
uploadUid: string | null;
|
|
86
|
+
attachToken: string | null;
|
|
70
87
|
filename: string;
|
|
71
88
|
uppyFileId: string | null;
|
|
72
89
|
listItem: HTMLElement;
|
|
@@ -144,33 +161,85 @@ function getAnchorInput(field: HTMLElement, assetInputName: string): HTMLInputEl
|
|
|
144
161
|
|
|
145
162
|
function getUploadedAssetInputs(field: HTMLElement, assetInputName: string): HTMLInputElement[] {
|
|
146
163
|
return getHiddenInputs(field).filter((hiddenInput) => {
|
|
147
|
-
return hiddenInput.
|
|
164
|
+
return hiddenInput.hasAttribute(HIDDEN_INPUT_VALUE_ATTR)
|
|
165
|
+
|| (hiddenInput.name === assetInputName && hiddenInput.value.trim() !== '');
|
|
148
166
|
});
|
|
149
167
|
}
|
|
150
168
|
|
|
151
169
|
function readAssetIdsFromDom(field: HTMLElement, assetInputName: string): number[] {
|
|
152
170
|
return getUploadedAssetInputs(field, assetInputName).map((input) => {
|
|
153
|
-
return toPositiveInt(input.value);
|
|
171
|
+
return toPositiveInt(input.getAttribute(HIDDEN_INPUT_VALUE_ATTR)) ?? toPositiveInt(input.value);
|
|
154
172
|
}).filter((assetId): assetId is number => {
|
|
155
173
|
return assetId !== null;
|
|
156
174
|
});
|
|
157
175
|
}
|
|
158
176
|
|
|
159
|
-
function
|
|
177
|
+
function readUploadTokensFromDom(field: HTMLElement, assetInputName: string): Record<number, string> {
|
|
178
|
+
const tokens: Record<number, string> = {};
|
|
179
|
+
|
|
180
|
+
getUploadedAssetInputs(field, assetInputName).forEach((input) => {
|
|
181
|
+
const assetId = toPositiveInt(input.getAttribute(HIDDEN_INPUT_VALUE_ATTR)) ?? toPositiveInt(input.value);
|
|
182
|
+
const token = input.getAttribute(HIDDEN_INPUT_TOKEN_ATTR)?.trim() || '';
|
|
183
|
+
|
|
184
|
+
if (assetId && token) {
|
|
185
|
+
tokens[assetId] = token;
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
return tokens;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
function syncHiddenAssetInputs(
|
|
193
|
+
field: HTMLElement,
|
|
194
|
+
anchorInput: HTMLInputElement,
|
|
195
|
+
assetInputName: string,
|
|
196
|
+
assets: Array<{
|
|
197
|
+
assetId: number;
|
|
198
|
+
uploadToken: string | null;
|
|
199
|
+
uploadUid: string | null;
|
|
200
|
+
attachToken: string | null;
|
|
201
|
+
}>,
|
|
202
|
+
): void {
|
|
160
203
|
let insertionPoint: HTMLInputElement = anchorInput;
|
|
204
|
+
const baseName = assetInputName.endsWith('[]') ? assetInputName.slice(0, -2) : assetInputName;
|
|
161
205
|
|
|
162
|
-
|
|
206
|
+
getHiddenInputs(field).filter((hiddenInput) => {
|
|
207
|
+
return hiddenInput.hasAttribute(HIDDEN_INPUT_ENTRY_ATTR)
|
|
208
|
+
|| (hiddenInput.name === assetInputName && hiddenInput.value.trim() !== '');
|
|
209
|
+
}).forEach((hiddenInput) => {
|
|
163
210
|
hiddenInput.remove();
|
|
164
211
|
});
|
|
165
212
|
|
|
166
|
-
|
|
167
|
-
const
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
213
|
+
assets.forEach(({ assetId, uploadToken, uploadUid, attachToken }, index) => {
|
|
214
|
+
const primaryInput = document.createElement('input');
|
|
215
|
+
primaryInput.type = 'hidden';
|
|
216
|
+
primaryInput.setAttribute(HIDDEN_INPUT_ENTRY_ATTR, 'true');
|
|
217
|
+
primaryInput.setAttribute(HIDDEN_INPUT_VALUE_ATTR, String(assetId));
|
|
218
|
+
|
|
219
|
+
if (uploadUid && attachToken) {
|
|
220
|
+
primaryInput.name = `${baseName}[${index}][uploadUid]`;
|
|
221
|
+
primaryInput.value = uploadUid;
|
|
222
|
+
} else {
|
|
223
|
+
primaryInput.name = `${baseName}[${index}][assetId]`;
|
|
224
|
+
primaryInput.value = String(assetId);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
if (uploadToken) {
|
|
228
|
+
primaryInput.setAttribute(HIDDEN_INPUT_TOKEN_ATTR, uploadToken);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
insertionPoint.insertAdjacentElement('afterend', primaryInput);
|
|
232
|
+
insertionPoint = primaryInput;
|
|
233
|
+
|
|
234
|
+
if (uploadUid && attachToken) {
|
|
235
|
+
const capabilityInput = document.createElement('input');
|
|
236
|
+
capabilityInput.type = 'hidden';
|
|
237
|
+
capabilityInput.name = `${baseName}[${index}][attachToken]`;
|
|
238
|
+
capabilityInput.value = attachToken;
|
|
239
|
+
capabilityInput.setAttribute(HIDDEN_INPUT_ENTRY_ATTR, 'true');
|
|
240
|
+
insertionPoint.insertAdjacentElement('afterend', capabilityInput);
|
|
241
|
+
insertionPoint = capabilityInput;
|
|
242
|
+
}
|
|
174
243
|
});
|
|
175
244
|
}
|
|
176
245
|
|
|
@@ -189,7 +258,7 @@ function getUploadContext(form: HTMLFormElement | null, field: HTMLElement, drop
|
|
|
189
258
|
return context;
|
|
190
259
|
}
|
|
191
260
|
|
|
192
|
-
const passthroughNames = ['renderId', 'draftContextToken', 'draftContext', 'submissionId'] as const;
|
|
261
|
+
const passthroughNames = ['renderId', 'draftContextToken', 'draftContext', 'submissionId', 'siteId', 'submissionEditToken', 'resumeToken', 'submissionUid', 'uploadCreateToken'] as const;
|
|
193
262
|
|
|
194
263
|
passthroughNames.forEach((name) => {
|
|
195
264
|
const input = form.querySelector(`input[name="${name}"]`);
|
|
@@ -199,16 +268,18 @@ function getUploadContext(form: HTMLFormElement | null, field: HTMLElement, drop
|
|
|
199
268
|
}
|
|
200
269
|
});
|
|
201
270
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
if (csrfInput instanceof HTMLInputElement && csrfInput.value.trim()) {
|
|
205
|
-
context.CRAFT_CSRF_TOKEN = csrfInput.value.trim();
|
|
206
|
-
}
|
|
271
|
+
// Honour custom Craft csrfTokenName values from the rendered form.
|
|
272
|
+
applyFormCsrfToRecord(context, form);
|
|
207
273
|
|
|
208
274
|
return context;
|
|
209
275
|
}
|
|
210
276
|
|
|
211
|
-
function buildHydrateFormData(
|
|
277
|
+
function buildHydrateFormData(
|
|
278
|
+
form: HTMLFormElement | null,
|
|
279
|
+
field: HTMLElement,
|
|
280
|
+
assetIds: number[],
|
|
281
|
+
uploadTokens: Record<number, string> = {},
|
|
282
|
+
): FormData {
|
|
212
283
|
const body = new FormData();
|
|
213
284
|
const handle = getFormHandle(form);
|
|
214
285
|
const fieldHandle = getFieldHandle(field);
|
|
@@ -221,16 +292,28 @@ function buildHydrateFormData(form: HTMLFormElement | null, field: HTMLElement,
|
|
|
221
292
|
body.append('fieldHandle', fieldHandle);
|
|
222
293
|
}
|
|
223
294
|
|
|
224
|
-
const
|
|
295
|
+
const passthroughNames = ['submissionUid', 'resumeToken', 'submissionEditToken', 'siteId', 'renderId', 'draftContext', 'draftContextToken'] as const;
|
|
225
296
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
297
|
+
passthroughNames.forEach((name) => {
|
|
298
|
+
const input = form?.querySelector(`input[name="${name}"]`);
|
|
299
|
+
|
|
300
|
+
if (input instanceof HTMLInputElement && input.value.trim()) {
|
|
301
|
+
body.append(name, input.value.trim());
|
|
302
|
+
}
|
|
303
|
+
});
|
|
229
304
|
|
|
230
305
|
assetIds.forEach((assetId) => {
|
|
231
306
|
body.append('assetIds[]', String(assetId));
|
|
307
|
+
|
|
308
|
+
const token = uploadTokens[assetId];
|
|
309
|
+
|
|
310
|
+
if (token) {
|
|
311
|
+
body.append(`uploadTokens[${assetId}]`, token);
|
|
312
|
+
}
|
|
232
313
|
});
|
|
233
314
|
|
|
315
|
+
appendFormCsrfToFormData(body, form);
|
|
316
|
+
|
|
234
317
|
return body;
|
|
235
318
|
}
|
|
236
319
|
|
|
@@ -524,17 +607,20 @@ function createListItem(field: HTMLElement, filename: string): {
|
|
|
524
607
|
}
|
|
525
608
|
|
|
526
609
|
function getAssetInputName(field: HTMLElement): string {
|
|
527
|
-
|
|
528
|
-
|
|
610
|
+
// Prefer the template anchor name — nested Group/Repeater fields use
|
|
611
|
+
// `fields[group][upload][]`, not a dotted `fields[group.upload][]`.
|
|
612
|
+
const anchorInput = getHiddenInputs(field).find((input) => {
|
|
613
|
+
return input.hasAttribute(HIDDEN_INPUT_ANCHOR_ATTR);
|
|
529
614
|
});
|
|
530
615
|
|
|
531
|
-
if (
|
|
532
|
-
return
|
|
616
|
+
if (anchorInput?.name) {
|
|
617
|
+
return anchorInput.name.endsWith('[]') ? anchorInput.name : `${anchorInput.name}[]`;
|
|
533
618
|
}
|
|
534
619
|
|
|
535
620
|
const fieldHandle = getFieldHandle(field);
|
|
621
|
+
const inputName = fieldHandle ? fieldKeyToInputName(fieldHandle) : '';
|
|
536
622
|
|
|
537
|
-
return
|
|
623
|
+
return inputName ? `${inputName}[]` : 'fields[fileUpload][]';
|
|
538
624
|
}
|
|
539
625
|
|
|
540
626
|
function countManagedAssets(state: UploadManagerState): number {
|
|
@@ -544,27 +630,31 @@ function countManagedAssets(state: UploadManagerState): number {
|
|
|
544
630
|
}
|
|
545
631
|
|
|
546
632
|
function syncUploadedAssetsEvent(state: UploadManagerState): void {
|
|
547
|
-
const
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
633
|
+
const assets = state.files
|
|
634
|
+
.filter((file): file is ManagedFile & { assetId: number } => {
|
|
635
|
+
return file.assetId !== null;
|
|
636
|
+
})
|
|
637
|
+
.map((file) => {
|
|
638
|
+
return {
|
|
639
|
+
assetId: file.assetId,
|
|
640
|
+
uploadToken: file.uploadToken,
|
|
641
|
+
uploadUid: file.uploadUid,
|
|
642
|
+
attachToken: file.attachToken,
|
|
643
|
+
filename: file.filename,
|
|
644
|
+
};
|
|
645
|
+
});
|
|
552
646
|
|
|
553
|
-
syncHiddenAssetInputs(state.field, state.anchorInput, state.assetInputName,
|
|
647
|
+
syncHiddenAssetInputs(state.field, state.anchorInput, state.assetInputName, assets);
|
|
554
648
|
|
|
555
649
|
if (state.statusInput) {
|
|
556
|
-
state.statusInput.value =
|
|
650
|
+
state.statusInput.value = assets.length ? 'uploaded' : '';
|
|
557
651
|
}
|
|
558
652
|
|
|
559
653
|
dispatchFieldEvent(state.field, 'file-upload', 'uploaded-assets-sync', {
|
|
560
|
-
assets:
|
|
561
|
-
const managed = state.files.find((file) => {
|
|
562
|
-
return file.assetId === assetId;
|
|
563
|
-
});
|
|
564
|
-
|
|
654
|
+
assets: assets.map(({ assetId, filename }) => {
|
|
565
655
|
return {
|
|
566
656
|
assetId,
|
|
567
|
-
filename
|
|
657
|
+
filename,
|
|
568
658
|
};
|
|
569
659
|
}),
|
|
570
660
|
});
|
|
@@ -707,11 +797,15 @@ function bindUploadManagerField(field: HTMLElement, form: HTMLFormElement | null
|
|
|
707
797
|
restrictions,
|
|
708
798
|
});
|
|
709
799
|
|
|
800
|
+
// Resolve once for Uppy's allow-list; per-request meta/header refresh
|
|
801
|
+
// still re-reads the live form token (including custom csrfTokenName).
|
|
802
|
+
const initialCsrf = getFormCsrfToken(resolvedForm);
|
|
803
|
+
|
|
710
804
|
uppy.use(XHRUpload, {
|
|
711
805
|
endpoint: uploadEndpoint,
|
|
712
806
|
fieldName: 'file',
|
|
713
807
|
formData: true,
|
|
714
|
-
withCredentials:
|
|
808
|
+
withCredentials: resolvedForm?.dataset.formieRequestProfile !== 'cross-origin-public',
|
|
715
809
|
timeout: UPLOAD_XHR_TIMEOUT_MS,
|
|
716
810
|
shouldRetry: shouldRetryUpload,
|
|
717
811
|
headers: {
|
|
@@ -725,7 +819,11 @@ function bindUploadManagerField(field: HTMLElement, form: HTMLFormElement | null
|
|
|
725
819
|
'draftContextToken',
|
|
726
820
|
'draftContext',
|
|
727
821
|
'submissionId',
|
|
728
|
-
'
|
|
822
|
+
'siteId',
|
|
823
|
+
'submissionEditToken',
|
|
824
|
+
'resumeToken',
|
|
825
|
+
'uploadCreateToken',
|
|
826
|
+
...(initialCsrf ? [initialCsrf.name] : []),
|
|
729
827
|
],
|
|
730
828
|
getResponseData(xhr) {
|
|
731
829
|
try {
|
|
@@ -735,6 +833,14 @@ function bindUploadManagerField(field: HTMLElement, form: HTMLFormElement | null
|
|
|
735
833
|
}
|
|
736
834
|
},
|
|
737
835
|
onBeforeRequest(xhr, _retryCount, files) {
|
|
836
|
+
browserRequestHeaders(uploadEndpoint, { profile: resolvedForm?.dataset.formieRequestProfile as BrowserRequestOptions['profile'] }).forEach((value, name) => xhr.setRequestHeader(name, value));
|
|
837
|
+
// Header works regardless of csrfTokenName / allowedMetaFields.
|
|
838
|
+
const csrf = getFormCsrfToken(resolvedForm);
|
|
839
|
+
|
|
840
|
+
if (csrf) {
|
|
841
|
+
xhr.setRequestHeader('X-CSRF-Token', csrf.value);
|
|
842
|
+
}
|
|
843
|
+
|
|
738
844
|
const uppyFile = files[0];
|
|
739
845
|
|
|
740
846
|
if (!uppyFile?.id || !uppyFile.size) {
|
|
@@ -888,8 +994,13 @@ function bindUploadManagerField(field: HTMLElement, form: HTMLFormElement | null
|
|
|
888
994
|
|
|
889
995
|
body.append('assetId', String(managedFile.assetId));
|
|
890
996
|
|
|
997
|
+
if (managedFile.uploadToken) {
|
|
998
|
+
body.append('uploadToken', managedFile.deleteToken || '');
|
|
999
|
+
}
|
|
1000
|
+
|
|
891
1001
|
try {
|
|
892
1002
|
await requestJson<DeleteResponse>(deleteEndpoint, {
|
|
1003
|
+
profile: resolvedForm?.dataset.formieRequestProfile as BrowserRequestOptions['profile'],
|
|
893
1004
|
method: 'POST',
|
|
894
1005
|
body,
|
|
895
1006
|
});
|
|
@@ -906,13 +1017,24 @@ function bindUploadManagerField(field: HTMLElement, form: HTMLFormElement | null
|
|
|
906
1017
|
syncSortControls();
|
|
907
1018
|
};
|
|
908
1019
|
|
|
909
|
-
const addManagedFileFromAsset = (
|
|
1020
|
+
const addManagedFileFromAsset = (
|
|
1021
|
+
assetId: number,
|
|
1022
|
+
filename: string,
|
|
1023
|
+
uploadToken: string | null = null,
|
|
1024
|
+
deleteToken: string | null = null,
|
|
1025
|
+
uploadUid: string | null = null,
|
|
1026
|
+
attachToken: string | null = null,
|
|
1027
|
+
) => {
|
|
910
1028
|
const { listItem, removeButton, sortUpButton, sortDownButton } = createListItem(field, filename);
|
|
911
1029
|
listItem.classList.add('is-complete');
|
|
912
1030
|
fileList.append(listItem);
|
|
913
1031
|
|
|
914
1032
|
const managedFile: ManagedFile = {
|
|
915
1033
|
assetId,
|
|
1034
|
+
uploadToken,
|
|
1035
|
+
deleteToken,
|
|
1036
|
+
uploadUid,
|
|
1037
|
+
attachToken,
|
|
916
1038
|
filename,
|
|
917
1039
|
uppyFileId: null,
|
|
918
1040
|
listItem,
|
|
@@ -930,10 +1052,13 @@ function bindUploadManagerField(field: HTMLElement, form: HTMLFormElement | null
|
|
|
930
1052
|
return;
|
|
931
1053
|
}
|
|
932
1054
|
|
|
1055
|
+
const uploadTokens = readUploadTokensFromDom(field, assetInputName);
|
|
1056
|
+
|
|
933
1057
|
try {
|
|
934
1058
|
const response = await requestJson<HydrateResponse>(hydrateEndpoint, {
|
|
1059
|
+
profile: resolvedForm?.dataset.formieRequestProfile as BrowserRequestOptions['profile'],
|
|
935
1060
|
method: 'POST',
|
|
936
|
-
body: buildHydrateFormData(resolvedForm, field, assetIds),
|
|
1061
|
+
body: buildHydrateFormData(resolvedForm, field, assetIds, uploadTokens),
|
|
937
1062
|
});
|
|
938
1063
|
|
|
939
1064
|
const assets = response.assets || [];
|
|
@@ -956,7 +1081,14 @@ function bindUploadManagerField(field: HTMLElement, form: HTMLFormElement | null
|
|
|
956
1081
|
return;
|
|
957
1082
|
}
|
|
958
1083
|
|
|
959
|
-
addManagedFileFromAsset(
|
|
1084
|
+
addManagedFileFromAsset(
|
|
1085
|
+
assetId,
|
|
1086
|
+
asset.filename || `Asset #${assetId}`,
|
|
1087
|
+
toTrimmedString(asset.uploadToken) || uploadTokens[assetId] || null,
|
|
1088
|
+
toTrimmedString(asset.deleteToken) || null,
|
|
1089
|
+
toTrimmedString(asset.uploadUid) || null,
|
|
1090
|
+
toTrimmedString(asset.attachToken) || null,
|
|
1091
|
+
);
|
|
960
1092
|
});
|
|
961
1093
|
|
|
962
1094
|
syncUploadedAssetsEvent(state);
|
|
@@ -1034,6 +1166,10 @@ function bindUploadManagerField(field: HTMLElement, form: HTMLFormElement | null
|
|
|
1034
1166
|
}
|
|
1035
1167
|
|
|
1036
1168
|
managedFile.assetId = assetId;
|
|
1169
|
+
managedFile.uploadToken = toTrimmedString(body.uploadToken) || null;
|
|
1170
|
+
managedFile.deleteToken = toTrimmedString(body.deleteToken) || null;
|
|
1171
|
+
managedFile.uploadUid = toTrimmedString(body.uploadUid) || null;
|
|
1172
|
+
managedFile.attachToken = toTrimmedString(body.attachToken) || null;
|
|
1037
1173
|
managedFile.filename = body.filename || managedFile.filename;
|
|
1038
1174
|
markUploadComplete(managedFile.listItem);
|
|
1039
1175
|
syncUploadedAssetsEvent(state);
|
|
@@ -1073,6 +1209,9 @@ function bindUploadManagerField(field: HTMLElement, form: HTMLFormElement | null
|
|
|
1073
1209
|
|
|
1074
1210
|
const managedFile: ManagedFile = {
|
|
1075
1211
|
assetId: null,
|
|
1212
|
+
uploadToken: null,
|
|
1213
|
+
uploadUid: null,
|
|
1214
|
+
attachToken: null,
|
|
1076
1215
|
filename: file.name || 'Upload',
|
|
1077
1216
|
uppyFileId: file.id,
|
|
1078
1217
|
listItem,
|
|
@@ -1191,8 +1330,10 @@ function bindUploadManagerField(field: HTMLElement, form: HTMLFormElement | null
|
|
|
1191
1330
|
};
|
|
1192
1331
|
}
|
|
1193
1332
|
|
|
1194
|
-
export const uploadManagerModule:
|
|
1195
|
-
|
|
1333
|
+
export const uploadManagerModule: BrowserModuleDefinition = {
|
|
1334
|
+
moduleId: `formie:${MODULE_ID}`,
|
|
1335
|
+
version: 2,
|
|
1336
|
+
surfaces: ['server-rendered', 'client-rendered', 'cp-edit'],
|
|
1196
1337
|
kind: 'field',
|
|
1197
1338
|
match: (ctx) => {
|
|
1198
1339
|
return !!ctx.target.querySelector(ROOT_SELECTOR);
|