@10x-media/form-builder 0.1.0-beta.2 → 0.1.0-beta.21
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 +360 -0
- package/README.md +7 -5
- package/dist/actions/assertNoBlockCollision.js +18 -0
- package/dist/actions/assertNoBlockCollision.js.map +1 -0
- 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 +12 -9
- package/dist/actions/buildActionBlocks.js.map +1 -1
- package/dist/actions/builtin/confirmation.js +47 -43
- package/dist/actions/builtin/confirmation.js.map +1 -1
- package/dist/actions/builtin/emailAction.d.ts +20 -0
- package/dist/actions/builtin/emailAction.js +120 -0
- package/dist/actions/builtin/emailAction.js.map +1 -0
- package/dist/actions/builtin/emailTeam.js +20 -38
- package/dist/actions/builtin/emailTeam.js.map +1 -1
- package/dist/actions/builtin/index.d.ts +16 -1
- package/dist/actions/builtin/index.js +21 -7
- package/dist/actions/builtin/index.js.map +1 -1
- package/dist/actions/builtin/signedWebhook.js +6 -2
- package/dist/actions/builtin/signedWebhook.js.map +1 -1
- package/dist/actions/defineAction.d.ts +17 -5
- package/dist/actions/defineAction.js.map +1 -1
- package/dist/actions/dispatch.js +51 -6
- package/dist/actions/dispatch.js.map +1 -1
- package/dist/actions/dispatchContext.js +13 -0
- package/dist/actions/dispatchContext.js.map +1 -0
- package/dist/actions/emailRecipients.d.ts +12 -0
- package/dist/actions/emailRecipients.js +146 -0
- package/dist/actions/emailRecipients.js.map +1 -0
- package/dist/actions/fromAddresses.d.ts +37 -0
- package/dist/actions/fromAddresses.js +131 -0
- package/dist/actions/fromAddresses.js.map +1 -0
- package/dist/actions/recipientSources.d.ts +34 -0
- package/dist/actions/recipientSources.js +11 -0
- package/dist/actions/recipientSources.js.map +1 -0
- package/dist/actions/registry.d.ts +2 -1
- package/dist/actions/registry.js +5 -7
- package/dist/actions/registry.js.map +1 -1
- package/dist/actions/runActions.js +10 -1
- package/dist/actions/runActions.js.map +1 -1
- package/dist/actions/task.js +47 -16
- package/dist/actions/task.js.map +1 -1
- package/dist/aggregation/aggregateResponses.d.ts +9 -0
- package/dist/aggregation/aggregateResponses.js +8 -14
- package/dist/aggregation/aggregateResponses.js.map +1 -1
- package/dist/aggregation/resolveResultsRequest.d.ts +41 -6
- package/dist/aggregation/resolveResultsRequest.js +97 -11
- package/dist/aggregation/resolveResultsRequest.js.map +1 -1
- package/dist/calc/computeCalcFields.d.ts +5 -3
- package/dist/calc/computeCalcFields.js +6 -4
- package/dist/calc/computeCalcFields.js.map +1 -1
- package/dist/calc/evaluate.d.ts +26 -3
- package/dist/calc/evaluate.js +34 -13
- package/dist/calc/evaluate.js.map +1 -1
- package/dist/calc/formatCalc.d.ts +11 -0
- package/dist/calc/formatCalc.js +35 -0
- package/dist/calc/formatCalc.js.map +1 -0
- package/dist/calc/formatCalcValue.d.ts +17 -0
- package/dist/calc/formatCalcValue.js +17 -0
- package/dist/calc/formatCalcValue.js.map +1 -0
- package/dist/calc/normalizeCalc.d.ts +17 -3
- package/dist/calc/normalizeCalc.js +42 -33
- package/dist/calc/normalizeCalc.js.map +1 -1
- package/dist/calc/registry.d.ts +43 -0
- package/dist/calc/registry.js +27 -0
- package/dist/calc/registry.js.map +1 -0
- package/dist/calc/resolveCalcContext.d.ts +36 -0
- package/dist/calc/resolveCalcContext.js +87 -0
- package/dist/calc/resolveCalcContext.js.map +1 -0
- package/dist/calc/types.d.ts +25 -4
- package/dist/calc/types.js +23 -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/CalcExpressionBuilder.d.ts +20 -0
- package/dist/client/CalcExpressionBuilder.js +890 -0
- package/dist/client/CalcExpressionBuilder.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 +2 -1
- package/dist/client/ConditionBuilder.js.map +1 -1
- 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 +55 -0
- package/dist/client/EndpointOptionsSelect.js +112 -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 +2 -2
- package/dist/client/FlowBuilder.js +137 -88
- package/dist/client/FlowBuilder.js.map +1 -1
- package/dist/client/FormConditionField.js +1 -4
- package/dist/client/FormConditionField.js.map +1 -1
- package/dist/client/RecipientsSelect.d.ts +37 -0
- package/dist/client/RecipientsSelect.js +197 -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 +557 -0
- package/dist/client/endpointOptions.d.ts +11 -0
- package/dist/client/endpointOptions.js +38 -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 +21 -10
- package/dist/client/synthesizeClientField.js.map +1 -1
- 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 +114 -28
- package/dist/collections/formSubmissions.js.map +1 -1
- package/dist/collections/forms.js +449 -112
- package/dist/collections/forms.js.map +1 -1
- package/dist/collections/formsEndpoints.js +106 -0
- package/dist/collections/formsEndpoints.js.map +1 -0
- package/dist/collections/redirectFields.d.ts +29 -0
- package/dist/collections/settingsFields.d.ts +31 -0
- package/dist/collections/settingsFields.js +45 -0
- package/dist/collections/settingsFields.js.map +1 -0
- package/dist/conditions/conditionType.js +9 -2
- package/dist/conditions/conditionType.js.map +1 -1
- package/dist/conditions/evaluate.js +1 -1
- package/dist/conditions/evaluate.js.map +1 -1
- package/dist/conditions/fieldTypes.d.ts +3 -1
- package/dist/conditions/fieldTypes.js +4 -1
- package/dist/conditions/fieldTypes.js.map +1 -1
- package/dist/conditions/normalizeConditions.js +20 -6
- package/dist/conditions/normalizeConditions.js.map +1 -1
- 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 +39 -11
- package/dist/consent/captureConsent.js +63 -13
- package/dist/consent/captureConsent.js.map +1 -1
- package/dist/consent/consentSourcesField.d.ts +66 -0
- package/dist/consent/consentSourcesField.js +98 -0
- package/dist/consent/consentSourcesField.js.map +1 -0
- package/dist/consent/effectiveStatement.js +16 -0
- package/dist/consent/effectiveStatement.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 +46 -0
- package/dist/consent/resolveConsentStatements.js.map +1 -0
- package/dist/consent/resolvePublishedVersionRef.d.ts +17 -11
- package/dist/consent/resolvePublishedVersionRef.js +13 -10
- package/dist/consent/resolvePublishedVersionRef.js.map +1 -1
- package/dist/consent/types.d.ts +69 -0
- package/dist/context/formContext.d.ts +30 -0
- package/dist/context/formContext.js +54 -0
- package/dist/context/formContext.js.map +1 -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/exports/client.d.ts +14 -1
- package/dist/exports/client.js +14 -1
- package/dist/exports/i18n.d.ts +5 -2
- package/dist/exports/i18n.js +5 -2
- package/dist/exports/react.d.ts +34 -10
- package/dist/exports/react.js +24 -4
- package/dist/exports/rsc.d.ts +10 -1
- package/dist/exports/rsc.js +10 -1
- package/dist/exports/types.d.ts +20 -12
- package/dist/fields/buildFieldBlocks.js +46 -25
- package/dist/fields/buildFieldBlocks.js.map +1 -1
- package/dist/fields/builtin/calculation.d.ts +17 -0
- package/dist/fields/builtin/calculation.js +193 -18
- package/dist/fields/builtin/calculation.js.map +1 -1
- package/dist/fields/builtin/checkbox.js +23 -0
- package/dist/fields/builtin/checkbox.js.map +1 -1
- package/dist/fields/builtin/consent.js +49 -14
- package/dist/fields/builtin/consent.js.map +1 -1
- 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 +8 -1
- package/dist/fields/builtin/email.js.map +1 -1
- package/dist/fields/builtin/file.d.ts +15 -0
- package/dist/fields/builtin/file.js +95 -8
- package/dist/fields/builtin/file.js.map +1 -1
- package/dist/fields/builtin/index.d.ts +30 -0
- package/dist/fields/builtin/index.js +37 -10
- package/dist/fields/builtin/index.js.map +1 -1
- package/dist/fields/builtin/message.js +30 -0
- package/dist/fields/builtin/message.js.map +1 -0
- package/dist/fields/builtin/repeater.js +8 -3
- package/dist/fields/builtin/repeater.js.map +1 -1
- package/dist/fields/builtin/select.js +28 -4
- package/dist/fields/builtin/select.js.map +1 -1
- 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 +7 -0
- package/dist/fields/builtin/text.js.map +1 -1
- 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/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 +3 -1
- package/dist/fields/registry.js +23 -8
- package/dist/fields/registry.js.map +1 -1
- package/dist/fields/sharedConfig.js +125 -59
- package/dist/fields/sharedConfig.js.map +1 -1
- package/dist/fields/types.d.ts +78 -9
- package/dist/flow/engine.d.ts +6 -4
- package/dist/flow/engine.js +11 -6
- package/dist/flow/engine.js.map +1 -1
- package/dist/flow/normalizeFlow.js +28 -9
- package/dist/flow/normalizeFlow.js.map +1 -1
- package/dist/flow/stepLabel.js +15 -0
- package/dist/flow/stepLabel.js.map +1 -0
- package/dist/flow/types.d.ts +12 -3
- package/dist/flow/types.js +11 -0
- package/dist/flow/types.js.map +1 -0
- package/dist/form/pollState.d.ts +23 -0
- package/dist/form/pollState.js +17 -0
- package/dist/form/pollState.js.map +1 -0
- package/dist/form/toFormDocument.d.ts +110 -0
- package/dist/form/toFormDocument.js +89 -0
- package/dist/form/toFormDocument.js.map +1 -0
- package/dist/form/types.d.ts +73 -0
- package/dist/index.d.ts +67 -61
- package/dist/index.js +120 -25
- package/dist/index.js.map +1 -1
- package/dist/options.d.ts +281 -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/customState.js +26 -0
- package/dist/plugin/customState.js.map +1 -0
- package/dist/plugin/registerCollections.js +43 -40
- package/dist/plugin/registerCollections.js.map +1 -1
- 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 +53 -0
- package/dist/poll/closeJob.js +121 -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 +106 -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 +40 -0
- package/dist/poll/resolvePollOutcome.js +90 -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/poll/votes/aggregateFromVotes.d.ts +27 -0
- package/dist/poll/votes/aggregateFromVotes.js +54 -0
- package/dist/poll/votes/aggregateFromVotes.js.map +1 -0
- package/dist/poll/votes/answerValues.js +16 -0
- package/dist/poll/votes/answerValues.js.map +1 -0
- package/dist/poll/votes/bumpPollVote.js +88 -0
- package/dist/poll/votes/bumpPollVote.js.map +1 -0
- package/dist/poll/votes/recountPollVotes.d.ts +20 -0
- package/dist/poll/votes/recountPollVotes.js +63 -0
- package/dist/poll/votes/recountPollVotes.js.map +1 -0
- package/dist/poll/votes/voteTallyHook.js +76 -0
- package/dist/poll/votes/voteTallyHook.js.map +1 -0
- package/dist/poll/votes/votesCollection.d.ts +19 -0
- package/dist/poll/votes/votesCollection.js +89 -0
- package/dist/poll/votes/votesCollection.js.map +1 -0
- package/dist/prefill/valuesFromSearchParams.js +5 -9
- package/dist/prefill/valuesFromSearchParams.js.map +1 -1
- package/dist/presentations/types.d.ts +3 -2
- package/dist/react/Form.d.ts +77 -35
- package/dist/react/Form.js +368 -222
- package/dist/react/Form.js.map +1 -1
- package/dist/react/FormContext.d.ts +51 -1
- package/dist/react/FormContext.js.map +1 -1
- 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 +4 -2
- package/dist/react/FormLayout.js +3 -2
- package/dist/react/FormLayout.js.map +1 -1
- package/dist/react/FormResults.d.ts +8 -3
- package/dist/react/FormResults.js +50 -29
- package/dist/react/FormResults.js.map +1 -1
- 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/Poll.d.ts +40 -6
- package/dist/react/Poll.js +137 -33
- package/dist/react/Poll.js.map +1 -1
- package/dist/react/adapters.d.ts +35 -0
- package/dist/react/adapters.js +11 -0
- package/dist/react/adapters.js.map +1 -0
- package/dist/react/captcha/HcaptchaCaptcha.d.ts +31 -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 +44 -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 +31 -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 +63 -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/contract.d.ts +2 -3
- package/dist/react/contract.js.map +1 -1
- package/dist/react/fetchResults.d.ts +1 -1
- package/dist/react/fetchResults.js +1 -1
- package/dist/react/fetchResults.js.map +1 -1
- package/dist/react/presentation/DialogSurface.js +1 -4
- package/dist/react/presentation/DialogSurface.js.map +1 -1
- package/dist/react/primitives/Checkbox.d.ts +6 -2
- package/dist/react/primitives/Checkbox.js +4 -2
- package/dist/react/primitives/Checkbox.js.map +1 -1
- package/dist/react/primitives/ChoiceGroup.d.ts +40 -0
- package/dist/react/primitives/ChoiceGroup.js +33 -0
- package/dist/react/primitives/ChoiceGroup.js.map +1 -0
- package/dist/react/primitives/FieldShell.d.ts +13 -5
- package/dist/react/primitives/FieldShell.js +35 -32
- package/dist/react/primitives/FieldShell.js.map +1 -1
- package/dist/react/primitives/Input.d.ts +4 -2
- package/dist/react/primitives/Input.js +2 -1
- package/dist/react/primitives/Input.js.map +1 -1
- package/dist/react/renderers/calculation.js +7 -5
- package/dist/react/renderers/calculation.js.map +1 -1
- package/dist/react/renderers/checkbox.js +3 -5
- package/dist/react/renderers/checkbox.js.map +1 -1
- package/dist/react/renderers/consent.js +84 -36
- package/dist/react/renderers/consent.js.map +1 -1
- package/dist/react/renderers/date.js +33 -0
- package/dist/react/renderers/date.js.map +1 -0
- package/dist/react/renderers/email.js +4 -5
- package/dist/react/renderers/email.js.map +1 -1
- package/dist/react/renderers/file.js +29 -14
- package/dist/react/renderers/file.js.map +1 -1
- package/dist/react/renderers/index.js +7 -0
- package/dist/react/renderers/index.js.map +1 -1
- package/dist/react/renderers/message.js +41 -0
- package/dist/react/renderers/message.js.map +1 -0
- package/dist/react/renderers/number.js +1 -4
- package/dist/react/renderers/number.js.map +1 -1
- package/dist/react/renderers/region.js +43 -0
- package/dist/react/renderers/region.js.map +1 -0
- package/dist/react/renderers/repeater.js +32 -14
- package/dist/react/renderers/repeater.js.map +1 -1
- package/dist/react/renderers/select.js +21 -6
- package/dist/react/renderers/select.js.map +1 -1
- package/dist/react/renderers/text.js +4 -5
- package/dist/react/renderers/text.js.map +1 -1
- package/dist/react/renderers/textarea.js +1 -4
- package/dist/react/renderers/textarea.js.map +1 -1
- package/dist/react/state.d.ts +46 -3
- package/dist/react/state.js +73 -10
- package/dist/react/state.js.map +1 -1
- package/dist/react/submitForm.js +1 -1
- package/dist/react/submitForm.js.map +1 -1
- package/dist/react/uploadFile.d.ts +2 -2
- package/dist/react/uploadFile.js +1 -1
- package/dist/react/uploadFile.js.map +1 -1
- package/dist/react/useCalcValues.d.ts +10 -0
- package/dist/react/useCalcValues.js +13 -0
- package/dist/react/useCalcValues.js.map +1 -0
- package/dist/react/useField.d.ts +0 -1
- package/dist/react/useField.js +7 -6
- package/dist/react/useField.js.map +1 -1
- package/dist/react/useFormState.d.ts +1 -1
- package/dist/react/useFormState.js +1 -1
- package/dist/react/useFormState.js.map +1 -1
- package/dist/react/validateField.js +3 -6
- package/dist/react/validateField.js.map +1 -1
- package/dist/recall/interpolate.d.ts +4 -3
- package/dist/recall/interpolate.js +5 -4
- package/dist/recall/interpolate.js.map +1 -1
- package/dist/recall/resolver.d.ts +1 -1
- package/dist/recall/resolver.js +15 -3
- package/dist/recall/resolver.js.map +1 -1
- package/dist/spam/captcha.d.ts +4 -3
- package/dist/spam/captcha.js +4 -3
- package/dist/spam/captcha.js.map +1 -1
- package/dist/spam/clientIp.js +9 -0
- package/dist/spam/clientIp.js.map +1 -0
- package/dist/spam/constants.js +13 -1
- package/dist/spam/constants.js.map +1 -1
- package/dist/spam/identify.js +3 -6
- package/dist/spam/identify.js.map +1 -1
- 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/resolveSpam.js +2 -1
- package/dist/spam/resolveSpam.js.map +1 -1
- package/dist/spam/spamGuard.js +25 -11
- package/dist/spam/spamGuard.js.map +1 -1
- package/dist/spam/types.d.ts +19 -4
- package/dist/submissions/SubmissionAnswers.js +6 -2
- package/dist/submissions/SubmissionAnswers.js.map +1 -1
- package/dist/submissions/SubmissionAnswersClient.js +100 -64
- package/dist/submissions/SubmissionAnswersClient.js.map +1 -1
- 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/formIdOf.js +13 -0
- package/dist/submissions/formIdOf.js.map +1 -0
- package/dist/submissions/resolveVotedSubmission.d.ts +27 -0
- package/dist/submissions/resolveVotedSubmission.js +51 -0
- package/dist/submissions/resolveVotedSubmission.js.map +1 -0
- package/dist/submissions/runSubmission.d.ts +10 -0
- package/dist/submissions/runSubmission.js +104 -54
- package/dist/submissions/runSubmission.js.map +1 -1
- package/dist/submissions/types.d.ts +11 -4
- package/dist/submissions/validateSubmission.js +99 -13
- package/dist/submissions/validateSubmission.js.map +1 -1
- package/dist/submissions/verifyContext.js +35 -0
- package/dist/submissions/verifyContext.js.map +1 -0
- package/dist/submissions/voteChangeEndpoint.js +105 -0
- package/dist/submissions/voteChangeEndpoint.js.map +1 -0
- package/dist/submissions/votedCookie.d.ts +15 -0
- package/dist/submissions/votedCookie.js +74 -0
- package/dist/submissions/votedCookie.js.map +1 -0
- package/dist/translations/clientRuntimeKeys.d.ts +17 -0
- package/dist/translations/clientRuntimeKeys.js +48 -0
- package/dist/translations/clientRuntimeKeys.js.map +1 -0
- package/dist/translations/de.d.ts +12 -0
- package/dist/translations/de.js +380 -0
- package/dist/translations/de.js.map +1 -0
- package/dist/translations/en.js +250 -28
- package/dist/translations/en.js.map +1 -1
- package/dist/translations/index.d.ts +14 -5
- package/dist/translations/index.js +14 -3
- package/dist/translations/index.js.map +1 -1
- package/dist/translations/keys.d.ts +245 -23
- package/dist/translations/keys.js +246 -24
- package/dist/translations/keys.js.map +1 -1
- package/dist/translations/makeTranslate.d.ts +7 -3
- package/dist/translations/makeTranslate.js +12 -3
- package/dist/translations/makeTranslate.js.map +1 -1
- package/dist/translations/server.js +8 -1
- package/dist/translations/server.js.map +1 -1
- package/dist/uploads/captureFileRef.d.ts +10 -3
- package/dist/uploads/captureFileRef.js +18 -9
- package/dist/uploads/captureFileRef.js.map +1 -1
- 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.js +3 -2
- package/dist/uploads/resolveFileRef.js.map +1 -1
- package/dist/uploads/types.d.ts +1 -2
- package/dist/validation/buildRuleBlocks.js +18 -17
- package/dist/validation/buildRuleBlocks.js.map +1 -1
- package/dist/validation/builtin/email.js +2 -1
- package/dist/validation/builtin/email.js.map +1 -1
- package/dist/validation/builtin/index.d.ts +14 -0
- package/dist/validation/builtin/index.js +14 -1
- package/dist/validation/builtin/index.js.map +1 -1
- package/dist/validation/builtin/integer.js +15 -0
- package/dist/validation/builtin/integer.js.map +1 -0
- package/dist/validation/builtin/matchesField.js +3 -7
- package/dist/validation/builtin/matchesField.js.map +1 -1
- package/dist/validation/builtin/max.js +1 -0
- package/dist/validation/builtin/max.js.map +1 -1
- package/dist/validation/builtin/maxDate.js +24 -0
- package/dist/validation/builtin/maxDate.js.map +1 -0
- package/dist/validation/builtin/maxLength.js +1 -0
- package/dist/validation/builtin/maxLength.js.map +1 -1
- package/dist/validation/builtin/min.js +1 -0
- package/dist/validation/builtin/min.js.map +1 -1
- package/dist/validation/builtin/minDate.js +24 -0
- package/dist/validation/builtin/minDate.js.map +1 -0
- package/dist/validation/builtin/minLength.js +1 -0
- package/dist/validation/builtin/minLength.js.map +1 -1
- package/dist/validation/builtin/notAlreadySubmitted.js +5 -1
- package/dist/validation/builtin/notAlreadySubmitted.js.map +1 -1
- package/dist/validation/builtin/oneOf.js +1 -0
- package/dist/validation/builtin/oneOf.js.map +1 -1
- package/dist/validation/builtin/pattern.js +11 -2
- package/dist/validation/builtin/pattern.js.map +1 -1
- package/dist/validation/builtin/url.js +1 -0
- package/dist/validation/builtin/url.js.map +1 -1
- 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/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/registry.d.ts +2 -1
- package/dist/validation/registry.js +2 -9
- package/dist/validation/registry.js.map +1 -1
- package/dist/validation/runValidation.js +8 -29
- package/dist/validation/runValidation.js.map +1 -1
- package/dist/validation/types.d.ts +5 -11
- package/dist/validation/validateUrl.js +22 -0
- package/dist/validation/validateUrl.js.map +1 -0
- package/package.json +14 -6
- package/styles/form-builder.css +94 -190
- package/dist/collections/uploads.d.ts +0 -30
- package/dist/collections/uploads.js +0 -55
- package/dist/collections/uploads.js.map +0 -1
- package/dist/consent/buildConsentSourceConfig.js +0 -49
- package/dist/consent/buildConsentSourceConfig.js.map +0 -1
- package/dist/consent/builtin/index.d.ts +0 -7
- package/dist/consent/builtin/index.js +0 -11
- package/dist/consent/builtin/index.js.map +0 -1
- package/dist/consent/builtin/pageReference.js +0 -75
- package/dist/consent/builtin/pageReference.js.map +0 -1
- package/dist/consent/builtin/static.js +0 -44
- package/dist/consent/builtin/static.js.map +0 -1
- package/dist/consent/defineConsentSource.d.ts +0 -35
- package/dist/consent/defineConsentSource.js +0 -6
- package/dist/consent/defineConsentSource.js.map +0 -1
- package/dist/consent/registry.d.ts +0 -16
- package/dist/consent/registry.js +0 -16
- package/dist/consent/registry.js.map +0 -1
- package/dist/consent/resolveConsentLinks.d.ts +0 -19
- package/dist/consent/resolveConsentLinks.js +0 -26
- package/dist/consent/resolveConsentLinks.js.map +0 -1
- package/dist/presentations/registry.d.ts +0 -15
- package/dist/presentations/registry.js +0 -15
- package/dist/presentations/registry.js.map +0 -1
- package/dist/react/toFormDocument.d.ts +0 -24
- package/dist/react/toFormDocument.js +0 -22
- package/dist/react/toFormDocument.js.map +0 -1
|
@@ -1,23 +1,9 @@
|
|
|
1
|
+
import { CALC_OPS, isCalcFn } from "./types.js";
|
|
1
2
|
//#region src/calc/normalizeCalc.ts
|
|
2
|
-
const
|
|
3
|
-
const OP_SET = new Set([
|
|
4
|
-
"+",
|
|
5
|
-
"-",
|
|
6
|
-
"*",
|
|
7
|
-
"/",
|
|
8
|
-
"%"
|
|
9
|
-
]);
|
|
10
|
-
const FN_SET = new Set([
|
|
11
|
-
"min",
|
|
12
|
-
"max",
|
|
13
|
-
"round",
|
|
14
|
-
"abs",
|
|
15
|
-
"ceil",
|
|
16
|
-
"floor"
|
|
17
|
-
]);
|
|
3
|
+
const isOp = (v) => CALC_OPS.includes(v);
|
|
18
4
|
const isRecord = (v) => v !== null && typeof v === "object" && !Array.isArray(v);
|
|
19
|
-
const normalizeNode = (value, depth) => {
|
|
20
|
-
if (depth >
|
|
5
|
+
const normalizeNode = (value, depth, allowed) => {
|
|
6
|
+
if (depth > 64) return void 0;
|
|
21
7
|
if (!isRecord(value)) return void 0;
|
|
22
8
|
switch (value.type) {
|
|
23
9
|
case "lit": {
|
|
@@ -38,10 +24,10 @@ const normalizeNode = (value, depth) => {
|
|
|
38
24
|
}
|
|
39
25
|
case "op": {
|
|
40
26
|
const { op, left, right } = value;
|
|
41
|
-
if (
|
|
42
|
-
const l = normalizeNode(left, depth + 1);
|
|
27
|
+
if (!isOp(op)) return void 0;
|
|
28
|
+
const l = normalizeNode(left, depth + 1, allowed);
|
|
43
29
|
if (!l) return void 0;
|
|
44
|
-
const r = normalizeNode(right, depth + 1);
|
|
30
|
+
const r = normalizeNode(right, depth + 1, allowed);
|
|
45
31
|
if (!r) return void 0;
|
|
46
32
|
return {
|
|
47
33
|
type: "op",
|
|
@@ -51,7 +37,7 @@ const normalizeNode = (value, depth) => {
|
|
|
51
37
|
};
|
|
52
38
|
}
|
|
53
39
|
case "neg": {
|
|
54
|
-
const operand = normalizeNode(value.operand, depth + 1);
|
|
40
|
+
const operand = normalizeNode(value.operand, depth + 1, allowed);
|
|
55
41
|
if (!operand) return void 0;
|
|
56
42
|
return {
|
|
57
43
|
type: "neg",
|
|
@@ -60,11 +46,12 @@ const normalizeNode = (value, depth) => {
|
|
|
60
46
|
}
|
|
61
47
|
case "fn": {
|
|
62
48
|
const { fn, args } = value;
|
|
63
|
-
if (typeof fn !== "string"
|
|
49
|
+
if (typeof fn !== "string") return void 0;
|
|
50
|
+
if (!isCalcFn(fn) && !allowed?.functions?.has(fn)) return void 0;
|
|
64
51
|
if (!Array.isArray(args)) return void 0;
|
|
65
52
|
const normalizedArgs = [];
|
|
66
53
|
for (const arg of args) {
|
|
67
|
-
const a = normalizeNode(arg, depth + 1);
|
|
54
|
+
const a = normalizeNode(arg, depth + 1, allowed);
|
|
68
55
|
if (!a) return void 0;
|
|
69
56
|
normalizedArgs.push(a);
|
|
70
57
|
}
|
|
@@ -74,26 +61,48 @@ const normalizeNode = (value, depth) => {
|
|
|
74
61
|
args: normalizedArgs
|
|
75
62
|
};
|
|
76
63
|
}
|
|
64
|
+
case "source": {
|
|
65
|
+
const { source } = value;
|
|
66
|
+
if (typeof source !== "string") return void 0;
|
|
67
|
+
if (!allowed?.sources?.has(source)) return void 0;
|
|
68
|
+
return {
|
|
69
|
+
type: "source",
|
|
70
|
+
source
|
|
71
|
+
};
|
|
72
|
+
}
|
|
77
73
|
case "weight": {
|
|
78
|
-
const { field, weights } = value;
|
|
74
|
+
const { field, weights, source } = value;
|
|
79
75
|
if (typeof field !== "string") return void 0;
|
|
80
|
-
if (
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
76
|
+
if (source !== void 0) {
|
|
77
|
+
if (typeof source !== "string" || !allowed?.sources?.has(source)) return void 0;
|
|
78
|
+
}
|
|
79
|
+
let normalizedWeights;
|
|
80
|
+
if (weights !== void 0) {
|
|
81
|
+
if (!isRecord(weights)) return void 0;
|
|
82
|
+
normalizedWeights = {};
|
|
83
|
+
for (const [k, v] of Object.entries(weights)) {
|
|
84
|
+
if (typeof v !== "number" || !Number.isFinite(v)) return void 0;
|
|
85
|
+
normalizedWeights[k] = v;
|
|
86
|
+
}
|
|
85
87
|
}
|
|
88
|
+
if (normalizedWeights === void 0 && source === void 0) return void 0;
|
|
86
89
|
return {
|
|
87
90
|
type: "weight",
|
|
88
91
|
field,
|
|
89
|
-
weights: normalizedWeights
|
|
92
|
+
...normalizedWeights !== void 0 ? { weights: normalizedWeights } : {},
|
|
93
|
+
...typeof source === "string" ? { source } : {}
|
|
90
94
|
};
|
|
91
95
|
}
|
|
92
96
|
default: return;
|
|
93
97
|
}
|
|
94
98
|
};
|
|
95
|
-
/**
|
|
96
|
-
|
|
99
|
+
/**
|
|
100
|
+
* Structural guard: returns a valid CalcExpression if `value` is structurally sound (depth-guarded
|
|
101
|
+
* at 64), otherwise undefined. Never throws. `allowed` admits registered extension names (source
|
|
102
|
+
* keys, custom function names); without it only the built-in grammar passes, so an un-threaded
|
|
103
|
+
* caller can never validate an expression the evaluator has no values for.
|
|
104
|
+
*/
|
|
105
|
+
const normalizeCalc = (value, allowed) => normalizeNode(value, 0, allowed);
|
|
97
106
|
//#endregion
|
|
98
107
|
export { normalizeCalc };
|
|
99
108
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"normalizeCalc.js","names":[],"sources":["../../src/calc/normalizeCalc.ts"],"sourcesContent":["import type
|
|
1
|
+
{"version":3,"file":"normalizeCalc.js","names":[],"sources":["../../src/calc/normalizeCalc.ts"],"sourcesContent":["import { CALC_OPS, type CalcExpression, type CalcOp, isCalcFn, MAX_DEPTH } from './types'\n\n/**\n * The extension names a normalized expression may reference: registered calc source keys and custom\n * function names (plugin option `calc`). Absent (the default for every un-threaded caller), only the\n * built-in grammar is valid: `source` nodes, sourced weights, and custom fns all reject.\n */\nexport type CalcAllowed = {\n\tsources?: ReadonlySet<string>\n\tfunctions?: ReadonlySet<string>\n}\n\nconst isOp = (v: unknown): v is CalcOp => (CALC_OPS as readonly unknown[]).includes(v)\n\nconst isRecord = (v: unknown): v is Record<string, unknown> =>\n\tv !== null && typeof v === 'object' && !Array.isArray(v)\n\nconst normalizeNode = (\n\tvalue: unknown,\n\tdepth: number,\n\tallowed?: CalcAllowed\n): CalcExpression | undefined => {\n\tif (depth > MAX_DEPTH) return undefined\n\tif (!isRecord(value)) return undefined\n\n\tswitch (value.type) {\n\t\tcase 'lit': {\n\t\t\tconst { value: v } = value\n\t\t\tif (typeof v !== 'number' || !Number.isFinite(v)) return undefined\n\t\t\treturn { type: 'lit', value: v }\n\t\t}\n\t\tcase 'ref': {\n\t\t\tconst { field } = value\n\t\t\tif (typeof field !== 'string') return undefined\n\t\t\treturn { type: 'ref', field }\n\t\t}\n\t\tcase 'op': {\n\t\t\tconst { op, left, right } = value\n\t\t\tif (!isOp(op)) return undefined\n\t\t\tconst l = normalizeNode(left, depth + 1, allowed)\n\t\t\tif (!l) return undefined\n\t\t\tconst r = normalizeNode(right, depth + 1, allowed)\n\t\t\tif (!r) return undefined\n\t\t\treturn { type: 'op', op, left: l, right: r }\n\t\t}\n\t\tcase 'neg': {\n\t\t\tconst operand = normalizeNode(value.operand, depth + 1, allowed)\n\t\t\tif (!operand) return undefined\n\t\t\treturn { type: 'neg', operand }\n\t\t}\n\t\tcase 'fn': {\n\t\t\tconst { fn, args } = value\n\t\t\tif (typeof fn !== 'string') return undefined\n\t\t\tif (!isCalcFn(fn) && !allowed?.functions?.has(fn)) return undefined\n\t\t\tif (!Array.isArray(args)) return undefined\n\t\t\tconst normalizedArgs: CalcExpression[] = []\n\t\t\tfor (const arg of args) {\n\t\t\t\tconst a = normalizeNode(arg, depth + 1, allowed)\n\t\t\t\tif (!a) return undefined\n\t\t\t\tnormalizedArgs.push(a)\n\t\t\t}\n\t\t\treturn { type: 'fn', fn, args: normalizedArgs }\n\t\t}\n\t\tcase 'source': {\n\t\t\tconst { source } = value\n\t\t\tif (typeof source !== 'string') return undefined\n\t\t\tif (!allowed?.sources?.has(source)) return undefined\n\t\t\treturn { type: 'source', source }\n\t\t}\n\t\tcase 'weight': {\n\t\t\tconst { field, weights, source } = value\n\t\t\tif (typeof field !== 'string') return undefined\n\t\t\tif (source !== undefined) {\n\t\t\t\tif (typeof source !== 'string' || !allowed?.sources?.has(source)) return undefined\n\t\t\t}\n\t\t\tlet normalizedWeights: Record<string, number> | undefined\n\t\t\tif (weights !== undefined) {\n\t\t\t\tif (!isRecord(weights)) return undefined\n\t\t\t\tnormalizedWeights = {}\n\t\t\t\tfor (const [k, v] of Object.entries(weights)) {\n\t\t\t\t\tif (typeof v !== 'number' || !Number.isFinite(v)) return undefined\n\t\t\t\t\tnormalizedWeights[k] = v\n\t\t\t\t}\n\t\t\t}\n\t\t\t// A weight must carry a per-option map from somewhere: inline weights or a registered source.\n\t\t\tif (normalizedWeights === undefined && source === undefined) return undefined\n\t\t\treturn {\n\t\t\t\ttype: 'weight',\n\t\t\t\tfield,\n\t\t\t\t...(normalizedWeights !== undefined ? { weights: normalizedWeights } : {}),\n\t\t\t\t...(typeof source === 'string' ? { source } : {}),\n\t\t\t}\n\t\t}\n\t\tdefault:\n\t\t\treturn undefined\n\t}\n}\n\n/**\n * Structural guard: returns a valid CalcExpression if `value` is structurally sound (depth-guarded\n * at 64), otherwise undefined. Never throws. `allowed` admits registered extension names (source\n * keys, custom function names); without it only the built-in grammar passes, so an un-threaded\n * caller can never validate an expression the evaluator has no values for.\n */\nexport const normalizeCalc = (value: unknown, allowed?: CalcAllowed): CalcExpression | undefined =>\n\tnormalizeNode(value, 0, allowed)\n"],"mappings":";;AAYA,MAAM,QAAQ,MAA6B,SAAgC,SAAS,CAAC;AAErF,MAAM,YAAY,MACjB,MAAM,QAAQ,OAAO,MAAM,YAAY,CAAC,MAAM,QAAQ,CAAC;AAExD,MAAM,iBACL,OACA,OACA,YACgC;CAChC,IAAI,QAAA,IAAmB,OAAO,KAAA;CAC9B,IAAI,CAAC,SAAS,KAAK,GAAG,OAAO,KAAA;CAE7B,QAAQ,MAAM,MAAd;EACC,KAAK,OAAO;GACX,MAAM,EAAE,OAAO,MAAM;GACrB,IAAI,OAAO,MAAM,YAAY,CAAC,OAAO,SAAS,CAAC,GAAG,OAAO,KAAA;GACzD,OAAO;IAAE,MAAM;IAAO,OAAO;GAAE;EAChC;EACA,KAAK,OAAO;GACX,MAAM,EAAE,UAAU;GAClB,IAAI,OAAO,UAAU,UAAU,OAAO,KAAA;GACtC,OAAO;IAAE,MAAM;IAAO;GAAM;EAC7B;EACA,KAAK,MAAM;GACV,MAAM,EAAE,IAAI,MAAM,UAAU;GAC5B,IAAI,CAAC,KAAK,EAAE,GAAG,OAAO,KAAA;GACtB,MAAM,IAAI,cAAc,MAAM,QAAQ,GAAG,OAAO;GAChD,IAAI,CAAC,GAAG,OAAO,KAAA;GACf,MAAM,IAAI,cAAc,OAAO,QAAQ,GAAG,OAAO;GACjD,IAAI,CAAC,GAAG,OAAO,KAAA;GACf,OAAO;IAAE,MAAM;IAAM;IAAI,MAAM;IAAG,OAAO;GAAE;EAC5C;EACA,KAAK,OAAO;GACX,MAAM,UAAU,cAAc,MAAM,SAAS,QAAQ,GAAG,OAAO;GAC/D,IAAI,CAAC,SAAS,OAAO,KAAA;GACrB,OAAO;IAAE,MAAM;IAAO;GAAQ;EAC/B;EACA,KAAK,MAAM;GACV,MAAM,EAAE,IAAI,SAAS;GACrB,IAAI,OAAO,OAAO,UAAU,OAAO,KAAA;GACnC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,SAAS,WAAW,IAAI,EAAE,GAAG,OAAO,KAAA;GAC1D,IAAI,CAAC,MAAM,QAAQ,IAAI,GAAG,OAAO,KAAA;GACjC,MAAM,iBAAmC,CAAC;GAC1C,KAAK,MAAM,OAAO,MAAM;IACvB,MAAM,IAAI,cAAc,KAAK,QAAQ,GAAG,OAAO;IAC/C,IAAI,CAAC,GAAG,OAAO,KAAA;IACf,eAAe,KAAK,CAAC;GACtB;GACA,OAAO;IAAE,MAAM;IAAM;IAAI,MAAM;GAAe;EAC/C;EACA,KAAK,UAAU;GACd,MAAM,EAAE,WAAW;GACnB,IAAI,OAAO,WAAW,UAAU,OAAO,KAAA;GACvC,IAAI,CAAC,SAAS,SAAS,IAAI,MAAM,GAAG,OAAO,KAAA;GAC3C,OAAO;IAAE,MAAM;IAAU;GAAO;EACjC;EACA,KAAK,UAAU;GACd,MAAM,EAAE,OAAO,SAAS,WAAW;GACnC,IAAI,OAAO,UAAU,UAAU,OAAO,KAAA;GACtC,IAAI,WAAW,KAAA;QACV,OAAO,WAAW,YAAY,CAAC,SAAS,SAAS,IAAI,MAAM,GAAG,OAAO,KAAA;GAAA;GAE1E,IAAI;GACJ,IAAI,YAAY,KAAA,GAAW;IAC1B,IAAI,CAAC,SAAS,OAAO,GAAG,OAAO,KAAA;IAC/B,oBAAoB,CAAC;IACrB,KAAK,MAAM,CAAC,GAAG,MAAM,OAAO,QAAQ,OAAO,GAAG;KAC7C,IAAI,OAAO,MAAM,YAAY,CAAC,OAAO,SAAS,CAAC,GAAG,OAAO,KAAA;KACzD,kBAAkB,KAAK;IACxB;GACD;GAEA,IAAI,sBAAsB,KAAA,KAAa,WAAW,KAAA,GAAW,OAAO,KAAA;GACpE,OAAO;IACN,MAAM;IACN;IACA,GAAI,sBAAsB,KAAA,IAAY,EAAE,SAAS,kBAAkB,IAAI,CAAC;IACxE,GAAI,OAAO,WAAW,WAAW,EAAE,OAAO,IAAI,CAAC;GAChD;EACD;EACA,SACC;CACF;AACD;;;;;;;AAQA,MAAa,iBAAiB,OAAgB,YAC7C,cAAc,OAAO,GAAG,OAAO"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Payload, PayloadRequest } from "payload";
|
|
2
|
+
|
|
3
|
+
//#region src/calc/registry.d.ts
|
|
4
|
+
type CalcSourceResolveArgs = {
|
|
5
|
+
form: {
|
|
6
|
+
id: number | string;
|
|
7
|
+
} & Record<string, unknown>;
|
|
8
|
+
payload: Payload;
|
|
9
|
+
/**
|
|
10
|
+
* On public form reads and submits this is an unauthenticated visitor request: never feed data
|
|
11
|
+
* derived from it into access-escalated queries, and gate any per-user-sensitive number on
|
|
12
|
+
* `req.user` (resolved values are embedded on every readable form document).
|
|
13
|
+
*/
|
|
14
|
+
req?: PayloadRequest;
|
|
15
|
+
};
|
|
16
|
+
type CalcWeightResolveArgs = CalcSourceResolveArgs & {
|
|
17
|
+
/** The field instance whose options are being priced (name, blockType, options, custom config). */field: Record<string, unknown> & {
|
|
18
|
+
name: string;
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* A named server-side value resolver the calculation field can reference. Values resolve on the
|
|
23
|
+
* server (render embedding and again at submit), so the client never supplies them. A source may
|
|
24
|
+
* offer either mode or both; an expression using a mode the source does not implement fails
|
|
25
|
+
* loudly at resolution.
|
|
26
|
+
*/
|
|
27
|
+
type CalcSource = {
|
|
28
|
+
label: string | Record<string, string>; /** Scalar mode: one number for the whole form render/submission. */
|
|
29
|
+
resolve?: (args: CalcSourceResolveArgs) => number | Promise<number>; /** Weight mode: per-option values for a chosen field, keyed by option value. */
|
|
30
|
+
resolveWeights?: (args: CalcWeightResolveArgs) => Record<string, number> | Promise<Record<string, number>>;
|
|
31
|
+
};
|
|
32
|
+
/** A host-registered calculation function; `apply` must be pure and sync (it runs isomorphically in the live preview). */
|
|
33
|
+
type CalcFunction = {
|
|
34
|
+
label: string | Record<string, string>;
|
|
35
|
+
apply: (args: number[]) => number;
|
|
36
|
+
};
|
|
37
|
+
/** Identity helper: define a calc source once with full typing (the `defineFormField` precedent). */
|
|
38
|
+
declare const defineCalcSource: (source: CalcSource) => CalcSource;
|
|
39
|
+
/** Identity helper: define a calc function once with full typing (the `defineFormField` precedent). */
|
|
40
|
+
declare const defineCalcFunction: (fn: CalcFunction) => CalcFunction;
|
|
41
|
+
//#endregion
|
|
42
|
+
export { CalcFunction, CalcSource, CalcSourceResolveArgs, CalcWeightResolveArgs, defineCalcFunction, defineCalcSource };
|
|
43
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { CALC_FNS } from "./types.js";
|
|
2
|
+
//#region src/calc/registry.ts
|
|
3
|
+
/** Identity helper: define a calc source once with full typing (the `defineFormField` precedent). */
|
|
4
|
+
const defineCalcSource = (source) => source;
|
|
5
|
+
/** Identity helper: define a calc function once with full typing (the `defineFormField` precedent). */
|
|
6
|
+
const defineCalcFunction = (fn) => fn;
|
|
7
|
+
/**
|
|
8
|
+
* Fail fast at boot when a registered calc function key collides with a built-in. The evaluator
|
|
9
|
+
* always resolves built-ins first, so a colliding custom function could never run; rather than let
|
|
10
|
+
* it be shadowed quietly, throw a clear error naming the collision so the author renames it.
|
|
11
|
+
*/
|
|
12
|
+
const assertNoCalcFunctionCollision = (functions) => {
|
|
13
|
+
for (const key of Object.keys(functions)) if (CALC_FNS.includes(key)) throw new Error(`@10x-media/form-builder: calculation function "${key}" collides with the built-in function "${key}". Rename the custom function.`);
|
|
14
|
+
};
|
|
15
|
+
const CALC_SOURCE_KEY_PATTERN = /^[\w.-]+$/;
|
|
16
|
+
/**
|
|
17
|
+
* Fail fast at boot on a calc source key outside `[\w.-]`. Resolved weight maps are keyed
|
|
18
|
+
* `source + ' ' + field` (`calcWeightKey`), so the separator char must never appear in a source
|
|
19
|
+
* key or two different (source, field) pairs could collide on one map.
|
|
20
|
+
*/
|
|
21
|
+
const assertValidCalcSourceKeys = (sources) => {
|
|
22
|
+
for (const key of Object.keys(sources)) if (!CALC_SOURCE_KEY_PATTERN.test(key)) throw new Error(`@10x-media/form-builder: calculation source key "${key}" is invalid. Use only letters, digits, "_", "." or "-".`);
|
|
23
|
+
};
|
|
24
|
+
//#endregion
|
|
25
|
+
export { assertNoCalcFunctionCollision, assertValidCalcSourceKeys, defineCalcFunction, defineCalcSource };
|
|
26
|
+
|
|
27
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","names":[],"sources":["../../src/calc/registry.ts"],"sourcesContent":["import type { Payload, PayloadRequest } from 'payload'\nimport { CALC_FNS } from './types'\n\nexport type CalcSourceResolveArgs = {\n\tform: { id: number | string } & Record<string, unknown>\n\tpayload: Payload\n\t/**\n\t * On public form reads and submits this is an unauthenticated visitor request: never feed data\n\t * derived from it into access-escalated queries, and gate any per-user-sensitive number on\n\t * `req.user` (resolved values are embedded on every readable form document).\n\t */\n\treq?: PayloadRequest\n}\n\nexport type CalcWeightResolveArgs = CalcSourceResolveArgs & {\n\t/** The field instance whose options are being priced (name, blockType, options, custom config). */\n\tfield: Record<string, unknown> & { name: string }\n}\n\n/**\n * A named server-side value resolver the calculation field can reference. Values resolve on the\n * server (render embedding and again at submit), so the client never supplies them. A source may\n * offer either mode or both; an expression using a mode the source does not implement fails\n * loudly at resolution.\n */\nexport type CalcSource = {\n\tlabel: string | Record<string, string>\n\t/** Scalar mode: one number for the whole form render/submission. */\n\tresolve?: (args: CalcSourceResolveArgs) => number | Promise<number>\n\t/** Weight mode: per-option values for a chosen field, keyed by option value. */\n\tresolveWeights?: (\n\t\targs: CalcWeightResolveArgs\n\t) => Record<string, number> | Promise<Record<string, number>>\n}\n\n/** A host-registered calculation function; `apply` must be pure and sync (it runs isomorphically in the live preview). */\nexport type CalcFunction = {\n\tlabel: string | Record<string, string>\n\tapply: (args: number[]) => number\n}\n\n/** Identity helper: define a calc source once with full typing (the `defineFormField` precedent). */\nexport const defineCalcSource = (source: CalcSource): CalcSource => source\n\n/** Identity helper: define a calc function once with full typing (the `defineFormField` precedent). */\nexport const defineCalcFunction = (fn: CalcFunction): CalcFunction => fn\n\n/**\n * Fail fast at boot when a registered calc function key collides with a built-in. The evaluator\n * always resolves built-ins first, so a colliding custom function could never run; rather than let\n * it be shadowed quietly, throw a clear error naming the collision so the author renames it.\n */\nexport const assertNoCalcFunctionCollision = (functions: Record<string, CalcFunction>): void => {\n\tfor (const key of Object.keys(functions)) {\n\t\tif ((CALC_FNS as readonly string[]).includes(key)) {\n\t\t\tthrow new Error(\n\t\t\t\t`@10x-media/form-builder: calculation function \"${key}\" collides with the built-in function \"${key}\". Rename the custom function.`\n\t\t\t)\n\t\t}\n\t}\n}\n\nconst CALC_SOURCE_KEY_PATTERN = /^[\\w.-]+$/\n\n/**\n * Fail fast at boot on a calc source key outside `[\\w.-]`. Resolved weight maps are keyed\n * `source + ' ' + field` (`calcWeightKey`), so the separator char must never appear in a source\n * key or two different (source, field) pairs could collide on one map.\n */\nexport const assertValidCalcSourceKeys = (sources: Record<string, CalcSource>): void => {\n\tfor (const key of Object.keys(sources)) {\n\t\tif (!CALC_SOURCE_KEY_PATTERN.test(key)) {\n\t\t\tthrow new Error(\n\t\t\t\t`@10x-media/form-builder: calculation source key \"${key}\" is invalid. Use only letters, digits, \"_\", \".\" or \"-\".`\n\t\t\t)\n\t\t}\n\t}\n}\n"],"mappings":";;;AA0CA,MAAa,oBAAoB,WAAmC;;AAGpE,MAAa,sBAAsB,OAAmC;;;;;;AAOtE,MAAa,iCAAiC,cAAkD;CAC/F,KAAK,MAAM,OAAO,OAAO,KAAK,SAAS,GACtC,IAAK,SAA+B,SAAS,GAAG,GAC/C,MAAM,IAAI,MACT,kDAAkD,IAAI,yCAAyC,IAAI,+BACpG;AAGH;AAEA,MAAM,0BAA0B;;;;;;AAOhC,MAAa,6BAA6B,YAA8C;CACvF,KAAK,MAAM,OAAO,OAAO,KAAK,OAAO,GACpC,IAAI,CAAC,wBAAwB,KAAK,GAAG,GACpC,MAAM,IAAI,MACT,oDAAoD,IAAI,yDACzD;AAGH"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { FormFieldInstance } from "../submissions/types.js";
|
|
2
|
+
import { CalcResolved } from "./evaluate.js";
|
|
3
|
+
import { CalcSource } from "./registry.js";
|
|
4
|
+
import { Payload, PayloadRequest } from "payload";
|
|
5
|
+
|
|
6
|
+
//#region src/calc/resolveCalcContext.d.ts
|
|
7
|
+
/** Whether any calc field's expression references a registered calc source (scalar or weight mode). */
|
|
8
|
+
declare const calcUsesSources: (fields: FormFieldInstance[]) => boolean;
|
|
9
|
+
type ResolveCalcContextArgs = {
|
|
10
|
+
fields: FormFieldInstance[]; /** The registered calc sources (plugin option `calc.sources`). */
|
|
11
|
+
sources: Record<string, CalcSource>;
|
|
12
|
+
form: {
|
|
13
|
+
id: number | string;
|
|
14
|
+
} & Record<string, unknown>;
|
|
15
|
+
payload: Payload;
|
|
16
|
+
req?: PayloadRequest;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Resolve every calc source a form's expressions reference: used scalar keys through `resolve`,
|
|
20
|
+
* used (source, field) weight pairs through `resolveWeights` with the referenced field instance,
|
|
21
|
+
* each exactly once. A weight pair whose field instance is missing resolves to an empty map. A
|
|
22
|
+
* used-but-unregistered key (or a mode the source does not implement) and any resolver failure
|
|
23
|
+
* THROW: these values are money math, so the caller decides how loud a failure is (submit rejects,
|
|
24
|
+
* the render hook catches and degrades). Custom functions are not resolved here; they come straight
|
|
25
|
+
* off the registry per environment.
|
|
26
|
+
*/
|
|
27
|
+
declare const resolveCalcContext: ({
|
|
28
|
+
fields,
|
|
29
|
+
sources,
|
|
30
|
+
form,
|
|
31
|
+
payload,
|
|
32
|
+
req
|
|
33
|
+
}: ResolveCalcContextArgs) => Promise<CalcResolved>;
|
|
34
|
+
//#endregion
|
|
35
|
+
export { ResolveCalcContextArgs, calcUsesSources, resolveCalcContext };
|
|
36
|
+
//# sourceMappingURL=resolveCalcContext.d.ts.map
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { calcWeightKey } from "./evaluate.js";
|
|
2
|
+
import { calcExpressionOf } from "./computeCalcFields.js";
|
|
3
|
+
//#region src/calc/resolveCalcContext.ts
|
|
4
|
+
const collectNode = (expr, usage, depth) => {
|
|
5
|
+
if (depth > 64 || expr == null || typeof expr !== "object") return;
|
|
6
|
+
switch (expr.type) {
|
|
7
|
+
case "source":
|
|
8
|
+
usage.scalars.add(expr.source);
|
|
9
|
+
return;
|
|
10
|
+
case "weight":
|
|
11
|
+
if (typeof expr.source === "string") usage.weightPairs.set(calcWeightKey(expr.source, expr.field), {
|
|
12
|
+
source: expr.source,
|
|
13
|
+
field: expr.field
|
|
14
|
+
});
|
|
15
|
+
return;
|
|
16
|
+
case "op":
|
|
17
|
+
collectNode(expr.left, usage, depth + 1);
|
|
18
|
+
collectNode(expr.right, usage, depth + 1);
|
|
19
|
+
return;
|
|
20
|
+
case "neg":
|
|
21
|
+
collectNode(expr.operand, usage, depth + 1);
|
|
22
|
+
return;
|
|
23
|
+
case "fn":
|
|
24
|
+
if (Array.isArray(expr.args)) for (const arg of expr.args) collectNode(arg, usage, depth + 1);
|
|
25
|
+
return;
|
|
26
|
+
default: return;
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
const usageOf = (fields) => {
|
|
30
|
+
const usage = {
|
|
31
|
+
scalars: /* @__PURE__ */ new Set(),
|
|
32
|
+
weightPairs: /* @__PURE__ */ new Map()
|
|
33
|
+
};
|
|
34
|
+
for (const field of fields) {
|
|
35
|
+
const expr = calcExpressionOf(field);
|
|
36
|
+
if (expr) collectNode(expr, usage, 0);
|
|
37
|
+
}
|
|
38
|
+
return usage;
|
|
39
|
+
};
|
|
40
|
+
/** Whether any calc field's expression references a registered calc source (scalar or weight mode). */
|
|
41
|
+
const calcUsesSources = (fields) => {
|
|
42
|
+
const usage = usageOf(fields);
|
|
43
|
+
return usage.scalars.size > 0 || usage.weightPairs.size > 0;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Resolve every calc source a form's expressions reference: used scalar keys through `resolve`,
|
|
47
|
+
* used (source, field) weight pairs through `resolveWeights` with the referenced field instance,
|
|
48
|
+
* each exactly once. A weight pair whose field instance is missing resolves to an empty map. A
|
|
49
|
+
* used-but-unregistered key (or a mode the source does not implement) and any resolver failure
|
|
50
|
+
* THROW: these values are money math, so the caller decides how loud a failure is (submit rejects,
|
|
51
|
+
* the render hook catches and degrades). Custom functions are not resolved here; they come straight
|
|
52
|
+
* off the registry per environment.
|
|
53
|
+
*/
|
|
54
|
+
const resolveCalcContext = async ({ fields, sources, form, payload, req }) => {
|
|
55
|
+
const usage = usageOf(fields);
|
|
56
|
+
if (usage.scalars.size === 0 && usage.weightPairs.size === 0) return {};
|
|
57
|
+
const resolvedSources = {};
|
|
58
|
+
for (const key of usage.scalars) {
|
|
59
|
+
const source = sources[key];
|
|
60
|
+
if (!source?.resolve) throw new Error(`@10x-media/form-builder: calculation expression references source "${key}", which is not registered or has no \`resolve\`.`);
|
|
61
|
+
resolvedSources[key] = await source.resolve({
|
|
62
|
+
form,
|
|
63
|
+
payload,
|
|
64
|
+
req
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
const resolvedWeights = {};
|
|
68
|
+
for (const [key, pair] of usage.weightPairs) {
|
|
69
|
+
const source = sources[pair.source];
|
|
70
|
+
if (!source?.resolveWeights) throw new Error(`@10x-media/form-builder: calculation expression references weights from source "${pair.source}", which is not registered or has no \`resolveWeights\`.`);
|
|
71
|
+
const instance = fields.find((field) => field.name === pair.field);
|
|
72
|
+
resolvedWeights[key] = instance ? await source.resolveWeights({
|
|
73
|
+
form,
|
|
74
|
+
payload,
|
|
75
|
+
req,
|
|
76
|
+
field: instance
|
|
77
|
+
}) : {};
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
...usage.scalars.size > 0 ? { sources: resolvedSources } : {},
|
|
81
|
+
...usage.weightPairs.size > 0 ? { weights: resolvedWeights } : {}
|
|
82
|
+
};
|
|
83
|
+
};
|
|
84
|
+
//#endregion
|
|
85
|
+
export { calcUsesSources, resolveCalcContext };
|
|
86
|
+
|
|
87
|
+
//# sourceMappingURL=resolveCalcContext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolveCalcContext.js","names":[],"sources":["../../src/calc/resolveCalcContext.ts"],"sourcesContent":["import type { Payload, PayloadRequest } from 'payload'\nimport type { FormFieldInstance } from '../submissions/types'\nimport { calcExpressionOf } from './computeCalcFields'\nimport { type CalcResolved, calcWeightKey } from './evaluate'\nimport type { CalcSource, CalcWeightResolveArgs } from './registry'\nimport { type CalcExpression, MAX_DEPTH } from './types'\n\ntype CalcSourceUsage = {\n\tscalars: Set<string>\n\t/** Keyed by `calcWeightKey(source, field)`, deduped across expressions. */\n\tweightPairs: Map<string, { source: string; field: string }>\n}\n\nconst collectNode = (expr: CalcExpression, usage: CalcSourceUsage, depth: number): void => {\n\tif (depth > MAX_DEPTH || expr == null || typeof expr !== 'object') return\n\tswitch (expr.type) {\n\t\tcase 'source':\n\t\t\tusage.scalars.add(expr.source)\n\t\t\treturn\n\t\tcase 'weight':\n\t\t\tif (typeof expr.source === 'string') {\n\t\t\t\tusage.weightPairs.set(calcWeightKey(expr.source, expr.field), {\n\t\t\t\t\tsource: expr.source,\n\t\t\t\t\tfield: expr.field,\n\t\t\t\t})\n\t\t\t}\n\t\t\treturn\n\t\tcase 'op':\n\t\t\tcollectNode(expr.left, usage, depth + 1)\n\t\t\tcollectNode(expr.right, usage, depth + 1)\n\t\t\treturn\n\t\tcase 'neg':\n\t\t\tcollectNode(expr.operand, usage, depth + 1)\n\t\t\treturn\n\t\tcase 'fn':\n\t\t\tif (Array.isArray(expr.args)) {\n\t\t\t\tfor (const arg of expr.args) collectNode(arg, usage, depth + 1)\n\t\t\t}\n\t\t\treturn\n\t\tdefault:\n\t\t\treturn\n\t}\n}\n\nconst usageOf = (fields: FormFieldInstance[]): CalcSourceUsage => {\n\tconst usage: CalcSourceUsage = { scalars: new Set(), weightPairs: new Map() }\n\tfor (const field of fields) {\n\t\tconst expr = calcExpressionOf(field)\n\t\tif (expr) collectNode(expr, usage, 0)\n\t}\n\treturn usage\n}\n\n/** Whether any calc field's expression references a registered calc source (scalar or weight mode). */\nexport const calcUsesSources = (fields: FormFieldInstance[]): boolean => {\n\tconst usage = usageOf(fields)\n\treturn usage.scalars.size > 0 || usage.weightPairs.size > 0\n}\n\nexport type ResolveCalcContextArgs = {\n\tfields: FormFieldInstance[]\n\t/** The registered calc sources (plugin option `calc.sources`). */\n\tsources: Record<string, CalcSource>\n\tform: { id: number | string } & Record<string, unknown>\n\tpayload: Payload\n\treq?: PayloadRequest\n}\n\n/**\n * Resolve every calc source a form's expressions reference: used scalar keys through `resolve`,\n * used (source, field) weight pairs through `resolveWeights` with the referenced field instance,\n * each exactly once. A weight pair whose field instance is missing resolves to an empty map. A\n * used-but-unregistered key (or a mode the source does not implement) and any resolver failure\n * THROW: these values are money math, so the caller decides how loud a failure is (submit rejects,\n * the render hook catches and degrades). Custom functions are not resolved here; they come straight\n * off the registry per environment.\n */\nexport const resolveCalcContext = async ({\n\tfields,\n\tsources,\n\tform,\n\tpayload,\n\treq,\n}: ResolveCalcContextArgs): Promise<CalcResolved> => {\n\tconst usage = usageOf(fields)\n\tif (usage.scalars.size === 0 && usage.weightPairs.size === 0) {\n\t\treturn {}\n\t}\n\tconst resolvedSources: Record<string, number> = {}\n\tfor (const key of usage.scalars) {\n\t\tconst source = sources[key]\n\t\tif (!source?.resolve) {\n\t\t\tthrow new Error(\n\t\t\t\t`@10x-media/form-builder: calculation expression references source \"${key}\", which is not registered or has no \\`resolve\\`.`\n\t\t\t)\n\t\t}\n\t\tresolvedSources[key] = await source.resolve({ form, payload, req })\n\t}\n\tconst resolvedWeights: Record<string, Record<string, number>> = {}\n\tfor (const [key, pair] of usage.weightPairs) {\n\t\tconst source = sources[pair.source]\n\t\tif (!source?.resolveWeights) {\n\t\t\tthrow new Error(\n\t\t\t\t`@10x-media/form-builder: calculation expression references weights from source \"${pair.source}\", which is not registered or has no \\`resolveWeights\\`.`\n\t\t\t)\n\t\t}\n\t\tconst instance = fields.find((field) => field.name === pair.field)\n\t\tresolvedWeights[key] = instance\n\t\t\t? await source.resolveWeights({\n\t\t\t\t\tform,\n\t\t\t\t\tpayload,\n\t\t\t\t\treq,\n\t\t\t\t\tfield: instance as CalcWeightResolveArgs['field'],\n\t\t\t\t})\n\t\t\t: {}\n\t}\n\treturn {\n\t\t...(usage.scalars.size > 0 ? { sources: resolvedSources } : {}),\n\t\t...(usage.weightPairs.size > 0 ? { weights: resolvedWeights } : {}),\n\t}\n}\n"],"mappings":";;;AAaA,MAAM,eAAe,MAAsB,OAAwB,UAAwB;CAC1F,IAAI,QAAA,MAAqB,QAAQ,QAAQ,OAAO,SAAS,UAAU;CACnE,QAAQ,KAAK,MAAb;EACC,KAAK;GACJ,MAAM,QAAQ,IAAI,KAAK,MAAM;GAC7B;EACD,KAAK;GACJ,IAAI,OAAO,KAAK,WAAW,UAC1B,MAAM,YAAY,IAAI,cAAc,KAAK,QAAQ,KAAK,KAAK,GAAG;IAC7D,QAAQ,KAAK;IACb,OAAO,KAAK;GACb,CAAC;GAEF;EACD,KAAK;GACJ,YAAY,KAAK,MAAM,OAAO,QAAQ,CAAC;GACvC,YAAY,KAAK,OAAO,OAAO,QAAQ,CAAC;GACxC;EACD,KAAK;GACJ,YAAY,KAAK,SAAS,OAAO,QAAQ,CAAC;GAC1C;EACD,KAAK;GACJ,IAAI,MAAM,QAAQ,KAAK,IAAI,GAC1B,KAAK,MAAM,OAAO,KAAK,MAAM,YAAY,KAAK,OAAO,QAAQ,CAAC;GAE/D;EACD,SACC;CACF;AACD;AAEA,MAAM,WAAW,WAAiD;CACjE,MAAM,QAAyB;EAAE,yBAAS,IAAI,IAAI;EAAG,6BAAa,IAAI,IAAI;CAAE;CAC5E,KAAK,MAAM,SAAS,QAAQ;EAC3B,MAAM,OAAO,iBAAiB,KAAK;EACnC,IAAI,MAAM,YAAY,MAAM,OAAO,CAAC;CACrC;CACA,OAAO;AACR;;AAGA,MAAa,mBAAmB,WAAyC;CACxE,MAAM,QAAQ,QAAQ,MAAM;CAC5B,OAAO,MAAM,QAAQ,OAAO,KAAK,MAAM,YAAY,OAAO;AAC3D;;;;;;;;;;AAoBA,MAAa,qBAAqB,OAAO,EACxC,QACA,SACA,MACA,SACA,UACoD;CACpD,MAAM,QAAQ,QAAQ,MAAM;CAC5B,IAAI,MAAM,QAAQ,SAAS,KAAK,MAAM,YAAY,SAAS,GAC1D,OAAO,CAAC;CAET,MAAM,kBAA0C,CAAC;CACjD,KAAK,MAAM,OAAO,MAAM,SAAS;EAChC,MAAM,SAAS,QAAQ;EACvB,IAAI,CAAC,QAAQ,SACZ,MAAM,IAAI,MACT,sEAAsE,IAAI,kDAC3E;EAED,gBAAgB,OAAO,MAAM,OAAO,QAAQ;GAAE;GAAM;GAAS;EAAI,CAAC;CACnE;CACA,MAAM,kBAA0D,CAAC;CACjE,KAAK,MAAM,CAAC,KAAK,SAAS,MAAM,aAAa;EAC5C,MAAM,SAAS,QAAQ,KAAK;EAC5B,IAAI,CAAC,QAAQ,gBACZ,MAAM,IAAI,MACT,mFAAmF,KAAK,OAAO,yDAChG;EAED,MAAM,WAAW,OAAO,MAAM,UAAU,MAAM,SAAS,KAAK,KAAK;EACjE,gBAAgB,OAAO,WACpB,MAAM,OAAO,eAAe;GAC5B;GACA;GACA;GACA,OAAO;EACR,CAAC,IACA,CAAC;CACL;CACA,OAAO;EACN,GAAI,MAAM,QAAQ,OAAO,IAAI,EAAE,SAAS,gBAAgB,IAAI,CAAC;EAC7D,GAAI,MAAM,YAAY,OAAO,IAAI,EAAE,SAAS,gBAAgB,IAAI,CAAC;CAClE;AACD"}
|
package/dist/calc/types.d.ts
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
//#region src/calc/types.d.ts
|
|
2
|
-
/**
|
|
2
|
+
/** Canonical operator grammar; `CalcExpression`, `normalizeCalc`, and the admin editor's jsonSchema all derive from this list. */
|
|
3
|
+
declare const CALC_OPS: readonly ["+", "-", "*", "/", "%"];
|
|
4
|
+
type CalcOp = (typeof CALC_OPS)[number];
|
|
5
|
+
/** Canonical function grammar; same single source of truth as `CALC_OPS`. */
|
|
6
|
+
declare const CALC_FNS: readonly ["min", "max", "round", "abs", "ceil", "floor"];
|
|
7
|
+
type CalcFn = (typeof CALC_FNS)[number];
|
|
8
|
+
/**
|
|
9
|
+
* A function slot in the AST: a built-in, or a host-registered function name (plugin option
|
|
10
|
+
* `calc.functions`). The intersection trick keeps built-in autocomplete while admitting any
|
|
11
|
+
* registered key; `normalizeCalc` gates which names are actually valid.
|
|
12
|
+
*/
|
|
13
|
+
type CalcFnName = CalcFn | (string & {});
|
|
14
|
+
/**
|
|
15
|
+
* A serializable, safe-by-construction calculation expression. No strings are parsed; the evaluator
|
|
16
|
+
* tree-walks this closed node set (never `eval`). `source` reads a server-resolved scalar from a
|
|
17
|
+
* registered calc source; a `weight` node with `source` reads its per-option map from a registered
|
|
18
|
+
* weight resolver instead of the inline `weights` (which is then ignored).
|
|
19
|
+
*/
|
|
3
20
|
type CalcExpression = {
|
|
4
21
|
type: 'lit';
|
|
5
22
|
value: number;
|
|
@@ -8,7 +25,7 @@ type CalcExpression = {
|
|
|
8
25
|
field: string;
|
|
9
26
|
} | {
|
|
10
27
|
type: 'op';
|
|
11
|
-
op:
|
|
28
|
+
op: CalcOp;
|
|
12
29
|
left: CalcExpression;
|
|
13
30
|
right: CalcExpression;
|
|
14
31
|
} | {
|
|
@@ -16,12 +33,16 @@ type CalcExpression = {
|
|
|
16
33
|
operand: CalcExpression;
|
|
17
34
|
} | {
|
|
18
35
|
type: 'fn';
|
|
19
|
-
fn:
|
|
36
|
+
fn: CalcFnName;
|
|
20
37
|
args: CalcExpression[];
|
|
38
|
+
} | {
|
|
39
|
+
type: 'source';
|
|
40
|
+
source: string;
|
|
21
41
|
} | {
|
|
22
42
|
type: 'weight';
|
|
23
43
|
field: string;
|
|
24
|
-
weights
|
|
44
|
+
weights?: Record<string, number>;
|
|
45
|
+
source?: string;
|
|
25
46
|
};
|
|
26
47
|
//#endregion
|
|
27
48
|
export { CalcExpression };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
//#region src/calc/types.ts
|
|
2
|
+
/** Canonical operator grammar; `CalcExpression`, `normalizeCalc`, and the admin editor's jsonSchema all derive from this list. */
|
|
3
|
+
const CALC_OPS = [
|
|
4
|
+
"+",
|
|
5
|
+
"-",
|
|
6
|
+
"*",
|
|
7
|
+
"/",
|
|
8
|
+
"%"
|
|
9
|
+
];
|
|
10
|
+
/** Canonical function grammar; same single source of truth as `CALC_OPS`. */
|
|
11
|
+
const CALC_FNS = [
|
|
12
|
+
"min",
|
|
13
|
+
"max",
|
|
14
|
+
"round",
|
|
15
|
+
"abs",
|
|
16
|
+
"ceil",
|
|
17
|
+
"floor"
|
|
18
|
+
];
|
|
19
|
+
const isCalcFn = (v) => CALC_FNS.includes(v);
|
|
20
|
+
//#endregion
|
|
21
|
+
export { CALC_FNS, CALC_OPS, isCalcFn };
|
|
22
|
+
|
|
23
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","names":[],"sources":["../../src/calc/types.ts"],"sourcesContent":["/** Canonical operator grammar; `CalcExpression`, `normalizeCalc`, and the admin editor's jsonSchema all derive from this list. */\nexport const CALC_OPS = ['+', '-', '*', '/', '%'] as const\nexport type CalcOp = (typeof CALC_OPS)[number]\n\n/** Canonical function grammar; same single source of truth as `CALC_OPS`. */\nexport const CALC_FNS = ['min', 'max', 'round', 'abs', 'ceil', 'floor'] as const\nexport type CalcFn = (typeof CALC_FNS)[number]\n\nexport const isCalcFn = (v: unknown): v is CalcFn => (CALC_FNS as readonly unknown[]).includes(v)\n\n/**\n * A function slot in the AST: a built-in, or a host-registered function name (plugin option\n * `calc.functions`). The intersection trick keeps built-in autocomplete while admitting any\n * registered key; `normalizeCalc` gates which names are actually valid.\n */\nexport type CalcFnName = CalcFn | (string & {})\n\n/** Recursion guard shared by `normalizeCalc` (parse) and `evaluate` (walk) so both bound depth identically. */\nexport const MAX_DEPTH = 64\n\n/**\n * A serializable, safe-by-construction calculation expression. No strings are parsed; the evaluator\n * tree-walks this closed node set (never `eval`). `source` reads a server-resolved scalar from a\n * registered calc source; a `weight` node with `source` reads its per-option map from a registered\n * weight resolver instead of the inline `weights` (which is then ignored).\n */\nexport type CalcExpression =\n\t| { type: 'lit'; value: number }\n\t| { type: 'ref'; field: string }\n\t| { type: 'op'; op: CalcOp; left: CalcExpression; right: CalcExpression }\n\t| { type: 'neg'; operand: CalcExpression }\n\t| { type: 'fn'; fn: CalcFnName; args: CalcExpression[] }\n\t| { type: 'source'; source: string }\n\t| { type: 'weight'; field: string; weights?: Record<string, number>; source?: string }\n"],"mappings":";;AACA,MAAa,WAAW;CAAC;CAAK;CAAK;CAAK;CAAK;AAAG;;AAIhD,MAAa,WAAW;CAAC;CAAO;CAAO;CAAS;CAAO;CAAQ;AAAO;AAGtE,MAAa,YAAY,MAA6B,SAAgC,SAAS,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { TranslationKey } from "../translations/keys.js";
|
|
2
|
+
|
|
3
|
+
//#region src/client/ByteSizeField.d.ts
|
|
4
|
+
/** Props: standard number field client props; label and description arrive resolved on `field`. */
|
|
5
|
+
type ByteSizeFieldProps = {
|
|
6
|
+
path?: string;
|
|
7
|
+
field?: {
|
|
8
|
+
label?: unknown;
|
|
9
|
+
admin?: {
|
|
10
|
+
description?: unknown;
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
label?: unknown;
|
|
14
|
+
/**
|
|
15
|
+
* Field description as a translation key, resolved client-side. Payload drops `admin.description`
|
|
16
|
+
* functions from client fields, so a translated description must travel as a key; a static
|
|
17
|
+
* `admin.description` string still renders when this is unset.
|
|
18
|
+
*/
|
|
19
|
+
descriptionKey?: TranslationKey;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* The `Field` mounted on a byte-count number config field (the file field's `maxSize`): a plain
|
|
23
|
+
* number input that live-previews the value as a human-readable size ('= 2.5 MB') so authors are
|
|
24
|
+
* not left decoding raw bytes. Stores the raw byte number unchanged.
|
|
25
|
+
*/
|
|
26
|
+
declare const ByteSizeField: (props: ByteSizeFieldProps) => import("react/jsx-runtime").JSX.Element;
|
|
27
|
+
//#endregion
|
|
28
|
+
export { ByteSizeField };
|
|
29
|
+
//# sourceMappingURL=ByteSizeField.d.ts.map
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { formatBytes } from "../uploads/formatBytes.js";
|
|
3
|
+
import { useTranslation as useTranslation$1 } from "../translations/useTranslation.js";
|
|
4
|
+
import { toStaticLabel } from "./toStaticLabel.js";
|
|
5
|
+
import { FieldDescription, FieldLabel, useField } from "@payloadcms/ui";
|
|
6
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
|
+
//#region src/client/ByteSizeField.tsx
|
|
8
|
+
/**
|
|
9
|
+
* The `Field` mounted on a byte-count number config field (the file field's `maxSize`): a plain
|
|
10
|
+
* number input that live-previews the value as a human-readable size ('= 2.5 MB') so authors are
|
|
11
|
+
* not left decoding raw bytes. Stores the raw byte number unchanged.
|
|
12
|
+
*/
|
|
13
|
+
const ByteSizeField = (props) => {
|
|
14
|
+
const { path, setValue, value } = useField({ path: props.path });
|
|
15
|
+
const label = toStaticLabel(props.field?.label ?? props.label);
|
|
16
|
+
const { t } = useTranslation$1();
|
|
17
|
+
const description = props.descriptionKey ? t(props.descriptionKey) : toStaticLabel(props.field?.admin?.description);
|
|
18
|
+
const handleChange = (event) => {
|
|
19
|
+
if (event.target.value === "") {
|
|
20
|
+
setValue(null);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const parsed = Number(event.target.value);
|
|
24
|
+
if (Number.isFinite(parsed)) setValue(parsed);
|
|
25
|
+
};
|
|
26
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
27
|
+
className: "field-type number",
|
|
28
|
+
style: { marginBlockEnd: "1rem" },
|
|
29
|
+
children: [/* @__PURE__ */ jsx(FieldLabel, {
|
|
30
|
+
label,
|
|
31
|
+
path
|
|
32
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
33
|
+
className: "field-type__wrap",
|
|
34
|
+
children: [
|
|
35
|
+
/* @__PURE__ */ jsx("input", {
|
|
36
|
+
id: `field-${path.replace(/\./g, "__")}`,
|
|
37
|
+
min: 0,
|
|
38
|
+
name: path,
|
|
39
|
+
onChange: handleChange,
|
|
40
|
+
type: "number",
|
|
41
|
+
value: typeof value === "number" ? value : ""
|
|
42
|
+
}),
|
|
43
|
+
typeof value === "number" && value > 0 ? /* @__PURE__ */ jsx("div", {
|
|
44
|
+
className: "field-description",
|
|
45
|
+
children: `= ${formatBytes(value)}`
|
|
46
|
+
}) : null,
|
|
47
|
+
/* @__PURE__ */ jsx(FieldDescription, {
|
|
48
|
+
description,
|
|
49
|
+
path
|
|
50
|
+
})
|
|
51
|
+
]
|
|
52
|
+
})]
|
|
53
|
+
});
|
|
54
|
+
};
|
|
55
|
+
//#endregion
|
|
56
|
+
export { ByteSizeField };
|
|
57
|
+
|
|
58
|
+
//# sourceMappingURL=ByteSizeField.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ByteSizeField.js","names":["useTranslation"],"sources":["../../src/client/ByteSizeField.tsx"],"sourcesContent":["'use client'\n\nimport { FieldDescription, FieldLabel, useField } from '@payloadcms/ui'\nimport type { ChangeEvent } from 'react'\nimport type { TranslationKey } from '../translations/keys'\nimport { useTranslation } from '../translations/useTranslation'\nimport { formatBytes } from '../uploads/formatBytes'\nimport { toStaticLabel } from './toStaticLabel'\n\n/** Props: standard number field client props; label and description arrive resolved on `field`. */\nexport type ByteSizeFieldProps = {\n\tpath?: string\n\tfield?: { label?: unknown; admin?: { description?: unknown } }\n\tlabel?: unknown\n\t/**\n\t * Field description as a translation key, resolved client-side. Payload drops `admin.description`\n\t * functions from client fields, so a translated description must travel as a key; a static\n\t * `admin.description` string still renders when this is unset.\n\t */\n\tdescriptionKey?: TranslationKey\n}\n\n/**\n * The `Field` mounted on a byte-count number config field (the file field's `maxSize`): a plain\n * number input that live-previews the value as a human-readable size ('= 2.5 MB') so authors are\n * not left decoding raw bytes. Stores the raw byte number unchanged.\n */\nexport const ByteSizeField = (props: ByteSizeFieldProps) => {\n\tconst { path, setValue, value } = useField<number>({ path: props.path })\n\tconst label = toStaticLabel(props.field?.label ?? props.label)\n\tconst { t } = useTranslation()\n\tconst description = props.descriptionKey\n\t\t? t(props.descriptionKey)\n\t\t: toStaticLabel(props.field?.admin?.description)\n\n\tconst handleChange = (event: ChangeEvent<HTMLInputElement>) => {\n\t\tif (event.target.value === '') {\n\t\t\tsetValue(null)\n\t\t\treturn\n\t\t}\n\t\tconst parsed = Number(event.target.value)\n\t\tif (Number.isFinite(parsed)) {\n\t\t\tsetValue(parsed)\n\t\t}\n\t}\n\n\treturn (\n\t\t<div className=\"field-type number\" style={{ marginBlockEnd: '1rem' }}>\n\t\t\t<FieldLabel label={label} path={path} />\n\t\t\t<div className=\"field-type__wrap\">\n\t\t\t\t<input\n\t\t\t\t\tid={`field-${path.replace(/\\./g, '__')}`}\n\t\t\t\t\tmin={0}\n\t\t\t\t\tname={path}\n\t\t\t\t\tonChange={handleChange}\n\t\t\t\t\ttype=\"number\"\n\t\t\t\t\tvalue={typeof value === 'number' ? value : ''}\n\t\t\t\t/>\n\t\t\t\t{typeof value === 'number' && value > 0 ? (\n\t\t\t\t\t<div className=\"field-description\">{`= ${formatBytes(value)}`}</div>\n\t\t\t\t) : null}\n\t\t\t\t<FieldDescription description={description} path={path} />\n\t\t\t</div>\n\t\t</div>\n\t)\n}\n"],"mappings":";;;;;;;;;;;;AA2BA,MAAa,iBAAiB,UAA8B;CAC3D,MAAM,EAAE,MAAM,UAAU,UAAU,SAAiB,EAAE,MAAM,MAAM,KAAK,CAAC;CACvE,MAAM,QAAQ,cAAc,MAAM,OAAO,SAAS,MAAM,KAAK;CAC7D,MAAM,EAAE,MAAMA,iBAAe;CAC7B,MAAM,cAAc,MAAM,iBACvB,EAAE,MAAM,cAAc,IACtB,cAAc,MAAM,OAAO,OAAO,WAAW;CAEhD,MAAM,gBAAgB,UAAyC;EAC9D,IAAI,MAAM,OAAO,UAAU,IAAI;GAC9B,SAAS,IAAI;GACb;EACD;EACA,MAAM,SAAS,OAAO,MAAM,OAAO,KAAK;EACxC,IAAI,OAAO,SAAS,MAAM,GACzB,SAAS,MAAM;CAEjB;CAEA,OACC,qBAAC,OAAD;EAAK,WAAU;EAAoB,OAAO,EAAE,gBAAgB,OAAO;YAAnE,CACC,oBAAC,YAAD;GAAmB;GAAa;EAAO,CAAA,GACvC,qBAAC,OAAD;GAAK,WAAU;aAAf;IACC,oBAAC,SAAD;KACC,IAAI,SAAS,KAAK,QAAQ,OAAO,IAAI;KACrC,KAAK;KACL,MAAM;KACN,UAAU;KACV,MAAK;KACL,OAAO,OAAO,UAAU,WAAW,QAAQ;IAC3C,CAAA;IACA,OAAO,UAAU,YAAY,QAAQ,IACrC,oBAAC,OAAD;KAAK,WAAU;eAAqB,KAAK,YAAY,KAAK;IAAS,CAAA,IAChE;IACJ,oBAAC,kBAAD;KAA+B;KAAmB;IAAO,CAAA;GACrD;IACD;;AAEP"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { CalcSourceClientMeta } from "../fields/builtin/calculation.js";
|
|
2
|
+
//#region src/client/CalcExpressionBuilder.d.ts
|
|
3
|
+
type CalcExpressionBuilderProps = {
|
|
4
|
+
path?: string;
|
|
5
|
+
field?: {
|
|
6
|
+
label?: unknown;
|
|
7
|
+
};
|
|
8
|
+
readOnly?: boolean; /** Registered calc-source metadata (key, label, modes), threaded as clientProps by `buildCalculationField`. */
|
|
9
|
+
sources?: CalcSourceClientMeta[]; /** Registered custom calc function names, so client-side normalization accepts what the server accepts. */
|
|
10
|
+
functions?: string[];
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Visual editor for the calculation field's `expression` AST, presented as a left-to-right chain.
|
|
14
|
+
* Storage shape is unchanged and `validateExpression` stays the server gate; the AST remains
|
|
15
|
+
* authorable via the API.
|
|
16
|
+
*/
|
|
17
|
+
declare const CalcExpressionBuilder: (props: CalcExpressionBuilderProps) => import("react/jsx-runtime").JSX.Element;
|
|
18
|
+
//#endregion
|
|
19
|
+
export { CalcExpressionBuilder };
|
|
20
|
+
//# sourceMappingURL=CalcExpressionBuilder.d.ts.map
|