@nextlyhq/plugin-form-builder 0.0.2-alpha.67 → 0.0.2-alpha.69
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/README.md +5 -5
- package/dist/admin/index.d.ts +218 -250
- package/dist/admin/index.js +4662 -4785
- package/dist/admin/index.js.map +1 -1
- package/dist/field-references-BshlgMcn.js +1048 -0
- package/dist/field-references-BshlgMcn.js.map +1 -0
- package/dist/index.d.ts +304 -513
- package/dist/index.js +3753 -2916
- package/dist/index.js.map +1 -1
- package/dist/types-BHReIA0j.d.ts +986 -0
- package/package.json +22 -23
- package/dist/chunk-X5WLJLAR.js +0 -703
- package/dist/chunk-X5WLJLAR.js.map +0 -1
- package/dist/types-Bo4lk9BD.d.ts +0 -997
package/dist/index.d.ts
CHANGED
|
@@ -1,29 +1,15 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
export { B as BUILT_IN_FORM_FIELD_TYPES, k as BaseFormField, l as ConditionalLogicCondition, m as CustomFormField, n as EmailConfig, o as FieldBlockConfig, p as FormAccess, q as FormField, r as FormFieldType, s as FormFieldTypeId, t as FormHookContext, u as FormHooks, v as FormNotification, w as FormNotificationItem, x as FormSubmission, V as ValidationRules, y as isCheckboxFormField, z as isEmailFormField, G as isFileFormField, I as isFormField, J as isFormFieldType, K as isKnownFormField, L as isSelectFormField, M as isTextFormField } from './types-Bo4lk9BD.js';
|
|
6
|
-
import { z } from 'zod';
|
|
7
|
-
import 'react';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Form Builder Plugin
|
|
11
|
-
*
|
|
12
|
-
* Visual form builder with drag-and-drop UI, submission management,
|
|
13
|
-
* email notifications, and spam protection.
|
|
14
|
-
*
|
|
15
|
-
* @module plugin
|
|
16
|
-
* @since 0.1.0
|
|
17
|
-
*/
|
|
18
|
-
|
|
1
|
+
import { A as RadioFormField, B as isEmailFormField, C as FormNotificationItem, D as HiddenFormField, E as FormSubmission, F as TextareaFormField, G as isSelectFormField, H as isFormField, I as TimeFormField, K as isTextFormField, L as UrlFormField, M as SelectFormField, N as SubmissionDocument, O as NumberFormField, P as TextFormField, R as ValidationRules, S as FormNotification, T as FormSettings, U as isFormFieldType, V as isFileFormField, W as isKnownFormField, _ as FormField, a as ConditionalLogic, b as FormHookContext, c as DateFormField, d as FieldBlockConfig, f as FileFormField, g as FormDocument, h as FormConfig, i as CheckboxFormField, j as ResolvedFormBuilderConfig, k as PhoneFormField, l as EmailConfig, m as FormBuilderPluginOptions, n as BUILT_IN_FORM_FIELD_TYPES, o as ConditionalLogicCondition, p as FormAccess, r as BaseFormField, s as CustomFormField, t as AnyFormField, u as EmailFormField, v as FormFieldType, w as FormNotifications, x as FormHooks, y as FormFieldTypeId, z as isCheckboxFormField } from "./types-BHReIA0j.js";
|
|
2
|
+
import { PluginDefinition } from "@nextlyhq/plugin-sdk";
|
|
3
|
+
import { CollectionConfig, PluginContext } from "nextly";
|
|
4
|
+
import { z } from "zod";
|
|
19
5
|
type NextlyPlugin = PluginDefinition;
|
|
20
6
|
interface FormBuilderPluginResult {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
7
|
+
/** Plugin definition — pass to `defineConfig({ plugins: [...] })`. */
|
|
8
|
+
plugin: NextlyPlugin;
|
|
9
|
+
/** Forms & Submissions collections (also auto-added by the plugin). */
|
|
10
|
+
collections: CollectionConfig[];
|
|
11
|
+
/** Resolved configuration with all defaults applied. */
|
|
12
|
+
config: ResolvedFormBuilderConfig;
|
|
27
13
|
}
|
|
28
14
|
/**
|
|
29
15
|
* Create a Form Builder plugin instance.
|
|
@@ -52,36 +38,11 @@ interface FormBuilderPluginResult {
|
|
|
52
38
|
* });
|
|
53
39
|
* ```
|
|
54
40
|
*/
|
|
55
|
-
declare function formBuilder(options?: FormBuilderPluginOptions): FormBuilderPluginResult;
|
|
41
|
+
export declare function formBuilder(options?: FormBuilderPluginOptions): FormBuilderPluginResult;
|
|
56
42
|
/**
|
|
57
43
|
* Retrieve the resolved Form Builder config from a Nextly plugin context.
|
|
58
44
|
*/
|
|
59
|
-
declare function getFormBuilderConfig(nextly: unknown): ResolvedFormBuilderConfig | undefined;
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Form Configuration Validator
|
|
63
|
-
*
|
|
64
|
-
* Provides comprehensive validation for form configurations including:
|
|
65
|
-
* - Slug validation (format, reserved names)
|
|
66
|
-
* - Field name validation (format, duplicates)
|
|
67
|
-
* - Field-specific validation (select/radio options, min/max constraints)
|
|
68
|
-
* - Conditional logic validation
|
|
69
|
-
* - Nested field validation
|
|
70
|
-
*
|
|
71
|
-
* @module config/validate-form
|
|
72
|
-
* @since 1.0.0
|
|
73
|
-
*
|
|
74
|
-
* @example
|
|
75
|
-
* ```typescript
|
|
76
|
-
* import { validateFormConfig } from '@nextly/plugin-form-builder';
|
|
77
|
-
*
|
|
78
|
-
* const result = validateFormConfig(config);
|
|
79
|
-
* if (!result.valid) {
|
|
80
|
-
* console.error('Validation errors:', result.errors);
|
|
81
|
-
* }
|
|
82
|
-
* ```
|
|
83
|
-
*/
|
|
84
|
-
|
|
45
|
+
export declare function getFormBuilderConfig(nextly: unknown): ResolvedFormBuilderConfig | undefined;
|
|
85
46
|
/**
|
|
86
47
|
* Error codes for form validation failures.
|
|
87
48
|
* Used for programmatic error handling.
|
|
@@ -100,38 +61,38 @@ type FormValidationErrorCode = "SLUG_REQUIRED" | "SLUG_INVALID_TYPE" | "SLUG_TOO
|
|
|
100
61
|
* ```
|
|
101
62
|
*/
|
|
102
63
|
interface FormValidationError {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
64
|
+
/**
|
|
65
|
+
* Dot-notation path to the invalid property.
|
|
66
|
+
* @example 'slug', 'fields.0.name', 'fields.email.options'
|
|
67
|
+
*/
|
|
68
|
+
path: string;
|
|
69
|
+
/**
|
|
70
|
+
* Human-readable error message.
|
|
71
|
+
*/
|
|
72
|
+
message: string;
|
|
73
|
+
/**
|
|
74
|
+
* Machine-readable error code for programmatic handling.
|
|
75
|
+
*/
|
|
76
|
+
code: FormValidationErrorCode;
|
|
116
77
|
}
|
|
117
78
|
/**
|
|
118
79
|
* Result of form config validation.
|
|
119
80
|
*/
|
|
120
81
|
interface FormValidationResult {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
82
|
+
/**
|
|
83
|
+
* Whether the configuration is valid.
|
|
84
|
+
*/
|
|
85
|
+
valid: boolean;
|
|
86
|
+
/**
|
|
87
|
+
* Array of validation errors (empty if valid).
|
|
88
|
+
*/
|
|
89
|
+
errors: FormValidationError[];
|
|
129
90
|
}
|
|
130
91
|
/**
|
|
131
92
|
* Reserved form slugs that cannot be used.
|
|
132
93
|
* These are used by the system or have special meaning.
|
|
133
94
|
*/
|
|
134
|
-
declare const RESERVED_FORM_SLUGS: readonly ["api", "submit", "submissions", "export", "admin", "new", "create", "edit", "delete"];
|
|
95
|
+
export declare const RESERVED_FORM_SLUGS: readonly ["api", "submit", "submissions", "export", "admin", "new", "create", "edit", "delete"];
|
|
135
96
|
/**
|
|
136
97
|
* Validates a complete form configuration.
|
|
137
98
|
*
|
|
@@ -169,7 +130,7 @@ declare const RESERVED_FORM_SLUGS: readonly ["api", "submit", "submissions", "ex
|
|
|
169
130
|
* }
|
|
170
131
|
* ```
|
|
171
132
|
*/
|
|
172
|
-
declare function validateFormConfig(config: FormConfig): FormValidationResult;
|
|
133
|
+
export declare function validateFormConfig(config: FormConfig): FormValidationResult;
|
|
173
134
|
/**
|
|
174
135
|
* Throws an error if the form configuration is invalid.
|
|
175
136
|
*
|
|
@@ -187,42 +148,15 @@ declare function validateFormConfig(config: FormConfig): FormValidationResult;
|
|
|
187
148
|
* assertValidFormConfig(config);
|
|
188
149
|
* ```
|
|
189
150
|
*/
|
|
190
|
-
declare function assertValidFormConfig(config: FormConfig): void;
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* Form Configuration Defaults
|
|
194
|
-
*
|
|
195
|
-
* Applies default values to form configurations, ensuring all required
|
|
196
|
-
* properties have sensible defaults while preserving user-specified values.
|
|
197
|
-
*
|
|
198
|
-
* @module config/defaults
|
|
199
|
-
* @since 1.0.0
|
|
200
|
-
*
|
|
201
|
-
* @example
|
|
202
|
-
* ```typescript
|
|
203
|
-
* import { applyFormDefaults } from '@nextly/plugin-form-builder';
|
|
204
|
-
*
|
|
205
|
-
* const config = {
|
|
206
|
-
* slug: 'contact-form',
|
|
207
|
-
* fields: [
|
|
208
|
-
* { type: 'text', name: 'name', label: 'Name' },
|
|
209
|
-
* { type: 'email', name: 'email', label: 'Email' },
|
|
210
|
-
* ],
|
|
211
|
-
* };
|
|
212
|
-
*
|
|
213
|
-
* const configWithDefaults = applyFormDefaults(config);
|
|
214
|
-
* // configWithDefaults now has labels, settings, etc. with defaults applied
|
|
215
|
-
* ```
|
|
216
|
-
*/
|
|
217
|
-
|
|
151
|
+
export declare function assertValidFormConfig(config: FormConfig): void;
|
|
218
152
|
/**
|
|
219
153
|
* Default form settings.
|
|
220
154
|
*/
|
|
221
|
-
declare const DEFAULT_FORM_SETTINGS: Required<Pick<FormSettings, "submitButtonText" | "confirmationType" | "successMessage" | "allowMultipleSubmissions">>;
|
|
155
|
+
export declare const DEFAULT_FORM_SETTINGS: Required<Pick<FormSettings, "submitButtonText" | "confirmationType" | "successMessage" | "allowMultipleSubmissions">>;
|
|
222
156
|
/**
|
|
223
157
|
* Default notification settings.
|
|
224
158
|
*/
|
|
225
|
-
declare const DEFAULT_NOTIFICATION_SETTINGS: Pick<FormNotifications, "enabled" | "replyTo">;
|
|
159
|
+
export declare const DEFAULT_NOTIFICATION_SETTINGS: Pick<FormNotifications, "enabled" | "replyTo">;
|
|
226
160
|
/**
|
|
227
161
|
* Converts a slug to title case.
|
|
228
162
|
*
|
|
@@ -235,7 +169,7 @@ declare const DEFAULT_NOTIFICATION_SETTINGS: Pick<FormNotifications, "enabled" |
|
|
|
235
169
|
* toTitleCase('newsletter_signup'); // 'Newsletter Signup'
|
|
236
170
|
* ```
|
|
237
171
|
*/
|
|
238
|
-
declare function toTitleCase(str: string): string;
|
|
172
|
+
export declare function toTitleCase(str: string): string;
|
|
239
173
|
/**
|
|
240
174
|
* Generates a plural form from a singular label.
|
|
241
175
|
* Handles common English pluralization rules.
|
|
@@ -250,7 +184,7 @@ declare function toTitleCase(str: string): string;
|
|
|
250
184
|
* pluralize('Quiz'); // 'Quizzes'
|
|
251
185
|
* ```
|
|
252
186
|
*/
|
|
253
|
-
declare function pluralize(singular: string): string;
|
|
187
|
+
export declare function pluralize(singular: string): string;
|
|
254
188
|
/**
|
|
255
189
|
* Apply default values to form configuration.
|
|
256
190
|
*
|
|
@@ -293,7 +227,7 @@ declare function pluralize(singular: string): string;
|
|
|
293
227
|
* // }
|
|
294
228
|
* ```
|
|
295
229
|
*/
|
|
296
|
-
declare function applyFormDefaults(config: FormConfig): FormConfig;
|
|
230
|
+
export declare function applyFormDefaults(config: FormConfig): FormConfig;
|
|
297
231
|
/**
|
|
298
232
|
* Apply default values to individual form field.
|
|
299
233
|
*
|
|
@@ -312,11 +246,11 @@ declare function applyFormDefaults(config: FormConfig): FormConfig;
|
|
|
312
246
|
* // { type: 'text', name: 'firstName', label: 'First Name', required: false }
|
|
313
247
|
* ```
|
|
314
248
|
*/
|
|
315
|
-
declare function applyFieldDefaults<T extends {
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
249
|
+
export declare function applyFieldDefaults<T extends {
|
|
250
|
+
type: string;
|
|
251
|
+
name?: string;
|
|
252
|
+
label?: string;
|
|
253
|
+
required?: boolean;
|
|
320
254
|
}>(field: T): T;
|
|
321
255
|
/**
|
|
322
256
|
* Creates a complete form config with minimal input.
|
|
@@ -340,51 +274,13 @@ declare function applyFieldDefaults<T extends {
|
|
|
340
274
|
* ]);
|
|
341
275
|
* ```
|
|
342
276
|
*/
|
|
343
|
-
declare function createFormConfig(slug: string, fields: FormConfig["fields"], options?: Partial<Omit<FormConfig, "slug" | "fields">>): FormConfig;
|
|
344
|
-
|
|
345
|
-
/**
|
|
346
|
-
* Form Field Helpers
|
|
347
|
-
*
|
|
348
|
-
* Convenient factory functions for creating form field configurations.
|
|
349
|
-
* These helpers eliminate the need to manually specify the `type` property,
|
|
350
|
-
* providing a cleaner, more ergonomic API for form definitions.
|
|
351
|
-
*
|
|
352
|
-
* @module config/field-helpers
|
|
353
|
-
*
|
|
354
|
-
* @example
|
|
355
|
-
* ```typescript
|
|
356
|
-
* import {
|
|
357
|
-
* text,
|
|
358
|
-
* email,
|
|
359
|
-
* select,
|
|
360
|
-
* checkbox,
|
|
361
|
-
* option,
|
|
362
|
-
* } from '@nextly/plugin-form-builder';
|
|
363
|
-
*
|
|
364
|
-
* const contactFormFields = [
|
|
365
|
-
* text({ name: 'firstName', label: 'First Name', required: true }),
|
|
366
|
-
* text({ name: 'lastName', label: 'Last Name', required: true }),
|
|
367
|
-
* email({ name: 'email', label: 'Email Address', required: true }),
|
|
368
|
-
* select({
|
|
369
|
-
* name: 'subject',
|
|
370
|
-
* label: 'Subject',
|
|
371
|
-
* options: [
|
|
372
|
-
* option('General Inquiry'),
|
|
373
|
-
* option('Support Request'),
|
|
374
|
-
* option('Feedback'),
|
|
375
|
-
* ],
|
|
376
|
-
* }),
|
|
377
|
-
* checkbox({ name: 'subscribe', label: 'Subscribe to newsletter' }),
|
|
378
|
-
* ];
|
|
379
|
-
* ```
|
|
380
|
-
*/
|
|
381
|
-
|
|
277
|
+
export declare function createFormConfig(slug: string, fields: FormConfig["fields"], options?: Partial<Omit<FormConfig, "slug" | "fields">>): FormConfig;
|
|
382
278
|
/**
|
|
383
279
|
* Option for select and radio fields.
|
|
384
280
|
*/
|
|
385
281
|
interface FormFieldOption {
|
|
386
|
-
|
|
387
|
-
|
|
282
|
+
label: string;
|
|
283
|
+
value: string;
|
|
388
284
|
}
|
|
389
285
|
/**
|
|
390
286
|
* Creates an option for select or radio fields.
|
|
@@ -416,7 +312,7 @@ interface FormFieldOption {
|
|
|
416
312
|
* })
|
|
417
313
|
* ```
|
|
418
314
|
*/
|
|
419
|
-
declare const option: (label: string, value?: string) => FormFieldOption;
|
|
315
|
+
export declare const option: (label: string, value?: string) => FormFieldOption;
|
|
420
316
|
/**
|
|
421
317
|
* Creates a text input field configuration.
|
|
422
318
|
*
|
|
@@ -445,7 +341,7 @@ declare const option: (label: string, value?: string) => FormFieldOption;
|
|
|
445
341
|
* })
|
|
446
342
|
* ```
|
|
447
343
|
*/
|
|
448
|
-
declare const text: (config: Omit<TextFormField, "type">) => TextFormField;
|
|
344
|
+
export declare const text: (config: Omit<TextFormField, "type">) => TextFormField;
|
|
449
345
|
/**
|
|
450
346
|
* Creates an email input field configuration.
|
|
451
347
|
*
|
|
@@ -468,7 +364,7 @@ declare const text: (config: Omit<TextFormField, "type">) => TextFormField;
|
|
|
468
364
|
* })
|
|
469
365
|
* ```
|
|
470
366
|
*/
|
|
471
|
-
declare const email: (config: Omit<EmailFormField, "type">) => EmailFormField;
|
|
367
|
+
export declare const email: (config: Omit<EmailFormField, "type">) => EmailFormField;
|
|
472
368
|
/**
|
|
473
369
|
* Creates a phone input field configuration.
|
|
474
370
|
*
|
|
@@ -491,7 +387,7 @@ declare const email: (config: Omit<EmailFormField, "type">) => EmailFormField;
|
|
|
491
387
|
* })
|
|
492
388
|
* ```
|
|
493
389
|
*/
|
|
494
|
-
declare const phone: (config: Omit<PhoneFormField, "type">) => PhoneFormField;
|
|
390
|
+
export declare const phone: (config: Omit<PhoneFormField, "type">) => PhoneFormField;
|
|
495
391
|
/**
|
|
496
392
|
* Creates a URL input field configuration.
|
|
497
393
|
*
|
|
@@ -513,7 +409,7 @@ declare const phone: (config: Omit<PhoneFormField, "type">) => PhoneFormField;
|
|
|
513
409
|
* })
|
|
514
410
|
* ```
|
|
515
411
|
*/
|
|
516
|
-
declare const url: (config: Omit<UrlFormField, "type">) => UrlFormField;
|
|
412
|
+
export declare const url: (config: Omit<UrlFormField, "type">) => UrlFormField;
|
|
517
413
|
/**
|
|
518
414
|
* Creates a textarea field configuration.
|
|
519
415
|
*
|
|
@@ -540,7 +436,7 @@ declare const url: (config: Omit<UrlFormField, "type">) => UrlFormField;
|
|
|
540
436
|
* })
|
|
541
437
|
* ```
|
|
542
438
|
*/
|
|
543
|
-
declare const textarea: (config: Omit<TextareaFormField, "type">) => TextareaFormField;
|
|
439
|
+
export declare const textarea: (config: Omit<TextareaFormField, "type">) => TextareaFormField;
|
|
544
440
|
/**
|
|
545
441
|
* Creates a number input field configuration.
|
|
546
442
|
*
|
|
@@ -568,7 +464,7 @@ declare const textarea: (config: Omit<TextareaFormField, "type">) => TextareaFor
|
|
|
568
464
|
* })
|
|
569
465
|
* ```
|
|
570
466
|
*/
|
|
571
|
-
declare const number: (config: Omit<NumberFormField, "type">) => NumberFormField;
|
|
467
|
+
export declare const number: (config: Omit<NumberFormField, "type">) => NumberFormField;
|
|
572
468
|
/**
|
|
573
469
|
* Creates a select dropdown field configuration.
|
|
574
470
|
*
|
|
@@ -605,7 +501,7 @@ declare const number: (config: Omit<NumberFormField, "type">) => NumberFormField
|
|
|
605
501
|
* })
|
|
606
502
|
* ```
|
|
607
503
|
*/
|
|
608
|
-
declare const select: (config: Omit<SelectFormField, "type">) => SelectFormField;
|
|
504
|
+
export declare const select: (config: Omit<SelectFormField, "type">) => SelectFormField;
|
|
609
505
|
/**
|
|
610
506
|
* Creates a single checkbox field configuration.
|
|
611
507
|
*
|
|
@@ -631,7 +527,7 @@ declare const select: (config: Omit<SelectFormField, "type">) => SelectFormField
|
|
|
631
527
|
* })
|
|
632
528
|
* ```
|
|
633
529
|
*/
|
|
634
|
-
declare const checkbox: (config: Omit<CheckboxFormField, "type">) => CheckboxFormField;
|
|
530
|
+
export declare const checkbox: (config: Omit<CheckboxFormField, "type">) => CheckboxFormField;
|
|
635
531
|
/**
|
|
636
532
|
* Creates a radio group field configuration.
|
|
637
533
|
*
|
|
@@ -655,7 +551,7 @@ declare const checkbox: (config: Omit<CheckboxFormField, "type">) => CheckboxFor
|
|
|
655
551
|
* })
|
|
656
552
|
* ```
|
|
657
553
|
*/
|
|
658
|
-
declare const radio: (config: Omit<RadioFormField, "type">) => RadioFormField;
|
|
554
|
+
export declare const radio: (config: Omit<RadioFormField, "type">) => RadioFormField;
|
|
659
555
|
/**
|
|
660
556
|
* Creates a file upload field configuration.
|
|
661
557
|
*
|
|
@@ -686,7 +582,7 @@ declare const radio: (config: Omit<RadioFormField, "type">) => RadioFormField;
|
|
|
686
582
|
* })
|
|
687
583
|
* ```
|
|
688
584
|
*/
|
|
689
|
-
declare const file: (config: Omit<FileFormField, "type">) => FileFormField;
|
|
585
|
+
export declare const file: (config: Omit<FileFormField, "type">) => FileFormField;
|
|
690
586
|
/**
|
|
691
587
|
* Creates a date picker field configuration.
|
|
692
588
|
*
|
|
@@ -710,7 +606,7 @@ declare const file: (config: Omit<FileFormField, "type">) => FileFormField;
|
|
|
710
606
|
* })
|
|
711
607
|
* ```
|
|
712
608
|
*/
|
|
713
|
-
declare const date: (config: Omit<DateFormField, "type">) => DateFormField;
|
|
609
|
+
export declare const date: (config: Omit<DateFormField, "type">) => DateFormField;
|
|
714
610
|
/**
|
|
715
611
|
* Creates a time picker field configuration.
|
|
716
612
|
*
|
|
@@ -732,7 +628,7 @@ declare const date: (config: Omit<DateFormField, "type">) => DateFormField;
|
|
|
732
628
|
* })
|
|
733
629
|
* ```
|
|
734
630
|
*/
|
|
735
|
-
declare const time: (config: Omit<TimeFormField, "type">) => TimeFormField;
|
|
631
|
+
export declare const time: (config: Omit<TimeFormField, "type">) => TimeFormField;
|
|
736
632
|
/**
|
|
737
633
|
* Creates a hidden field configuration.
|
|
738
634
|
*
|
|
@@ -752,37 +648,7 @@ declare const time: (config: Omit<TimeFormField, "type">) => TimeFormField;
|
|
|
752
648
|
* hidden({ name: 'campaign', label: 'Campaign', defaultValue: 'summer-sale' })
|
|
753
649
|
* ```
|
|
754
650
|
*/
|
|
755
|
-
declare const hidden: (config: Omit<HiddenFormField, "type">) => HiddenFormField;
|
|
756
|
-
|
|
757
|
-
/**
|
|
758
|
-
* Conditional Logic Evaluator
|
|
759
|
-
*
|
|
760
|
-
* Evaluates conditional logic rules to determine field visibility in forms.
|
|
761
|
-
* Used by the FormRenderer component to show/hide fields based on user input.
|
|
762
|
-
*
|
|
763
|
-
* @module utils/evaluate-conditions
|
|
764
|
-
* @since 1.0.0
|
|
765
|
-
*
|
|
766
|
-
* @example
|
|
767
|
-
* ```typescript
|
|
768
|
-
* import { evaluateConditions } from '@nextly/plugin-form-builder';
|
|
769
|
-
*
|
|
770
|
-
* const conditionalLogic = {
|
|
771
|
-
* enabled: true,
|
|
772
|
-
* action: 'show',
|
|
773
|
-
* operator: 'AND',
|
|
774
|
-
* conditions: [
|
|
775
|
-
* { field: 'country', comparison: 'equals', value: 'US' },
|
|
776
|
-
* { field: 'age', comparison: 'greaterThan', value: 18 },
|
|
777
|
-
* ],
|
|
778
|
-
* };
|
|
779
|
-
*
|
|
780
|
-
* const formData = { country: 'US', age: 25 };
|
|
781
|
-
* const isVisible = evaluateConditions(conditionalLogic, formData);
|
|
782
|
-
* // isVisible = true (all conditions met, action is 'show')
|
|
783
|
-
* ```
|
|
784
|
-
*/
|
|
785
|
-
|
|
651
|
+
export declare const hidden: (config: Omit<HiddenFormField, "type">) => HiddenFormField;
|
|
786
652
|
/**
|
|
787
653
|
* Comparison operators supported by the conditional logic system.
|
|
788
654
|
*/
|
|
@@ -848,31 +714,20 @@ type ComparisonOperator = "equals" | "notEquals" | "contains" | "isEmpty" | "isN
|
|
|
848
714
|
* evaluateConditions(orLogic, { role: 'viewer' }); // false
|
|
849
715
|
* ```
|
|
850
716
|
*/
|
|
851
|
-
declare function evaluateConditions(logic: ConditionalLogic | undefined, formData: Record<string, unknown>): boolean;
|
|
717
|
+
export declare function evaluateConditions(logic: ConditionalLogic | undefined, formData: Record<string, unknown>): boolean;
|
|
852
718
|
/**
|
|
853
719
|
* Checks if a comparison operator is valid.
|
|
854
720
|
*
|
|
855
721
|
* @param operator - The operator to check
|
|
856
722
|
* @returns Whether the operator is valid
|
|
857
723
|
*/
|
|
858
|
-
declare function isValidComparisonOperator(operator: string): operator is ComparisonOperator;
|
|
724
|
+
export declare function isValidComparisonOperator(operator: string): operator is ComparisonOperator;
|
|
859
725
|
/**
|
|
860
726
|
* Gets the list of supported comparison operators.
|
|
861
727
|
*
|
|
862
728
|
* @returns Array of supported operator names
|
|
863
729
|
*/
|
|
864
|
-
declare function getSupportedComparisonOperators(): ComparisonOperator[];
|
|
865
|
-
|
|
866
|
-
/**
|
|
867
|
-
* Dynamic Zod Schema Generator
|
|
868
|
-
*
|
|
869
|
-
* Converts FormField[] configuration to Zod validation schemas.
|
|
870
|
-
* Supports all form field types with proper validation rules.
|
|
871
|
-
*
|
|
872
|
-
* @module utils/generate-schema
|
|
873
|
-
* @since 0.1.0
|
|
874
|
-
*/
|
|
875
|
-
|
|
730
|
+
export declare function getSupportedComparisonOperators(): ComparisonOperator[];
|
|
876
731
|
/**
|
|
877
732
|
* Generate a Zod validation schema from form field configuration.
|
|
878
733
|
*
|
|
@@ -894,7 +749,7 @@ declare function getSupportedComparisonOperators(): ComparisonOperator[];
|
|
|
894
749
|
* const result = schema.safeParse({ firstName: 'John', email: 'john@example.com', age: 25 });
|
|
895
750
|
* ```
|
|
896
751
|
*/
|
|
897
|
-
declare function generateZodSchema(fields: AnyFormField[]): z.ZodObject<Record<string, z.ZodTypeAny>>;
|
|
752
|
+
export declare function generateZodSchema(fields: AnyFormField[]): z.ZodObject<Record<string, z.ZodTypeAny>>;
|
|
898
753
|
/**
|
|
899
754
|
* Transform form data before validation.
|
|
900
755
|
*
|
|
@@ -908,7 +763,7 @@ declare function generateZodSchema(fields: AnyFormField[]): z.ZodObject<Record<s
|
|
|
908
763
|
* @param fields - Form field configurations
|
|
909
764
|
* @returns Transformed data ready for validation
|
|
910
765
|
*/
|
|
911
|
-
declare function transformFormData(data: Record<string, unknown>, fields: AnyFormField[]): Record<string, unknown>;
|
|
766
|
+
export declare function transformFormData(data: Record<string, unknown>, fields: AnyFormField[]): Record<string, unknown>;
|
|
912
767
|
/**
|
|
913
768
|
* Validate form data against a form's field configuration.
|
|
914
769
|
*
|
|
@@ -929,7 +784,7 @@ declare function transformFormData(data: Record<string, unknown>, fields: AnyFor
|
|
|
929
784
|
* }
|
|
930
785
|
* ```
|
|
931
786
|
*/
|
|
932
|
-
declare function validateFormData(data: Record<string, unknown>, fields: AnyFormField[]): z.ZodSafeParseResult<Record<string, unknown>>;
|
|
787
|
+
export declare function validateFormData(data: Record<string, unknown>, fields: AnyFormField[]): z.ZodSafeParseResult<Record<string, unknown>>;
|
|
933
788
|
/**
|
|
934
789
|
* Get validation errors as a flat object.
|
|
935
790
|
*
|
|
@@ -938,10 +793,10 @@ declare function validateFormData(data: Record<string, unknown>, fields: AnyForm
|
|
|
938
793
|
*/
|
|
939
794
|
/** A field that failed, with the machine code a wire error reports. */
|
|
940
795
|
interface ValidationIssue {
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
796
|
+
path: string;
|
|
797
|
+
/** `REQUIRED` for an answer that is missing or empty, else `INVALID`. */
|
|
798
|
+
code: "REQUIRED" | "INVALID";
|
|
799
|
+
message: string;
|
|
945
800
|
}
|
|
946
801
|
/**
|
|
947
802
|
* The same failures as a field-to-message map.
|
|
@@ -950,85 +805,73 @@ interface ValidationIssue {
|
|
|
950
805
|
* second time, so the two cannot disagree about which message belongs to a
|
|
951
806
|
* field or which failure won when one field had several.
|
|
952
807
|
*/
|
|
953
|
-
declare function getValidationErrors(result: z.ZodSafeParseResult<unknown>): Record<string, string>;
|
|
954
|
-
|
|
955
|
-
/**
|
|
956
|
-
* Export Formats Utilities
|
|
957
|
-
*
|
|
958
|
-
* Pure utility functions for exporting form submissions to CSV and JSON formats.
|
|
959
|
-
* These functions generate formatted strings that can be used for file downloads
|
|
960
|
-
* or API responses.
|
|
961
|
-
*
|
|
962
|
-
* @module utils/export-formats
|
|
963
|
-
* @since 0.1.0
|
|
964
|
-
*/
|
|
965
|
-
|
|
808
|
+
export declare function getValidationErrors(result: z.ZodSafeParseResult<unknown>): Record<string, string>;
|
|
966
809
|
/**
|
|
967
810
|
* Options for CSV export.
|
|
968
811
|
*/
|
|
969
812
|
interface CSVExportOptions {
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
813
|
+
/**
|
|
814
|
+
* Whether to include metadata columns (_id, _status, _submittedAt, etc.).
|
|
815
|
+
* @default true
|
|
816
|
+
*/
|
|
817
|
+
includeMetadata?: boolean;
|
|
818
|
+
/**
|
|
819
|
+
* Delimiter character for CSV.
|
|
820
|
+
* @default ","
|
|
821
|
+
*/
|
|
822
|
+
delimiter?: string;
|
|
823
|
+
/**
|
|
824
|
+
* Whether to include UTF-8 BOM for Excel compatibility.
|
|
825
|
+
* @default true
|
|
826
|
+
*/
|
|
827
|
+
includeBOM?: boolean;
|
|
828
|
+
/**
|
|
829
|
+
* Date format for timestamps.
|
|
830
|
+
* @default "iso" (ISO 8601)
|
|
831
|
+
*/
|
|
832
|
+
dateFormat?: "iso" | "locale";
|
|
990
833
|
}
|
|
991
834
|
/**
|
|
992
835
|
* Options for JSON export.
|
|
993
836
|
*/
|
|
994
837
|
interface JSONExportOptions {
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
838
|
+
/**
|
|
839
|
+
* Whether to include metadata in each submission.
|
|
840
|
+
* @default true
|
|
841
|
+
*/
|
|
842
|
+
includeMetadata?: boolean;
|
|
843
|
+
/**
|
|
844
|
+
* Whether to include form definition in the export.
|
|
845
|
+
* @default true
|
|
846
|
+
*/
|
|
847
|
+
includeFormDefinition?: boolean;
|
|
848
|
+
/**
|
|
849
|
+
* Number of spaces for indentation (0 for minified).
|
|
850
|
+
* @default 2
|
|
851
|
+
*/
|
|
852
|
+
indent?: number;
|
|
1010
853
|
}
|
|
1011
854
|
/**
|
|
1012
855
|
* Exported JSON structure.
|
|
1013
856
|
*/
|
|
1014
857
|
interface ExportedJSON {
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
858
|
+
/** Export metadata */
|
|
859
|
+
exportedAt: string;
|
|
860
|
+
/** Form information (if includeFormDefinition is true) */
|
|
861
|
+
form?: {
|
|
862
|
+
id: string;
|
|
863
|
+
name: string;
|
|
864
|
+
slug: string;
|
|
865
|
+
fields: Array<{
|
|
866
|
+
name: string;
|
|
867
|
+
label: string;
|
|
868
|
+
type: string;
|
|
869
|
+
}>;
|
|
870
|
+
};
|
|
871
|
+
/** Total number of submissions in export */
|
|
872
|
+
totalSubmissions: number;
|
|
873
|
+
/** Array of submission data */
|
|
874
|
+
submissions: Array<Record<string, unknown>>;
|
|
1032
875
|
}
|
|
1033
876
|
/**
|
|
1034
877
|
* Format a field value for export based on field type.
|
|
@@ -1044,7 +887,7 @@ interface ExportedJSON {
|
|
|
1044
887
|
* formatExportValue(new Date(), { type: 'date' }); // "2024-01-15"
|
|
1045
888
|
* ```
|
|
1046
889
|
*/
|
|
1047
|
-
declare function formatExportValue(value: unknown, field?: AnyFormField): string;
|
|
890
|
+
export declare function formatExportValue(value: unknown, field?: AnyFormField): string;
|
|
1048
891
|
/**
|
|
1049
892
|
* Export submissions to CSV format.
|
|
1050
893
|
*
|
|
@@ -1070,7 +913,7 @@ declare function formatExportValue(value: unknown, field?: AnyFormField): string
|
|
|
1070
913
|
* downloadFile(csv, 'submissions.csv', 'text/csv;charset=utf-8');
|
|
1071
914
|
* ```
|
|
1072
915
|
*/
|
|
1073
|
-
declare function exportToCSV(submissions: SubmissionDocument[], form: FormDocument, options?: CSVExportOptions): string;
|
|
916
|
+
export declare function exportToCSV(submissions: SubmissionDocument[], form: FormDocument, options?: CSVExportOptions): string;
|
|
1074
917
|
/**
|
|
1075
918
|
* Export submissions to JSON format.
|
|
1076
919
|
*
|
|
@@ -1097,7 +940,7 @@ declare function exportToCSV(submissions: SubmissionDocument[], form: FormDocume
|
|
|
1097
940
|
* downloadFile(json, 'submissions.json', 'application/json');
|
|
1098
941
|
* ```
|
|
1099
942
|
*/
|
|
1100
|
-
declare function exportToJSON(submissions: SubmissionDocument[], form: FormDocument, options?: JSONExportOptions): string;
|
|
943
|
+
export declare function exportToJSON(submissions: SubmissionDocument[], form: FormDocument, options?: JSONExportOptions): string;
|
|
1101
944
|
/**
|
|
1102
945
|
* Trigger a file download in the browser.
|
|
1103
946
|
*
|
|
@@ -1117,7 +960,7 @@ declare function exportToJSON(submissions: SubmissionDocument[], form: FormDocum
|
|
|
1117
960
|
* downloadFile(json, 'submissions.json', 'application/json');
|
|
1118
961
|
* ```
|
|
1119
962
|
*/
|
|
1120
|
-
declare function downloadFile(content: string, filename: string, mimeType: string): void;
|
|
963
|
+
export declare function downloadFile(content: string, filename: string, mimeType: string): void;
|
|
1121
964
|
/**
|
|
1122
965
|
* Generate a filename for export.
|
|
1123
966
|
*
|
|
@@ -1133,7 +976,7 @@ declare function downloadFile(content: string, filename: string, mimeType: strin
|
|
|
1133
976
|
* // Returns: "contact-form-submissions-2024-01-15.csv"
|
|
1134
977
|
* ```
|
|
1135
978
|
*/
|
|
1136
|
-
declare function generateExportFilename(formSlug: string, format: "csv" | "json"): string;
|
|
979
|
+
export declare function generateExportFilename(formSlug: string, format: "csv" | "json"): string;
|
|
1137
980
|
/**
|
|
1138
981
|
* Export submissions and trigger browser download.
|
|
1139
982
|
*
|
|
@@ -1153,72 +996,61 @@ declare function generateExportFilename(formSlug: string, format: "csv" | "json"
|
|
|
1153
996
|
* };
|
|
1154
997
|
* ```
|
|
1155
998
|
*/
|
|
1156
|
-
declare function exportAndDownload(submissions: SubmissionDocument[], form: FormDocument, format: "csv" | "json", options?: CSVExportOptions | JSONExportOptions): void;
|
|
1157
|
-
|
|
1158
|
-
/**
|
|
1159
|
-
* Form Submission Handler
|
|
1160
|
-
*
|
|
1161
|
-
* Processes form submissions including validation, spam detection,
|
|
1162
|
-
* storage, and notification triggering.
|
|
1163
|
-
*
|
|
1164
|
-
* @module handlers/submit-form
|
|
1165
|
-
* @since 0.1.0
|
|
1166
|
-
*/
|
|
1167
|
-
|
|
999
|
+
export declare function exportAndDownload(submissions: SubmissionDocument[], form: FormDocument, format: "csv" | "json", options?: CSVExportOptions | JSONExportOptions): void;
|
|
1168
1000
|
/**
|
|
1169
1001
|
* Options for submitting a form.
|
|
1170
1002
|
*/
|
|
1171
1003
|
interface SubmitFormOptions {
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1004
|
+
/** Form slug (URL-friendly identifier) */
|
|
1005
|
+
formSlug: string;
|
|
1006
|
+
/** Form submission data */
|
|
1007
|
+
data: Record<string, unknown>;
|
|
1008
|
+
/** Optional metadata about the submission */
|
|
1009
|
+
metadata?: {
|
|
1010
|
+
/** Submitter's IP address */
|
|
1011
|
+
ipAddress?: string;
|
|
1012
|
+
/** Submitter's user agent string */
|
|
1013
|
+
userAgent?: string;
|
|
1014
|
+
};
|
|
1015
|
+
/**
|
|
1016
|
+
* The HTTP request this submission arrived on.
|
|
1017
|
+
*
|
|
1018
|
+
* A route calling this helper is its own route, outside everything Nextly
|
|
1019
|
+
* pins a request around, so nothing else can supply it. Without it the write
|
|
1020
|
+
* reaches the submissions hooks looking like a seed or a job, and every rule
|
|
1021
|
+
* scoped to a visitor stands down: the rate limit above all.
|
|
1022
|
+
*
|
|
1023
|
+
* The request rather than an address, because the core resolves the client
|
|
1024
|
+
* from it under this deployment's proxy-trust settings. `metadata.ipAddress`
|
|
1025
|
+
* is a string the caller chose, which is the right shape for the audit column
|
|
1026
|
+
* it fills and the wrong shape for deciding who to throttle.
|
|
1027
|
+
*/
|
|
1028
|
+
request?: Request;
|
|
1029
|
+
/**
|
|
1030
|
+
* Whose permissions the reads and the write are judged against.
|
|
1031
|
+
*
|
|
1032
|
+
* Defaults to `system`, so every existing caller behaves as before.
|
|
1033
|
+
*/
|
|
1034
|
+
access?: SubmissionAccess;
|
|
1035
|
+
/**
|
|
1036
|
+
* The language the visitor submitted in.
|
|
1037
|
+
*
|
|
1038
|
+
* Decides which translation a picked redirect page is read in, and so which
|
|
1039
|
+
* URL the visitor is sent to: a page whose slug is `thanks` in English and
|
|
1040
|
+
* `merci` in French answered `/thanks` to everyone, because the target was
|
|
1041
|
+
* read with no locale and the default answered. The built-in route takes it
|
|
1042
|
+
* from `?locale=` on the submit URL, the same way core's own routes take a
|
|
1043
|
+
* locale on the wire; a host route passes whatever it resolved for the page
|
|
1044
|
+
* the form was on.
|
|
1045
|
+
*
|
|
1046
|
+
* A code that is not a configured locale reads as the default rather than
|
|
1047
|
+
* failing the submission, which the collection services decide. Absent means
|
|
1048
|
+
* the default, as it always has. The read wildcards (`all`, `*`) are not a
|
|
1049
|
+
* language a visitor can have submitted in and are treated as absent: a read
|
|
1050
|
+
* in "every language" answers a localized URL field with one value per
|
|
1051
|
+
* language, which no URL pattern can be filled from.
|
|
1052
|
+
*/
|
|
1053
|
+
locale?: string;
|
|
1222
1054
|
}
|
|
1223
1055
|
/**
|
|
1224
1056
|
* How this submission reaches the collections it touches.
|
|
@@ -1233,9 +1065,9 @@ interface SubmitFormOptions {
|
|
|
1233
1065
|
* silently overrode that configuration.
|
|
1234
1066
|
*/
|
|
1235
1067
|
type SubmissionAccess = {
|
|
1236
|
-
|
|
1068
|
+
as: "system";
|
|
1237
1069
|
} | {
|
|
1238
|
-
|
|
1070
|
+
as: "public";
|
|
1239
1071
|
};
|
|
1240
1072
|
/**
|
|
1241
1073
|
* Why a submission ended the way it did.
|
|
@@ -1255,60 +1087,60 @@ type SubmitFormOutcome = "accepted" | "no-such-form" | "closed" | "invalid" | "d
|
|
|
1255
1087
|
* Result of form submission.
|
|
1256
1088
|
*/
|
|
1257
1089
|
interface SubmitFormResult {
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1090
|
+
/** Whether the submission was successful */
|
|
1091
|
+
success: boolean;
|
|
1092
|
+
/**
|
|
1093
|
+
* Which ending this was, for a caller that has to map it to a status code.
|
|
1094
|
+
*
|
|
1095
|
+
* Required rather than optional, so a return path added later cannot omit it
|
|
1096
|
+
* and leave the HTTP route guessing from the message text.
|
|
1097
|
+
*/
|
|
1098
|
+
outcome: SubmitFormOutcome;
|
|
1099
|
+
/** The created submission document (on success) */
|
|
1100
|
+
submission?: SubmissionDocument;
|
|
1101
|
+
/** Error message (on failure) */
|
|
1102
|
+
error?: string;
|
|
1103
|
+
/** Field-level validation errors */
|
|
1104
|
+
validationErrors?: Record<string, string>;
|
|
1105
|
+
/**
|
|
1106
|
+
* The same failures with their machine codes, for a caller building an HTTP
|
|
1107
|
+
* error. `validationErrors` above cannot carry one, so a route reading only
|
|
1108
|
+
* that has to invent a code and reports every blank answer as `INVALID`.
|
|
1109
|
+
*/
|
|
1110
|
+
validationIssues?: ValidationIssue[];
|
|
1111
|
+
/** Redirect URL (if form configured for redirect on success) */
|
|
1112
|
+
redirect?: string;
|
|
1113
|
+
/**
|
|
1114
|
+
* The error that ended a `failed` submission, kept rather than flattened.
|
|
1115
|
+
*
|
|
1116
|
+
* A collection can refuse a write for reasons its host chose: a
|
|
1117
|
+
* `beforeValidate` hook throwing `NextlyError.validation`, a uniqueness
|
|
1118
|
+
* conflict. Those carry their own status and field detail, and reporting them
|
|
1119
|
+
* all as one internal error tells a visitor the server broke when in fact
|
|
1120
|
+
* their submission was answered deliberately.
|
|
1121
|
+
*/
|
|
1122
|
+
cause?: unknown;
|
|
1123
|
+
/**
|
|
1124
|
+
* The toast the form's author wrote for a successful submission.
|
|
1125
|
+
*
|
|
1126
|
+
* Carried on the result rather than read from the form again by whoever
|
|
1127
|
+
* presents it: the HTTP route would otherwise have to fetch the form a second
|
|
1128
|
+
* time purely to learn a string this function already had in hand, and a
|
|
1129
|
+
* second read is a second chance to disagree about which form was submitted.
|
|
1130
|
+
*
|
|
1131
|
+
* Present on every `accepted` ending, including the ones a bot caused, so the
|
|
1132
|
+
* message cannot be used to tell an accepted submission from a flagged one.
|
|
1133
|
+
*/
|
|
1134
|
+
successMessage?: string;
|
|
1303
1135
|
}
|
|
1304
1136
|
/**
|
|
1305
1137
|
* Context for the submission handler.
|
|
1306
1138
|
*/
|
|
1307
1139
|
interface SubmitFormContext {
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1140
|
+
/** Plugin context with access to services */
|
|
1141
|
+
pluginContext: PluginContext;
|
|
1142
|
+
/** Resolved plugin configuration */
|
|
1143
|
+
pluginConfig: ResolvedFormBuilderConfig;
|
|
1312
1144
|
}
|
|
1313
1145
|
/**
|
|
1314
1146
|
* Process a form submission.
|
|
@@ -1351,7 +1183,7 @@ interface SubmitFormContext {
|
|
|
1351
1183
|
* }
|
|
1352
1184
|
* ```
|
|
1353
1185
|
*/
|
|
1354
|
-
declare function submitForm(options: SubmitFormOptions, context: SubmitFormContext): Promise<SubmitFormResult>;
|
|
1186
|
+
export declare function submitForm(options: SubmitFormOptions, context: SubmitFormContext): Promise<SubmitFormResult>;
|
|
1355
1187
|
/**
|
|
1356
1188
|
* Validate form data without creating a submission.
|
|
1357
1189
|
*
|
|
@@ -1375,9 +1207,9 @@ declare function submitForm(options: SubmitFormOptions, context: SubmitFormConte
|
|
|
1375
1207
|
* }
|
|
1376
1208
|
* ```
|
|
1377
1209
|
*/
|
|
1378
|
-
declare function validateSubmission(formSlug: string, data: Record<string, unknown>, context: SubmitFormContext): Promise<{
|
|
1379
|
-
|
|
1380
|
-
|
|
1210
|
+
export declare function validateSubmission(formSlug: string, data: Record<string, unknown>, context: SubmitFormContext): Promise<{
|
|
1211
|
+
valid: boolean;
|
|
1212
|
+
errors?: Record<string, string>;
|
|
1381
1213
|
}>;
|
|
1382
1214
|
/**
|
|
1383
1215
|
* Check if a form is accepting submissions.
|
|
@@ -1386,7 +1218,7 @@ declare function validateSubmission(formSlug: string, data: Record<string, unkno
|
|
|
1386
1218
|
* @param context - Handler context
|
|
1387
1219
|
* @returns Whether the form accepts submissions
|
|
1388
1220
|
*/
|
|
1389
|
-
declare function isFormAcceptingSubmissions(formSlug: string, context: SubmitFormContext): Promise<boolean>;
|
|
1221
|
+
export declare function isFormAcceptingSubmissions(formSlug: string, context: SubmitFormContext): Promise<boolean>;
|
|
1390
1222
|
/**
|
|
1391
1223
|
* Get submission statistics for a form.
|
|
1392
1224
|
*
|
|
@@ -1398,80 +1230,62 @@ declare function isFormAcceptingSubmissions(formSlug: string, context: SubmitFor
|
|
|
1398
1230
|
* @param context - Handler context
|
|
1399
1231
|
* @returns Submission statistics
|
|
1400
1232
|
*/
|
|
1401
|
-
declare function getFormSubmissionStats(formSlug: string, context: SubmitFormContext): Promise<{
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1233
|
+
export declare function getFormSubmissionStats(formSlug: string, context: SubmitFormContext): Promise<{
|
|
1234
|
+
total: number;
|
|
1235
|
+
new: number;
|
|
1236
|
+
read: number;
|
|
1237
|
+
archived: number;
|
|
1406
1238
|
} | null>;
|
|
1407
|
-
|
|
1408
|
-
/**
|
|
1409
|
-
* Spam Detection
|
|
1410
|
-
*
|
|
1411
|
-
* Honeypot and rate limiting for form submissions.
|
|
1412
|
-
*
|
|
1413
|
-
* The honeypot is a pure read of the submitted payload. The rate limit is not:
|
|
1414
|
-
* it counts, and where the count lives decides whether the limit means
|
|
1415
|
-
* anything. It lives in the deployment's own {@link RateLimitStore}, the one
|
|
1416
|
-
* the REST and auth limiters already share, so `rateLimit.store` is configured
|
|
1417
|
-
* once and all three agree about what they are counting. A store private to
|
|
1418
|
-
* this module would count per process, and on a deployment that spans several
|
|
1419
|
-
* the effective limit becomes `configured x instances` -- a number the operator
|
|
1420
|
-
* never chose, that fails open, and only under load.
|
|
1421
|
-
*
|
|
1422
|
-
* @module handlers/spam-detection
|
|
1423
|
-
* @since 0.1.0
|
|
1424
|
-
*/
|
|
1425
1239
|
/**
|
|
1426
1240
|
* Configuration for spam detection.
|
|
1427
1241
|
*/
|
|
1428
1242
|
interface SpamCheckConfig {
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1243
|
+
/**
|
|
1244
|
+
* Enable honeypot field detection.
|
|
1245
|
+
* When enabled, submissions with filled honeypot fields are marked as spam.
|
|
1246
|
+
*/
|
|
1247
|
+
honeypot?: boolean;
|
|
1248
|
+
/**
|
|
1249
|
+
* Rate limiting configuration.
|
|
1250
|
+
*/
|
|
1251
|
+
rateLimit?: {
|
|
1252
|
+
/** Maximum submissions allowed per window */
|
|
1253
|
+
maxSubmissions: number;
|
|
1254
|
+
/** Time window in milliseconds */
|
|
1255
|
+
windowMs: number;
|
|
1256
|
+
};
|
|
1257
|
+
/**
|
|
1258
|
+
* reCAPTCHA configuration (for future implementation).
|
|
1259
|
+
*/
|
|
1260
|
+
recaptcha?: {
|
|
1261
|
+
enabled: boolean;
|
|
1262
|
+
secretKey?: string;
|
|
1263
|
+
scoreThreshold?: number;
|
|
1264
|
+
};
|
|
1451
1265
|
}
|
|
1452
1266
|
/**
|
|
1453
1267
|
* Options for spam check.
|
|
1454
1268
|
*/
|
|
1455
1269
|
interface SpamCheckOptions {
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1270
|
+
/** Form submission data */
|
|
1271
|
+
data: Record<string, unknown>;
|
|
1272
|
+
/** Submitter's IP address */
|
|
1273
|
+
ipAddress?: string;
|
|
1274
|
+
/** Form slug for rate limiting key */
|
|
1275
|
+
formSlug: string;
|
|
1276
|
+
/** Spam protection configuration */
|
|
1277
|
+
config: SpamCheckConfig;
|
|
1464
1278
|
}
|
|
1465
1279
|
/**
|
|
1466
1280
|
* Result of spam check.
|
|
1467
1281
|
*/
|
|
1468
1282
|
interface SpamCheckResult {
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1283
|
+
/** Whether the submission is detected as spam */
|
|
1284
|
+
isSpam: boolean;
|
|
1285
|
+
/** Reason for spam detection (for logging, not exposed to user) */
|
|
1286
|
+
reason?: "honeypot" | "rate_limit" | "recaptcha";
|
|
1287
|
+
/** Additional details (for logging) */
|
|
1288
|
+
details?: string;
|
|
1475
1289
|
}
|
|
1476
1290
|
/**
|
|
1477
1291
|
* Check a form submission for spam indicators.
|
|
@@ -1502,18 +1316,7 @@ interface SpamCheckResult {
|
|
|
1502
1316
|
* }
|
|
1503
1317
|
* ```
|
|
1504
1318
|
*/
|
|
1505
|
-
declare function checkSpam(options: SpamCheckOptions): Promise<SpamCheckResult>;
|
|
1506
|
-
|
|
1507
|
-
/**
|
|
1508
|
-
* Forms Collection
|
|
1509
|
-
*
|
|
1510
|
-
* Stores form definitions created via Code-First or Schema Builder.
|
|
1511
|
-
* Each form contains field definitions, settings, notifications, and access control.
|
|
1512
|
-
*
|
|
1513
|
-
* @module collections/forms
|
|
1514
|
-
* @since 0.1.0
|
|
1515
|
-
*/
|
|
1516
|
-
|
|
1319
|
+
export declare function checkSpam(options: SpamCheckOptions): Promise<SpamCheckResult>;
|
|
1517
1320
|
/**
|
|
1518
1321
|
* Component path string format.
|
|
1519
1322
|
* Format: `"package-name/path#ExportName"`
|
|
@@ -1523,54 +1326,43 @@ type ComponentPath = string;
|
|
|
1523
1326
|
* Custom view configuration for replacing default admin views.
|
|
1524
1327
|
*/
|
|
1525
1328
|
interface CollectionAdminViewConfig {
|
|
1526
|
-
|
|
1527
|
-
|
|
1329
|
+
/** Component path to the custom view component */
|
|
1330
|
+
Component: ComponentPath;
|
|
1528
1331
|
}
|
|
1529
1332
|
/**
|
|
1530
1333
|
* Custom components configuration for collection admin UI.
|
|
1531
1334
|
*/
|
|
1532
1335
|
interface CollectionAdminComponents {
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1336
|
+
views?: {
|
|
1337
|
+
Edit?: CollectionAdminViewConfig;
|
|
1338
|
+
List?: CollectionAdminViewConfig;
|
|
1339
|
+
};
|
|
1340
|
+
BeforeListTable?: ComponentPath;
|
|
1341
|
+
AfterListTable?: ComponentPath;
|
|
1342
|
+
BeforeEdit?: ComponentPath;
|
|
1343
|
+
AfterEdit?: ComponentPath;
|
|
1541
1344
|
}
|
|
1542
1345
|
/**
|
|
1543
1346
|
* Extended CollectionConfig with custom admin components support.
|
|
1544
1347
|
* This extends the base CollectionConfig to include the components property.
|
|
1545
1348
|
*/
|
|
1546
1349
|
interface ExtendedCollectionConfig$1 extends Omit<CollectionConfig, "admin"> {
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1350
|
+
admin?: CollectionConfig["admin"] & {
|
|
1351
|
+
/** Whether this collection is provided by a plugin */
|
|
1352
|
+
isPlugin?: boolean;
|
|
1353
|
+
components?: CollectionAdminComponents;
|
|
1354
|
+
};
|
|
1552
1355
|
}
|
|
1553
|
-
declare function formsCollection(pluginConfig: ResolvedFormBuilderConfig): ExtendedCollectionConfig$1;
|
|
1554
|
-
|
|
1555
|
-
/**
|
|
1556
|
-
* Form Submissions Collection
|
|
1557
|
-
*
|
|
1558
|
-
* Stores form submission data from user-submitted forms.
|
|
1559
|
-
* Each submission contains the submitted data, metadata, and status.
|
|
1560
|
-
*
|
|
1561
|
-
* @module collections/submissions
|
|
1562
|
-
* @since 0.1.0
|
|
1563
|
-
*/
|
|
1564
|
-
|
|
1356
|
+
export declare function formsCollection(pluginConfig: ResolvedFormBuilderConfig): ExtendedCollectionConfig$1;
|
|
1565
1357
|
/**
|
|
1566
1358
|
* Extended CollectionConfig with isPlugin support.
|
|
1567
1359
|
* This extends the base CollectionConfig to include the isPlugin property.
|
|
1568
1360
|
*/
|
|
1569
1361
|
interface ExtendedCollectionConfig extends Omit<CollectionConfig, "admin"> {
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1362
|
+
admin?: CollectionConfig["admin"] & {
|
|
1363
|
+
/** Whether this collection is provided by a plugin */
|
|
1364
|
+
isPlugin?: boolean;
|
|
1365
|
+
};
|
|
1574
1366
|
}
|
|
1575
1367
|
/**
|
|
1576
1368
|
* Generate the Form Submissions collection configuration.
|
|
@@ -1591,8 +1383,7 @@ interface ExtendedCollectionConfig extends Omit<CollectionConfig, "admin"> {
|
|
|
1591
1383
|
* // Returns a collection with slug "form-submissions" (or custom slug from config)
|
|
1592
1384
|
* ```
|
|
1593
1385
|
*/
|
|
1594
|
-
declare function submissionsCollection(pluginConfig: ResolvedFormBuilderConfig): ExtendedCollectionConfig;
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
export { AnyFormField, type CSVExportOptions, CheckboxFormField, type ComparisonOperator, ConditionalLogic, DEFAULT_FORM_SETTINGS, DEFAULT_NOTIFICATION_SETTINGS, DateFormField, EmailFormField, type ExportedJSON, FileFormField, FormBuilderPluginOptions, type FormBuilderPluginResult, FormConfig, FormDocument, type FormFieldOption, FormNotifications, FormSettings, type FormValidationError, type FormValidationErrorCode, type FormValidationResult, HiddenFormField, type JSONExportOptions, type NextlyPlugin, NumberFormField, PhoneFormField, RESERVED_FORM_SLUGS, RadioFormField, ResolvedFormBuilderConfig, SelectFormField, type SpamCheckConfig, type SpamCheckOptions, type SpamCheckResult, SubmissionDocument, type SubmitFormContext, type SubmitFormOptions, type SubmitFormResult, TextFormField, TextareaFormField, TimeFormField, UrlFormField, applyFieldDefaults, applyFormDefaults, assertValidFormConfig, checkSpam, checkbox, createFormConfig, date, downloadFile, email, evaluateConditions, exportAndDownload, exportToCSV, exportToJSON, file, formBuilder, formBuilderPlugin, formatExportValue, formsCollection, generateExportFilename, generateZodSchema, getFormBuilderConfig, getFormSubmissionStats, getSupportedComparisonOperators, getValidationErrors, hidden, isFormAcceptingSubmissions, isValidComparisonOperator, number, option, phone, pluralize, radio, select, submissionsCollection, submitForm, text, textarea, time, toTitleCase, transformFormData, url, validateFormConfig, validateFormData, validateSubmission };
|
|
1386
|
+
export declare function submissionsCollection(pluginConfig: ResolvedFormBuilderConfig): ExtendedCollectionConfig;
|
|
1387
|
+
export declare const formBuilderPlugin: ReturnType<typeof formBuilder>["plugin"];
|
|
1388
|
+
export { type AnyFormField, BUILT_IN_FORM_FIELD_TYPES, type BaseFormField, type CSVExportOptions, type CheckboxFormField, type ComparisonOperator, type ConditionalLogic, type ConditionalLogicCondition, type CustomFormField, type DateFormField, type EmailConfig, type EmailFormField, type ExportedJSON, type FieldBlockConfig, type FileFormField, type FormAccess, type FormBuilderPluginOptions, type FormBuilderPluginResult, type FormConfig, type FormDocument, type FormField, type FormFieldOption, type FormFieldType, type FormFieldTypeId, type FormHookContext, type FormHooks, type FormNotification, type FormNotificationItem, type FormNotifications, type FormSettings, type FormSubmission, type FormValidationError, type FormValidationErrorCode, type FormValidationResult, type HiddenFormField, type JSONExportOptions, type NextlyPlugin, type NumberFormField, type PhoneFormField, type RadioFormField, type ResolvedFormBuilderConfig, type SelectFormField, type SpamCheckConfig, type SpamCheckOptions, type SpamCheckResult, type SubmissionDocument, type SubmitFormContext, type SubmitFormOptions, type SubmitFormResult, type TextFormField, type TextareaFormField, type TimeFormField, type UrlFormField, type ValidationRules, isCheckboxFormField, isEmailFormField, isFileFormField, isFormField, isFormFieldType, isKnownFormField, isSelectFormField, isTextFormField };
|
|
1389
|
+
//# sourceMappingURL=index.d.ts.map
|