@10x-media/form-builder 0.1.0-beta.0 → 0.1.0-beta.10
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 +345 -0
- package/README.md +45 -1402
- package/dist/actions/body/converters.d.ts +20 -0
- package/dist/actions/body/converters.js +57 -0
- package/dist/actions/body/converters.js.map +1 -0
- package/dist/actions/body/escapeHtml.d.ts +6 -0
- package/dist/actions/body/escapeHtml.js +14 -0
- package/dist/actions/body/escapeHtml.js.map +1 -0
- package/dist/actions/body/serializeBody.d.ts +55 -0
- package/dist/actions/body/serializeBody.js +78 -0
- package/dist/actions/body/serializeBody.js.map +1 -0
- package/dist/actions/body/serializeSlate.js +31 -0
- package/dist/actions/body/serializeSlate.js.map +1 -0
- package/dist/actions/body/textOfBody.d.ts +13 -0
- package/dist/actions/body/textOfBody.js +35 -0
- package/dist/actions/body/textOfBody.js.map +1 -0
- package/dist/actions/body/wildcards.d.ts +10 -0
- package/dist/actions/body/wildcards.js +33 -0
- package/dist/actions/body/wildcards.js.map +1 -0
- package/dist/actions/buildActionBlocks.js +22 -0
- package/dist/actions/buildActionBlocks.js.map +1 -0
- package/dist/actions/builtin/confirmation.js +52 -0
- package/dist/actions/builtin/confirmation.js.map +1 -0
- package/dist/actions/builtin/emailAction.d.ts +17 -0
- package/dist/actions/builtin/emailAction.js +83 -0
- package/dist/actions/builtin/emailAction.js.map +1 -0
- package/dist/actions/builtin/emailTeam.js +22 -0
- package/dist/actions/builtin/emailTeam.js.map +1 -0
- package/dist/actions/builtin/index.d.ts +22 -0
- package/dist/actions/builtin/index.js +27 -0
- package/dist/actions/builtin/index.js.map +1 -0
- package/dist/actions/builtin/signedWebhook.js +53 -0
- package/dist/actions/builtin/signedWebhook.js.map +1 -0
- package/dist/actions/defineAction.d.ts +37 -0
- package/dist/actions/defineAction.js +6 -0
- package/dist/actions/defineAction.js.map +1 -0
- package/dist/actions/dispatch.js +49 -0
- package/dist/actions/dispatch.js.map +1 -0
- package/dist/actions/emailRecipients.d.ts +12 -0
- package/dist/actions/emailRecipients.js +116 -0
- package/dist/actions/emailRecipients.js.map +1 -0
- package/dist/actions/fromAddresses.d.ts +21 -0
- package/dist/actions/fromAddresses.js +74 -0
- package/dist/actions/fromAddresses.js.map +1 -0
- package/dist/actions/registry.d.ts +17 -0
- package/dist/actions/registry.js +12 -0
- package/dist/actions/registry.js.map +1 -0
- package/dist/actions/runActions.d.ts +9 -0
- package/dist/actions/runActions.js +43 -0
- package/dist/actions/runActions.js.map +1 -0
- package/dist/actions/sign.d.ts +7 -0
- package/dist/actions/sign.js +9 -0
- package/dist/actions/sign.js.map +1 -0
- package/dist/actions/task.js +87 -0
- package/dist/actions/task.js.map +1 -0
- package/dist/aggregation/aggregateResponses.d.ts +40 -0
- package/dist/aggregation/aggregateResponses.js +80 -0
- package/dist/aggregation/aggregateResponses.js.map +1 -0
- package/dist/aggregation/aggregateRows.d.ts +10 -0
- package/dist/aggregation/aggregateRows.js +64 -0
- package/dist/aggregation/aggregateRows.js.map +1 -0
- package/dist/aggregation/resolveResultsRequest.d.ts +61 -0
- package/dist/aggregation/resolveResultsRequest.js +113 -0
- package/dist/aggregation/resolveResultsRequest.js.map +1 -0
- package/dist/aggregation/types.d.ts +39 -0
- package/dist/calc/computeCalcFields.d.ts +15 -0
- package/dist/calc/computeCalcFields.js +28 -0
- package/dist/calc/computeCalcFields.js.map +1 -0
- package/dist/calc/evaluate.d.ts +8 -0
- package/dist/calc/evaluate.js +58 -0
- package/dist/calc/evaluate.js.map +1 -0
- package/dist/calc/normalizeCalc.d.ts +8 -0
- package/dist/calc/normalizeCalc.js +87 -0
- package/dist/calc/normalizeCalc.js.map +1 -0
- package/dist/calc/types.d.ts +34 -0
- package/dist/calc/types.js +22 -0
- package/dist/calc/types.js.map +1 -0
- package/dist/client/ByteSizeField.d.ts +29 -0
- package/dist/client/ByteSizeField.js +58 -0
- package/dist/client/ByteSizeField.js.map +1 -0
- package/dist/client/ClosePollButton.d.ts +15 -0
- package/dist/client/ClosePollButton.js +80 -0
- package/dist/client/ClosePollButton.js.map +1 -0
- package/dist/client/CondensedArray.d.ts +15 -0
- package/dist/client/CondensedArray.js +97 -0
- package/dist/client/CondensedArray.js.map +1 -0
- package/dist/client/ConditionBuilder.js +122 -0
- package/dist/client/ConditionBuilder.js.map +1 -0
- package/dist/client/ConditionRow.js +150 -0
- package/dist/client/ConditionRow.js.map +1 -0
- package/dist/client/ConsentBlockLabel.d.ts +15 -0
- package/dist/client/ConsentBlockLabel.js +71 -0
- package/dist/client/ConsentBlockLabel.js.map +1 -0
- package/dist/client/ConsentSourceRowLabel.d.ts +9 -0
- package/dist/client/ConsentSourceRowLabel.js +21 -0
- package/dist/client/ConsentSourceRowLabel.js.map +1 -0
- package/dist/client/EndpointOptionsSelect.d.ts +46 -0
- package/dist/client/EndpointOptionsSelect.js +106 -0
- package/dist/client/EndpointOptionsSelect.js.map +1 -0
- package/dist/client/FieldBlockLabel.d.ts +18 -0
- package/dist/client/FieldBlockLabel.js +34 -0
- package/dist/client/FieldBlockLabel.js.map +1 -0
- package/dist/client/FieldNameSelect.d.ts +37 -0
- package/dist/client/FieldNameSelect.js +72 -0
- package/dist/client/FieldNameSelect.js.map +1 -0
- package/dist/client/FlowBuilder.d.ts +15 -0
- package/dist/client/FlowBuilder.js +457 -0
- package/dist/client/FlowBuilder.js.map +1 -0
- package/dist/client/FormConditionField.d.ts +21 -0
- package/dist/client/FormConditionField.js +30 -0
- package/dist/client/FormConditionField.js.map +1 -0
- package/dist/client/RecipientsSelect.d.ts +31 -0
- package/dist/client/RecipientsSelect.js +174 -0
- package/dist/client/RecipientsSelect.js.map +1 -0
- package/dist/client/RuleDescription.d.ts +21 -0
- package/dist/client/RuleDescription.js +19 -0
- package/dist/client/RuleDescription.js.map +1 -0
- package/dist/client/admin.css +275 -0
- package/dist/client/endpointOptions.js +29 -0
- package/dist/client/endpointOptions.js.map +1 -0
- package/dist/client/flowAuthoring.js +142 -0
- package/dist/client/flowAuthoring.js.map +1 -0
- package/dist/client/synthesizeClientField.js +57 -0
- package/dist/client/synthesizeClientField.js.map +1 -0
- package/dist/client/toStaticLabel.js +13 -0
- package/dist/client/toStaticLabel.js.map +1 -0
- package/dist/collections/buttonFields.d.ts +34 -0
- package/dist/collections/buttonFields.js +35 -0
- package/dist/collections/buttonFields.js.map +1 -0
- package/dist/collections/cells/FieldCountCell.d.ts +15 -0
- package/dist/collections/cells/FieldCountCell.js +18 -0
- package/dist/collections/cells/FieldCountCell.js.map +1 -0
- package/dist/collections/cells/FlowStepsCell.d.ts +14 -0
- package/dist/collections/cells/FlowStepsCell.js +17 -0
- package/dist/collections/cells/FlowStepsCell.js.map +1 -0
- package/dist/collections/formSubmissions.js +204 -0
- package/dist/collections/formSubmissions.js.map +1 -0
- package/dist/collections/forms.js +482 -0
- package/dist/collections/forms.js.map +1 -0
- package/dist/collections/formsEndpoints.js +101 -0
- package/dist/collections/formsEndpoints.js.map +1 -0
- package/dist/collections/redirectFields.d.ts +29 -0
- package/dist/conditions/conditionType.js +21 -0
- package/dist/conditions/conditionType.js.map +1 -0
- package/dist/conditions/evaluate.d.ts +17 -0
- package/dist/conditions/evaluate.js +94 -0
- package/dist/conditions/evaluate.js.map +1 -0
- package/dist/conditions/fieldTypes.d.ts +11 -0
- package/dist/{fieldTypes-CzhhJXjg.js → conditions/fieldTypes.js} +6 -3
- package/dist/conditions/fieldTypes.js.map +1 -0
- package/dist/conditions/normalizeConditions.js +61 -0
- package/dist/conditions/normalizeConditions.js.map +1 -0
- package/dist/conditions/types.d.ts +8 -0
- package/dist/consent/applyConsentStatements.d.ts +14 -0
- package/dist/consent/applyConsentStatements.js +17 -0
- package/dist/consent/applyConsentStatements.js.map +1 -0
- package/dist/consent/captureConsent.d.ts +55 -0
- package/dist/consent/captureConsent.js +73 -0
- package/dist/consent/captureConsent.js.map +1 -0
- package/dist/consent/consentSourcesField.d.ts +66 -0
- package/dist/consent/consentSourcesField.js +90 -0
- package/dist/consent/consentSourcesField.js.map +1 -0
- package/dist/consent/resolveConsentEntries.d.ts +24 -0
- package/dist/consent/resolveConsentEntries.js +40 -0
- package/dist/consent/resolveConsentEntries.js.map +1 -0
- package/dist/consent/resolveConsentSourcesRequest.d.ts +37 -0
- package/dist/consent/resolveConsentSourcesRequest.js +54 -0
- package/dist/consent/resolveConsentSourcesRequest.js.map +1 -0
- package/dist/consent/resolveConsentStatements.d.ts +45 -0
- package/dist/consent/resolveConsentStatements.js +44 -0
- package/dist/consent/resolveConsentStatements.js.map +1 -0
- package/dist/consent/resolvePublishedVersionRef.d.ts +23 -0
- package/dist/consent/resolvePublishedVersionRef.js +30 -0
- package/dist/consent/resolvePublishedVersionRef.js.map +1 -0
- package/dist/consent/types.d.ts +61 -0
- package/dist/email/departments.d.ts +59 -0
- package/dist/email/departments.js +87 -0
- package/dist/email/departments.js.map +1 -0
- package/dist/email/departmentsField.d.ts +53 -0
- package/dist/email/departmentsField.js +73 -0
- package/dist/email/departmentsField.js.map +1 -0
- package/dist/events/noopSink.js +6 -0
- package/dist/events/noopSink.js.map +1 -0
- package/dist/events/resolveEventSink.js +8 -0
- package/dist/events/resolveEventSink.js.map +1 -0
- package/dist/events/types.d.ts +31 -0
- package/dist/exports/client.d.ts +15 -21
- package/dist/exports/client.js +15 -319
- package/dist/exports/i18n.d.ts +6 -138
- package/dist/exports/i18n.js +6 -3
- package/dist/exports/react.d.ts +63 -550
- package/dist/exports/react.js +55 -1563
- package/dist/exports/rsc.d.ts +9 -16
- package/dist/exports/rsc.js +9 -55
- package/dist/exports/types.d.ts +36 -5
- package/dist/fields/buildFieldBlocks.js +80 -0
- package/dist/fields/buildFieldBlocks.js.map +1 -0
- package/dist/fields/builtin/calculation.js +144 -0
- package/dist/fields/builtin/calculation.js.map +1 -0
- package/dist/fields/builtin/checkbox.js +21 -0
- package/dist/fields/builtin/checkbox.js.map +1 -0
- package/dist/fields/builtin/consent.js +47 -0
- package/dist/fields/builtin/consent.js.map +1 -0
- package/dist/fields/builtin/country.d.ts +13 -0
- package/dist/fields/builtin/country.js +30 -0
- package/dist/fields/builtin/country.js.map +1 -0
- package/dist/fields/builtin/date.js +31 -0
- package/dist/fields/builtin/date.js.map +1 -0
- package/dist/fields/builtin/email.js +18 -0
- package/dist/fields/builtin/email.js.map +1 -0
- package/dist/fields/builtin/file.d.ts +15 -0
- package/dist/fields/builtin/file.js +127 -0
- package/dist/fields/builtin/file.js.map +1 -0
- package/dist/fields/builtin/index.d.ts +26 -0
- package/dist/fields/builtin/index.js +49 -0
- package/dist/fields/builtin/index.js.map +1 -0
- package/dist/fields/builtin/message.js +30 -0
- package/dist/fields/builtin/message.js.map +1 -0
- package/dist/fields/builtin/number.js +17 -0
- package/dist/fields/builtin/number.js.map +1 -0
- package/dist/fields/builtin/repeater.js +49 -0
- package/dist/fields/builtin/repeater.js.map +1 -0
- package/dist/fields/builtin/select.js +49 -0
- package/dist/fields/builtin/select.js.map +1 -0
- package/dist/fields/builtin/state.d.ts +13 -0
- package/dist/fields/builtin/state.js +30 -0
- package/dist/fields/builtin/state.js.map +1 -0
- package/dist/fields/builtin/text.js +13 -0
- package/dist/fields/builtin/text.js.map +1 -0
- package/dist/fields/builtin/textarea.js +13 -0
- package/dist/fields/builtin/textarea.js.map +1 -0
- package/dist/fields/data/regions.d.ts +21 -0
- package/dist/fields/data/regions.js +1238 -0
- package/dist/fields/data/regions.js.map +1 -0
- package/dist/fields/defineFormField.d.ts +13 -0
- package/dist/fields/defineFormField.js +12 -0
- package/dist/fields/defineFormField.js.map +1 -0
- package/dist/fields/fieldKey.d.ts +15 -0
- package/dist/fields/fieldKey.js +16 -0
- package/dist/fields/fieldKey.js.map +1 -0
- package/dist/fields/fieldNamesOfType.js +30 -0
- package/dist/fields/fieldNamesOfType.js.map +1 -0
- package/dist/fields/instanceOptions.js +20 -0
- package/dist/fields/instanceOptions.js.map +1 -0
- package/dist/fields/localizedIf.d.ts +13 -0
- package/dist/fields/localizedIf.js +12 -0
- package/dist/fields/localizedIf.js.map +1 -0
- package/dist/fields/registry.d.ts +12 -0
- package/dist/fields/registry.js +39 -0
- package/dist/fields/registry.js.map +1 -0
- package/dist/fields/sharedConfig.js +151 -0
- package/dist/fields/sharedConfig.js.map +1 -0
- package/dist/fields/types.d.ts +152 -0
- package/dist/flow/engine.d.ts +19 -0
- package/dist/flow/engine.js +29 -0
- package/dist/flow/engine.js.map +1 -0
- package/dist/flow/normalizeFlow.js +54 -0
- package/dist/flow/normalizeFlow.js.map +1 -0
- package/dist/flow/stepLabel.js +15 -0
- package/dist/flow/stepLabel.js.map +1 -0
- package/dist/flow/types.d.ts +32 -0
- package/dist/flow/types.js +11 -0
- package/dist/flow/types.js.map +1 -0
- package/dist/form/pollState.d.ts +22 -0
- package/dist/form/pollState.js +17 -0
- package/dist/form/pollState.js.map +1 -0
- package/dist/form/toFormDocument.d.ts +102 -0
- package/dist/form/toFormDocument.js +87 -0
- package/dist/form/toFormDocument.js.map +1 -0
- package/dist/form/types.d.ts +65 -0
- package/dist/index.d.ts +88 -4
- package/dist/index.js +111 -1898
- package/dist/index.js.map +1 -1
- package/dist/options.d.ts +229 -0
- package/dist/plugin/access.js +12 -0
- package/dist/plugin/access.js.map +1 -0
- package/dist/plugin/applyRegistryConfig.d.ts +11 -0
- package/dist/plugin/applyRegistryConfig.js +20 -0
- package/dist/plugin/applyRegistryConfig.js.map +1 -0
- package/dist/plugin/collectionOverrides.d.ts +22 -0
- package/dist/plugin/customState.js +26 -0
- package/dist/plugin/customState.js.map +1 -0
- package/dist/plugin/registerCollections.js +60 -0
- package/dist/plugin/registerCollections.js.map +1 -0
- package/dist/plugin/registerTranslations.js +19 -0
- package/dist/plugin/registerTranslations.js.map +1 -0
- package/dist/plugin/uploadsCollection.d.ts +16 -0
- package/dist/plugin/uploadsCollection.js +53 -0
- package/dist/plugin/uploadsCollection.js.map +1 -0
- package/dist/poll/applyPollOptions.js +18 -0
- package/dist/poll/applyPollOptions.js.map +1 -0
- package/dist/poll/buildPollOptionSourceFields.js +50 -0
- package/dist/poll/buildPollOptionSourceFields.js.map +1 -0
- package/dist/poll/closeJob.d.ts +52 -0
- package/dist/poll/closeJob.js +119 -0
- package/dist/poll/closeJob.js.map +1 -0
- package/dist/poll/definePollOptionSource.d.ts +44 -0
- package/dist/poll/definePollOptionSource.js +6 -0
- package/dist/poll/definePollOptionSource.js.map +1 -0
- package/dist/poll/definePollType.d.ts +34 -0
- package/dist/poll/definePollType.js +6 -0
- package/dist/poll/definePollType.js.map +1 -0
- package/dist/poll/effectivePollOptions.d.ts +38 -0
- package/dist/poll/effectivePollOptions.js +64 -0
- package/dist/poll/effectivePollOptions.js.map +1 -0
- package/dist/poll/mostVoted.d.ts +21 -0
- package/dist/poll/mostVoted.js +32 -0
- package/dist/poll/mostVoted.js.map +1 -0
- package/dist/poll/outcomeBeforeChange.js +91 -0
- package/dist/poll/outcomeBeforeChange.js.map +1 -0
- package/dist/poll/outcomeFields.d.ts +38 -0
- package/dist/poll/outcomeFields.js +52 -0
- package/dist/poll/outcomeFields.js.map +1 -0
- package/dist/poll/pollTypeRegistry.d.ts +34 -0
- package/dist/poll/pollTypeRegistry.js +69 -0
- package/dist/poll/pollTypeRegistry.js.map +1 -0
- package/dist/poll/registry.d.ts +17 -0
- package/dist/poll/registry.js +12 -0
- package/dist/poll/registry.js.map +1 -0
- package/dist/poll/resolvePollCloseRequest.js +105 -0
- package/dist/poll/resolvePollCloseRequest.js.map +1 -0
- package/dist/poll/resolvePollOptions.d.ts +29 -0
- package/dist/poll/resolvePollOptions.js +52 -0
- package/dist/poll/resolvePollOptions.js.map +1 -0
- package/dist/poll/resolvePollOptionsRequest.js +50 -0
- package/dist/poll/resolvePollOptionsRequest.js.map +1 -0
- package/dist/poll/resolvePollOutcome.d.ts +34 -0
- package/dist/poll/resolvePollOutcome.js +76 -0
- package/dist/poll/resolvePollOutcome.js.map +1 -0
- package/dist/poll/resultsField.js +21 -0
- package/dist/poll/resultsField.js.map +1 -0
- package/dist/prefill/valuesFromSearchParams.d.ts +18 -0
- package/dist/prefill/valuesFromSearchParams.js +41 -0
- package/dist/prefill/valuesFromSearchParams.js.map +1 -0
- package/dist/presentations/defaults.d.ts +33 -0
- package/dist/presentations/defaults.js +35 -0
- package/dist/presentations/defaults.js.map +1 -0
- package/dist/presentations/types.d.ts +19 -0
- package/dist/react/Form.d.ts +128 -0
- package/dist/react/Form.js +619 -0
- package/dist/react/Form.js.map +1 -0
- package/dist/react/FormContext.d.ts +59 -0
- package/dist/react/FormContext.js +14 -0
- package/dist/react/FormContext.js.map +1 -0
- package/dist/react/FormControls.d.ts +55 -0
- package/dist/react/FormControls.js +56 -0
- package/dist/react/FormControls.js.map +1 -0
- package/dist/react/FormFields.d.ts +18 -0
- package/dist/react/FormFields.js +114 -0
- package/dist/react/FormFields.js.map +1 -0
- package/dist/react/FormLayout.d.ts +22 -0
- package/dist/react/FormLayout.js +15 -0
- package/dist/react/FormLayout.js.map +1 -0
- package/dist/react/FormResults.d.ts +28 -0
- package/dist/react/FormResults.js +93 -0
- package/dist/react/FormResults.js.map +1 -0
- package/dist/react/FormSteps.d.ts +17 -0
- package/dist/react/FormSteps.js +35 -0
- package/dist/react/FormSteps.js.map +1 -0
- package/dist/react/Honeypot.d.ts +22 -0
- package/dist/react/Honeypot.js +38 -0
- package/dist/react/Honeypot.js.map +1 -0
- package/dist/react/Poll.d.ts +43 -0
- package/dist/react/Poll.js +135 -0
- package/dist/react/Poll.js.map +1 -0
- package/dist/react/captcha/HcaptchaCaptcha.d.ts +28 -0
- package/dist/react/captcha/HcaptchaCaptcha.js +53 -0
- package/dist/react/captcha/HcaptchaCaptcha.js.map +1 -0
- package/dist/react/captcha/RecaptchaCaptcha.d.ts +41 -0
- package/dist/react/captcha/RecaptchaCaptcha.js +93 -0
- package/dist/react/captcha/RecaptchaCaptcha.js.map +1 -0
- package/dist/react/captcha/TurnstileCaptcha.d.ts +28 -0
- package/dist/react/captcha/TurnstileCaptcha.js +53 -0
- package/dist/react/captcha/TurnstileCaptcha.js.map +1 -0
- package/dist/react/captcha/types.d.ts +8 -0
- package/dist/react/captcha/useCaptchaScript.js +45 -0
- package/dist/react/captcha/useCaptchaScript.js.map +1 -0
- package/dist/react/captcha/vendors.js +8 -0
- package/dist/react/captcha/vendors.js.map +1 -0
- package/dist/react/cn.d.ts +6 -0
- package/dist/react/cn.js +8 -0
- package/dist/react/cn.js.map +1 -0
- package/dist/react/contract.d.ts +31 -0
- package/dist/react/contract.js +7 -0
- package/dist/react/contract.js.map +1 -0
- package/dist/react/events.js +14 -0
- package/dist/react/events.js.map +1 -0
- package/dist/react/fetchResults.d.ts +25 -0
- package/dist/react/fetchResults.js +31 -0
- package/dist/react/fetchResults.js.map +1 -0
- package/dist/react/presentation/Backdrop.d.ts +18 -0
- package/dist/react/presentation/Backdrop.js +14 -0
- package/dist/react/presentation/Backdrop.js.map +1 -0
- package/dist/react/presentation/DialogSurface.d.ts +35 -0
- package/dist/react/presentation/DialogSurface.js +53 -0
- package/dist/react/presentation/DialogSurface.js.map +1 -0
- package/dist/react/presentation/presentations.d.ts +7 -0
- package/dist/react/presentation/presentations.js +32 -0
- package/dist/react/presentation/presentations.js.map +1 -0
- package/dist/react/presentation/registry.d.ts +11 -0
- package/dist/react/presentation/registry.js +12 -0
- package/dist/react/presentation/registry.js.map +1 -0
- package/dist/react/presentation/types.d.ts +19 -0
- package/dist/react/presentation/useDismiss.d.ts +19 -0
- package/dist/react/presentation/useDismiss.js +33 -0
- package/dist/react/presentation/useDismiss.js.map +1 -0
- package/dist/react/presentation/useFocusTrap.d.ts +8 -0
- package/dist/react/presentation/useFocusTrap.js +35 -0
- package/dist/react/presentation/useFocusTrap.js.map +1 -0
- package/dist/react/presentation/useScrollLock.d.ts +6 -0
- package/dist/react/presentation/useScrollLock.js +18 -0
- package/dist/react/presentation/useScrollLock.js.map +1 -0
- package/dist/react/primitives/Checkbox.d.ts +28 -0
- package/dist/react/primitives/Checkbox.js +21 -0
- package/dist/react/primitives/Checkbox.js.map +1 -0
- package/dist/react/primitives/FieldShell.d.ts +29 -0
- package/dist/react/primitives/FieldShell.js +44 -0
- package/dist/react/primitives/FieldShell.js.map +1 -0
- package/dist/react/primitives/Input.d.ts +30 -0
- package/dist/react/primitives/Input.js +21 -0
- package/dist/react/primitives/Input.js.map +1 -0
- package/dist/react/primitives/Select.d.ts +34 -0
- package/dist/react/primitives/Select.js +26 -0
- package/dist/react/primitives/Select.js.map +1 -0
- package/dist/react/primitives/Textarea.d.ts +28 -0
- package/dist/react/primitives/Textarea.js +20 -0
- package/dist/react/primitives/Textarea.js.map +1 -0
- package/dist/react/recall.js +20 -0
- package/dist/react/recall.js.map +1 -0
- package/dist/react/registry.d.ts +16 -0
- package/dist/react/registry.js +16 -0
- package/dist/react/registry.js.map +1 -0
- package/dist/react/renderers/calculation.js +27 -0
- package/dist/react/renderers/calculation.js.map +1 -0
- package/dist/react/renderers/checkbox.js +32 -0
- package/dist/react/renderers/checkbox.js.map +1 -0
- package/dist/react/renderers/consent.js +97 -0
- package/dist/react/renderers/consent.js.map +1 -0
- package/dist/react/renderers/date.js +33 -0
- package/dist/react/renderers/date.js.map +1 -0
- package/dist/react/renderers/email.js +34 -0
- package/dist/react/renderers/email.js.map +1 -0
- package/dist/react/renderers/file.js +107 -0
- package/dist/react/renderers/file.js.map +1 -0
- package/dist/react/renderers/index.d.ts +8 -0
- package/dist/react/renderers/index.js +35 -0
- package/dist/react/renderers/index.js.map +1 -0
- package/dist/react/renderers/message.js +41 -0
- package/dist/react/renderers/message.js.map +1 -0
- package/dist/react/renderers/number.js +37 -0
- package/dist/react/renderers/number.js.map +1 -0
- package/dist/react/renderers/region.js +43 -0
- package/dist/react/renderers/region.js.map +1 -0
- package/dist/react/renderers/repeater.js +131 -0
- package/dist/react/renderers/repeater.js.map +1 -0
- package/dist/react/renderers/select.js +35 -0
- package/dist/react/renderers/select.js.map +1 -0
- package/dist/react/renderers/text.js +34 -0
- package/dist/react/renderers/text.js.map +1 -0
- package/dist/react/renderers/textarea.js +33 -0
- package/dist/react/renderers/textarea.js.map +1 -0
- package/dist/react/resolveForm.js +16 -0
- package/dist/react/resolveForm.js.map +1 -0
- package/dist/react/state.d.ts +52 -0
- package/dist/react/state.js +125 -0
- package/dist/react/state.js.map +1 -0
- package/dist/react/submitForm.d.ts +31 -0
- package/dist/react/submitForm.js +58 -0
- package/dist/react/submitForm.js.map +1 -0
- package/dist/react/uploadFile.d.ts +23 -0
- package/dist/react/uploadFile.js +39 -0
- package/dist/react/uploadFile.js.map +1 -0
- package/dist/react/useField.d.ts +13 -0
- package/dist/react/useField.js +49 -0
- package/dist/react/useField.js.map +1 -0
- package/dist/react/useFormState.d.ts +8 -0
- package/dist/react/useFormState.js +9 -0
- package/dist/react/useFormState.js.map +1 -0
- package/dist/react/useFormStep.d.ts +8 -0
- package/dist/react/useFormStep.js +9 -0
- package/dist/react/useFormStep.js.map +1 -0
- package/dist/react/validateField.js +27 -0
- package/dist/react/validateField.js.map +1 -0
- package/dist/recall/interpolate.d.ts +11 -0
- package/dist/recall/interpolate.js +17 -0
- package/dist/recall/interpolate.js.map +1 -0
- package/dist/recall/resolver.d.ts +22 -0
- package/dist/recall/resolver.js +48 -0
- package/dist/recall/resolver.js.map +1 -0
- package/dist/spam/captcha.d.ts +13 -0
- package/dist/spam/captcha.js +12 -0
- package/dist/spam/captcha.js.map +1 -0
- package/dist/spam/clientIp.js +9 -0
- package/dist/spam/clientIp.js.map +1 -0
- package/dist/spam/constants.d.ts +12 -0
- package/dist/spam/constants.js +21 -0
- package/dist/spam/constants.js.map +1 -0
- package/dist/spam/identify.d.ts +12 -0
- package/dist/spam/identify.js +17 -0
- package/dist/spam/identify.js.map +1 -0
- package/dist/spam/providers/hcaptcha.d.ts +17 -0
- package/dist/spam/providers/hcaptcha.js +18 -0
- package/dist/spam/providers/hcaptcha.js.map +1 -0
- package/dist/spam/providers/recaptcha.d.ts +23 -0
- package/dist/spam/providers/recaptcha.js +23 -0
- package/dist/spam/providers/recaptcha.js.map +1 -0
- package/dist/spam/providers/siteverify.js +34 -0
- package/dist/spam/providers/siteverify.js.map +1 -0
- package/dist/spam/providers/turnstile.d.ts +17 -0
- package/dist/spam/providers/turnstile.js +18 -0
- package/dist/spam/providers/turnstile.js.map +1 -0
- package/dist/spam/rateLimiter.d.ts +18 -0
- package/dist/spam/rateLimiter.js +41 -0
- package/dist/spam/rateLimiter.js.map +1 -0
- package/dist/spam/reserved.js +30 -0
- package/dist/spam/reserved.js.map +1 -0
- package/dist/spam/resolveSpam.d.ts +12 -0
- package/dist/spam/resolveSpam.js +43 -0
- package/dist/spam/resolveSpam.js.map +1 -0
- package/dist/spam/spamGuard.js +81 -0
- package/dist/spam/spamGuard.js.map +1 -0
- package/dist/spam/types.d.ts +88 -0
- package/dist/spam/uploadHooks.js +33 -0
- package/dist/spam/uploadHooks.js.map +1 -0
- package/dist/submissions/SubmissionAnswers.d.ts +14 -0
- package/dist/submissions/SubmissionAnswers.js +137 -0
- package/dist/submissions/SubmissionAnswers.js.map +1 -0
- package/dist/submissions/SubmissionAnswersClient.js +178 -0
- package/dist/submissions/SubmissionAnswersClient.js.map +1 -0
- package/dist/submissions/coerceBoolean.js +14 -0
- package/dist/submissions/coerceBoolean.js.map +1 -0
- package/dist/submissions/createSubmission.d.ts +36 -0
- package/dist/submissions/createSubmission.js +26 -0
- package/dist/submissions/createSubmission.js.map +1 -0
- package/dist/submissions/runSubmission.d.ts +10 -0
- package/dist/submissions/runSubmission.js +306 -0
- package/dist/submissions/runSubmission.js.map +1 -0
- package/dist/submissions/types.d.ts +41 -0
- package/dist/submissions/validateSubmission.js +110 -0
- package/dist/submissions/validateSubmission.js.map +1 -0
- package/dist/submissions/votedCookie.d.ts +13 -0
- package/dist/submissions/votedCookie.js +27 -0
- package/dist/submissions/votedCookie.js.map +1 -0
- package/dist/translations/clientRuntimeKeys.d.ts +17 -0
- package/dist/translations/clientRuntimeKeys.js +46 -0
- package/dist/translations/clientRuntimeKeys.js.map +1 -0
- package/dist/translations/de.d.ts +12 -0
- package/dist/translations/de.js +309 -0
- package/dist/translations/de.js.map +1 -0
- package/dist/translations/en.d.ts +12 -0
- package/dist/translations/en.js +309 -0
- package/dist/translations/en.js.map +1 -0
- package/dist/translations/index.d.ts +23 -0
- package/dist/translations/index.js +37 -0
- package/dist/translations/index.js.map +1 -0
- package/dist/translations/keys.d.ts +308 -0
- package/dist/translations/keys.js +308 -0
- package/dist/translations/keys.js.map +1 -0
- package/dist/translations/makeTranslate.d.ts +15 -0
- package/dist/translations/makeTranslate.js +20 -0
- package/dist/translations/makeTranslate.js.map +1 -0
- package/dist/translations/server.js +32 -0
- package/dist/translations/server.js.map +1 -0
- package/dist/translations/useTranslation.js +12 -0
- package/dist/translations/useTranslation.js.map +1 -0
- package/dist/uploads/captureFileRef.d.ts +34 -0
- package/dist/uploads/captureFileRef.js +43 -0
- package/dist/uploads/captureFileRef.js.map +1 -0
- package/dist/uploads/formatBytes.d.ts +9 -0
- package/dist/uploads/formatBytes.js +25 -0
- package/dist/uploads/formatBytes.js.map +1 -0
- package/dist/uploads/resolveFileRef.d.ts +26 -0
- package/dist/uploads/resolveFileRef.js +45 -0
- package/dist/uploads/resolveFileRef.js.map +1 -0
- package/dist/uploads/types.d.ts +19 -0
- package/dist/validation/buildRuleBlocks.js +47 -0
- package/dist/validation/buildRuleBlocks.js.map +1 -0
- package/dist/validation/builtin/email.js +20 -0
- package/dist/validation/builtin/email.js.map +1 -0
- package/dist/validation/builtin/index.d.ts +14 -0
- package/dist/validation/builtin/index.js +38 -0
- package/dist/validation/builtin/index.js.map +1 -0
- package/dist/validation/builtin/matchesField.js +16 -0
- package/dist/validation/builtin/matchesField.js.map +1 -0
- package/dist/validation/builtin/max.js +22 -0
- package/dist/validation/builtin/max.js.map +1 -0
- package/dist/validation/builtin/maxDate.js +24 -0
- package/dist/validation/builtin/maxDate.js.map +1 -0
- package/dist/validation/builtin/maxLength.js +27 -0
- package/dist/validation/builtin/maxLength.js.map +1 -0
- package/dist/validation/builtin/min.js +22 -0
- package/dist/validation/builtin/min.js.map +1 -0
- package/dist/validation/builtin/minDate.js +24 -0
- package/dist/validation/builtin/minDate.js.map +1 -0
- package/dist/validation/builtin/minLength.js +27 -0
- package/dist/validation/builtin/minLength.js.map +1 -0
- package/dist/validation/builtin/notAlreadySubmitted.js +34 -0
- package/dist/validation/builtin/notAlreadySubmitted.js.map +1 -0
- package/dist/validation/builtin/oneOf.js +35 -0
- package/dist/validation/builtin/oneOf.js.map +1 -0
- package/dist/validation/builtin/pattern.js +50 -0
- package/dist/validation/builtin/pattern.js.map +1 -0
- package/dist/validation/builtin/url.js +23 -0
- package/dist/validation/builtin/url.js.map +1 -0
- package/dist/validation/builtin/validateDateBound.js +18 -0
- package/dist/validation/builtin/validateDateBound.js.map +1 -0
- package/dist/validation/builtin/validateRegexParams.js +44 -0
- package/dist/validation/builtin/validateRegexParams.js.map +1 -0
- package/dist/validation/defineValidationRule.d.ts +12 -0
- package/dist/validation/defineValidationRule.js +11 -0
- package/dist/validation/defineValidationRule.js.map +1 -0
- package/dist/validation/emailPattern.js +10 -0
- package/dist/validation/emailPattern.js.map +1 -0
- package/dist/validation/fieldTargetParam.d.ts +22 -0
- package/dist/validation/fieldTargetParam.js +38 -0
- package/dist/validation/fieldTargetParam.js.map +1 -0
- package/dist/validation/message.js +14 -0
- package/dist/validation/message.js.map +1 -0
- package/dist/validation/registry.d.ts +11 -0
- package/dist/validation/registry.js +13 -0
- package/dist/validation/registry.js.map +1 -0
- package/dist/validation/runValidation.js +90 -0
- package/dist/validation/runValidation.js.map +1 -0
- package/dist/validation/types.d.ts +70 -0
- package/dist/validation/validateUrl.js +22 -0
- package/dist/validation/validateUrl.js.map +1 -0
- package/package.json +12 -7
- package/styles/form-builder.css +21 -11
- package/dist/constants-B-BUfetP.d.ts +0 -288
- package/dist/exports/client.js.map +0 -1
- package/dist/exports/react.js.map +0 -1
- package/dist/exports/rsc.js.map +0 -1
- package/dist/fieldTypes-B8jkNRob.d.ts +0 -188
- package/dist/fieldTypes-CzhhJXjg.js.map +0 -1
- package/dist/index-DfFYGbVF.d.ts +0 -481
- package/dist/keys-N5xGiUsh.js +0 -132
- package/dist/keys-N5xGiUsh.js.map +0 -1
- package/dist/registry-CoCyhtvB.js +0 -282
- package/dist/registry-CoCyhtvB.js.map +0 -1
- package/dist/resolver-OeQyVH2N.js +0 -665
- package/dist/resolver-OeQyVH2N.js.map +0 -1
- package/dist/translations-edMqq_2e.js +0 -152
- package/dist/translations-edMqq_2e.js.map +0 -1
- package/dist/types-DsJ_6kGJ.d.ts +0 -23
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { resolveFromAddressesRequest } from "../actions/fromAddresses.js";
|
|
2
|
+
import { resolveFormResultsRequest } from "../aggregation/resolveResultsRequest.js";
|
|
3
|
+
import { resolveConsentSourcesRequest } from "../consent/resolveConsentSourcesRequest.js";
|
|
4
|
+
import { resolveDepartmentsRequest } from "../email/departments.js";
|
|
5
|
+
import { resolvePollCloseRequest } from "../poll/resolvePollCloseRequest.js";
|
|
6
|
+
import { resolvePollOptionsRequest } from "../poll/resolvePollOptionsRequest.js";
|
|
7
|
+
//#region src/collections/formsEndpoints.ts
|
|
8
|
+
/**
|
|
9
|
+
* The forms collection's built-in endpoints: poll results/options/close, plus the optional
|
|
10
|
+
* consent-sources, from-addresses, and departments option endpoints that only exist when the
|
|
11
|
+
* matching plugin option is set. Each delegates to its request helper, which owns the auth check
|
|
12
|
+
* (anonymous callers get a 403 from the helper, not here). Extracted from `buildFormsCollection`
|
|
13
|
+
* so the collection builder stays focused on field and hook composition.
|
|
14
|
+
*/
|
|
15
|
+
const buildFormsEndpoints = ({ resultsAccess, pollResultsTypes, consentSources, fromAddresses, departments }) => [
|
|
16
|
+
{
|
|
17
|
+
path: "/:id/results",
|
|
18
|
+
method: "get",
|
|
19
|
+
handler: async (req) => {
|
|
20
|
+
const field = typeof req.query?.field === "string" ? req.query.field : void 0;
|
|
21
|
+
const { status, body } = await resolveFormResultsRequest({
|
|
22
|
+
payload: req.payload,
|
|
23
|
+
formId: req.routeParams?.id,
|
|
24
|
+
field,
|
|
25
|
+
isAuthed: Boolean(req.user),
|
|
26
|
+
req,
|
|
27
|
+
access: resultsAccess,
|
|
28
|
+
eligibleTypes: pollResultsTypes
|
|
29
|
+
});
|
|
30
|
+
return Response.json(body, { status });
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
path: "/:id/poll-options",
|
|
35
|
+
method: "get",
|
|
36
|
+
handler: async (req) => {
|
|
37
|
+
const { status, body } = await resolvePollOptionsRequest({
|
|
38
|
+
payload: req.payload,
|
|
39
|
+
formId: req.routeParams?.id,
|
|
40
|
+
isAuthed: Boolean(req.user),
|
|
41
|
+
req
|
|
42
|
+
});
|
|
43
|
+
return Response.json(body, { status });
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
path: "/:id/close",
|
|
48
|
+
method: "post",
|
|
49
|
+
handler: async (req) => {
|
|
50
|
+
const { status, body } = await resolvePollCloseRequest({
|
|
51
|
+
payload: req.payload,
|
|
52
|
+
formId: req.routeParams?.id,
|
|
53
|
+
isAuthed: Boolean(req.user),
|
|
54
|
+
req
|
|
55
|
+
});
|
|
56
|
+
return Response.json(body, { status });
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
...consentSources ? [{
|
|
60
|
+
path: "/:id/consent-sources",
|
|
61
|
+
method: "get",
|
|
62
|
+
handler: async (req) => {
|
|
63
|
+
const { status, body } = await resolveConsentSourcesRequest({
|
|
64
|
+
payload: req.payload,
|
|
65
|
+
formId: req.routeParams?.id,
|
|
66
|
+
isAuthed: Boolean(req.user),
|
|
67
|
+
req,
|
|
68
|
+
resolver: consentSources
|
|
69
|
+
});
|
|
70
|
+
return Response.json(body, { status });
|
|
71
|
+
}
|
|
72
|
+
}] : [],
|
|
73
|
+
...fromAddresses ? [{
|
|
74
|
+
path: "/:id/from-addresses",
|
|
75
|
+
method: "get",
|
|
76
|
+
handler: async (req) => {
|
|
77
|
+
const { status, body } = await resolveFromAddressesRequest({
|
|
78
|
+
isAuthed: Boolean(req.user),
|
|
79
|
+
req,
|
|
80
|
+
resolver: fromAddresses
|
|
81
|
+
});
|
|
82
|
+
return Response.json(body, { status });
|
|
83
|
+
}
|
|
84
|
+
}] : [],
|
|
85
|
+
...departments ? [{
|
|
86
|
+
path: "/:id/departments",
|
|
87
|
+
method: "get",
|
|
88
|
+
handler: async (req) => {
|
|
89
|
+
const { status, body } = await resolveDepartmentsRequest({
|
|
90
|
+
isAuthed: Boolean(req.user),
|
|
91
|
+
req,
|
|
92
|
+
resolver: departments
|
|
93
|
+
});
|
|
94
|
+
return Response.json(body, { status });
|
|
95
|
+
}
|
|
96
|
+
}] : []
|
|
97
|
+
];
|
|
98
|
+
//#endregion
|
|
99
|
+
export { buildFormsEndpoints };
|
|
100
|
+
|
|
101
|
+
//# sourceMappingURL=formsEndpoints.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formsEndpoints.js","names":[],"sources":["../../src/collections/formsEndpoints.ts"],"sourcesContent":["import type { CollectionConfig, PayloadRequest } from 'payload'\nimport { type FromAddressesResolver, resolveFromAddressesRequest } from '../actions/fromAddresses'\nimport {\n\ttype FormResultsAccess,\n\tresolveFormResultsRequest,\n} from '../aggregation/resolveResultsRequest'\nimport { resolveConsentSourcesRequest } from '../consent/resolveConsentSourcesRequest'\nimport type { ConsentSourcesResolver } from '../consent/types'\nimport { type DepartmentEmailsResolver, resolveDepartmentsRequest } from '../email/departments'\nimport { resolvePollCloseRequest } from '../poll/resolvePollCloseRequest'\nimport { resolvePollOptionsRequest } from '../poll/resolvePollOptionsRequest'\n\ntype FormsEndpointDeps = {\n\t/** Host seam gating anonymous results reads (plugin option `results.access`). */\n\tresultsAccess?: FormResultsAccess\n\t/** The poll-eligible field-type names; the `/:id/results` endpoint restricts reads to these. */\n\tpollResultsTypes: string[]\n\t/** The plugin `consent.sources` option; present registers the `/:id/consent-sources` endpoint. */\n\tconsentSources?: ConsentSourcesResolver\n\t/** The plugin `email.fromAddresses` option; present registers the `/:id/from-addresses` endpoint. */\n\tfromAddresses?: FromAddressesResolver\n\t/** The plugin `email.departments` option; present registers the `/:id/departments` endpoint. */\n\tdepartments?: DepartmentEmailsResolver\n}\n\n/**\n * The forms collection's built-in endpoints: poll results/options/close, plus the optional\n * consent-sources, from-addresses, and departments option endpoints that only exist when the\n * matching plugin option is set. Each delegates to its request helper, which owns the auth check\n * (anonymous callers get a 403 from the helper, not here). Extracted from `buildFormsCollection`\n * so the collection builder stays focused on field and hook composition.\n */\nexport const buildFormsEndpoints = ({\n\tresultsAccess,\n\tpollResultsTypes,\n\tconsentSources,\n\tfromAddresses,\n\tdepartments,\n}: FormsEndpointDeps): Exclude<CollectionConfig['endpoints'], false | undefined> => [\n\t{\n\t\tpath: '/:id/results',\n\t\tmethod: 'get',\n\t\thandler: async (req: PayloadRequest) => {\n\t\t\tconst field = typeof req.query?.field === 'string' ? req.query.field : undefined\n\t\t\tconst { status, body } = await resolveFormResultsRequest({\n\t\t\t\tpayload: req.payload,\n\t\t\t\tformId: req.routeParams?.id as number | string | undefined,\n\t\t\t\tfield,\n\t\t\t\tisAuthed: Boolean(req.user),\n\t\t\t\treq,\n\t\t\t\taccess: resultsAccess,\n\t\t\t\teligibleTypes: pollResultsTypes,\n\t\t\t})\n\t\t\treturn Response.json(body, { status })\n\t\t},\n\t},\n\t{\n\t\tpath: '/:id/poll-options',\n\t\tmethod: 'get',\n\t\thandler: async (req: PayloadRequest) => {\n\t\t\tconst { status, body } = await resolvePollOptionsRequest({\n\t\t\t\tpayload: req.payload,\n\t\t\t\tformId: req.routeParams?.id as number | string | undefined,\n\t\t\t\tisAuthed: Boolean(req.user),\n\t\t\t\treq,\n\t\t\t})\n\t\t\treturn Response.json(body, { status })\n\t\t},\n\t},\n\t// Trusted admin action (authenticated only): close a poll now and resolve its outcome. A POST\n\t// because it mutates; auth is `Boolean(req.user)` so an anonymous caller gets 403 from the helper.\n\t{\n\t\tpath: '/:id/close',\n\t\tmethod: 'post',\n\t\thandler: async (req: PayloadRequest) => {\n\t\t\tconst { status, body } = await resolvePollCloseRequest({\n\t\t\t\tpayload: req.payload,\n\t\t\t\tformId: req.routeParams?.id as number | string | undefined,\n\t\t\t\tisAuthed: Boolean(req.user),\n\t\t\t\treq,\n\t\t\t})\n\t\t\treturn Response.json(body, { status })\n\t\t},\n\t},\n\t...(consentSources\n\t\t? [\n\t\t\t\t{\n\t\t\t\t\tpath: '/:id/consent-sources',\n\t\t\t\t\tmethod: 'get' as const,\n\t\t\t\t\thandler: async (req: PayloadRequest) => {\n\t\t\t\t\t\tconst { status, body } = await resolveConsentSourcesRequest({\n\t\t\t\t\t\t\tpayload: req.payload,\n\t\t\t\t\t\t\tformId: req.routeParams?.id as number | string | undefined,\n\t\t\t\t\t\t\tisAuthed: Boolean(req.user),\n\t\t\t\t\t\t\treq,\n\t\t\t\t\t\t\tresolver: consentSources,\n\t\t\t\t\t\t})\n\t\t\t\t\t\treturn Response.json(body, { status })\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t]\n\t\t: []),\n\t// The route id is unused: the from-addresses set is request-scoped (e.g. per tenant), not\n\t// per-form. Registered as a doc-scoped route only so the admin field can reuse\n\t// EndpointOptionsSelect unmodified (see buildFromField).\n\t...(fromAddresses\n\t\t? [\n\t\t\t\t{\n\t\t\t\t\tpath: '/:id/from-addresses',\n\t\t\t\t\tmethod: 'get' as const,\n\t\t\t\t\thandler: async (req: PayloadRequest) => {\n\t\t\t\t\t\tconst { status, body } = await resolveFromAddressesRequest({\n\t\t\t\t\t\t\tisAuthed: Boolean(req.user),\n\t\t\t\t\t\t\treq,\n\t\t\t\t\t\t\tresolver: fromAddresses,\n\t\t\t\t\t\t})\n\t\t\t\t\t\treturn Response.json(body, { status })\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t]\n\t\t: []),\n\t// Same request-scoped, id-unused shape as from-addresses: registered doc-scoped only so the\n\t// recipient selects can fetch it (see RecipientsSelect / buildRecipientField).\n\t...(departments\n\t\t? [\n\t\t\t\t{\n\t\t\t\t\tpath: '/:id/departments',\n\t\t\t\t\tmethod: 'get' as const,\n\t\t\t\t\thandler: async (req: PayloadRequest) => {\n\t\t\t\t\t\tconst { status, body } = await resolveDepartmentsRequest({\n\t\t\t\t\t\t\tisAuthed: Boolean(req.user),\n\t\t\t\t\t\t\treq,\n\t\t\t\t\t\t\tresolver: departments,\n\t\t\t\t\t\t})\n\t\t\t\t\t\treturn Response.json(body, { status })\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t]\n\t\t: []),\n]\n"],"mappings":";;;;;;;;;;;;;;AAgCA,MAAa,uBAAuB,EACnC,eACA,kBACA,gBACA,eACA,kBACmF;CACnF;EACC,MAAM;EACN,QAAQ;EACR,SAAS,OAAO,QAAwB;GACvC,MAAM,QAAQ,OAAO,IAAI,OAAO,UAAU,WAAW,IAAI,MAAM,QAAQ,KAAA;GACvE,MAAM,EAAE,QAAQ,SAAS,MAAM,0BAA0B;IACxD,SAAS,IAAI;IACb,QAAQ,IAAI,aAAa;IACzB;IACA,UAAU,QAAQ,IAAI,IAAI;IAC1B;IACA,QAAQ;IACR,eAAe;GAChB,CAAC;GACD,OAAO,SAAS,KAAK,MAAM,EAAE,OAAO,CAAC;EACtC;CACD;CACA;EACC,MAAM;EACN,QAAQ;EACR,SAAS,OAAO,QAAwB;GACvC,MAAM,EAAE,QAAQ,SAAS,MAAM,0BAA0B;IACxD,SAAS,IAAI;IACb,QAAQ,IAAI,aAAa;IACzB,UAAU,QAAQ,IAAI,IAAI;IAC1B;GACD,CAAC;GACD,OAAO,SAAS,KAAK,MAAM,EAAE,OAAO,CAAC;EACtC;CACD;CAGA;EACC,MAAM;EACN,QAAQ;EACR,SAAS,OAAO,QAAwB;GACvC,MAAM,EAAE,QAAQ,SAAS,MAAM,wBAAwB;IACtD,SAAS,IAAI;IACb,QAAQ,IAAI,aAAa;IACzB,UAAU,QAAQ,IAAI,IAAI;IAC1B;GACD,CAAC;GACD,OAAO,SAAS,KAAK,MAAM,EAAE,OAAO,CAAC;EACtC;CACD;CACA,GAAI,iBACD,CACA;EACC,MAAM;EACN,QAAQ;EACR,SAAS,OAAO,QAAwB;GACvC,MAAM,EAAE,QAAQ,SAAS,MAAM,6BAA6B;IAC3D,SAAS,IAAI;IACb,QAAQ,IAAI,aAAa;IACzB,UAAU,QAAQ,IAAI,IAAI;IAC1B;IACA,UAAU;GACX,CAAC;GACD,OAAO,SAAS,KAAK,MAAM,EAAE,OAAO,CAAC;EACtC;CACD,CACD,IACC,CAAC;CAIJ,GAAI,gBACD,CACA;EACC,MAAM;EACN,QAAQ;EACR,SAAS,OAAO,QAAwB;GACvC,MAAM,EAAE,QAAQ,SAAS,MAAM,4BAA4B;IAC1D,UAAU,QAAQ,IAAI,IAAI;IAC1B;IACA,UAAU;GACX,CAAC;GACD,OAAO,SAAS,KAAK,MAAM,EAAE,OAAO,CAAC;EACtC;CACD,CACD,IACC,CAAC;CAGJ,GAAI,cACD,CACA;EACC,MAAM;EACN,QAAQ;EACR,SAAS,OAAO,QAAwB;GACvC,MAAM,EAAE,QAAQ,SAAS,MAAM,0BAA0B;IACxD,UAAU,QAAQ,IAAI,IAAI;IAC1B;IACA,UAAU;GACX,CAAC;GACD,OAAO,SAAS,KAAK,MAAM,EAAE,OAAO,CAAC;EACtC;CACD,CACD,IACC,CAAC;AACL"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Field } from "payload";
|
|
2
|
+
|
|
3
|
+
//#region src/collections/redirectFields.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Composes the fields inside the forms `response.redirect` group. Receives the default fields (the
|
|
6
|
+
* `url` text field, plus the polymorphic `reference` relationship when `redirectRelationships` is
|
|
7
|
+
* set) and returns the group's final field array verbatim, so a host can prepend a custom link
|
|
8
|
+
* field, swap `url` for their own picker, reorder, or filter. Mirrors `buttons.fields` and
|
|
9
|
+
* `poll.outcomeFields`.
|
|
10
|
+
*
|
|
11
|
+
* The plugin's built-in redirect handling reads `redirect.url` (and `redirect.reference` when
|
|
12
|
+
* configured); `toFormDocument` passes the whole `response` group through, so a host that replaces
|
|
13
|
+
* `url` with their own link field owns resolving it to a destination in their frontend, the same as
|
|
14
|
+
* the internal-reference case.
|
|
15
|
+
*/
|
|
16
|
+
type RedirectFieldsOverride = (args: {
|
|
17
|
+
defaultFields: Field[];
|
|
18
|
+
}) => Field[];
|
|
19
|
+
/** The forms `response.redirect` group options: its fields composition seam. */
|
|
20
|
+
type RedirectOption = {
|
|
21
|
+
fields?: RedirectFieldsOverride;
|
|
22
|
+
};
|
|
23
|
+
/** The plugin `response` option: currently the `redirect` group's composition seam. */
|
|
24
|
+
type ResponseOption = {
|
|
25
|
+
redirect?: RedirectOption;
|
|
26
|
+
};
|
|
27
|
+
//#endregion
|
|
28
|
+
export { RedirectFieldsOverride, RedirectOption, ResponseOption };
|
|
29
|
+
//# sourceMappingURL=redirectFields.d.ts.map
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { defaultConditionType } from "./fieldTypes.js";
|
|
2
|
+
//#region src/conditions/conditionType.ts
|
|
3
|
+
/** The condition input a field type uses in the builder: its declared `conditionType` or the value-kind default. */
|
|
4
|
+
const conditionTypeForDefinition = (definition) => definition.conditionType ?? defaultConditionType(definition.value);
|
|
5
|
+
/**
|
|
6
|
+
* A serializable slug -> condition type map for every conditionable field type, handed to the client
|
|
7
|
+
* builder. Valueless ('none' kind, display-only) types are left out so they never appear as operands;
|
|
8
|
+
* consumers treat a missing entry as "not conditionable". An explicit `conditionType` opts back in.
|
|
9
|
+
*/
|
|
10
|
+
const buildConditionTypeMap = (registry) => {
|
|
11
|
+
const map = {};
|
|
12
|
+
for (const definition of registry.values()) {
|
|
13
|
+
if (definition.value === "none" && definition.conditionType == null) continue;
|
|
14
|
+
map[definition.type] = conditionTypeForDefinition(definition);
|
|
15
|
+
}
|
|
16
|
+
return map;
|
|
17
|
+
};
|
|
18
|
+
//#endregion
|
|
19
|
+
export { buildConditionTypeMap };
|
|
20
|
+
|
|
21
|
+
//# sourceMappingURL=conditionType.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conditionType.js","names":[],"sources":["../../src/conditions/conditionType.ts"],"sourcesContent":["import type { AnyFormFieldDefinition } from '../fields/types'\nimport { type ConditionFieldType, defaultConditionType } from './fieldTypes'\n\n/** The condition input a field type uses in the builder: its declared `conditionType` or the value-kind default. */\nexport const conditionTypeForDefinition = (\n\tdefinition: Pick<AnyFormFieldDefinition, 'value' | 'conditionType'>\n): ConditionFieldType => definition.conditionType ?? defaultConditionType(definition.value)\n\n/**\n * A serializable slug -> condition type map for every conditionable field type, handed to the client\n * builder. Valueless ('none' kind, display-only) types are left out so they never appear as operands;\n * consumers treat a missing entry as \"not conditionable\". An explicit `conditionType` opts back in.\n */\nexport const buildConditionTypeMap = (\n\tregistry: Map<string, AnyFormFieldDefinition>\n): Record<string, ConditionFieldType> => {\n\tconst map: Record<string, ConditionFieldType> = {}\n\tfor (const definition of registry.values()) {\n\t\tif (definition.value === 'none' && definition.conditionType == null) {\n\t\t\tcontinue\n\t\t}\n\t\tmap[definition.type] = conditionTypeForDefinition(definition)\n\t}\n\treturn map\n}\n"],"mappings":";;;AAIA,MAAa,8BACZ,eACwB,WAAW,iBAAiB,qBAAqB,WAAW,KAAK;;;;;;AAO1F,MAAa,yBACZ,aACwC;CACxC,MAAM,MAA0C,CAAC;CACjD,KAAK,MAAM,cAAc,SAAS,OAAO,GAAG;EAC3C,IAAI,WAAW,UAAU,UAAU,WAAW,iBAAiB,MAC9D;EAED,IAAI,WAAW,QAAQ,2BAA2B,UAAU;CAC7D;CACA,OAAO;AACR"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Where } from "payload";
|
|
2
|
+
|
|
3
|
+
//#region src/conditions/evaluate.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Evaluate a serializable `Where`-shaped condition against a flat map of (already coerced) form answers.
|
|
6
|
+
* An absent or empty condition matches (returns true). Operator semantics mirror Payload's query
|
|
7
|
+
* adapters: coerce then compare; `not_equals`/`not_in` are null-inclusive; `exists` treats `''`/absent
|
|
8
|
+
* as not-existing; `like` is case-insensitive and space-splits (every word must be a substring), and
|
|
9
|
+
* `not_like` is its logical negation (at least one word absent); `contains` is a single case-insensitive
|
|
10
|
+
* substring; comma-delimited `in`/`not_in` string values are split and trimmed. Geo (`near`/`within`/
|
|
11
|
+
* `intersects`) and `all` are out of scope and evaluate to false. Isomorphic: no `req`/DB access, so the
|
|
12
|
+
* renderer reuses it client-side.
|
|
13
|
+
*/
|
|
14
|
+
declare const evaluateCondition: (where: Where | null | undefined, answers: Record<string, unknown>) => boolean;
|
|
15
|
+
//#endregion
|
|
16
|
+
export { evaluateCondition };
|
|
17
|
+
//# sourceMappingURL=evaluate.d.ts.map
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { transformWhereQuery } from "payload/shared";
|
|
2
|
+
//#region src/conditions/evaluate.ts
|
|
3
|
+
const isNil = (value) => value === null || value === void 0;
|
|
4
|
+
const toNumber = (value) => {
|
|
5
|
+
if (typeof value === "number") return Number.isFinite(value) ? value : void 0;
|
|
6
|
+
if (typeof value === "string" && value.trim() !== "") {
|
|
7
|
+
const next = Number(value);
|
|
8
|
+
return Number.isNaN(next) ? void 0 : next;
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
const toTime = (value) => {
|
|
12
|
+
if (value instanceof Date) return value.getTime();
|
|
13
|
+
if (typeof value === "string" && value.trim() !== "") {
|
|
14
|
+
const time = Date.parse(value);
|
|
15
|
+
return Number.isNaN(time) ? void 0 : time;
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
/** Strict, then numeric, then string equality, mirroring Payload's coerce-by-type-then-compare. */
|
|
19
|
+
const valuesEqual = (answer, value) => {
|
|
20
|
+
if (answer === value) return true;
|
|
21
|
+
if (isNil(answer) || isNil(value)) return false;
|
|
22
|
+
const a = toNumber(answer);
|
|
23
|
+
const b = toNumber(value);
|
|
24
|
+
if (a !== void 0 && b !== void 0) return a === b;
|
|
25
|
+
return String(answer) === String(value);
|
|
26
|
+
};
|
|
27
|
+
const toList = (value) => {
|
|
28
|
+
if (Array.isArray(value)) return value;
|
|
29
|
+
if (typeof value === "string") return value.split(",").map((entry) => entry.trim());
|
|
30
|
+
return [value];
|
|
31
|
+
};
|
|
32
|
+
const ordered = (answer, value, compare) => {
|
|
33
|
+
const a = toNumber(answer) ?? toTime(answer);
|
|
34
|
+
const b = toNumber(value) ?? toTime(value);
|
|
35
|
+
if (a === void 0 || b === void 0) return false;
|
|
36
|
+
return compare(a, b);
|
|
37
|
+
};
|
|
38
|
+
/** Case-insensitive: every space-separated word in `value` is a substring of `answer` (Payload `like`). */
|
|
39
|
+
const everyWord = (answer, value) => {
|
|
40
|
+
const haystack = String(answer).toLowerCase();
|
|
41
|
+
return String(value).toLowerCase().split(" ").filter((word) => word.length > 0).every((word) => haystack.includes(word));
|
|
42
|
+
};
|
|
43
|
+
const evaluateOperator = (operator, answer, value) => {
|
|
44
|
+
switch (operator) {
|
|
45
|
+
case "equals": return isNil(value) ? isNil(answer) : valuesEqual(answer, value);
|
|
46
|
+
case "not_equals": return isNil(value) ? !isNil(answer) : isNil(answer) || !valuesEqual(answer, value);
|
|
47
|
+
case "in": return toList(value).some((entry) => valuesEqual(answer, entry));
|
|
48
|
+
case "not_in": return isNil(answer) || !toList(value).some((entry) => valuesEqual(answer, entry));
|
|
49
|
+
case "exists": {
|
|
50
|
+
const present = !isNil(answer) && answer !== "" && !(Array.isArray(answer) && answer.length === 0);
|
|
51
|
+
return value === true || value === "true" ? present : !present;
|
|
52
|
+
}
|
|
53
|
+
case "greater_than": return ordered(answer, value, (a, b) => a > b);
|
|
54
|
+
case "greater_than_equal": return ordered(answer, value, (a, b) => a >= b);
|
|
55
|
+
case "less_than": return ordered(answer, value, (a, b) => a < b);
|
|
56
|
+
case "less_than_equal": return ordered(answer, value, (a, b) => a <= b);
|
|
57
|
+
case "like": return isNil(answer) ? false : everyWord(answer, value);
|
|
58
|
+
case "not_like": return isNil(answer) ? true : !everyWord(answer, value);
|
|
59
|
+
case "contains": return isNil(answer) ? false : String(answer).toLowerCase().includes(String(value).toLowerCase());
|
|
60
|
+
default: return false;
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Evaluate one `Where` node: every top-level key is ANDed. `or` is a disjunction of sub-conditions
|
|
65
|
+
* (an empty `or` matches), `and` is a conjunction, and any other key is a field path whose
|
|
66
|
+
* `{ operator: value }` constraints are ANDed. Recurses, so nested `or`/`and` groups are supported.
|
|
67
|
+
*/
|
|
68
|
+
const evaluateWhere = (where, answers) => Object.entries(where).every(([key, constraint]) => {
|
|
69
|
+
if (key === "or") {
|
|
70
|
+
const groups = Array.isArray(constraint) ? constraint : [];
|
|
71
|
+
return groups.length === 0 || groups.some((group) => evaluateWhere(group, answers));
|
|
72
|
+
}
|
|
73
|
+
if (key === "and") return (Array.isArray(constraint) ? constraint : []).every((group) => evaluateWhere(group, answers));
|
|
74
|
+
if (constraint == null || typeof constraint !== "object" || Array.isArray(constraint)) return false;
|
|
75
|
+
return Object.entries(constraint).every(([operator, value]) => evaluateOperator(operator, answers[key], value));
|
|
76
|
+
});
|
|
77
|
+
/**
|
|
78
|
+
* Evaluate a serializable `Where`-shaped condition against a flat map of (already coerced) form answers.
|
|
79
|
+
* An absent or empty condition matches (returns true). Operator semantics mirror Payload's query
|
|
80
|
+
* adapters: coerce then compare; `not_equals`/`not_in` are null-inclusive; `exists` treats `''`/absent
|
|
81
|
+
* as not-existing; `like` is case-insensitive and space-splits (every word must be a substring), and
|
|
82
|
+
* `not_like` is its logical negation (at least one word absent); `contains` is a single case-insensitive
|
|
83
|
+
* substring; comma-delimited `in`/`not_in` string values are split and trimmed. Geo (`near`/`within`/
|
|
84
|
+
* `intersects`) and `all` are out of scope and evaluate to false. Isomorphic: no `req`/DB access, so the
|
|
85
|
+
* renderer reuses it client-side.
|
|
86
|
+
*/
|
|
87
|
+
const evaluateCondition = (where, answers) => {
|
|
88
|
+
if (!where || Object.keys(where).length === 0) return true;
|
|
89
|
+
return evaluateWhere(transformWhereQuery(where), answers);
|
|
90
|
+
};
|
|
91
|
+
//#endregion
|
|
92
|
+
export { evaluateCondition };
|
|
93
|
+
|
|
94
|
+
//# sourceMappingURL=evaluate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evaluate.js","names":[],"sources":["../../src/conditions/evaluate.ts"],"sourcesContent":["import type { Operator, Where } from 'payload'\nimport { transformWhereQuery } from 'payload/shared'\n\nconst isNil = (value: unknown): boolean => value === null || value === undefined\n\nconst toNumber = (value: unknown): number | undefined => {\n\tif (typeof value === 'number') {\n\t\treturn Number.isFinite(value) ? value : undefined\n\t}\n\tif (typeof value === 'string' && value.trim() !== '') {\n\t\tconst next = Number(value)\n\t\treturn Number.isNaN(next) ? undefined : next\n\t}\n\treturn undefined\n}\n\nconst toTime = (value: unknown): number | undefined => {\n\tif (value instanceof Date) {\n\t\treturn value.getTime()\n\t}\n\tif (typeof value === 'string' && value.trim() !== '') {\n\t\tconst time = Date.parse(value)\n\t\treturn Number.isNaN(time) ? undefined : time\n\t}\n\treturn undefined\n}\n\n/** Strict, then numeric, then string equality, mirroring Payload's coerce-by-type-then-compare. */\nconst valuesEqual = (answer: unknown, value: unknown): boolean => {\n\tif (answer === value) {\n\t\treturn true\n\t}\n\tif (isNil(answer) || isNil(value)) {\n\t\treturn false\n\t}\n\tconst a = toNumber(answer)\n\tconst b = toNumber(value)\n\tif (a !== undefined && b !== undefined) {\n\t\treturn a === b\n\t}\n\treturn String(answer) === String(value)\n}\n\nconst toList = (value: unknown): unknown[] => {\n\tif (Array.isArray(value)) {\n\t\treturn value\n\t}\n\tif (typeof value === 'string') {\n\t\treturn value.split(',').map((entry) => entry.trim())\n\t}\n\treturn [value]\n}\n\nconst ordered = (\n\tanswer: unknown,\n\tvalue: unknown,\n\tcompare: (a: number, b: number) => boolean\n): boolean => {\n\tconst a = toNumber(answer) ?? toTime(answer)\n\tconst b = toNumber(value) ?? toTime(value)\n\tif (a === undefined || b === undefined) {\n\t\treturn false\n\t}\n\treturn compare(a, b)\n}\n\n/** Case-insensitive: every space-separated word in `value` is a substring of `answer` (Payload `like`). */\nconst everyWord = (answer: unknown, value: unknown): boolean => {\n\tconst haystack = String(answer).toLowerCase()\n\treturn String(value)\n\t\t.toLowerCase()\n\t\t.split(' ')\n\t\t.filter((word) => word.length > 0)\n\t\t.every((word) => haystack.includes(word))\n}\n\nconst evaluateOperator = (operator: Operator, answer: unknown, value: unknown): boolean => {\n\tswitch (operator) {\n\t\tcase 'equals':\n\t\t\treturn isNil(value) ? isNil(answer) : valuesEqual(answer, value)\n\t\tcase 'not_equals':\n\t\t\treturn isNil(value) ? !isNil(answer) : isNil(answer) || !valuesEqual(answer, value)\n\t\tcase 'in':\n\t\t\treturn toList(value).some((entry) => valuesEqual(answer, entry))\n\t\tcase 'not_in':\n\t\t\treturn isNil(answer) || !toList(value).some((entry) => valuesEqual(answer, entry))\n\t\tcase 'exists': {\n\t\t\t// Empty string and empty array both count as absent, so a repeater with no rows and an\n\t\t\t// unfilled text field are treated the same by a presence check.\n\t\t\tconst present =\n\t\t\t\t!isNil(answer) && answer !== '' && !(Array.isArray(answer) && answer.length === 0)\n\t\t\treturn value === true || value === 'true' ? present : !present\n\t\t}\n\t\tcase 'greater_than':\n\t\t\treturn ordered(answer, value, (a, b) => a > b)\n\t\tcase 'greater_than_equal':\n\t\t\treturn ordered(answer, value, (a, b) => a >= b)\n\t\tcase 'less_than':\n\t\t\treturn ordered(answer, value, (a, b) => a < b)\n\t\tcase 'less_than_equal':\n\t\t\treturn ordered(answer, value, (a, b) => a <= b)\n\t\tcase 'like':\n\t\t\treturn isNil(answer) ? false : everyWord(answer, value)\n\t\tcase 'not_like':\n\t\t\treturn isNil(answer) ? true : !everyWord(answer, value)\n\t\tcase 'contains':\n\t\t\treturn isNil(answer)\n\t\t\t\t? false\n\t\t\t\t: String(answer).toLowerCase().includes(String(value).toLowerCase())\n\t\tdefault:\n\t\t\treturn false\n\t}\n}\n\n/**\n * Evaluate one `Where` node: every top-level key is ANDed. `or` is a disjunction of sub-conditions\n * (an empty `or` matches), `and` is a conjunction, and any other key is a field path whose\n * `{ operator: value }` constraints are ANDed. Recurses, so nested `or`/`and` groups are supported.\n */\nconst evaluateWhere = (where: Where, answers: Record<string, unknown>): boolean =>\n\tObject.entries(where).every(([key, constraint]) => {\n\t\tif (key === 'or') {\n\t\t\tconst groups = (Array.isArray(constraint) ? constraint : []) as Where[]\n\t\t\treturn groups.length === 0 || groups.some((group) => evaluateWhere(group, answers))\n\t\t}\n\t\tif (key === 'and') {\n\t\t\tconst groups = (Array.isArray(constraint) ? constraint : []) as Where[]\n\t\t\treturn groups.every((group) => evaluateWhere(group, answers))\n\t\t}\n\t\tif (constraint == null || typeof constraint !== 'object' || Array.isArray(constraint)) {\n\t\t\treturn false\n\t\t}\n\t\treturn Object.entries(constraint as Record<string, unknown>).every(([operator, value]) =>\n\t\t\tevaluateOperator(operator as Operator, answers[key], value)\n\t\t)\n\t})\n\n/**\n * Evaluate a serializable `Where`-shaped condition against a flat map of (already coerced) form answers.\n * An absent or empty condition matches (returns true). Operator semantics mirror Payload's query\n * adapters: coerce then compare; `not_equals`/`not_in` are null-inclusive; `exists` treats `''`/absent\n * as not-existing; `like` is case-insensitive and space-splits (every word must be a substring), and\n * `not_like` is its logical negation (at least one word absent); `contains` is a single case-insensitive\n * substring; comma-delimited `in`/`not_in` string values are split and trimmed. Geo (`near`/`within`/\n * `intersects`) and `all` are out of scope and evaluate to false. Isomorphic: no `req`/DB access, so the\n * renderer reuses it client-side.\n */\nexport const evaluateCondition = (\n\twhere: Where | null | undefined,\n\tanswers: Record<string, unknown>\n): boolean => {\n\tif (!where || Object.keys(where).length === 0) {\n\t\treturn true\n\t}\n\treturn evaluateWhere(transformWhereQuery(where), answers)\n}\n"],"mappings":";;AAGA,MAAM,SAAS,UAA4B,UAAU,QAAQ,UAAU,KAAA;AAEvE,MAAM,YAAY,UAAuC;CACxD,IAAI,OAAO,UAAU,UACpB,OAAO,OAAO,SAAS,KAAK,IAAI,QAAQ,KAAA;CAEzC,IAAI,OAAO,UAAU,YAAY,MAAM,KAAK,MAAM,IAAI;EACrD,MAAM,OAAO,OAAO,KAAK;EACzB,OAAO,OAAO,MAAM,IAAI,IAAI,KAAA,IAAY;CACzC;AAED;AAEA,MAAM,UAAU,UAAuC;CACtD,IAAI,iBAAiB,MACpB,OAAO,MAAM,QAAQ;CAEtB,IAAI,OAAO,UAAU,YAAY,MAAM,KAAK,MAAM,IAAI;EACrD,MAAM,OAAO,KAAK,MAAM,KAAK;EAC7B,OAAO,OAAO,MAAM,IAAI,IAAI,KAAA,IAAY;CACzC;AAED;;AAGA,MAAM,eAAe,QAAiB,UAA4B;CACjE,IAAI,WAAW,OACd,OAAO;CAER,IAAI,MAAM,MAAM,KAAK,MAAM,KAAK,GAC/B,OAAO;CAER,MAAM,IAAI,SAAS,MAAM;CACzB,MAAM,IAAI,SAAS,KAAK;CACxB,IAAI,MAAM,KAAA,KAAa,MAAM,KAAA,GAC5B,OAAO,MAAM;CAEd,OAAO,OAAO,MAAM,MAAM,OAAO,KAAK;AACvC;AAEA,MAAM,UAAU,UAA8B;CAC7C,IAAI,MAAM,QAAQ,KAAK,GACtB,OAAO;CAER,IAAI,OAAO,UAAU,UACpB,OAAO,MAAM,MAAM,GAAG,EAAE,KAAK,UAAU,MAAM,KAAK,CAAC;CAEpD,OAAO,CAAC,KAAK;AACd;AAEA,MAAM,WACL,QACA,OACA,YACa;CACb,MAAM,IAAI,SAAS,MAAM,KAAK,OAAO,MAAM;CAC3C,MAAM,IAAI,SAAS,KAAK,KAAK,OAAO,KAAK;CACzC,IAAI,MAAM,KAAA,KAAa,MAAM,KAAA,GAC5B,OAAO;CAER,OAAO,QAAQ,GAAG,CAAC;AACpB;;AAGA,MAAM,aAAa,QAAiB,UAA4B;CAC/D,MAAM,WAAW,OAAO,MAAM,EAAE,YAAY;CAC5C,OAAO,OAAO,KAAK,EACjB,YAAY,EACZ,MAAM,GAAG,EACT,QAAQ,SAAS,KAAK,SAAS,CAAC,EAChC,OAAO,SAAS,SAAS,SAAS,IAAI,CAAC;AAC1C;AAEA,MAAM,oBAAoB,UAAoB,QAAiB,UAA4B;CAC1F,QAAQ,UAAR;EACC,KAAK,UACJ,OAAO,MAAM,KAAK,IAAI,MAAM,MAAM,IAAI,YAAY,QAAQ,KAAK;EAChE,KAAK,cACJ,OAAO,MAAM,KAAK,IAAI,CAAC,MAAM,MAAM,IAAI,MAAM,MAAM,KAAK,CAAC,YAAY,QAAQ,KAAK;EACnF,KAAK,MACJ,OAAO,OAAO,KAAK,EAAE,MAAM,UAAU,YAAY,QAAQ,KAAK,CAAC;EAChE,KAAK,UACJ,OAAO,MAAM,MAAM,KAAK,CAAC,OAAO,KAAK,EAAE,MAAM,UAAU,YAAY,QAAQ,KAAK,CAAC;EAClF,KAAK,UAAU;GAGd,MAAM,UACL,CAAC,MAAM,MAAM,KAAK,WAAW,MAAM,EAAE,MAAM,QAAQ,MAAM,KAAK,OAAO,WAAW;GACjF,OAAO,UAAU,QAAQ,UAAU,SAAS,UAAU,CAAC;EACxD;EACA,KAAK,gBACJ,OAAO,QAAQ,QAAQ,QAAQ,GAAG,MAAM,IAAI,CAAC;EAC9C,KAAK,sBACJ,OAAO,QAAQ,QAAQ,QAAQ,GAAG,MAAM,KAAK,CAAC;EAC/C,KAAK,aACJ,OAAO,QAAQ,QAAQ,QAAQ,GAAG,MAAM,IAAI,CAAC;EAC9C,KAAK,mBACJ,OAAO,QAAQ,QAAQ,QAAQ,GAAG,MAAM,KAAK,CAAC;EAC/C,KAAK,QACJ,OAAO,MAAM,MAAM,IAAI,QAAQ,UAAU,QAAQ,KAAK;EACvD,KAAK,YACJ,OAAO,MAAM,MAAM,IAAI,OAAO,CAAC,UAAU,QAAQ,KAAK;EACvD,KAAK,YACJ,OAAO,MAAM,MAAM,IAChB,QACA,OAAO,MAAM,EAAE,YAAY,EAAE,SAAS,OAAO,KAAK,EAAE,YAAY,CAAC;EACrE,SACC,OAAO;CACT;AACD;;;;;;AAOA,MAAM,iBAAiB,OAAc,YACpC,OAAO,QAAQ,KAAK,EAAE,OAAO,CAAC,KAAK,gBAAgB;CAClD,IAAI,QAAQ,MAAM;EACjB,MAAM,SAAU,MAAM,QAAQ,UAAU,IAAI,aAAa,CAAC;EAC1D,OAAO,OAAO,WAAW,KAAK,OAAO,MAAM,UAAU,cAAc,OAAO,OAAO,CAAC;CACnF;CACA,IAAI,QAAQ,OAEX,QADgB,MAAM,QAAQ,UAAU,IAAI,aAAa,CAAC,GAC5C,OAAO,UAAU,cAAc,OAAO,OAAO,CAAC;CAE7D,IAAI,cAAc,QAAQ,OAAO,eAAe,YAAY,MAAM,QAAQ,UAAU,GACnF,OAAO;CAER,OAAO,OAAO,QAAQ,UAAqC,EAAE,OAAO,CAAC,UAAU,WAC9E,iBAAiB,UAAsB,QAAQ,MAAM,KAAK,CAC3D;AACD,CAAC;;;;;;;;;;;AAYF,MAAa,qBACZ,OACA,YACa;CACb,IAAI,CAAC,SAAS,OAAO,KAAK,KAAK,EAAE,WAAW,GAC3C,OAAO;CAER,OAAO,cAAc,oBAAoB,KAAK,GAAG,OAAO;AACzD"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
//#region src/conditions/fieldTypes.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* The condition input families the builder supports. A deliberate subset of Payload's field-condition
|
|
4
|
+
* types, restricted to the operators `evaluateCondition` implements (no geo/relationship in v1).
|
|
5
|
+
* `presence` is for values that only support an existence check (a file upload, a repeater), never a
|
|
6
|
+
* scalar comparison.
|
|
7
|
+
*/
|
|
8
|
+
type ConditionFieldType = 'text' | 'number' | 'select' | 'checkbox' | 'date' | 'presence';
|
|
9
|
+
//#endregion
|
|
10
|
+
export { ConditionFieldType };
|
|
11
|
+
//# sourceMappingURL=fieldTypes.d.ts.map
|
|
@@ -37,7 +37,8 @@ const conditionOperators = {
|
|
|
37
37
|
...EQUALITY,
|
|
38
38
|
...ORDER,
|
|
39
39
|
...EXISTS
|
|
40
|
-
]
|
|
40
|
+
],
|
|
41
|
+
presence: [...EXISTS]
|
|
41
42
|
};
|
|
42
43
|
/** Default condition input for a stored value kind; a field type may override via its `conditionType`. */
|
|
43
44
|
const defaultConditionType = (value) => {
|
|
@@ -46,6 +47,8 @@ const defaultConditionType = (value) => {
|
|
|
46
47
|
case "boolean": return "checkbox";
|
|
47
48
|
case "date": return "date";
|
|
48
49
|
case "text[]": return "select";
|
|
50
|
+
case "file":
|
|
51
|
+
case "repeater": return "presence";
|
|
49
52
|
default: return "text";
|
|
50
53
|
}
|
|
51
54
|
};
|
|
@@ -83,6 +86,6 @@ const operatorValueShape = (operator) => {
|
|
|
83
86
|
return "scalar";
|
|
84
87
|
};
|
|
85
88
|
//#endregion
|
|
86
|
-
export {
|
|
89
|
+
export { conditionOperators, defaultConditionType, firstOperatorFor, operatorLabelKey, operatorValueShape };
|
|
87
90
|
|
|
88
|
-
//# sourceMappingURL=fieldTypes
|
|
91
|
+
//# sourceMappingURL=fieldTypes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fieldTypes.js","names":[],"sources":["../../src/conditions/fieldTypes.ts"],"sourcesContent":["import type { Operator } from 'payload'\nimport type { FormFieldValueKind } from '../fields/types'\n\n/**\n * The condition input families the builder supports. A deliberate subset of Payload's field-condition\n * types, restricted to the operators `evaluateCondition` implements (no geo/relationship in v1).\n * `presence` is for values that only support an existence check (a file upload, a repeater), never a\n * scalar comparison.\n */\nexport type ConditionFieldType = 'text' | 'number' | 'select' | 'checkbox' | 'date' | 'presence'\n\nconst EQUALITY: Operator[] = ['equals', 'not_equals']\nconst MEMBERSHIP: Operator[] = ['in', 'not_in']\nconst ORDER: Operator[] = ['greater_than', 'greater_than_equal', 'less_than', 'less_than_equal']\nconst TEXT_MATCH: Operator[] = ['like', 'not_like', 'contains']\nconst EXISTS: Operator[] = ['exists']\n\n/** Operators offered per condition type. Each is implemented by `evaluateCondition`. */\nexport const conditionOperators: Record<ConditionFieldType, Operator[]> = {\n\ttext: [...EQUALITY, ...MEMBERSHIP, ...TEXT_MATCH, ...EXISTS],\n\tnumber: [...EQUALITY, ...MEMBERSHIP, ...ORDER, ...EXISTS],\n\tselect: [...EQUALITY, ...MEMBERSHIP, ...EXISTS],\n\tcheckbox: [...EQUALITY, ...EXISTS],\n\tdate: [...EQUALITY, ...ORDER, ...EXISTS],\n\tpresence: [...EXISTS],\n}\n\n/** Default condition input for a stored value kind; a field type may override via its `conditionType`. */\nexport const defaultConditionType = (value: FormFieldValueKind): ConditionFieldType => {\n\tswitch (value) {\n\t\tcase 'number':\n\t\t\treturn 'number'\n\t\tcase 'boolean':\n\t\t\treturn 'checkbox'\n\t\tcase 'date':\n\t\t\treturn 'date'\n\t\tcase 'text[]':\n\t\t\treturn 'select'\n\t\tcase 'file':\n\t\tcase 'repeater':\n\t\t\t// Non-scalar values: a FileRef object or a row array cannot be compared with text/select\n\t\t\t// operators (they only stringify), so offer presence-only checks.\n\t\t\treturn 'presence'\n\t\tdefault:\n\t\t\treturn 'text'\n\t}\n}\n\n/**\n * The Payload `operators:*` i18n keys the builder uses for operator labels. A local literal union (not\n * imported from `@payloadcms/translations`, which this package never depends on); each member is a real\n * client translation key, so a value of this type is accepted by Payload's `i18n.t`.\n */\nexport type OperatorLabelKey =\n\t| 'operators:contains'\n\t| 'operators:equals'\n\t| 'operators:exists'\n\t| 'operators:isGreaterThan'\n\t| 'operators:isGreaterThanOrEqualTo'\n\t| 'operators:isIn'\n\t| 'operators:isLessThan'\n\t| 'operators:isLessThanOrEqualTo'\n\t| 'operators:isLike'\n\t| 'operators:isNotEqualTo'\n\t| 'operators:isNotIn'\n\t| 'operators:isNotLike'\n\nconst OPERATOR_LABEL_KEYS: Partial<Record<Operator, OperatorLabelKey>> = {\n\tequals: 'operators:equals',\n\tnot_equals: 'operators:isNotEqualTo',\n\tin: 'operators:isIn',\n\tnot_in: 'operators:isNotIn',\n\texists: 'operators:exists',\n\tgreater_than: 'operators:isGreaterThan',\n\tgreater_than_equal: 'operators:isGreaterThanOrEqualTo',\n\tless_than: 'operators:isLessThan',\n\tless_than_equal: 'operators:isLessThanOrEqualTo',\n\tlike: 'operators:isLike',\n\tnot_like: 'operators:isNotLike',\n\tcontains: 'operators:contains',\n}\n\n/**\n * The i18n key for an operator's label, in Payload's own `operators:*` namespace (always present in the\n * admin), so the builder reads native, localized operator labels without duplicating them in our i18n.\n * Keys mirror Payload's `WhereBuilder/field-types.tsx` operator labels. Every operator surfaced by\n * `conditionOperators` is mapped; the `operators:equals` fallback is unreachable for the offered\n * catalogs (no geo/`all` operator is ever presented) and exists only to keep the return type total.\n */\nexport const operatorLabelKey = (operator: Operator): OperatorLabelKey =>\n\tOPERATOR_LABEL_KEYS[operator] ?? 'operators:equals'\n\n/**\n * The first (default) operator a condition type offers. Every catalog leads with `equals`, so the\n * fallback is unreachable; it exists only to keep the return non-optional under `noUncheckedIndexedAccess`.\n */\nexport const firstOperatorFor = (type: ConditionFieldType): Operator =>\n\tconditionOperators[type][0] ?? 'equals'\n\n/** The value control an operator needs: a boolean toggle (`exists`), a list (`in`/`not_in`), or a scalar. */\nexport const operatorValueShape = (operator: Operator): 'boolean' | 'array' | 'scalar' => {\n\tif (operator === 'exists') {\n\t\treturn 'boolean'\n\t}\n\tif (operator === 'in' || operator === 'not_in') {\n\t\treturn 'array'\n\t}\n\treturn 'scalar'\n}\n"],"mappings":";AAWA,MAAM,WAAuB,CAAC,UAAU,YAAY;AACpD,MAAM,aAAyB,CAAC,MAAM,QAAQ;AAC9C,MAAM,QAAoB;CAAC;CAAgB;CAAsB;CAAa;AAAiB;AAC/F,MAAM,aAAyB;CAAC;CAAQ;CAAY;AAAU;AAC9D,MAAM,SAAqB,CAAC,QAAQ;;AAGpC,MAAa,qBAA6D;CACzE,MAAM;EAAC,GAAG;EAAU,GAAG;EAAY,GAAG;EAAY,GAAG;CAAM;CAC3D,QAAQ;EAAC,GAAG;EAAU,GAAG;EAAY,GAAG;EAAO,GAAG;CAAM;CACxD,QAAQ;EAAC,GAAG;EAAU,GAAG;EAAY,GAAG;CAAM;CAC9C,UAAU,CAAC,GAAG,UAAU,GAAG,MAAM;CACjC,MAAM;EAAC,GAAG;EAAU,GAAG;EAAO,GAAG;CAAM;CACvC,UAAU,CAAC,GAAG,MAAM;AACrB;;AAGA,MAAa,wBAAwB,UAAkD;CACtF,QAAQ,OAAR;EACC,KAAK,UACJ,OAAO;EACR,KAAK,WACJ,OAAO;EACR,KAAK,QACJ,OAAO;EACR,KAAK,UACJ,OAAO;EACR,KAAK;EACL,KAAK,YAGJ,OAAO;EACR,SACC,OAAO;CACT;AACD;AAqBA,MAAM,sBAAmE;CACxE,QAAQ;CACR,YAAY;CACZ,IAAI;CACJ,QAAQ;CACR,QAAQ;CACR,cAAc;CACd,oBAAoB;CACpB,WAAW;CACX,iBAAiB;CACjB,MAAM;CACN,UAAU;CACV,UAAU;AACX;;;;;;;;AASA,MAAa,oBAAoB,aAChC,oBAAoB,aAAa;;;;;AAMlC,MAAa,oBAAoB,SAChC,mBAAmB,MAAM,MAAM;;AAGhC,MAAa,sBAAsB,aAAuD;CACzF,IAAI,aAAa,UAChB,OAAO;CAER,IAAI,aAAa,QAAQ,aAAa,UACrC,OAAO;CAER,OAAO;AACR"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { conditionOperators } from "./fieldTypes.js";
|
|
2
|
+
import { transformWhereQuery } from "payload/shared";
|
|
3
|
+
//#region src/conditions/normalizeConditions.ts
|
|
4
|
+
const isValidConstraint = (constraint, operandTypes) => {
|
|
5
|
+
if (constraint == null || typeof constraint !== "object") return false;
|
|
6
|
+
const field = Object.keys(constraint)[0];
|
|
7
|
+
if (!field) return false;
|
|
8
|
+
const type = operandTypes.get(field);
|
|
9
|
+
if (!type) return false;
|
|
10
|
+
const ops = constraint[field];
|
|
11
|
+
if (ops == null || typeof ops !== "object") return false;
|
|
12
|
+
const operator = Object.keys(ops)[0];
|
|
13
|
+
return Boolean(operator && conditionOperators[type].includes(operator));
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Canonicalize a `Where` to OR-of-ANDs and strip constraints whose operand field is unknown or whose
|
|
17
|
+
* operator is invalid for that field's condition type. Returns undefined when nothing valid remains.
|
|
18
|
+
*/
|
|
19
|
+
const normalizeWhere = (raw, operandTypes) => {
|
|
20
|
+
if (raw == null || typeof raw !== "object" || Object.keys(raw).length === 0) return;
|
|
21
|
+
const canonical = transformWhereQuery(raw);
|
|
22
|
+
const groups = (Array.isArray(canonical.or) ? canonical.or : Array.isArray(canonical.and) ? [{ and: canonical.and }] : []).map((group) => {
|
|
23
|
+
return (Array.isArray(group.and) ? group.and : []).filter((constraint) => isValidConstraint(constraint, operandTypes));
|
|
24
|
+
}).filter((group) => group.length > 0);
|
|
25
|
+
return groups.length > 0 ? { or: groups.map((and) => ({ and })) } : void 0;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Normalize every field's `visibleWhen`/`validateWhen` against the form's own field list. Canonicalizes
|
|
29
|
+
* to OR-of-ANDs and strips constraints whose operand field is missing or whose operator is invalid for
|
|
30
|
+
* that field's condition type, so stored conditions always match what `evaluateCondition` can run.
|
|
31
|
+
*/
|
|
32
|
+
/**
|
|
33
|
+
* The operand-name -> condition-type map for a form's fields. A field is a valid condition operand
|
|
34
|
+
* only when it has a name and its block type has a condition type (display-only types are excluded),
|
|
35
|
+
* so a constraint referencing anything else is stripped, matching the client operand list.
|
|
36
|
+
*/
|
|
37
|
+
const buildOperandTypes = (fields, conditionTypes) => {
|
|
38
|
+
const operandTypes = /* @__PURE__ */ new Map();
|
|
39
|
+
for (const row of fields) {
|
|
40
|
+
const name = typeof row.name === "string" ? row.name.trim() : "";
|
|
41
|
+
const conditionType = conditionTypes[row.blockType];
|
|
42
|
+
if (name.length > 0 && conditionType) operandTypes.set(name, conditionType);
|
|
43
|
+
}
|
|
44
|
+
return operandTypes;
|
|
45
|
+
};
|
|
46
|
+
const normalizeFormConditions = (fields, conditionTypes) => {
|
|
47
|
+
const operandTypes = buildOperandTypes(fields, conditionTypes);
|
|
48
|
+
return fields.map((row) => {
|
|
49
|
+
const visibleWhen = normalizeWhere(row.visibleWhen, operandTypes);
|
|
50
|
+
const validateWhen = normalizeWhere(row.validateWhen, operandTypes);
|
|
51
|
+
return {
|
|
52
|
+
...row,
|
|
53
|
+
visibleWhen,
|
|
54
|
+
validateWhen
|
|
55
|
+
};
|
|
56
|
+
});
|
|
57
|
+
};
|
|
58
|
+
//#endregion
|
|
59
|
+
export { buildOperandTypes, normalizeFormConditions, normalizeWhere };
|
|
60
|
+
|
|
61
|
+
//# sourceMappingURL=normalizeConditions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalizeConditions.js","names":[],"sources":["../../src/conditions/normalizeConditions.ts"],"sourcesContent":["import type { Where } from 'payload'\nimport { transformWhereQuery } from 'payload/shared'\nimport type { ConditionFieldType } from './fieldTypes'\nimport { conditionOperators } from './fieldTypes'\n\nexport type FieldRow = {\n\tblockType: string\n\tname?: string\n\tvisibleWhen?: unknown\n\tvalidateWhen?: unknown\n\t[key: string]: unknown\n}\n\nconst isValidConstraint = (\n\tconstraint: unknown,\n\toperandTypes: Map<string, ConditionFieldType>\n): boolean => {\n\tif (constraint == null || typeof constraint !== 'object') {\n\t\treturn false\n\t}\n\tconst field = Object.keys(constraint as object)[0]\n\tif (!field) {\n\t\treturn false\n\t}\n\tconst type = operandTypes.get(field)\n\tif (!type) {\n\t\treturn false\n\t}\n\tconst ops = (constraint as Record<string, unknown>)[field]\n\tif (ops == null || typeof ops !== 'object') {\n\t\treturn false\n\t}\n\tconst operator = Object.keys(ops as object)[0]\n\treturn Boolean(operator && (conditionOperators[type] as readonly string[]).includes(operator))\n}\n\n/**\n * Canonicalize a `Where` to OR-of-ANDs and strip constraints whose operand field is unknown or whose\n * operator is invalid for that field's condition type. Returns undefined when nothing valid remains.\n */\nexport const normalizeWhere = (\n\traw: unknown,\n\toperandTypes: Map<string, ConditionFieldType>\n): Where | undefined => {\n\tif (raw == null || typeof raw !== 'object' || Object.keys(raw as object).length === 0) {\n\t\treturn undefined\n\t}\n\tconst canonical = transformWhereQuery(raw as Where)\n\tconst or = Array.isArray(canonical.or)\n\t\t? canonical.or\n\t\t: Array.isArray(canonical.and)\n\t\t\t? [{ and: canonical.and }]\n\t\t\t: []\n\tconst groups = or\n\t\t.map((group) => {\n\t\t\tconst and = Array.isArray((group as Where).and) ? ((group as Where).and as unknown[]) : []\n\t\t\treturn and.filter((constraint) => isValidConstraint(constraint, operandTypes))\n\t\t})\n\t\t.filter((group) => group.length > 0)\n\treturn groups.length > 0 ? ({ or: groups.map((and) => ({ and })) } as Where) : undefined\n}\n\n/**\n * Normalize every field's `visibleWhen`/`validateWhen` against the form's own field list. Canonicalizes\n * to OR-of-ANDs and strips constraints whose operand field is missing or whose operator is invalid for\n * that field's condition type, so stored conditions always match what `evaluateCondition` can run.\n */\n/**\n * The operand-name -> condition-type map for a form's fields. A field is a valid condition operand\n * only when it has a name and its block type has a condition type (display-only types are excluded),\n * so a constraint referencing anything else is stripped, matching the client operand list.\n */\nexport const buildOperandTypes = (\n\tfields: FieldRow[],\n\tconditionTypes: Record<string, ConditionFieldType>\n): Map<string, ConditionFieldType> => {\n\tconst operandTypes = new Map<string, ConditionFieldType>()\n\tfor (const row of fields) {\n\t\tconst name = typeof row.name === 'string' ? row.name.trim() : ''\n\t\tconst conditionType = conditionTypes[row.blockType]\n\t\tif (name.length > 0 && conditionType) {\n\t\t\toperandTypes.set(name, conditionType)\n\t\t}\n\t}\n\treturn operandTypes\n}\n\nexport const normalizeFormConditions = (\n\tfields: FieldRow[],\n\tconditionTypes: Record<string, ConditionFieldType>\n): FieldRow[] => {\n\tconst operandTypes = buildOperandTypes(fields, conditionTypes)\n\treturn fields.map((row) => {\n\t\tconst visibleWhen = normalizeWhere(row.visibleWhen, operandTypes)\n\t\tconst validateWhen = normalizeWhere(row.validateWhen, operandTypes)\n\t\treturn { ...row, visibleWhen, validateWhen }\n\t})\n}\n"],"mappings":";;;AAaA,MAAM,qBACL,YACA,iBACa;CACb,IAAI,cAAc,QAAQ,OAAO,eAAe,UAC/C,OAAO;CAER,MAAM,QAAQ,OAAO,KAAK,UAAoB,EAAE;CAChD,IAAI,CAAC,OACJ,OAAO;CAER,MAAM,OAAO,aAAa,IAAI,KAAK;CACnC,IAAI,CAAC,MACJ,OAAO;CAER,MAAM,MAAO,WAAuC;CACpD,IAAI,OAAO,QAAQ,OAAO,QAAQ,UACjC,OAAO;CAER,MAAM,WAAW,OAAO,KAAK,GAAa,EAAE;CAC5C,OAAO,QAAQ,YAAa,mBAAmB,MAA4B,SAAS,QAAQ,CAAC;AAC9F;;;;;AAMA,MAAa,kBACZ,KACA,iBACuB;CACvB,IAAI,OAAO,QAAQ,OAAO,QAAQ,YAAY,OAAO,KAAK,GAAa,EAAE,WAAW,GACnF;CAED,MAAM,YAAY,oBAAoB,GAAY;CAMlD,MAAM,UALK,MAAM,QAAQ,UAAU,EAAE,IAClC,UAAU,KACV,MAAM,QAAQ,UAAU,GAAG,IAC1B,CAAC,EAAE,KAAK,UAAU,IAAI,CAAC,IACvB,CAAC,GAEH,KAAK,UAAU;EAEf,QADY,MAAM,QAAS,MAAgB,GAAG,IAAM,MAAgB,MAAoB,CAAC,GAC9E,QAAQ,eAAe,kBAAkB,YAAY,YAAY,CAAC;CAC9E,CAAC,EACA,QAAQ,UAAU,MAAM,SAAS,CAAC;CACpC,OAAO,OAAO,SAAS,IAAK,EAAE,IAAI,OAAO,KAAK,SAAS,EAAE,IAAI,EAAE,EAAE,IAAc,KAAA;AAChF;;;;;;;;;;;AAYA,MAAa,qBACZ,QACA,mBACqC;CACrC,MAAM,+BAAe,IAAI,IAAgC;CACzD,KAAK,MAAM,OAAO,QAAQ;EACzB,MAAM,OAAO,OAAO,IAAI,SAAS,WAAW,IAAI,KAAK,KAAK,IAAI;EAC9D,MAAM,gBAAgB,eAAe,IAAI;EACzC,IAAI,KAAK,SAAS,KAAK,eACtB,aAAa,IAAI,MAAM,aAAa;CAEtC;CACA,OAAO;AACR;AAEA,MAAa,2BACZ,QACA,mBACgB;CAChB,MAAM,eAAe,kBAAkB,QAAQ,cAAc;CAC7D,OAAO,OAAO,KAAK,QAAQ;EAC1B,MAAM,cAAc,eAAe,IAAI,aAAa,YAAY;EAChE,MAAM,eAAe,eAAe,IAAI,cAAc,YAAY;EAClE,OAAO;GAAE,GAAG;GAAK;GAAa;EAAa;CAC5C,CAAC;AACF"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Where as Where$1 } from "payload";
|
|
2
|
+
|
|
3
|
+
//#region src/conditions/types.d.ts
|
|
4
|
+
/** A serializable field-visibility/validation condition, stored in Payload's canonical `Where` shape. */
|
|
5
|
+
type FieldCondition = Where$1;
|
|
6
|
+
//#endregion
|
|
7
|
+
export { FieldCondition };
|
|
8
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ConsentStatements } from "./resolveConsentStatements.js";
|
|
2
|
+
|
|
3
|
+
//#region src/consent/applyConsentStatements.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Merge server-resolved statements onto the consent field instances they belong to, keyed by field
|
|
6
|
+
* name, without mutating the input. A field with no resolved statement (no source picked, or a key
|
|
7
|
+
* the host's sources no longer carry) is left untouched and renders without one.
|
|
8
|
+
*/
|
|
9
|
+
declare const applyConsentStatements: <T extends {
|
|
10
|
+
name?: string;
|
|
11
|
+
}>(fields: T[], statements: ConsentStatements) => T[];
|
|
12
|
+
//#endregion
|
|
13
|
+
export { applyConsentStatements };
|
|
14
|
+
//# sourceMappingURL=applyConsentStatements.d.ts.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
//#region src/consent/applyConsentStatements.ts
|
|
2
|
+
/**
|
|
3
|
+
* Merge server-resolved statements onto the consent field instances they belong to, keyed by field
|
|
4
|
+
* name, without mutating the input. A field with no resolved statement (no source picked, or a key
|
|
5
|
+
* the host's sources no longer carry) is left untouched and renders without one.
|
|
6
|
+
*/
|
|
7
|
+
const applyConsentStatements = (fields, statements) => fields.map((instance) => {
|
|
8
|
+
const resolved = instance.name ? statements[instance.name] : void 0;
|
|
9
|
+
return resolved ? {
|
|
10
|
+
...instance,
|
|
11
|
+
...resolved
|
|
12
|
+
} : instance;
|
|
13
|
+
});
|
|
14
|
+
//#endregion
|
|
15
|
+
export { applyConsentStatements };
|
|
16
|
+
|
|
17
|
+
//# sourceMappingURL=applyConsentStatements.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"applyConsentStatements.js","names":[],"sources":["../../src/consent/applyConsentStatements.ts"],"sourcesContent":["import type { ConsentStatements } from './resolveConsentStatements'\n\n/**\n * Merge server-resolved statements onto the consent field instances they belong to, keyed by field\n * name, without mutating the input. A field with no resolved statement (no source picked, or a key\n * the host's sources no longer carry) is left untouched and renders without one.\n */\nexport const applyConsentStatements = <T extends { name?: string }>(\n\tfields: T[],\n\tstatements: ConsentStatements\n): T[] =>\n\tfields.map((instance) => {\n\t\tconst resolved = instance.name ? statements[instance.name] : undefined\n\t\treturn resolved ? { ...instance, ...resolved } : instance\n\t})\n"],"mappings":";;;;;;AAOA,MAAa,0BACZ,QACA,eAEA,OAAO,KAAK,aAAa;CACxB,MAAM,WAAW,SAAS,OAAO,WAAW,SAAS,QAAQ,KAAA;CAC7D,OAAO,WAAW;EAAE,GAAG;EAAU,GAAG;CAAS,IAAI;AAClD,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { FormFieldInstance } from "../submissions/types.js";
|
|
2
|
+
import { ConsentSourceEntry, ConsentSourcePage } from "./types.js";
|
|
3
|
+
import { Payload, PayloadRequest } from "payload";
|
|
4
|
+
|
|
5
|
+
//#region src/consent/captureConsent.d.ts
|
|
6
|
+
/** What a submission snapshots of the agreed wording. `'hash'` and `'text'` combine as `'both'`. */
|
|
7
|
+
type ConsentSnapshotMode = 'hash' | 'text' | 'both' | false;
|
|
8
|
+
type ConsentProof = {
|
|
9
|
+
agreed: boolean; /** The source `id` the field referenced; empty when the author never picked one. */
|
|
10
|
+
source: string;
|
|
11
|
+
page?: ConsentSourcePage;
|
|
12
|
+
versionRef?: string; /** The source label at submit time, so an audit names the statement even after a rename or delete. */
|
|
13
|
+
name?: string; /** sha256 of the statement plain text agreed to: tamper-evident and PII-free. */
|
|
14
|
+
statementHash?: string; /** Plain-text snapshot of the statement agreed to, for a human-readable audit. */
|
|
15
|
+
statementText?: string;
|
|
16
|
+
at: string;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* The authoritative consent proof, built at submit time from the server's own view of the source
|
|
20
|
+
* (the field carries an id, never a statement, so there is nothing here the client could forge).
|
|
21
|
+
*
|
|
22
|
+
* Proof is id-based on purpose: it records which document was agreed to, so renaming, re-slugging,
|
|
23
|
+
* or re-routing the policy leaves every past proof intact and resolvable. `snapshot` additionally
|
|
24
|
+
* captures the agreed wording (a `statementHash`, the plain `statementText`, or both) plus the source
|
|
25
|
+
* `name`, so an audit shows exactly what was agreed to independent of later edits; `false` keeps the
|
|
26
|
+
* lean id-only proof. The snapshot is captured in every branch, including a refusal and a page-less
|
|
27
|
+
* source.
|
|
28
|
+
*
|
|
29
|
+
* Time-of-check/time-of-use: a visitor reads the wording resolved when the form loaded, but the
|
|
30
|
+
* snapshot here is re-resolved from the source at submit. If the source text changed in that window,
|
|
31
|
+
* the proof records the submit-time wording, not the exact bytes rendered earlier. This is
|
|
32
|
+
* deliberate, the server's live view is authoritative and the window is one visitor session; a form
|
|
33
|
+
* that must freeze the exact wording agreed to should version the source (drafts give a `versionRef`
|
|
34
|
+
* pinning the published version, below).
|
|
35
|
+
*
|
|
36
|
+
* `versionRef` is recorded only when the page's collection has drafts enabled, and then it is the
|
|
37
|
+
* published version document's own id. Versions without drafts get no `versionRef`, because there
|
|
38
|
+
* is no published/draft distinction to pin to: `_status` only exists under drafts, so a
|
|
39
|
+
* published-version lookup there matches nothing, and recording that as a version reference would
|
|
40
|
+
* be inventing one. Absent means absent, in both cases.
|
|
41
|
+
*
|
|
42
|
+
* `now` is injected by the caller (`new Date().toISOString()`) for testability.
|
|
43
|
+
*/
|
|
44
|
+
declare const captureConsent: (args: {
|
|
45
|
+
field: FormFieldInstance;
|
|
46
|
+
agreed: boolean; /** The host's resolved sources for this request (see `resolveConsentEntries`). */
|
|
47
|
+
entries: ConsentSourceEntry[];
|
|
48
|
+
payload: Payload;
|
|
49
|
+
req?: PayloadRequest;
|
|
50
|
+
now: string; /** What to snapshot of the agreed wording (plugin option `consent.snapshot`); defaults to `'both'`. */
|
|
51
|
+
snapshot?: ConsentSnapshotMode;
|
|
52
|
+
}) => Promise<ConsentProof>;
|
|
53
|
+
//#endregion
|
|
54
|
+
export { ConsentProof, ConsentSnapshotMode, captureConsent };
|
|
55
|
+
//# sourceMappingURL=captureConsent.d.ts.map
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { textOfBody } from "../actions/body/textOfBody.js";
|
|
2
|
+
import { resolvePublishedVersionRef } from "./resolvePublishedVersionRef.js";
|
|
3
|
+
import { createHash } from "node:crypto";
|
|
4
|
+
import { hasDraftsEnabled } from "payload/shared";
|
|
5
|
+
//#region src/consent/captureConsent.ts
|
|
6
|
+
/**
|
|
7
|
+
* The authoritative consent proof, built at submit time from the server's own view of the source
|
|
8
|
+
* (the field carries an id, never a statement, so there is nothing here the client could forge).
|
|
9
|
+
*
|
|
10
|
+
* Proof is id-based on purpose: it records which document was agreed to, so renaming, re-slugging,
|
|
11
|
+
* or re-routing the policy leaves every past proof intact and resolvable. `snapshot` additionally
|
|
12
|
+
* captures the agreed wording (a `statementHash`, the plain `statementText`, or both) plus the source
|
|
13
|
+
* `name`, so an audit shows exactly what was agreed to independent of later edits; `false` keeps the
|
|
14
|
+
* lean id-only proof. The snapshot is captured in every branch, including a refusal and a page-less
|
|
15
|
+
* source.
|
|
16
|
+
*
|
|
17
|
+
* Time-of-check/time-of-use: a visitor reads the wording resolved when the form loaded, but the
|
|
18
|
+
* snapshot here is re-resolved from the source at submit. If the source text changed in that window,
|
|
19
|
+
* the proof records the submit-time wording, not the exact bytes rendered earlier. This is
|
|
20
|
+
* deliberate, the server's live view is authoritative and the window is one visitor session; a form
|
|
21
|
+
* that must freeze the exact wording agreed to should version the source (drafts give a `versionRef`
|
|
22
|
+
* pinning the published version, below).
|
|
23
|
+
*
|
|
24
|
+
* `versionRef` is recorded only when the page's collection has drafts enabled, and then it is the
|
|
25
|
+
* published version document's own id. Versions without drafts get no `versionRef`, because there
|
|
26
|
+
* is no published/draft distinction to pin to: `_status` only exists under drafts, so a
|
|
27
|
+
* published-version lookup there matches nothing, and recording that as a version reference would
|
|
28
|
+
* be inventing one. Absent means absent, in both cases.
|
|
29
|
+
*
|
|
30
|
+
* `now` is injected by the caller (`new Date().toISOString()`) for testability.
|
|
31
|
+
*/
|
|
32
|
+
const captureConsent = async (args) => {
|
|
33
|
+
const source = typeof args.field.source === "string" ? args.field.source : "";
|
|
34
|
+
const entry = source ? args.entries.find((candidate) => candidate.id === source) : void 0;
|
|
35
|
+
const snapshot = args.snapshot ?? "both";
|
|
36
|
+
const withSnapshot = (proof) => {
|
|
37
|
+
if (!entry || snapshot === false) return proof;
|
|
38
|
+
if (typeof entry.name === "string" && entry.name.trim().length > 0) proof.name = entry.name.trim();
|
|
39
|
+
const text = textOfBody(entry.statement);
|
|
40
|
+
if (text.length > 0) {
|
|
41
|
+
if (snapshot === "hash" || snapshot === "both") proof.statementHash = createHash("sha256").update(text).digest("hex");
|
|
42
|
+
if (snapshot === "text" || snapshot === "both") proof.statementText = text;
|
|
43
|
+
}
|
|
44
|
+
return proof;
|
|
45
|
+
};
|
|
46
|
+
const page = entry?.page;
|
|
47
|
+
if (!page) return withSnapshot({
|
|
48
|
+
agreed: args.agreed,
|
|
49
|
+
source,
|
|
50
|
+
at: args.now
|
|
51
|
+
});
|
|
52
|
+
const collection = args.payload.collections[page.relationTo];
|
|
53
|
+
const versionRef = collection && hasDraftsEnabled(collection.config) ? await resolvePublishedVersionRef({
|
|
54
|
+
payload: args.payload,
|
|
55
|
+
collection: page.relationTo,
|
|
56
|
+
id: page.id,
|
|
57
|
+
req: args.req
|
|
58
|
+
}) : null;
|
|
59
|
+
return withSnapshot({
|
|
60
|
+
agreed: args.agreed,
|
|
61
|
+
source,
|
|
62
|
+
page: {
|
|
63
|
+
relationTo: page.relationTo,
|
|
64
|
+
id: page.id
|
|
65
|
+
},
|
|
66
|
+
...versionRef ? { versionRef } : {},
|
|
67
|
+
at: args.now
|
|
68
|
+
});
|
|
69
|
+
};
|
|
70
|
+
//#endregion
|
|
71
|
+
export { captureConsent };
|
|
72
|
+
|
|
73
|
+
//# sourceMappingURL=captureConsent.js.map
|