@marktiderman/genesis-forms 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 +386 -8
- package/dist/destinations.cjs +856 -53
- package/dist/destinations.cjs.map +1 -1
- package/dist/destinations.d.cts +452 -18
- package/dist/destinations.d.ts +452 -18
- package/dist/destinations.js +826 -54
- package/dist/destinations.js.map +1 -1
- package/dist/{engine-C5tb3mkf.d.cts → engine-BaHPC2-1.d.cts} +2 -2
- package/dist/{engine-DcNQ-6oJ.d.ts → engine-Da99Tv-E.d.ts} +2 -2
- package/dist/index.cjs +996 -167
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +288 -11
- package/dist/index.d.ts +288 -11
- package/dist/index.js +975 -168
- package/dist/index.js.map +1 -1
- package/dist/server.cjs +563 -173
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +3 -474
- package/dist/server.d.ts +3 -474
- package/dist/server.js +558 -174
- package/dist/server.js.map +1 -1
- package/dist/submit-protocol-CFi-0Qd0.d.ts +840 -0
- package/dist/submit-protocol-D0cOckmK.d.cts +840 -0
- package/dist/testing.cjs +250 -154
- 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 +250 -154
- package/dist/testing.js.map +1 -1
- package/dist/{types-oAckGR_Z.d.cts → types-C0pUfew3.d.cts} +8 -2
- package/dist/{types-oAckGR_Z.d.ts → types-C0pUfew3.d.ts} +8 -2
- package/dist/{validate-BFpNJbjf.d.cts → validate-DpmBssFk.d.ts} +258 -140
- package/dist/{validate-qwkdcr3H.d.ts → validate-U5LoW3eR.d.cts} +258 -140
- package/package.json +2 -2
- package/dist/upload-protocol-Bw0CWRJc.d.cts +0 -122
- package/dist/upload-protocol-PX0jroTV.d.ts +0 -122
|
@@ -57,8 +57,14 @@ interface OptionsSource {
|
|
|
57
57
|
interface ContentBlock {
|
|
58
58
|
kind: "content";
|
|
59
59
|
id: string;
|
|
60
|
-
|
|
60
|
+
/**
|
|
61
|
+
* A registered content kind: `heading` and `text` are built in; a host adds others with
|
|
62
|
+
* `registerContentType`.
|
|
63
|
+
*/
|
|
64
|
+
type: "heading" | "text" | (string & {});
|
|
61
65
|
text: string;
|
|
66
|
+
/** Settings for a host's own content kind, checked by its `checkProps`. */
|
|
67
|
+
props?: Record<string, Json>;
|
|
62
68
|
}
|
|
63
69
|
interface PageBreakBlock {
|
|
64
70
|
kind: "page-break";
|
|
@@ -182,4 +188,4 @@ type FormEvent = {
|
|
|
182
188
|
at?: number;
|
|
183
189
|
};
|
|
184
190
|
|
|
185
|
-
export type { Block as B,
|
|
191
|
+
export type { Block as B, Condition as C, Ending as E, FormDefinition as F, HiddenInput as H, Json as J, LogicRule as L, OptionsSource as O, PageBreakBlock as P, FieldBlock as a, ContentBlock as b, FormLayout as c, FormSettings as d, FormEvent as e, Operand as f, Operator as g };
|
|
@@ -57,8 +57,14 @@ interface OptionsSource {
|
|
|
57
57
|
interface ContentBlock {
|
|
58
58
|
kind: "content";
|
|
59
59
|
id: string;
|
|
60
|
-
|
|
60
|
+
/**
|
|
61
|
+
* A registered content kind: `heading` and `text` are built in; a host adds others with
|
|
62
|
+
* `registerContentType`.
|
|
63
|
+
*/
|
|
64
|
+
type: "heading" | "text" | (string & {});
|
|
61
65
|
text: string;
|
|
66
|
+
/** Settings for a host's own content kind, checked by its `checkProps`. */
|
|
67
|
+
props?: Record<string, Json>;
|
|
62
68
|
}
|
|
63
69
|
interface PageBreakBlock {
|
|
64
70
|
kind: "page-break";
|
|
@@ -182,4 +188,4 @@ type FormEvent = {
|
|
|
182
188
|
at?: number;
|
|
183
189
|
};
|
|
184
190
|
|
|
185
|
-
export type { Block as B,
|
|
191
|
+
export type { Block as B, Condition as C, Ending as E, FormDefinition as F, HiddenInput as H, Json as J, LogicRule as L, OptionsSource as O, PageBreakBlock as P, FieldBlock as a, ContentBlock as b, FormLayout as c, FormSettings as d, FormEvent as e, Operand as f, Operator as g };
|
|
@@ -1,146 +1,32 @@
|
|
|
1
|
-
import { J as Json,
|
|
1
|
+
import { J as Json, e as FormEvent, F as FormDefinition, a as FieldBlock, b as ContentBlock, g as Operator, B as Block, O as OptionsSource } from './types-C0pUfew3.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Checking a block's `props` for `parseForm`: the shared helpers every content and field kind's
|
|
5
|
+
* `checkProps` uses, so each kind states its own settings once and they are reported the same way.
|
|
6
6
|
*/
|
|
7
|
-
interface FieldTypeManifest {
|
|
8
|
-
type: string;
|
|
9
|
-
label: string;
|
|
10
|
-
category: "text" | "choice" | "scale" | "date" | "media" | "advanced";
|
|
11
|
-
/** `json: false` types must convert, so drafts and server replay never lose an answer. */
|
|
12
|
-
value: {
|
|
13
|
-
json: true;
|
|
14
|
-
} | {
|
|
15
|
-
json: false;
|
|
16
|
-
serialize: (value: unknown) => Json;
|
|
17
|
-
deserialize: (json: Json) => unknown;
|
|
18
|
-
};
|
|
19
|
-
operators: Operator[];
|
|
20
|
-
a11y: {
|
|
21
|
-
semantics: "control" | "group";
|
|
22
|
-
/** The HTML `autocomplete` token, such as `"email"` or `"tel"`. */
|
|
23
|
-
autocomplete?: string;
|
|
24
|
-
/** The HTML `inputmode` hint for on-screen keyboards, such as `"email"` or `"tel"`. */
|
|
25
|
-
inputMode?: "text" | "email" | "tel" | "numeric" | "decimal" | "url" | "search";
|
|
26
|
-
};
|
|
27
|
-
isEmpty?: (value: Json | undefined) => boolean;
|
|
28
|
-
/** Return an error message, or null when the (non-empty) value is valid. */
|
|
29
|
-
validate?: (value: Json, field: FieldBlock) => string | null;
|
|
30
|
-
/** Plain text for recall, exports and emails. */
|
|
31
|
-
summarize?: (value: Json, field: FieldBlock) => string;
|
|
32
|
-
/**
|
|
33
|
-
* The form a (valid, non-empty) value is stored in, such as an email
|
|
34
|
-
* without surrounding spaces. Applied by `engine.answers()` and the server.
|
|
35
|
-
*/
|
|
36
|
-
normalize?: (value: Json, field: FieldBlock) => Json;
|
|
37
|
-
/** Valid example answers, used by `coverage()` and other test tools to explore a path. */
|
|
38
|
-
samples?: (field: FieldBlock) => Json[];
|
|
39
|
-
}
|
|
40
|
-
declare function registerFieldType(manifest: FieldTypeManifest): void;
|
|
41
|
-
declare function getFieldType(type: string): FieldTypeManifest | undefined;
|
|
42
|
-
declare function listFieldTypes(): FieldTypeManifest[];
|
|
43
|
-
declare function isEmptyValue(value: Json | undefined, field?: FieldBlock): boolean;
|
|
44
|
-
/** A value in its stored form (see `FieldTypeManifest.normalize`). */
|
|
45
|
-
declare function normalizeValue(value: Json, field: FieldBlock): Json;
|
|
46
|
-
/** Whether a block holds personal or secret data: `sensitive: true`, or the `props.sensitive: true` alias. */
|
|
47
|
-
declare function isSensitive(block: Block): boolean;
|
|
48
|
-
declare function summarizeValue(value: Json | undefined, field: FieldBlock): string;
|
|
49
|
-
interface ChoiceOption {
|
|
50
|
-
value: string;
|
|
51
|
-
label?: string;
|
|
52
|
-
/** A muted line under the label, such as a location's address. At most `OPTION_LIMITS.description` characters. */
|
|
53
|
-
description?: string;
|
|
54
|
-
/** A small picture beside the label: an `https://` URL, at most `OPTION_LIMITS.image` characters. */
|
|
55
|
-
image?: string;
|
|
56
|
-
/**
|
|
57
|
-
* Facts about the option for filtering and recall, such as `{ location: ["riverside", "hilltop"] }`
|
|
58
|
-
* for a coach who works at two locations (see `props.optionsFrom.filter`). Names and values are
|
|
59
|
-
* text; a value is one text or a list of them.
|
|
60
|
-
*/
|
|
61
|
-
attributes?: Record<string, string | string[]>;
|
|
62
|
-
}
|
|
63
|
-
/** Bounds on an option's extra details. A longer or malformed detail is dropped when options are read. */
|
|
64
|
-
declare const OPTION_LIMITS: {
|
|
65
|
-
/** Characters in a description. */
|
|
66
|
-
readonly description: 500;
|
|
67
|
-
/** Characters in an image URL. */
|
|
68
|
-
readonly image: 2048;
|
|
69
|
-
/** Attributes on one option. */
|
|
70
|
-
readonly attributes: 20;
|
|
71
|
-
/** Characters in an attribute's name. */
|
|
72
|
-
readonly attributeName: 64;
|
|
73
|
-
/** Characters in one attribute value. */
|
|
74
|
-
readonly attributeValue: 200;
|
|
75
|
-
/** Values in one attribute's list. */
|
|
76
|
-
readonly attributeItems: 50;
|
|
77
|
-
};
|
|
78
7
|
/**
|
|
79
|
-
*
|
|
80
|
-
* `
|
|
8
|
+
* A kind's check of its `props` (an object, `{}` when the block has none). Report through
|
|
9
|
+
* `check`, with paths under `props` (`"max"`, `"columns[0].key"`); `parseForm` prefixes each
|
|
10
|
+
* with the block's (`blocks[3].props.`).
|
|
81
11
|
*/
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
*/
|
|
88
|
-
|
|
89
|
-
/** An
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
*/
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
} | null;
|
|
101
|
-
/** Whether a value is a typed "Other" answer: text that isn't one of the question's options. */
|
|
102
|
-
declare function isOtherValue(field: FieldBlock, value: unknown): value is string;
|
|
103
|
-
declare function choiceOptions(field: FieldBlock): ChoiceOption[];
|
|
104
|
-
/**
|
|
105
|
-
* Option lists the app showing a form supplies, by key (`OptionsSource.key`):
|
|
106
|
-
* `{ coaches: [{ value: "8c1…", label: "Ada Lovelace" }] }`.
|
|
107
|
-
*/
|
|
108
|
-
type HostOptions = Readonly<Record<string, readonly ChoiceOption[]>>;
|
|
109
|
-
/**
|
|
110
|
-
* A choice field's `props.optionsFrom`, when it is a well-formed `{ source: "host", key }`, with its
|
|
111
|
-
* `filter` when that is well formed too (`{ attribute, field }`, both non-empty text).
|
|
112
|
-
*/
|
|
113
|
-
declare function optionsSource(field: FieldBlock): OptionsSource | undefined;
|
|
114
|
-
/**
|
|
115
|
-
* The definition with each `optionsFrom: { source: "host" }` field's options
|
|
116
|
-
* filled in from `hostOptions`: its own `props.options` first, then the host's
|
|
117
|
-
* list for its key (a value the field already has is not added twice). A key
|
|
118
|
-
* the host does not supply adds nothing, so the field offers its own options
|
|
119
|
-
* only. `createForm` and `validateSubmission` call it with their `hostOptions`,
|
|
120
|
-
* so a respondent sees, and a submit accepts, exactly these. Returns
|
|
121
|
-
* `definition` itself when no field takes options from the host.
|
|
122
|
-
*/
|
|
123
|
-
declare function withHostOptions(definition: FormDefinition, hostOptions: HostOptions | undefined): FormDefinition;
|
|
124
|
-
/** The optional words under the ends of a rating or NPS scale ("Poor", "Great"). */
|
|
125
|
-
declare function scaleLabels(field: FieldBlock): {
|
|
126
|
-
low?: string;
|
|
127
|
-
high?: string;
|
|
128
|
-
};
|
|
129
|
-
/** How a rating is drawn: `"numbers"` (default) or `"stars"`. */
|
|
130
|
-
declare function ratingDisplay(field: FieldBlock): "numbers" | "stars";
|
|
131
|
-
/** A `number` field's limits: `min`, `max` and `step` (each optional; `step` is above 0). */
|
|
132
|
-
declare function numberLimits(field: FieldBlock): {
|
|
133
|
-
min?: number;
|
|
134
|
-
max?: number;
|
|
135
|
-
step?: number;
|
|
136
|
-
};
|
|
137
|
-
/** `YYYY-MM-DD`, a real calendar day (no 2026-02-30), years 0001 to 9999. */
|
|
138
|
-
declare function isIsoDate(value: string): boolean;
|
|
139
|
-
/** A `date` field's earliest and latest days (`YYYY-MM-DD`), when set. */
|
|
140
|
-
declare function dateLimits(field: FieldBlock): {
|
|
141
|
-
min?: string;
|
|
142
|
-
max?: string;
|
|
143
|
-
};
|
|
12
|
+
type PropsCheck = (props: Readonly<Record<string, unknown>>, check: PropsChecker) => void;
|
|
13
|
+
/** The helpers a `PropsCheck` reports through. Paths are relative to `props`. */
|
|
14
|
+
interface PropsChecker {
|
|
15
|
+
/** Report a problem with the setting at `path`. */
|
|
16
|
+
issue(path: string, message: string): void;
|
|
17
|
+
/** A required string (non-empty with `nonEmpty`). */
|
|
18
|
+
text(v: unknown, path: string, nonEmpty?: boolean): void;
|
|
19
|
+
/** An optional string. */
|
|
20
|
+
optionalText(v: unknown, path: string): void;
|
|
21
|
+
/** An optional true or false. */
|
|
22
|
+
optionalBoolean(v: unknown, path: string): void;
|
|
23
|
+
/** An optional whole number of at least `floor`. */
|
|
24
|
+
optionalInt(v: unknown, path: string, floor: number): void;
|
|
25
|
+
/** `low` may not exceed `high` when both are whole numbers. */
|
|
26
|
+
ordered(low: unknown, high: unknown, path: string, what: string): void;
|
|
27
|
+
/** An identifier: a non-empty string that is not an `Object.prototype` name. */
|
|
28
|
+
name(v: unknown, path: string, what: string): v is string;
|
|
29
|
+
}
|
|
144
30
|
|
|
145
31
|
/**
|
|
146
32
|
* Which options a choice question shows, and how they are picked: lists filtered by another
|
|
@@ -149,7 +35,10 @@ declare function dateLimits(field: FieldBlock): {
|
|
|
149
35
|
* decide the same way.
|
|
150
36
|
*/
|
|
151
37
|
|
|
152
|
-
/**
|
|
38
|
+
/**
|
|
39
|
+
* The built-in field types whose answer is one or more of their options. A host's own choice
|
|
40
|
+
* kinds (`FieldTypeManifest.choice`) aren't in it: ask `isChoiceField` or `choiceKind`.
|
|
41
|
+
*/
|
|
153
42
|
declare const CHOICE_FIELD_TYPES: ReadonlySet<string>;
|
|
154
43
|
/** A choice field's `props.optionsFrom.filter` (`{ attribute, field }`), when it is well formed. */
|
|
155
44
|
declare function optionFilter(field: FieldBlock): {
|
|
@@ -292,6 +181,235 @@ interface RestoredAnswers {
|
|
|
292
181
|
*/
|
|
293
182
|
declare function answersFromSnapshots(definition: FormDefinition, snapshots: Readonly<Record<string, unknown>>): RestoredAnswers;
|
|
294
183
|
|
|
184
|
+
/** The JSON type a comparison literal must have to match an answer (`parseForm` warns otherwise). */
|
|
185
|
+
type LiteralType = "string" | "number" | "boolean";
|
|
186
|
+
/**
|
|
187
|
+
* A field kind, without any UI: the one definition the engine, `parseForm`, validation, the
|
|
188
|
+
* server and snapshots all read, so a kind is described once instead of in a switch in each.
|
|
189
|
+
* Renderers are registered separately per platform (`genesis-forms-react`), so a manifest runs
|
|
190
|
+
* anywhere. Every hook is optional except where noted; a missing one means "nothing special".
|
|
191
|
+
* `validate`, `checkProps`, `literal`, `snapshot` and `fromSnapshot` may throw (each fails safe,
|
|
192
|
+
* as its doc says); `isEmpty`, `normalize` and `summarize` must not.
|
|
193
|
+
*/
|
|
194
|
+
interface FieldTypeManifest {
|
|
195
|
+
type: string;
|
|
196
|
+
label: string;
|
|
197
|
+
category: "text" | "choice" | "scale" | "date" | "media" | "advanced";
|
|
198
|
+
/** `json: false` types must convert, so drafts and server replay never lose an answer. */
|
|
199
|
+
value: {
|
|
200
|
+
json: true;
|
|
201
|
+
} | {
|
|
202
|
+
json: false;
|
|
203
|
+
serialize: (value: unknown) => Json;
|
|
204
|
+
deserialize: (json: Json) => unknown;
|
|
205
|
+
};
|
|
206
|
+
operators: Operator[];
|
|
207
|
+
a11y: {
|
|
208
|
+
semantics: "control" | "group";
|
|
209
|
+
/** The HTML `autocomplete` token, such as `"email"` or `"tel"`. */
|
|
210
|
+
autocomplete?: string;
|
|
211
|
+
/** The HTML `inputmode` hint for on-screen keyboards, such as `"email"` or `"tel"`. */
|
|
212
|
+
inputMode?: "text" | "email" | "tel" | "numeric" | "decimal" | "url" | "search";
|
|
213
|
+
};
|
|
214
|
+
/**
|
|
215
|
+
* The props schema: `parseForm` calls it with the field's `props` (`{}` when it has none) and
|
|
216
|
+
* reports what it finds as issues at `blocks[i].props.<path>`. A check that throws is reported
|
|
217
|
+
* as one issue, never thrown.
|
|
218
|
+
*/
|
|
219
|
+
checkProps?: PropsCheck;
|
|
220
|
+
/**
|
|
221
|
+
* The answer's shape. `choice`: the answer is one of `props.options` (`multiple: false`, a
|
|
222
|
+
* text) or several (`multiple: true`, a list of texts), so the field takes `optionsFrom`,
|
|
223
|
+
* `prefill`, `other` and filters, and its answers are snapshotted with their labels. Without
|
|
224
|
+
* its own `validate` (or `summarize`) it gets the built-in one for its shape, so an answer is
|
|
225
|
+
* always one of its options (or a typed "Other" when `props.other` allows it).
|
|
226
|
+
*/
|
|
227
|
+
choice?: {
|
|
228
|
+
multiple: boolean;
|
|
229
|
+
};
|
|
230
|
+
/**
|
|
231
|
+
* The JSON type a logic literal compared with this field must have, or a function of its props
|
|
232
|
+
* (`undefined`: not known). `parseForm` warns about a literal that can never match.
|
|
233
|
+
*/
|
|
234
|
+
literal?: LiteralType | ((props: Readonly<Record<string, unknown>>) => LiteralType | undefined);
|
|
235
|
+
/** The empty-check: whether a value counts as no answer. Default: nothing, null, blank text or `[]`. */
|
|
236
|
+
isEmpty?: (value: Json | undefined) => boolean;
|
|
237
|
+
/**
|
|
238
|
+
* The validator: an error message, or null when the (non-empty) value is valid. A validator
|
|
239
|
+
* that throws refuses the answer (`VALIDATOR_FAILED_MESSAGE`) rather than throwing.
|
|
240
|
+
*/
|
|
241
|
+
validate?: (value: Json, field: FieldBlock) => string | null;
|
|
242
|
+
/** The display text: plain text for recall, exports and emails. */
|
|
243
|
+
summarize?: (value: Json, field: FieldBlock) => string;
|
|
244
|
+
/**
|
|
245
|
+
* The form a (valid, non-empty) value is stored in, such as an email
|
|
246
|
+
* without surrounding spaces. Applied by `engine.answers()` and the server.
|
|
247
|
+
*/
|
|
248
|
+
normalize?: (value: Json, field: FieldBlock) => Json;
|
|
249
|
+
/**
|
|
250
|
+
* The snapshot of a (non-empty) answer as it was when stored, for `answerSnapshots`: the
|
|
251
|
+
* labels it showed, so history keeps them when the source changes. Choice kinds have one
|
|
252
|
+
* built in (for fields with `optionsFrom`); give another kind one here.
|
|
253
|
+
*/
|
|
254
|
+
snapshot?: (value: Json, field: FieldBlock) => AnswerSnapshot | undefined;
|
|
255
|
+
/**
|
|
256
|
+
* The reverse of `snapshot`, for `answersFromSnapshots`: the answer to prefill from a stored
|
|
257
|
+
* snapshot (or none), and the picks that no longer exist.
|
|
258
|
+
*/
|
|
259
|
+
fromSnapshot?: (snapshot: unknown, field: FieldBlock) => {
|
|
260
|
+
value?: Json;
|
|
261
|
+
missing: OptionSnapshot[];
|
|
262
|
+
};
|
|
263
|
+
/** Valid example answers, used by `coverage()` and other test tools to explore a path. */
|
|
264
|
+
samples?: (field: FieldBlock) => Json[];
|
|
265
|
+
}
|
|
266
|
+
/** The message an answer gets when its kind's validator throws. */
|
|
267
|
+
declare const VALIDATOR_FAILED_MESSAGE = "This answer couldn't be checked.";
|
|
268
|
+
interface RegisterOptions {
|
|
269
|
+
/**
|
|
270
|
+
* Replace a built-in kind (`email`, `single-choice`…). Off by default: the registry is shared
|
|
271
|
+
* by every form in the process, the server's checks included, so changing what a built-in
|
|
272
|
+
* accepts must be deliberate.
|
|
273
|
+
*/
|
|
274
|
+
replace?: boolean;
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Register a field kind, or replace one a host registered before (re-registering is allowed,
|
|
278
|
+
* so hot reload works). Throws on a malformed manifest, and on a built-in kind's name unless
|
|
279
|
+
* `{ replace: true }`. Registered kinds are frozen copies.
|
|
280
|
+
*/
|
|
281
|
+
declare function registerFieldType(manifest: FieldTypeManifest, options?: RegisterOptions): void;
|
|
282
|
+
declare function getFieldType(type: string): FieldTypeManifest | undefined;
|
|
283
|
+
declare function listFieldTypes(): FieldTypeManifest[];
|
|
284
|
+
/** Whether `type` is one of the field kinds the package ships. */
|
|
285
|
+
declare function isBuiltInFieldType(type: string): boolean;
|
|
286
|
+
/** A choice kind's answer shape (`FieldTypeManifest.choice`), or undefined for any other kind. */
|
|
287
|
+
declare function choiceKind(type: string): {
|
|
288
|
+
multiple: boolean;
|
|
289
|
+
} | undefined;
|
|
290
|
+
/** Whether a block is a field of a choice kind: its answer is one or more of its options. */
|
|
291
|
+
declare function isChoiceField(block: unknown): block is FieldBlock;
|
|
292
|
+
/**
|
|
293
|
+
* A content kind (a block that shows something and takes no answer): `heading` and `text` are
|
|
294
|
+
* built in; a host registers others (a message screen, a media block) with
|
|
295
|
+
* `registerContentType`, plus a renderer per platform.
|
|
296
|
+
*/
|
|
297
|
+
interface ContentTypeManifest {
|
|
298
|
+
type: string;
|
|
299
|
+
label: string;
|
|
300
|
+
/** The props schema, as for a field kind; the block's `props`, `{}` when it has none. */
|
|
301
|
+
checkProps?: PropsCheck;
|
|
302
|
+
/** The display text (recall, exports, a renderer with no special drawing). Default: `block.text`. */
|
|
303
|
+
text?: (block: ContentBlock) => string;
|
|
304
|
+
}
|
|
305
|
+
/** Register a content kind. Throws on a malformed manifest or a built-in kind's name (unless `{ replace: true }`). */
|
|
306
|
+
declare function registerContentType(manifest: ContentTypeManifest, options?: RegisterOptions): void;
|
|
307
|
+
declare function getContentType(type: string): ContentTypeManifest | undefined;
|
|
308
|
+
declare function listContentTypes(): ContentTypeManifest[];
|
|
309
|
+
/** A content block's display text: its kind's `text` (when it gives a string without throwing), or `block.text`. */
|
|
310
|
+
declare function contentText(block: ContentBlock): string;
|
|
311
|
+
declare function isEmptyValue(value: Json | undefined, field?: FieldBlock): boolean;
|
|
312
|
+
/** A value in its stored form (see `FieldTypeManifest.normalize`). */
|
|
313
|
+
declare function normalizeValue(value: Json, field: FieldBlock): Json;
|
|
314
|
+
/** Whether a block holds personal or secret data: `sensitive: true`, or the `props.sensitive: true` alias. */
|
|
315
|
+
declare function isSensitive(block: Block): boolean;
|
|
316
|
+
declare function summarizeValue(value: Json | undefined, field: FieldBlock): string;
|
|
317
|
+
interface ChoiceOption {
|
|
318
|
+
value: string;
|
|
319
|
+
label?: string;
|
|
320
|
+
/** A muted line under the label, such as a location's address. At most `OPTION_LIMITS.description` characters. */
|
|
321
|
+
description?: string;
|
|
322
|
+
/** A small picture beside the label: an `https://` URL, at most `OPTION_LIMITS.image` characters. */
|
|
323
|
+
image?: string;
|
|
324
|
+
/**
|
|
325
|
+
* Facts about the option for filtering and recall, such as `{ location: ["riverside", "hilltop"] }`
|
|
326
|
+
* for a coach who works at two locations (see `props.optionsFrom.filter`). Names and values are
|
|
327
|
+
* text; a value is one text or a list of them.
|
|
328
|
+
*/
|
|
329
|
+
attributes?: Record<string, string | string[]>;
|
|
330
|
+
}
|
|
331
|
+
/** Bounds on an option's extra details. A longer or malformed detail is dropped when options are read. */
|
|
332
|
+
declare const OPTION_LIMITS: {
|
|
333
|
+
/** Characters in a description. */
|
|
334
|
+
readonly description: 500;
|
|
335
|
+
/** Characters in an image URL. */
|
|
336
|
+
readonly image: 2048;
|
|
337
|
+
/** Attributes on one option. */
|
|
338
|
+
readonly attributes: 20;
|
|
339
|
+
/** Characters in an attribute's name. */
|
|
340
|
+
readonly attributeName: 64;
|
|
341
|
+
/** Characters in one attribute value. */
|
|
342
|
+
readonly attributeValue: 200;
|
|
343
|
+
/** Values in one attribute's list. */
|
|
344
|
+
readonly attributeItems: 50;
|
|
345
|
+
};
|
|
346
|
+
/**
|
|
347
|
+
* Whether `url` is an `https://` link with a host and no spaces or control characters, within
|
|
348
|
+
* `OPTION_LIMITS.image`. A pattern rather than `new URL`, so it behaves the same in React Native.
|
|
349
|
+
*/
|
|
350
|
+
declare function isHttpsUrl(url: unknown): url is string;
|
|
351
|
+
/**
|
|
352
|
+
* An option from untrusted JSON (a definition, the host's list): its string `value`, and its
|
|
353
|
+
* `label`, `description`, `image` and `attributes` when each is well formed and within
|
|
354
|
+
* `OPTION_LIMITS`; anything else is left out. Null when there is no string value.
|
|
355
|
+
*/
|
|
356
|
+
declare function readOption(raw: unknown): ChoiceOption | null;
|
|
357
|
+
/** An option as JSON, with only the details it has. */
|
|
358
|
+
declare function optionJson(option: ChoiceOption): Json;
|
|
359
|
+
/** The longest answer an "Other" option takes. */
|
|
360
|
+
declare const OTHER_MAX_LENGTH = 200;
|
|
361
|
+
/**
|
|
362
|
+
* A choice question's "Other" option (`props.other: true` or `{ label }`): the respondent types
|
|
363
|
+
* their own answer, stored as the answer's value itself (single choice, dropdown) or as one more
|
|
364
|
+
* item (multiple choice). Null when the question has none.
|
|
365
|
+
*/
|
|
366
|
+
declare function otherOption(field: FieldBlock): {
|
|
367
|
+
label: string;
|
|
368
|
+
} | null;
|
|
369
|
+
/** Whether a value is a typed "Other" answer: text that isn't one of the question's options. */
|
|
370
|
+
declare function isOtherValue(field: FieldBlock, value: unknown): value is string;
|
|
371
|
+
declare function choiceOptions(field: FieldBlock): ChoiceOption[];
|
|
372
|
+
/**
|
|
373
|
+
* Option lists the app showing a form supplies, by key (`OptionsSource.key`):
|
|
374
|
+
* `{ coaches: [{ value: "8c1…", label: "Ada Lovelace" }] }`.
|
|
375
|
+
*/
|
|
376
|
+
type HostOptions = Readonly<Record<string, readonly ChoiceOption[]>>;
|
|
377
|
+
/**
|
|
378
|
+
* A choice field's `props.optionsFrom`, when it is a well-formed `{ source: "host", key }`, with its
|
|
379
|
+
* `filter` when that is well formed too (`{ attribute, field }`, both non-empty text).
|
|
380
|
+
*/
|
|
381
|
+
declare function optionsSource(field: FieldBlock): OptionsSource | undefined;
|
|
382
|
+
/**
|
|
383
|
+
* The definition with each `optionsFrom: { source: "host" }` field's options
|
|
384
|
+
* filled in from `hostOptions`: its own `props.options` first, then the host's
|
|
385
|
+
* list for its key (a value the field already has is not added twice). A key
|
|
386
|
+
* the host does not supply adds nothing, so the field offers its own options
|
|
387
|
+
* only. `createForm` and `validateSubmission` call it with their `hostOptions`,
|
|
388
|
+
* so a respondent sees, and a submit accepts, exactly these. Returns
|
|
389
|
+
* `definition` itself when no field takes options from the host.
|
|
390
|
+
*/
|
|
391
|
+
declare function withHostOptions(definition: FormDefinition, hostOptions: HostOptions | undefined): FormDefinition;
|
|
392
|
+
/** The optional words under the ends of a rating or NPS scale ("Poor", "Great"). */
|
|
393
|
+
declare function scaleLabels(field: FieldBlock): {
|
|
394
|
+
low?: string;
|
|
395
|
+
high?: string;
|
|
396
|
+
};
|
|
397
|
+
/** How a rating is drawn: `"numbers"` (default) or `"stars"`. */
|
|
398
|
+
declare function ratingDisplay(field: FieldBlock): "numbers" | "stars";
|
|
399
|
+
/** A `number` field's limits: `min`, `max` and `step` (each optional; `step` is above 0). */
|
|
400
|
+
declare function numberLimits(field: FieldBlock): {
|
|
401
|
+
min?: number;
|
|
402
|
+
max?: number;
|
|
403
|
+
step?: number;
|
|
404
|
+
};
|
|
405
|
+
/** `YYYY-MM-DD`, a real calendar day (no 2026-02-30), years 0001 to 9999. */
|
|
406
|
+
declare function isIsoDate(value: string): boolean;
|
|
407
|
+
/** A `date` field's earliest and latest days (`YYYY-MM-DD`), when set. */
|
|
408
|
+
declare function dateLimits(field: FieldBlock): {
|
|
409
|
+
min?: string;
|
|
410
|
+
max?: string;
|
|
411
|
+
};
|
|
412
|
+
|
|
295
413
|
/** The Standard Schema interface (standardschema.dev), as far as validation needs it. */
|
|
296
414
|
interface StandardSchemaV1<T = unknown> {
|
|
297
415
|
readonly "~standard": {
|
|
@@ -319,4 +437,4 @@ declare function validateField(field: FieldBlock, value: Json | undefined, optio
|
|
|
319
437
|
custom?: FieldValidator;
|
|
320
438
|
}): string | null;
|
|
321
439
|
|
|
322
|
-
export {
|
|
440
|
+
export { otherOption as $, type AnswerSnapshot as A, isChoiceField as B, CHOICE_FIELD_TYPES as C, isEmptyValue as D, isHttpsUrl as E, type FieldValidator as F, isIsoDate as G, type HostOptions as H, isOtherValue as I, isPrefillParam as J, isSearchable as K, type LinkParams as L, MAX_PREFILL_PARAM_LENGTH as M, isSensitive as N, OPTION_LIMITS as O, type PrefillSetting as P, listContentTypes as Q, REQUIRED_MESSAGE as R, SEARCHABLE_OPTION_COUNT as S, listFieldTypes as T, normalizeValue as U, VALIDATOR_FAILED_MESSAGE as V, numberLimits as W, optionFilter as X, optionJson as Y, optionMatches as Z, optionsSource as _, type ChoiceOption as a, prefillFromLink as a0, prefillSetting as a1, ratingDisplay as a2, readOption as a3, registerContentType as a4, registerFieldType as a5, respondentPath as a6, scaleLabels as a7, searchOptions as a8, summarizeValue as a9, validateField as aa, visibleOptions as ab, withHostOptions as ac, type ContentTypeManifest as b, type FieldTypeManifest as c, type LiteralType as d, OTHER_MAX_LENGTH as e, type OptionSnapshot as f, type PrefillState as g, type PropsCheck as h, type PropsChecker as i, type RegisterOptions as j, type RestoredAnswers as k, type StandardSchemaV1 as l, answerSnapshots as m, answersFromSnapshots as n, answersOnPath as o, choiceKind as p, choiceOptions as q, clearFilteredAnswers as r, contentText as s, dateLimits as t, filteredChoiceError as u, getContentType as v, getFieldType as w, hasOptionFilters as x, hiddenByPrefill as y, isBuiltInFieldType as z };
|