@verbb/formie-browser 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +5 -0
- package/LICENSE.md +40 -0
- package/README.md +34 -0
- package/dist/chunks/address-finder-DfMCiW89.js +47 -0
- package/dist/chunks/api-CbqEMQT5.js +181 -0
- package/dist/chunks/api-DE7LfK-R.js +960 -0
- package/dist/chunks/api-DOfDzYC_.js +538 -0
- package/dist/chunks/async-B3DUf1GZ.js +26 -0
- package/dist/chunks/bpoint-Ciy3yY9Q.js +34 -0
- package/dist/chunks/calculations-CkYAqO_-.js +197 -0
- package/dist/chunks/captcha-eu-DnOWhMwr.js +43 -0
- package/dist/chunks/checkbox-radio-0x7Tc0br.js +197 -0
- package/dist/chunks/chunk-K6L4z4UQ.js +24 -0
- package/dist/chunks/conditions-4fXKhEJS.js +609 -0
- package/dist/chunks/date-picker-B6iZkjHS.js +6204 -0
- package/dist/chunks/debug-KnZeKYBI.js +39 -0
- package/dist/chunks/dist-D09GnXMW.js +2663 -0
- package/dist/chunks/event-names-DamGPtXR.js +51 -0
- package/dist/chunks/eway-DEAYcwT0.js +86 -0
- package/dist/chunks/field-references.keys-BpBZ_quS.js +24 -0
- package/dist/chunks/field-references.resolver-Ba6xhiJC.js +183 -0
- package/dist/chunks/file-upload-Bh63PQSE.js +430 -0
- package/dist/chunks/friendly-captcha-v1-CqO4WVre.js +40 -0
- package/dist/chunks/friendly-captcha-v2-CyykcJcM.js +47 -0
- package/dist/chunks/friendly-challenge-Dg8XkStd.js +1101 -0
- package/dist/chunks/go-cardless-CuND59rR.js +26 -0
- package/dist/chunks/google-address--uR8WDSm.js +208 -0
- package/dist/chunks/hcaptcha-CmaFUesv.js +72 -0
- package/dist/chunks/hidden-CYnZYple.js +36 -0
- package/dist/chunks/http-18nn97DZ.js +29 -0
- package/dist/chunks/i18n-vUh-KGiH.js +55 -0
- package/dist/chunks/loqate-BICNJlVK.js +97 -0
- package/dist/chunks/mollie-DwlsgHZ1.js +26 -0
- package/dist/chunks/moneris-B_IFZFTx.js +159 -0
- package/dist/chunks/opayo-U2x_TOII.js +192 -0
- package/dist/chunks/paddle-BqXFrc79.js +75 -0
- package/dist/chunks/paypal-Cn_DYGDb.js +121 -0
- package/dist/chunks/payway-Rnq796eC.js +75 -0
- package/dist/chunks/phone-country-B6Me4lK0.js +3317 -0
- package/dist/chunks/place-kit-ldUl-u9w.js +56 -0
- package/dist/chunks/placekit-autocomplete.esm-D-lGeaZl.js +1771 -0
- package/dist/chunks/recaptcha-enterprise-DPJNyv1X.js +72 -0
- package/dist/chunks/recaptcha-shared-DTI4qWVR.js +22 -0
- package/dist/chunks/recaptcha-v2-checkbox-zFjpvJ5c.js +49 -0
- package/dist/chunks/recaptcha-v2-invisible-CnYtkNvz.js +62 -0
- package/dist/chunks/recaptcha-v3-EAlWhnkX.js +33 -0
- package/dist/chunks/repeater-CXD1eLSn.js +151 -0
- package/dist/chunks/rich-text-DkmZRhGj.js +442 -0
- package/dist/chunks/scripts-BGD_iU_6.js +41 -0
- package/dist/chunks/sdk-B7u9fTlP.js +2103 -0
- package/dist/chunks/shared-DC6_1u8X.js +85 -0
- package/dist/chunks/signature-E9KyYXS1.js +765 -0
- package/dist/chunks/snaptcha-CCDunGeb.js +8 -0
- package/dist/chunks/square-BLqK51rS.js +61 -0
- package/dist/chunks/stripe-B8gHpZNC.js +273 -0
- package/dist/chunks/styles-BIh6g7V_.js +22 -0
- package/dist/chunks/summary-EcNE0cvg.js +191 -0
- package/dist/chunks/table-yxEDL6kA.js +124 -0
- package/dist/chunks/text-limit-D0H_Ca2c.js +179 -0
- package/dist/chunks/theme-classes-vSHpdCUO.js +59 -0
- package/dist/chunks/turnstile-DP0bdR7T.js +68 -0
- package/dist/chunks/utils-ByrEVYrJ.js +49584 -0
- package/dist/css/formie-base.css +78 -0
- package/dist/css/formie-theme.css +19 -0
- package/dist/css/formie.css +2 -0
- package/dist/css/theme/_buttons.css +249 -0
- package/dist/css/theme/_loading.css +37 -0
- package/dist/css/theme/_messages.css +39 -0
- package/dist/css/theme/_progress.css +62 -0
- package/dist/css/theme/_tokens.css +361 -0
- package/dist/css/theme/_typography.css +70 -0
- package/dist/css/theme/fields/_address.css +17 -0
- package/dist/css/theme/fields/_check-radio.css +108 -0
- package/dist/css/theme/fields/_file.css +58 -0
- package/dist/css/theme/fields/_group.css +13 -0
- package/dist/css/theme/fields/_input.css +48 -0
- package/dist/css/theme/fields/_nested.css +19 -0
- package/dist/css/theme/fields/_repeater.css +69 -0
- package/dist/css/theme/fields/_rich-text.css +201 -0
- package/dist/css/theme/fields/_select.css +37 -0
- package/dist/css/theme/fields/_signature.css +39 -0
- package/dist/css/theme/fields/_summary.css +53 -0
- package/dist/css/theme/fields/_table.css +121 -0
- package/dist/css/theme/fields/_text-limit.css +10 -0
- package/dist/css/theme/forms/_field.css +62 -0
- package/dist/css/theme/forms/_form.css +166 -0
- package/dist/css/theme/integrations/_payment-modal.css +32 -0
- package/dist/css/theme/integrations/_paypal.css +10 -0
- package/dist/css/theme/integrations/_payway.css +10 -0
- package/dist/css/theme/integrations/_stripe.css +24 -0
- package/dist/css/theme/utilities/_accessibility.css +13 -0
- package/dist/css/theme-base/_controls.css +41 -0
- package/dist/css/theme-base/_primitives.css +34 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3206 -0
- package/dist/js/compatibility/dom-adapter.d.ts +12 -0
- package/dist/js/compatibility/dom-adapter.d.ts.map +1 -0
- package/dist/js/compatibility/event-map.d.ts +25 -0
- package/dist/js/compatibility/event-map.d.ts.map +1 -0
- package/dist/js/compatibility/validator-adapter.d.ts +17 -0
- package/dist/js/compatibility/validator-adapter.d.ts.map +1 -0
- package/dist/js/contracts/client.d.ts +40 -0
- package/dist/js/contracts/client.d.ts.map +1 -0
- package/dist/js/contracts/common.d.ts +5 -0
- package/dist/js/contracts/common.d.ts.map +1 -0
- package/dist/js/contracts/modules.d.ts +47 -0
- package/dist/js/contracts/modules.d.ts.map +1 -0
- package/dist/js/contracts/schema.d.ts +79 -0
- package/dist/js/contracts/schema.d.ts.map +1 -0
- package/dist/js/contracts/theme.d.ts +2 -0
- package/dist/js/contracts/theme.d.ts.map +1 -0
- package/dist/js/core/create-formie-client.d.ts +3 -0
- package/dist/js/core/create-formie-client.d.ts.map +1 -0
- package/dist/js/core/dom-events.d.ts +2 -0
- package/dist/js/core/dom-events.d.ts.map +1 -0
- package/dist/js/core/formie.d.ts +27 -0
- package/dist/js/core/formie.d.ts.map +1 -0
- package/dist/js/core/hydrate-modules.d.ts +22 -0
- package/dist/js/core/hydrate-modules.d.ts.map +1 -0
- package/dist/js/core/page-client-event.d.ts +9 -0
- package/dist/js/core/page-client-event.d.ts.map +1 -0
- package/dist/js/core/page-tab-errors.d.ts +2 -0
- package/dist/js/core/page-tab-errors.d.ts.map +1 -0
- package/dist/js/core/submit-flow.d.ts +21 -0
- package/dist/js/core/submit-flow.d.ts.map +1 -0
- package/dist/js/core/submit-result-state.d.ts +8 -0
- package/dist/js/core/submit-result-state.d.ts.map +1 -0
- package/dist/js/core/submit-result-ui.d.ts +10 -0
- package/dist/js/core/submit-result-ui.d.ts.map +1 -0
- package/dist/js/events/event-bus.d.ts +21 -0
- package/dist/js/events/event-bus.d.ts.map +1 -0
- package/dist/js/modules/address/address-finder.d.ts +2 -0
- package/dist/js/modules/address/address-finder.d.ts.map +1 -0
- package/dist/js/modules/address/api.d.ts +8 -0
- package/dist/js/modules/address/api.d.ts.map +1 -0
- package/dist/js/modules/address/constants.d.ts +15 -0
- package/dist/js/modules/address/constants.d.ts.map +1 -0
- package/dist/js/modules/address/factories.d.ts +35 -0
- package/dist/js/modules/address/factories.d.ts.map +1 -0
- package/dist/js/modules/address/google-address.d.ts +2 -0
- package/dist/js/modules/address/google-address.d.ts.map +1 -0
- package/dist/js/modules/address/host.d.ts +30 -0
- package/dist/js/modules/address/host.d.ts.map +1 -0
- package/dist/js/modules/address/index.d.ts +3 -0
- package/dist/js/modules/address/index.d.ts.map +1 -0
- package/dist/js/modules/address/loqate.d.ts +2 -0
- package/dist/js/modules/address/loqate.d.ts.map +1 -0
- package/dist/js/modules/address/place-kit.d.ts +2 -0
- package/dist/js/modules/address/place-kit.d.ts.map +1 -0
- package/dist/js/modules/captchas/api.d.ts +9 -0
- package/dist/js/modules/captchas/api.d.ts.map +1 -0
- package/dist/js/modules/captchas/captcha-eu.d.ts +2 -0
- package/dist/js/modules/captchas/captcha-eu.d.ts.map +1 -0
- package/dist/js/modules/captchas/constants.d.ts +5 -0
- package/dist/js/modules/captchas/constants.d.ts.map +1 -0
- package/dist/js/modules/captchas/factories.d.ts +63 -0
- package/dist/js/modules/captchas/factories.d.ts.map +1 -0
- package/dist/js/modules/captchas/friendly-captcha-v1.d.ts +2 -0
- package/dist/js/modules/captchas/friendly-captcha-v1.d.ts.map +1 -0
- package/dist/js/modules/captchas/friendly-captcha-v2.d.ts +2 -0
- package/dist/js/modules/captchas/friendly-captcha-v2.d.ts.map +1 -0
- package/dist/js/modules/captchas/hcaptcha.d.ts +2 -0
- package/dist/js/modules/captchas/hcaptcha.d.ts.map +1 -0
- package/dist/js/modules/captchas/host.d.ts +78 -0
- package/dist/js/modules/captchas/host.d.ts.map +1 -0
- package/dist/js/modules/captchas/index.d.ts +3 -0
- package/dist/js/modules/captchas/index.d.ts.map +1 -0
- package/dist/js/modules/captchas/recaptcha-enterprise.d.ts +2 -0
- package/dist/js/modules/captchas/recaptcha-enterprise.d.ts.map +1 -0
- package/dist/js/modules/captchas/recaptcha-shared.d.ts +26 -0
- package/dist/js/modules/captchas/recaptcha-shared.d.ts.map +1 -0
- package/dist/js/modules/captchas/recaptcha-v2-checkbox.d.ts +2 -0
- package/dist/js/modules/captchas/recaptcha-v2-checkbox.d.ts.map +1 -0
- package/dist/js/modules/captchas/recaptcha-v2-invisible.d.ts +2 -0
- package/dist/js/modules/captchas/recaptcha-v2-invisible.d.ts.map +1 -0
- package/dist/js/modules/captchas/recaptcha-v3.d.ts +2 -0
- package/dist/js/modules/captchas/recaptcha-v3.d.ts.map +1 -0
- package/dist/js/modules/captchas/snaptcha.d.ts +2 -0
- package/dist/js/modules/captchas/snaptcha.d.ts.map +1 -0
- package/dist/js/modules/captchas/turnstile.d.ts +2 -0
- package/dist/js/modules/captchas/turnstile.d.ts.map +1 -0
- package/dist/js/modules/captchas/utils.d.ts +13 -0
- package/dist/js/modules/captchas/utils.d.ts.map +1 -0
- package/dist/js/modules/fields/calculations.d.ts +3 -0
- package/dist/js/modules/fields/calculations.d.ts.map +1 -0
- package/dist/js/modules/fields/checkbox-radio.d.ts +3 -0
- package/dist/js/modules/fields/checkbox-radio.d.ts.map +1 -0
- package/dist/js/modules/fields/conditions/config.d.ts +5 -0
- package/dist/js/modules/fields/conditions/config.d.ts.map +1 -0
- package/dist/js/modules/fields/conditions/effects.d.ts +2 -0
- package/dist/js/modules/fields/conditions/effects.d.ts.map +1 -0
- package/dist/js/modules/fields/conditions/evaluator.d.ts +6 -0
- package/dist/js/modules/fields/conditions/evaluator.d.ts.map +1 -0
- package/dist/js/modules/fields/conditions/references.d.ts +5 -0
- package/dist/js/modules/fields/conditions/references.d.ts.map +1 -0
- package/dist/js/modules/fields/conditions/transforms.d.ts +3 -0
- package/dist/js/modules/fields/conditions/transforms.d.ts.map +1 -0
- package/dist/js/modules/fields/conditions/types.d.ts +30 -0
- package/dist/js/modules/fields/conditions/types.d.ts.map +1 -0
- package/dist/js/modules/fields/conditions/values.d.ts +5 -0
- package/dist/js/modules/fields/conditions/values.d.ts.map +1 -0
- package/dist/js/modules/fields/conditions.d.ts +3 -0
- package/dist/js/modules/fields/conditions.d.ts.map +1 -0
- package/dist/js/modules/fields/date-picker.d.ts +3 -0
- package/dist/js/modules/fields/date-picker.d.ts.map +1 -0
- package/dist/js/modules/fields/file-upload.d.ts +3 -0
- package/dist/js/modules/fields/file-upload.d.ts.map +1 -0
- package/dist/js/modules/fields/hidden.d.ts +3 -0
- package/dist/js/modules/fields/hidden.d.ts.map +1 -0
- package/dist/js/modules/fields/index.d.ts +3 -0
- package/dist/js/modules/fields/index.d.ts.map +1 -0
- package/dist/js/modules/fields/phone-country.d.ts +3 -0
- package/dist/js/modules/fields/phone-country.d.ts.map +1 -0
- package/dist/js/modules/fields/repeater.d.ts +3 -0
- package/dist/js/modules/fields/repeater.d.ts.map +1 -0
- package/dist/js/modules/fields/rich-text.d.ts +3 -0
- package/dist/js/modules/fields/rich-text.d.ts.map +1 -0
- package/dist/js/modules/fields/shared.d.ts +20 -0
- package/dist/js/modules/fields/shared.d.ts.map +1 -0
- package/dist/js/modules/fields/signature.d.ts +3 -0
- package/dist/js/modules/fields/signature.d.ts.map +1 -0
- package/dist/js/modules/fields/summary.d.ts +3 -0
- package/dist/js/modules/fields/summary.d.ts.map +1 -0
- package/dist/js/modules/fields/table.d.ts +3 -0
- package/dist/js/modules/fields/table.d.ts.map +1 -0
- package/dist/js/modules/fields/text-limit.d.ts +3 -0
- package/dist/js/modules/fields/text-limit.d.ts.map +1 -0
- package/dist/js/modules/loader.d.ts +11 -0
- package/dist/js/modules/loader.d.ts.map +1 -0
- package/dist/js/modules/payments/api.d.ts +8 -0
- package/dist/js/modules/payments/api.d.ts.map +1 -0
- package/dist/js/modules/payments/bpoint.d.ts +2 -0
- package/dist/js/modules/payments/bpoint.d.ts.map +1 -0
- package/dist/js/modules/payments/constants.d.ts +5 -0
- package/dist/js/modules/payments/constants.d.ts.map +1 -0
- package/dist/js/modules/payments/eway.d.ts +9 -0
- package/dist/js/modules/payments/eway.d.ts.map +1 -0
- package/dist/js/modules/payments/factories.d.ts +54 -0
- package/dist/js/modules/payments/factories.d.ts.map +1 -0
- package/dist/js/modules/payments/go-cardless.d.ts +2 -0
- package/dist/js/modules/payments/go-cardless.d.ts.map +1 -0
- package/dist/js/modules/payments/host.d.ts +70 -0
- package/dist/js/modules/payments/host.d.ts.map +1 -0
- package/dist/js/modules/payments/index.d.ts +3 -0
- package/dist/js/modules/payments/index.d.ts.map +1 -0
- package/dist/js/modules/payments/mollie.d.ts +2 -0
- package/dist/js/modules/payments/mollie.d.ts.map +1 -0
- package/dist/js/modules/payments/moneris.d.ts +2 -0
- package/dist/js/modules/payments/moneris.d.ts.map +1 -0
- package/dist/js/modules/payments/opayo.d.ts +25 -0
- package/dist/js/modules/payments/opayo.d.ts.map +1 -0
- package/dist/js/modules/payments/paddle.d.ts +2 -0
- package/dist/js/modules/payments/paddle.d.ts.map +1 -0
- package/dist/js/modules/payments/paypal.d.ts +2 -0
- package/dist/js/modules/payments/paypal.d.ts.map +1 -0
- package/dist/js/modules/payments/payway.d.ts +2 -0
- package/dist/js/modules/payments/payway.d.ts.map +1 -0
- package/dist/js/modules/payments/square.d.ts +2 -0
- package/dist/js/modules/payments/square.d.ts.map +1 -0
- package/dist/js/modules/payments/stripe.d.ts +2 -0
- package/dist/js/modules/payments/stripe.d.ts.map +1 -0
- package/dist/js/modules/payments/utils.d.ts +17 -0
- package/dist/js/modules/payments/utils.d.ts.map +1 -0
- package/dist/js/modules/registry.d.ts +9 -0
- package/dist/js/modules/registry.d.ts.map +1 -0
- package/dist/js/modules/styles.d.ts +2 -0
- package/dist/js/modules/styles.d.ts.map +1 -0
- package/dist/js/submit/pipeline.d.ts +18 -0
- package/dist/js/submit/pipeline.d.ts.map +1 -0
- package/dist/js/theme/theme-classes.d.ts +10 -0
- package/dist/js/theme/theme-classes.d.ts.map +1 -0
- package/dist/js/transport/forms-api.d.ts +11 -0
- package/dist/js/transport/forms-api.d.ts.map +1 -0
- package/dist/js/utils/async.d.ts +8 -0
- package/dist/js/utils/async.d.ts.map +1 -0
- package/dist/js/utils/debug.d.ts +10 -0
- package/dist/js/utils/debug.d.ts.map +1 -0
- package/dist/js/utils/event-names.d.ts +13 -0
- package/dist/js/utils/event-names.d.ts.map +1 -0
- package/dist/js/utils/field-references.d.ts +6 -0
- package/dist/js/utils/field-references.d.ts.map +1 -0
- package/dist/js/utils/field-references.keys.d.ts +4 -0
- package/dist/js/utils/field-references.keys.d.ts.map +1 -0
- package/dist/js/utils/field-references.parser.d.ts +3 -0
- package/dist/js/utils/field-references.parser.d.ts.map +1 -0
- package/dist/js/utils/field-references.registry.d.ts +3 -0
- package/dist/js/utils/field-references.registry.d.ts.map +1 -0
- package/dist/js/utils/field-references.resolver.d.ts +4 -0
- package/dist/js/utils/field-references.resolver.d.ts.map +1 -0
- package/dist/js/utils/field-references.types.d.ts +27 -0
- package/dist/js/utils/field-references.types.d.ts.map +1 -0
- package/dist/js/utils/fields.d.ts +5 -0
- package/dist/js/utils/fields.d.ts.map +1 -0
- package/dist/js/utils/http.d.ts +9 -0
- package/dist/js/utils/http.d.ts.map +1 -0
- package/dist/js/utils/i18n.d.ts +7 -0
- package/dist/js/utils/i18n.d.ts.map +1 -0
- package/dist/js/utils/scripts.d.ts +13 -0
- package/dist/js/utils/scripts.d.ts.map +1 -0
- package/dist/js/utils/unload-warning.d.ts +10 -0
- package/dist/js/utils/unload-warning.d.ts.map +1 -0
- package/dist/js/validation/rules/email.d.ts +4 -0
- package/dist/js/validation/rules/email.d.ts.map +1 -0
- package/dist/js/validation/rules/match.d.ts +4 -0
- package/dist/js/validation/rules/match.d.ts.map +1 -0
- package/dist/js/validation/rules/number.d.ts +4 -0
- package/dist/js/validation/rules/number.d.ts.map +1 -0
- package/dist/js/validation/rules/required.d.ts +4 -0
- package/dist/js/validation/rules/required.d.ts.map +1 -0
- package/dist/js/validation/rules/shared.d.ts +7 -0
- package/dist/js/validation/rules/shared.d.ts.map +1 -0
- package/dist/js/validation/rules/url.d.ts +4 -0
- package/dist/js/validation/rules/url.d.ts.map +1 -0
- package/dist/js/validation/rules.d.ts +10 -0
- package/dist/js/validation/rules.d.ts.map +1 -0
- package/dist/js/validation/types.d.ts +44 -0
- package/dist/js/validation/types.d.ts.map +1 -0
- package/dist/js/validation/validator.d.ts +53 -0
- package/dist/js/validation/validator.d.ts.map +1 -0
- package/package.json +78 -0
- package/src/css/formie-base.css +78 -0
- package/src/css/formie-theme.css +19 -0
- package/src/css/formie.css +2 -0
- package/src/css/theme/_buttons.css +249 -0
- package/src/css/theme/_loading.css +37 -0
- package/src/css/theme/_messages.css +39 -0
- package/src/css/theme/_progress.css +62 -0
- package/src/css/theme/_tokens.css +361 -0
- package/src/css/theme/_typography.css +70 -0
- package/src/css/theme/fields/_address.css +17 -0
- package/src/css/theme/fields/_check-radio.css +108 -0
- package/src/css/theme/fields/_file.css +58 -0
- package/src/css/theme/fields/_group.css +13 -0
- package/src/css/theme/fields/_input.css +48 -0
- package/src/css/theme/fields/_nested.css +19 -0
- package/src/css/theme/fields/_repeater.css +69 -0
- package/src/css/theme/fields/_rich-text.css +201 -0
- package/src/css/theme/fields/_select.css +37 -0
- package/src/css/theme/fields/_signature.css +39 -0
- package/src/css/theme/fields/_summary.css +53 -0
- package/src/css/theme/fields/_table.css +121 -0
- package/src/css/theme/fields/_text-limit.css +10 -0
- package/src/css/theme/forms/_field.css +62 -0
- package/src/css/theme/forms/_form.css +166 -0
- package/src/css/theme/integrations/_payment-modal.css +32 -0
- package/src/css/theme/integrations/_paypal.css +10 -0
- package/src/css/theme/integrations/_payway.css +10 -0
- package/src/css/theme/integrations/_stripe.css +24 -0
- package/src/css/theme/utilities/_accessibility.css +13 -0
- package/src/css/theme-base/_controls.css +41 -0
- package/src/css/theme-base/_primitives.css +34 -0
- package/src/icons/rich-text/aligncenter.svg +6 -0
- package/src/icons/rich-text/alignleft.svg +6 -0
- package/src/icons/rich-text/alignright.svg +6 -0
- package/src/icons/rich-text/bold.svg +4 -0
- package/src/icons/rich-text/clear.svg +6 -0
- package/src/icons/rich-text/code.svg +4 -0
- package/src/icons/rich-text/heading1.svg +3 -0
- package/src/icons/rich-text/heading2.svg +3 -0
- package/src/icons/rich-text/image.svg +6 -0
- package/src/icons/rich-text/italic.svg +5 -0
- package/src/icons/rich-text/line.svg +3 -0
- package/src/icons/rich-text/link.svg +4 -0
- package/src/icons/rich-text/olist.svg +8 -0
- package/src/icons/rich-text/paragraph.svg +3 -0
- package/src/icons/rich-text/quote.svg +4 -0
- package/src/icons/rich-text/strikethrough.svg +4 -0
- package/src/icons/rich-text/ulist.svg +8 -0
- package/src/icons/rich-text/underline.svg +4 -0
- package/src/index.ts +125 -0
- package/src/js/compatibility/dom-adapter.ts +129 -0
- package/src/js/compatibility/event-map.ts +72 -0
- package/src/js/compatibility/validator-adapter.ts +105 -0
- package/src/js/contracts/client.ts +43 -0
- package/src/js/contracts/common.ts +14 -0
- package/src/js/contracts/modules.ts +53 -0
- package/src/js/contracts/schema.ts +83 -0
- package/src/js/contracts/theme.ts +1 -0
- package/src/js/core/create-formie-client.ts +1519 -0
- package/src/js/core/dom-events.ts +8 -0
- package/src/js/core/formie.ts +242 -0
- package/src/js/core/hydrate-modules.ts +102 -0
- package/src/js/core/page-client-event.ts +129 -0
- package/src/js/core/page-tab-errors.ts +37 -0
- package/src/js/core/submit-flow.ts +120 -0
- package/src/js/core/submit-result-state.ts +597 -0
- package/src/js/core/submit-result-ui.ts +448 -0
- package/src/js/events/event-bus.ts +109 -0
- package/src/js/modules/address/address-finder.ts +85 -0
- package/src/js/modules/address/api.ts +22 -0
- package/src/js/modules/address/constants.ts +15 -0
- package/src/js/modules/address/factories.ts +203 -0
- package/src/js/modules/address/google-address.ts +345 -0
- package/src/js/modules/address/host.ts +137 -0
- package/src/js/modules/address/index.ts +10 -0
- package/src/js/modules/address/loqate.ts +128 -0
- package/src/js/modules/address/place-kit.ts +94 -0
- package/src/js/modules/captchas/api.ts +25 -0
- package/src/js/modules/captchas/captcha-eu.ts +86 -0
- package/src/js/modules/captchas/constants.ts +4 -0
- package/src/js/modules/captchas/factories.ts +485 -0
- package/src/js/modules/captchas/friendly-captcha-v1.ts +65 -0
- package/src/js/modules/captchas/friendly-captcha-v2.ts +84 -0
- package/src/js/modules/captchas/hcaptcha.ts +153 -0
- package/src/js/modules/captchas/host.ts +448 -0
- package/src/js/modules/captchas/index.ts +16 -0
- package/src/js/modules/captchas/recaptcha-enterprise.ts +138 -0
- package/src/js/modules/captchas/recaptcha-shared.ts +69 -0
- package/src/js/modules/captchas/recaptcha-v2-checkbox.ts +72 -0
- package/src/js/modules/captchas/recaptcha-v2-invisible.ts +108 -0
- package/src/js/modules/captchas/recaptcha-v3.ts +62 -0
- package/src/js/modules/captchas/snaptcha.ts +10 -0
- package/src/js/modules/captchas/turnstile.ts +131 -0
- package/src/js/modules/captchas/utils.ts +85 -0
- package/src/js/modules/fields/calculations.ts +273 -0
- package/src/js/modules/fields/checkbox-radio.ts +295 -0
- package/src/js/modules/fields/conditions/config.ts +79 -0
- package/src/js/modules/fields/conditions/effects.ts +166 -0
- package/src/js/modules/fields/conditions/evaluator.ts +44 -0
- package/src/js/modules/fields/conditions/references.ts +165 -0
- package/src/js/modules/fields/conditions/transforms.ts +206 -0
- package/src/js/modules/fields/conditions/types.ts +33 -0
- package/src/js/modules/fields/conditions/values.ts +115 -0
- package/src/js/modules/fields/conditions.ts +229 -0
- package/src/js/modules/fields/date-picker.ts +272 -0
- package/src/js/modules/fields/file-upload.ts +628 -0
- package/src/js/modules/fields/hidden.ts +58 -0
- package/src/js/modules/fields/index.ts +19 -0
- package/src/js/modules/fields/phone-country.ts +226 -0
- package/src/js/modules/fields/repeater.ts +231 -0
- package/src/js/modules/fields/rich-text.ts +217 -0
- package/src/js/modules/fields/shared.ts +238 -0
- package/src/js/modules/fields/signature.ts +202 -0
- package/src/js/modules/fields/summary.ts +272 -0
- package/src/js/modules/fields/table.ts +197 -0
- package/src/js/modules/fields/text-limit.ts +280 -0
- package/src/js/modules/loader.ts +331 -0
- package/src/js/modules/payments/api.ts +20 -0
- package/src/js/modules/payments/bpoint.ts +48 -0
- package/src/js/modules/payments/constants.ts +17 -0
- package/src/js/modules/payments/eway.ts +132 -0
- package/src/js/modules/payments/factories.ts +332 -0
- package/src/js/modules/payments/go-cardless.ts +37 -0
- package/src/js/modules/payments/host.ts +459 -0
- package/src/js/modules/payments/index.ts +17 -0
- package/src/js/modules/payments/mollie.ts +38 -0
- package/src/js/modules/payments/moneris.ts +216 -0
- package/src/js/modules/payments/opayo.ts +272 -0
- package/src/js/modules/payments/paddle.ts +111 -0
- package/src/js/modules/payments/payment.ts +183 -0
- package/src/js/modules/payments/paypal.ts +214 -0
- package/src/js/modules/payments/payway.ts +114 -0
- package/src/js/modules/payments/square.ts +106 -0
- package/src/js/modules/payments/stripe.ts +426 -0
- package/src/js/modules/payments/stub-payment-module.ts +87 -0
- package/src/js/modules/payments/utils.ts +60 -0
- package/src/js/modules/registry.ts +38 -0
- package/src/js/modules/styles.ts +29 -0
- package/src/js/submit/pipeline.ts +514 -0
- package/src/js/theme/theme-classes.ts +106 -0
- package/src/js/transport/forms-api.ts +345 -0
- package/src/js/utils/async.ts +81 -0
- package/src/js/utils/debug.ts +59 -0
- package/src/js/utils/event-names.ts +60 -0
- package/src/js/utils/field-references.keys.ts +47 -0
- package/src/js/utils/field-references.parser.ts +121 -0
- package/src/js/utils/field-references.registry.ts +50 -0
- package/src/js/utils/field-references.resolver.ts +115 -0
- package/src/js/utils/field-references.ts +11 -0
- package/src/js/utils/field-references.types.ts +31 -0
- package/src/js/utils/fields.ts +58 -0
- package/src/js/utils/http.ts +51 -0
- package/src/js/utils/i18n.ts +98 -0
- package/src/js/utils/scripts.ts +84 -0
- package/src/js/utils/unload-warning.ts +190 -0
- package/src/js/validation/rules/email.ts +18 -0
- package/src/js/validation/rules/match.ts +26 -0
- package/src/js/validation/rules/minmax.ts +47 -0
- package/src/js/validation/rules/number.ts +55 -0
- package/src/js/validation/rules/pattern.ts +29 -0
- package/src/js/validation/rules/required.ts +30 -0
- package/src/js/validation/rules/shared.ts +47 -0
- package/src/js/validation/rules/url.ts +23 -0
- package/src/js/validation/rules.ts +16 -0
- package/src/js/validation/types.ts +50 -0
- package/src/js/validation/validator.ts +643 -0
- package/src/vendor.d.ts +100 -0
- package/src/vite-env.d.ts +22 -0
- package/vite-dev.mjs +22 -0
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
FormieModuleDefinition,
|
|
3
|
+
FormieModuleInstance,
|
|
4
|
+
ModuleMatchContext,
|
|
5
|
+
ModuleSetupContext,
|
|
6
|
+
} from '#contracts/modules';
|
|
7
|
+
import type { FormModuleManifest, FormModuleTarget, FormModuleTargetType } from '#contracts/schema';
|
|
8
|
+
import { builtinAddressModuleLoaders } from '#modules/address';
|
|
9
|
+
import { builtinCaptchaModuleLoaders } from '#modules/captchas';
|
|
10
|
+
import { builtinFieldModuleLoaders } from '#modules/fields';
|
|
11
|
+
import { builtinPaymentModuleLoaders } from '#modules/payments';
|
|
12
|
+
import { ModuleRegistry } from '#modules/registry';
|
|
13
|
+
import { createDebug } from '#utils/debug';
|
|
14
|
+
import {
|
|
15
|
+
getGlobalModuleLifecycleEventName,
|
|
16
|
+
getScopedModuleLifecycleEventName,
|
|
17
|
+
type ModuleLifecycleEventPhase,
|
|
18
|
+
} from '#utils/event-names';
|
|
19
|
+
|
|
20
|
+
type ModuleLoadContext = {
|
|
21
|
+
registry: ModuleRegistry;
|
|
22
|
+
setupContext: ModuleSetupContext;
|
|
23
|
+
matchContext: Omit<ModuleMatchContext, 'target' | 'scope' | 'manifestItem'>;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
type ModuleDefinitionLoader = () => Promise<FormieModuleDefinition>;
|
|
27
|
+
|
|
28
|
+
const builtinModuleLoaders: Record<string, ModuleDefinitionLoader> = {
|
|
29
|
+
...builtinFieldModuleLoaders,
|
|
30
|
+
...builtinAddressModuleLoaders,
|
|
31
|
+
...builtinCaptchaModuleLoaders,
|
|
32
|
+
...builtinPaymentModuleLoaders,
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const builtinModuleLoadCache = new Map<string, Promise<FormieModuleDefinition | null>>();
|
|
36
|
+
const debug = createDebug('general', 'loader');
|
|
37
|
+
const importModuleFromSrc = new Function('src', 'return import(src);') as (src: string) => Promise<unknown>;
|
|
38
|
+
|
|
39
|
+
async function emitModuleLifecycleEvent(
|
|
40
|
+
emit: ModuleSetupContext['emit'],
|
|
41
|
+
moduleId: string,
|
|
42
|
+
phase: ModuleLifecycleEventPhase,
|
|
43
|
+
detail: Record<string, unknown>,
|
|
44
|
+
): Promise<void> {
|
|
45
|
+
// Emit one stable global lifecycle event plus the scoped module event.
|
|
46
|
+
// Consumers can subscribe globally and filter by `detail.moduleId`, or bind
|
|
47
|
+
// directly to the scoped module id when they need a narrow hook.
|
|
48
|
+
await emit(getGlobalModuleLifecycleEventName(phase), detail);
|
|
49
|
+
await emit(getScopedModuleLifecycleEventName(moduleId, phase), detail);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function isModuleDefinition(definition: unknown): definition is FormieModuleDefinition {
|
|
53
|
+
return !!definition && typeof definition === 'object' &&
|
|
54
|
+
typeof (definition as FormieModuleDefinition).id === 'string' &&
|
|
55
|
+
typeof (definition as FormieModuleDefinition).setup === 'function' &&
|
|
56
|
+
typeof (definition as FormieModuleDefinition).match === 'function';
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async function resolveBuiltinDefinition(moduleId: string, ctx: ModuleLoadContext): Promise<FormieModuleDefinition | null> {
|
|
60
|
+
const loader = builtinModuleLoaders[moduleId];
|
|
61
|
+
|
|
62
|
+
if (!loader) {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Cache the in-flight import promise so multiple forms needing the same builtin
|
|
67
|
+
// module share one chunk fetch and one registration path.
|
|
68
|
+
if (!builtinModuleLoadCache.has(moduleId)) {
|
|
69
|
+
builtinModuleLoadCache.set(moduleId, (async() => {
|
|
70
|
+
try {
|
|
71
|
+
const definition = await loader();
|
|
72
|
+
|
|
73
|
+
if (!isModuleDefinition(definition)) {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
ctx.registry.register(definition);
|
|
78
|
+
|
|
79
|
+
return definition;
|
|
80
|
+
} catch (error) {
|
|
81
|
+
console.error('[formie] Failed to load builtin module:', moduleId, error);
|
|
82
|
+
debug.warn('Failed loading builtin module.', { moduleId, error });
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
})());
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return builtinModuleLoadCache.get(moduleId) || null;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
async function resolveDefinitionFromSrc(src: string): Promise<FormieModuleDefinition | null> {
|
|
92
|
+
try {
|
|
93
|
+
const imported = await importModuleFromSrc(src) as {
|
|
94
|
+
default?: unknown;
|
|
95
|
+
formieModule?: unknown;
|
|
96
|
+
};
|
|
97
|
+
const definition = imported?.default || imported?.formieModule || null;
|
|
98
|
+
|
|
99
|
+
if (!isModuleDefinition(definition)) {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return definition;
|
|
104
|
+
} catch (error) {
|
|
105
|
+
console.error('[formie] Failed to load module from src:', src, error);
|
|
106
|
+
debug.warn('Failed loading module from src.', { src, error });
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
async function resolveDefinition(manifestItem: FormModuleManifest, ctx: ModuleLoadContext): Promise<FormieModuleDefinition | null> {
|
|
112
|
+
const registered = ctx.registry.get(manifestItem.id);
|
|
113
|
+
|
|
114
|
+
// Resolution order is deliberate:
|
|
115
|
+
// 1) already-registered custom/client-side modules
|
|
116
|
+
// 2) first-party lazy builtin modules
|
|
117
|
+
// 3) explicit manifest src imports
|
|
118
|
+
if (registered) {
|
|
119
|
+
return registered;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const builtin = await resolveBuiltinDefinition(manifestItem.id, ctx);
|
|
123
|
+
|
|
124
|
+
if (builtin) {
|
|
125
|
+
return builtin;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (manifestItem.src) {
|
|
129
|
+
const fromSrc = await resolveDefinitionFromSrc(manifestItem.src);
|
|
130
|
+
|
|
131
|
+
if (fromSrc) {
|
|
132
|
+
ctx.registry.register(fromSrc);
|
|
133
|
+
return fromSrc;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function escapeSelectorValue(value: string): string {
|
|
141
|
+
if (typeof window.CSS?.escape === 'function') {
|
|
142
|
+
return window.CSS.escape(value);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return value.replace(/["\\]/g, '\\$&');
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function queryTargets(root: Element, selector: string): Element[] {
|
|
149
|
+
if (root.matches(selector)) {
|
|
150
|
+
return [root, ...Array.from(root.querySelectorAll(selector))];
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return Array.from(root.querySelectorAll(selector));
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function resolveTarget(target: FormModuleTarget, ctx: ModuleLoadContext): Array<{ scope: FormModuleTargetType; element: Element }> {
|
|
157
|
+
const root = ctx.setupContext.root;
|
|
158
|
+
const form = ctx.setupContext.form;
|
|
159
|
+
const scope = target.targetType;
|
|
160
|
+
const targetId = target.targetId;
|
|
161
|
+
|
|
162
|
+
// Manifest targeting is resolved centrally so module implementations receive
|
|
163
|
+
// a concrete DOM surface instead of re-querying ownership from options.
|
|
164
|
+
if (scope === 'selector') {
|
|
165
|
+
return queryTargets(root, targetId).map((element) => {
|
|
166
|
+
return { scope, element };
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (scope === 'field') {
|
|
171
|
+
return queryTargets(root, `[data-formie-field-handle="${escapeSelectorValue(targetId)}"]`).map((element) => {
|
|
172
|
+
return { scope, element };
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (scope === 'page') {
|
|
177
|
+
return queryTargets(root, `[data-formie-page-id="${escapeSelectorValue(targetId)}"]`).map((element) => {
|
|
178
|
+
return { scope, element };
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (scope === 'button') {
|
|
183
|
+
return queryTargets(root, `[data-formie-action="${escapeSelectorValue(targetId)}"]`).map((element) => {
|
|
184
|
+
return { scope, element };
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
return [{
|
|
189
|
+
scope: 'form',
|
|
190
|
+
element: form || root,
|
|
191
|
+
}];
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
function resolveTargets(item: FormModuleManifest, ctx: ModuleLoadContext): Array<{ scope: FormModuleTargetType; element: Element }> {
|
|
195
|
+
const targets: FormModuleTarget[] = item.targets && item.targets.length > 0 ? item.targets : [{
|
|
196
|
+
targetType: 'form',
|
|
197
|
+
targetId: 'form',
|
|
198
|
+
}];
|
|
199
|
+
|
|
200
|
+
return targets.flatMap((target) => {
|
|
201
|
+
return resolveTarget(target, ctx);
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
export async function loadModulesFromManifest(
|
|
206
|
+
manifest: FormModuleManifest[],
|
|
207
|
+
ctx: ModuleLoadContext,
|
|
208
|
+
): Promise<FormieModuleInstance[]> {
|
|
209
|
+
const instances: FormieModuleInstance[] = [];
|
|
210
|
+
debug.log('Loading module manifest.', {
|
|
211
|
+
manifestCount: manifest.length,
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
for (const item of manifest) {
|
|
215
|
+
const definition = await resolveDefinition(item, ctx);
|
|
216
|
+
|
|
217
|
+
if (!definition) {
|
|
218
|
+
debug.warn('Skipping manifest item (definition not resolved).', {
|
|
219
|
+
moduleId: item.id,
|
|
220
|
+
src: item.src,
|
|
221
|
+
});
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
const targets = resolveTargets(item, ctx);
|
|
226
|
+
debug.log('Resolved module targets.', {
|
|
227
|
+
moduleId: definition.id,
|
|
228
|
+
targets: item.targets || [],
|
|
229
|
+
targetCount: targets.length,
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
if (targets.length === 0 && definition.kind === 'address') {
|
|
233
|
+
console.warn(
|
|
234
|
+
`[formie] Address module "${item.id}" skipped: no target element found for ` +
|
|
235
|
+
`fieldHandle="${item.targets?.find((target) => target.targetType === 'field')?.targetId ?? '?'}". ` +
|
|
236
|
+
'Check that the Address field exists in the rendered form.',
|
|
237
|
+
);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
for (const target of targets) {
|
|
241
|
+
const matchContext: ModuleMatchContext = {
|
|
242
|
+
...ctx.matchContext,
|
|
243
|
+
target: target.element,
|
|
244
|
+
scope: target.scope,
|
|
245
|
+
manifestItem: item,
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
if (!definition.match(matchContext)) {
|
|
249
|
+
if (definition.kind === 'address') {
|
|
250
|
+
console.warn(
|
|
251
|
+
`[formie] Address module "${definition.id}" skipped: target element does not contain ` +
|
|
252
|
+
'[data-formie-address-autocomplete-input]. Enable the Auto-Complete subfield.',
|
|
253
|
+
);
|
|
254
|
+
}
|
|
255
|
+
debug.log('Module target did not match predicate.', {
|
|
256
|
+
moduleId: definition.id,
|
|
257
|
+
scope: target.scope,
|
|
258
|
+
});
|
|
259
|
+
continue;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
const options = item.config || ctx.setupContext.options;
|
|
263
|
+
const moduleEventName = definition.id;
|
|
264
|
+
const lifecycleDetail = {
|
|
265
|
+
moduleId: definition.id,
|
|
266
|
+
moduleKind: definition.kind,
|
|
267
|
+
target: target.element,
|
|
268
|
+
scope: target.scope,
|
|
269
|
+
options,
|
|
270
|
+
manifestItem: item,
|
|
271
|
+
};
|
|
272
|
+
|
|
273
|
+
await emitModuleLifecycleEvent(ctx.setupContext.emit, moduleEventName, 'before-setup', lifecycleDetail);
|
|
274
|
+
|
|
275
|
+
let instance: FormieModuleInstance | null = null;
|
|
276
|
+
|
|
277
|
+
try {
|
|
278
|
+
const setupResult = await definition.setup({
|
|
279
|
+
...ctx.setupContext,
|
|
280
|
+
target: target.element,
|
|
281
|
+
scope: target.scope,
|
|
282
|
+
options,
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
if (setupResult) {
|
|
286
|
+
instance = setupResult;
|
|
287
|
+
}
|
|
288
|
+
} catch (err) {
|
|
289
|
+
console.error(`[formie] Module "${definition.id}" setup failed:`, err);
|
|
290
|
+
debug.warn('Module setup failed.', {
|
|
291
|
+
moduleId: definition.id,
|
|
292
|
+
scope: target.scope,
|
|
293
|
+
error: err,
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
await emitModuleLifecycleEvent(ctx.setupContext.emit, moduleEventName, 'after-setup', {
|
|
298
|
+
...lifecycleDetail,
|
|
299
|
+
instanceCreated: !!instance,
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
if (instance) {
|
|
303
|
+
debug.log('Module instance created.', {
|
|
304
|
+
moduleId: definition.id,
|
|
305
|
+
scope: target.scope,
|
|
306
|
+
});
|
|
307
|
+
instances.push({
|
|
308
|
+
...instance,
|
|
309
|
+
destroy: async() => {
|
|
310
|
+
debug.log('Destroying module instance.', {
|
|
311
|
+
moduleId: definition.id,
|
|
312
|
+
scope: target.scope,
|
|
313
|
+
});
|
|
314
|
+
await emitModuleLifecycleEvent(ctx.setupContext.emit, moduleEventName, 'before-destroy', lifecycleDetail);
|
|
315
|
+
await instance.destroy();
|
|
316
|
+
await emitModuleLifecycleEvent(ctx.setupContext.emit, moduleEventName, 'after-destroy', lifecycleDetail);
|
|
317
|
+
debug.log('Module instance destroyed.', {
|
|
318
|
+
moduleId: definition.id,
|
|
319
|
+
scope: target.scope,
|
|
320
|
+
});
|
|
321
|
+
},
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
debug.log('Module manifest processing complete.', {
|
|
328
|
+
instanceCount: instances.length,
|
|
329
|
+
});
|
|
330
|
+
return instances;
|
|
331
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createManagedPaymentModule,
|
|
3
|
+
type PaymentModuleSetupContext,
|
|
4
|
+
type ManagedPaymentModuleAdapter,
|
|
5
|
+
} from '#modules/payments/factories';
|
|
6
|
+
import type {
|
|
7
|
+
PaymentHostServices,
|
|
8
|
+
PaymentModuleOptions as PaymentModuleManifestOptions,
|
|
9
|
+
} from '#modules/payments/host';
|
|
10
|
+
|
|
11
|
+
export const definePaymentModule = createManagedPaymentModule;
|
|
12
|
+
|
|
13
|
+
export type PaymentServices = PaymentHostServices;
|
|
14
|
+
export type PaymentModuleContext<TProvider extends Record<string, unknown>> = PaymentModuleSetupContext<TProvider>;
|
|
15
|
+
export type PaymentModuleOptions<TProvider extends Record<string, unknown>> = PaymentModuleManifestOptions<TProvider>;
|
|
16
|
+
export type PaymentProviderModule<
|
|
17
|
+
TProvider extends Record<string, unknown>,
|
|
18
|
+
TApi,
|
|
19
|
+
TWidget,
|
|
20
|
+
> = ManagedPaymentModuleAdapter<TProvider, TApi, TWidget>;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { definePaymentModule } from '#modules/payments/api';
|
|
2
|
+
|
|
3
|
+
type BpointCardData = {
|
|
4
|
+
cardholderName: string;
|
|
5
|
+
cardNumber: string;
|
|
6
|
+
expiryDate: string;
|
|
7
|
+
cvn: string;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export const bpointModule = definePaymentModule<Record<string, never>, null, null>({
|
|
11
|
+
id: 'bpoint',
|
|
12
|
+
defaultRequiredInputSuffixes: ['bpointToken'],
|
|
13
|
+
load: async() => {
|
|
14
|
+
return null;
|
|
15
|
+
},
|
|
16
|
+
onBeforeAuthorize: async({ field, services }) => {
|
|
17
|
+
const existingValue = (field.querySelector('input[name$="[bpointToken]"]') as HTMLInputElement | null)?.value || '';
|
|
18
|
+
if (existingValue.trim() !== '') {
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const cardholderName = field.querySelector<HTMLInputElement>('[data-bpoint-card="cardholder-name"]')?.value?.trim() || '';
|
|
23
|
+
const cardNumber = field.querySelector<HTMLInputElement>('[data-bpoint-card="card-number"]')?.value?.replace(/\s+/g, '') || '';
|
|
24
|
+
const expiryRaw = field.querySelector<HTMLInputElement>('[data-bpoint-card="expiry-date"]')?.value || '';
|
|
25
|
+
const cvn = field.querySelector<HTMLInputElement>('[data-bpoint-card="security-code"]')?.value?.trim() || '';
|
|
26
|
+
const expiryDate = (expiryRaw.match(/\d/g) || []).join('').slice(0, 4);
|
|
27
|
+
|
|
28
|
+
if (!cardNumber || expiryDate.length !== 4 || !cvn) {
|
|
29
|
+
services.addError('Please provide valid card details to continue.');
|
|
30
|
+
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const cardData: BpointCardData = {
|
|
35
|
+
cardholderName,
|
|
36
|
+
cardNumber,
|
|
37
|
+
expiryDate,
|
|
38
|
+
cvn,
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
services.updateInputs('bpointToken', JSON.stringify(cardData));
|
|
42
|
+
|
|
43
|
+
return true;
|
|
44
|
+
},
|
|
45
|
+
onAfterSubmit: async({ services }) => {
|
|
46
|
+
services.updateInputs('bpointToken', '');
|
|
47
|
+
},
|
|
48
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** Default timeout (ms) to wait for payment token inputs to populate. */
|
|
2
|
+
export const DEFAULT_WAIT_FOR_VALUE_MS = 2500;
|
|
3
|
+
|
|
4
|
+
/** Per-provider default required input name suffixes for payment tokens. */
|
|
5
|
+
export const DEFAULT_REQUIRED_INPUT_SUFFIXES: Record<string, string[]> = {
|
|
6
|
+
bpoint: ['bpointToken'],
|
|
7
|
+
stripe: ['stripePaymentIntentId'],
|
|
8
|
+
paypal: ['paypalOrderId', 'paypalAuthId'],
|
|
9
|
+
payway: ['paywayTokenId'],
|
|
10
|
+
opayo: ['opayoTokenId'],
|
|
11
|
+
eway: ['ewayTokenData'],
|
|
12
|
+
'go-cardless': ['goCardlessRedirectId'],
|
|
13
|
+
mollie: ['molliePaymentId'],
|
|
14
|
+
moneris: ['monerisTokenId'],
|
|
15
|
+
paddle: ['paddleTransactionId'],
|
|
16
|
+
square: ['squarePaymentId'],
|
|
17
|
+
};
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { definePaymentModule } from '#modules/payments/api';
|
|
2
|
+
import { waitFor } from '#utils/async';
|
|
3
|
+
import { loadScriptAndEnsureGlobal } from '#utils/scripts';
|
|
4
|
+
|
|
5
|
+
declare global {
|
|
6
|
+
interface Window {
|
|
7
|
+
eCrypt?: {
|
|
8
|
+
encryptValue(value: string, key: string): string;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
type EwayProviderOptions = {
|
|
14
|
+
cseKey?: string;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const SCRIPT_SOURCES = [
|
|
18
|
+
{
|
|
19
|
+
id: 'FORMIE_EWAY_SCRIPT_MIN',
|
|
20
|
+
src: 'https://secure.ewaypayments.com/scripts/eCrypt.min.js',
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
id: 'FORMIE_EWAY_SCRIPT',
|
|
24
|
+
src: 'https://secure.ewaypayments.com/scripts/eCrypt.js',
|
|
25
|
+
},
|
|
26
|
+
];
|
|
27
|
+
|
|
28
|
+
type EwayEncryptApi = {
|
|
29
|
+
encryptValue: (value: string, key: string) => string;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
async function ensureEwayEncryptApi(): Promise<EwayEncryptApi> {
|
|
33
|
+
let lastError: Error | null = null;
|
|
34
|
+
|
|
35
|
+
for (const source of SCRIPT_SOURCES) {
|
|
36
|
+
try {
|
|
37
|
+
await loadScriptAndEnsureGlobal<unknown>('eCrypt', {
|
|
38
|
+
id: source.id,
|
|
39
|
+
src: source.src,
|
|
40
|
+
timeoutMs: 10000,
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
const api = await waitFor<EwayEncryptApi>(() => {
|
|
44
|
+
const candidate = (window as Window).eCrypt as EwayEncryptApi | undefined;
|
|
45
|
+
|
|
46
|
+
if (candidate && typeof candidate.encryptValue === 'function') {
|
|
47
|
+
return candidate;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return null;
|
|
51
|
+
}, {
|
|
52
|
+
timeoutMs: 10000,
|
|
53
|
+
intervalMs: 50,
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
return api;
|
|
57
|
+
} catch (error) {
|
|
58
|
+
lastError = error instanceof Error ? error : new Error('Unknown eWay script load error.');
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// If a prior load inserted a stale/failed script element, remove all
|
|
62
|
+
// candidate tags so the next source can retry cleanly.
|
|
63
|
+
SCRIPT_SOURCES.forEach(({ id }) => {
|
|
64
|
+
document.getElementById(id)?.remove();
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
throw lastError || new Error('Eway encryption script failed to load.');
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export const ewayModule = definePaymentModule<EwayProviderOptions, EwayEncryptApi | null, null>({
|
|
72
|
+
id: 'eway',
|
|
73
|
+
defaultRequiredInputSuffixes: ['ewayTokenData'],
|
|
74
|
+
load: async(ctx) => {
|
|
75
|
+
const { provider } = ctx.options;
|
|
76
|
+
const cseKey = provider.cseKey as string | undefined;
|
|
77
|
+
|
|
78
|
+
if (!cseKey?.trim()) {
|
|
79
|
+
console.error('[formie] Missing cseKey for Eway.');
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return ensureEwayEncryptApi();
|
|
84
|
+
},
|
|
85
|
+
onBeforeAuthorize: async(args) => {
|
|
86
|
+
const { field, services, provider, api } = args;
|
|
87
|
+
const cseKey = provider.cseKey as string | undefined;
|
|
88
|
+
|
|
89
|
+
if (!cseKey?.trim()) {
|
|
90
|
+
services.addError('Missing cseKey for Eway.');
|
|
91
|
+
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
let eCrypt = api;
|
|
96
|
+
|
|
97
|
+
if (!eCrypt?.encryptValue) {
|
|
98
|
+
try {
|
|
99
|
+
eCrypt = await ensureEwayEncryptApi();
|
|
100
|
+
} catch (error) {
|
|
101
|
+
services.addError(error instanceof Error ? error.message : 'Eway encryption script failed to load.');
|
|
102
|
+
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const cardholderName = field.querySelector<HTMLInputElement>('[data-eway-card="cardholder-name"]')?.value ?? '';
|
|
108
|
+
const cardNumber = field.querySelector<HTMLInputElement>('[data-eway-card="card-number"]')?.value ?? '';
|
|
109
|
+
const expiryDate = field.querySelector<HTMLInputElement>('[data-eway-card="expiry-date"]')?.value ?? '';
|
|
110
|
+
const securityCode = field.querySelector<HTMLInputElement>('[data-eway-card="security-code"]')?.value ?? '';
|
|
111
|
+
|
|
112
|
+
try {
|
|
113
|
+
const cardDetails = {
|
|
114
|
+
cardholderName,
|
|
115
|
+
cardNumber: eCrypt.encryptValue(cardNumber, cseKey),
|
|
116
|
+
expiryDate,
|
|
117
|
+
securityCode: eCrypt.encryptValue(securityCode, cseKey),
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
services.updateInputs('ewayTokenData', JSON.stringify(cardDetails));
|
|
121
|
+
|
|
122
|
+
return true;
|
|
123
|
+
} catch (e) {
|
|
124
|
+
services.addError(e instanceof Error ? e.message : 'Failed to encrypt card details.');
|
|
125
|
+
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
onAfterSubmit: async({ services }) => {
|
|
130
|
+
services.updateInputs('ewayTokenData', '');
|
|
131
|
+
},
|
|
132
|
+
});
|