@forms.expert/sdk 0.1.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,430 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ReactNode, CSSProperties } from 'react';
3
+
4
+ /**
5
+ * Form field types
6
+ */
7
+ type BasicFieldType = 'text' | 'email' | 'number' | 'textarea' | 'select' | 'checkbox' | 'file' | 'date' | 'hidden';
8
+ type InteractiveFieldType = 'radio' | 'multiselect' | 'rating' | 'scale' | 'toggle' | 'ranking' | 'imageChoice' | 'phone' | 'url' | 'password' | 'richText' | 'slider' | 'currency' | 'time' | 'datetime' | 'dateRange' | 'address' | 'name' | 'dropdown' | 'colorPicker' | 'location' | 'opinionScale' | 'consent';
9
+ type LayoutFieldType = 'heading' | 'divider' | 'paragraph';
10
+ type FormFieldType = BasicFieldType | InteractiveFieldType | LayoutFieldType;
11
+ interface FormFieldOption {
12
+ label: string;
13
+ value: string;
14
+ imageUrl?: string;
15
+ }
16
+ /**
17
+ * Form field definition
18
+ */
19
+ interface FormField {
20
+ name: string;
21
+ type: FormFieldType;
22
+ label?: string;
23
+ placeholder?: string;
24
+ required?: boolean;
25
+ options?: string[] | FormFieldOption[];
26
+ defaultValue?: unknown;
27
+ maxFileSize?: number;
28
+ allowedMimeTypes?: string[];
29
+ multiple?: boolean;
30
+ min?: number;
31
+ max?: number;
32
+ step?: number;
33
+ ratingMax?: number;
34
+ lowLabel?: string;
35
+ highLabel?: string;
36
+ defaultCountryCode?: string;
37
+ currencyCode?: string;
38
+ currencySymbol?: string;
39
+ addressFields?: ('street' | 'street2' | 'city' | 'state' | 'zip' | 'country')[];
40
+ nameFields?: ('prefix' | 'first' | 'middle' | 'last' | 'suffix')[];
41
+ content?: string;
42
+ consentText?: string;
43
+ consentUrl?: string;
44
+ maxLength?: number;
45
+ stepId?: string;
46
+ visibleWhen?: {
47
+ field: string;
48
+ operator: 'eq' | 'neq' | 'contains' | 'gt' | 'lt';
49
+ value: unknown;
50
+ };
51
+ }
52
+ /**
53
+ * Form styling configuration
54
+ */
55
+ interface FormStyling {
56
+ theme: 'light' | 'dark' | 'system';
57
+ primaryColor: string;
58
+ backgroundColor: string;
59
+ textColor: string;
60
+ borderRadius: 'none' | 'sm' | 'md' | 'lg';
61
+ fontSize: 'sm' | 'md' | 'lg';
62
+ buttonStyle: 'filled' | 'outline';
63
+ labelPosition: 'top' | 'left' | 'floating';
64
+ customCss?: string;
65
+ }
66
+ /**
67
+ * Form schema
68
+ */
69
+ interface FormSchema {
70
+ fields: FormField[];
71
+ styling?: FormStyling;
72
+ }
73
+ /**
74
+ * Form captcha settings
75
+ */
76
+ interface CaptchaSettings {
77
+ enabled: boolean;
78
+ provider?: 'turnstile' | 'recaptcha' | 'hcaptcha';
79
+ siteKey?: string;
80
+ }
81
+ /**
82
+ * Form branding configuration
83
+ */
84
+ interface FormBranding {
85
+ enabled: boolean;
86
+ text?: string;
87
+ url?: string;
88
+ }
89
+ /**
90
+ * Form status response from API
91
+ */
92
+ interface FormStatusResponse {
93
+ active: boolean;
94
+ formId?: string;
95
+ name?: string;
96
+ mode?: 'free' | 'schema';
97
+ schema?: FormSchema;
98
+ error?: string;
99
+ settings?: {
100
+ captcha: CaptchaSettings;
101
+ honeypot: boolean;
102
+ allowAttachments: boolean;
103
+ maxAttachments?: number;
104
+ maxAttachmentSize?: number;
105
+ successMessage?: string;
106
+ redirectUrl?: string;
107
+ };
108
+ /** Branding configuration */
109
+ branding?: FormBranding;
110
+ }
111
+ /**
112
+ * Validation error
113
+ */
114
+ interface ValidationError {
115
+ field: string;
116
+ message: string;
117
+ }
118
+ /**
119
+ * Validation response from API
120
+ */
121
+ interface ValidationResponse {
122
+ valid: boolean;
123
+ errors: ValidationError[];
124
+ }
125
+ /**
126
+ * Submission response from API
127
+ */
128
+ interface SubmissionResponse {
129
+ success: boolean;
130
+ submissionId: string;
131
+ message: string;
132
+ }
133
+ /**
134
+ * Submit options
135
+ */
136
+ interface SubmitOptions {
137
+ pageUrl?: string;
138
+ captchaToken?: string;
139
+ /** Callback for upload progress */
140
+ onProgress?: (progress: UploadProgress) => void;
141
+ }
142
+ /**
143
+ * Upload progress information
144
+ */
145
+ interface UploadProgress {
146
+ loaded: number;
147
+ total: number;
148
+ percentage: number;
149
+ }
150
+ /**
151
+ * File validation error
152
+ */
153
+ interface FileValidationError {
154
+ field: string;
155
+ file: string;
156
+ error: 'size' | 'type' | 'count';
157
+ message: string;
158
+ }
159
+ /**
160
+ * SDK configuration
161
+ */
162
+ interface FormsSDKConfig {
163
+ apiKey: string;
164
+ resourceId: string;
165
+ baseUrl?: string;
166
+ }
167
+ /**
168
+ * Form handler options
169
+ */
170
+ interface FormHandlerOptions {
171
+ /** Track form views for analytics (completion rate) */
172
+ trackViews?: boolean;
173
+ onSubmitStart?: () => void;
174
+ onSubmitSuccess?: (response: SubmissionResponse) => void;
175
+ onSubmitError?: (error: FormsError) => void;
176
+ onValidationError?: (errors: ValidationError[]) => void;
177
+ }
178
+ /**
179
+ * Forms SDK error
180
+ */
181
+ declare class FormsError extends Error {
182
+ code: string;
183
+ statusCode: number;
184
+ retryAfter?: number | undefined;
185
+ constructor(message: string, code: string, statusCode: number, retryAfter?: number | undefined);
186
+ }
187
+
188
+ /**
189
+ * API client for forms backend
190
+ */
191
+ declare class FormsApiClient {
192
+ private baseUrl;
193
+ private apiKey;
194
+ private resourceId;
195
+ constructor(config: FormsSDKConfig);
196
+ /**
197
+ * Build URL with token query parameter
198
+ */
199
+ private buildUrl;
200
+ /**
201
+ * Make an API request
202
+ */
203
+ private request;
204
+ /**
205
+ * Check if form is active and get configuration
206
+ */
207
+ isActive(slug: string): Promise<FormStatusResponse>;
208
+ /**
209
+ * Validate form data without submitting
210
+ */
211
+ validate(slug: string, data: Record<string, unknown>): Promise<ValidationResponse>;
212
+ /**
213
+ * Submit form data (supports files)
214
+ */
215
+ submit(slug: string, data: Record<string, unknown>, options?: SubmitOptions): Promise<SubmissionResponse>;
216
+ /**
217
+ * Submit with FormData (for file uploads with progress tracking)
218
+ */
219
+ private submitWithFormData;
220
+ /**
221
+ * Track a form view (for analytics completion rate)
222
+ */
223
+ trackView(slug: string): Promise<void>;
224
+ /**
225
+ * Get resource ID
226
+ */
227
+ getResourceId(): string;
228
+ /**
229
+ * Get base URL
230
+ */
231
+ getBaseUrl(): string;
232
+ }
233
+
234
+ /**
235
+ * Form handler for a specific form
236
+ */
237
+ declare class FormHandler {
238
+ private apiClient;
239
+ private slug;
240
+ private config;
241
+ private options;
242
+ constructor(apiClient: FormsApiClient, slug: string, options?: FormHandlerOptions);
243
+ /**
244
+ * Initialize form handler and fetch configuration
245
+ */
246
+ initialize(): Promise<FormStatusResponse>;
247
+ /**
248
+ * Get cached form configuration
249
+ */
250
+ getConfig(): FormStatusResponse | null;
251
+ /**
252
+ * Check if form is active
253
+ */
254
+ isActive(): boolean;
255
+ /**
256
+ * Check if captcha is required
257
+ */
258
+ requiresCaptcha(): boolean;
259
+ /**
260
+ * Get captcha provider
261
+ */
262
+ getCaptchaProvider(): 'turnstile' | 'recaptcha' | 'hcaptcha' | undefined;
263
+ /**
264
+ * Get form schema
265
+ */
266
+ getSchema(): FormSchema | undefined;
267
+ /**
268
+ * Validate form data
269
+ */
270
+ validate(data: Record<string, unknown>): Promise<ValidationResponse>;
271
+ /**
272
+ * Submit form data
273
+ */
274
+ submit(data: Record<string, unknown>, options?: SubmitOptions): Promise<SubmissionResponse>;
275
+ /**
276
+ * Get success message from config
277
+ */
278
+ getSuccessMessage(): string;
279
+ /**
280
+ * Get redirect URL from config
281
+ */
282
+ getRedirectUrl(): string | undefined;
283
+ }
284
+ /**
285
+ * Main Forms SDK class
286
+ */
287
+ declare class FormsSDK {
288
+ private apiClient;
289
+ constructor(config: FormsSDKConfig);
290
+ /**
291
+ * Check if form is active and get configuration
292
+ */
293
+ isActive(slug: string): Promise<FormStatusResponse>;
294
+ /**
295
+ * Validate form data without submitting
296
+ */
297
+ validate(slug: string, data: Record<string, unknown>): Promise<ValidationResponse>;
298
+ /**
299
+ * Submit form data
300
+ */
301
+ submit(slug: string, data: Record<string, unknown>, options?: SubmitOptions): Promise<SubmissionResponse>;
302
+ /**
303
+ * Create a form handler for a specific form
304
+ */
305
+ form(slug: string, options?: FormHandlerOptions): FormHandler;
306
+ /**
307
+ * Track a form view (for analytics completion rate)
308
+ */
309
+ trackView(slug: string): Promise<void>;
310
+ /**
311
+ * Submit with retry logic for rate limits
312
+ */
313
+ submitWithRetry(slug: string, data: Record<string, unknown>, options?: SubmitOptions & {
314
+ maxRetries?: number;
315
+ }): Promise<SubmissionResponse>;
316
+ }
317
+
318
+ interface FormsProviderProps {
319
+ config: FormsSDKConfig;
320
+ children: ReactNode;
321
+ }
322
+ /**
323
+ * Forms provider component
324
+ */
325
+ declare function FormsProvider({ config, children }: FormsProviderProps): react_jsx_runtime.JSX.Element;
326
+ /**
327
+ * Hook to access the Forms SDK
328
+ */
329
+ declare function useFormsSDK(): FormsSDK;
330
+ interface UseFormOptions {
331
+ /** Form slug */
332
+ slug: string;
333
+ /** SDK config (if not using provider) */
334
+ config?: FormsSDKConfig;
335
+ /** Track form views for analytics (completion rate). Default: false for SDK usage, pass true to enable. */
336
+ trackViews?: boolean;
337
+ /** Success callback */
338
+ onSuccess?: (response: SubmissionResponse) => void;
339
+ /** Error callback */
340
+ onError?: (error: Error) => void;
341
+ /** Validation error callback */
342
+ onValidationError?: (errors: ValidationError[]) => void;
343
+ /** Auto-initialize on mount */
344
+ autoInit?: boolean;
345
+ }
346
+ interface UseFormReturn {
347
+ /** Form configuration */
348
+ config: FormStatusResponse | null;
349
+ /** Form schema (shorthand for config.schema) */
350
+ schema: FormStatusResponse['schema'] | null;
351
+ /** Whether form is loading */
352
+ isLoading: boolean;
353
+ /** Whether form is initializing */
354
+ isInitializing: boolean;
355
+ /** Whether form was submitted successfully */
356
+ isSubmitted: boolean;
357
+ /** Alias for isSubmitted */
358
+ isSuccess: boolean;
359
+ /** Validation errors by field name */
360
+ errors: Record<string, string>;
361
+ /** File validation errors */
362
+ fileErrors: FileValidationError[];
363
+ /** Last submission error (if any) */
364
+ error: Error | null;
365
+ /** Form values */
366
+ values: Record<string, unknown>;
367
+ /** Upload progress (when uploading files) */
368
+ uploadProgress: UploadProgress | null;
369
+ /** Initialize the form */
370
+ initialize: () => Promise<FormStatusResponse>;
371
+ /** Set a field value */
372
+ setValue: (name: string, value: unknown) => void;
373
+ /** Set multiple values */
374
+ setValues: (values: Record<string, unknown>) => void;
375
+ /** Validate form data */
376
+ validate: () => Promise<boolean>;
377
+ /** Validate files against form settings */
378
+ validateFiles: (files: File[]) => FileValidationError[];
379
+ /** Submit the form */
380
+ submit: (captchaToken?: string) => Promise<SubmissionResponse | null>;
381
+ /** Reset form to initial state */
382
+ reset: () => void;
383
+ /** Clear errors */
384
+ clearErrors: () => void;
385
+ /** Whether captcha is required */
386
+ requiresCaptcha: boolean;
387
+ /** Captcha provider */
388
+ captchaProvider: 'turnstile' | 'recaptcha' | 'hcaptcha' | undefined;
389
+ /** Captcha site key */
390
+ captchaSiteKey: string | undefined;
391
+ /** Whether honeypot is enabled */
392
+ honeypotEnabled: boolean;
393
+ /** Whether attachments are allowed */
394
+ allowsAttachments: boolean;
395
+ /** Max attachments allowed */
396
+ maxAttachments: number;
397
+ /** Max attachment size in bytes */
398
+ maxAttachmentSize: number;
399
+ }
400
+ /**
401
+ * Hook for managing form state and submission
402
+ */
403
+ declare function useForm(options: UseFormOptions): UseFormReturn;
404
+
405
+ interface FormsExpertFormProps {
406
+ /** SDK configuration (optional if using FormsProvider) */
407
+ config?: FormsSDKConfig;
408
+ /** Form slug */
409
+ slug: string;
410
+ /** Track form views for analytics (completion rate). Default: false */
411
+ trackViews?: boolean;
412
+ /** Custom submit button text */
413
+ submitText?: string;
414
+ /** Success callback */
415
+ onSuccess?: (response: SubmissionResponse) => void;
416
+ /** Error callback */
417
+ onError?: (error: Error) => void;
418
+ /** Validation error callback */
419
+ onValidationError?: (errors: ValidationError[]) => void;
420
+ /** Custom class name */
421
+ className?: string;
422
+ /** Custom styles */
423
+ style?: CSSProperties;
424
+ }
425
+ /**
426
+ * Forms Expert form component
427
+ */
428
+ declare function FormsExpertForm({ config, slug, trackViews, submitText, onSuccess, onError, onValidationError, className, style, }: FormsExpertFormProps): react_jsx_runtime.JSX.Element;
429
+
430
+ export { FormsExpertForm, FormsProvider, type UseFormOptions, type UseFormReturn, useForm, useFormsSDK };