@usefillo/core 0.7.0 → 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 CHANGED
@@ -4,7 +4,7 @@ The framework-agnostic core of [Fillo](https://fillo.so) — forms that render *
4
4
 
5
5
  ### 📚 Full documentation → **[fillo.so/docs](https://fillo.so/docs)**
6
6
 
7
- This package holds the shared foundation: the form schema, validation, the conditional-logic engine, response prefill/piping, and a JS client with a resumable upload protocol. It has **zero framework dependencies**.
7
+ This package holds the shared foundation: the form schema, validation, the conditional-logic engine, response prefill/piping, and a JS client for provider-aware browser-direct uploads, with resume support where the storage provider offers it. It has **zero framework dependencies**.
8
8
 
9
9
  Most apps don't install this directly — you install a renderer (**[@usefillo/react](https://www.npmjs.com/package/@usefillo/react)** or **[@usefillo/dom](https://www.npmjs.com/package/@usefillo/dom)**), which re-exports everything here you need for embedding. Reach for `@usefillo/core` when you're building your own renderer or working with forms on the server.
10
10
 
@@ -15,7 +15,7 @@ npm i @usefillo/core
15
15
  ```ts
16
16
  import { createClient, defineForm, validateResponse, visibleBlocks } from "@usefillo/core";
17
17
 
18
- const client = createClient({ key: "pk_live_…" }); // for syncing code-defined forms
18
+ const client = createClient({ key: "pk_…" }); // for syncing code-defined forms
19
19
 
20
20
  const form = defineForm({
21
21
  id: "cust-feedback",
@@ -39,7 +39,7 @@ Key exports: `createClient` / `FilloClient`, `defineForm`, `validateResponse`, `
39
39
 
40
40
  MIT licensed.
41
41
 
42
- ## 0.6.0 surface
42
+ ## Additional authoring surface
43
43
 
44
44
  Framework-neutral pieces the renderers share: `defineForm` / `schemaFromJsx`
45
45
  (the JSX compiler), `when()` condition builder, the `FilloAppearance` styling
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";
@@ -291,6 +295,10 @@ type UploadStatus = "pending" | "uploading" | "complete" | "aborted";
291
295
  * - "gdrive": direct to a Google Drive resumable session URL (Content-Range
292
296
  * protocol).
293
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.
294
302
  * - "box": direct to Box with a folder-scoped upload token — small files via a
295
303
  * single multipart POST, large files via Box's chunked session (the client
296
304
  * computes the SHA-1 digests Box requires). The server commits/verifies in the
@@ -302,6 +310,8 @@ type UploadTransport = {
302
310
  } | {
303
311
  type: "s3-put";
304
312
  uploadUrl: string;
313
+ } | {
314
+ type: "s3-multipart";
305
315
  } | {
306
316
  type: "box";
307
317
  mode: "simple";
@@ -344,6 +354,19 @@ interface UploadSession {
344
354
  /** All conditions must hold (AND). No conditions = visible. */
345
355
  declare function isBlockVisible(block: Block, data: ResponseData): boolean;
346
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[];
347
370
  /** Every field in the form (across pages), in order. */
348
371
  declare function allFields(form: FormSchema): Field[];
349
372
  /**
@@ -376,6 +399,16 @@ declare function validateResponse(form: FormSchema, data: ResponseData): Validat
376
399
  declare const FILLO_SCHEMA_VERSION: 1;
377
400
  /** Injected from package.json at build time (tsup define) — never hand-edited. */
378
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";
379
412
  declare function normalizeSettings(value: unknown): FormSettings;
380
413
  interface SchemaValidationResult {
381
414
  ok: boolean;
@@ -457,6 +490,18 @@ declare function parsePhone(value: string, fallback?: PhoneCountry): ParsedPhone
457
490
  * validation. `country` (when known) tightens the accepted lengths.
458
491
  */
459
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;
460
505
 
461
506
  /** Display metadata for every block kind — drives the builder palette. */
462
507
  declare const BLOCK_KIND_META: Record<BlockKind, {
@@ -491,6 +536,7 @@ interface FieldSpec {
491
536
  max?: number;
492
537
  minLabel?: string;
493
538
  maxLabel?: string;
539
+ insightsMetric?: "csat" | "nps";
494
540
  rows?: string[];
495
541
  columns?: string[];
496
542
  placeholder?: string;
@@ -656,14 +702,23 @@ interface UploadFileOptions {
656
702
  sessionId?: string;
657
703
  /** Ownership token for the resumed session (from the original create call). */
658
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;
659
710
  }
660
711
  declare class FilloError extends Error {
661
712
  status?: number | undefined;
662
713
  /** Server-suggested wait (from a 429's Retry-After header), seconds. */
663
714
  retryAfterSec?: number | undefined;
715
+ /** Stable machine-readable API error code, when the server provides one. */
716
+ code?: string | undefined;
664
717
  constructor(message: string, status?: number | undefined,
665
718
  /** Server-suggested wait (from a 429's Retry-After header), seconds. */
666
- retryAfterSec?: number | undefined);
719
+ retryAfterSec?: number | undefined,
720
+ /** Stable machine-readable API error code, when the server provides one. */
721
+ code?: string | undefined);
667
722
  }
668
723
  /** Duck-typed — `instanceof` breaks when two SDK copies end up in one bundle. */
669
724
  declare function isFilloError(err: unknown): err is FilloError;
@@ -675,6 +730,17 @@ interface SyncFormResult {
675
730
  status?: "draft" | "published";
676
731
  /** Changes were staged as a draft for a human to publish. */
677
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
+ };
678
744
  warning?: string;
679
745
  }
680
746
  declare class FilloClient {
@@ -689,8 +755,10 @@ declare class FilloClient {
689
755
  /** Fetch a published form definition by id or slug. */
690
756
  getForm(idOrSlug: string): Promise<PublishedForm>;
691
757
  /**
692
- * Upsert a code-defined form into the workspace identified by the client's
693
- * publishable key. Returns the canonical form id used for submissions.
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.
694
762
  */
695
763
  syncForm(handle: string, schema: FormSchema, theme?: FormTheme | null): Promise<SyncFormResult>;
696
764
  /** Submit a response. Returns per-field errors instead of throwing on validation failure. */
@@ -700,8 +768,14 @@ declare class FilloClient {
700
768
  * used to prefill their answers for editing. Requires a VERIFIED identity
701
769
  * ({id, hash}); anything else 404s (returned as null), because an
702
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.
703
777
  */
704
- fetchOwnResponse(formId: string, respondent: FilloRespondent): Promise<{
778
+ fetchOwnResponse(formId: string, respondent: FilloRespondent, scopeValue?: string): Promise<{
705
779
  responseId: string;
706
780
  data: ResponseData;
707
781
  } | null>;
@@ -743,13 +817,12 @@ declare class FilloClient {
743
817
  /** Discard a draft (the "Start over" path). */
744
818
  deleteDraft(draftId: string, token: string): Promise<void>;
745
819
  /** Current state of an upload session — used to resume after interruption. */
746
- getUploadSession(sessionId: string, token?: string): Promise<UploadSession>;
820
+ getUploadSession(sessionId: string, token?: string, signal?: AbortSignal): Promise<UploadSession>;
747
821
  /**
748
- * Resumable chunked upload. Creates (or resumes) a session, streams the file
749
- * chunk by chunk with progress callbacks, and finalizes into a FileValue that
750
- * goes into the response data. Survives flaky connections: each chunk is
751
- * retried, and on repeated failure the true offset is re-queried so no byte
752
- * 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.
753
826
  *
754
827
  * Depending on the form's storage settings the server picks a transport:
755
828
  * direct-to-Google-Drive resumable
@@ -768,7 +841,7 @@ declare class FilloClient {
768
841
  /**
769
842
  * Caller signal (if any) combined with a fresh per-request timeout. Created per
770
843
  * fetch so each retry attempt gets its own deadline; the caller's own abort
771
- * still drives the resumable-upload cancel semantics.
844
+ * still drives upload cancellation across every provider transport.
772
845
  */
773
846
  private uploadSignal;
774
847
  /** Retry a request with exponential backoff; never retries an aborted upload. */
@@ -780,6 +853,13 @@ declare class FilloClient {
780
853
  * queries Drive for the authoritative offset).
781
854
  */
782
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;
783
863
  /**
784
864
  * S3-compatible single PUT to a presigned URL — bytes go straight to the
785
865
  * bucket. Not resumable (S3 single PUT is atomic), but retried on failure.
@@ -791,13 +871,13 @@ interface ProvisionWorkspaceResult {
791
871
  /** Publishable key (pk_…) for the new workspace. Pass to createClient({ key }). */
792
872
  key: string;
793
873
  organizationId: string;
794
- /** A claim link was emailed here so the owner can take ownership later. */
874
+ /** The private workspace link is emailed directly; `url` stays null. */
795
875
  claim: {
796
876
  url: string | null;
797
877
  email: string | null;
798
878
  sent: boolean;
799
879
  };
800
- /** Caps applied until the workspace is claimed. */
880
+ /** Caps applied until the workspace is saved to an account. */
801
881
  limits: {
802
882
  responses: number;
803
883
  expiresAt: string;
@@ -805,9 +885,9 @@ interface ProvisionWorkspaceResult {
805
885
  }
806
886
  /**
807
887
  * 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 claim link is
809
- * emailed to `email`; until someone claims it the workspace runs as a capped
810
- * 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,
811
891
  * e.g. a coding agent wiring Fillo into an app during integration.
812
892
  *
813
893
  * const { key } = await provisionWorkspace({ email: "you@co.com" });
@@ -853,10 +933,10 @@ interface FormControllerOptions {
853
933
  */
854
934
  surface?: "default" | "headless";
855
935
  /**
856
- * Resolve the submission target at submit time when `formId` is still
857
- * unset — e.g. re-run a code-form sync that failed at mount. Answers are
858
- * held (never dropped) while it runs; failure sets `submitError` and the
859
- * 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.
860
940
  */
861
941
  resolveFormId?: () => Promise<string>;
862
942
  /**
@@ -904,6 +984,27 @@ interface FormControllerState {
904
984
  * show an "updating your earlier response" notice.
905
985
  */
906
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;
907
1008
  }
908
1009
  interface FormController {
909
1010
  /** Stable snapshot — same reference until something changes (safe for useSyncExternalStore). */
@@ -1061,10 +1162,23 @@ declare const FILLO_THEME_VARS: readonly [{
1061
1162
  }];
1062
1163
 
1063
1164
  /**
1064
- * Every visitor-facing string the default renderers emit, overridable as a
1065
- * unit so a localized site never shows stray English at the submit moment.
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.
1066
1174
  * Schema-authored text (labels, descriptions, success copy set in settings)
1067
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.
1068
1182
  */
1069
1183
  interface FilloStrings {
1070
1184
  back: string;
@@ -1099,7 +1213,45 @@ interface FilloStrings {
1099
1213
  resumeStartOver: string;
1100
1214
  }
1101
1215
  declare const DEFAULT_STRINGS: FilloStrings;
1102
- declare function resolveStrings(overrides?: Partial<FilloStrings>): FilloStrings;
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;
1103
1255
 
1104
1256
  /** Result of syncing a code-defined form: its canonical id, slug, and branding. */
1105
1257
  interface SyncedForm {
@@ -1110,12 +1262,21 @@ interface SyncedForm {
1110
1262
  status?: "draft" | "published";
1111
1263
  /** Changes were staged as a draft for a human to publish. */
1112
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
+ };
1113
1273
  warning?: string;
1114
1274
  }
1115
1275
  /**
1116
- * A form whose structure lives in user code. Framework renderers can show it
1117
- * immediately, then sync it into a Fillo workspace when a publishable key is
1118
- * present so responses, uploads, webhooks, and exports work normally.
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.
1119
1280
  */
1120
1281
  interface CodeForm {
1121
1282
  /** Stable handle, unique in the workspace. */
@@ -1136,10 +1297,16 @@ declare function isCodeForm(form: unknown): form is CodeForm;
1136
1297
  /** Stable djb2 hash of a string — used to key code-form sync by content. */
1137
1298
  declare function contentHash(input: string): string;
1138
1299
  /**
1139
- * Sync a code-defined form into a workspace at most once per session for the
1140
- * same client, handle, schema, and theme. `bypassCache` forces the network —
1141
- * used by submit-time resolution, where a stale cached formId must not be
1142
- * trusted over a fresh sync.
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.
1143
1310
  */
1144
1311
  declare function syncCodeForm(client: FilloClient, form: CodeForm, opts?: {
1145
1312
  bypassCache?: boolean;
@@ -1263,4 +1430,4 @@ declare class Sha1 {
1263
1430
  }
1264
1431
  declare const sha1Base64: (bytes: Uint8Array) => string;
1265
1432
 
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 };
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 };