@marktiderman/genesis-forms 0.4.2 → 0.6.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 +195 -0
- package/dist/destinations.cjs +147 -7
- package/dist/destinations.cjs.map +1 -1
- package/dist/destinations.d.cts +1 -1
- package/dist/destinations.d.ts +1 -1
- package/dist/destinations.js +147 -7
- package/dist/destinations.js.map +1 -1
- package/dist/{engine-BkNuzlna.d.cts → engine-CpfOz8FN.d.ts} +33 -3
- package/dist/{engine-Dz9J5ej2.d.ts → engine-DC4YTPdr.d.cts} +33 -3
- package/dist/index.cjs +734 -69
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +142 -75
- package/dist/index.d.ts +142 -75
- package/dist/index.js +687 -70
- package/dist/index.js.map +1 -1
- package/dist/server.cjs +721 -26
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +201 -4
- package/dist/server.d.ts +201 -4
- package/dist/server.js +702 -27
- package/dist/server.js.map +1 -1
- package/dist/testing.cjs +494 -26
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.cts +4 -4
- package/dist/testing.d.ts +4 -4
- package/dist/testing.js +494 -26
- package/dist/testing.js.map +1 -1
- package/dist/{types-BBKBQ8sp.d.cts → types-oAckGR_Z.d.cts} +31 -1
- package/dist/{types-BBKBQ8sp.d.ts → types-oAckGR_Z.d.ts} +31 -1
- package/dist/validate-B5WKHbst.d.cts +322 -0
- package/dist/validate-GpTXPwyl.d.ts +322 -0
- package/package.json +1 -1
- package/dist/validate-BXXqi0fq.d.cts +0 -30
- package/dist/validate-BjNwF1UE.d.ts +0 -30
package/dist/index.d.cts
CHANGED
|
@@ -1,9 +1,68 @@
|
|
|
1
|
-
import { a as FieldBlock, C as ContentBlock, P as PageBreakBlock, F as FormDefinition, H as HiddenInput, b as FormLayout, L as LogicRule, E as Ending, c as FormSettings,
|
|
2
|
-
export { e as FormEvent, f as Operand } from './types-
|
|
3
|
-
import { F as FormEngine } from './engine-
|
|
4
|
-
export { C as CreateFormOptions,
|
|
5
|
-
import { F as FieldValidator } from './validate-
|
|
6
|
-
export { R as REQUIRED_MESSAGE, S as StandardSchemaV1, v as validateField } from './validate-
|
|
1
|
+
import { a as FieldBlock, J as Json, C as ContentBlock, P as PageBreakBlock, O as OptionsSource, F as FormDefinition, H as HiddenInput, b as FormLayout, L as LogicRule, E as Ending, c as FormSettings, d as Condition, B as Block } from './types-oAckGR_Z.cjs';
|
|
2
|
+
export { e as FormEvent, f as Operand, g as Operator } from './types-oAckGR_Z.cjs';
|
|
3
|
+
import { F as FormEngine, a as FormState } from './engine-DC4YTPdr.cjs';
|
|
4
|
+
export { C as CreateFormOptions, c as createForm, i as isFormEvent, b as isJson, r as replay } from './engine-DC4YTPdr.cjs';
|
|
5
|
+
import { F as FieldValidator } from './validate-B5WKHbst.cjs';
|
|
6
|
+
export { A as AnswerSnapshot, C as CHOICE_FIELD_TYPES, a as ChoiceOption, b as FieldTypeManifest, H as HostOptions, L as LinkParams, M as MAX_PREFILL_PARAM_LENGTH, O as OPTION_LIMITS, c as OTHER_MAX_LENGTH, d as OptionSnapshot, P as PrefillSetting, e as PrefillState, R as REQUIRED_MESSAGE, f as RestoredAnswers, S as SEARCHABLE_OPTION_COUNT, g as StandardSchemaV1, h as answerSnapshots, i as answersFromSnapshots, j as answersOnPath, k as choiceOptions, l as clearFilteredAnswers, m as dateLimits, n as filteredChoiceError, o as getFieldType, p as hasOptionFilters, q as hiddenByPrefill, r as isEmptyValue, s as isHttpsUrl, t as isIsoDate, u as isOtherValue, v as isPrefillParam, w as isSearchable, x as isSensitive, y as listFieldTypes, z as normalizeValue, B as numberLimits, D as optionFilter, E as optionJson, G as optionMatches, I as optionsSource, J as otherOption, K as prefillFromLink, N as prefillSetting, Q as ratingDisplay, T as readOption, U as registerFieldType, V as respondentPath, W as scaleLabels, X as searchOptions, Y as summarizeValue, Z as validateField, _ as visibleOptions, $ as withHostOptions } from './validate-B5WKHbst.cjs';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* The `photo` field type: a respondent attaches up to a few photos, such as a
|
|
10
|
+
* picture of broken equipment. The answer holds references the host's storage
|
|
11
|
+
* handed back (`PhotoRef`), never the bytes: the renderer uploads through the
|
|
12
|
+
* host (`onUpload` on genesis-forms-web's `Form`), so the engine and the
|
|
13
|
+
* server stay storage-agnostic. A host's server should check that each
|
|
14
|
+
* reference is a file it stored for this respondent before saving.
|
|
15
|
+
*
|
|
16
|
+
* Opt-in in a builder palette (`UPLOAD_FIELD_TYPES`), since a host must be
|
|
17
|
+
* able to store the files.
|
|
18
|
+
*/
|
|
19
|
+
declare const PHOTO_TYPE = "photo";
|
|
20
|
+
/** Field types that need the host to store files; a builder offers them only when the host names them. */
|
|
21
|
+
declare const UPLOAD_FIELD_TYPES: readonly ["photo"];
|
|
22
|
+
/** One stored photo, as the host's upload returned it. */
|
|
23
|
+
type PhotoRef = {
|
|
24
|
+
/** The host's id for the stored file. */
|
|
25
|
+
id: string;
|
|
26
|
+
/** The file's name on the respondent's device. */
|
|
27
|
+
name: string;
|
|
28
|
+
/** Its MIME type, such as `image/jpeg`. */
|
|
29
|
+
type: string;
|
|
30
|
+
/** Bytes. */
|
|
31
|
+
size: number;
|
|
32
|
+
};
|
|
33
|
+
type PhotoFormat = "jpeg" | "png" | "heic" | "webp";
|
|
34
|
+
/** The MIME types each format covers. */
|
|
35
|
+
declare const PHOTO_FORMATS: Record<PhotoFormat, readonly string[]>;
|
|
36
|
+
declare const DEFAULT_PHOTO_FILES = 3;
|
|
37
|
+
declare const MAX_PHOTO_FILES = 5;
|
|
38
|
+
declare const DEFAULT_PHOTO_SIZE_MB = 10;
|
|
39
|
+
declare const MAX_PHOTO_SIZE_MB = 25;
|
|
40
|
+
/** The longest reference id and file name a photo answer may carry. */
|
|
41
|
+
declare const MAX_PHOTO_ID_LENGTH = 200;
|
|
42
|
+
declare const MAX_PHOTO_NAME_LENGTH = 255;
|
|
43
|
+
declare const isPhotoFormat: (v: unknown) => v is PhotoFormat;
|
|
44
|
+
interface PhotoLimits {
|
|
45
|
+
maxFiles: number;
|
|
46
|
+
maxSizeMb: number;
|
|
47
|
+
maxBytes: number;
|
|
48
|
+
formats: PhotoFormat[];
|
|
49
|
+
/** Every MIME type the formats cover. */
|
|
50
|
+
mimeTypes: string[];
|
|
51
|
+
}
|
|
52
|
+
/** A photo field's limits; a prop that is missing or out of range uses its default. */
|
|
53
|
+
declare function photoLimits(field: FieldBlock): PhotoLimits;
|
|
54
|
+
/** Whether `v` has a photo reference's shape (any type and size). */
|
|
55
|
+
declare function isPhotoRef(v: unknown): v is PhotoRef;
|
|
56
|
+
/** The well-formed references in a photo answer, as `{ id, name, type, size }` only. */
|
|
57
|
+
declare function photoRefs(value: Json | undefined): PhotoRef[];
|
|
58
|
+
/** "JPEG, PNG or WebP". */
|
|
59
|
+
declare function photoFormatList(formats: readonly PhotoFormat[]): string;
|
|
60
|
+
/** The message for a file of a type the field doesn't take. */
|
|
61
|
+
declare const photoTypeMessage: (field: FieldBlock) => string;
|
|
62
|
+
/** The message for a file over the field's size limit. */
|
|
63
|
+
declare const photoSizeMessage: (field: FieldBlock) => string;
|
|
64
|
+
/** The message for more photos than the field takes. */
|
|
65
|
+
declare const photoCountMessage: (field: FieldBlock) => string;
|
|
7
66
|
|
|
8
67
|
/** A field block that remembers its key and value type, for answer inference. */
|
|
9
68
|
type FieldSpec<K extends string = string, V = unknown> = FieldBlock & {
|
|
@@ -24,10 +83,38 @@ interface FieldOptions {
|
|
|
24
83
|
id?: string | undefined;
|
|
25
84
|
}
|
|
26
85
|
interface ChoiceFieldOptions<O extends string> extends FieldOptions {
|
|
27
|
-
options
|
|
86
|
+
/** The options. Optional only with `optionsFrom`, whose options follow these. */
|
|
87
|
+
options?: readonly {
|
|
28
88
|
value: O;
|
|
29
89
|
label?: string;
|
|
30
|
-
|
|
90
|
+
description?: string;
|
|
91
|
+
image?: string;
|
|
92
|
+
attributes?: Record<string, string | string[]>;
|
|
93
|
+
}[] | undefined;
|
|
94
|
+
/**
|
|
95
|
+
* Options the app showing the form supplies, by key (`OptionsSource`), such
|
|
96
|
+
* as `{ source: "host", key: "coaches" }`; pass the lists as `hostOptions`
|
|
97
|
+
* to `createForm` and `validateSubmission`.
|
|
98
|
+
*/
|
|
99
|
+
optionsFrom?: OptionsSource | undefined;
|
|
100
|
+
/**
|
|
101
|
+
* An "Other" option the respondent fills in (`true`, or `{ label }` to name it): their text is
|
|
102
|
+
* the answer (one more item on a multiple choice). See `otherOption`.
|
|
103
|
+
*/
|
|
104
|
+
other?: boolean | {
|
|
105
|
+
label?: string;
|
|
106
|
+
} | undefined;
|
|
107
|
+
/**
|
|
108
|
+
* Preselect from the link the form was opened from: `{ param: "location" }` takes
|
|
109
|
+
* `?location=…` when it is one of the options; `hideWhenPrefilled` then skips the question.
|
|
110
|
+
* See `prefillFromLink`.
|
|
111
|
+
*/
|
|
112
|
+
prefill?: {
|
|
113
|
+
param: string;
|
|
114
|
+
hideWhenPrefilled?: boolean;
|
|
115
|
+
} | undefined;
|
|
116
|
+
/** A search box over the options: true or false, or by default when there are more than 10 (`isSearchable`). */
|
|
117
|
+
searchable?: boolean | undefined;
|
|
31
118
|
}
|
|
32
119
|
interface HiddenOptions {
|
|
33
120
|
source?: HiddenInput["source"] | undefined;
|
|
@@ -137,6 +224,16 @@ declare const f: {
|
|
|
137
224
|
quote: string;
|
|
138
225
|
note: string;
|
|
139
226
|
}[]>;
|
|
227
|
+
/**
|
|
228
|
+
* Up to a few photos (a picture of broken equipment). The answer holds the
|
|
229
|
+
* references the host's upload returned, never the bytes; `formats` from
|
|
230
|
+
* jpeg, png, heic and webp (default all four).
|
|
231
|
+
*/
|
|
232
|
+
photo: <K extends string>(key: K, o: FieldOptions & {
|
|
233
|
+
maxFiles?: number | undefined;
|
|
234
|
+
maxSizeMb?: number | undefined;
|
|
235
|
+
formats?: readonly PhotoFormat[] | undefined;
|
|
236
|
+
}) => FieldSpec<K, PhotoRef[]>;
|
|
140
237
|
/** Any registered field type, including plugins. */
|
|
141
238
|
custom: <K extends string, V = Json>(type: string, key: K, o: FieldOptions & {
|
|
142
239
|
props?: Record<string, Json>;
|
|
@@ -333,76 +430,38 @@ declare function computePath(def: FormDefinition, scope: EvalScope): PathResult;
|
|
|
333
430
|
declare function ruleVisible(def: FormDefinition, blockId: string, scope: EvalScope): boolean;
|
|
334
431
|
|
|
335
432
|
/**
|
|
336
|
-
*
|
|
337
|
-
*
|
|
433
|
+
* How far a respondent has got, for saving answers as they go
|
|
434
|
+
* (`settings.saveProgress`) and for drop-off by question. Pure: reads a form's
|
|
435
|
+
* state, never changes it.
|
|
338
436
|
*/
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
label: string;
|
|
342
|
-
category: "text" | "choice" | "scale" | "date" | "media" | "advanced";
|
|
343
|
-
/** `json: false` types must convert, so drafts and server replay never lose an answer. */
|
|
344
|
-
value: {
|
|
345
|
-
json: true;
|
|
346
|
-
} | {
|
|
347
|
-
json: false;
|
|
348
|
-
serialize: (value: unknown) => Json;
|
|
349
|
-
deserialize: (json: Json) => unknown;
|
|
350
|
-
};
|
|
351
|
-
operators: Operator[];
|
|
352
|
-
a11y: {
|
|
353
|
-
semantics: "control" | "group";
|
|
354
|
-
/** The HTML `autocomplete` token, such as `"email"` or `"tel"`. */
|
|
355
|
-
autocomplete?: string;
|
|
356
|
-
/** The HTML `inputmode` hint for on-screen keyboards, such as `"email"` or `"tel"`. */
|
|
357
|
-
inputMode?: "text" | "email" | "tel" | "numeric" | "decimal" | "url" | "search";
|
|
358
|
-
};
|
|
359
|
-
isEmpty?: (value: Json | undefined) => boolean;
|
|
360
|
-
/** Return an error message, or null when the (non-empty) value is valid. */
|
|
361
|
-
validate?: (value: Json, field: FieldBlock) => string | null;
|
|
362
|
-
/** Plain text for recall, exports and emails. */
|
|
363
|
-
summarize?: (value: Json, field: FieldBlock) => string;
|
|
437
|
+
|
|
438
|
+
interface FormProgress {
|
|
364
439
|
/**
|
|
365
|
-
* The
|
|
366
|
-
*
|
|
440
|
+
* The furthest block reached, 1-based, on the path as it is now (logic can
|
|
441
|
+
* lengthen or shorten the path, so store `fieldId`, not this). 0 before any.
|
|
367
442
|
*/
|
|
368
|
-
|
|
369
|
-
/**
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
declare function normalizeValue(value: Json, field: FieldBlock): Json;
|
|
378
|
-
/** Whether a block holds personal or secret data: `sensitive: true`, or the `props.sensitive: true` alias. */
|
|
379
|
-
declare function isSensitive(block: Block): boolean;
|
|
380
|
-
declare function summarizeValue(value: Json | undefined, field: FieldBlock): string;
|
|
381
|
-
interface ChoiceOption {
|
|
382
|
-
value: string;
|
|
383
|
-
label?: string;
|
|
443
|
+
step: number;
|
|
444
|
+
/** How many blocks the path has now. */
|
|
445
|
+
total: number;
|
|
446
|
+
/**
|
|
447
|
+
* The id of the furthest question (field) reached: shown in focus layout, or
|
|
448
|
+
* answered. Null before any. A content block on the way is not a question,
|
|
449
|
+
* so the question before it counts.
|
|
450
|
+
*/
|
|
451
|
+
fieldId: string | null;
|
|
384
452
|
}
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
/**
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
step?: number;
|
|
398
|
-
};
|
|
399
|
-
/** `YYYY-MM-DD`, a real calendar day (no 2026-02-30), years 0001 to 9999. */
|
|
400
|
-
declare function isIsoDate(value: string): boolean;
|
|
401
|
-
/** A `date` field's earliest and latest days (`YYYY-MM-DD`), when set. */
|
|
402
|
-
declare function dateLimits(field: FieldBlock): {
|
|
403
|
-
min?: string;
|
|
404
|
-
max?: string;
|
|
405
|
-
};
|
|
453
|
+
/**
|
|
454
|
+
* The furthest block on the path the respondent has reached: the one on screen,
|
|
455
|
+
* one they went back from, or (in classic layout, where every question shows at
|
|
456
|
+
* once) the last one they answered. Null when the path is empty.
|
|
457
|
+
*/
|
|
458
|
+
declare function furthestReached(state: FormState, definition: FormDefinition): string | null;
|
|
459
|
+
/**
|
|
460
|
+
* Where the respondent is: the furthest step and the furthest question reached.
|
|
461
|
+
* What genesis-forms-web's `onProgress` passes; `engine.answers()` has the
|
|
462
|
+
* answers so far.
|
|
463
|
+
*/
|
|
464
|
+
declare function formProgress(engine: Pick<FormEngine, "definition" | "getState">): FormProgress;
|
|
406
465
|
|
|
407
466
|
declare function listLimits(field: FieldBlock): {
|
|
408
467
|
min: number;
|
|
@@ -676,4 +735,12 @@ declare function explain(source: FormEngine | ExplainInput, blockId: string, opt
|
|
|
676
735
|
/** A condition as a plain-English clause: `contact_me is not Yes`. */
|
|
677
736
|
declare function describeCondition(condition: Condition, def: FormDefinition, fields?: Map<string, FieldBlock>): string;
|
|
678
737
|
|
|
679
|
-
|
|
738
|
+
/**
|
|
739
|
+
* Answers given to one version of a form, as answers to another (by field id), matched
|
|
740
|
+
* by field key: what an edit link prefills when the form has a newer version. Answers
|
|
741
|
+
* to fields the other version doesn't have are dropped; `extra` (by key) fills fields
|
|
742
|
+
* the stored answers leave out, such as contact details kept apart.
|
|
743
|
+
*/
|
|
744
|
+
declare function carryAnswers(from: FormDefinition, to: FormDefinition, answers: Record<string, Json>, extra?: Record<string, Json | null | undefined>): Record<string, Json>;
|
|
745
|
+
|
|
746
|
+
export { type AnswersOf, Block, CALCULATED_TYPE, COMPUTED_FIELD_TYPES, type CalculatedFormat, type CalculatedProps, type ChoiceFieldOptions, type CoerceHiddenOptions, type CoercedHidden, Condition, ContentBlock, DEFAULT_PHOTO_FILES, DEFAULT_PHOTO_SIZE_MB, Ending, type ExplainInput, type ExplainOptions, type Explanation, FORMULA_FUNCTIONS, FieldBlock, type FieldOptions, type FieldSpec, type FieldValidation, FieldValidator, type Form, FormDefinition, FormEngine, type FormInput, type FormIssue, FormLayout, type FormProgress, FormSettings, FormState, type FormulaFunction, type FormulaNode, type FormulaParseResult, type FormulaReader, type FormulaRef, type FormulaValue, HIGHLIGHT_NOTE_MESSAGE, HiddenInput, type Highlight, Json, type JumpTrace, type KeyResolver, LogicRule, MAX_CALCULATED_DECIMALS, MAX_FORMULA_ITEMS, MAX_FORMULA_LENGTH, MAX_FORM_FORMULA_LENGTH, MAX_HIDDEN_STRING_LENGTH, MAX_HIGHLIGHT_NOTE_LENGTH, MAX_HIGHLIGHT_QUOTE_LENGTH, MAX_PHOTO_FILES, MAX_PHOTO_ID_LENGTH, MAX_PHOTO_NAME_LENGTH, MAX_PHOTO_SIZE_MB, MAX_SETTLE_ITEMS, MAX_TABLE_CELL_LENGTH, MAX_TABLE_COLUMNS, MAX_TIMESTAMP_SECONDS, type MediaNote, OptionsSource, PHOTO_FORMATS, PHOTO_TYPE, PageBreakBlock, type ParseResult, type PathResult, type PhotoFormat, type PhotoLimits, type PhotoRef, type RuleSpec, type RuleTrace, STRUCTURED_FIELD_TYPES, type TableColumn, UPLOAD_FIELD_TYPES, calculatedProps, calculatedValue, canonicalJson, carryAnswers, coerceHidden, coerceHiddenValue, computePath, defineForm, describeCondition, evaluate, evaluateFormula, explain, f, fingerprint, formProgress, formatCalculated, formatTimestamp, formulaInput, formulaNumber, formulaRefs, furthestReached, isPhotoFormat, isPhotoRef, listLimits, parseForm, parseFormula, parseTimestamp, photoCountMessage, photoFormatList, photoLimits, photoRefs, photoSizeMessage, photoTypeMessage, recall, renameFormulaKey, ruleVisible, steps, tableColumns, tableLimits, when };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,68 @@
|
|
|
1
|
-
import { a as FieldBlock, C as ContentBlock, P as PageBreakBlock, F as FormDefinition, H as HiddenInput, b as FormLayout, L as LogicRule, E as Ending, c as FormSettings,
|
|
2
|
-
export { e as FormEvent, f as Operand } from './types-
|
|
3
|
-
import { F as FormEngine } from './engine-
|
|
4
|
-
export { C as CreateFormOptions,
|
|
5
|
-
import { F as FieldValidator } from './validate-
|
|
6
|
-
export { R as REQUIRED_MESSAGE, S as StandardSchemaV1, v as validateField } from './validate-
|
|
1
|
+
import { a as FieldBlock, J as Json, C as ContentBlock, P as PageBreakBlock, O as OptionsSource, F as FormDefinition, H as HiddenInput, b as FormLayout, L as LogicRule, E as Ending, c as FormSettings, d as Condition, B as Block } from './types-oAckGR_Z.js';
|
|
2
|
+
export { e as FormEvent, f as Operand, g as Operator } from './types-oAckGR_Z.js';
|
|
3
|
+
import { F as FormEngine, a as FormState } from './engine-CpfOz8FN.js';
|
|
4
|
+
export { C as CreateFormOptions, c as createForm, i as isFormEvent, b as isJson, r as replay } from './engine-CpfOz8FN.js';
|
|
5
|
+
import { F as FieldValidator } from './validate-GpTXPwyl.js';
|
|
6
|
+
export { A as AnswerSnapshot, C as CHOICE_FIELD_TYPES, a as ChoiceOption, b as FieldTypeManifest, H as HostOptions, L as LinkParams, M as MAX_PREFILL_PARAM_LENGTH, O as OPTION_LIMITS, c as OTHER_MAX_LENGTH, d as OptionSnapshot, P as PrefillSetting, e as PrefillState, R as REQUIRED_MESSAGE, f as RestoredAnswers, S as SEARCHABLE_OPTION_COUNT, g as StandardSchemaV1, h as answerSnapshots, i as answersFromSnapshots, j as answersOnPath, k as choiceOptions, l as clearFilteredAnswers, m as dateLimits, n as filteredChoiceError, o as getFieldType, p as hasOptionFilters, q as hiddenByPrefill, r as isEmptyValue, s as isHttpsUrl, t as isIsoDate, u as isOtherValue, v as isPrefillParam, w as isSearchable, x as isSensitive, y as listFieldTypes, z as normalizeValue, B as numberLimits, D as optionFilter, E as optionJson, G as optionMatches, I as optionsSource, J as otherOption, K as prefillFromLink, N as prefillSetting, Q as ratingDisplay, T as readOption, U as registerFieldType, V as respondentPath, W as scaleLabels, X as searchOptions, Y as summarizeValue, Z as validateField, _ as visibleOptions, $ as withHostOptions } from './validate-GpTXPwyl.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* The `photo` field type: a respondent attaches up to a few photos, such as a
|
|
10
|
+
* picture of broken equipment. The answer holds references the host's storage
|
|
11
|
+
* handed back (`PhotoRef`), never the bytes: the renderer uploads through the
|
|
12
|
+
* host (`onUpload` on genesis-forms-web's `Form`), so the engine and the
|
|
13
|
+
* server stay storage-agnostic. A host's server should check that each
|
|
14
|
+
* reference is a file it stored for this respondent before saving.
|
|
15
|
+
*
|
|
16
|
+
* Opt-in in a builder palette (`UPLOAD_FIELD_TYPES`), since a host must be
|
|
17
|
+
* able to store the files.
|
|
18
|
+
*/
|
|
19
|
+
declare const PHOTO_TYPE = "photo";
|
|
20
|
+
/** Field types that need the host to store files; a builder offers them only when the host names them. */
|
|
21
|
+
declare const UPLOAD_FIELD_TYPES: readonly ["photo"];
|
|
22
|
+
/** One stored photo, as the host's upload returned it. */
|
|
23
|
+
type PhotoRef = {
|
|
24
|
+
/** The host's id for the stored file. */
|
|
25
|
+
id: string;
|
|
26
|
+
/** The file's name on the respondent's device. */
|
|
27
|
+
name: string;
|
|
28
|
+
/** Its MIME type, such as `image/jpeg`. */
|
|
29
|
+
type: string;
|
|
30
|
+
/** Bytes. */
|
|
31
|
+
size: number;
|
|
32
|
+
};
|
|
33
|
+
type PhotoFormat = "jpeg" | "png" | "heic" | "webp";
|
|
34
|
+
/** The MIME types each format covers. */
|
|
35
|
+
declare const PHOTO_FORMATS: Record<PhotoFormat, readonly string[]>;
|
|
36
|
+
declare const DEFAULT_PHOTO_FILES = 3;
|
|
37
|
+
declare const MAX_PHOTO_FILES = 5;
|
|
38
|
+
declare const DEFAULT_PHOTO_SIZE_MB = 10;
|
|
39
|
+
declare const MAX_PHOTO_SIZE_MB = 25;
|
|
40
|
+
/** The longest reference id and file name a photo answer may carry. */
|
|
41
|
+
declare const MAX_PHOTO_ID_LENGTH = 200;
|
|
42
|
+
declare const MAX_PHOTO_NAME_LENGTH = 255;
|
|
43
|
+
declare const isPhotoFormat: (v: unknown) => v is PhotoFormat;
|
|
44
|
+
interface PhotoLimits {
|
|
45
|
+
maxFiles: number;
|
|
46
|
+
maxSizeMb: number;
|
|
47
|
+
maxBytes: number;
|
|
48
|
+
formats: PhotoFormat[];
|
|
49
|
+
/** Every MIME type the formats cover. */
|
|
50
|
+
mimeTypes: string[];
|
|
51
|
+
}
|
|
52
|
+
/** A photo field's limits; a prop that is missing or out of range uses its default. */
|
|
53
|
+
declare function photoLimits(field: FieldBlock): PhotoLimits;
|
|
54
|
+
/** Whether `v` has a photo reference's shape (any type and size). */
|
|
55
|
+
declare function isPhotoRef(v: unknown): v is PhotoRef;
|
|
56
|
+
/** The well-formed references in a photo answer, as `{ id, name, type, size }` only. */
|
|
57
|
+
declare function photoRefs(value: Json | undefined): PhotoRef[];
|
|
58
|
+
/** "JPEG, PNG or WebP". */
|
|
59
|
+
declare function photoFormatList(formats: readonly PhotoFormat[]): string;
|
|
60
|
+
/** The message for a file of a type the field doesn't take. */
|
|
61
|
+
declare const photoTypeMessage: (field: FieldBlock) => string;
|
|
62
|
+
/** The message for a file over the field's size limit. */
|
|
63
|
+
declare const photoSizeMessage: (field: FieldBlock) => string;
|
|
64
|
+
/** The message for more photos than the field takes. */
|
|
65
|
+
declare const photoCountMessage: (field: FieldBlock) => string;
|
|
7
66
|
|
|
8
67
|
/** A field block that remembers its key and value type, for answer inference. */
|
|
9
68
|
type FieldSpec<K extends string = string, V = unknown> = FieldBlock & {
|
|
@@ -24,10 +83,38 @@ interface FieldOptions {
|
|
|
24
83
|
id?: string | undefined;
|
|
25
84
|
}
|
|
26
85
|
interface ChoiceFieldOptions<O extends string> extends FieldOptions {
|
|
27
|
-
options
|
|
86
|
+
/** The options. Optional only with `optionsFrom`, whose options follow these. */
|
|
87
|
+
options?: readonly {
|
|
28
88
|
value: O;
|
|
29
89
|
label?: string;
|
|
30
|
-
|
|
90
|
+
description?: string;
|
|
91
|
+
image?: string;
|
|
92
|
+
attributes?: Record<string, string | string[]>;
|
|
93
|
+
}[] | undefined;
|
|
94
|
+
/**
|
|
95
|
+
* Options the app showing the form supplies, by key (`OptionsSource`), such
|
|
96
|
+
* as `{ source: "host", key: "coaches" }`; pass the lists as `hostOptions`
|
|
97
|
+
* to `createForm` and `validateSubmission`.
|
|
98
|
+
*/
|
|
99
|
+
optionsFrom?: OptionsSource | undefined;
|
|
100
|
+
/**
|
|
101
|
+
* An "Other" option the respondent fills in (`true`, or `{ label }` to name it): their text is
|
|
102
|
+
* the answer (one more item on a multiple choice). See `otherOption`.
|
|
103
|
+
*/
|
|
104
|
+
other?: boolean | {
|
|
105
|
+
label?: string;
|
|
106
|
+
} | undefined;
|
|
107
|
+
/**
|
|
108
|
+
* Preselect from the link the form was opened from: `{ param: "location" }` takes
|
|
109
|
+
* `?location=…` when it is one of the options; `hideWhenPrefilled` then skips the question.
|
|
110
|
+
* See `prefillFromLink`.
|
|
111
|
+
*/
|
|
112
|
+
prefill?: {
|
|
113
|
+
param: string;
|
|
114
|
+
hideWhenPrefilled?: boolean;
|
|
115
|
+
} | undefined;
|
|
116
|
+
/** A search box over the options: true or false, or by default when there are more than 10 (`isSearchable`). */
|
|
117
|
+
searchable?: boolean | undefined;
|
|
31
118
|
}
|
|
32
119
|
interface HiddenOptions {
|
|
33
120
|
source?: HiddenInput["source"] | undefined;
|
|
@@ -137,6 +224,16 @@ declare const f: {
|
|
|
137
224
|
quote: string;
|
|
138
225
|
note: string;
|
|
139
226
|
}[]>;
|
|
227
|
+
/**
|
|
228
|
+
* Up to a few photos (a picture of broken equipment). The answer holds the
|
|
229
|
+
* references the host's upload returned, never the bytes; `formats` from
|
|
230
|
+
* jpeg, png, heic and webp (default all four).
|
|
231
|
+
*/
|
|
232
|
+
photo: <K extends string>(key: K, o: FieldOptions & {
|
|
233
|
+
maxFiles?: number | undefined;
|
|
234
|
+
maxSizeMb?: number | undefined;
|
|
235
|
+
formats?: readonly PhotoFormat[] | undefined;
|
|
236
|
+
}) => FieldSpec<K, PhotoRef[]>;
|
|
140
237
|
/** Any registered field type, including plugins. */
|
|
141
238
|
custom: <K extends string, V = Json>(type: string, key: K, o: FieldOptions & {
|
|
142
239
|
props?: Record<string, Json>;
|
|
@@ -333,76 +430,38 @@ declare function computePath(def: FormDefinition, scope: EvalScope): PathResult;
|
|
|
333
430
|
declare function ruleVisible(def: FormDefinition, blockId: string, scope: EvalScope): boolean;
|
|
334
431
|
|
|
335
432
|
/**
|
|
336
|
-
*
|
|
337
|
-
*
|
|
433
|
+
* How far a respondent has got, for saving answers as they go
|
|
434
|
+
* (`settings.saveProgress`) and for drop-off by question. Pure: reads a form's
|
|
435
|
+
* state, never changes it.
|
|
338
436
|
*/
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
label: string;
|
|
342
|
-
category: "text" | "choice" | "scale" | "date" | "media" | "advanced";
|
|
343
|
-
/** `json: false` types must convert, so drafts and server replay never lose an answer. */
|
|
344
|
-
value: {
|
|
345
|
-
json: true;
|
|
346
|
-
} | {
|
|
347
|
-
json: false;
|
|
348
|
-
serialize: (value: unknown) => Json;
|
|
349
|
-
deserialize: (json: Json) => unknown;
|
|
350
|
-
};
|
|
351
|
-
operators: Operator[];
|
|
352
|
-
a11y: {
|
|
353
|
-
semantics: "control" | "group";
|
|
354
|
-
/** The HTML `autocomplete` token, such as `"email"` or `"tel"`. */
|
|
355
|
-
autocomplete?: string;
|
|
356
|
-
/** The HTML `inputmode` hint for on-screen keyboards, such as `"email"` or `"tel"`. */
|
|
357
|
-
inputMode?: "text" | "email" | "tel" | "numeric" | "decimal" | "url" | "search";
|
|
358
|
-
};
|
|
359
|
-
isEmpty?: (value: Json | undefined) => boolean;
|
|
360
|
-
/** Return an error message, or null when the (non-empty) value is valid. */
|
|
361
|
-
validate?: (value: Json, field: FieldBlock) => string | null;
|
|
362
|
-
/** Plain text for recall, exports and emails. */
|
|
363
|
-
summarize?: (value: Json, field: FieldBlock) => string;
|
|
437
|
+
|
|
438
|
+
interface FormProgress {
|
|
364
439
|
/**
|
|
365
|
-
* The
|
|
366
|
-
*
|
|
440
|
+
* The furthest block reached, 1-based, on the path as it is now (logic can
|
|
441
|
+
* lengthen or shorten the path, so store `fieldId`, not this). 0 before any.
|
|
367
442
|
*/
|
|
368
|
-
|
|
369
|
-
/**
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
declare function normalizeValue(value: Json, field: FieldBlock): Json;
|
|
378
|
-
/** Whether a block holds personal or secret data: `sensitive: true`, or the `props.sensitive: true` alias. */
|
|
379
|
-
declare function isSensitive(block: Block): boolean;
|
|
380
|
-
declare function summarizeValue(value: Json | undefined, field: FieldBlock): string;
|
|
381
|
-
interface ChoiceOption {
|
|
382
|
-
value: string;
|
|
383
|
-
label?: string;
|
|
443
|
+
step: number;
|
|
444
|
+
/** How many blocks the path has now. */
|
|
445
|
+
total: number;
|
|
446
|
+
/**
|
|
447
|
+
* The id of the furthest question (field) reached: shown in focus layout, or
|
|
448
|
+
* answered. Null before any. A content block on the way is not a question,
|
|
449
|
+
* so the question before it counts.
|
|
450
|
+
*/
|
|
451
|
+
fieldId: string | null;
|
|
384
452
|
}
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
/**
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
step?: number;
|
|
398
|
-
};
|
|
399
|
-
/** `YYYY-MM-DD`, a real calendar day (no 2026-02-30), years 0001 to 9999. */
|
|
400
|
-
declare function isIsoDate(value: string): boolean;
|
|
401
|
-
/** A `date` field's earliest and latest days (`YYYY-MM-DD`), when set. */
|
|
402
|
-
declare function dateLimits(field: FieldBlock): {
|
|
403
|
-
min?: string;
|
|
404
|
-
max?: string;
|
|
405
|
-
};
|
|
453
|
+
/**
|
|
454
|
+
* The furthest block on the path the respondent has reached: the one on screen,
|
|
455
|
+
* one they went back from, or (in classic layout, where every question shows at
|
|
456
|
+
* once) the last one they answered. Null when the path is empty.
|
|
457
|
+
*/
|
|
458
|
+
declare function furthestReached(state: FormState, definition: FormDefinition): string | null;
|
|
459
|
+
/**
|
|
460
|
+
* Where the respondent is: the furthest step and the furthest question reached.
|
|
461
|
+
* What genesis-forms-web's `onProgress` passes; `engine.answers()` has the
|
|
462
|
+
* answers so far.
|
|
463
|
+
*/
|
|
464
|
+
declare function formProgress(engine: Pick<FormEngine, "definition" | "getState">): FormProgress;
|
|
406
465
|
|
|
407
466
|
declare function listLimits(field: FieldBlock): {
|
|
408
467
|
min: number;
|
|
@@ -676,4 +735,12 @@ declare function explain(source: FormEngine | ExplainInput, blockId: string, opt
|
|
|
676
735
|
/** A condition as a plain-English clause: `contact_me is not Yes`. */
|
|
677
736
|
declare function describeCondition(condition: Condition, def: FormDefinition, fields?: Map<string, FieldBlock>): string;
|
|
678
737
|
|
|
679
|
-
|
|
738
|
+
/**
|
|
739
|
+
* Answers given to one version of a form, as answers to another (by field id), matched
|
|
740
|
+
* by field key: what an edit link prefills when the form has a newer version. Answers
|
|
741
|
+
* to fields the other version doesn't have are dropped; `extra` (by key) fills fields
|
|
742
|
+
* the stored answers leave out, such as contact details kept apart.
|
|
743
|
+
*/
|
|
744
|
+
declare function carryAnswers(from: FormDefinition, to: FormDefinition, answers: Record<string, Json>, extra?: Record<string, Json | null | undefined>): Record<string, Json>;
|
|
745
|
+
|
|
746
|
+
export { type AnswersOf, Block, CALCULATED_TYPE, COMPUTED_FIELD_TYPES, type CalculatedFormat, type CalculatedProps, type ChoiceFieldOptions, type CoerceHiddenOptions, type CoercedHidden, Condition, ContentBlock, DEFAULT_PHOTO_FILES, DEFAULT_PHOTO_SIZE_MB, Ending, type ExplainInput, type ExplainOptions, type Explanation, FORMULA_FUNCTIONS, FieldBlock, type FieldOptions, type FieldSpec, type FieldValidation, FieldValidator, type Form, FormDefinition, FormEngine, type FormInput, type FormIssue, FormLayout, type FormProgress, FormSettings, FormState, type FormulaFunction, type FormulaNode, type FormulaParseResult, type FormulaReader, type FormulaRef, type FormulaValue, HIGHLIGHT_NOTE_MESSAGE, HiddenInput, type Highlight, Json, type JumpTrace, type KeyResolver, LogicRule, MAX_CALCULATED_DECIMALS, MAX_FORMULA_ITEMS, MAX_FORMULA_LENGTH, MAX_FORM_FORMULA_LENGTH, MAX_HIDDEN_STRING_LENGTH, MAX_HIGHLIGHT_NOTE_LENGTH, MAX_HIGHLIGHT_QUOTE_LENGTH, MAX_PHOTO_FILES, MAX_PHOTO_ID_LENGTH, MAX_PHOTO_NAME_LENGTH, MAX_PHOTO_SIZE_MB, MAX_SETTLE_ITEMS, MAX_TABLE_CELL_LENGTH, MAX_TABLE_COLUMNS, MAX_TIMESTAMP_SECONDS, type MediaNote, OptionsSource, PHOTO_FORMATS, PHOTO_TYPE, PageBreakBlock, type ParseResult, type PathResult, type PhotoFormat, type PhotoLimits, type PhotoRef, type RuleSpec, type RuleTrace, STRUCTURED_FIELD_TYPES, type TableColumn, UPLOAD_FIELD_TYPES, calculatedProps, calculatedValue, canonicalJson, carryAnswers, coerceHidden, coerceHiddenValue, computePath, defineForm, describeCondition, evaluate, evaluateFormula, explain, f, fingerprint, formProgress, formatCalculated, formatTimestamp, formulaInput, formulaNumber, formulaRefs, furthestReached, isPhotoFormat, isPhotoRef, listLimits, parseForm, parseFormula, parseTimestamp, photoCountMessage, photoFormatList, photoLimits, photoRefs, photoSizeMessage, photoTypeMessage, recall, renameFormulaKey, ruleVisible, steps, tableColumns, tableLimits, when };
|