@10x-media/form-builder 0.1.0-beta.1 → 0.1.0-beta.3
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 +34 -0
- package/README.md +4 -2
- 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 +35 -0
- package/dist/actions/body/serializeBody.js +76 -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/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/builtin/confirmation.js +28 -12
- package/dist/actions/builtin/confirmation.js.map +1 -1
- package/dist/actions/builtin/emailTeam.js +7 -9
- package/dist/actions/builtin/emailTeam.js.map +1 -1
- package/dist/actions/builtin/signedWebhook.js +21 -3
- package/dist/actions/builtin/signedWebhook.js.map +1 -1
- package/dist/actions/defineAction.d.ts +2 -1
- package/dist/actions/defineAction.js.map +1 -1
- package/dist/actions/dispatch.js +2 -1
- package/dist/actions/dispatch.js.map +1 -1
- package/dist/actions/runActions.js +8 -1
- package/dist/actions/runActions.js.map +1 -1
- package/dist/actions/task.js +7 -5
- package/dist/actions/task.js.map +1 -1
- package/dist/calc/normalizeCalc.js +5 -17
- package/dist/calc/normalizeCalc.js.map +1 -1
- package/dist/calc/types.d.ts +8 -2
- package/dist/calc/types.js +22 -0
- package/dist/calc/types.js.map +1 -0
- package/dist/client/ByteSizeField.d.ts +21 -0
- package/dist/client/ByteSizeField.js +56 -0
- package/dist/client/ByteSizeField.js.map +1 -0
- package/dist/client/ConditionBuilder.js +2 -1
- package/dist/client/ConditionBuilder.js.map +1 -1
- package/dist/client/FieldNameSelect.d.ts +20 -0
- package/dist/client/FieldNameSelect.js +58 -0
- package/dist/client/FieldNameSelect.js.map +1 -0
- package/dist/client/FlowBuilder.d.ts +0 -1
- package/dist/client/FlowBuilder.js +4 -6
- 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/admin.css +192 -0
- package/dist/client/toStaticLabel.js +13 -0
- package/dist/client/toStaticLabel.js.map +1 -0
- package/dist/collections/formSubmissions.js +60 -39
- package/dist/collections/formSubmissions.js.map +1 -1
- package/dist/collections/forms.js +143 -115
- package/dist/collections/forms.js.map +1 -1
- package/dist/collections/uploads.d.ts +2 -1
- package/dist/collections/uploads.js +22 -13
- package/dist/collections/uploads.js.map +1 -1
- package/dist/exports/client.d.ts +3 -1
- package/dist/exports/client.js +3 -1
- package/dist/exports/react.d.ts +7 -2
- package/dist/exports/react.js +6 -2
- package/dist/exports/types.d.ts +2 -1
- package/dist/fields/buildFieldBlocks.js +22 -12
- package/dist/fields/buildFieldBlocks.js.map +1 -1
- package/dist/fields/builtin/calculation.js +115 -2
- package/dist/fields/builtin/calculation.js.map +1 -1
- package/dist/fields/builtin/date.js +29 -0
- package/dist/fields/builtin/date.js.map +1 -0
- package/dist/fields/builtin/file.d.ts +15 -0
- package/dist/fields/builtin/file.js +79 -3
- package/dist/fields/builtin/file.js.map +1 -1
- package/dist/fields/builtin/index.d.ts +14 -0
- package/dist/fields/builtin/index.js +13 -2
- package/dist/fields/builtin/index.js.map +1 -1
- package/dist/fields/builtin/repeater.js +44 -0
- package/dist/fields/builtin/repeater.js.map +1 -0
- package/dist/fields/fieldNamesOfType.js +25 -0
- package/dist/fields/fieldNamesOfType.js.map +1 -0
- package/dist/fields/sharedConfig.js +30 -18
- package/dist/fields/sharedConfig.js.map +1 -1
- package/dist/fields/types.d.ts +2 -1
- package/dist/index.d.ts +38 -2
- package/dist/index.js +17 -5
- package/dist/index.js.map +1 -1
- package/dist/plugin/collectionOverrides.d.ts +22 -0
- package/dist/plugin/registerCollections.js +39 -10
- package/dist/plugin/registerCollections.js.map +1 -1
- package/dist/react/Form.d.ts +32 -3
- package/dist/react/Form.js +50 -8
- package/dist/react/Form.js.map +1 -1
- package/dist/react/FormContext.js.map +1 -1
- package/dist/react/Poll.js +1 -1
- 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/primitives/Input.d.ts +1 -1
- package/dist/react/primitives/Input.js.map +1 -1
- package/dist/react/renderers/calculation.js +1 -1
- package/dist/react/renderers/checkbox.js +1 -1
- package/dist/react/renderers/consent.js +1 -1
- package/dist/react/renderers/date.js +37 -0
- package/dist/react/renderers/date.js.map +1 -0
- package/dist/react/renderers/email.js +1 -1
- package/dist/react/renderers/file.js +20 -7
- package/dist/react/renderers/file.js.map +1 -1
- package/dist/react/renderers/index.js +4 -0
- package/dist/react/renderers/index.js.map +1 -1
- package/dist/react/renderers/number.js +1 -1
- package/dist/react/renderers/repeater.js +113 -0
- package/dist/react/renderers/repeater.js.map +1 -0
- package/dist/react/renderers/select.js +1 -1
- package/dist/react/renderers/text.js +1 -1
- package/dist/react/renderers/textarea.js +1 -1
- package/dist/spam/captcha.d.ts +3 -2
- package/dist/spam/captcha.js +3 -2
- 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/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/spamGuard.js +2 -5
- package/dist/spam/spamGuard.js.map +1 -1
- package/dist/spam/types.d.ts +2 -2
- package/dist/submissions/SubmissionAnswers.d.ts +2 -4
- package/dist/submissions/SubmissionAnswers.js +110 -34
- package/dist/submissions/SubmissionAnswers.js.map +1 -1
- package/dist/submissions/SubmissionAnswersClient.js +142 -0
- package/dist/submissions/SubmissionAnswersClient.js.map +1 -0
- package/dist/submissions/runSubmission.js +54 -2
- package/dist/submissions/runSubmission.js.map +1 -1
- package/dist/submissions/types.d.ts +2 -1
- package/dist/translations/en.js +52 -5
- package/dist/translations/en.js.map +1 -1
- package/dist/translations/keys.d.ts +51 -4
- package/dist/translations/keys.js +52 -5
- package/dist/translations/keys.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 +1 -1
- package/dist/uploads/resolveFileRef.js.map +1 -1
- package/dist/validation/builtin/index.d.ts +14 -0
- package/dist/validation/builtin/index.js +12 -1
- package/dist/validation/builtin/index.js.map +1 -1
- package/dist/validation/builtin/maxDate.js +23 -0
- package/dist/validation/builtin/maxDate.js.map +1 -0
- package/dist/validation/builtin/minDate.js +23 -0
- package/dist/validation/builtin/minDate.js.map +1 -0
- package/dist/validation/builtin/validateDateBound.js +18 -0
- package/dist/validation/builtin/validateDateBound.js.map +1 -0
- package/dist/validation/runValidation.js +1 -1
- package/dist/validation/runValidation.js.map +1 -1
- package/package.json +4 -3
- package/styles/form-builder.css +0 -190
package/dist/index.d.ts
CHANGED
|
@@ -14,11 +14,15 @@ import { PresentationDensity, PresentationDescriptor, PresentationSurface } from
|
|
|
14
14
|
import { interpolate } from "./recall/interpolate.js";
|
|
15
15
|
import { RecallResolver, buildRecallResolver, optionLabelsFor } from "./recall/resolver.js";
|
|
16
16
|
import { CAPTCHA_TOKEN_KEY, DEFAULT_HONEYPOT_FIELD } from "./spam/constants.js";
|
|
17
|
+
import { formatBytes } from "./uploads/formatBytes.js";
|
|
17
18
|
import { ActionDefinition, ActionRunArgs, AnyActionDefinition, defineAction } from "./actions/defineAction.js";
|
|
18
19
|
import { ActionOption, ActionRegistry, ActionsConfig, resolveActions } from "./actions/registry.js";
|
|
20
|
+
import { BodyConverter, BodyConverterArgs, BodyRender, defaultBodyConverters, sanitizeUrl } from "./actions/body/converters.js";
|
|
21
|
+
import { BodyContext, RichTextBodyOption, SerializeBodyArgs, serializeBody } from "./actions/body/serializeBody.js";
|
|
19
22
|
import { ActionResult } from "./actions/runActions.js";
|
|
20
23
|
import { AggregateFieldResponsesArgs, AggregateFormResponsesArgs, aggregateFieldResponses, aggregateFormResponses, fieldHasOptions } from "./aggregation/aggregateResponses.js";
|
|
21
24
|
import { ResolveResultsRequestArgs, ResolveResultsRequestResult, resolveFormResultsRequest } from "./aggregation/resolveResultsRequest.js";
|
|
25
|
+
import { CollectionOverrides } from "./plugin/collectionOverrides.js";
|
|
22
26
|
import { FORM_UPLOADS_SLUG, UploadsCollectionConfig, UploadsOption, buildUploadsCollection, resolveUploads } from "./collections/uploads.js";
|
|
23
27
|
import { FieldCondition } from "./conditions/types.js";
|
|
24
28
|
import { AnyConsentSource, ConsentLink, ConsentResolveArgs, ConsentResolved, ConsentSource, defineConsentSource } from "./consent/defineConsentSource.js";
|
|
@@ -27,6 +31,8 @@ import { ConsentProof, captureConsent } from "./consent/captureConsent.js";
|
|
|
27
31
|
import { PresentationDescriptorOption, PresentationDescriptorRegistry, PresentationsDescriptorConfig, resolvePresentationDescriptors } from "./presentations/registry.js";
|
|
28
32
|
import { CaptchaProvider, CaptchaVerifyArgs, IdentifyFn, RateLimitCheckArgs, RateLimitConfig, RateLimitResult, RateLimiter, SpamConfig, SpamMetadataConfig, SpamOption } from "./spam/types.js";
|
|
29
33
|
import { ValidationRuleOption, ValidationRuleRegistry, ValidationRulesConfig } from "./validation/registry.js";
|
|
34
|
+
import { escapeHtml } from "./actions/body/escapeHtml.js";
|
|
35
|
+
import { renderAllValues, renderAllValuesTable } from "./actions/body/wildcards.js";
|
|
30
36
|
import { defaultActionDefinitions } from "./actions/builtin/index.js";
|
|
31
37
|
import { SIGNATURE_HEADER, signPayload } from "./actions/sign.js";
|
|
32
38
|
import { aggregateRowForField, aggregateRowsForFields } from "./aggregation/aggregateRows.js";
|
|
@@ -34,14 +40,20 @@ import { normalizeCalc } from "./calc/normalizeCalc.js";
|
|
|
34
40
|
import { defaultConsentSources } from "./consent/builtin/index.js";
|
|
35
41
|
import { resolveConsentLinks } from "./consent/resolveConsentLinks.js";
|
|
36
42
|
import { resolvePublishedVersionRef } from "./consent/resolvePublishedVersionRef.js";
|
|
43
|
+
import { defaultFieldDefinitions, defaultFieldDefinitionsByType } from "./fields/builtin/index.js";
|
|
44
|
+
import { fileMimeTypeOptions } from "./fields/builtin/file.js";
|
|
37
45
|
import { defineFormField } from "./fields/defineFormField.js";
|
|
38
46
|
import { DEFAULT_PRESENTATION_NAME, defaultPresentationDescriptors } from "./presentations/defaults.js";
|
|
39
47
|
import { defineCaptchaProvider } from "./spam/captcha.js";
|
|
40
48
|
import { defaultIdentify } from "./spam/identify.js";
|
|
49
|
+
import { HcaptchaProviderOptions, hcaptchaProvider } from "./spam/providers/hcaptcha.js";
|
|
50
|
+
import { RecaptchaProviderOptions, recaptchaProvider } from "./spam/providers/recaptcha.js";
|
|
51
|
+
import { TurnstileProviderOptions, turnstileProvider } from "./spam/providers/turnstile.js";
|
|
41
52
|
import { createKvRateLimiter } from "./spam/rateLimiter.js";
|
|
42
53
|
import { resolveSpamConfig } from "./spam/resolveSpam.js";
|
|
43
54
|
import { resolveFileRef } from "./uploads/resolveFileRef.js";
|
|
44
55
|
import { captureFileRef } from "./uploads/captureFileRef.js";
|
|
56
|
+
import { defaultValidationRules, defaultValidationRulesByType } from "./validation/builtin/index.js";
|
|
45
57
|
import { defineValidationRule } from "./validation/defineValidationRule.js";
|
|
46
58
|
|
|
47
59
|
//#region src/index.d.ts
|
|
@@ -58,10 +70,34 @@ type FormBuilderPluginOptions = {
|
|
|
58
70
|
fields?: FieldTypesConfig; /** Add, override, or remove presentations. `false` removes a built-in, `true` keeps it, an object adds or replaces one. */
|
|
59
71
|
presentations?: PresentationsDescriptorConfig; /** Add, override, or remove validation rule types. `false` removes a built-in, `true` keeps it, an object adds or replaces one. */
|
|
60
72
|
rules?: ValidationRulesConfig; /** Add, override, or remove post-submit action types. `false` removes a built-in, `true` keeps it, an object adds or replaces one. */
|
|
61
|
-
actions?: ActionsConfig;
|
|
73
|
+
actions?: ActionsConfig;
|
|
74
|
+
/**
|
|
75
|
+
* Customize how rich text action bodies are rendered. `converters` spread over the default
|
|
76
|
+
* Lexical node converters; `serialize` replaces the whole pipeline (e.g. to target chat or
|
|
77
|
+
* plain-text channels instead of email HTML).
|
|
78
|
+
*/
|
|
79
|
+
richText?: RichTextBodyOption; /** Add, override, or remove consent source types. `false` removes a built-in, `true` keeps it, an object adds or replaces one. */
|
|
62
80
|
consentSources?: ConsentSourcesConfig; /** The built-in `form-uploads` collection backing file fields. `false` disables it (bring your own); an object overrides slug/upload/access/fields. */
|
|
63
81
|
uploads?: UploadsOption; /** Honeypot + rate-limiting (on by default) + a captcha adapter seam + upload-ownership scoping. `false` disables the whole subsystem. */
|
|
64
82
|
spam?: SpamOption;
|
|
83
|
+
/**
|
|
84
|
+
* When `true`, the raw `values`, `descriptors`, and `consent` JSON fields are visible in the
|
|
85
|
+
* submission admin view. Default `false` — those fields are fully represented by the
|
|
86
|
+
* `SubmissionAnswers` UI component and are noisy when shown alongside it.
|
|
87
|
+
*/
|
|
88
|
+
showSubmissionRawFields?: boolean;
|
|
89
|
+
/**
|
|
90
|
+
* Override individual plugin-managed collections using explicit spreads. Each key accepts a
|
|
91
|
+
* `CollectionOverrides` object: top-level keys are spread with the plugin's defaults (spread
|
|
92
|
+
* order per key determines who wins), hooks are appended after the plugin's own hooks, and
|
|
93
|
+
* `fields` is a function that receives the default fields and returns the final array so
|
|
94
|
+
* additions/removals are always intentional.
|
|
95
|
+
*/
|
|
96
|
+
overrides?: {
|
|
97
|
+
forms?: CollectionOverrides;
|
|
98
|
+
formSubmissions?: CollectionOverrides;
|
|
99
|
+
uploads?: CollectionOverrides;
|
|
100
|
+
};
|
|
65
101
|
};
|
|
66
102
|
declare module 'payload' {
|
|
67
103
|
interface RegisteredPlugins {
|
|
@@ -70,5 +106,5 @@ declare module 'payload' {
|
|
|
70
106
|
}
|
|
71
107
|
declare const formBuilder: (options: FormBuilderPluginOptions) => import("payload").Plugin;
|
|
72
108
|
//#endregion
|
|
73
|
-
export { type ActionDefinition, type ActionOption, type ActionRegistry, type ActionResult, type ActionRunArgs, type ActionsConfig, type AggregateFieldResponsesArgs, type AggregateFormResponsesArgs, type AggregationBucket, type AggregationRow, type AnyActionDefinition, type AnyConsentSource, type AnyFormFieldDefinition, type AnyValidationRuleDefinition, CAPTCHA_TOKEN_KEY, type CalcExpression, type CaptchaProvider, type CaptchaVerifyArgs, type ConsentLink, type ConsentProof, type ConsentResolveArgs, type ConsentResolved, type ConsentSource, type ConsentSourceOption, type ConsentSourceRegistry, type ConsentSourcesConfig, DEFAULT_HONEYPOT_FIELD, DEFAULT_PRESENTATION_NAME, FORM_UPLOADS_SLUG, type FieldAggregation, type FieldCondition, type FieldMeta, type FieldTypeOption, type FieldTypeRegistry, type FieldTypesConfig, type FileFieldConfig, type FileRef, type FileRefError, FormBuilderPluginOptions, type FormBuilderPluginOptions as PluginOptions, type FormFieldDefinition, type FormFieldFormat, type FormFieldValidate, type FormFieldValueKind, type IdentifyFn, type PrefillOptions, type PresentationDensity, type PresentationDescriptor, type PresentationDescriptorOption, type PresentationDescriptorRegistry, type PresentationSurface, type PresentationsDescriptorConfig, type RateLimitCheckArgs, type RateLimitConfig, type RateLimitResult, type RateLimiter, type RecallResolver, type ResolveResultsRequestArgs, type ResolveResultsRequestResult, SIGNATURE_HEADER, type SpamConfig, type SpamMetadataConfig, type SpamOption, type SubmissionStatusFilter, type UploadsCollectionConfig, type UploadsOption, type ValidationRuleDefinition, type ValidationRuleOption, type ValidationRuleRegistry, type ValidationRuleResult, type ValidationRulesConfig, type ValidationSeverity, aggregateFieldResponses, aggregateFormResponses, aggregateRowForField, aggregateRowsForFields, buildRecallResolver, buildUploadsCollection, calcExpressionOf, captureConsent, captureFileRef, computeCalcFields, createKvRateLimiter, defaultActionDefinitions, defaultConsentSources, defaultIdentify, defaultPresentationDescriptors, defineAction, defineCaptchaProvider, defineConsentSource, defineFormField, defineValidationRule, evaluateCalc, evaluateCondition, fieldHasOptions, formBuilder, interpolate, normalizeCalc, optionLabelsFor, resolveActions, resolveConsentLinks, resolveConsentSources, resolveFileRef, resolveFormResultsRequest, resolvePresentationDescriptors, resolvePublishedVersionRef, resolveSpamConfig, resolveUploads, signPayload, valuesFromSearchParams };
|
|
109
|
+
export { type ActionDefinition, type ActionOption, type ActionRegistry, type ActionResult, type ActionRunArgs, type ActionsConfig, type AggregateFieldResponsesArgs, type AggregateFormResponsesArgs, type AggregationBucket, type AggregationRow, type AnyActionDefinition, type AnyConsentSource, type AnyFormFieldDefinition, type AnyValidationRuleDefinition, type BodyContext, type BodyConverter, type BodyConverterArgs, type BodyRender, CAPTCHA_TOKEN_KEY, type CalcExpression, type CaptchaProvider, type CaptchaVerifyArgs, type ConsentLink, type ConsentProof, type ConsentResolveArgs, type ConsentResolved, type ConsentSource, type ConsentSourceOption, type ConsentSourceRegistry, type ConsentSourcesConfig, DEFAULT_HONEYPOT_FIELD, DEFAULT_PRESENTATION_NAME, FORM_UPLOADS_SLUG, type FieldAggregation, type FieldCondition, type FieldMeta, type FieldTypeOption, type FieldTypeRegistry, type FieldTypesConfig, type FileFieldConfig, type FileRef, type FileRefError, FormBuilderPluginOptions, type FormBuilderPluginOptions as PluginOptions, type FormFieldDefinition, type FormFieldFormat, type FormFieldValidate, type FormFieldValueKind, type HcaptchaProviderOptions, type IdentifyFn, type PrefillOptions, type PresentationDensity, type PresentationDescriptor, type PresentationDescriptorOption, type PresentationDescriptorRegistry, type PresentationSurface, type PresentationsDescriptorConfig, type RateLimitCheckArgs, type RateLimitConfig, type RateLimitResult, type RateLimiter, type RecallResolver, type RecaptchaProviderOptions, type ResolveResultsRequestArgs, type ResolveResultsRequestResult, type RichTextBodyOption, SIGNATURE_HEADER, type SerializeBodyArgs, type SpamConfig, type SpamMetadataConfig, type SpamOption, type SubmissionStatusFilter, type TurnstileProviderOptions, type UploadsCollectionConfig, type UploadsOption, type ValidationRuleDefinition, type ValidationRuleOption, type ValidationRuleRegistry, type ValidationRuleResult, type ValidationRulesConfig, type ValidationSeverity, aggregateFieldResponses, aggregateFormResponses, aggregateRowForField, aggregateRowsForFields, buildRecallResolver, buildUploadsCollection, calcExpressionOf, captureConsent, captureFileRef, computeCalcFields, createKvRateLimiter, defaultActionDefinitions, defaultBodyConverters, defaultConsentSources, defaultFieldDefinitions, defaultFieldDefinitionsByType, defaultIdentify, defaultPresentationDescriptors, defaultValidationRules, defaultValidationRulesByType, defineAction, defineCaptchaProvider, defineConsentSource, defineFormField, defineValidationRule, escapeHtml, evaluateCalc, evaluateCondition, fieldHasOptions, fileMimeTypeOptions, formBuilder, formatBytes, hcaptchaProvider, interpolate, normalizeCalc, optionLabelsFor, recaptchaProvider, renderAllValues, renderAllValuesTable, resolveActions, resolveConsentLinks, resolveConsentSources, resolveFileRef, resolveFormResultsRequest, resolvePresentationDescriptors, resolvePublishedVersionRef, resolveSpamConfig, resolveUploads, sanitizeUrl, serializeBody, signPayload, turnstileProvider, valuesFromSearchParams };
|
|
74
110
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import { interpolate } from "./recall/interpolate.js";
|
|
2
|
+
import { escapeHtml } from "./actions/body/escapeHtml.js";
|
|
3
|
+
import { defaultBodyConverters, sanitizeUrl } from "./actions/body/converters.js";
|
|
4
|
+
import { renderAllValues, renderAllValuesTable } from "./actions/body/wildcards.js";
|
|
5
|
+
import { serializeBody } from "./actions/body/serializeBody.js";
|
|
2
6
|
import { defineAction } from "./actions/defineAction.js";
|
|
3
7
|
import { SIGNATURE_HEADER, signPayload } from "./actions/sign.js";
|
|
4
8
|
import { defaultActionDefinitions } from "./actions/builtin/index.js";
|
|
@@ -8,14 +12,15 @@ import { defineConsentSource } from "./consent/defineConsentSource.js";
|
|
|
8
12
|
import { resolvePublishedVersionRef } from "./consent/resolvePublishedVersionRef.js";
|
|
9
13
|
import { defaultConsentSources } from "./consent/builtin/index.js";
|
|
10
14
|
import { resolveConsentSources } from "./consent/registry.js";
|
|
15
|
+
import { normalizeCalc } from "./calc/normalizeCalc.js";
|
|
11
16
|
import { defineFormField } from "./fields/defineFormField.js";
|
|
12
|
-
import {
|
|
17
|
+
import { fileMimeTypeOptions } from "./fields/builtin/file.js";
|
|
18
|
+
import { defaultFieldDefinitions, defaultFieldDefinitionsByType } from "./fields/builtin/index.js";
|
|
13
19
|
import { resolveFieldTypes } from "./fields/registry.js";
|
|
14
20
|
import { CAPTCHA_TOKEN_KEY, DEFAULT_HONEYPOT_FIELD } from "./spam/constants.js";
|
|
15
21
|
import { aggregateRowForField, aggregateRowsForFields } from "./aggregation/aggregateRows.js";
|
|
16
22
|
import { aggregateFieldResponses, aggregateFormResponses, fieldHasOptions } from "./aggregation/aggregateResponses.js";
|
|
17
23
|
import { resolveFormResultsRequest } from "./aggregation/resolveResultsRequest.js";
|
|
18
|
-
import { normalizeCalc } from "./calc/normalizeCalc.js";
|
|
19
24
|
import { DEFAULT_PRESENTATION_NAME, defaultPresentationDescriptors } from "./presentations/defaults.js";
|
|
20
25
|
import { evaluateCalc } from "./calc/evaluate.js";
|
|
21
26
|
import { calcExpressionOf, computeCalcFields } from "./calc/computeCalcFields.js";
|
|
@@ -31,11 +36,15 @@ import { defaultIdentify } from "./spam/identify.js";
|
|
|
31
36
|
import { createKvRateLimiter } from "./spam/rateLimiter.js";
|
|
32
37
|
import { resolveSpamConfig } from "./spam/resolveSpam.js";
|
|
33
38
|
import { defineValidationRule } from "./validation/defineValidationRule.js";
|
|
34
|
-
import { defaultValidationRules } from "./validation/builtin/index.js";
|
|
39
|
+
import { defaultValidationRules, defaultValidationRulesByType } from "./validation/builtin/index.js";
|
|
35
40
|
import { resolveValidationRules } from "./validation/registry.js";
|
|
36
41
|
import { valuesFromSearchParams } from "./prefill/valuesFromSearchParams.js";
|
|
37
42
|
import { buildRecallResolver, optionLabelsFor } from "./recall/resolver.js";
|
|
38
43
|
import { defineCaptchaProvider } from "./spam/captcha.js";
|
|
44
|
+
import { hcaptchaProvider } from "./spam/providers/hcaptcha.js";
|
|
45
|
+
import { recaptchaProvider } from "./spam/providers/recaptcha.js";
|
|
46
|
+
import { turnstileProvider } from "./spam/providers/turnstile.js";
|
|
47
|
+
import { formatBytes } from "./uploads/formatBytes.js";
|
|
39
48
|
import { definePlugin } from "payload";
|
|
40
49
|
//#region src/index.ts
|
|
41
50
|
const formBuilder = definePlugin({
|
|
@@ -58,15 +67,18 @@ const formBuilder = definePlugin({
|
|
|
58
67
|
consentRegistry,
|
|
59
68
|
presentationRegistry,
|
|
60
69
|
actionRegistry,
|
|
70
|
+
richText: options.richText,
|
|
61
71
|
hasJobsPlugin: Boolean(plugins["@10x-media/jobs"]),
|
|
62
72
|
events: options.events,
|
|
63
73
|
uploads,
|
|
64
|
-
spam
|
|
74
|
+
spam,
|
|
75
|
+
showSubmissionRawFields: options.showSubmissionRawFields ?? false,
|
|
76
|
+
overrides: options.overrides
|
|
65
77
|
});
|
|
66
78
|
return config;
|
|
67
79
|
}
|
|
68
80
|
});
|
|
69
81
|
//#endregion
|
|
70
|
-
export { CAPTCHA_TOKEN_KEY, DEFAULT_HONEYPOT_FIELD, DEFAULT_PRESENTATION_NAME, FORM_UPLOADS_SLUG, SIGNATURE_HEADER, aggregateFieldResponses, aggregateFormResponses, aggregateRowForField, aggregateRowsForFields, buildRecallResolver, buildUploadsCollection, calcExpressionOf, captureConsent, captureFileRef, computeCalcFields, createKvRateLimiter, defaultActionDefinitions, defaultConsentSources, defaultIdentify, defaultPresentationDescriptors, defineAction, defineCaptchaProvider, defineConsentSource, defineFormField, defineValidationRule, evaluateCalc, evaluateCondition, fieldHasOptions, formBuilder, interpolate, normalizeCalc, optionLabelsFor, resolveActions, resolveConsentLinks, resolveConsentSources, resolveFileRef, resolveFormResultsRequest, resolvePresentationDescriptors, resolvePublishedVersionRef, resolveSpamConfig, resolveUploads, signPayload, valuesFromSearchParams };
|
|
82
|
+
export { CAPTCHA_TOKEN_KEY, DEFAULT_HONEYPOT_FIELD, DEFAULT_PRESENTATION_NAME, FORM_UPLOADS_SLUG, SIGNATURE_HEADER, aggregateFieldResponses, aggregateFormResponses, aggregateRowForField, aggregateRowsForFields, buildRecallResolver, buildUploadsCollection, calcExpressionOf, captureConsent, captureFileRef, computeCalcFields, createKvRateLimiter, defaultActionDefinitions, defaultBodyConverters, defaultConsentSources, defaultFieldDefinitions, defaultFieldDefinitionsByType, defaultIdentify, defaultPresentationDescriptors, defaultValidationRules, defaultValidationRulesByType, defineAction, defineCaptchaProvider, defineConsentSource, defineFormField, defineValidationRule, escapeHtml, evaluateCalc, evaluateCondition, fieldHasOptions, fileMimeTypeOptions, formBuilder, formatBytes, hcaptchaProvider, interpolate, normalizeCalc, optionLabelsFor, recaptchaProvider, renderAllValues, renderAllValuesTable, resolveActions, resolveConsentLinks, resolveConsentSources, resolveFileRef, resolveFormResultsRequest, resolvePresentationDescriptors, resolvePublishedVersionRef, resolveSpamConfig, resolveUploads, sanitizeUrl, serializeBody, signPayload, turnstileProvider, valuesFromSearchParams };
|
|
71
83
|
|
|
72
84
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["import { type Config, definePlugin } from 'payload'\nimport { defaultActionDefinitions } from './actions/builtin'\nimport type { ActionsConfig } from './actions/registry'\nimport { resolveActions } from './actions/registry'\nimport { resolveUploads, type UploadsOption } from './collections/uploads'\nimport { defaultConsentSources } from './consent/builtin'\nimport type { ConsentSourcesConfig } from './consent/registry'\nimport { resolveConsentSources } from './consent/registry'\nimport type { FormEventSink } from './events/types'\nimport { defaultFieldDefinitions } from './fields/builtin'\nimport { type FieldTypesConfig, resolveFieldTypes } from './fields/registry'\nimport { registerCollections } from './plugin/registerCollections'\nimport { registerTranslations } from './plugin/registerTranslations'\nimport { defaultPresentationDescriptors } from './presentations/defaults'\nimport type { PresentationsDescriptorConfig } from './presentations/registry'\nimport { resolvePresentationDescriptors } from './presentations/registry'\nimport { resolveSpamConfig } from './spam/resolveSpam'\nimport type { SpamOption } from './spam/types'\nimport type { TranslationsOption } from './translations'\nimport { defaultValidationRules } from './validation/builtin'\nimport { resolveValidationRules, type ValidationRulesConfig } from './validation/registry'\n\nexport type FormBuilderPluginOptions = {\n\tdisabled?: boolean\n\t/**\n\t * Per-locale overrides for this plugin's UI strings, keyed by the typed\n\t * translation keys exported from `@10x-media/form-builder/i18n`. Values win\n\t * over the built-in locales key-by-key; locales the plugin does not ship are\n\t * added whole. App-level `i18n.translations` still wins over both.\n\t */\n\ttranslations?: TranslationsOption\n\t/** Pluggable sink for form lifecycle events. Defaults to a no-op; analytics adapters or a future analytics plugin subscribe here. */\n\tevents?: FormEventSink\n\t/** Add, override, or remove field types. `false` removes a built-in, `true` keeps it, an object adds or replaces one. */\n\tfields?: FieldTypesConfig\n\t/** Add, override, or remove presentations. `false` removes a built-in, `true` keeps it, an object adds or replaces one. */\n\tpresentations?: PresentationsDescriptorConfig\n\t/** Add, override, or remove validation rule types. `false` removes a built-in, `true` keeps it, an object adds or replaces one. */\n\trules?: ValidationRulesConfig\n\t/** Add, override, or remove post-submit action types. `false` removes a built-in, `true` keeps it, an object adds or replaces one. */\n\tactions?: ActionsConfig\n\t/** Add, override, or remove consent source types. `false` removes a built-in, `true` keeps it, an object adds or replaces one. */\n\tconsentSources?: ConsentSourcesConfig\n\t/** The built-in `form-uploads` collection backing file fields. `false` disables it (bring your own); an object overrides slug/upload/access/fields. */\n\tuploads?: UploadsOption\n\t/** Honeypot + rate-limiting (on by default) + a captcha adapter seam + upload-ownership scoping. `false` disables the whole subsystem. */\n\tspam?: SpamOption\n}\n\ndeclare module 'payload' {\n\tinterface RegisteredPlugins {\n\t\t'@10x-media/form-builder': FormBuilderPluginOptions\n\t}\n}\n\nexport const formBuilder = definePlugin<FormBuilderPluginOptions>({\n\tslug: '@10x-media/form-builder',\n\torder: 50,\n\tplugin: ({ config, plugins, ...options }): Config => {\n\t\tif (options.disabled === true) {\n\t\t\treturn config\n\t\t}\n\t\tconst registry = resolveFieldTypes(defaultFieldDefinitions, options.fields)\n\t\tconst ruleRegistry = resolveValidationRules(defaultValidationRules, options.rules)\n\t\tconst consentRegistry = resolveConsentSources(defaultConsentSources, options.consentSources)\n\t\tconst presentationRegistry = resolvePresentationDescriptors(\n\t\t\tdefaultPresentationDescriptors,\n\t\t\toptions.presentations\n\t\t)\n\t\tconst actionRegistry = resolveActions(defaultActionDefinitions, options.actions)\n\t\tconst uploads = resolveUploads(options.uploads)\n\t\tconst spam = resolveSpamConfig(options.spam)\n\t\tregisterTranslations(config, options.translations)\n\t\tregisterCollections({\n\t\t\tconfig,\n\t\t\tregistry,\n\t\t\truleRegistry,\n\t\t\tconsentRegistry,\n\t\t\tpresentationRegistry,\n\t\t\tactionRegistry,\n\t\t\thasJobsPlugin: Boolean(plugins['@10x-media/jobs']),\n\t\t\tevents: options.events,\n\t\t\tuploads,\n\t\t\tspam,\n\t\t})\n\t\treturn config\n\t},\n})\n\nexport { defaultActionDefinitions } from './actions/builtin'\nexport type { ActionDefinition, ActionRunArgs, AnyActionDefinition } from './actions/defineAction'\nexport { defineAction } from './actions/defineAction'\nexport type { ActionOption, ActionRegistry, ActionsConfig } from './actions/registry'\nexport { resolveActions } from './actions/registry'\nexport type { ActionResult } from './actions/runActions'\nexport { SIGNATURE_HEADER, signPayload } from './actions/sign'\nexport type {\n\tAggregateFieldResponsesArgs,\n\tAggregateFormResponsesArgs,\n} from './aggregation/aggregateResponses'\nexport {\n\taggregateFieldResponses,\n\taggregateFormResponses,\n\tfieldHasOptions,\n} from './aggregation/aggregateResponses'\nexport { aggregateRowForField, aggregateRowsForFields } from './aggregation/aggregateRows'\nexport type {\n\tResolveResultsRequestArgs,\n\tResolveResultsRequestResult,\n} from './aggregation/resolveResultsRequest'\nexport { resolveFormResultsRequest } from './aggregation/resolveResultsRequest'\nexport type {\n\tAggregationBucket,\n\tAggregationRow,\n\tFieldAggregation,\n\tFieldMeta,\n\tSubmissionStatusFilter,\n} from './aggregation/types'\nexport { calcExpressionOf, computeCalcFields } from './calc/computeCalcFields'\nexport { evaluateCalc } from './calc/evaluate'\nexport { normalizeCalc } from './calc/normalizeCalc'\nexport type { CalcExpression } from './calc/types'\nexport type { UploadsCollectionConfig, UploadsOption } from './collections/uploads'\nexport { buildUploadsCollection, FORM_UPLOADS_SLUG, resolveUploads } from './collections/uploads'\nexport { evaluateCondition } from './conditions/evaluate'\nexport type { FieldCondition } from './conditions/types'\nexport { defaultConsentSources } from './consent/builtin'\nexport type { ConsentProof } from './consent/captureConsent'\nexport { captureConsent } from './consent/captureConsent'\nexport type {\n\tAnyConsentSource,\n\tConsentLink,\n\tConsentResolveArgs,\n\tConsentResolved,\n\tConsentSource,\n} from './consent/defineConsentSource'\nexport { defineConsentSource } from './consent/defineConsentSource'\nexport type {\n\tConsentSourceOption,\n\tConsentSourceRegistry,\n\tConsentSourcesConfig,\n} from './consent/registry'\nexport { resolveConsentSources } from './consent/registry'\nexport { resolveConsentLinks } from './consent/resolveConsentLinks'\nexport { resolvePublishedVersionRef } from './consent/resolvePublishedVersionRef'\nexport { defineFormField } from './fields/defineFormField'\nexport type { FieldTypeOption, FieldTypeRegistry, FieldTypesConfig } from './fields/registry'\nexport type {\n\tAnyFormFieldDefinition,\n\tFormFieldDefinition,\n\tFormFieldFormat,\n\tFormFieldValidate,\n\tFormFieldValueKind,\n} from './fields/types'\nexport type { PrefillOptions } from './prefill/valuesFromSearchParams'\nexport { valuesFromSearchParams } from './prefill/valuesFromSearchParams'\nexport { DEFAULT_PRESENTATION_NAME, defaultPresentationDescriptors } from './presentations/defaults'\nexport type {\n\tPresentationDescriptorOption,\n\tPresentationDescriptorRegistry,\n\tPresentationsDescriptorConfig,\n} from './presentations/registry'\nexport { resolvePresentationDescriptors } from './presentations/registry'\nexport type {\n\tPresentationDensity,\n\tPresentationDescriptor,\n\tPresentationSurface,\n} from './presentations/types'\nexport { interpolate } from './recall/interpolate'\nexport type { RecallResolver } from './recall/resolver'\nexport { buildRecallResolver, optionLabelsFor } from './recall/resolver'\nexport { defineCaptchaProvider } from './spam/captcha'\nexport { CAPTCHA_TOKEN_KEY, DEFAULT_HONEYPOT_FIELD } from './spam/constants'\nexport { defaultIdentify } from './spam/identify'\nexport { createKvRateLimiter } from './spam/rateLimiter'\nexport { resolveSpamConfig } from './spam/resolveSpam'\nexport type {\n\tCaptchaProvider,\n\tCaptchaVerifyArgs,\n\tIdentifyFn,\n\tRateLimitCheckArgs,\n\tRateLimitConfig,\n\tRateLimiter,\n\tRateLimitResult,\n\tSpamConfig,\n\tSpamMetadataConfig,\n\tSpamOption,\n} from './spam/types'\nexport { captureFileRef } from './uploads/captureFileRef'\nexport { resolveFileRef } from './uploads/resolveFileRef'\nexport type { FileFieldConfig, FileRef, FileRefError } from './uploads/types'\nexport { defineValidationRule } from './validation/defineValidationRule'\nexport type {\n\tValidationRuleOption,\n\tValidationRuleRegistry,\n\tValidationRulesConfig,\n} from './validation/registry'\nexport type {\n\tAnyValidationRuleDefinition,\n\tValidationRuleDefinition,\n\tValidationRuleResult,\n\tValidationSeverity,\n} from './validation/types'\nexport type { FormBuilderPluginOptions as PluginOptions }\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuDA,MAAa,cAAc,aAAuC;CACjE,MAAM;CACN,OAAO;CACP,SAAS,EAAE,QAAQ,SAAS,GAAG,cAAsB;EACpD,IAAI,QAAQ,aAAa,MACxB,OAAO;EAER,MAAM,WAAW,kBAAkB,yBAAyB,QAAQ,MAAM;EAC1E,MAAM,eAAe,uBAAuB,wBAAwB,QAAQ,KAAK;EACjF,MAAM,kBAAkB,sBAAsB,uBAAuB,QAAQ,cAAc;EAC3F,MAAM,uBAAuB,+BAC5B,gCACA,QAAQ,aACT;EACA,MAAM,iBAAiB,eAAe,0BAA0B,QAAQ,OAAO;EAC/E,MAAM,UAAU,eAAe,QAAQ,OAAO;EAC9C,MAAM,OAAO,kBAAkB,QAAQ,IAAI;EAC3C,qBAAqB,QAAQ,QAAQ,YAAY;EACjD,oBAAoB;GACnB;GACA;GACA;GACA;GACA;GACA;GACA,eAAe,QAAQ,QAAQ,kBAAkB;GACjD,QAAQ,QAAQ;GAChB;GACA;EACD,CAAC;EACD,OAAO;CACR;AACD,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["import { type Config, definePlugin } from 'payload'\nimport type { RichTextBodyOption } from './actions/body/serializeBody'\nimport { defaultActionDefinitions } from './actions/builtin'\nimport type { ActionsConfig } from './actions/registry'\nimport { resolveActions } from './actions/registry'\nimport { resolveUploads, type UploadsOption } from './collections/uploads'\nimport { defaultConsentSources } from './consent/builtin'\nimport type { ConsentSourcesConfig } from './consent/registry'\nimport { resolveConsentSources } from './consent/registry'\nimport type { FormEventSink } from './events/types'\nimport { defaultFieldDefinitions } from './fields/builtin'\nimport { type FieldTypesConfig, resolveFieldTypes } from './fields/registry'\nimport type { CollectionOverrides } from './plugin/collectionOverrides'\nimport { registerCollections } from './plugin/registerCollections'\nimport { registerTranslations } from './plugin/registerTranslations'\nimport { defaultPresentationDescriptors } from './presentations/defaults'\nimport type { PresentationsDescriptorConfig } from './presentations/registry'\nimport { resolvePresentationDescriptors } from './presentations/registry'\nimport { resolveSpamConfig } from './spam/resolveSpam'\nimport type { SpamOption } from './spam/types'\nimport type { TranslationsOption } from './translations'\nimport { defaultValidationRules } from './validation/builtin'\nimport { resolveValidationRules, type ValidationRulesConfig } from './validation/registry'\n\nexport type FormBuilderPluginOptions = {\n\tdisabled?: boolean\n\t/**\n\t * Per-locale overrides for this plugin's UI strings, keyed by the typed\n\t * translation keys exported from `@10x-media/form-builder/i18n`. Values win\n\t * over the built-in locales key-by-key; locales the plugin does not ship are\n\t * added whole. App-level `i18n.translations` still wins over both.\n\t */\n\ttranslations?: TranslationsOption\n\t/** Pluggable sink for form lifecycle events. Defaults to a no-op; analytics adapters or a future analytics plugin subscribe here. */\n\tevents?: FormEventSink\n\t/** Add, override, or remove field types. `false` removes a built-in, `true` keeps it, an object adds or replaces one. */\n\tfields?: FieldTypesConfig\n\t/** Add, override, or remove presentations. `false` removes a built-in, `true` keeps it, an object adds or replaces one. */\n\tpresentations?: PresentationsDescriptorConfig\n\t/** Add, override, or remove validation rule types. `false` removes a built-in, `true` keeps it, an object adds or replaces one. */\n\trules?: ValidationRulesConfig\n\t/** Add, override, or remove post-submit action types. `false` removes a built-in, `true` keeps it, an object adds or replaces one. */\n\tactions?: ActionsConfig\n\t/**\n\t * Customize how rich text action bodies are rendered. `converters` spread over the default\n\t * Lexical node converters; `serialize` replaces the whole pipeline (e.g. to target chat or\n\t * plain-text channels instead of email HTML).\n\t */\n\trichText?: RichTextBodyOption\n\t/** Add, override, or remove consent source types. `false` removes a built-in, `true` keeps it, an object adds or replaces one. */\n\tconsentSources?: ConsentSourcesConfig\n\t/** The built-in `form-uploads` collection backing file fields. `false` disables it (bring your own); an object overrides slug/upload/access/fields. */\n\tuploads?: UploadsOption\n\t/** Honeypot + rate-limiting (on by default) + a captcha adapter seam + upload-ownership scoping. `false` disables the whole subsystem. */\n\tspam?: SpamOption\n\t/**\n\t * When `true`, the raw `values`, `descriptors`, and `consent` JSON fields are visible in the\n\t * submission admin view. Default `false` — those fields are fully represented by the\n\t * `SubmissionAnswers` UI component and are noisy when shown alongside it.\n\t */\n\tshowSubmissionRawFields?: boolean\n\t/**\n\t * Override individual plugin-managed collections using explicit spreads. Each key accepts a\n\t * `CollectionOverrides` object: top-level keys are spread with the plugin's defaults (spread\n\t * order per key determines who wins), hooks are appended after the plugin's own hooks, and\n\t * `fields` is a function that receives the default fields and returns the final array so\n\t * additions/removals are always intentional.\n\t */\n\toverrides?: {\n\t\tforms?: CollectionOverrides\n\t\tformSubmissions?: CollectionOverrides\n\t\tuploads?: CollectionOverrides\n\t}\n}\n\ndeclare module 'payload' {\n\tinterface RegisteredPlugins {\n\t\t'@10x-media/form-builder': FormBuilderPluginOptions\n\t}\n}\n\nexport const formBuilder = definePlugin<FormBuilderPluginOptions>({\n\tslug: '@10x-media/form-builder',\n\torder: 50,\n\tplugin: ({ config, plugins, ...options }): Config => {\n\t\tif (options.disabled === true) {\n\t\t\treturn config\n\t\t}\n\t\tconst registry = resolveFieldTypes(defaultFieldDefinitions, options.fields)\n\t\tconst ruleRegistry = resolveValidationRules(defaultValidationRules, options.rules)\n\t\tconst consentRegistry = resolveConsentSources(defaultConsentSources, options.consentSources)\n\t\tconst presentationRegistry = resolvePresentationDescriptors(\n\t\t\tdefaultPresentationDescriptors,\n\t\t\toptions.presentations\n\t\t)\n\t\tconst actionRegistry = resolveActions(defaultActionDefinitions, options.actions)\n\t\tconst uploads = resolveUploads(options.uploads)\n\t\tconst spam = resolveSpamConfig(options.spam)\n\t\tregisterTranslations(config, options.translations)\n\t\tregisterCollections({\n\t\t\tconfig,\n\t\t\tregistry,\n\t\t\truleRegistry,\n\t\t\tconsentRegistry,\n\t\t\tpresentationRegistry,\n\t\t\tactionRegistry,\n\t\t\trichText: options.richText,\n\t\t\thasJobsPlugin: Boolean(plugins['@10x-media/jobs']),\n\t\t\tevents: options.events,\n\t\t\tuploads,\n\t\t\tspam,\n\t\t\tshowSubmissionRawFields: options.showSubmissionRawFields ?? false,\n\t\t\toverrides: options.overrides,\n\t\t})\n\t\treturn config\n\t},\n})\n\nexport type {\n\tBodyConverter,\n\tBodyConverterArgs,\n\tBodyRender,\n} from './actions/body/converters'\nexport { defaultBodyConverters, sanitizeUrl } from './actions/body/converters'\nexport { escapeHtml } from './actions/body/escapeHtml'\nexport type {\n\tBodyContext,\n\tRichTextBodyOption,\n\tSerializeBodyArgs,\n} from './actions/body/serializeBody'\nexport { serializeBody } from './actions/body/serializeBody'\nexport { renderAllValues, renderAllValuesTable } from './actions/body/wildcards'\nexport { defaultActionDefinitions } from './actions/builtin'\nexport type { ActionDefinition, ActionRunArgs, AnyActionDefinition } from './actions/defineAction'\nexport { defineAction } from './actions/defineAction'\nexport type { ActionOption, ActionRegistry, ActionsConfig } from './actions/registry'\nexport { resolveActions } from './actions/registry'\nexport type { ActionResult } from './actions/runActions'\nexport { SIGNATURE_HEADER, signPayload } from './actions/sign'\nexport type {\n\tAggregateFieldResponsesArgs,\n\tAggregateFormResponsesArgs,\n} from './aggregation/aggregateResponses'\nexport {\n\taggregateFieldResponses,\n\taggregateFormResponses,\n\tfieldHasOptions,\n} from './aggregation/aggregateResponses'\nexport { aggregateRowForField, aggregateRowsForFields } from './aggregation/aggregateRows'\nexport type {\n\tResolveResultsRequestArgs,\n\tResolveResultsRequestResult,\n} from './aggregation/resolveResultsRequest'\nexport { resolveFormResultsRequest } from './aggregation/resolveResultsRequest'\nexport type {\n\tAggregationBucket,\n\tAggregationRow,\n\tFieldAggregation,\n\tFieldMeta,\n\tSubmissionStatusFilter,\n} from './aggregation/types'\nexport { calcExpressionOf, computeCalcFields } from './calc/computeCalcFields'\nexport { evaluateCalc } from './calc/evaluate'\nexport { normalizeCalc } from './calc/normalizeCalc'\nexport type { CalcExpression } from './calc/types'\nexport type { UploadsCollectionConfig, UploadsOption } from './collections/uploads'\nexport { buildUploadsCollection, FORM_UPLOADS_SLUG, resolveUploads } from './collections/uploads'\nexport { evaluateCondition } from './conditions/evaluate'\nexport type { FieldCondition } from './conditions/types'\nexport { defaultConsentSources } from './consent/builtin'\nexport type { ConsentProof } from './consent/captureConsent'\nexport { captureConsent } from './consent/captureConsent'\nexport type {\n\tAnyConsentSource,\n\tConsentLink,\n\tConsentResolveArgs,\n\tConsentResolved,\n\tConsentSource,\n} from './consent/defineConsentSource'\nexport { defineConsentSource } from './consent/defineConsentSource'\nexport type {\n\tConsentSourceOption,\n\tConsentSourceRegistry,\n\tConsentSourcesConfig,\n} from './consent/registry'\nexport { resolveConsentSources } from './consent/registry'\nexport { resolveConsentLinks } from './consent/resolveConsentLinks'\nexport { resolvePublishedVersionRef } from './consent/resolvePublishedVersionRef'\nexport { defaultFieldDefinitions, defaultFieldDefinitionsByType } from './fields/builtin'\nexport { fileMimeTypeOptions } from './fields/builtin/file'\nexport { defineFormField } from './fields/defineFormField'\nexport type { FieldTypeOption, FieldTypeRegistry, FieldTypesConfig } from './fields/registry'\nexport type {\n\tAnyFormFieldDefinition,\n\tFormFieldDefinition,\n\tFormFieldFormat,\n\tFormFieldValidate,\n\tFormFieldValueKind,\n} from './fields/types'\nexport type { PrefillOptions } from './prefill/valuesFromSearchParams'\nexport { valuesFromSearchParams } from './prefill/valuesFromSearchParams'\nexport { DEFAULT_PRESENTATION_NAME, defaultPresentationDescriptors } from './presentations/defaults'\nexport type {\n\tPresentationDescriptorOption,\n\tPresentationDescriptorRegistry,\n\tPresentationsDescriptorConfig,\n} from './presentations/registry'\nexport { resolvePresentationDescriptors } from './presentations/registry'\nexport type {\n\tPresentationDensity,\n\tPresentationDescriptor,\n\tPresentationSurface,\n} from './presentations/types'\nexport { interpolate } from './recall/interpolate'\nexport type { RecallResolver } from './recall/resolver'\nexport { buildRecallResolver, optionLabelsFor } from './recall/resolver'\nexport { defineCaptchaProvider } from './spam/captcha'\nexport { CAPTCHA_TOKEN_KEY, DEFAULT_HONEYPOT_FIELD } from './spam/constants'\nexport { defaultIdentify } from './spam/identify'\nexport type { HcaptchaProviderOptions } from './spam/providers/hcaptcha'\nexport { hcaptchaProvider } from './spam/providers/hcaptcha'\nexport type { RecaptchaProviderOptions } from './spam/providers/recaptcha'\nexport { recaptchaProvider } from './spam/providers/recaptcha'\nexport type { TurnstileProviderOptions } from './spam/providers/turnstile'\nexport { turnstileProvider } from './spam/providers/turnstile'\nexport { createKvRateLimiter } from './spam/rateLimiter'\nexport { resolveSpamConfig } from './spam/resolveSpam'\nexport type {\n\tCaptchaProvider,\n\tCaptchaVerifyArgs,\n\tIdentifyFn,\n\tRateLimitCheckArgs,\n\tRateLimitConfig,\n\tRateLimiter,\n\tRateLimitResult,\n\tSpamConfig,\n\tSpamMetadataConfig,\n\tSpamOption,\n} from './spam/types'\nexport { captureFileRef } from './uploads/captureFileRef'\nexport { formatBytes } from './uploads/formatBytes'\nexport { resolveFileRef } from './uploads/resolveFileRef'\nexport type { FileFieldConfig, FileRef, FileRefError } from './uploads/types'\nexport { defaultValidationRules, defaultValidationRulesByType } from './validation/builtin'\nexport { defineValidationRule } from './validation/defineValidationRule'\nexport type {\n\tValidationRuleOption,\n\tValidationRuleRegistry,\n\tValidationRulesConfig,\n} from './validation/registry'\nexport type {\n\tAnyValidationRuleDefinition,\n\tValidationRuleDefinition,\n\tValidationRuleResult,\n\tValidationSeverity,\n} from './validation/types'\nexport type { FormBuilderPluginOptions as PluginOptions }\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiFA,MAAa,cAAc,aAAuC;CACjE,MAAM;CACN,OAAO;CACP,SAAS,EAAE,QAAQ,SAAS,GAAG,cAAsB;EACpD,IAAI,QAAQ,aAAa,MACxB,OAAO;EAER,MAAM,WAAW,kBAAkB,yBAAyB,QAAQ,MAAM;EAC1E,MAAM,eAAe,uBAAuB,wBAAwB,QAAQ,KAAK;EACjF,MAAM,kBAAkB,sBAAsB,uBAAuB,QAAQ,cAAc;EAC3F,MAAM,uBAAuB,+BAC5B,gCACA,QAAQ,aACT;EACA,MAAM,iBAAiB,eAAe,0BAA0B,QAAQ,OAAO;EAC/E,MAAM,UAAU,eAAe,QAAQ,OAAO;EAC9C,MAAM,OAAO,kBAAkB,QAAQ,IAAI;EAC3C,qBAAqB,QAAQ,QAAQ,YAAY;EACjD,oBAAoB;GACnB;GACA;GACA;GACA;GACA;GACA;GACA,UAAU,QAAQ;GAClB,eAAe,QAAQ,QAAQ,kBAAkB;GACjD,QAAQ,QAAQ;GAChB;GACA;GACA,yBAAyB,QAAQ,2BAA2B;GAC5D,WAAW,QAAQ;EACpB,CAAC;EACD,OAAO;CACR;AACD,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { CollectionConfig, Field } from "payload";
|
|
2
|
+
|
|
3
|
+
//#region src/plugin/collectionOverrides.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Instead of accepting a static field array (which deepMerge would silently replace), the consumer
|
|
6
|
+
* receives the plugin's default fields and returns the final array. This makes the intent explicit:
|
|
7
|
+
* append, prepend, filter out, or wrap any field without risk of accidentally wiping the defaults.
|
|
8
|
+
*/
|
|
9
|
+
type FieldsOverride = (args: {
|
|
10
|
+
defaultFields: Field[];
|
|
11
|
+
}) => Field[];
|
|
12
|
+
/**
|
|
13
|
+
* Typed override surface for plugin-managed collections. Top-level keys use explicit spread order
|
|
14
|
+
* (see each collection builder) so the consumer always knows which values they can override and
|
|
15
|
+
* which are locked by the plugin for correctness or security.
|
|
16
|
+
*/
|
|
17
|
+
type CollectionOverrides = {
|
|
18
|
+
fields?: FieldsOverride;
|
|
19
|
+
} & Partial<Omit<CollectionConfig, 'fields'>>;
|
|
20
|
+
//#endregion
|
|
21
|
+
export { CollectionOverrides, FieldsOverride };
|
|
22
|
+
//# sourceMappingURL=collectionOverrides.d.ts.map
|
|
@@ -3,34 +3,63 @@ import { buildSubmissionsCollection } from "../collections/formSubmissions.js";
|
|
|
3
3
|
import { registerActionsTask } from "../actions/task.js";
|
|
4
4
|
import { buildUploadOwnerStamp, buildUploadRateLimit } from "../spam/uploadHooks.js";
|
|
5
5
|
//#region src/plugin/registerCollections.ts
|
|
6
|
-
const registerCollections = ({ config, registry, ruleRegistry, consentRegistry, presentationRegistry, actionRegistry, hasJobsPlugin, events, uploads, spam }) => {
|
|
7
|
-
registerActionsTask(config, actionRegistry);
|
|
6
|
+
const registerCollections = ({ config, registry, ruleRegistry, consentRegistry, presentationRegistry, actionRegistry, richText, hasJobsPlugin, events, uploads, spam, showSubmissionRawFields, overrides }) => {
|
|
7
|
+
registerActionsTask(config, actionRegistry, richText);
|
|
8
8
|
const hasRunner = Boolean(config.jobs?.autoRun) || hasJobsPlugin;
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
let uploadsCollection = null;
|
|
10
|
+
if (uploads.enabled && uploads.collection) {
|
|
11
|
+
const col = uploads.collection;
|
|
12
|
+
if (spam) {
|
|
13
|
+
col.hooks = col.hooks ?? {};
|
|
14
|
+
col.hooks.beforeOperation = [...col.hooks.beforeOperation ?? [], buildUploadRateLimit(spam)];
|
|
15
|
+
col.hooks.beforeValidate = [...col.hooks.beforeValidate ?? [], buildUploadOwnerStamp(spam)];
|
|
16
|
+
}
|
|
17
|
+
const ov = overrides?.uploads;
|
|
18
|
+
if (ov) {
|
|
19
|
+
const defaultFields = col.fields ?? [];
|
|
20
|
+
uploadsCollection = {
|
|
21
|
+
...col,
|
|
22
|
+
...ov ?? {},
|
|
23
|
+
access: {
|
|
24
|
+
...col.access ?? {},
|
|
25
|
+
...ov.access ?? {}
|
|
26
|
+
},
|
|
27
|
+
admin: {
|
|
28
|
+
...col.admin ?? {},
|
|
29
|
+
...ov.admin ?? {}
|
|
30
|
+
},
|
|
31
|
+
hooks: {
|
|
32
|
+
...ov.hooks ?? {},
|
|
33
|
+
beforeOperation: [...col.hooks?.beforeOperation ?? [], ...ov.hooks?.beforeOperation ?? []],
|
|
34
|
+
beforeValidate: [...col.hooks?.beforeValidate ?? [], ...ov.hooks?.beforeValidate ?? []]
|
|
35
|
+
},
|
|
36
|
+
fields: ov.fields ? ov.fields({ defaultFields }) : defaultFields
|
|
37
|
+
};
|
|
38
|
+
} else uploadsCollection = col;
|
|
14
39
|
}
|
|
15
40
|
config.collections = [
|
|
16
41
|
...config.collections ?? [],
|
|
17
|
-
...
|
|
42
|
+
...uploadsCollection ? [uploadsCollection] : [],
|
|
18
43
|
buildFormsCollection({
|
|
19
44
|
registry,
|
|
20
45
|
ruleRegistry,
|
|
21
46
|
consentRegistry,
|
|
22
47
|
presentationRegistry,
|
|
23
|
-
actionRegistry
|
|
48
|
+
actionRegistry,
|
|
49
|
+
overrides: overrides?.forms
|
|
24
50
|
}),
|
|
25
51
|
buildSubmissionsCollection({
|
|
26
52
|
registry,
|
|
27
53
|
ruleRegistry,
|
|
28
54
|
consentRegistry,
|
|
29
55
|
actionRegistry,
|
|
56
|
+
richText,
|
|
30
57
|
events,
|
|
31
58
|
hasRunner,
|
|
32
59
|
uploadSlug: uploads.slug,
|
|
33
|
-
spam
|
|
60
|
+
spam,
|
|
61
|
+
showRawFields: showSubmissionRawFields,
|
|
62
|
+
overrides: overrides?.formSubmissions
|
|
34
63
|
})
|
|
35
64
|
];
|
|
36
65
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registerCollections.js","names":[],"sources":["../../src/plugin/registerCollections.ts"],"sourcesContent":["import type { CollectionConfig, Config } from 'payload'\nimport type { ActionRegistry } from '../actions/registry'\nimport { registerActionsTask } from '../actions/task'\nimport { buildSubmissionsCollection } from '../collections/formSubmissions'\nimport { buildFormsCollection } from '../collections/forms'\nimport type { ConsentSourceRegistry } from '../consent/registry'\nimport type { FormEventSink } from '../events/types'\nimport type { FieldTypeRegistry } from '../fields/registry'\nimport type { PresentationDescriptorRegistry } from '../presentations/registry'\nimport type { ResolvedSpamConfig } from '../spam/types'\nimport { buildUploadOwnerStamp, buildUploadRateLimit } from '../spam/uploadHooks'\nimport type { ValidationRuleRegistry } from '../validation/registry'\n\ntype RegisterCollectionsArgs = {\n\tconfig: Config\n\tregistry: FieldTypeRegistry\n\truleRegistry: ValidationRuleRegistry\n\tconsentRegistry: ConsentSourceRegistry\n\tpresentationRegistry: PresentationDescriptorRegistry\n\tactionRegistry: ActionRegistry\n\thasJobsPlugin: boolean\n\tevents?: FormEventSink\n\tuploads: { enabled: boolean; slug: string; collection?: CollectionConfig }\n\tspam: ResolvedSpamConfig | false\n}\n\nexport const registerCollections = ({\n\tconfig,\n\tregistry,\n\truleRegistry,\n\tconsentRegistry,\n\tpresentationRegistry,\n\tactionRegistry,\n\thasJobsPlugin,\n\tevents,\n\tuploads,\n\tspam,\n}: RegisterCollectionsArgs): void => {\n\tregisterActionsTask(config, actionRegistry)\n\tconst hasRunner = Boolean(config.jobs?.autoRun) || hasJobsPlugin\n\tif (
|
|
1
|
+
{"version":3,"file":"registerCollections.js","names":[],"sources":["../../src/plugin/registerCollections.ts"],"sourcesContent":["import type { CollectionConfig, Config, Field } from 'payload'\nimport type { RichTextBodyOption } from '../actions/body/serializeBody'\nimport type { ActionRegistry } from '../actions/registry'\nimport { registerActionsTask } from '../actions/task'\nimport { buildSubmissionsCollection } from '../collections/formSubmissions'\nimport { buildFormsCollection } from '../collections/forms'\nimport type { ConsentSourceRegistry } from '../consent/registry'\nimport type { FormEventSink } from '../events/types'\nimport type { FieldTypeRegistry } from '../fields/registry'\nimport type { PresentationDescriptorRegistry } from '../presentations/registry'\nimport type { ResolvedSpamConfig } from '../spam/types'\nimport { buildUploadOwnerStamp, buildUploadRateLimit } from '../spam/uploadHooks'\nimport type { ValidationRuleRegistry } from '../validation/registry'\nimport type { CollectionOverrides } from './collectionOverrides'\n\ntype RegisterCollectionsArgs = {\n\tconfig: Config\n\tregistry: FieldTypeRegistry\n\truleRegistry: ValidationRuleRegistry\n\tconsentRegistry: ConsentSourceRegistry\n\tpresentationRegistry: PresentationDescriptorRegistry\n\tactionRegistry: ActionRegistry\n\trichText?: RichTextBodyOption\n\thasJobsPlugin: boolean\n\tevents?: FormEventSink\n\tuploads: { enabled: boolean; slug: string; collection?: CollectionConfig }\n\tspam: ResolvedSpamConfig | false\n\tshowSubmissionRawFields: boolean\n\toverrides?: {\n\t\tforms?: CollectionOverrides\n\t\tformSubmissions?: CollectionOverrides\n\t\tuploads?: CollectionOverrides\n\t}\n}\n\nexport const registerCollections = ({\n\tconfig,\n\tregistry,\n\truleRegistry,\n\tconsentRegistry,\n\tpresentationRegistry,\n\tactionRegistry,\n\trichText,\n\thasJobsPlugin,\n\tevents,\n\tuploads,\n\tspam,\n\tshowSubmissionRawFields,\n\toverrides,\n}: RegisterCollectionsArgs): void => {\n\tregisterActionsTask(config, actionRegistry, richText)\n\tconst hasRunner = Boolean(config.jobs?.autoRun) || hasJobsPlugin\n\n\tlet uploadsCollection: CollectionConfig | null = null\n\tif (uploads.enabled && uploads.collection) {\n\t\tconst col = uploads.collection\n\n\t\t// Spam hooks are added first (plugin-owned invariant)\n\t\tif (spam) {\n\t\t\tcol.hooks = col.hooks ?? {}\n\t\t\tcol.hooks.beforeOperation = [...(col.hooks.beforeOperation ?? []), buildUploadRateLimit(spam)]\n\t\t\tcol.hooks.beforeValidate = [...(col.hooks.beforeValidate ?? []), buildUploadOwnerStamp(spam)]\n\t\t}\n\n\t\t// Apply CollectionOverrides using explicit spreads after spam hooks are in place.\n\t\t// ...col first so the plugin defaults are the base, ...(ov ?? {}) second so the consumer\n\t\t// wins for any top-level key not explicitly re-set below (consistent with forms/formSubmissions).\n\t\t// The locked keys (hooks array ordering, fields function) are spread last.\n\t\tconst ov = overrides?.uploads\n\t\tif (ov) {\n\t\t\tconst defaultFields = (col.fields ?? []) as Field[]\n\t\t\tuploadsCollection = {\n\t\t\t\t...col,\n\t\t\t\t...(ov ?? {}),\n\t\t\t\taccess: { ...(col.access ?? {}), ...(ov.access ?? {}) },\n\t\t\t\tadmin: { ...(col.admin ?? {}), ...(ov.admin ?? {}) },\n\t\t\t\thooks: {\n\t\t\t\t\t...(ov.hooks ?? {}),\n\t\t\t\t\t// Spam hooks stay first in each array; consumer hooks appended\n\t\t\t\t\tbeforeOperation: [\n\t\t\t\t\t\t...(col.hooks?.beforeOperation ?? []),\n\t\t\t\t\t\t...(ov.hooks?.beforeOperation ?? []),\n\t\t\t\t\t],\n\t\t\t\t\tbeforeValidate: [\n\t\t\t\t\t\t...(col.hooks?.beforeValidate ?? []),\n\t\t\t\t\t\t...(ov.hooks?.beforeValidate ?? []),\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t\tfields: ov.fields ? ov.fields({ defaultFields }) : defaultFields,\n\t\t\t}\n\t\t} else {\n\t\t\tuploadsCollection = col\n\t\t}\n\t}\n\n\tconfig.collections = [\n\t\t...(config.collections ?? []),\n\t\t...(uploadsCollection ? [uploadsCollection] : []),\n\t\tbuildFormsCollection({\n\t\t\tregistry,\n\t\t\truleRegistry,\n\t\t\tconsentRegistry,\n\t\t\tpresentationRegistry,\n\t\t\tactionRegistry,\n\t\t\toverrides: overrides?.forms,\n\t\t}),\n\t\tbuildSubmissionsCollection({\n\t\t\tregistry,\n\t\t\truleRegistry,\n\t\t\tconsentRegistry,\n\t\t\tactionRegistry,\n\t\t\trichText,\n\t\t\tevents,\n\t\t\thasRunner,\n\t\t\tuploadSlug: uploads.slug,\n\t\t\tspam,\n\t\t\tshowRawFields: showSubmissionRawFields,\n\t\t\toverrides: overrides?.formSubmissions,\n\t\t}),\n\t]\n}\n"],"mappings":";;;;;AAmCA,MAAa,uBAAuB,EACnC,QACA,UACA,cACA,iBACA,sBACA,gBACA,UACA,eACA,QACA,SACA,MACA,yBACA,gBACoC;CACpC,oBAAoB,QAAQ,gBAAgB,QAAQ;CACpD,MAAM,YAAY,QAAQ,OAAO,MAAM,OAAO,KAAK;CAEnD,IAAI,oBAA6C;CACjD,IAAI,QAAQ,WAAW,QAAQ,YAAY;EAC1C,MAAM,MAAM,QAAQ;EAGpB,IAAI,MAAM;GACT,IAAI,QAAQ,IAAI,SAAS,CAAC;GAC1B,IAAI,MAAM,kBAAkB,CAAC,GAAI,IAAI,MAAM,mBAAmB,CAAC,GAAI,qBAAqB,IAAI,CAAC;GAC7F,IAAI,MAAM,iBAAiB,CAAC,GAAI,IAAI,MAAM,kBAAkB,CAAC,GAAI,sBAAsB,IAAI,CAAC;EAC7F;EAMA,MAAM,KAAK,WAAW;EACtB,IAAI,IAAI;GACP,MAAM,gBAAiB,IAAI,UAAU,CAAC;GACtC,oBAAoB;IACnB,GAAG;IACH,GAAI,MAAM,CAAC;IACX,QAAQ;KAAE,GAAI,IAAI,UAAU,CAAC;KAAI,GAAI,GAAG,UAAU,CAAC;IAAG;IACtD,OAAO;KAAE,GAAI,IAAI,SAAS,CAAC;KAAI,GAAI,GAAG,SAAS,CAAC;IAAG;IACnD,OAAO;KACN,GAAI,GAAG,SAAS,CAAC;KAEjB,iBAAiB,CAChB,GAAI,IAAI,OAAO,mBAAmB,CAAC,GACnC,GAAI,GAAG,OAAO,mBAAmB,CAAC,CACnC;KACA,gBAAgB,CACf,GAAI,IAAI,OAAO,kBAAkB,CAAC,GAClC,GAAI,GAAG,OAAO,kBAAkB,CAAC,CAClC;IACD;IACA,QAAQ,GAAG,SAAS,GAAG,OAAO,EAAE,cAAc,CAAC,IAAI;GACpD;EACD,OACC,oBAAoB;CAEtB;CAEA,OAAO,cAAc;EACpB,GAAI,OAAO,eAAe,CAAC;EAC3B,GAAI,oBAAoB,CAAC,iBAAiB,IAAI,CAAC;EAC/C,qBAAqB;GACpB;GACA;GACA;GACA;GACA;GACA,WAAW,WAAW;EACvB,CAAC;EACD,2BAA2B;GAC1B;GACA;GACA;GACA;GACA;GACA;GACA;GACA,YAAY,QAAQ;GACpB;GACA,eAAe;GACf,WAAW,WAAW;EACvB,CAAC;CACF;AACD"}
|
package/dist/react/Form.d.ts
CHANGED
|
@@ -17,6 +17,23 @@ type FormDocument = {
|
|
|
17
17
|
flow?: FormFlow; /** Stored presentation name; overridden by the `presentation` prop. */
|
|
18
18
|
defaultPresentation?: string;
|
|
19
19
|
};
|
|
20
|
+
/** Props passed to `renderSubmit`. */
|
|
21
|
+
type SubmitButtonRenderProps = {
|
|
22
|
+
label: string;
|
|
23
|
+
submitting: boolean;
|
|
24
|
+
};
|
|
25
|
+
/** Props passed to `renderNext`. */
|
|
26
|
+
type NextButtonRenderProps = {
|
|
27
|
+
label: string;
|
|
28
|
+
submitting: boolean;
|
|
29
|
+
onClick: () => void;
|
|
30
|
+
};
|
|
31
|
+
/** Props passed to `renderBack`. */
|
|
32
|
+
type BackButtonRenderProps = {
|
|
33
|
+
label: string;
|
|
34
|
+
submitting: boolean;
|
|
35
|
+
onClick: () => void;
|
|
36
|
+
};
|
|
20
37
|
type FormProps = {
|
|
21
38
|
form: FormDocument;
|
|
22
39
|
fieldTypes?: AnyFormFieldDefinition[];
|
|
@@ -45,7 +62,13 @@ type FormProps = {
|
|
|
45
62
|
}; /** A token from your captcha widget; verified server-side when a captcha provider is configured. */
|
|
46
63
|
captchaToken?: string; /** Custom layout: render fields with `useField`/`useFormState` instead of the auto-rendered field loop. */
|
|
47
64
|
children?: ReactNode; /** Additional CSS class names applied to the root `<form>` element (and the success node). */
|
|
48
|
-
className?: string;
|
|
65
|
+
className?: string; /** Replace the default submit button entirely. Receives the resolved label and submitting state. */
|
|
66
|
+
renderSubmit?: (props: SubmitButtonRenderProps) => ReactNode; /** Replace the default "Next" button in multi-step forms. */
|
|
67
|
+
renderNext?: (props: NextButtonRenderProps) => ReactNode; /** Replace the default "Back" button in multi-step forms. */
|
|
68
|
+
renderBack?: (props: BackButtonRenderProps) => ReactNode; /** CSS class forwarded to the default submit `<button>`. Ignored when `renderSubmit` is provided. */
|
|
69
|
+
submitButtonClassName?: string; /** CSS class forwarded to the default "Next" `<button>`. Ignored when `renderNext` is provided. */
|
|
70
|
+
nextButtonClassName?: string; /** CSS class forwarded to the default "Back" `<button>`. Ignored when `renderBack` is provided. */
|
|
71
|
+
backButtonClassName?: string;
|
|
49
72
|
};
|
|
50
73
|
/** The headless form controller: state, progressive client validation, conditional visibility, submission, events. */
|
|
51
74
|
declare const Form: ({
|
|
@@ -74,8 +97,14 @@ declare const Form: ({
|
|
|
74
97
|
honeypot,
|
|
75
98
|
captchaToken,
|
|
76
99
|
children,
|
|
77
|
-
className
|
|
100
|
+
className,
|
|
101
|
+
renderSubmit,
|
|
102
|
+
renderNext,
|
|
103
|
+
renderBack,
|
|
104
|
+
submitButtonClassName,
|
|
105
|
+
nextButtonClassName,
|
|
106
|
+
backButtonClassName
|
|
78
107
|
}: FormProps) => import("react/jsx-runtime").JSX.Element;
|
|
79
108
|
//#endregion
|
|
80
|
-
export { Form, FormDocument, FormProps };
|
|
109
|
+
export { BackButtonRenderProps, Form, FormDocument, FormProps, NextButtonRenderProps, SubmitButtonRenderProps };
|
|
81
110
|
//# sourceMappingURL=Form.d.ts.map
|
package/dist/react/Form.js
CHANGED
|
@@ -18,14 +18,14 @@ import { defaultPresentations } from "./presentation/presentations.js";
|
|
|
18
18
|
import { resolvePresentations } from "./presentation/registry.js";
|
|
19
19
|
import { applyRecall } from "./recall.js";
|
|
20
20
|
import { resolveRenderers } from "./registry.js";
|
|
21
|
+
import { useField } from "./useField.js";
|
|
21
22
|
import { defaultRenderers } from "./renderers/index.js";
|
|
22
23
|
import { buildFieldTypeRegistry, buildValidationRuleRegistry, visibleFields } from "./resolveForm.js";
|
|
23
24
|
import { formReducer, initialFormState } from "./state.js";
|
|
24
25
|
import { submitForm } from "./submitForm.js";
|
|
25
|
-
import { useField } from "./useField.js";
|
|
26
26
|
import { validateFieldValue } from "./validateField.js";
|
|
27
|
-
import { createElement, useCallback, useEffect, useId, useMemo, useReducer, useRef, useState } from "react";
|
|
28
27
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
28
|
+
import { createElement, useCallback, useEffect, useId, useMemo, useReducer, useRef, useState } from "react";
|
|
29
29
|
//#region src/react/Form.tsx
|
|
30
30
|
const isEmpty = (value) => value == null || value === "" || Array.isArray(value) && value.length === 0;
|
|
31
31
|
const FIELD_WIDTHS = new Set([
|
|
@@ -69,7 +69,7 @@ const CalcFieldHost = ({ field, renderer, value, locale, t }) => {
|
|
|
69
69
|
});
|
|
70
70
|
};
|
|
71
71
|
/** The headless form controller: state, progressive client validation, conditional visibility, submission, events. */
|
|
72
|
-
const Form = ({ form, fieldTypes, rules, renderers, apiRoute, onSubmit, onSuccess, onError, events, t, locale = "en", layout, submitLabel = "Submit", nextLabel = "Next", backLabel = "Back", closeLabel = "Close", successMessage = "Thank you.", presentation, presentations, onClose, title, initialValues, honeypot, captchaToken, children, className }) => {
|
|
72
|
+
const Form = ({ form, fieldTypes, rules, renderers, apiRoute, onSubmit, onSuccess, onError, events, t, locale = "en", layout, submitLabel = "Submit", nextLabel = "Next", backLabel = "Back", closeLabel = "Close", successMessage = "Thank you.", presentation, presentations, onClose, title, initialValues, honeypot, captchaToken, children, className, renderSubmit, renderNext, renderBack, submitButtonClassName, nextButtonClassName, backButtonClassName }) => {
|
|
73
73
|
const honeypotName = honeypot === false ? null : honeypot?.name ?? "website";
|
|
74
74
|
const honeypotRef = useRef(null);
|
|
75
75
|
const registry = useMemo(() => buildFieldTypeRegistry(fieldTypes), [fieldTypes]);
|
|
@@ -193,7 +193,7 @@ const Form = ({ form, fieldTypes, rules, renderers, apiRoute, onSubmit, onSucces
|
|
|
193
193
|
if (result.errors.length > 0) hasError = true;
|
|
194
194
|
}
|
|
195
195
|
if (hasError) return;
|
|
196
|
-
const next = resolveNextStepId(flow, currentStepId,
|
|
196
|
+
const next = resolveNextStepId(flow, currentStepId, effectiveValues);
|
|
197
197
|
if (!next) return;
|
|
198
198
|
emitFormEvent(sinkRef.current, formIdRef.current, {
|
|
199
199
|
type: "step.completed",
|
|
@@ -264,6 +264,29 @@ const Form = ({ form, fieldTypes, rules, renderers, apiRoute, onSubmit, onSucces
|
|
|
264
264
|
}
|
|
265
265
|
if (result.warnings.length > 0) warnings[result.field.name] = result.warnings;
|
|
266
266
|
}
|
|
267
|
+
for (const field of visible.filter((f) => f.blockType === "repeater")) {
|
|
268
|
+
const rows = Array.isArray(effectiveValues[field.name]) ? effectiveValues[field.name] : [];
|
|
269
|
+
const subFields = Array.isArray(field.subFields) ? field.subFields : [];
|
|
270
|
+
for (let rowIndex = 0; rowIndex < rows.length; rowIndex++) {
|
|
271
|
+
const row = rows[rowIndex] ?? {};
|
|
272
|
+
for (const subField of subFields) {
|
|
273
|
+
if (!evaluateCondition(subField.visibleWhen, row)) continue;
|
|
274
|
+
if (!evaluateCondition(subField.validateWhen, row)) continue;
|
|
275
|
+
const subResult = await validateFieldValue({
|
|
276
|
+
field: subField,
|
|
277
|
+
value: row[subField.name],
|
|
278
|
+
registry,
|
|
279
|
+
ruleRegistry,
|
|
280
|
+
answers: row,
|
|
281
|
+
locale,
|
|
282
|
+
t: translate
|
|
283
|
+
});
|
|
284
|
+
const compositeKey = `${field.name}[${rowIndex}].${subField.name}`;
|
|
285
|
+
if (subResult.errors.length > 0) errors[compositeKey] = subResult.errors;
|
|
286
|
+
if (subResult.warnings.length > 0) warnings[compositeKey] = subResult.warnings;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
267
290
|
rawDispatch({
|
|
268
291
|
type: "SET_ALL_ISSUES",
|
|
269
292
|
errors,
|
|
@@ -327,7 +350,7 @@ const Form = ({ form, fieldTypes, rules, renderers, apiRoute, onSubmit, onSucces
|
|
|
327
350
|
stepIndex: flow.steps.findIndex((s) => s.id === currentStepId),
|
|
328
351
|
stepCount: flow.steps.length,
|
|
329
352
|
isFirst: history.length === 0,
|
|
330
|
-
isTerminal: currentStepId ? isTerminalStepId(flow, currentStepId,
|
|
353
|
+
isTerminal: currentStepId ? isTerminalStepId(flow, currentStepId, effectiveValues) : true,
|
|
331
354
|
goNext: () => {
|
|
332
355
|
goNext();
|
|
333
356
|
},
|
|
@@ -345,7 +368,8 @@ const Form = ({ form, fieldTypes, rules, renderers, apiRoute, onSubmit, onSucces
|
|
|
345
368
|
dispatch,
|
|
346
369
|
validateField,
|
|
347
370
|
locale,
|
|
348
|
-
step
|
|
371
|
+
step,
|
|
372
|
+
rendererRegistry
|
|
349
373
|
};
|
|
350
374
|
const PresentationWrapper = activePresentation.Wrapper;
|
|
351
375
|
const wrap = (content) => PresentationWrapper ? /* @__PURE__ */ jsx(PresentationWrapper, {
|
|
@@ -425,25 +449,43 @@ const Form = ({ form, fieldTypes, rules, renderers, apiRoute, onSubmit, onSucces
|
|
|
425
449
|
}) : null,
|
|
426
450
|
flow ? /* @__PURE__ */ jsxs("div", {
|
|
427
451
|
className: "fb-form__controls",
|
|
428
|
-
children: [!step.isFirst ?
|
|
452
|
+
children: [!step.isFirst ? renderBack ? renderBack({
|
|
453
|
+
label: backLabel,
|
|
454
|
+
submitting: state.submitting,
|
|
455
|
+
onClick: goBack
|
|
456
|
+
}) : /* @__PURE__ */ jsx("button", {
|
|
429
457
|
type: "button",
|
|
458
|
+
className: backButtonClassName,
|
|
430
459
|
onClick: goBack,
|
|
431
460
|
disabled: state.submitting,
|
|
432
461
|
children: backLabel
|
|
433
|
-
}) : null, step.isTerminal ?
|
|
462
|
+
}) : null, step.isTerminal ? renderSubmit ? renderSubmit({
|
|
463
|
+
label: submitLabel,
|
|
464
|
+
submitting: state.submitting
|
|
465
|
+
}) : /* @__PURE__ */ jsx("button", {
|
|
434
466
|
type: "submit",
|
|
467
|
+
className: submitButtonClassName,
|
|
435
468
|
disabled: state.submitting,
|
|
436
469
|
children: submitLabel
|
|
470
|
+
}) : renderNext ? renderNext({
|
|
471
|
+
label: nextLabel,
|
|
472
|
+
submitting: state.submitting,
|
|
473
|
+
onClick: () => void goNext()
|
|
437
474
|
}) : /* @__PURE__ */ jsx("button", {
|
|
438
475
|
type: "button",
|
|
476
|
+
className: nextButtonClassName,
|
|
439
477
|
disabled: state.submitting,
|
|
440
478
|
onClick: () => {
|
|
441
479
|
goNext();
|
|
442
480
|
},
|
|
443
481
|
children: nextLabel
|
|
444
482
|
})]
|
|
483
|
+
}) : renderSubmit ? renderSubmit({
|
|
484
|
+
label: submitLabel,
|
|
485
|
+
submitting: state.submitting
|
|
445
486
|
}) : /* @__PURE__ */ jsx("button", {
|
|
446
487
|
type: "submit",
|
|
488
|
+
className: submitButtonClassName,
|
|
447
489
|
disabled: state.submitting,
|
|
448
490
|
children: submitLabel
|
|
449
491
|
})
|