@usefillo/core 0.7.0 → 0.9.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 +3 -3
- package/dist/index.d.ts +360 -36
- package/dist/index.js +715 -121
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -8,6 +8,18 @@ interface Condition {
|
|
|
8
8
|
op: ConditionOp;
|
|
9
9
|
value?: string | number | boolean;
|
|
10
10
|
}
|
|
11
|
+
/**
|
|
12
|
+
* A single conditional page-flow rule (P1 logic depth). When every condition in
|
|
13
|
+
* `when` matches (AND — the same evaluator as `visibleIf`), navigation leaves
|
|
14
|
+
* the current page for `to`: another page's id, or the literal `"end"` to finish
|
|
15
|
+
* the form early. An empty `when` is an unconditional jump. Rules are evaluated
|
|
16
|
+
* top-to-bottom; the first match wins. See {@link FormPage.next}.
|
|
17
|
+
*/
|
|
18
|
+
interface JumpRule {
|
|
19
|
+
when: Condition[];
|
|
20
|
+
/** Target page id, or "end" to finish the form. */
|
|
21
|
+
to: string | "end";
|
|
22
|
+
}
|
|
11
23
|
type FieldKind = "short_text" | "long_text" | "email" | "url" | "phone" | "number" | "select" | "multi_select" | "dropdown" | "checkbox" | "rating" | "linear_scale" | "ranking" | "matrix" | "signature" | "date" | "file_upload" | "hidden" | "custom";
|
|
12
24
|
type ContentKind = "heading" | "paragraph" | "divider";
|
|
13
25
|
type BlockKind = FieldKind | ContentKind;
|
|
@@ -67,6 +79,8 @@ interface RatingField extends BaseField {
|
|
|
67
79
|
kind: "rating";
|
|
68
80
|
/** Number of steps, default 5. */
|
|
69
81
|
max?: number;
|
|
82
|
+
/** Optional analysis meaning. CSAT requires a 1–5 rating. */
|
|
83
|
+
insightsMetric?: "csat";
|
|
70
84
|
}
|
|
71
85
|
interface DateField extends BaseField {
|
|
72
86
|
kind: "date";
|
|
@@ -79,6 +93,8 @@ interface LinearScaleField extends BaseField {
|
|
|
79
93
|
max?: number;
|
|
80
94
|
minLabel?: string;
|
|
81
95
|
maxLabel?: string;
|
|
96
|
+
/** Optional analysis meaning. NPS requires 0–10; CSAT requires 1–5. */
|
|
97
|
+
insightsMetric?: "csat" | "nps";
|
|
82
98
|
}
|
|
83
99
|
interface RankingField extends BaseField {
|
|
84
100
|
kind: "ranking";
|
|
@@ -147,6 +163,10 @@ interface FormPage {
|
|
|
147
163
|
id: string;
|
|
148
164
|
title?: string;
|
|
149
165
|
blocks: Block[];
|
|
166
|
+
/** Conditional page flow (P1 logic depth). Rules are evaluated top-to-bottom;
|
|
167
|
+
* the first whose conditions all match decides the next step. No rule matches
|
|
168
|
+
* → default linear next page. Absent → today's linear behavior. */
|
|
169
|
+
next?: JumpRule[];
|
|
150
170
|
}
|
|
151
171
|
/**
|
|
152
172
|
* Limit repeat responses. Absent = no limit (submit as often as you like).
|
|
@@ -181,6 +201,22 @@ interface ResponseLimit {
|
|
|
181
201
|
*/
|
|
182
202
|
onRepeat: "keep" | "update";
|
|
183
203
|
}
|
|
204
|
+
/**
|
|
205
|
+
* Per-form submission-trust policy. Absent = accept everything (today's
|
|
206
|
+
* behavior). See docs/roadmap/07-submission-trust.md.
|
|
207
|
+
*/
|
|
208
|
+
interface TrustPolicy {
|
|
209
|
+
/** What to do with a submission whose respondent is NOT HMAC-verified.
|
|
210
|
+
* "allow" (default) accepts it normally; "quarantine" stores it withheld
|
|
211
|
+
* from every downstream consumer until an owner releases it. Declared-agent
|
|
212
|
+
* classes come in a later phase. */
|
|
213
|
+
unverified?: "allow" | "quarantine";
|
|
214
|
+
/** Require a human-verification challenge before accepting a submission.
|
|
215
|
+
* "off" (default) = no challenge; "turnstile" = a Cloudflare Turnstile widget
|
|
216
|
+
* that the SDK renders and the server verifies. Provider-agnostic on purpose.
|
|
217
|
+
* Independent of `unverified` — a form can require both. */
|
|
218
|
+
challenge?: "off" | "turnstile";
|
|
219
|
+
}
|
|
184
220
|
interface FormSettings {
|
|
185
221
|
/**
|
|
186
222
|
* Default "button": respondents submit with the footer button. "auto" hides
|
|
@@ -196,6 +232,9 @@ interface FormSettings {
|
|
|
196
232
|
/** Limit repeat responses (who counts as the same responder, and what a
|
|
197
233
|
* repeat does). Absent = no limit. See {@link ResponseLimit}. */
|
|
198
234
|
responseLimit?: ResponseLimit;
|
|
235
|
+
/** Per-form submission-trust policy. Absent = accept everything (today's
|
|
236
|
+
* behavior). See docs/roadmap/07-submission-trust.md. */
|
|
237
|
+
trust?: TrustPolicy;
|
|
199
238
|
/** Notify this address on every submission. */
|
|
200
239
|
notifyEmail?: string;
|
|
201
240
|
/** Send respondents a receipt (to the first answered email field). */
|
|
@@ -291,6 +330,10 @@ type UploadStatus = "pending" | "uploading" | "complete" | "aborted";
|
|
|
291
330
|
* - "gdrive": direct to a Google Drive resumable session URL (Content-Range
|
|
292
331
|
* protocol).
|
|
293
332
|
* - "s3-put": a single PUT to a presigned S3/R2 URL — straight to the bucket.
|
|
333
|
+
* Retained for sessions created by older Fillo servers.
|
|
334
|
+
* - "s3-multipart": resumable S3/R2 multipart upload. The client asks Fillo
|
|
335
|
+
* for one short-lived UploadPart URL at a time; only the server can assemble
|
|
336
|
+
* the parts into an object.
|
|
294
337
|
* - "box": direct to Box with a folder-scoped upload token — small files via a
|
|
295
338
|
* single multipart POST, large files via Box's chunked session (the client
|
|
296
339
|
* computes the SHA-1 digests Box requires). The server commits/verifies in the
|
|
@@ -302,6 +345,8 @@ type UploadTransport = {
|
|
|
302
345
|
} | {
|
|
303
346
|
type: "s3-put";
|
|
304
347
|
uploadUrl: string;
|
|
348
|
+
} | {
|
|
349
|
+
type: "s3-multipart";
|
|
305
350
|
} | {
|
|
306
351
|
type: "box";
|
|
307
352
|
mode: "simple";
|
|
@@ -341,9 +386,29 @@ interface UploadSession {
|
|
|
341
386
|
file?: FileValue;
|
|
342
387
|
}
|
|
343
388
|
|
|
389
|
+
/**
|
|
390
|
+
* All conditions must hold (AND); no conditions = true. THE shared evaluator —
|
|
391
|
+
* both block visibility (`visibleIf`) and page jumps (`JumpRule.when`) run
|
|
392
|
+
* through this over the SAME whole-form fixpoint resolver, so a jump gated by a
|
|
393
|
+
* logic-hidden controller field behaves identically to a visibility rule.
|
|
394
|
+
*/
|
|
395
|
+
declare function conditionsMet(conds: Condition[], resolve: (fieldId: string) => FieldValue): boolean;
|
|
344
396
|
/** All conditions must hold (AND). No conditions = visible. */
|
|
345
397
|
declare function isBlockVisible(block: Block, data: ResponseData): boolean;
|
|
346
398
|
declare function visibleBlocks(page: FormPage, data: ResponseData): Block[];
|
|
399
|
+
/**
|
|
400
|
+
* Blocks to render on `page`, resolved against the WHOLE-FORM visibility
|
|
401
|
+
* fixpoint rather than just this page's own fields. A field whose `visibleIf`
|
|
402
|
+
* references an answer on another page must appear/validate here exactly when
|
|
403
|
+
* the server would keep that answer — and the server (validateResponse →
|
|
404
|
+
* visibleFields) uses the whole-form fixpoint, hiding any controlling field
|
|
405
|
+
* that is itself logic-hidden. Scoping per page instead reads a stale answer
|
|
406
|
+
* behind a hidden cross-page trigger as still-answered, so the client would
|
|
407
|
+
* render (and validate) a field whose answer the server then silently drops.
|
|
408
|
+
* Use this for anything that must agree with validateResponse; the per-page
|
|
409
|
+
* `visibleBlocks` remains for callers holding only a single page.
|
|
410
|
+
*/
|
|
411
|
+
declare function visiblePageBlocks(form: FormSchema, page: FormPage, data: ResponseData): Block[];
|
|
347
412
|
/** Every field in the form (across pages), in order. */
|
|
348
413
|
declare function allFields(form: FormSchema): Field[];
|
|
349
414
|
/**
|
|
@@ -355,8 +420,57 @@ declare function allFields(form: FormSchema): Field[];
|
|
|
355
420
|
* per-visitor key and the server's per-person dedup so both scope identically.
|
|
356
421
|
*/
|
|
357
422
|
declare function responseScopeValue(settings: FormSettings, data: ResponseData): string | null;
|
|
358
|
-
/** Fields currently visible given the response data
|
|
423
|
+
/** Fields currently visible given the response data. */
|
|
359
424
|
declare function visibleFields(form: FormSchema, data: ResponseData): Field[];
|
|
425
|
+
/** Where navigation goes when leaving a page. */
|
|
426
|
+
type NextPage = {
|
|
427
|
+
to: string;
|
|
428
|
+
} | {
|
|
429
|
+
end: true;
|
|
430
|
+
} | {
|
|
431
|
+
linear: true;
|
|
432
|
+
};
|
|
433
|
+
/**
|
|
434
|
+
* Evaluate a page's `next` jump rules top-to-bottom against the current data;
|
|
435
|
+
* the first whose conditions all match decides the step ("end" → finish the
|
|
436
|
+
* form). No rule (or no `next`) → the default linear next page. THE single
|
|
437
|
+
* function the client renderer, the server validator, and the funnel share so
|
|
438
|
+
* they always agree on flow.
|
|
439
|
+
*/
|
|
440
|
+
declare function resolveNextPage(form: FormSchema, currentPageId: string, data: ResponseData): NextPage;
|
|
441
|
+
/**
|
|
442
|
+
* The ORDERED list of reachable page ids for the given data: walk from
|
|
443
|
+
* `pages[0]` following `resolveNextPage` (linear → next index; jump → target id;
|
|
444
|
+
* end → stop). A rule that points backward could loop, so stop on the first
|
|
445
|
+
* revisit and cap the walk at `pages.length` steps. THE single ordered engine
|
|
446
|
+
* the client renderer, the server validator, and navigation all agree through —
|
|
447
|
+
* a no-jump form yields `[pages[0].id, …, pages[N].id]`, so everything built on
|
|
448
|
+
* it reduces to today's linear behavior. {@link reachablePageIds} is the set of
|
|
449
|
+
* this exact walk (one walk, no divergence).
|
|
450
|
+
*/
|
|
451
|
+
declare function reachablePageSequence(form: FormSchema, data: ResponseData): string[];
|
|
452
|
+
/**
|
|
453
|
+
* The page ids reachable for the given data. The unordered set of
|
|
454
|
+
* {@link reachablePageSequence} — one shared walk keeps the ordered navigation
|
|
455
|
+
* and the reachability the validator uses provably in agreement. THE function
|
|
456
|
+
* the client renderer and server validator both use to decide which pages/fields
|
|
457
|
+
* are in play.
|
|
458
|
+
*/
|
|
459
|
+
declare function reachablePageIds(form: FormSchema, data: ResponseData): Set<string>;
|
|
460
|
+
/**
|
|
461
|
+
* Whether `pageId` is terminal for the given data — pressing the footer button
|
|
462
|
+
* there submits rather than advancing. True when a matched jump rule resolves to
|
|
463
|
+
* "end", or when the page is the LAST element of the reachable sequence (the
|
|
464
|
+
* last reachable page, including a cycle broken at its revisit, so a backward
|
|
465
|
+
* jump can never loop — the pre-revisit page becomes terminal and Submit
|
|
466
|
+
* appears). For a no-jump form this is exactly "the last page".
|
|
467
|
+
*/
|
|
468
|
+
declare function isTerminalPage(form: FormSchema, pageId: string, data: ResponseData): boolean;
|
|
469
|
+
/** Reachable field ids: fields on reachable pages, intersected with visibility. */
|
|
470
|
+
declare function reachableFieldIds(form: FormSchema, data: ResponseData): Set<string>;
|
|
471
|
+
/** Fields that are both reachable AND visible — the set that gets validated and
|
|
472
|
+
* kept on submit. Equals {@link visibleFields} for a form with no jumps. */
|
|
473
|
+
declare function reachableFields(form: FormSchema, data: ResponseData): Field[];
|
|
360
474
|
|
|
361
475
|
/** Validate a single answered value for a field. Returns an error message or null. */
|
|
362
476
|
declare function validateField(field: Field, value: FieldValue): string | null;
|
|
@@ -364,18 +478,42 @@ interface ValidationResult {
|
|
|
364
478
|
ok: boolean;
|
|
365
479
|
/** fieldId -> message for every failing field. */
|
|
366
480
|
errors: Record<string, string>;
|
|
367
|
-
/** Data trimmed to the fields that are visible (
|
|
481
|
+
/** Data trimmed to the fields that are reachable + visible (answers to fields
|
|
482
|
+
* hidden by logic OR on pages skipped by a jump/early-end are dropped). */
|
|
368
483
|
data: ResponseData;
|
|
369
484
|
}
|
|
370
485
|
/**
|
|
371
|
-
* Validate a full submission against the schema. Only currently-
|
|
372
|
-
* are validated and kept — answers to fields hidden by logic
|
|
486
|
+
* Validate a full submission against the schema. Only reachable + currently-
|
|
487
|
+
* visible fields are validated and kept — answers to fields hidden by logic, or
|
|
488
|
+
* on pages a page-jump/early-end skipped, are discarded. A legitimately
|
|
489
|
+
* early-ended submission therefore does NOT 422 on a skipped page's required
|
|
490
|
+
* field. Reachability is computed by the SAME shared engine the client renderer
|
|
491
|
+
* navigates with, so render and validate always agree. A form with no jumps has
|
|
492
|
+
* every page reachable, so this validates exactly as before.
|
|
373
493
|
*/
|
|
374
494
|
declare function validateResponse(form: FormSchema, data: ResponseData): ValidationResult;
|
|
375
495
|
|
|
376
496
|
declare const FILLO_SCHEMA_VERSION: 1;
|
|
377
497
|
/** Injected from package.json at build time (tsup define) — never hand-edited. */
|
|
378
498
|
declare const FILLO_SDK_VERSION: string;
|
|
499
|
+
/**
|
|
500
|
+
* The oldest published @usefillo/* SDK that can still render a form the current
|
|
501
|
+
* server serves. This is a DELIBERATE floor — bump it BY HAND only when a
|
|
502
|
+
* genuinely wire-breaking change ships (a new required request/response field an
|
|
503
|
+
* old SDK can't produce or read). It must never be tied to FILLO_SDK_VERSION:
|
|
504
|
+
* the server used to serve its own build version as the min, so every release
|
|
505
|
+
* 426'd every customer still on an older pinned SDK. Field-kind/schema-shape
|
|
506
|
+
* breaks are gated separately by FILLO_SCHEMA_VERSION, so this floor stays low.
|
|
507
|
+
*/
|
|
508
|
+
declare const FILLO_MIN_SDK_VERSION = "0.4.0";
|
|
509
|
+
/**
|
|
510
|
+
* The floor served INSTEAD of FILLO_MIN_SDK_VERSION for challenge-enabled
|
|
511
|
+
* forms: the first release that ships the Turnstile widget. An older SDK passes
|
|
512
|
+
* the base floor but renders no widget, so the server would reject its every
|
|
513
|
+
* submit — the raised floor makes it fail fast with the clear "update
|
|
514
|
+
* @usefillo/*" error instead of a form that silently can't submit.
|
|
515
|
+
*/
|
|
516
|
+
declare const FILLO_CHALLENGE_MIN_SDK_VERSION = "0.9.0";
|
|
379
517
|
declare function normalizeSettings(value: unknown): FormSettings;
|
|
380
518
|
interface SchemaValidationResult {
|
|
381
519
|
ok: boolean;
|
|
@@ -457,6 +595,18 @@ declare function parsePhone(value: string, fallback?: PhoneCountry): ParsedPhone
|
|
|
457
595
|
* validation. `country` (when known) tightens the accepted lengths.
|
|
458
596
|
*/
|
|
459
597
|
declare function isPossiblePhone(value: string): boolean;
|
|
598
|
+
/** Whether the country-picker popover opens below or above its trigger. */
|
|
599
|
+
type PhonePopoverPlacement = "below" | "above";
|
|
600
|
+
/** Minimum gap kept between the popover and the viewport edge, in px. */
|
|
601
|
+
declare const PHONE_POPOVER_VIEWPORT_GAP = 8;
|
|
602
|
+
/**
|
|
603
|
+
* Decide whether the country-picker popover should open below or above its
|
|
604
|
+
* anchor and size it to fit the viewport, writing the result to CSS custom
|
|
605
|
+
* properties on the popover. Pure DOM math with no framework assumptions, so
|
|
606
|
+
* the React and vanilla renderers share one implementation instead of drifting
|
|
607
|
+
* copies. Returns "below" when there is nothing to position (SSR / detached).
|
|
608
|
+
*/
|
|
609
|
+
declare function positionPhonePopover(anchor: HTMLElement | null, popover: HTMLElement | null): PhonePopoverPlacement;
|
|
460
610
|
|
|
461
611
|
/** Display metadata for every block kind — drives the builder palette. */
|
|
462
612
|
declare const BLOCK_KIND_META: Record<BlockKind, {
|
|
@@ -491,6 +641,7 @@ interface FieldSpec {
|
|
|
491
641
|
max?: number;
|
|
492
642
|
minLabel?: string;
|
|
493
643
|
maxLabel?: string;
|
|
644
|
+
insightsMetric?: "csat" | "nps";
|
|
494
645
|
rows?: string[];
|
|
495
646
|
columns?: string[];
|
|
496
647
|
placeholder?: string;
|
|
@@ -532,6 +683,18 @@ interface FilloClientOptions {
|
|
|
532
683
|
baseUrl?: string;
|
|
533
684
|
fetch?: typeof fetch;
|
|
534
685
|
}
|
|
686
|
+
/**
|
|
687
|
+
* Public human-verification challenge config the SDK needs to render a widget.
|
|
688
|
+
* Delivered as a TOP-LEVEL field on the form GET (never inside the schema): the
|
|
689
|
+
* schema's trust policy is server-only and stripped, but the widget needs the
|
|
690
|
+
* PUBLIC site key. Injected server-side from Fillo's env — the SECRET key never
|
|
691
|
+
* leaves the server. Absent = no challenge (render nothing, load no script).
|
|
692
|
+
*/
|
|
693
|
+
interface ChallengeConfig {
|
|
694
|
+
provider: "turnstile";
|
|
695
|
+
/** Cloudflare Turnstile PUBLIC site key. Safe to ship to the browser. */
|
|
696
|
+
siteKey: string;
|
|
697
|
+
}
|
|
535
698
|
interface PublishedForm {
|
|
536
699
|
id: string;
|
|
537
700
|
slug: string;
|
|
@@ -547,6 +710,9 @@ interface PublishedForm {
|
|
|
547
710
|
closed?: boolean;
|
|
548
711
|
/** Workspace branding state — absent means show the badge (default). */
|
|
549
712
|
branding?: FormBranding;
|
|
713
|
+
/** Human-verification challenge to render before submit, when the form
|
|
714
|
+
* requires one. Absent = no challenge. Carries only the PUBLIC site key. */
|
|
715
|
+
challenge?: ChallengeConfig;
|
|
550
716
|
}
|
|
551
717
|
type SubmitResult = {
|
|
552
718
|
ok: true;
|
|
@@ -592,6 +758,13 @@ interface SubmitMeta {
|
|
|
592
758
|
* stable user/account id.
|
|
593
759
|
*/
|
|
594
760
|
respondent?: FilloRespondent;
|
|
761
|
+
/**
|
|
762
|
+
* Human-verification challenge token (e.g. from the Cloudflare Turnstile
|
|
763
|
+
* widget). Present only when the form requires a challenge; the server
|
|
764
|
+
* verifies it and rejects the submit if it is missing or invalid. Never a
|
|
765
|
+
* secret — it is a single-use, server-verifiable proof of the widget solve.
|
|
766
|
+
*/
|
|
767
|
+
challengeToken?: string;
|
|
595
768
|
}
|
|
596
769
|
/**
|
|
597
770
|
* The host app's account context for the person filling the form. Passed as
|
|
@@ -656,14 +829,23 @@ interface UploadFileOptions {
|
|
|
656
829
|
sessionId?: string;
|
|
657
830
|
/** Ownership token for the resumed session (from the original create call). */
|
|
658
831
|
uploadToken?: string;
|
|
832
|
+
/** Persist this handle if the host wants reload-safe resumability. */
|
|
833
|
+
onSession?: (handle: {
|
|
834
|
+
sessionId: string;
|
|
835
|
+
uploadToken?: string;
|
|
836
|
+
}) => void;
|
|
659
837
|
}
|
|
660
838
|
declare class FilloError extends Error {
|
|
661
839
|
status?: number | undefined;
|
|
662
840
|
/** Server-suggested wait (from a 429's Retry-After header), seconds. */
|
|
663
841
|
retryAfterSec?: number | undefined;
|
|
842
|
+
/** Stable machine-readable API error code, when the server provides one. */
|
|
843
|
+
code?: string | undefined;
|
|
664
844
|
constructor(message: string, status?: number | undefined,
|
|
665
845
|
/** Server-suggested wait (from a 429's Retry-After header), seconds. */
|
|
666
|
-
retryAfterSec?: number | undefined
|
|
846
|
+
retryAfterSec?: number | undefined,
|
|
847
|
+
/** Stable machine-readable API error code, when the server provides one. */
|
|
848
|
+
code?: string | undefined);
|
|
667
849
|
}
|
|
668
850
|
/** Duck-typed — `instanceof` breaks when two SDK copies end up in one bundle. */
|
|
669
851
|
declare function isFilloError(err: unknown): err is FilloError;
|
|
@@ -671,10 +853,25 @@ interface SyncFormResult {
|
|
|
671
853
|
formId: string;
|
|
672
854
|
slug: string;
|
|
673
855
|
branding?: FormBranding;
|
|
856
|
+
/** Human-verification challenge to render before submit, when the LIVE form
|
|
857
|
+
* requires one (staged changes don't gate until published). Absent = no
|
|
858
|
+
* challenge. Carries only the PUBLIC site key. */
|
|
859
|
+
challenge?: ChallengeConfig;
|
|
674
860
|
/** Lifecycle on newer servers: a draft can't accept public responses yet. */
|
|
675
861
|
status?: "draft" | "published";
|
|
676
862
|
/** Changes were staged as a draft for a human to publish. */
|
|
677
863
|
staged?: boolean;
|
|
864
|
+
/**
|
|
865
|
+
* Server-authoritative live snapshot. Present when the incoming code schema
|
|
866
|
+
* is not the version respondents may submit against yet.
|
|
867
|
+
*/
|
|
868
|
+
resolvedSchema?: FormSchema;
|
|
869
|
+
resolvedTheme?: FormTheme | null;
|
|
870
|
+
/** Non-fatal integration problem; the resolved live snapshot remains usable. */
|
|
871
|
+
syncError?: {
|
|
872
|
+
code: string;
|
|
873
|
+
message: string;
|
|
874
|
+
};
|
|
678
875
|
warning?: string;
|
|
679
876
|
}
|
|
680
877
|
declare class FilloClient {
|
|
@@ -689,8 +886,10 @@ declare class FilloClient {
|
|
|
689
886
|
/** Fetch a published form definition by id or slug. */
|
|
690
887
|
getForm(idOrSlug: string): Promise<PublishedForm>;
|
|
691
888
|
/**
|
|
692
|
-
*
|
|
693
|
-
* publishable key.
|
|
889
|
+
* Resolve a code-defined form through the workspace identified by the
|
|
890
|
+
* client's publishable key. Depending on workspace policy, changed content
|
|
891
|
+
* may be staged for review or resolved to the authoritative live snapshot.
|
|
892
|
+
* Returns the canonical form id used for submissions.
|
|
694
893
|
*/
|
|
695
894
|
syncForm(handle: string, schema: FormSchema, theme?: FormTheme | null): Promise<SyncFormResult>;
|
|
696
895
|
/** Submit a response. Returns per-field errors instead of throwing on validation failure. */
|
|
@@ -700,8 +899,14 @@ declare class FilloClient {
|
|
|
700
899
|
* used to prefill their answers for editing. Requires a VERIFIED identity
|
|
701
900
|
* ({id, hash}); anything else 404s (returned as null), because an
|
|
702
901
|
* unverified read would hand anyone's answers to any page script.
|
|
902
|
+
*
|
|
903
|
+
* `scopeValue` scopes the lookup for forms whose response limit is keyed to
|
|
904
|
+
* a field (responseLimit.scopeField) — e.g. one response per article. When
|
|
905
|
+
* the form is scoped, the server returns 404 unless the matching scope value
|
|
906
|
+
* is sent, so a page loaded for article B never prefills article A's answers.
|
|
907
|
+
* Optional and back-compatible: omit it for unscoped forms.
|
|
703
908
|
*/
|
|
704
|
-
fetchOwnResponse(formId: string, respondent: FilloRespondent): Promise<{
|
|
909
|
+
fetchOwnResponse(formId: string, respondent: FilloRespondent, scopeValue?: string): Promise<{
|
|
705
910
|
responseId: string;
|
|
706
911
|
data: ResponseData;
|
|
707
912
|
} | null>;
|
|
@@ -743,13 +948,12 @@ declare class FilloClient {
|
|
|
743
948
|
/** Discard a draft (the "Start over" path). */
|
|
744
949
|
deleteDraft(draftId: string, token: string): Promise<void>;
|
|
745
950
|
/** Current state of an upload session — used to resume after interruption. */
|
|
746
|
-
getUploadSession(sessionId: string, token?: string): Promise<UploadSession>;
|
|
951
|
+
getUploadSession(sessionId: string, token?: string, signal?: AbortSignal): Promise<UploadSession>;
|
|
747
952
|
/**
|
|
748
|
-
*
|
|
749
|
-
*
|
|
750
|
-
*
|
|
751
|
-
*
|
|
752
|
-
* is sent twice or skipped.
|
|
953
|
+
* Provider-aware browser-direct upload. Creates a session, uses the storage
|
|
954
|
+
* transport selected by the server, reports progress, and finalizes into a
|
|
955
|
+
* FileValue. Resumable providers can continue an existing session; one-shot
|
|
956
|
+
* transports are retried according to their own safe semantics.
|
|
753
957
|
*
|
|
754
958
|
* Depending on the form's storage settings the server picks a transport:
|
|
755
959
|
* direct-to-Google-Drive resumable
|
|
@@ -768,7 +972,7 @@ declare class FilloClient {
|
|
|
768
972
|
/**
|
|
769
973
|
* Caller signal (if any) combined with a fresh per-request timeout. Created per
|
|
770
974
|
* fetch so each retry attempt gets its own deadline; the caller's own abort
|
|
771
|
-
* still drives
|
|
975
|
+
* still drives upload cancellation across every provider transport.
|
|
772
976
|
*/
|
|
773
977
|
private uploadSignal;
|
|
774
978
|
/** Retry a request with exponential backoff; never retries an aborted upload. */
|
|
@@ -780,6 +984,13 @@ declare class FilloClient {
|
|
|
780
984
|
* queries Drive for the authoritative offset).
|
|
781
985
|
*/
|
|
782
986
|
private driveUploadLoop;
|
|
987
|
+
/**
|
|
988
|
+
* S3-compatible multipart protocol. Fillo owns the provider upload id and is
|
|
989
|
+
* the only party allowed to complete it; the browser receives only narrowly
|
|
990
|
+
* scoped UploadPart URLs. That keeps uploads resumable and means an old or
|
|
991
|
+
* slow browser request cannot materialize an object after server-side abort.
|
|
992
|
+
*/
|
|
993
|
+
private s3MultipartUploadLoop;
|
|
783
994
|
/**
|
|
784
995
|
* S3-compatible single PUT to a presigned URL — bytes go straight to the
|
|
785
996
|
* bucket. Not resumable (S3 single PUT is atomic), but retried on failure.
|
|
@@ -791,13 +1002,13 @@ interface ProvisionWorkspaceResult {
|
|
|
791
1002
|
/** Publishable key (pk_…) for the new workspace. Pass to createClient({ key }). */
|
|
792
1003
|
key: string;
|
|
793
1004
|
organizationId: string;
|
|
794
|
-
/**
|
|
1005
|
+
/** The private workspace link is emailed directly; `url` stays null. */
|
|
795
1006
|
claim: {
|
|
796
1007
|
url: string | null;
|
|
797
1008
|
email: string | null;
|
|
798
1009
|
sent: boolean;
|
|
799
1010
|
};
|
|
800
|
-
/** Caps applied until the workspace is
|
|
1011
|
+
/** Caps applied until the workspace is saved to an account. */
|
|
801
1012
|
limits: {
|
|
802
1013
|
responses: number;
|
|
803
1014
|
expiresAt: string;
|
|
@@ -805,9 +1016,9 @@ interface ProvisionWorkspaceResult {
|
|
|
805
1016
|
}
|
|
806
1017
|
/**
|
|
807
1018
|
* Provision a Fillo workspace from an email — no signup — and get a publishable
|
|
808
|
-
* key back, so a form can collect real responses immediately. A
|
|
809
|
-
* emailed to `email`; until someone
|
|
810
|
-
* preview (limited responses, for a limited time). Built for setup automation,
|
|
1019
|
+
* key back, so a form can collect real responses immediately. A private
|
|
1020
|
+
* workspace link is emailed to `email`; until someone saves it to an account,
|
|
1021
|
+
* the workspace runs as a capped preview (limited responses, for a limited time). Built for setup automation,
|
|
811
1022
|
* e.g. a coding agent wiring Fillo into an app during integration.
|
|
812
1023
|
*
|
|
813
1024
|
* const { key } = await provisionWorkspace({ email: "you@co.com" });
|
|
@@ -853,10 +1064,10 @@ interface FormControllerOptions {
|
|
|
853
1064
|
*/
|
|
854
1065
|
surface?: "default" | "headless";
|
|
855
1066
|
/**
|
|
856
|
-
* Resolve the submission target
|
|
857
|
-
*
|
|
858
|
-
* held (never dropped) while it
|
|
859
|
-
* respondent can retry.
|
|
1067
|
+
* Resolve/verify the submission target immediately before submit. Code-form
|
|
1068
|
+
* renderers use this to recover a missing target and to detect a live schema
|
|
1069
|
+
* change after a cached mount. Answers are held (never dropped) while it
|
|
1070
|
+
* runs; failure sets `submitError` and the respondent can retry.
|
|
860
1071
|
*/
|
|
861
1072
|
resolveFormId?: () => Promise<string>;
|
|
862
1073
|
/**
|
|
@@ -866,6 +1077,24 @@ interface FormControllerOptions {
|
|
|
866
1077
|
* the respondent can do.
|
|
867
1078
|
*/
|
|
868
1079
|
respondent?: FilloRespondent;
|
|
1080
|
+
/**
|
|
1081
|
+
* True when the form requires a human-verification challenge (Turnstile).
|
|
1082
|
+
* When set, submit refuses to send until a token is available and always
|
|
1083
|
+
* attaches the token from {@link getChallengeToken}. The server is the real
|
|
1084
|
+
* gate — this only avoids firing a submit the server would reject.
|
|
1085
|
+
*/
|
|
1086
|
+
challengeRequired?: boolean;
|
|
1087
|
+
/**
|
|
1088
|
+
* Read the current challenge token (from the rendered widget) at submit time.
|
|
1089
|
+
* Returns undefined until the challenge is solved. Read lazily so an expired
|
|
1090
|
+
* token that was refreshed just before submit is picked up fresh.
|
|
1091
|
+
*/
|
|
1092
|
+
getChallengeToken?: () => string | undefined;
|
|
1093
|
+
/**
|
|
1094
|
+
* The server rejected the submission's challenge (stale/replayed/invalid
|
|
1095
|
+
* token). The renderer resets the widget so the human can solve a fresh one.
|
|
1096
|
+
*/
|
|
1097
|
+
onChallengeFailed?: () => void;
|
|
869
1098
|
}
|
|
870
1099
|
interface FormControllerState {
|
|
871
1100
|
data: ResponseData;
|
|
@@ -904,6 +1133,27 @@ interface FormControllerState {
|
|
|
904
1133
|
* show an "updating your earlier response" notice.
|
|
905
1134
|
*/
|
|
906
1135
|
editingPrevious: boolean;
|
|
1136
|
+
/**
|
|
1137
|
+
* True when the last submit was accepted as an already-recorded response
|
|
1138
|
+
* rather than a new one (the server returns this only for a VERIFIED
|
|
1139
|
+
* identify() repeat on a keep-mode form). Renderers show an "already
|
|
1140
|
+
* answered" message on the success screen instead of implying a fresh
|
|
1141
|
+
* submission — otherwise a repeat visitor's new answers look saved when the
|
|
1142
|
+
* server kept the original.
|
|
1143
|
+
*/
|
|
1144
|
+
duplicateSubmission: boolean;
|
|
1145
|
+
/**
|
|
1146
|
+
* True when the last submit UPDATED the person's existing response in place
|
|
1147
|
+
* (responseLimit onRepeat "update"), rather than creating a new one.
|
|
1148
|
+
*/
|
|
1149
|
+
updatedSubmission: boolean;
|
|
1150
|
+
/**
|
|
1151
|
+
* True when a resume link (#fillo-draft=…) could not be adopted because it
|
|
1152
|
+
* was expired, already used, or not this browser's — so no progress was
|
|
1153
|
+
* restored. Renderers surface a "that link expired — start again" notice
|
|
1154
|
+
* instead of showing a silently blank form.
|
|
1155
|
+
*/
|
|
1156
|
+
resumeLinkFailed: boolean;
|
|
907
1157
|
}
|
|
908
1158
|
interface FormController {
|
|
909
1159
|
/** Stable snapshot — same reference until something changes (safe for useSyncExternalStore). */
|
|
@@ -963,6 +1213,8 @@ interface AutoSubmitContext {
|
|
|
963
1213
|
form: FormSchema;
|
|
964
1214
|
data: ResponseData;
|
|
965
1215
|
status: FormStatus;
|
|
1216
|
+
/** Terminal-aware last-page flag from the controller. Advisory here —
|
|
1217
|
+
* shouldAutoSubmit re-derives terminal from the RESULTING data (see below). */
|
|
966
1218
|
isLastPage: boolean;
|
|
967
1219
|
uploading: boolean;
|
|
968
1220
|
}
|
|
@@ -974,7 +1226,7 @@ declare function shouldAutoSubmit(field: Field, value: FieldValue, ctx: AutoSubm
|
|
|
974
1226
|
* (Tailwind `data-[invalid]:…`) can react to it. Slot names and attribute
|
|
975
1227
|
* names are public API — renames are breaking; additions are minors.
|
|
976
1228
|
*/
|
|
977
|
-
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"];
|
|
1229
|
+
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", "turnstile"];
|
|
978
1230
|
type FilloSlot = (typeof FILLO_SLOTS)[number];
|
|
979
1231
|
/** data-* names emitted alongside the stable fillo-* classes. */
|
|
980
1232
|
declare const FILLO_DATA_ATTRS: {
|
|
@@ -1061,10 +1313,23 @@ declare const FILLO_THEME_VARS: readonly [{
|
|
|
1061
1313
|
}];
|
|
1062
1314
|
|
|
1063
1315
|
/**
|
|
1064
|
-
*
|
|
1065
|
-
*
|
|
1316
|
+
* The default English validation message for a required field left empty.
|
|
1317
|
+
* `validateField` returns this exact sentinel (core has no strings context),
|
|
1318
|
+
* and the React render layer swaps it for `strings.required` so a localized
|
|
1319
|
+
* site can translate it. Keep it identical to `DEFAULT_FIELD_STRINGS.required`.
|
|
1320
|
+
*/
|
|
1321
|
+
declare const REQUIRED_FIELD_MESSAGE = "This field is required";
|
|
1322
|
+
/**
|
|
1323
|
+
* The form-chrome strings the default renderers emit, overridable as a unit so
|
|
1324
|
+
* a localized site never shows stray English at the submit moment.
|
|
1066
1325
|
* Schema-authored text (labels, descriptions, success copy set in settings)
|
|
1067
1326
|
* always wins over these defaults.
|
|
1327
|
+
*
|
|
1328
|
+
* Field-level and validation copy (required message, upload field, duplicate/
|
|
1329
|
+
* resume notices) lives in {@link FilloFieldStrings} — split out so this
|
|
1330
|
+
* documented, all-`string` surface stays stable while parametrized field
|
|
1331
|
+
* strings can be functions. The renderers resolve both together
|
|
1332
|
+
* ({@link FilloRendererStrings}); the `strings` prop overrides either.
|
|
1068
1333
|
*/
|
|
1069
1334
|
interface FilloStrings {
|
|
1070
1335
|
back: string;
|
|
@@ -1097,25 +1362,78 @@ interface FilloStrings {
|
|
|
1097
1362
|
editNotice: string;
|
|
1098
1363
|
/** The discard action next to the resume notice. */
|
|
1099
1364
|
resumeStartOver: string;
|
|
1365
|
+
/** Shown when the human-verification widget can't load (script blocked). */
|
|
1366
|
+
challengeUnavailable: string;
|
|
1100
1367
|
}
|
|
1101
1368
|
declare const DEFAULT_STRINGS: FilloStrings;
|
|
1102
|
-
|
|
1369
|
+
/**
|
|
1370
|
+
* Field-level and validation strings the default renderers emit. Kept apart
|
|
1371
|
+
* from {@link FilloStrings} so parametrized entries can be functions (a
|
|
1372
|
+
* translation places the value where its grammar needs it) without widening
|
|
1373
|
+
* the documented all-`string` chrome surface.
|
|
1374
|
+
*/
|
|
1375
|
+
interface FilloFieldStrings {
|
|
1376
|
+
/** Validation: a required field was left empty. Mirrors REQUIRED_FIELD_MESSAGE. */
|
|
1377
|
+
required: string;
|
|
1378
|
+
/** Notice when a spent/expired resume link couldn't restore progress. */
|
|
1379
|
+
resumeLinkExpired: string;
|
|
1380
|
+
/** Success-screen message when a verified identity re-submits and the form
|
|
1381
|
+
* keeps the first answer (a visible duplicate, not a fresh response). */
|
|
1382
|
+
alreadyAnswered: string;
|
|
1383
|
+
/** Retry control on a failed upload row. */
|
|
1384
|
+
uploadRetry: string;
|
|
1385
|
+
/** Dropzone copy when uploads can't run (no client / preview). */
|
|
1386
|
+
uploadsDisabled: string;
|
|
1387
|
+
/** An upload attempt failed with no actionable server message. */
|
|
1388
|
+
uploadFailed: string;
|
|
1389
|
+
/** Dropzone call to action; `multiple` is true when several files are allowed. */
|
|
1390
|
+
dropzoneTitle: (multiple: boolean) => string;
|
|
1391
|
+
/** Dropzone hint stating the per-file size limit in MB. */
|
|
1392
|
+
dropzoneHint: (maxMb: number) => string;
|
|
1393
|
+
/** A file exceeded the per-file MB limit before upload started. */
|
|
1394
|
+
fileTooLarge: (maxMb: number) => string;
|
|
1395
|
+
/** Screen-reader status: N uploads in progress. */
|
|
1396
|
+
filesUploading: (count: number) => string;
|
|
1397
|
+
/** Screen-reader status: N uploads failed. */
|
|
1398
|
+
uploadsFailed: (count: number) => string;
|
|
1399
|
+
/** Screen-reader status: N uploads completed. */
|
|
1400
|
+
filesUploaded: (count: number) => string;
|
|
1401
|
+
}
|
|
1402
|
+
declare const DEFAULT_FIELD_STRINGS: FilloFieldStrings;
|
|
1403
|
+
/** Everything the default renderers can localize — chrome + field/validation. */
|
|
1404
|
+
type FilloRendererStrings = FilloStrings & FilloFieldStrings;
|
|
1405
|
+
/** Merge overrides over the built-in chrome + field defaults. Accepts a partial
|
|
1406
|
+
* of the full renderer surface so the `strings` prop can override either set. */
|
|
1407
|
+
declare function resolveStrings(overrides?: Partial<FilloRendererStrings>): FilloRendererStrings;
|
|
1103
1408
|
|
|
1104
1409
|
/** Result of syncing a code-defined form: its canonical id, slug, and branding. */
|
|
1105
1410
|
interface SyncedForm {
|
|
1106
1411
|
formId: string;
|
|
1107
1412
|
slug: string;
|
|
1108
1413
|
branding?: FormBranding;
|
|
1414
|
+
/** Human-verification challenge to render before submit, when the LIVE form
|
|
1415
|
+
* requires one (staged changes don't gate until published). Absent = no
|
|
1416
|
+
* challenge. Carries only the PUBLIC site key. */
|
|
1417
|
+
challenge?: ChallengeConfig;
|
|
1109
1418
|
/** Lifecycle on newer servers: a draft can't accept public responses yet. */
|
|
1110
1419
|
status?: "draft" | "published";
|
|
1111
1420
|
/** Changes were staged as a draft for a human to publish. */
|
|
1112
1421
|
staged?: boolean;
|
|
1422
|
+
/** Server-authoritative live snapshot when local code is not live yet. */
|
|
1423
|
+
resolvedSchema?: FormSchema;
|
|
1424
|
+
resolvedTheme?: FormTheme | null;
|
|
1425
|
+
/** Non-fatal integration problem; resolvedSchema remains safe to render. */
|
|
1426
|
+
syncError?: {
|
|
1427
|
+
code: string;
|
|
1428
|
+
message: string;
|
|
1429
|
+
};
|
|
1113
1430
|
warning?: string;
|
|
1114
1431
|
}
|
|
1115
1432
|
/**
|
|
1116
|
-
* A form whose structure lives in user code.
|
|
1117
|
-
*
|
|
1118
|
-
*
|
|
1433
|
+
* A form whose structure lives in user code. Development and explicit
|
|
1434
|
+
* render-only usage can show it immediately; production renderers with a
|
|
1435
|
+
* publishable key first resolve the canonical form from Fillo so responses,
|
|
1436
|
+
* uploads, webhooks, and exports stay bound to the published version.
|
|
1119
1437
|
*/
|
|
1120
1438
|
interface CodeForm {
|
|
1121
1439
|
/** Stable handle, unique in the workspace. */
|
|
@@ -1136,10 +1454,16 @@ declare function isCodeForm(form: unknown): form is CodeForm;
|
|
|
1136
1454
|
/** Stable djb2 hash of a string — used to key code-form sync by content. */
|
|
1137
1455
|
declare function contentHash(input: string): string;
|
|
1138
1456
|
/**
|
|
1139
|
-
*
|
|
1140
|
-
*
|
|
1141
|
-
*
|
|
1142
|
-
|
|
1457
|
+
* Compare normalized schema JSON while ignoring object-key order (Postgres
|
|
1458
|
+
* jsonb and custom API proxies may reorder keys). Array order remains part of
|
|
1459
|
+
* the form definition because it controls pages, blocks, and options.
|
|
1460
|
+
*/
|
|
1461
|
+
declare function formSchemasEqual(left: FormSchema, right: FormSchema): boolean;
|
|
1462
|
+
/**
|
|
1463
|
+
* Resolve a code-defined form with in-flight dedupe and bounded stable-result
|
|
1464
|
+
* caching (published 1h, draft 60s). Staged/live-fallback results are evicted
|
|
1465
|
+
* once settled so an SPA can observe publication without a hard reload.
|
|
1466
|
+
* `bypassCache` forces the network for submit-time compatibility checks.
|
|
1143
1467
|
*/
|
|
1144
1468
|
declare function syncCodeForm(client: FilloClient, form: CodeForm, opts?: {
|
|
1145
1469
|
bypassCache?: boolean;
|
|
@@ -1263,4 +1587,4 @@ declare class Sha1 {
|
|
|
1263
1587
|
}
|
|
1264
1588
|
declare const sha1Base64: (bytes: Uint8Array) => string;
|
|
1265
1589
|
|
|
1266
|
-
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_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 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, type ParagraphBlock, type ParsedPhone, type PhoneCountry, type PhoneField, type ProvisionWorkspaceResult, type PublishedForm, 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, formatAnswer, formatNational, isAutoSubmitBlock, isBlockVisible, isCodeForm, isField, isFilloError, isPossiblePhone, needsExplicitSubmit, normalizeFormSchema, normalizeFormTheme, normalizeSettings, parsePhone, pipeBlock, prefillFromParams, provisionWorkspace, resolveSlotClass, resolveStrings, resolveText, responseScopeValue, schemaFromJsx, sha1Base64, shouldAutoSubmit, slotClass, syncCodeForm, toE164, validateField, validateFormSchema, validateResponse, visibleBlocks, visibleFields, when };
|
|
1590
|
+
export { type AutoSubmitContext, BLOCK_KIND_META, type BaseField, type Block, type BlockKind, CONTENT_KINDS, type ChallengeConfig, 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_CHALLENGE_MIN_SDK_VERSION, 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 JumpRule, type LinearScaleField, type MatrixField, type NextPage, 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 TrustPolicy, type UploadFileOptions, type UploadProgress, type UploadSession, type UploadStatus, type UploadTransport, type ValidationResult, type WhenBuilder, allFields, assembleForm, codeFormFromJsx, conditionsMet, contentHash, countryByDialCode, countryByIso, countryByTimeZone, createBlock, createClient, createEmptyForm, createFormController, createId, defineForm, digitsOnly, flagEmoji, formSchemasEqual, formatAnswer, formatNational, isAutoSubmitBlock, isBlockVisible, isCodeForm, isField, isFilloError, isPossiblePhone, isTerminalPage, needsExplicitSubmit, normalizeFormSchema, normalizeFormTheme, normalizeSettings, parsePhone, pipeBlock, positionPhonePopover, prefillFromParams, provisionWorkspace, reachableFieldIds, reachableFields, reachablePageIds, reachablePageSequence, resolveNextPage, resolveSlotClass, resolveStrings, resolveText, responseScopeValue, schemaFromJsx, sha1Base64, shouldAutoSubmit, slotClass, syncCodeForm, toE164, validateField, validateFormSchema, validateResponse, visibleBlocks, visibleFields, visiblePageBlocks, when };
|