@usefillo/core 0.6.2 → 0.8.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.
- package/README.md +4 -4
- package/dist/index.d.ts +433 -39
- package/dist/index.js +896 -126
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -67,6 +67,8 @@ interface RatingField extends BaseField {
|
|
|
67
67
|
kind: "rating";
|
|
68
68
|
/** Number of steps, default 5. */
|
|
69
69
|
max?: number;
|
|
70
|
+
/** Optional analysis meaning. CSAT requires a 1–5 rating. */
|
|
71
|
+
insightsMetric?: "csat";
|
|
70
72
|
}
|
|
71
73
|
interface DateField extends BaseField {
|
|
72
74
|
kind: "date";
|
|
@@ -79,6 +81,8 @@ interface LinearScaleField extends BaseField {
|
|
|
79
81
|
max?: number;
|
|
80
82
|
minLabel?: string;
|
|
81
83
|
maxLabel?: string;
|
|
84
|
+
/** Optional analysis meaning. NPS requires 0–10; CSAT requires 1–5. */
|
|
85
|
+
insightsMetric?: "csat" | "nps";
|
|
82
86
|
}
|
|
83
87
|
interface RankingField extends BaseField {
|
|
84
88
|
kind: "ranking";
|
|
@@ -148,6 +152,39 @@ interface FormPage {
|
|
|
148
152
|
title?: string;
|
|
149
153
|
blocks: Block[];
|
|
150
154
|
}
|
|
155
|
+
/**
|
|
156
|
+
* Limit repeat responses. Absent = no limit (submit as often as you like).
|
|
157
|
+
*/
|
|
158
|
+
interface ResponseLimit {
|
|
159
|
+
/**
|
|
160
|
+
* Who counts as the same responder:
|
|
161
|
+
* - "browser": same device, anonymous — the SDK remembers this browser
|
|
162
|
+
* answered and sends a de-duplication key (ratings, polls, "was this
|
|
163
|
+
* helpful").
|
|
164
|
+
* - "field": the person self-identifies by answering `field` (an email or
|
|
165
|
+
* phone field). A self-claim — unverified, soft dedup — so the hosted link
|
|
166
|
+
* and anonymous embeds can still dedupe.
|
|
167
|
+
* - "identify": the identify() respondent (HMAC-verifiable). The strong
|
|
168
|
+
* path; only embedded surfaces that call identify() are recognized.
|
|
169
|
+
*/
|
|
170
|
+
by: "browser" | "field" | "identify";
|
|
171
|
+
/** The email/phone field whose answer identifies the person. `by: "field"` only. */
|
|
172
|
+
field?: string;
|
|
173
|
+
/**
|
|
174
|
+
* Optionally sub-scope the limit by a field's answer (usually a hidden
|
|
175
|
+
* article/product/order id): "one response per responder PER that value" —
|
|
176
|
+
* e.g. one 👍 per visitor per article from a single shared form.
|
|
177
|
+
*/
|
|
178
|
+
scopeField?: string;
|
|
179
|
+
/**
|
|
180
|
+
* A repeat from the same responder: "keep" answers with the standing
|
|
181
|
+
* response (the first answer stands); "update" edits it in place (re-anchored
|
|
182
|
+
* to the current schema, `response.updated` webhook, previous answers
|
|
183
|
+
* prefilled for a verified respondent). "update" applies to `by: "identify"`
|
|
184
|
+
* only — a self-claim/browser must not overwrite another person's response.
|
|
185
|
+
*/
|
|
186
|
+
onRepeat: "keep" | "update";
|
|
187
|
+
}
|
|
151
188
|
interface FormSettings {
|
|
152
189
|
/**
|
|
153
190
|
* Default "button": respondents submit with the footer button. "auto" hides
|
|
@@ -160,17 +197,49 @@ interface FormSettings {
|
|
|
160
197
|
successMessage?: string;
|
|
161
198
|
redirectUrl?: string;
|
|
162
199
|
showProgress?: boolean;
|
|
163
|
-
/**
|
|
164
|
-
*
|
|
165
|
-
|
|
166
|
-
* remember this browser has already answered and send a server-side
|
|
167
|
-
* de-duplication key with the response.
|
|
168
|
-
*/
|
|
169
|
-
submissionLimit?: "multiple" | "once_per_visitor";
|
|
200
|
+
/** Limit repeat responses (who counts as the same responder, and what a
|
|
201
|
+
* repeat does). Absent = no limit. See {@link ResponseLimit}. */
|
|
202
|
+
responseLimit?: ResponseLimit;
|
|
170
203
|
/** Notify this address on every submission. */
|
|
171
204
|
notifyEmail?: string;
|
|
172
205
|
/** Send respondents a receipt (to the first answered email field). */
|
|
173
206
|
sendReceipt?: boolean;
|
|
207
|
+
/**
|
|
208
|
+
* Save respondents' in-progress answers to Fillo (default off). The SDK
|
|
209
|
+
* autosaves as they type and restores on return, so long forms survive
|
|
210
|
+
* reloads and tab closes. Off by default because it stores answers before
|
|
211
|
+
* the respondent chooses to submit — the form owner opts in.
|
|
212
|
+
*/
|
|
213
|
+
saveProgress?: boolean;
|
|
214
|
+
/**
|
|
215
|
+
* Let workspace members read the answers a respondent has typed but not yet
|
|
216
|
+
* submitted (default off; requires saveProgress). This exposes pre-submission
|
|
217
|
+
* content to the owner's team, so it's a separate opt-in with its own consent
|
|
218
|
+
* framing — disclose it in your privacy policy. Respondents still see the
|
|
219
|
+
* "progress saved" notice. The content is visible only in the authenticated
|
|
220
|
+
* dashboard; the draft token stays the only public read capability.
|
|
221
|
+
*/
|
|
222
|
+
draftAnswersVisible?: boolean;
|
|
223
|
+
/**
|
|
224
|
+
* Email a respondent one "pick up where you left off" link when they leave a
|
|
225
|
+
* form idle (default off; requires saveProgress). Sent at most once per
|
|
226
|
+
* draft, to an address they entered or their verified account email — never
|
|
227
|
+
* with any answer content. Owner opt-in.
|
|
228
|
+
*/
|
|
229
|
+
resumeEmails?: boolean;
|
|
230
|
+
/**
|
|
231
|
+
* Where a resume link should land for an embedded form (http(s) only). The
|
|
232
|
+
* draft reference travels in the URL fragment, which the SDK adopts on load;
|
|
233
|
+
* defaults to the hosted /f page when unset.
|
|
234
|
+
*/
|
|
235
|
+
resumeUrl?: string;
|
|
236
|
+
/**
|
|
237
|
+
* Email the form's notification address a daily digest of who dropped off —
|
|
238
|
+
* abandoned and open draft counts, where people stalled, and verified
|
|
239
|
+
* respondents by name (default off; requires notifyEmail). Never any answer
|
|
240
|
+
* content or resume links.
|
|
241
|
+
*/
|
|
242
|
+
draftDigest?: boolean;
|
|
174
243
|
}
|
|
175
244
|
interface FormSchema {
|
|
176
245
|
version: 1;
|
|
@@ -226,6 +295,10 @@ type UploadStatus = "pending" | "uploading" | "complete" | "aborted";
|
|
|
226
295
|
* - "gdrive": direct to a Google Drive resumable session URL (Content-Range
|
|
227
296
|
* protocol).
|
|
228
297
|
* - "s3-put": a single PUT to a presigned S3/R2 URL — straight to the bucket.
|
|
298
|
+
* Retained for sessions created by older Fillo servers.
|
|
299
|
+
* - "s3-multipart": resumable S3/R2 multipart upload. The client asks Fillo
|
|
300
|
+
* for one short-lived UploadPart URL at a time; only the server can assemble
|
|
301
|
+
* the parts into an object.
|
|
229
302
|
* - "box": direct to Box with a folder-scoped upload token — small files via a
|
|
230
303
|
* single multipart POST, large files via Box's chunked session (the client
|
|
231
304
|
* computes the SHA-1 digests Box requires). The server commits/verifies in the
|
|
@@ -237,6 +310,8 @@ type UploadTransport = {
|
|
|
237
310
|
} | {
|
|
238
311
|
type: "s3-put";
|
|
239
312
|
uploadUrl: string;
|
|
313
|
+
} | {
|
|
314
|
+
type: "s3-multipart";
|
|
240
315
|
} | {
|
|
241
316
|
type: "box";
|
|
242
317
|
mode: "simple";
|
|
@@ -279,8 +354,30 @@ interface UploadSession {
|
|
|
279
354
|
/** All conditions must hold (AND). No conditions = visible. */
|
|
280
355
|
declare function isBlockVisible(block: Block, data: ResponseData): boolean;
|
|
281
356
|
declare function visibleBlocks(page: FormPage, data: ResponseData): Block[];
|
|
357
|
+
/**
|
|
358
|
+
* Blocks to render on `page`, resolved against the WHOLE-FORM visibility
|
|
359
|
+
* fixpoint rather than just this page's own fields. A field whose `visibleIf`
|
|
360
|
+
* references an answer on another page must appear/validate here exactly when
|
|
361
|
+
* the server would keep that answer — and the server (validateResponse →
|
|
362
|
+
* visibleFields) uses the whole-form fixpoint, hiding any controlling field
|
|
363
|
+
* that is itself logic-hidden. Scoping per page instead reads a stale answer
|
|
364
|
+
* behind a hidden cross-page trigger as still-answered, so the client would
|
|
365
|
+
* render (and validate) a field whose answer the server then silently drops.
|
|
366
|
+
* Use this for anything that must agree with validateResponse; the per-page
|
|
367
|
+
* `visibleBlocks` remains for callers holding only a single page.
|
|
368
|
+
*/
|
|
369
|
+
declare function visiblePageBlocks(form: FormSchema, page: FormPage, data: ResponseData): Block[];
|
|
282
370
|
/** Every field in the form (across pages), in order. */
|
|
283
371
|
declare function allFields(form: FormSchema): Field[];
|
|
372
|
+
/**
|
|
373
|
+
* The scope key for a response limit: the string form of the answer to
|
|
374
|
+
* `settings.responseLimit.scopeField`, or null when there is no scope field or the
|
|
375
|
+
* answer is not a usable scalar. A non-scalar answer (checkbox boolean,
|
|
376
|
+
* multi_select/ranking array, matrix object) means "no scope" — the limit
|
|
377
|
+
* spans the whole form rather than silently mis-bucketing. Shared by the SDK's
|
|
378
|
+
* per-visitor key and the server's per-person dedup so both scope identically.
|
|
379
|
+
*/
|
|
380
|
+
declare function responseScopeValue(settings: FormSettings, data: ResponseData): string | null;
|
|
284
381
|
/** Fields currently visible given the response data — the set that gets validated. */
|
|
285
382
|
declare function visibleFields(form: FormSchema, data: ResponseData): Field[];
|
|
286
383
|
|
|
@@ -302,6 +399,17 @@ declare function validateResponse(form: FormSchema, data: ResponseData): Validat
|
|
|
302
399
|
declare const FILLO_SCHEMA_VERSION: 1;
|
|
303
400
|
/** Injected from package.json at build time (tsup define) — never hand-edited. */
|
|
304
401
|
declare const FILLO_SDK_VERSION: string;
|
|
402
|
+
/**
|
|
403
|
+
* The oldest published @usefillo/* SDK that can still render a form the current
|
|
404
|
+
* server serves. This is a DELIBERATE floor — bump it BY HAND only when a
|
|
405
|
+
* genuinely wire-breaking change ships (a new required request/response field an
|
|
406
|
+
* old SDK can't produce or read). It must never be tied to FILLO_SDK_VERSION:
|
|
407
|
+
* the server used to serve its own build version as the min, so every release
|
|
408
|
+
* 426'd every customer still on an older pinned SDK. Field-kind/schema-shape
|
|
409
|
+
* breaks are gated separately by FILLO_SCHEMA_VERSION, so this floor stays low.
|
|
410
|
+
*/
|
|
411
|
+
declare const FILLO_MIN_SDK_VERSION = "0.4.0";
|
|
412
|
+
declare function normalizeSettings(value: unknown): FormSettings;
|
|
305
413
|
interface SchemaValidationResult {
|
|
306
414
|
ok: boolean;
|
|
307
415
|
/** Present when ok — a normalized, structurally-valid schema. */
|
|
@@ -382,6 +490,18 @@ declare function parsePhone(value: string, fallback?: PhoneCountry): ParsedPhone
|
|
|
382
490
|
* validation. `country` (when known) tightens the accepted lengths.
|
|
383
491
|
*/
|
|
384
492
|
declare function isPossiblePhone(value: string): boolean;
|
|
493
|
+
/** Whether the country-picker popover opens below or above its trigger. */
|
|
494
|
+
type PhonePopoverPlacement = "below" | "above";
|
|
495
|
+
/** Minimum gap kept between the popover and the viewport edge, in px. */
|
|
496
|
+
declare const PHONE_POPOVER_VIEWPORT_GAP = 8;
|
|
497
|
+
/**
|
|
498
|
+
* Decide whether the country-picker popover should open below or above its
|
|
499
|
+
* anchor and size it to fit the viewport, writing the result to CSS custom
|
|
500
|
+
* properties on the popover. Pure DOM math with no framework assumptions, so
|
|
501
|
+
* the React and vanilla renderers share one implementation instead of drifting
|
|
502
|
+
* copies. Returns "below" when there is nothing to position (SSR / detached).
|
|
503
|
+
*/
|
|
504
|
+
declare function positionPhonePopover(anchor: HTMLElement | null, popover: HTMLElement | null): PhonePopoverPlacement;
|
|
385
505
|
|
|
386
506
|
/** Display metadata for every block kind — drives the builder palette. */
|
|
387
507
|
declare const BLOCK_KIND_META: Record<BlockKind, {
|
|
@@ -416,6 +536,7 @@ interface FieldSpec {
|
|
|
416
536
|
max?: number;
|
|
417
537
|
minLabel?: string;
|
|
418
538
|
maxLabel?: string;
|
|
539
|
+
insightsMetric?: "csat" | "nps";
|
|
419
540
|
rows?: string[];
|
|
420
541
|
columns?: string[];
|
|
421
542
|
placeholder?: string;
|
|
@@ -478,6 +599,8 @@ type SubmitResult = {
|
|
|
478
599
|
responseId: string;
|
|
479
600
|
/** True when the API accepted the request as an already-recorded visitor response. */
|
|
480
601
|
duplicate?: boolean;
|
|
602
|
+
/** True when an update-in-place limit (responseLimit onRepeat "update") updated the person's living response. */
|
|
603
|
+
updated?: boolean;
|
|
481
604
|
errors?: undefined;
|
|
482
605
|
} | {
|
|
483
606
|
ok: false;
|
|
@@ -496,9 +619,74 @@ interface SubmitMeta {
|
|
|
496
619
|
surface?: "default" | "headless";
|
|
497
620
|
/**
|
|
498
621
|
* Browser-scoped de-duplication key sent when a form opts into
|
|
499
|
-
* settings.
|
|
622
|
+
* settings.responseLimit.by = "browser".
|
|
500
623
|
*/
|
|
501
624
|
submissionKey?: string;
|
|
625
|
+
/**
|
|
626
|
+
* Saved-progress draft this submission completes (forms with
|
|
627
|
+
* settings.saveProgress). The server deletes the draft with the response
|
|
628
|
+
* commit so it can't be resumed after submitting.
|
|
629
|
+
*/
|
|
630
|
+
draft?: {
|
|
631
|
+
id: string;
|
|
632
|
+
token: string;
|
|
633
|
+
};
|
|
634
|
+
/**
|
|
635
|
+
* Host-app account context for this respondent (identify()). Recorded with
|
|
636
|
+
* the response and shown in the dashboard/webhooks as a CLAIM from the
|
|
637
|
+
* embedding page — it is metadata, not authentication. `id` is your own
|
|
638
|
+
* stable user/account id.
|
|
639
|
+
*/
|
|
640
|
+
respondent?: FilloRespondent;
|
|
641
|
+
}
|
|
642
|
+
/**
|
|
643
|
+
* The host app's account context for the person filling the form. Passed as
|
|
644
|
+
* the `respondent` option on FilloForm / FilloProvider / renderForm /
|
|
645
|
+
* createFormController; Fillo keys responses to it so the dashboard,
|
|
646
|
+
* webhooks, and integrations can say WHO answered.
|
|
647
|
+
*/
|
|
648
|
+
interface FilloRespondent {
|
|
649
|
+
/** Your stable user/account id — the identity key within your workspace. */
|
|
650
|
+
id: string;
|
|
651
|
+
email?: string;
|
|
652
|
+
name?: string;
|
|
653
|
+
/** Small primitive facts (plan, role, region…) — not a data warehouse. */
|
|
654
|
+
traits?: Record<string, string | number | boolean>;
|
|
655
|
+
/**
|
|
656
|
+
* Identity verification (optional): hex HMAC-SHA256 of `id`, computed on
|
|
657
|
+
* YOUR server with the workspace identity secret from Fillo settings. Once
|
|
658
|
+
* the workspace holds a secret, Fillo records identity only with a valid
|
|
659
|
+
* hash — never compute this in the browser or the secret leaks.
|
|
660
|
+
*/
|
|
661
|
+
hash?: string;
|
|
662
|
+
}
|
|
663
|
+
/** Wire shape of a saved-progress draft (settings.saveProgress forms). */
|
|
664
|
+
interface ResponseDraft {
|
|
665
|
+
id: string;
|
|
666
|
+
formId: string;
|
|
667
|
+
/** Partial answers exactly as last saved — validated only at submit. */
|
|
668
|
+
data: ResponseData;
|
|
669
|
+
/** 0-based page the respondent was on when the draft was last saved. */
|
|
670
|
+
page: number;
|
|
671
|
+
/** A freshly rotated bearer, returned only when adopting a resume link — the
|
|
672
|
+
* URL token is spent, so this is what future saves must use. */
|
|
673
|
+
token?: string;
|
|
674
|
+
}
|
|
675
|
+
interface CreatedDraft {
|
|
676
|
+
id: string;
|
|
677
|
+
/**
|
|
678
|
+
* Per-draft bearer, returned once at creation; sent back as
|
|
679
|
+
* X-Fillo-Draft-Token on every read/save/delete of this draft.
|
|
680
|
+
*/
|
|
681
|
+
token: string;
|
|
682
|
+
/** ISO timestamp; the server slides it forward on every save. */
|
|
683
|
+
expiresAt?: string;
|
|
684
|
+
/**
|
|
685
|
+
* True when a VERIFIED identity picked up its existing draft from another
|
|
686
|
+
* device — the token was rotated to this caller, and the draft's answers
|
|
687
|
+
* were left untouched (fetch them with getDraft to restore).
|
|
688
|
+
*/
|
|
689
|
+
existing?: boolean;
|
|
502
690
|
}
|
|
503
691
|
interface UploadProgress {
|
|
504
692
|
uploadedBytes: number;
|
|
@@ -514,14 +702,23 @@ interface UploadFileOptions {
|
|
|
514
702
|
sessionId?: string;
|
|
515
703
|
/** Ownership token for the resumed session (from the original create call). */
|
|
516
704
|
uploadToken?: string;
|
|
705
|
+
/** Persist this handle if the host wants reload-safe resumability. */
|
|
706
|
+
onSession?: (handle: {
|
|
707
|
+
sessionId: string;
|
|
708
|
+
uploadToken?: string;
|
|
709
|
+
}) => void;
|
|
517
710
|
}
|
|
518
711
|
declare class FilloError extends Error {
|
|
519
712
|
status?: number | undefined;
|
|
520
713
|
/** Server-suggested wait (from a 429's Retry-After header), seconds. */
|
|
521
714
|
retryAfterSec?: number | undefined;
|
|
715
|
+
/** Stable machine-readable API error code, when the server provides one. */
|
|
716
|
+
code?: string | undefined;
|
|
522
717
|
constructor(message: string, status?: number | undefined,
|
|
523
718
|
/** Server-suggested wait (from a 429's Retry-After header), seconds. */
|
|
524
|
-
retryAfterSec?: number | undefined
|
|
719
|
+
retryAfterSec?: number | undefined,
|
|
720
|
+
/** Stable machine-readable API error code, when the server provides one. */
|
|
721
|
+
code?: string | undefined);
|
|
525
722
|
}
|
|
526
723
|
/** Duck-typed — `instanceof` breaks when two SDK copies end up in one bundle. */
|
|
527
724
|
declare function isFilloError(err: unknown): err is FilloError;
|
|
@@ -533,6 +730,17 @@ interface SyncFormResult {
|
|
|
533
730
|
status?: "draft" | "published";
|
|
534
731
|
/** Changes were staged as a draft for a human to publish. */
|
|
535
732
|
staged?: boolean;
|
|
733
|
+
/**
|
|
734
|
+
* Server-authoritative live snapshot. Present when the incoming code schema
|
|
735
|
+
* is not the version respondents may submit against yet.
|
|
736
|
+
*/
|
|
737
|
+
resolvedSchema?: FormSchema;
|
|
738
|
+
resolvedTheme?: FormTheme | null;
|
|
739
|
+
/** Non-fatal integration problem; the resolved live snapshot remains usable. */
|
|
740
|
+
syncError?: {
|
|
741
|
+
code: string;
|
|
742
|
+
message: string;
|
|
743
|
+
};
|
|
536
744
|
warning?: string;
|
|
537
745
|
}
|
|
538
746
|
declare class FilloClient {
|
|
@@ -547,12 +755,30 @@ declare class FilloClient {
|
|
|
547
755
|
/** Fetch a published form definition by id or slug. */
|
|
548
756
|
getForm(idOrSlug: string): Promise<PublishedForm>;
|
|
549
757
|
/**
|
|
550
|
-
*
|
|
551
|
-
* publishable key.
|
|
758
|
+
* Resolve a code-defined form through the workspace identified by the
|
|
759
|
+
* client's publishable key. Depending on workspace policy, changed content
|
|
760
|
+
* may be staged for review or resolved to the authoritative live snapshot.
|
|
761
|
+
* Returns the canonical form id used for submissions.
|
|
552
762
|
*/
|
|
553
763
|
syncForm(handle: string, schema: FormSchema, theme?: FormTheme | null): Promise<SyncFormResult>;
|
|
554
764
|
/** Submit a response. Returns per-field errors instead of throwing on validation failure. */
|
|
555
765
|
submit(formId: string, data: ResponseData, meta?: SubmitMeta): Promise<SubmitResult>;
|
|
766
|
+
/**
|
|
767
|
+
* The identified person's own living response on an upsert-mode form —
|
|
768
|
+
* used to prefill their answers for editing. Requires a VERIFIED identity
|
|
769
|
+
* ({id, hash}); anything else 404s (returned as null), because an
|
|
770
|
+
* unverified read would hand anyone's answers to any page script.
|
|
771
|
+
*
|
|
772
|
+
* `scopeValue` scopes the lookup for forms whose response limit is keyed to
|
|
773
|
+
* a field (responseLimit.scopeField) — e.g. one response per article. When
|
|
774
|
+
* the form is scoped, the server returns 404 unless the matching scope value
|
|
775
|
+
* is sent, so a page loaded for article B never prefills article A's answers.
|
|
776
|
+
* Optional and back-compatible: omit it for unscoped forms.
|
|
777
|
+
*/
|
|
778
|
+
fetchOwnResponse(formId: string, respondent: FilloRespondent, scopeValue?: string): Promise<{
|
|
779
|
+
responseId: string;
|
|
780
|
+
data: ResponseData;
|
|
781
|
+
} | null>;
|
|
556
782
|
/**
|
|
557
783
|
* Open a respondent session for funnel analysis. Fire-and-forget: returns the
|
|
558
784
|
* session id, or null if tracking is unavailable (never blocks the form).
|
|
@@ -563,14 +789,40 @@ declare class FilloClient {
|
|
|
563
789
|
furthestPage?: number;
|
|
564
790
|
completed?: boolean;
|
|
565
791
|
}): void;
|
|
792
|
+
/**
|
|
793
|
+
* Create a saved-progress draft (forms with settings.saveProgress). Returns
|
|
794
|
+
* the draft id and its ownership token — the token is shown only once.
|
|
795
|
+
*/
|
|
796
|
+
createDraft(formId: string, body: {
|
|
797
|
+
data: ResponseData;
|
|
798
|
+
page?: number;
|
|
799
|
+
respondent?: FilloRespondent;
|
|
800
|
+
}): Promise<CreatedDraft>;
|
|
801
|
+
/** Fetch a draft to restore. 404s once expired, consumed, or deleted. When
|
|
802
|
+
* `adopt` is set (resume-link adoption), the server rotates the bearer and
|
|
803
|
+
* returns the new `token` — the URL token becomes single-use. */
|
|
804
|
+
getDraft(draftId: string, token: string, adopt?: boolean): Promise<ResponseDraft>;
|
|
805
|
+
/**
|
|
806
|
+
* Overwrite a draft's answers/page and slide its expiry. `keepalive` lets a
|
|
807
|
+
* tab-close flush outlive the page; browsers reject keepalive bodies over
|
|
808
|
+
* ~64KB, in which case this save is simply lost — the debounced autosaves
|
|
809
|
+
* every few keystrokes are the real persistence, the flush is a bonus.
|
|
810
|
+
*/
|
|
811
|
+
saveDraft(draftId: string, token: string, body: {
|
|
812
|
+
data: ResponseData;
|
|
813
|
+
page?: number;
|
|
814
|
+
}, opts?: {
|
|
815
|
+
keepalive?: boolean;
|
|
816
|
+
}): Promise<void>;
|
|
817
|
+
/** Discard a draft (the "Start over" path). */
|
|
818
|
+
deleteDraft(draftId: string, token: string): Promise<void>;
|
|
566
819
|
/** Current state of an upload session — used to resume after interruption. */
|
|
567
|
-
getUploadSession(sessionId: string, token?: string): Promise<UploadSession>;
|
|
820
|
+
getUploadSession(sessionId: string, token?: string, signal?: AbortSignal): Promise<UploadSession>;
|
|
568
821
|
/**
|
|
569
|
-
*
|
|
570
|
-
*
|
|
571
|
-
*
|
|
572
|
-
*
|
|
573
|
-
* is sent twice or skipped.
|
|
822
|
+
* Provider-aware browser-direct upload. Creates a session, uses the storage
|
|
823
|
+
* transport selected by the server, reports progress, and finalizes into a
|
|
824
|
+
* FileValue. Resumable providers can continue an existing session; one-shot
|
|
825
|
+
* transports are retried according to their own safe semantics.
|
|
574
826
|
*
|
|
575
827
|
* Depending on the form's storage settings the server picks a transport:
|
|
576
828
|
* direct-to-Google-Drive resumable
|
|
@@ -589,7 +841,7 @@ declare class FilloClient {
|
|
|
589
841
|
/**
|
|
590
842
|
* Caller signal (if any) combined with a fresh per-request timeout. Created per
|
|
591
843
|
* fetch so each retry attempt gets its own deadline; the caller's own abort
|
|
592
|
-
* still drives
|
|
844
|
+
* still drives upload cancellation across every provider transport.
|
|
593
845
|
*/
|
|
594
846
|
private uploadSignal;
|
|
595
847
|
/** Retry a request with exponential backoff; never retries an aborted upload. */
|
|
@@ -601,6 +853,13 @@ declare class FilloClient {
|
|
|
601
853
|
* queries Drive for the authoritative offset).
|
|
602
854
|
*/
|
|
603
855
|
private driveUploadLoop;
|
|
856
|
+
/**
|
|
857
|
+
* S3-compatible multipart protocol. Fillo owns the provider upload id and is
|
|
858
|
+
* the only party allowed to complete it; the browser receives only narrowly
|
|
859
|
+
* scoped UploadPart URLs. That keeps uploads resumable and means an old or
|
|
860
|
+
* slow browser request cannot materialize an object after server-side abort.
|
|
861
|
+
*/
|
|
862
|
+
private s3MultipartUploadLoop;
|
|
604
863
|
/**
|
|
605
864
|
* S3-compatible single PUT to a presigned URL — bytes go straight to the
|
|
606
865
|
* bucket. Not resumable (S3 single PUT is atomic), but retried on failure.
|
|
@@ -612,13 +871,13 @@ interface ProvisionWorkspaceResult {
|
|
|
612
871
|
/** Publishable key (pk_…) for the new workspace. Pass to createClient({ key }). */
|
|
613
872
|
key: string;
|
|
614
873
|
organizationId: string;
|
|
615
|
-
/**
|
|
874
|
+
/** The private workspace link is emailed directly; `url` stays null. */
|
|
616
875
|
claim: {
|
|
617
876
|
url: string | null;
|
|
618
877
|
email: string | null;
|
|
619
878
|
sent: boolean;
|
|
620
879
|
};
|
|
621
|
-
/** Caps applied until the workspace is
|
|
880
|
+
/** Caps applied until the workspace is saved to an account. */
|
|
622
881
|
limits: {
|
|
623
882
|
responses: number;
|
|
624
883
|
expiresAt: string;
|
|
@@ -626,9 +885,9 @@ interface ProvisionWorkspaceResult {
|
|
|
626
885
|
}
|
|
627
886
|
/**
|
|
628
887
|
* Provision a Fillo workspace from an email — no signup — and get a publishable
|
|
629
|
-
* key back, so a form can collect real responses immediately. A
|
|
630
|
-
* emailed to `email`; until someone
|
|
631
|
-
* preview (limited responses, for a limited time). Built for setup automation,
|
|
888
|
+
* key back, so a form can collect real responses immediately. A private
|
|
889
|
+
* workspace link is emailed to `email`; until someone saves it to an account,
|
|
890
|
+
* the workspace runs as a capped preview (limited responses, for a limited time). Built for setup automation,
|
|
632
891
|
* e.g. a coding agent wiring Fillo into an app during integration.
|
|
633
892
|
*
|
|
634
893
|
* const { key } = await provisionWorkspace({ email: "you@co.com" });
|
|
@@ -674,12 +933,19 @@ interface FormControllerOptions {
|
|
|
674
933
|
*/
|
|
675
934
|
surface?: "default" | "headless";
|
|
676
935
|
/**
|
|
677
|
-
* Resolve the submission target
|
|
678
|
-
*
|
|
679
|
-
* held (never dropped) while it
|
|
680
|
-
* respondent can retry.
|
|
936
|
+
* Resolve/verify the submission target immediately before submit. Code-form
|
|
937
|
+
* renderers use this to recover a missing target and to detect a live schema
|
|
938
|
+
* change after a cached mount. Answers are held (never dropped) while it
|
|
939
|
+
* runs; failure sets `submitError` and the respondent can retry.
|
|
681
940
|
*/
|
|
682
941
|
resolveFormId?: () => Promise<string>;
|
|
942
|
+
/**
|
|
943
|
+
* Host-app account context (identify()): who is filling this form, by your
|
|
944
|
+
* own user id. Sent with the submission and recorded as an unverified
|
|
945
|
+
* claim — it changes what the dashboard/webhooks can tell you, never what
|
|
946
|
+
* the respondent can do.
|
|
947
|
+
*/
|
|
948
|
+
respondent?: FilloRespondent;
|
|
683
949
|
}
|
|
684
950
|
interface FormControllerState {
|
|
685
951
|
data: ResponseData;
|
|
@@ -697,6 +963,48 @@ interface FormControllerState {
|
|
|
697
963
|
uploading: boolean;
|
|
698
964
|
/** Human-readable message for the last failed submit; cleared on edit/retry. */
|
|
699
965
|
submitError?: string;
|
|
966
|
+
/**
|
|
967
|
+
* True when `status` is "submitted" because the once-per-visitor gate
|
|
968
|
+
* restored a previous visit's response, not because a submit happened in
|
|
969
|
+
* this controller instance. Renderers use it to skip one-time "just
|
|
970
|
+
* submitted" reactions (moving focus to the success screen, redirecting) —
|
|
971
|
+
* otherwise every remount of an already-answered form replays them.
|
|
972
|
+
*/
|
|
973
|
+
restoredSubmission: boolean;
|
|
974
|
+
/**
|
|
975
|
+
* True when a saved-progress draft (settings.saveProgress) was restored
|
|
976
|
+
* into this fill — answers and/or page position came from a previous
|
|
977
|
+
* visit. Renderers use it to show a "continuing where you left off"
|
|
978
|
+
* notice with a Start over action (resetDraft).
|
|
979
|
+
*/
|
|
980
|
+
resumedDraft: boolean;
|
|
981
|
+
/**
|
|
982
|
+
* True when an update-in-place limit prefilled the VERIFIED respondent's own
|
|
983
|
+
* previous answers — submitting updates that response in place. Renderers
|
|
984
|
+
* show an "updating your earlier response" notice.
|
|
985
|
+
*/
|
|
986
|
+
editingPrevious: boolean;
|
|
987
|
+
/**
|
|
988
|
+
* True when the last submit was accepted as an already-recorded response
|
|
989
|
+
* rather than a new one (the server returns this only for a VERIFIED
|
|
990
|
+
* identify() repeat on a keep-mode form). Renderers show an "already
|
|
991
|
+
* answered" message on the success screen instead of implying a fresh
|
|
992
|
+
* submission — otherwise a repeat visitor's new answers look saved when the
|
|
993
|
+
* server kept the original.
|
|
994
|
+
*/
|
|
995
|
+
duplicateSubmission: boolean;
|
|
996
|
+
/**
|
|
997
|
+
* True when the last submit UPDATED the person's existing response in place
|
|
998
|
+
* (responseLimit onRepeat "update"), rather than creating a new one.
|
|
999
|
+
*/
|
|
1000
|
+
updatedSubmission: boolean;
|
|
1001
|
+
/**
|
|
1002
|
+
* True when a resume link (#fillo-draft=…) could not be adopted because it
|
|
1003
|
+
* was expired, already used, or not this browser's — so no progress was
|
|
1004
|
+
* restored. Renderers surface a "that link expired — start again" notice
|
|
1005
|
+
* instead of showing a silently blank form.
|
|
1006
|
+
*/
|
|
1007
|
+
resumeLinkFailed: boolean;
|
|
700
1008
|
}
|
|
701
1009
|
interface FormController {
|
|
702
1010
|
/** Stable snapshot — same reference until something changes (safe for useSyncExternalStore). */
|
|
@@ -721,7 +1029,21 @@ interface FormController {
|
|
|
721
1029
|
form?: FormSchema;
|
|
722
1030
|
formId?: string;
|
|
723
1031
|
client?: FilloClient;
|
|
1032
|
+
/** Late-bind identify() context — host sessions often resolve after mount. */
|
|
1033
|
+
respondent?: FilloRespondent;
|
|
724
1034
|
}): void;
|
|
1035
|
+
/**
|
|
1036
|
+
* Persist any unsaved draft progress right now (settings.saveProgress
|
|
1037
|
+
* forms). Renderers call this on pagehide/visibility-hidden so the last
|
|
1038
|
+
* keystrokes survive a tab close; a no-op when there's nothing to save.
|
|
1039
|
+
*/
|
|
1040
|
+
flushDraft(): void;
|
|
1041
|
+
/**
|
|
1042
|
+
* Discard the saved draft and reset to a fresh fill: answers back to
|
|
1043
|
+
* initialData + URL prefill, first page, errors cleared. The "Start over"
|
|
1044
|
+
* action next to the resume notice.
|
|
1045
|
+
*/
|
|
1046
|
+
resetDraft(): void;
|
|
725
1047
|
/** Drop all listeners. */
|
|
726
1048
|
destroy(): void;
|
|
727
1049
|
}
|
|
@@ -753,7 +1075,7 @@ declare function shouldAutoSubmit(field: Field, value: FieldValue, ctx: AutoSubm
|
|
|
753
1075
|
* (Tailwind `data-[invalid]:…`) can react to it. Slot names and attribute
|
|
754
1076
|
* names are public API — renames are breaking; additions are minors.
|
|
755
1077
|
*/
|
|
756
|
-
declare const FILLO_SLOTS: readonly ["root", "header", "title", "description", "pageTitle", "progress", "progressFill", "blocks", "field", "label", "fieldDescription", "control", "options", "option", "optionLabel", "error", "footer", "button", "success"];
|
|
1078
|
+
declare const FILLO_SLOTS: readonly ["root", "header", "title", "description", "pageTitle", "progress", "progressFill", "blocks", "field", "label", "fieldDescription", "control", "options", "option", "optionLabel", "error", "footer", "button", "success", "resume"];
|
|
757
1079
|
type FilloSlot = (typeof FILLO_SLOTS)[number];
|
|
758
1080
|
/** data-* names emitted alongside the stable fillo-* classes. */
|
|
759
1081
|
declare const FILLO_DATA_ATTRS: {
|
|
@@ -840,10 +1162,23 @@ declare const FILLO_THEME_VARS: readonly [{
|
|
|
840
1162
|
}];
|
|
841
1163
|
|
|
842
1164
|
/**
|
|
843
|
-
*
|
|
844
|
-
*
|
|
1165
|
+
* The default English validation message for a required field left empty.
|
|
1166
|
+
* `validateField` returns this exact sentinel (core has no strings context),
|
|
1167
|
+
* and the React render layer swaps it for `strings.required` so a localized
|
|
1168
|
+
* site can translate it. Keep it identical to `DEFAULT_FIELD_STRINGS.required`.
|
|
1169
|
+
*/
|
|
1170
|
+
declare const REQUIRED_FIELD_MESSAGE = "This field is required";
|
|
1171
|
+
/**
|
|
1172
|
+
* The form-chrome strings the default renderers emit, overridable as a unit so
|
|
1173
|
+
* a localized site never shows stray English at the submit moment.
|
|
845
1174
|
* Schema-authored text (labels, descriptions, success copy set in settings)
|
|
846
1175
|
* always wins over these defaults.
|
|
1176
|
+
*
|
|
1177
|
+
* Field-level and validation copy (required message, upload field, duplicate/
|
|
1178
|
+
* resume notices) lives in {@link FilloFieldStrings} — split out so this
|
|
1179
|
+
* documented, all-`string` surface stays stable while parametrized field
|
|
1180
|
+
* strings can be functions. The renderers resolve both together
|
|
1181
|
+
* ({@link FilloRendererStrings}); the `strings` prop overrides either.
|
|
847
1182
|
*/
|
|
848
1183
|
interface FilloStrings {
|
|
849
1184
|
back: string;
|
|
@@ -870,9 +1205,53 @@ interface FilloStrings {
|
|
|
870
1205
|
loadFailedNetwork: string;
|
|
871
1206
|
loadFailed: string;
|
|
872
1207
|
renderFailed: string;
|
|
1208
|
+
/** Saved-progress notice when a draft restored earlier answers. */
|
|
1209
|
+
resumeNotice: string;
|
|
1210
|
+
/** Upsert-mode notice when the person's previous response was prefilled. */
|
|
1211
|
+
editNotice: string;
|
|
1212
|
+
/** The discard action next to the resume notice. */
|
|
1213
|
+
resumeStartOver: string;
|
|
873
1214
|
}
|
|
874
1215
|
declare const DEFAULT_STRINGS: FilloStrings;
|
|
875
|
-
|
|
1216
|
+
/**
|
|
1217
|
+
* Field-level and validation strings the default renderers emit. Kept apart
|
|
1218
|
+
* from {@link FilloStrings} so parametrized entries can be functions (a
|
|
1219
|
+
* translation places the value where its grammar needs it) without widening
|
|
1220
|
+
* the documented all-`string` chrome surface.
|
|
1221
|
+
*/
|
|
1222
|
+
interface FilloFieldStrings {
|
|
1223
|
+
/** Validation: a required field was left empty. Mirrors REQUIRED_FIELD_MESSAGE. */
|
|
1224
|
+
required: string;
|
|
1225
|
+
/** Notice when a spent/expired resume link couldn't restore progress. */
|
|
1226
|
+
resumeLinkExpired: string;
|
|
1227
|
+
/** Success-screen message when a verified identity re-submits and the form
|
|
1228
|
+
* keeps the first answer (a visible duplicate, not a fresh response). */
|
|
1229
|
+
alreadyAnswered: string;
|
|
1230
|
+
/** Retry control on a failed upload row. */
|
|
1231
|
+
uploadRetry: string;
|
|
1232
|
+
/** Dropzone copy when uploads can't run (no client / preview). */
|
|
1233
|
+
uploadsDisabled: string;
|
|
1234
|
+
/** An upload attempt failed with no actionable server message. */
|
|
1235
|
+
uploadFailed: string;
|
|
1236
|
+
/** Dropzone call to action; `multiple` is true when several files are allowed. */
|
|
1237
|
+
dropzoneTitle: (multiple: boolean) => string;
|
|
1238
|
+
/** Dropzone hint stating the per-file size limit in MB. */
|
|
1239
|
+
dropzoneHint: (maxMb: number) => string;
|
|
1240
|
+
/** A file exceeded the per-file MB limit before upload started. */
|
|
1241
|
+
fileTooLarge: (maxMb: number) => string;
|
|
1242
|
+
/** Screen-reader status: N uploads in progress. */
|
|
1243
|
+
filesUploading: (count: number) => string;
|
|
1244
|
+
/** Screen-reader status: N uploads failed. */
|
|
1245
|
+
uploadsFailed: (count: number) => string;
|
|
1246
|
+
/** Screen-reader status: N uploads completed. */
|
|
1247
|
+
filesUploaded: (count: number) => string;
|
|
1248
|
+
}
|
|
1249
|
+
declare const DEFAULT_FIELD_STRINGS: FilloFieldStrings;
|
|
1250
|
+
/** Everything the default renderers can localize — chrome + field/validation. */
|
|
1251
|
+
type FilloRendererStrings = FilloStrings & FilloFieldStrings;
|
|
1252
|
+
/** Merge overrides over the built-in chrome + field defaults. Accepts a partial
|
|
1253
|
+
* of the full renderer surface so the `strings` prop can override either set. */
|
|
1254
|
+
declare function resolveStrings(overrides?: Partial<FilloRendererStrings>): FilloRendererStrings;
|
|
876
1255
|
|
|
877
1256
|
/** Result of syncing a code-defined form: its canonical id, slug, and branding. */
|
|
878
1257
|
interface SyncedForm {
|
|
@@ -883,12 +1262,21 @@ interface SyncedForm {
|
|
|
883
1262
|
status?: "draft" | "published";
|
|
884
1263
|
/** Changes were staged as a draft for a human to publish. */
|
|
885
1264
|
staged?: boolean;
|
|
1265
|
+
/** Server-authoritative live snapshot when local code is not live yet. */
|
|
1266
|
+
resolvedSchema?: FormSchema;
|
|
1267
|
+
resolvedTheme?: FormTheme | null;
|
|
1268
|
+
/** Non-fatal integration problem; resolvedSchema remains safe to render. */
|
|
1269
|
+
syncError?: {
|
|
1270
|
+
code: string;
|
|
1271
|
+
message: string;
|
|
1272
|
+
};
|
|
886
1273
|
warning?: string;
|
|
887
1274
|
}
|
|
888
1275
|
/**
|
|
889
|
-
* A form whose structure lives in user code.
|
|
890
|
-
*
|
|
891
|
-
*
|
|
1276
|
+
* A form whose structure lives in user code. Development and explicit
|
|
1277
|
+
* render-only usage can show it immediately; production renderers with a
|
|
1278
|
+
* publishable key first resolve the canonical form from Fillo so responses,
|
|
1279
|
+
* uploads, webhooks, and exports stay bound to the published version.
|
|
892
1280
|
*/
|
|
893
1281
|
interface CodeForm {
|
|
894
1282
|
/** Stable handle, unique in the workspace. */
|
|
@@ -909,10 +1297,16 @@ declare function isCodeForm(form: unknown): form is CodeForm;
|
|
|
909
1297
|
/** Stable djb2 hash of a string — used to key code-form sync by content. */
|
|
910
1298
|
declare function contentHash(input: string): string;
|
|
911
1299
|
/**
|
|
912
|
-
*
|
|
913
|
-
*
|
|
914
|
-
*
|
|
915
|
-
|
|
1300
|
+
* Compare normalized schema JSON while ignoring object-key order (Postgres
|
|
1301
|
+
* jsonb and custom API proxies may reorder keys). Array order remains part of
|
|
1302
|
+
* the form definition because it controls pages, blocks, and options.
|
|
1303
|
+
*/
|
|
1304
|
+
declare function formSchemasEqual(left: FormSchema, right: FormSchema): boolean;
|
|
1305
|
+
/**
|
|
1306
|
+
* Resolve a code-defined form with in-flight dedupe and bounded stable-result
|
|
1307
|
+
* caching (published 1h, draft 60s). Staged/live-fallback results are evicted
|
|
1308
|
+
* once settled so an SPA can observe publication without a hard reload.
|
|
1309
|
+
* `bypassCache` forces the network for submit-time compatibility checks.
|
|
916
1310
|
*/
|
|
917
1311
|
declare function syncCodeForm(client: FilloClient, form: CodeForm, opts?: {
|
|
918
1312
|
bypassCache?: boolean;
|
|
@@ -1036,4 +1430,4 @@ declare class Sha1 {
|
|
|
1036
1430
|
}
|
|
1037
1431
|
declare const sha1Base64: (bytes: Uint8Array) => string;
|
|
1038
1432
|
|
|
1039
|
-
export { type AutoSubmitContext, BLOCK_KIND_META, type BaseField, type Block, type BlockKind, CONTENT_KINDS, type CheckboxField, type ChoiceField, type CodeForm, type Condition, type ConditionOp, type ContentBlock, type ContentKind, type CustomField, DEFAULT_STRINGS, DRAFT_KINDS, type DateField, type DividerBlock, FILLO_DATA_ATTRS, FILLO_SCHEMA_VERSION, FILLO_SDK_VERSION, FILLO_SLOTS, FILLO_THEME_VARS, type Field, type FieldKind, type FieldSpec, type FieldValue, type FileUploadField, type FileValue, type FilloAppearance, FilloClient, type FilloClientOptions, FilloError, FilloJsxError, type FilloSlot, type FilloStrings, type FormBranding, type FormController, type FormControllerOptions, type FormControllerState, type FormDraftSpec, type FormPage, type FormSchema, type FormSettings, type FormStatus, type FormTheme, type HeadingBlock, type HiddenField, JSX_BLOCK_COMPONENTS, JSX_BLOCK_SPECS, type JsonValue, type JsxFormMeta, type LinearScaleField, type MatrixField, type NumberField, PHONE_COUNTRIES, type ParagraphBlock, type ParsedPhone, type PhoneCountry, type PhoneField, type ProvisionWorkspaceResult, type PublishedForm, type RankingField, type RatingField, type ResponseData, type SchemaValidationResult, type SelectOption, Sha1, type SignatureField, type SlotClass, type SlotState, type SubmitMeta, type SubmitResult, type SyncFormResult, type SyncedForm, type TextField, type UploadFileOptions, type UploadProgress, type UploadSession, type UploadStatus, type UploadTransport, type ValidationResult, type WhenBuilder, allFields, assembleForm, codeFormFromJsx, contentHash, countryByDialCode, countryByIso, countryByTimeZone, createBlock, createClient, createEmptyForm, createFormController, createId, defineForm, digitsOnly, flagEmoji, formatAnswer, formatNational, isAutoSubmitBlock, isBlockVisible, isCodeForm, isField, isFilloError, isPossiblePhone, needsExplicitSubmit, normalizeFormSchema, normalizeFormTheme, parsePhone, pipeBlock, prefillFromParams, provisionWorkspace, resolveSlotClass, resolveStrings, resolveText, schemaFromJsx, sha1Base64, shouldAutoSubmit, slotClass, syncCodeForm, toE164, validateField, validateFormSchema, validateResponse, visibleBlocks, visibleFields, when };
|
|
1433
|
+
export { type AutoSubmitContext, BLOCK_KIND_META, type BaseField, type Block, type BlockKind, CONTENT_KINDS, type CheckboxField, type ChoiceField, type CodeForm, type Condition, type ConditionOp, type ContentBlock, type ContentKind, type CreatedDraft, type CustomField, DEFAULT_FIELD_STRINGS, DEFAULT_STRINGS, DRAFT_KINDS, type DateField, type DividerBlock, FILLO_DATA_ATTRS, FILLO_MIN_SDK_VERSION, FILLO_SCHEMA_VERSION, FILLO_SDK_VERSION, FILLO_SLOTS, FILLO_THEME_VARS, type Field, type FieldKind, type FieldSpec, type FieldValue, type FileUploadField, type FileValue, type FilloAppearance, FilloClient, type FilloClientOptions, FilloError, type FilloFieldStrings, FilloJsxError, type FilloRendererStrings, type FilloRespondent, type FilloSlot, type FilloStrings, type FormBranding, type FormController, type FormControllerOptions, type FormControllerState, type FormDraftSpec, type FormPage, type FormSchema, type FormSettings, type FormStatus, type FormTheme, type HeadingBlock, type HiddenField, JSX_BLOCK_COMPONENTS, JSX_BLOCK_SPECS, type JsonValue, type JsxFormMeta, type LinearScaleField, type MatrixField, type NumberField, PHONE_COUNTRIES, PHONE_POPOVER_VIEWPORT_GAP, type ParagraphBlock, type ParsedPhone, type PhoneCountry, type PhoneField, type PhonePopoverPlacement, type ProvisionWorkspaceResult, type PublishedForm, REQUIRED_FIELD_MESSAGE, type RankingField, type RatingField, type ResponseData, type ResponseDraft, type ResponseLimit, type SchemaValidationResult, type SelectOption, Sha1, type SignatureField, type SlotClass, type SlotState, type SubmitMeta, type SubmitResult, type SyncFormResult, type SyncedForm, type TextField, type UploadFileOptions, type UploadProgress, type UploadSession, type UploadStatus, type UploadTransport, type ValidationResult, type WhenBuilder, allFields, assembleForm, codeFormFromJsx, contentHash, countryByDialCode, countryByIso, countryByTimeZone, createBlock, createClient, createEmptyForm, createFormController, createId, defineForm, digitsOnly, flagEmoji, formSchemasEqual, formatAnswer, formatNational, isAutoSubmitBlock, isBlockVisible, isCodeForm, isField, isFilloError, isPossiblePhone, needsExplicitSubmit, normalizeFormSchema, normalizeFormTheme, normalizeSettings, parsePhone, pipeBlock, positionPhonePopover, prefillFromParams, provisionWorkspace, resolveSlotClass, resolveStrings, resolveText, responseScopeValue, schemaFromJsx, sha1Base64, shouldAutoSubmit, slotClass, syncCodeForm, toE164, validateField, validateFormSchema, validateResponse, visibleBlocks, visibleFields, visiblePageBlocks, when };
|