@10x-media/form-builder 0.1.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,88 @@
1
+ //#region src/conditions/fieldTypes.ts
2
+ const EQUALITY = ["equals", "not_equals"];
3
+ const MEMBERSHIP = ["in", "not_in"];
4
+ const ORDER = [
5
+ "greater_than",
6
+ "greater_than_equal",
7
+ "less_than",
8
+ "less_than_equal"
9
+ ];
10
+ const TEXT_MATCH = [
11
+ "like",
12
+ "not_like",
13
+ "contains"
14
+ ];
15
+ const EXISTS = ["exists"];
16
+ /** Operators offered per condition type. Each is implemented by `evaluateCondition`. */
17
+ const conditionOperators = {
18
+ text: [
19
+ ...EQUALITY,
20
+ ...MEMBERSHIP,
21
+ ...TEXT_MATCH,
22
+ ...EXISTS
23
+ ],
24
+ number: [
25
+ ...EQUALITY,
26
+ ...MEMBERSHIP,
27
+ ...ORDER,
28
+ ...EXISTS
29
+ ],
30
+ select: [
31
+ ...EQUALITY,
32
+ ...MEMBERSHIP,
33
+ ...EXISTS
34
+ ],
35
+ checkbox: [...EQUALITY, ...EXISTS],
36
+ date: [
37
+ ...EQUALITY,
38
+ ...ORDER,
39
+ ...EXISTS
40
+ ]
41
+ };
42
+ /** Default condition input for a stored value kind; a field type may override via its `conditionType`. */
43
+ const defaultConditionType = (value) => {
44
+ switch (value) {
45
+ case "number": return "number";
46
+ case "boolean": return "checkbox";
47
+ case "date": return "date";
48
+ case "text[]": return "select";
49
+ default: return "text";
50
+ }
51
+ };
52
+ const OPERATOR_LABEL_KEYS = {
53
+ equals: "operators:equals",
54
+ not_equals: "operators:isNotEqualTo",
55
+ in: "operators:isIn",
56
+ not_in: "operators:isNotIn",
57
+ exists: "operators:exists",
58
+ greater_than: "operators:isGreaterThan",
59
+ greater_than_equal: "operators:isGreaterThanOrEqualTo",
60
+ less_than: "operators:isLessThan",
61
+ less_than_equal: "operators:isLessThanOrEqualTo",
62
+ like: "operators:isLike",
63
+ not_like: "operators:isNotLike",
64
+ contains: "operators:contains"
65
+ };
66
+ /**
67
+ * The i18n key for an operator's label, in Payload's own `operators:*` namespace (always present in the
68
+ * admin), so the builder reads native, localized operator labels without duplicating them in our i18n.
69
+ * Keys mirror Payload's `WhereBuilder/field-types.tsx` operator labels. Every operator surfaced by
70
+ * `conditionOperators` is mapped; the `operators:equals` fallback is unreachable for the offered
71
+ * catalogs (no geo/`all` operator is ever presented) and exists only to keep the return type total.
72
+ */
73
+ const operatorLabelKey = (operator) => OPERATOR_LABEL_KEYS[operator] ?? "operators:equals";
74
+ /**
75
+ * The first (default) operator a condition type offers. Every catalog leads with `equals`, so the
76
+ * fallback is unreachable; it exists only to keep the return non-optional under `noUncheckedIndexedAccess`.
77
+ */
78
+ const firstOperatorFor = (type) => conditionOperators[type][0] ?? "equals";
79
+ /** The value control an operator needs: a boolean toggle (`exists`), a list (`in`/`not_in`), or a scalar. */
80
+ const operatorValueShape = (operator) => {
81
+ if (operator === "exists") return "boolean";
82
+ if (operator === "in" || operator === "not_in") return "array";
83
+ return "scalar";
84
+ };
85
+ //#endregion
86
+ export { operatorValueShape as a, operatorLabelKey as i, defaultConditionType as n, firstOperatorFor as r, conditionOperators as t };
87
+
88
+ //# sourceMappingURL=fieldTypes-CzhhJXjg.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fieldTypes-CzhhJXjg.js","names":[],"sources":["../src/conditions/fieldTypes.ts"],"sourcesContent":["import type { Operator } from 'payload'\nimport type { FormFieldValueKind } from '../fields/types'\n\n/**\n * The condition input families the builder supports. A deliberate subset of Payload's field-condition\n * types, restricted to the operators `evaluateCondition` implements (no geo/relationship in v1).\n */\nexport type ConditionFieldType = 'text' | 'number' | 'select' | 'checkbox' | 'date'\n\nconst EQUALITY: Operator[] = ['equals', 'not_equals']\nconst MEMBERSHIP: Operator[] = ['in', 'not_in']\nconst ORDER: Operator[] = ['greater_than', 'greater_than_equal', 'less_than', 'less_than_equal']\nconst TEXT_MATCH: Operator[] = ['like', 'not_like', 'contains']\nconst EXISTS: Operator[] = ['exists']\n\n/** Operators offered per condition type. Each is implemented by `evaluateCondition`. */\nexport const conditionOperators: Record<ConditionFieldType, Operator[]> = {\n\ttext: [...EQUALITY, ...MEMBERSHIP, ...TEXT_MATCH, ...EXISTS],\n\tnumber: [...EQUALITY, ...MEMBERSHIP, ...ORDER, ...EXISTS],\n\tselect: [...EQUALITY, ...MEMBERSHIP, ...EXISTS],\n\tcheckbox: [...EQUALITY, ...EXISTS],\n\tdate: [...EQUALITY, ...ORDER, ...EXISTS],\n}\n\n/** Default condition input for a stored value kind; a field type may override via its `conditionType`. */\nexport const defaultConditionType = (value: FormFieldValueKind): ConditionFieldType => {\n\tswitch (value) {\n\t\tcase 'number':\n\t\t\treturn 'number'\n\t\tcase 'boolean':\n\t\t\treturn 'checkbox'\n\t\tcase 'date':\n\t\t\treturn 'date'\n\t\tcase 'text[]':\n\t\t\treturn 'select'\n\t\tdefault:\n\t\t\treturn 'text'\n\t}\n}\n\n/**\n * The Payload `operators:*` i18n keys the builder uses for operator labels. A local literal union (not\n * imported from `@payloadcms/translations`, which this package never depends on); each member is a real\n * client translation key, so a value of this type is accepted by Payload's `i18n.t`.\n */\nexport type OperatorLabelKey =\n\t| 'operators:contains'\n\t| 'operators:equals'\n\t| 'operators:exists'\n\t| 'operators:isGreaterThan'\n\t| 'operators:isGreaterThanOrEqualTo'\n\t| 'operators:isIn'\n\t| 'operators:isLessThan'\n\t| 'operators:isLessThanOrEqualTo'\n\t| 'operators:isLike'\n\t| 'operators:isNotEqualTo'\n\t| 'operators:isNotIn'\n\t| 'operators:isNotLike'\n\nconst OPERATOR_LABEL_KEYS: Partial<Record<Operator, OperatorLabelKey>> = {\n\tequals: 'operators:equals',\n\tnot_equals: 'operators:isNotEqualTo',\n\tin: 'operators:isIn',\n\tnot_in: 'operators:isNotIn',\n\texists: 'operators:exists',\n\tgreater_than: 'operators:isGreaterThan',\n\tgreater_than_equal: 'operators:isGreaterThanOrEqualTo',\n\tless_than: 'operators:isLessThan',\n\tless_than_equal: 'operators:isLessThanOrEqualTo',\n\tlike: 'operators:isLike',\n\tnot_like: 'operators:isNotLike',\n\tcontains: 'operators:contains',\n}\n\n/**\n * The i18n key for an operator's label, in Payload's own `operators:*` namespace (always present in the\n * admin), so the builder reads native, localized operator labels without duplicating them in our i18n.\n * Keys mirror Payload's `WhereBuilder/field-types.tsx` operator labels. Every operator surfaced by\n * `conditionOperators` is mapped; the `operators:equals` fallback is unreachable for the offered\n * catalogs (no geo/`all` operator is ever presented) and exists only to keep the return type total.\n */\nexport const operatorLabelKey = (operator: Operator): OperatorLabelKey =>\n\tOPERATOR_LABEL_KEYS[operator] ?? 'operators:equals'\n\n/**\n * The first (default) operator a condition type offers. Every catalog leads with `equals`, so the\n * fallback is unreachable; it exists only to keep the return non-optional under `noUncheckedIndexedAccess`.\n */\nexport const firstOperatorFor = (type: ConditionFieldType): Operator =>\n\tconditionOperators[type][0] ?? 'equals'\n\n/** The value control an operator needs: a boolean toggle (`exists`), a list (`in`/`not_in`), or a scalar. */\nexport const operatorValueShape = (operator: Operator): 'boolean' | 'array' | 'scalar' => {\n\tif (operator === 'exists') {\n\t\treturn 'boolean'\n\t}\n\tif (operator === 'in' || operator === 'not_in') {\n\t\treturn 'array'\n\t}\n\treturn 'scalar'\n}\n"],"mappings":";AASA,MAAM,WAAuB,CAAC,UAAU,YAAY;AACpD,MAAM,aAAyB,CAAC,MAAM,QAAQ;AAC9C,MAAM,QAAoB;CAAC;CAAgB;CAAsB;CAAa;AAAiB;AAC/F,MAAM,aAAyB;CAAC;CAAQ;CAAY;AAAU;AAC9D,MAAM,SAAqB,CAAC,QAAQ;;AAGpC,MAAa,qBAA6D;CACzE,MAAM;EAAC,GAAG;EAAU,GAAG;EAAY,GAAG;EAAY,GAAG;CAAM;CAC3D,QAAQ;EAAC,GAAG;EAAU,GAAG;EAAY,GAAG;EAAO,GAAG;CAAM;CACxD,QAAQ;EAAC,GAAG;EAAU,GAAG;EAAY,GAAG;CAAM;CAC9C,UAAU,CAAC,GAAG,UAAU,GAAG,MAAM;CACjC,MAAM;EAAC,GAAG;EAAU,GAAG;EAAO,GAAG;CAAM;AACxC;;AAGA,MAAa,wBAAwB,UAAkD;CACtF,QAAQ,OAAR;EACC,KAAK,UACJ,OAAO;EACR,KAAK,WACJ,OAAO;EACR,KAAK,QACJ,OAAO;EACR,KAAK,UACJ,OAAO;EACR,SACC,OAAO;CACT;AACD;AAqBA,MAAM,sBAAmE;CACxE,QAAQ;CACR,YAAY;CACZ,IAAI;CACJ,QAAQ;CACR,QAAQ;CACR,cAAc;CACd,oBAAoB;CACpB,WAAW;CACX,iBAAiB;CACjB,MAAM;CACN,UAAU;CACV,UAAU;AACX;;;;;;;;AASA,MAAa,oBAAoB,aAChC,oBAAoB,aAAa;;;;;AAMlC,MAAa,oBAAoB,SAChC,mBAAmB,MAAM,MAAM;;AAGhC,MAAa,sBAAsB,aAAuD;CACzF,IAAI,aAAa,UAChB,OAAO;CAER,IAAI,aAAa,QAAQ,aAAa,UACrC,OAAO;CAER,OAAO;AACR"}
@@ -0,0 +1,481 @@
1
+ import { c as Translate, d as FileRefError, i as FormFieldDefinition, l as FileFieldConfig, r as FormFieldConfigValues, s as FormFieldValueKind, u as FileRef } from "./fieldTypes-B8jkNRob.js";
2
+ import { A as FieldMeta, E as CalcExpression, F as SubmissionValue, M as FormFieldInstance, N as SubmissionDescriptor, O as AggregationRow, c as PresentationDescriptor, d as ValidationParams, f as ValidationRuleDefinition, g as FormEventSink, j as SubmissionStatusFilter, k as FieldAggregation, u as AnyValidationRuleDefinition, x as FieldTypesConfig } from "./constants-B-BUfetP.js";
3
+ import { CollectionConfig, Field, Payload, PayloadRequest, Where as Where$1 } from "payload";
4
+
5
+ //#region src/actions/defineAction.d.ts
6
+ /** Context passed to an action's `run` when a submission completes. */
7
+ type ActionRunArgs<TConfig extends Record<string, unknown> = Record<string, unknown>> = {
8
+ form: {
9
+ id: number | string;
10
+ title?: string;
11
+ };
12
+ submissionId: number | string;
13
+ values: SubmissionValue[];
14
+ descriptors: SubmissionDescriptor[];
15
+ config: TConfig;
16
+ payload: Payload;
17
+ req?: PayloadRequest;
18
+ locale: string;
19
+ t: Translate;
20
+ };
21
+ /**
22
+ * A post-submit action type, authored once: `config` is the admin `Field[]` for authoring;
23
+ * `run` executes when a submission completes. Built-ins use this same primitive.
24
+ */
25
+ type ActionDefinition<TConfig extends Record<string, unknown> = Record<string, unknown>> = {
26
+ type: string;
27
+ label: string;
28
+ config?: Field[];
29
+ run: (args: ActionRunArgs<TConfig>) => Promise<void> | void;
30
+ };
31
+ /** Erased shape stored in the registry; config re-narrows per matched type at execution. */
32
+ type AnyActionDefinition = ActionDefinition<Record<string, unknown>>;
33
+ declare const defineAction: <TConfig extends Record<string, unknown> = Record<string, unknown>>(definition: ActionDefinition<TConfig>) => ActionDefinition<TConfig>;
34
+ //#endregion
35
+ //#region src/actions/registry.d.ts
36
+ type ActionRegistry = Map<string, AnyActionDefinition>;
37
+ /** `false` removes a built-in, `true` keeps it, a definition adds or replaces one. */
38
+ type ActionOption = boolean | AnyActionDefinition;
39
+ type ActionsConfig = Record<string, ActionOption>;
40
+ /**
41
+ * Resolve the active action registry from built-in defaults and a consumer override map. `false`
42
+ * removes a type, `true` keeps the default (no-op when none exists), a definition adds or replaces.
43
+ * Mirrors the field-type and validation-rule registry convention.
44
+ */
45
+ declare const resolveActions: (defaults: Record<string, AnyActionDefinition>, config?: ActionsConfig) => ActionRegistry;
46
+ //#endregion
47
+ //#region src/actions/runActions.d.ts
48
+ type ActionResult = {
49
+ type: string;
50
+ ok: boolean;
51
+ error?: string;
52
+ };
53
+ //#endregion
54
+ //#region src/aggregation/aggregateResponses.d.ts
55
+ type AggregateFormResponsesArgs = {
56
+ payload: Payload;
57
+ formId: number | string; /** Field machine names to aggregate. Defaults to every field that declares options (enumerable). */
58
+ fields?: string[]; /** Submission status to count. Defaults to `complete`. */
59
+ status?: SubmissionStatusFilter;
60
+ req?: PayloadRequest; /** Safety cap on submissions scanned; beyond it the result is flagged `truncated`. Default 10000. */
61
+ maxSubmissions?: number; /** Page size for the submission scan. Default 500. */
62
+ pageSize?: number;
63
+ };
64
+ /** True when a field declares non-empty options (a choice field safe to aggregate publicly). */
65
+ declare const fieldHasOptions: (field: FormFieldInstance) => boolean;
66
+ /**
67
+ * Aggregate submission responses for a form. Loads the form for current labels + option order, then pages
68
+ * `payload.find` over its submissions (JSON `values` cannot be GROUP BY'd portably across Mongo + Postgres,
69
+ * so we scan + reduce in JS, cross-DB-identically). Bounded by `maxSubmissions`; beyond it the result is
70
+ * `truncated`. Returns one `FieldAggregation` per requested field (or per enumerable field by default).
71
+ */
72
+ declare const aggregateFormResponses: (args: AggregateFormResponsesArgs) => Promise<FieldAggregation[]>;
73
+ type AggregateFieldResponsesArgs = Omit<AggregateFormResponsesArgs, 'fields'> & {
74
+ field: string;
75
+ };
76
+ /** Single-field convenience over `aggregateFormResponses`. Returns the field's aggregation, or null if absent. */
77
+ declare const aggregateFieldResponses: (args: AggregateFieldResponsesArgs) => Promise<FieldAggregation | null>;
78
+ //#endregion
79
+ //#region src/aggregation/resolveResultsRequest.d.ts
80
+ type ResolveResultsRequestArgs = {
81
+ payload: Payload;
82
+ formId: number | string | undefined; /** The requested field (query param). */
83
+ field?: string; /** Whether the caller is authenticated (an admin/user). */
84
+ isAuthed: boolean;
85
+ req?: PayloadRequest;
86
+ };
87
+ type ResolveResultsRequestResult = {
88
+ status: number;
89
+ body: {
90
+ results: FieldAggregation[];
91
+ } | {
92
+ errors: {
93
+ message: string;
94
+ }[];
95
+ };
96
+ };
97
+ /**
98
+ * Authorize and resolve a poll/survey results request. Authed callers may aggregate any field (or all
99
+ * enumerable fields). Anonymous callers are allowed only when the form opted in (`showResults`), and then
100
+ * only for the configured `resultsField`, and only if that field is enumerable (has options) so a
101
+ * misconfigured `resultsField` pointing at a free-text or PII field can never be dumped publicly. Returns
102
+ * only aggregate counts, never raw submissions.
103
+ */
104
+ declare const resolveFormResultsRequest: (args: ResolveResultsRequestArgs) => Promise<ResolveResultsRequestResult>;
105
+ //#endregion
106
+ //#region src/collections/uploads.d.ts
107
+ declare const FORM_UPLOADS_SLUG = "form-uploads";
108
+ /** Override surface for the built-in upload collection. */
109
+ type UploadsCollectionConfig = {
110
+ slug?: string; /** Merged onto the collection's `upload` config (e.g. `staticDir`, `mimeTypes`). `true` uses Payload defaults. */
111
+ upload?: NonNullable<CollectionConfig['upload']> | true; /** Replace access (defaults: anonymous create, authed read/update/delete). */
112
+ access?: CollectionConfig['access']; /** Append extra fields. */
113
+ fields?: CollectionConfig['fields'];
114
+ };
115
+ type UploadsOption = boolean | UploadsCollectionConfig;
116
+ /**
117
+ * The built-in upload collection backing the `file` field. Anonymous create (public forms upload here),
118
+ * authed read/update/delete (only admins read stored files; submitters cannot enumerate others' uploads).
119
+ * Per-field MIME/size is re-enforced at submit, so the collection stays permissive by default. No
120
+ * `imageSizes`, so it needs no `sharp`. Projects with their own upload collection set `uploads: false` and
121
+ * point the file field's `relationTo` at theirs.
122
+ */
123
+ declare const buildUploadsCollection: (config?: UploadsCollectionConfig) => CollectionConfig;
124
+ /** Resolve the `uploads` plugin option: `false` disables, `true`/object enables the built-in collection. */
125
+ declare const resolveUploads: (option: UploadsOption | undefined) => {
126
+ enabled: boolean;
127
+ slug: string;
128
+ collection?: CollectionConfig;
129
+ };
130
+ //#endregion
131
+ //#region src/conditions/types.d.ts
132
+ /** A serializable field-visibility/validation condition, stored in Payload's canonical `Where` shape. */
133
+ type FieldCondition = Where$1;
134
+ //#endregion
135
+ //#region src/consent/defineConsentSource.d.ts
136
+ type ConsentLink = {
137
+ label: string;
138
+ url: string;
139
+ };
140
+ type ConsentResolved = {
141
+ links: ConsentLink[];
142
+ versionRef?: string;
143
+ versionLabel?: string;
144
+ };
145
+ type ConsentResolveArgs<TConfig extends Record<string, unknown> = Record<string, unknown>> = {
146
+ config: TConfig;
147
+ payload: Payload;
148
+ req?: PayloadRequest;
149
+ locale: string;
150
+ };
151
+ /**
152
+ * A consent source type, authored once: `config` is the admin `Field[]` for authoring;
153
+ * `resolve` returns localized policy links and an optional version reference at capture time.
154
+ * Built-ins use this same primitive.
155
+ */
156
+ type ConsentSource<TConfig extends Record<string, unknown> = Record<string, unknown>> = {
157
+ type: string;
158
+ label: string;
159
+ config?: Field[];
160
+ resolve: (args: ConsentResolveArgs<TConfig>) => Promise<ConsentResolved> | ConsentResolved;
161
+ };
162
+ /** Erased shape stored in the registry; config re-narrows per matched type at resolution. */
163
+ type AnyConsentSource = ConsentSource<Record<string, unknown>>;
164
+ declare const defineConsentSource: <TConfig extends Record<string, unknown> = Record<string, unknown>>(source: ConsentSource<TConfig>) => ConsentSource<TConfig>;
165
+ //#endregion
166
+ //#region src/consent/registry.d.ts
167
+ type ConsentSourceRegistry = Map<string, AnyConsentSource>;
168
+ /** `false` removes a built-in, `true` keeps it, a definition adds or replaces one. */
169
+ type ConsentSourceOption = boolean | AnyConsentSource;
170
+ type ConsentSourcesConfig = Record<string, ConsentSourceOption>;
171
+ /**
172
+ * Resolve the active consent-source registry from built-in defaults and a consumer override map.
173
+ * `false` removes a type, `true` keeps the default (no-op when none exists), a definition adds or
174
+ * replaces. Mirrors the action and field-type registry convention.
175
+ */
176
+ declare const resolveConsentSources: (defaults: Record<string, AnyConsentSource>, config?: ConsentSourcesConfig) => ConsentSourceRegistry;
177
+ //#endregion
178
+ //#region src/consent/captureConsent.d.ts
179
+ type ConsentProof = {
180
+ agreed: boolean;
181
+ ref?: string;
182
+ versionRef?: string;
183
+ at: string;
184
+ };
185
+ /**
186
+ * Build the authoritative consent proof at submit time: re-resolve the source server-side
187
+ * (ignores any client ref), capturing a reference url -- never the policy text.
188
+ * `now` is injected by the caller (`new Date().toISOString()`) for testability.
189
+ */
190
+ declare const captureConsent: (args: {
191
+ field: FormFieldInstance;
192
+ agreed: boolean;
193
+ registry: ConsentSourceRegistry;
194
+ payload: Payload;
195
+ req?: PayloadRequest;
196
+ locale: string;
197
+ now: string;
198
+ }) => Promise<ConsentProof>;
199
+ //#endregion
200
+ //#region src/presentations/registry.d.ts
201
+ type PresentationDescriptorRegistry = Map<string, PresentationDescriptor>;
202
+ /** Per-name override: `false` removes, `true` keeps the default, a descriptor adds or replaces one. */
203
+ type PresentationDescriptorOption = boolean | PresentationDescriptor;
204
+ type PresentationsDescriptorConfig = Record<string, PresentationDescriptorOption>;
205
+ /**
206
+ * Resolve the active presentation descriptors from the defaults and a consumer override map.
207
+ * Mirrors the field-type, validation-rule, and renderer registry convention.
208
+ */
209
+ declare const resolvePresentationDescriptors: (defaults: Record<string, PresentationDescriptor>, config?: PresentationsDescriptorConfig) => PresentationDescriptorRegistry;
210
+ //#endregion
211
+ //#region src/spam/types.d.ts
212
+ /** Stable identity key for a request, or null/undefined when the client cannot be identified (rate-limiting then skips: fail-open). */
213
+ type IdentifyFn = (req: PayloadRequest) => null | string | undefined | Promise<null | string | undefined>;
214
+ type RateLimitResult = {
215
+ ok: boolean; /** Remaining requests in the current window (>= 0). */
216
+ remaining: number; /** Epoch ms when the current window resets. */
217
+ resetAt: number;
218
+ };
219
+ type RateLimitCheckArgs = {
220
+ key: string; /** Max requests per window. */
221
+ max: number; /** Window length in ms. */
222
+ window: number;
223
+ req: PayloadRequest;
224
+ };
225
+ /** Pluggable limiter. The default is a window counter over `payload.kv`; swap for Redis/etc. */
226
+ type RateLimiter = {
227
+ check(args: RateLimitCheckArgs): Promise<RateLimitResult>;
228
+ };
229
+ type CaptchaVerifyArgs = {
230
+ token: string;
231
+ req: PayloadRequest;
232
+ };
233
+ /** A captcha adapter. v1 ships the seam only (no built-in provider). Build with `defineCaptchaProvider`. */
234
+ type CaptchaProvider = {
235
+ type: string;
236
+ verify(args: CaptchaVerifyArgs): Promise<boolean>;
237
+ };
238
+ type RateLimitConfig = {
239
+ /** Window length in ms. Default 60000. */window?: number; /** Max creates per identity per window. */
240
+ max?: number; /** Override the limiter (default: KV window counter). */
241
+ limiter?: RateLimiter;
242
+ };
243
+ type SpamMetadataConfig = {
244
+ /** Persist the client IP (from the trusted header) onto the submission `meta`. Default false (privacy). */ip?: boolean; /** Persist the user-agent onto the submission `meta`. Default false. */
245
+ ua?: boolean;
246
+ };
247
+ type SpamConfig = {
248
+ /** Honeypot decoy. Default on. `false` disables. */honeypot?: false | {
249
+ fieldName?: string;
250
+ }; /** Per-identity rate limit on submission create. Default on (60s window, max 5). `false` disables. */
251
+ rateLimit?: false | RateLimitConfig; /** Per-identity rate limit on upload create. Default on (60s window, max 20). `false` disables. */
252
+ uploadRateLimit?: false | RateLimitConfig; /** A captcha provider (none by default; seam only in v1). */
253
+ captcha?: CaptchaProvider; /** Identity resolution for rate-limiting, upload ownership, and (future) poll dedup. Default: user id, else trusted IP header. */
254
+ identify?: IdentifyFn; /** Header read for the client IP (proxy-dependent, best-effort). Default 'x-forwarded-for'. */
255
+ ipHeader?: string; /** Opt-in capture of client metadata onto the submission `meta`. Off by default. */
256
+ metadata?: SpamMetadataConfig;
257
+ };
258
+ /** `false` disables the whole subsystem; an object configures it (all controls default on except captcha + metadata). */
259
+ type SpamOption = false | SpamConfig;
260
+ type ResolvedRateLimit = {
261
+ window: number;
262
+ max: number;
263
+ limiter: RateLimiter;
264
+ };
265
+ type ResolvedSpamConfig = {
266
+ honeypot: false | {
267
+ fieldName: string;
268
+ };
269
+ rateLimit: false | ResolvedRateLimit;
270
+ uploadRateLimit: false | ResolvedRateLimit;
271
+ captcha?: CaptchaProvider;
272
+ identify: IdentifyFn;
273
+ ipHeader: string;
274
+ metadata: {
275
+ ip: boolean;
276
+ ua: boolean;
277
+ };
278
+ };
279
+ //#endregion
280
+ //#region src/validation/registry.d.ts
281
+ type ValidationRuleRegistry = Map<string, AnyValidationRuleDefinition>;
282
+ /** Per-rule opt-in: `false` removes a built-in, `true` keeps it, an object adds a new rule or replaces one. */
283
+ type ValidationRuleOption = boolean | AnyValidationRuleDefinition;
284
+ type ValidationRulesConfig = Record<string, ValidationRuleOption>;
285
+ //#endregion
286
+ //#region src/actions/builtin/index.d.ts
287
+ declare const defaultActionDefinitions: Record<string, AnyActionDefinition>;
288
+ //#endregion
289
+ //#region src/actions/sign.d.ts
290
+ declare const SIGNATURE_HEADER = "X-Form-Signature";
291
+ /** HMAC-SHA256 over `body`, hex-encoded, wrapped in the versioned header value (`v1=<hex>`). */
292
+ declare const signPayload: (body: string, secret: string) => string;
293
+ //#endregion
294
+ //#region src/aggregation/aggregateRows.d.ts
295
+ /** Aggregate one field across rows: respondent-denominated counts + percentages, option-ordered. */
296
+ declare const aggregateRowForField: (rows: AggregationRow[], meta: FieldMeta, truncated: boolean) => FieldAggregation;
297
+ /** Aggregate several fields across the same set of rows. */
298
+ declare const aggregateRowsForFields: (rows: AggregationRow[], metas: FieldMeta[], truncated: boolean) => FieldAggregation[];
299
+ //#endregion
300
+ //#region src/calc/normalizeCalc.d.ts
301
+ /** Structural guard: returns a valid CalcExpression if `value` is structurally sound (depth-guarded at 64), otherwise undefined. Never throws. */
302
+ declare const normalizeCalc: (value: unknown) => CalcExpression | undefined;
303
+ //#endregion
304
+ //#region src/consent/builtin/index.d.ts
305
+ declare const defaultConsentSources: Record<string, AnyConsentSource>;
306
+ //#endregion
307
+ //#region src/consent/resolveConsentLinks.d.ts
308
+ /**
309
+ * Resolve a consent field's policy links via its configured source (for display).
310
+ * Unknown/missing source returns empty links. Never throws.
311
+ */
312
+ declare const resolveConsentLinks: (field: FormFieldInstance, ctx: {
313
+ registry: ConsentSourceRegistry;
314
+ payload: Payload;
315
+ req?: PayloadRequest;
316
+ locale: string;
317
+ }) => Promise<ConsentResolved>;
318
+ //#endregion
319
+ //#region src/consent/resolvePublishedVersionRef.d.ts
320
+ /**
321
+ * Returns the latest published version of a doc, or null when versions/drafts are off or nothing
322
+ * is published. Never throws.
323
+ */
324
+ declare const resolvePublishedVersionRef: (payload: Payload, args: {
325
+ collection: string;
326
+ id: string | number;
327
+ }) => Promise<{
328
+ versionId: string;
329
+ updatedAt: string;
330
+ } | null>;
331
+ //#endregion
332
+ //#region src/fields/defineFormField.d.ts
333
+ /**
334
+ * Define a form field type once and get every facet from one object: a Payload `Field[]` for
335
+ * authoring, an isomorphic `validate`, a localized `format`, and a renderer ref. Built-ins use
336
+ * this same primitive, so custom field types are never second-class. The `value` kind drives the
337
+ * typed value threaded into `validate`/`format`; the optional second generic types the config.
338
+ */
339
+ declare const defineFormField: <K extends FormFieldValueKind, TConfig extends FormFieldConfigValues = FormFieldConfigValues>(definition: FormFieldDefinition<K, TConfig>) => FormFieldDefinition<K, TConfig>;
340
+ //#endregion
341
+ //#region src/presentations/defaults.d.ts
342
+ declare const DEFAULT_PRESENTATION_NAME = "page";
343
+ declare const defaultPresentationDescriptors: {
344
+ page: {
345
+ name: string;
346
+ label: "formBuilder:presentation.page";
347
+ surface: "page";
348
+ density: "comfortable";
349
+ };
350
+ inline: {
351
+ name: string;
352
+ label: "formBuilder:presentation.inline";
353
+ surface: "inline";
354
+ density: "comfortable";
355
+ };
356
+ modal: {
357
+ name: string;
358
+ label: "formBuilder:presentation.modal";
359
+ surface: "overlay";
360
+ density: "comfortable";
361
+ dismissOnSuccess: true;
362
+ };
363
+ drawer: {
364
+ name: string;
365
+ label: "formBuilder:presentation.drawer";
366
+ surface: "overlay";
367
+ density: "comfortable";
368
+ dismissOnSuccess: true;
369
+ };
370
+ };
371
+ //#endregion
372
+ //#region src/spam/captcha.d.ts
373
+ /**
374
+ * Identity helper for authoring a captcha provider (mirrors `defineAction`/`defineConsentSource`).
375
+ * v1 ships no built-in provider; a project supplies one (Turnstile/reCAPTCHA/hCaptcha) and the submit
376
+ * path verifies a token carried on the submission. Prebuilt providers are a v1.x addition.
377
+ */
378
+ declare const defineCaptchaProvider: (provider: CaptchaProvider) => CaptchaProvider;
379
+ //#endregion
380
+ //#region src/spam/identify.d.ts
381
+ /**
382
+ * Default identity resolution for rate-limiting + upload ownership. Prefers an authenticated user id
383
+ * (trustworthy); else the first hop of the configured trusted IP header (best-effort, proxy-dependent);
384
+ * else null, in which case the caller fails open (cannot fairly rate-limit an unidentifiable client).
385
+ */
386
+ declare const defaultIdentify: (ipHeader: string) => IdentifyFn;
387
+ //#endregion
388
+ //#region src/spam/rateLimiter.d.ts
389
+ /**
390
+ * The default rate limiter: a read-modify-write window counter over Payload's `payload.kv`
391
+ * (always present; default `DatabaseKVAdapter`, durable + cross-instance). Because the KV interface
392
+ * has no atomic increment, the get-then-set is NON-ATOMIC, so a concurrent burst can slightly undercount.
393
+ * This is a SOFT limit, acceptable for spam basics and complemented by edge/WAF limiting. The window
394
+ * expires lazily on read; stale keys for one-time identities linger (minor; the count self-resets).
395
+ * `now` is injectable for tests.
396
+ */
397
+ declare const createKvRateLimiter: (options?: {
398
+ now?: () => number;
399
+ namespace?: string;
400
+ }) => RateLimiter;
401
+ //#endregion
402
+ //#region src/spam/resolveSpam.d.ts
403
+ /**
404
+ * Resolve the `spam` plugin option into a concrete config. `false` disables the whole subsystem.
405
+ * Otherwise honeypot + both rate limits default on, captcha + metadata capture default off, and the
406
+ * identity seam defaults to user id / trusted IP header.
407
+ */
408
+ declare const resolveSpamConfig: (option: SpamOption | undefined) => ResolvedSpamConfig | false;
409
+ //#endregion
410
+ //#region src/uploads/resolveFileRef.d.ts
411
+ type UploadDoc = {
412
+ id?: string | number;
413
+ filename?: unknown;
414
+ mimeType?: unknown;
415
+ filesize?: unknown;
416
+ url?: unknown;
417
+ };
418
+ type ResolveFileRefResult = {
419
+ ok: true;
420
+ ref: FileRef;
421
+ } | {
422
+ ok: false;
423
+ code: FileRefError;
424
+ };
425
+ /**
426
+ * Pure server trust-boundary check for an uploaded file: given the loaded upload doc (or null) and the
427
+ * field's constraints, either return an authoritative `FileRef` snapshot or a rejection code. Never trusts
428
+ * client metadata; the caller passes the doc it loaded from the upload collection.
429
+ */
430
+ declare const resolveFileRef: (doc: UploadDoc | null | undefined, config: FileFieldConfig) => ResolveFileRefResult;
431
+ //#endregion
432
+ //#region src/uploads/captureFileRef.d.ts
433
+ type CaptureFileRefArgs = {
434
+ payload: Payload;
435
+ collectionSlug: string;
436
+ uploadId: string | number;
437
+ config: FileFieldConfig;
438
+ req?: PayloadRequest; /** Resolved submitter identity; must match the upload's `owner` stamp when both are present. */
439
+ expectedOwner?: string;
440
+ };
441
+ /**
442
+ * Load the referenced upload doc and run the pure trust-boundary check. The client sends only the id; the
443
+ * filename/mimeType/filesize are read authoritatively from the stored doc, never from the client. When the
444
+ * upload carries an `owner` stamp AND the submitter is identifiable, the two must match, so an anonymous
445
+ * submitter cannot capture another identity's upload; a mismatch collapses to `missing`, indistinguishable
446
+ * from a deleted upload. When the submitter cannot be identified (no `expectedOwner`), ownership is not
447
+ * enforced (fail-open, consistent with rate-limiting): a proxy-configured deployment identifies every
448
+ * request, so this only relaxes scoping where it could not be applied fairly anyway. Unstamped uploads
449
+ * (no identity at upload time, or a BYO collection without the field) pass unchanged.
450
+ */
451
+ declare const captureFileRef: (args: CaptureFileRefArgs) => Promise<ResolveFileRefResult>;
452
+ //#endregion
453
+ //#region src/validation/defineValidationRule.d.ts
454
+ /**
455
+ * Define a validation rule type once: its `params` become a Payload `Field[]` in the per-field
456
+ * constraint list, its typed `validate` runs in the one engine on client and server. Built-in rules
457
+ * use this same primitive, so custom rules are never second-class.
458
+ */
459
+ declare const defineValidationRule: <TParams extends ValidationParams, TValue = unknown, TData extends Record<string, unknown> = Record<string, unknown>>(rule: ValidationRuleDefinition<TParams, TValue, TData>) => ValidationRuleDefinition<TParams, TValue, TData>;
460
+ //#endregion
461
+ //#region src/index.d.ts
462
+ type FormBuilderPluginOptions = {
463
+ disabled?: boolean; /** Pluggable sink for form lifecycle events. Defaults to a no-op; analytics adapters or a future analytics plugin subscribe here. */
464
+ events?: FormEventSink; /** Add, override, or remove field types. `false` removes a built-in, `true` keeps it, an object adds or replaces one. */
465
+ fields?: FieldTypesConfig; /** Add, override, or remove presentations. `false` removes a built-in, `true` keeps it, an object adds or replaces one. */
466
+ presentations?: PresentationsDescriptorConfig; /** Add, override, or remove validation rule types. `false` removes a built-in, `true` keeps it, an object adds or replaces one. */
467
+ rules?: ValidationRulesConfig; /** Add, override, or remove post-submit action types. `false` removes a built-in, `true` keeps it, an object adds or replaces one. */
468
+ actions?: ActionsConfig; /** Add, override, or remove consent source types. `false` removes a built-in, `true` keeps it, an object adds or replaces one. */
469
+ consentSources?: ConsentSourcesConfig; /** The built-in `form-uploads` collection backing file fields. `false` disables it (bring your own); an object overrides slug/upload/access/fields. */
470
+ uploads?: UploadsOption; /** Honeypot + rate-limiting (on by default) + a captcha adapter seam + upload-ownership scoping. `false` disables the whole subsystem. */
471
+ spam?: SpamOption;
472
+ };
473
+ declare module 'payload' {
474
+ interface RegisteredPlugins {
475
+ '@10x-media/form-builder': FormBuilderPluginOptions;
476
+ }
477
+ }
478
+ declare const formBuilder: (options: FormBuilderPluginOptions) => import("payload").Plugin;
479
+ //#endregion
480
+ export { UploadsCollectionConfig as $, RateLimitResult as A, captureConsent as B, ValidationRuleRegistry as C, IdentifyFn as D, CaptchaVerifyArgs as E, PresentationDescriptorOption as F, AnyConsentSource as G, ConsentSourceRegistry as H, PresentationDescriptorRegistry as I, ConsentResolved as J, ConsentLink as K, PresentationsDescriptorConfig as L, SpamConfig as M, SpamMetadataConfig as N, RateLimitCheckArgs as O, SpamOption as P, FORM_UPLOADS_SLUG as Q, resolvePresentationDescriptors as R, ValidationRuleOption as S, CaptchaProvider as T, ConsentSourcesConfig as U, ConsentSourceOption as V, resolveConsentSources as W, defineConsentSource as X, ConsentSource as Y, FieldCondition as Z, aggregateRowForField as _, ActionRunArgs as _t, resolveFileRef as a, resolveFormResultsRequest as at, signPayload as b, defaultIdentify as c, aggregateFieldResponses as ct, defaultPresentationDescriptors as d, ActionResult as dt, UploadsOption as et, defineFormField as f, ActionOption as ft, normalizeCalc as g, ActionDefinition as gt, defaultConsentSources as h, resolveActions as ht, captureFileRef as i, ResolveResultsRequestResult as it, RateLimiter as j, RateLimitConfig as k, defineCaptchaProvider as l, aggregateFormResponses as lt, resolveConsentLinks as m, ActionsConfig as mt, formBuilder as n, resolveUploads as nt, resolveSpamConfig as o, AggregateFieldResponsesArgs as ot, resolvePublishedVersionRef as p, ActionRegistry as pt, ConsentResolveArgs as q, defineValidationRule as r, ResolveResultsRequestArgs as rt, createKvRateLimiter as s, AggregateFormResponsesArgs as st, FormBuilderPluginOptions as t, buildUploadsCollection as tt, DEFAULT_PRESENTATION_NAME as u, fieldHasOptions as ut, aggregateRowsForFields as v, AnyActionDefinition as vt, ValidationRulesConfig as w, defaultActionDefinitions as x, SIGNATURE_HEADER as y, defineAction as yt, ConsentProof as z };
481
+ //# sourceMappingURL=index-DfFYGbVF.d.ts.map
@@ -0,0 +1,4 @@
1
+ import { a as FormFieldFormat, d as FileRefError, i as FormFieldDefinition, l as FileFieldConfig, n as AnyFormFieldDefinition, o as FormFieldValidate, s as FormFieldValueKind, u as FileRef } from "./fieldTypes-B8jkNRob.js";
2
+ import { A as FieldMeta, C as evaluateCalc, D as AggregationBucket, E as CalcExpression, O as AggregationRow, S as evaluateCondition, T as computeCalcFields, _ as PrefillOptions, a as optionLabelsFor, b as FieldTypeRegistry, c as PresentationDescriptor, f as ValidationRuleDefinition, i as buildRecallResolver, j as SubmissionStatusFilter, k as FieldAggregation, l as PresentationSurface, m as ValidationSeverity, n as DEFAULT_HONEYPOT_FIELD, o as interpolate, p as ValidationRuleResult, r as RecallResolver, s as PresentationDensity, t as CAPTCHA_TOKEN_KEY, u as AnyValidationRuleDefinition, v as valuesFromSearchParams, w as calcExpressionOf, x as FieldTypesConfig, y as FieldTypeOption } from "./constants-B-BUfetP.js";
3
+ import { $ as UploadsCollectionConfig, A as RateLimitResult, B as captureConsent, C as ValidationRuleRegistry, D as IdentifyFn, E as CaptchaVerifyArgs, F as PresentationDescriptorOption, G as AnyConsentSource, H as ConsentSourceRegistry, I as PresentationDescriptorRegistry, J as ConsentResolved, K as ConsentLink, L as PresentationsDescriptorConfig, M as SpamConfig, N as SpamMetadataConfig, O as RateLimitCheckArgs, P as SpamOption, Q as FORM_UPLOADS_SLUG, R as resolvePresentationDescriptors, S as ValidationRuleOption, T as CaptchaProvider, U as ConsentSourcesConfig, V as ConsentSourceOption, W as resolveConsentSources, X as defineConsentSource, Y as ConsentSource, Z as FieldCondition, _ as aggregateRowForField, _t as ActionRunArgs, a as resolveFileRef, at as resolveFormResultsRequest, b as signPayload, c as defaultIdentify, ct as aggregateFieldResponses, d as defaultPresentationDescriptors, dt as ActionResult, et as UploadsOption, f as defineFormField, ft as ActionOption, g as normalizeCalc, gt as ActionDefinition, h as defaultConsentSources, ht as resolveActions, i as captureFileRef, it as ResolveResultsRequestResult, j as RateLimiter, k as RateLimitConfig, l as defineCaptchaProvider, lt as aggregateFormResponses, m as resolveConsentLinks, mt as ActionsConfig, n as formBuilder, nt as resolveUploads, o as resolveSpamConfig, ot as AggregateFieldResponsesArgs, p as resolvePublishedVersionRef, pt as ActionRegistry, q as ConsentResolveArgs, r as defineValidationRule, rt as ResolveResultsRequestArgs, s as createKvRateLimiter, st as AggregateFormResponsesArgs, t as FormBuilderPluginOptions, tt as buildUploadsCollection, u as DEFAULT_PRESENTATION_NAME, ut as fieldHasOptions, v as aggregateRowsForFields, vt as AnyActionDefinition, w as ValidationRulesConfig, x as defaultActionDefinitions, y as SIGNATURE_HEADER, yt as defineAction, z as ConsentProof } from "./index-DfFYGbVF.js";
4
+ 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 };