@usefillo/core 0.25.0 → 0.26.1

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/dist/index.d.ts CHANGED
@@ -95,6 +95,11 @@ interface RatingField extends BaseField {
95
95
  }
96
96
  interface DateField extends BaseField {
97
97
  kind: "date";
98
+ /**
99
+ * Start on today's date — the respondent's own day, set by their device once
100
+ * the form loads (the server can't know their time zone). They can change it.
101
+ */
102
+ defaultToday?: boolean;
98
103
  }
99
104
  interface LinearScaleField extends BaseField {
100
105
  kind: "linear_scale";
@@ -300,8 +305,12 @@ interface ResponseLimit {
300
305
  * and anonymous embeds can still dedupe.
301
306
  * - "identify": the identify() respondent (HMAC-verifiable). The strong
302
307
  * path; only embedded surfaces that call identify() are recognized.
308
+ * - "email": a verified email address. On the form's Fillo link the person
309
+ * confirms their email with a 6-digit code before filling in, and the
310
+ * device stays confirmed for 30 days. Embedded forms can't show that
311
+ * step — use "identify" there.
303
312
  */
304
- by: "browser" | "field" | "identify";
313
+ by: "browser" | "field" | "identify" | "email";
305
314
  /** The email/phone field whose answer identifies the person. `by: "field"` only. */
306
315
  field?: string;
307
316
  /**
@@ -315,7 +324,8 @@ interface ResponseLimit {
315
324
  * response (the first answer stands); "update" edits it in place (re-anchored
316
325
  * to the current schema, `response.updated` webhook, previous answers
317
326
  * prefilled for a verified respondent). "update" applies to `by: "identify"`
318
- * only — a self-claim/browser must not overwrite another person's response.
327
+ * and `by: "email"` only — a self-claim/browser must not overwrite another
328
+ * person's response.
319
329
  */
320
330
  onRepeat: "keep" | "update";
321
331
  }
@@ -2249,6 +2259,15 @@ declare function isBuildTimeDevEnv(): boolean;
2249
2259
  */
2250
2260
  declare function isLikelyDevEnv(): boolean;
2251
2261
 
2262
+ /** A device's local calendar date as YYYY-MM-DD — the value a date field holds. */
2263
+ declare function localDateString(now?: Date): string;
2264
+ /**
2265
+ * Fill each unanswered date field that starts on today (`defaultToday`). Only
2266
+ * the respondent's device knows their "today" (time zone), so renderers apply
2267
+ * this in the browser after hydration, never on the server. Returns `data`
2268
+ * itself when nothing needed filling.
2269
+ */
2270
+ declare function applyDateDefaults(form: FormSchema, data: ResponseData, now?: Date): ResponseData;
2252
2271
  /**
2253
2272
  * Build initial response data from URL query parameters — Tally-style
2254
2273
  * prefilling. Hidden fields read their configured paramName; every other
@@ -2293,4 +2312,4 @@ declare class Sha1 {
2293
2312
  }
2294
2313
  declare const sha1Base64: (bytes: Uint8Array) => string;
2295
2314
 
2296
- export { type AutoSubmitContext, BLOCK_KIND_META, type BaseField, type Block, type BlockKind, CONTENT_KINDS, type CalcExpr, type CalculatedField, type ChallengeConfig, type ChallengeTheme, type CheckboxField, type ChoiceField, type CodeForm, type Condition, type ConditionOp, type ContentBlock, type ContentKind, type CreatedDraft, type CustomField, DEFAULT_FIELD_STRINGS, DEFAULT_RESPONDENT_ERROR_STRINGS, DEFAULT_STRINGS, DRAFT_KINDS, type DateField, type DividerBlock, FILLO_CALC_MIN_SDK_VERSION, FILLO_CHALLENGE_MIN_SDK_VERSION, FILLO_DATA_ATTRS, FILLO_GROUP_MIN_SDK_VERSION, 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 FormThemePalette, type GroupInstanceValue, type HeadingBlock, type HiddenField, JSX_BLOCK_COMPONENTS, JSX_BLOCK_SPECS, type JsonValue, type JsxFormMeta, type JumpRule, type LinearScaleField, MAX_FILES_PER_FIELD, type MatrixField, type NextPage, type NumberField, PHONE_COUNTRIES, PHONE_PICKER_COUNTRIES, PHONE_POPOVER_VIEWPORT_GAP, type ParagraphBlock, type ParsePhoneOptions, type ParsedPhone, type PhoneCountry, type PhoneField, type PhonePopoverPlacement, type ProvisionWorkspaceResult, type PublishedForm, REQUIRED_FIELD_MESSAGE, type RankingField, type RatingField, type RepeatingGroupField, type RespondentErrorOverrides, type RespondentErrorStrings, 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 ThemeDomAttributes, type TrustPolicy, type UploadFileOptions, type UploadProgress, type UploadSession, type UploadStatus, type UploadTransport, type ValidationResult, type WhenBuilder, allFields, assembleForm, codeFormFromJsx, computeCalculated, conditionsMet, contentHash, countryByDialCode, countryByIso, countryByTimeZone, createBlock, createClient, createEmptyForm, createFormController, createId, defineForm, digitsOnly, evaluateCalc, flagEmoji, formSchemasEqual, formatAnswer, formatGroupedNumber, formatNational, isAutoSubmitBlock, isBlockVisible, isBuildTimeDevEnv, isCodeForm, isField, isFilloError, isLikelyDevEnv, isPossiblePhone, isTerminalPage, isValidPartialNumberText, localeForNotation, needsExplicitSubmit, normalizeFormSchema, normalizeFormTheme, normalizeSettings, parseGroupedNumber, parsePhone, pipeBlock, positionPhonePopover, prefillFromParams, provisionWorkspace, radioGroupStep, reachableFieldIds, reachableFields, reachablePageIds, reachablePageSequence, requiredFieldMessage, resolveNextPage, resolveSlotClass, resolveStrings, resolveText, resolveThemeAppearance, resolveThemeDom, respondentErrorStringsFor, responseScopeValue, schemaFromJsx, sha1Base64, shouldAutoSubmit, slotClass, syncCodeForm, themeHasDarkPalette, toE164, validateField, validateFormSchema, validateResponse, visibleBlocks, visibleFields, visibleGroupChildren, visiblePageBlocks, when };
2315
+ export { type AutoSubmitContext, BLOCK_KIND_META, type BaseField, type Block, type BlockKind, CONTENT_KINDS, type CalcExpr, type CalculatedField, type ChallengeConfig, type ChallengeTheme, type CheckboxField, type ChoiceField, type CodeForm, type Condition, type ConditionOp, type ContentBlock, type ContentKind, type CreatedDraft, type CustomField, DEFAULT_FIELD_STRINGS, DEFAULT_RESPONDENT_ERROR_STRINGS, DEFAULT_STRINGS, DRAFT_KINDS, type DateField, type DividerBlock, FILLO_CALC_MIN_SDK_VERSION, FILLO_CHALLENGE_MIN_SDK_VERSION, FILLO_DATA_ATTRS, FILLO_GROUP_MIN_SDK_VERSION, 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 FormThemePalette, type GroupInstanceValue, type HeadingBlock, type HiddenField, JSX_BLOCK_COMPONENTS, JSX_BLOCK_SPECS, type JsonValue, type JsxFormMeta, type JumpRule, type LinearScaleField, MAX_FILES_PER_FIELD, type MatrixField, type NextPage, type NumberField, PHONE_COUNTRIES, PHONE_PICKER_COUNTRIES, PHONE_POPOVER_VIEWPORT_GAP, type ParagraphBlock, type ParsePhoneOptions, type ParsedPhone, type PhoneCountry, type PhoneField, type PhonePopoverPlacement, type ProvisionWorkspaceResult, type PublishedForm, REQUIRED_FIELD_MESSAGE, type RankingField, type RatingField, type RepeatingGroupField, type RespondentErrorOverrides, type RespondentErrorStrings, 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 ThemeDomAttributes, type TrustPolicy, type UploadFileOptions, type UploadProgress, type UploadSession, type UploadStatus, type UploadTransport, type ValidationResult, type WhenBuilder, allFields, applyDateDefaults, assembleForm, codeFormFromJsx, computeCalculated, conditionsMet, contentHash, countryByDialCode, countryByIso, countryByTimeZone, createBlock, createClient, createEmptyForm, createFormController, createId, defineForm, digitsOnly, evaluateCalc, flagEmoji, formSchemasEqual, formatAnswer, formatGroupedNumber, formatNational, isAutoSubmitBlock, isBlockVisible, isBuildTimeDevEnv, isCodeForm, isField, isFilloError, isLikelyDevEnv, isPossiblePhone, isTerminalPage, isValidPartialNumberText, localDateString, localeForNotation, needsExplicitSubmit, normalizeFormSchema, normalizeFormTheme, normalizeSettings, parseGroupedNumber, parsePhone, pipeBlock, positionPhonePopover, prefillFromParams, provisionWorkspace, radioGroupStep, reachableFieldIds, reachableFields, reachablePageIds, reachablePageSequence, requiredFieldMessage, resolveNextPage, resolveSlotClass, resolveStrings, resolveText, resolveThemeAppearance, resolveThemeDom, respondentErrorStringsFor, responseScopeValue, schemaFromJsx, sha1Base64, shouldAutoSubmit, slotClass, syncCodeForm, themeHasDarkPalette, toE164, validateField, validateFormSchema, validateResponse, visibleBlocks, visibleFields, visibleGroupChildren, visiblePageBlocks, when };
package/dist/index.js CHANGED
@@ -1114,7 +1114,7 @@ var schemaShape = z2.object({
1114
1114
  });
1115
1115
  var MAX_SCHEMA_VERSION = 1;
1116
1116
  var FILLO_SCHEMA_VERSION = 1;
1117
- var FILLO_SDK_VERSION = true ? "0.25.0" : "0.0.0-dev";
1117
+ var FILLO_SDK_VERSION = true ? "0.26.1" : "0.0.0-dev";
1118
1118
  var FILLO_MIN_SDK_VERSION = "0.4.0";
1119
1119
  var FILLO_CHALLENGE_MIN_SDK_VERSION = "0.9.0";
1120
1120
  var FILLO_CALC_MIN_SDK_VERSION = "0.11.0";
@@ -1560,12 +1560,12 @@ function normalizeUrl(value) {
1560
1560
  function normalizeResponseLimit(value) {
1561
1561
  if (!value || typeof value !== "object") return void 0;
1562
1562
  const rec = value;
1563
- const by = rec.by === "browser" || rec.by === "field" || rec.by === "identify" ? rec.by : void 0;
1563
+ const by = rec.by === "browser" || rec.by === "field" || rec.by === "identify" || rec.by === "email" ? rec.by : void 0;
1564
1564
  if (!by) return void 0;
1565
1565
  const field2 = by === "field" ? optionalStr(rec.field, 128) : void 0;
1566
1566
  if (by === "field" && !field2) return void 0;
1567
1567
  const scopeField = optionalStr(rec.scopeField, 128);
1568
- const onRepeat = rec.onRepeat === "update" && by === "identify" ? "update" : "keep";
1568
+ const onRepeat = rec.onRepeat === "update" && (by === "identify" || by === "email") ? "update" : "keep";
1569
1569
  return {
1570
1570
  by,
1571
1571
  ...field2 ? { field: field2 } : {},
@@ -1675,8 +1675,12 @@ function normalizeBlock(input) {
1675
1675
  });
1676
1676
  }
1677
1677
  case "signature":
1678
- case "date":
1679
1678
  return cleanObject(baseField(rec, kind));
1679
+ case "date":
1680
+ return cleanObject({
1681
+ ...baseField(rec, kind),
1682
+ defaultToday: rec.defaultToday === true ? true : void 0
1683
+ });
1680
1684
  case "rating": {
1681
1685
  const max = int(rec.max, 1, 10, 5);
1682
1686
  return cleanObject({
@@ -3241,6 +3245,20 @@ function parseDecimal(raw) {
3241
3245
  const n = Number(s);
3242
3246
  return Number.isFinite(n) ? n : null;
3243
3247
  }
3248
+ function localDateString(now = /* @__PURE__ */ new Date()) {
3249
+ const month = String(now.getMonth() + 1).padStart(2, "0");
3250
+ const day = String(now.getDate()).padStart(2, "0");
3251
+ return `${now.getFullYear()}-${month}-${day}`;
3252
+ }
3253
+ function applyDateDefaults(form, data, now = /* @__PURE__ */ new Date()) {
3254
+ let next = null;
3255
+ for (const field2 of allFields(form)) {
3256
+ if (field2.kind !== "date" || !field2.defaultToday || data[field2.id] !== void 0) continue;
3257
+ next = next ?? { ...data };
3258
+ next[field2.id] = localDateString(now);
3259
+ }
3260
+ return next ?? data;
3261
+ }
3244
3262
  function prefillFromParams(form, params) {
3245
3263
  const data = {};
3246
3264
  for (const field2 of allFields(form)) {
@@ -3518,6 +3536,11 @@ function createFormController(options2) {
3518
3536
  notify();
3519
3537
  }
3520
3538
  }
3539
+ const withDates = applyDateDefaults(form, data);
3540
+ if (withDates !== data && status === "idle") {
3541
+ data = computeCalculated(form, withDates);
3542
+ notify();
3543
+ }
3521
3544
  if (status === "idle" && hasSubmittedOnce(form, formId, data)) {
3522
3545
  status = "submitted";
3523
3546
  restoredSubmission = true;
@@ -4053,6 +4076,7 @@ function createFormController(options2) {
4053
4076
  if (data[key] === void 0) data[key] = value;
4054
4077
  }
4055
4078
  }
4079
+ data = applyDateDefaults(form, data);
4056
4080
  data = computeCalculated(form, data);
4057
4081
  errors = {};
4058
4082
  pageIndex = 0;
@@ -4490,7 +4514,7 @@ var JSX_BLOCK_SPECS = [
4490
4514
  field("Ranking", "ranking", ["options"], { optionChildren: true }),
4491
4515
  field("Matrix", "matrix", ["rows", "columns"]),
4492
4516
  field("Signature", "signature", []),
4493
- field("Date", "date", []),
4517
+ field("Date", "date", ["defaultToday"]),
4494
4518
  field("FileUpload", "file_upload", ["maxFiles", "maxFileSizeMb", "accept"]),
4495
4519
  field("Hidden", "hidden", ["paramName", "defaultValue"]),
4496
4520
  field("Calculated", "calculated", ["calc", "decimals", "prefix", "suffix"]),
@@ -4883,6 +4907,7 @@ export {
4883
4907
  REQUIRED_FIELD_MESSAGE,
4884
4908
  Sha1,
4885
4909
  allFields,
4910
+ applyDateDefaults,
4886
4911
  assembleForm,
4887
4912
  codeFormFromJsx,
4888
4913
  computeCalculated,
@@ -4914,6 +4939,7 @@ export {
4914
4939
  isPossiblePhone,
4915
4940
  isTerminalPage,
4916
4941
  isValidPartialNumberText,
4942
+ localDateString,
4917
4943
  localeForNotation,
4918
4944
  needsExplicitSubmit,
4919
4945
  normalizeFormSchema,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@usefillo/core",
3
- "version": "0.25.0",
3
+ "version": "0.26.1",
4
4
  "description": "Form schema, validation, logic engine and JS client for Fillo. Framework-agnostic.",
5
5
  "license": "MIT",
6
6
  "keywords": [