@ai-matrx/records 0.87.32 → 0.92.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/CHANGELOG.md +92 -0
- package/README.md +115 -0
- package/dist/{client-E0VQ0NPO.d.ts → client-DE9Mq6YX.d.cts} +8 -5
- package/dist/{client-C3ZZNfGH.d.cts → client-vJAb7g9r.d.ts} +8 -5
- package/dist/core/index.cjs +25 -7
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +23 -12
- package/dist/core/index.d.ts +23 -12
- package/dist/core/index.js +25 -7
- package/dist/core/index.js.map +1 -1
- package/dist/data/index.cjs +19 -7
- package/dist/data/index.cjs.map +1 -1
- package/dist/data/index.d.cts +12 -142
- package/dist/data/index.d.ts +12 -142
- package/dist/data/index.js +19 -7
- package/dist/data/index.js.map +1 -1
- package/dist/{declareTable-BK3zufr7.d.cts → declareTable-Btg5bql1.d.cts} +4 -4
- package/dist/{declareTable-B12XybRp.d.ts → declareTable-JKt2q34d.d.ts} +4 -4
- package/dist/entity/index.cjs +984 -0
- package/dist/entity/index.cjs.map +1 -0
- package/dist/entity/index.d.cts +36 -0
- package/dist/entity/index.d.ts +36 -0
- package/dist/entity/index.js +964 -0
- package/dist/entity/index.js.map +1 -0
- package/dist/entity/react.cjs +1024 -0
- package/dist/entity/react.cjs.map +1 -0
- package/dist/entity/react.d.cts +511 -0
- package/dist/entity/react.d.ts +511 -0
- package/dist/entity/react.js +1015 -0
- package/dist/entity/react.js.map +1 -0
- package/dist/{field-BanTVGK2.d.cts → field-BJBnTyJ0.d.cts} +1 -1
- package/dist/{field-BPABOJ2Y.d.ts → field-Ti5iAxFr.d.ts} +1 -1
- package/dist/forms/index.cjs +984 -0
- package/dist/forms/index.cjs.map +1 -0
- package/dist/forms/index.d.cts +333 -0
- package/dist/forms/index.d.ts +333 -0
- package/dist/forms/index.js +961 -0
- package/dist/forms/index.js.map +1 -0
- package/dist/index.cjs +10 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -8
- package/dist/index.d.ts +11 -8
- package/dist/index.js +10 -1
- package/dist/index.js.map +1 -1
- package/dist/memory/index.d.cts +7 -6
- package/dist/memory/index.d.ts +7 -6
- package/dist/port-CPVBfDxS.d.cts +301 -0
- package/dist/port-D2i2o7Lg.d.ts +301 -0
- package/dist/portal-Db4CYyHe.d.ts +331 -0
- package/dist/portal-DfeY2Boy.d.cts +331 -0
- package/dist/{ports-TMWX-t9l.d.ts → ports-BWtxAnXh.d.ts} +2 -2
- package/dist/{ports-D8-iuY1P.d.cts → ports-DSU2RsR6.d.cts} +2 -2
- package/dist/react/index.cjs +55 -523
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +14 -1
- package/dist/react/index.d.ts +14 -1
- package/dist/react/index.js +52 -527
- package/dist/react/index.js.map +1 -1
- package/dist/realtime/index.d.cts +2 -2
- package/dist/realtime/index.d.ts +2 -2
- package/dist/{record-DpB2QgAZ.d.cts → record-BQi92d4-.d.cts} +7 -1
- package/dist/{record-DpB2QgAZ.d.ts → record-BQi92d4-.d.ts} +7 -1
- package/dist/relation-DMwkmzgN.d.cts +230 -0
- package/dist/relation-DlcqV_W5.d.ts +230 -0
- package/dist/rule-B8kR0l01.d.ts +250 -0
- package/dist/rule-BMViCLmW.d.cts +250 -0
- package/dist/search/index.cjs +283 -0
- package/dist/search/index.cjs.map +1 -0
- package/dist/search/index.d.cts +44 -0
- package/dist/search/index.d.ts +44 -0
- package/dist/search/index.js +260 -0
- package/dist/search/index.js.map +1 -0
- package/dist/setup/index.cjs +6854 -0
- package/dist/setup/index.cjs.map +1 -0
- package/dist/setup/index.d.cts +87 -0
- package/dist/setup/index.d.ts +87 -0
- package/dist/setup/index.js +6829 -0
- package/dist/setup/index.js.map +1 -0
- package/dist/{subscription-D7KQBHXN.d.ts → subscription-5CLN3Jug.d.ts} +3 -249
- package/dist/{subscription-BD9DnJxX.d.cts → subscription-D-VEzvyy.d.cts} +3 -249
- package/dist/{table-kind-BZu8mtND.d.cts → table-kind-CVp43g6h.d.ts} +3 -558
- package/dist/{table-kind-xKxTHtrV.d.ts → table-kind-Cm6PXkWx.d.cts} +3 -558
- package/dist/templates/index.d.cts +10 -9
- package/dist/templates/index.d.ts +10 -9
- package/dist/typed-table/index.cjs +19 -7
- package/dist/typed-table/index.cjs.map +1 -1
- package/dist/typed-table/index.d.cts +10 -7
- package/dist/typed-table/index.d.ts +10 -7
- package/dist/typed-table/index.js +19 -7
- package/dist/typed-table/index.js.map +1 -1
- package/dist/{types-CLP5H4Wk.d.cts → types-9Q5SHRDJ.d.cts} +2 -2
- package/dist/{types-DmPkWQic.d.ts → types-CfYy-vdV.d.ts} +2 -2
- package/dist/{types-C2uspRtf.d.cts → types-Cs2MyE3u.d.cts} +2 -2
- package/dist/{types-Dv61jStB.d.ts → types-DF-dxB_l.d.ts} +2 -2
- package/dist/types-DTEGaxso.d.cts +139 -0
- package/dist/types-Dji5SpFS.d.ts +139 -0
- package/dist/use-cases/index.d.cts +5 -5
- package/dist/use-cases/index.d.ts +5 -5
- package/dist/{validate-CWVToe1T.d.ts → validate-BydKd-Le.d.ts} +1 -1
- package/dist/{validate-DEB_mn4Y.d.cts → validate-CqJakTKk.d.cts} +1 -1
- package/dist/versions/index.cjs +375 -0
- package/dist/versions/index.cjs.map +1 -0
- package/dist/versions/index.d.cts +160 -0
- package/dist/versions/index.d.ts +160 -0
- package/dist/versions/index.js +353 -0
- package/dist/versions/index.js.map +1 -0
- package/package.json +62 -2
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
import { k as PortalAccent } from '../portal-DfeY2Boy.cjs';
|
|
2
|
+
import { F as FormSummary, R as RuleExpression } from '../rule-BMViCLmW.cjs';
|
|
3
|
+
import { U as Uuid } from '../record-BQi92d4-.cjs';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* THE WORDS FOR EACH STATE, SAID ONCE, FOR EVERY SCREEN THAT SHOWS A FORM.
|
|
7
|
+
*
|
|
8
|
+
* `FormsPanel` and `FormBuilder` both put a form in front of a person and both
|
|
9
|
+
* offer the one act that changes this (`custom.anon_publish`). Two copies of
|
|
10
|
+
* these four sentences is two places for them to drift, and a person who reads
|
|
11
|
+
* "Not published" on one screen and something else on the other has been lied
|
|
12
|
+
* to by one of them. The store owns the state; this owns the sentence.
|
|
13
|
+
*/
|
|
14
|
+
declare const FORM_STATE_WORDS: Record<FormSummary["state"], string>;
|
|
15
|
+
/** How a form is put in front of a person. */
|
|
16
|
+
declare const FORM_FLOWS: readonly ["one-at-a-time", "single-page"];
|
|
17
|
+
type FormFlow = (typeof FORM_FLOWS)[number];
|
|
18
|
+
/** One question. It ASKS FOR one Field of the subject Table — never its own column. */
|
|
19
|
+
interface FormQuestionSpec {
|
|
20
|
+
/** The Field's key on the subject Table. */
|
|
21
|
+
field: string;
|
|
22
|
+
/** Ask it in the form's own words. Left out, the Field's own label is the question. */
|
|
23
|
+
ask?: string | null;
|
|
24
|
+
/** One line under the question. */
|
|
25
|
+
help?: string | null;
|
|
26
|
+
/** Override the Field's own `required`. Left out, the Field decides. */
|
|
27
|
+
required?: boolean | null;
|
|
28
|
+
/**
|
|
29
|
+
* CONDITIONAL LOGIC, AS A RULE. `{"op":"eq","args":[{"field":"<field id>"},{"const":"Yes"}]}`
|
|
30
|
+
* — the store answers it, this package never does. An UNDECIDED answer (the
|
|
31
|
+
* store's `null`, which is what an unanswered question gives) SHOWS the
|
|
32
|
+
* question: a person is never silently skipped past something.
|
|
33
|
+
*/
|
|
34
|
+
showIf?: RuleExpression | null;
|
|
35
|
+
/**
|
|
36
|
+
* LOGIC JUMPS (lane TYPEFORM-DUP). After this question, the FIRST jump whose `when` the store
|
|
37
|
+
* answers true is taken — to a later question or to one of the form's endings. A jump with no
|
|
38
|
+
* `when` is "always". Undecided falls through to the next question. The store judges the route
|
|
39
|
+
* (`custom._form_route`); this package never does.
|
|
40
|
+
*/
|
|
41
|
+
jumps?: FormJump[] | null;
|
|
42
|
+
/** SCORING: what each answer is worth (`{"Yes": 5}`); a list answer adds each of its parts. */
|
|
43
|
+
points?: Record<string, number> | null;
|
|
44
|
+
}
|
|
45
|
+
/** One logic jump: when the Rule is true, go to a later question or to an ending. */
|
|
46
|
+
interface FormJump {
|
|
47
|
+
when?: RuleExpression | null;
|
|
48
|
+
to: {
|
|
49
|
+
question: string;
|
|
50
|
+
} | {
|
|
51
|
+
ending: string;
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* ONE ENDING (lane TYPEFORM-DUP). A form may have several; a jump picks one, or the first whose
|
|
56
|
+
* condition holds (`when`, `scoreMin`, `scoreMax`), or else the first with no condition.
|
|
57
|
+
*/
|
|
58
|
+
interface FormEnding {
|
|
59
|
+
/** A short name, lower-case letters, digits, - and _. Jumps point at it. */
|
|
60
|
+
id: string;
|
|
61
|
+
title?: string | null;
|
|
62
|
+
body?: string | null;
|
|
63
|
+
/** One of the organization's public pictures (the builder's side). */
|
|
64
|
+
pictureFileId?: Uuid | null;
|
|
65
|
+
/** The picture's public address (the store resolves it for the public page). */
|
|
66
|
+
pictureUrl?: string | null;
|
|
67
|
+
buttonLabel?: string | null;
|
|
68
|
+
/** A secure page on the organization's own sites — the thank-you's own rule. */
|
|
69
|
+
redirectUrl?: string | null;
|
|
70
|
+
when?: RuleExpression | null;
|
|
71
|
+
scoreMin?: number | null;
|
|
72
|
+
scoreMax?: number | null;
|
|
73
|
+
}
|
|
74
|
+
/** THE WELCOME SCREEN, before question one: a title, a message, a picture and a Start button. */
|
|
75
|
+
interface FormWelcome {
|
|
76
|
+
title?: string | null;
|
|
77
|
+
body?: string | null;
|
|
78
|
+
pictureFileId?: Uuid | null;
|
|
79
|
+
pictureUrl?: string | null;
|
|
80
|
+
buttonLabel?: string | null;
|
|
81
|
+
}
|
|
82
|
+
/** The look. Tokens, so light and dark both come out right without a second theme. */
|
|
83
|
+
interface FormTheme {
|
|
84
|
+
/** A design-system accent class or a CSS color. Left out, the app's own accent. */
|
|
85
|
+
accent?: string | null;
|
|
86
|
+
align?: "left" | "center" | null;
|
|
87
|
+
/** One of design-system `FORM_FONTS`. */
|
|
88
|
+
font?: string | null;
|
|
89
|
+
/** One of design-system `FORM_BUTTON_STYLES`. */
|
|
90
|
+
button?: string | null;
|
|
91
|
+
/** One of design-system `FORM_BACKGROUNDS`. */
|
|
92
|
+
background?: string | null;
|
|
93
|
+
/** The picture for the `picture` background: a public picture of the organization. */
|
|
94
|
+
backgroundFileId?: Uuid | null;
|
|
95
|
+
/** Its public address, as the store resolved it for the public page. */
|
|
96
|
+
backgroundUrl?: string | null;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* THE FORM'S OWN LOOK, in the portal's words (`custom._portal_style` resolves both): a colour of
|
|
100
|
+
* the app's own palette and two of the organization's PUBLIC pictures. Each part left out is the
|
|
101
|
+
* organization's look — its newest open portal's, then its own name and logo. `custom.form_declare`
|
|
102
|
+
* refuses a colour the app does not have or a picture a stranger could not see, by name.
|
|
103
|
+
*/
|
|
104
|
+
interface FormLook {
|
|
105
|
+
accent?: PortalAccent | null;
|
|
106
|
+
logoFileId?: Uuid | null;
|
|
107
|
+
coverFileId?: Uuid | null;
|
|
108
|
+
}
|
|
109
|
+
/** The screen after sending: the form's words, and optionally where to go next. */
|
|
110
|
+
interface FormThankYou {
|
|
111
|
+
title?: string | null;
|
|
112
|
+
body?: string | null;
|
|
113
|
+
/** A secure page on one of the organization's own sites. The store judges it. */
|
|
114
|
+
redirectUrl?: string | null;
|
|
115
|
+
}
|
|
116
|
+
/** THE COMPLETE DECLARATIVE SPEC. One `record_write` and the form exists. */
|
|
117
|
+
interface FormSpec {
|
|
118
|
+
name: string;
|
|
119
|
+
/** The Table a submission lands in. */
|
|
120
|
+
subject: Uuid;
|
|
121
|
+
intro?: string | null;
|
|
122
|
+
questions: FormQuestionSpec[];
|
|
123
|
+
flow?: FormFlow | null;
|
|
124
|
+
theme?: FormTheme | null;
|
|
125
|
+
/** Colour, logo and cover a stranger sees. Left out, the organization's look. */
|
|
126
|
+
look?: FormLook | null;
|
|
127
|
+
/**
|
|
128
|
+
* WHAT THE PERSON SEES AFTER SENDING. `title` and `body` are the form's own
|
|
129
|
+
* words for the next step ("You are all set" / "Next, book your first visit").
|
|
130
|
+
* `redirectUrl` optionally sends them on to a page instead — and only ever to
|
|
131
|
+
* one of the organization's own sites: `custom.form_declare` refuses anything
|
|
132
|
+
* else by name, and `custom.form_public` stops handing it out the moment its
|
|
133
|
+
* site leaves the organization's list (lane S7-PRIME).
|
|
134
|
+
*/
|
|
135
|
+
thankYou?: FormThankYou | null;
|
|
136
|
+
submitLabel?: string | null;
|
|
137
|
+
/** A separate first screen with a Start button (lane TYPEFORM-DUP). */
|
|
138
|
+
welcome?: FormWelcome | null;
|
|
139
|
+
/** Several endings, each picked by the answers (lane TYPEFORM-DUP). */
|
|
140
|
+
endings?: FormEnding[] | null;
|
|
141
|
+
/**
|
|
142
|
+
* HIDDEN FIELDS: names read from the link (`?utm_source=…&ref=…`), kept on the submission and
|
|
143
|
+
* never shown. Not questions — a question with the same key is prefilled instead.
|
|
144
|
+
*/
|
|
145
|
+
hiddenFields?: string[] | null;
|
|
146
|
+
/**
|
|
147
|
+
* Is this form meant to be answerable by someone who is not signed in? The
|
|
148
|
+
* runner does NOT make that true by itself — it needs the anonymous write
|
|
149
|
+
* door, and until that door exists it says so BY NAME rather than writing as
|
|
150
|
+
* whoever happens to be signed in and calling it public.
|
|
151
|
+
*/
|
|
152
|
+
isPublic?: boolean;
|
|
153
|
+
/**
|
|
154
|
+
* THE OWNER'S LOGO AND NAME ABOVE THE FORM (lane TYPEFORM-2). Left out, the organization's knob
|
|
155
|
+
* `forms/show_owner_header` (default on); false hides the agency's brand on a client's form.
|
|
156
|
+
*/
|
|
157
|
+
showOwnerHeader?: boolean | null;
|
|
158
|
+
/** A single choice goes on to the next question when picked. Left out, knob `forms/choice_auto_advance`. */
|
|
159
|
+
autoAdvance?: boolean | null;
|
|
160
|
+
/** NOTIFY ON ANSWER, the builder's words (lane TYPEFORM-2): a webhook and the automation that sends it. */
|
|
161
|
+
notify?: FormNotify | null;
|
|
162
|
+
}
|
|
163
|
+
/** Where an answer is sent besides the owner's own subscription (lane TYPEFORM-2). */
|
|
164
|
+
interface FormNotify {
|
|
165
|
+
webhookUrl?: string | null;
|
|
166
|
+
/** The `custom.automation_declare` row that posts to `webhookUrl` (trigger form_answered). */
|
|
167
|
+
webhookAutomationId?: Uuid | null;
|
|
168
|
+
/**
|
|
169
|
+
* EMAIL THE RESPONDENT (TYPEFORM-2), off unless set: one email to the address the person typed
|
|
170
|
+
* in `respondentField` (an email question), worded from the ending reached — sent by
|
|
171
|
+
* `custom.form_respondent_copy` through the platform's notification sender.
|
|
172
|
+
*/
|
|
173
|
+
emailRespondent?: boolean | null;
|
|
174
|
+
respondentField?: string | null;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* A form as `custom.forms` reports it — the spec a screen renders, plus the
|
|
178
|
+
* things only the STORE knows about it.
|
|
179
|
+
*
|
|
180
|
+
* The four store-side ids are carried on purpose. `custom.form_declare` is a
|
|
181
|
+
* RE-STATEMENT of the whole form, so a save that left `notifyRuleId` out would
|
|
182
|
+
* set it to null and the owner would quietly stop being told when somebody
|
|
183
|
+
* answers — the exact silent failure the notify Rule exists to prevent. They are
|
|
184
|
+
* read here and handed straight back by `formDeclareArgs`.
|
|
185
|
+
*/
|
|
186
|
+
interface SavedForm extends FormSpec {
|
|
187
|
+
id: Uuid;
|
|
188
|
+
/** draft · open · closed · full — the store's own word, never derived on a screen. */
|
|
189
|
+
state: FormSummary["state"];
|
|
190
|
+
/** The form's readable name in the store. `form_declare` keeps it across saves. */
|
|
191
|
+
slug: string;
|
|
192
|
+
/** Stops taking answers at this many. Null is no ceiling. */
|
|
193
|
+
submissionCap: number | null;
|
|
194
|
+
/** The accept Rule: what counts as a complete answer. Null holds every answer for a person. */
|
|
195
|
+
quarantineRuleId: Uuid | null;
|
|
196
|
+
/** The subscription Rule that tells somebody an answer arrived. */
|
|
197
|
+
notifyRuleId: Uuid | null;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* The spec as `custom.anon_form.presentation` holds it.
|
|
201
|
+
*
|
|
202
|
+
* `questions` is deliberately NOT here: the door writes it itself from the
|
|
203
|
+
* argument it validated (`presentation || {"questions": p_questions}`), so the
|
|
204
|
+
* words a form is asked in and the keys it is allowed to accept can never be two
|
|
205
|
+
* different lists.
|
|
206
|
+
*/
|
|
207
|
+
declare function formPresentation(spec: FormSpec): Record<string, unknown>;
|
|
208
|
+
/** `presentation.notify` back into the screen's words. */
|
|
209
|
+
declare function notifyFromDocument(raw: unknown): FormNotify | null;
|
|
210
|
+
/**
|
|
211
|
+
* WHAT A QUESTION REFUSES BEFORE IT GOES ON (lane TYPEFORM-2) — Typeform's words, one per case.
|
|
212
|
+
* `null` is "may go on". A required question with no answer is refused; an answer of the email,
|
|
213
|
+
* phone or link kind is refused when it cannot be one. The store judges again on send.
|
|
214
|
+
*/
|
|
215
|
+
declare function answerRefusal(kind: string, required: boolean, value: unknown): string | null;
|
|
216
|
+
/**
|
|
217
|
+
* ANSWER PIPING — Typeform's recall (lane TYPEFORM-2). `{{key}}` or `{{Question words}}` in a later
|
|
218
|
+
* question, a help line or an ending becomes that question's answer as the person gave it; a
|
|
219
|
+
* choice reads as its label. Unanswered, it becomes nothing.
|
|
220
|
+
*/
|
|
221
|
+
declare function pipeAnswers(text: string, answers: Readonly<Record<string, unknown>>, questions: ReadonlyArray<{
|
|
222
|
+
key: string;
|
|
223
|
+
ask?: string | null;
|
|
224
|
+
}>, labelOf?: (key: string, value: unknown) => string | null): string;
|
|
225
|
+
/** `presentation.theme` from the screen's words: camelCase out, the store's snake_case in. */
|
|
226
|
+
declare function themeDocument(theme: FormTheme | null): Record<string, unknown>;
|
|
227
|
+
declare function themeFromDocument(raw: unknown): FormTheme | null;
|
|
228
|
+
declare function welcomeDocument(welcome: FormWelcome | null): Record<string, unknown> | null;
|
|
229
|
+
declare function welcomeFromDocument(raw: unknown): FormWelcome | null;
|
|
230
|
+
declare function endingDocument(ending: FormEnding): Record<string, unknown>;
|
|
231
|
+
declare function endingsFromDocument(raw: unknown): FormEnding[];
|
|
232
|
+
/** The hidden fields' values out of a link's query, narrowed to the names the form declares. */
|
|
233
|
+
declare function hiddenFromLink(hiddenFields: readonly string[] | null | undefined, params: Record<string, string | string[] | undefined>): Record<string, string>;
|
|
234
|
+
/** Does this form route at all — conditions, jumps, endings or points the store must judge? */
|
|
235
|
+
declare function formRoutes(form: Pick<FormSpec, "questions" | "endings">): boolean;
|
|
236
|
+
/** HOW A FORM GOES INTO SOMEBODY ELSE'S PAGE. */
|
|
237
|
+
declare const FORM_EMBEDS: readonly ["inline", "popup", "slider"];
|
|
238
|
+
type FormEmbed = (typeof FORM_EMBEDS)[number];
|
|
239
|
+
/**
|
|
240
|
+
* THE SNIPPET THE OWNER COPIES (lane TYPEFORM-DUP). `inline` is a plain iframe of the public link
|
|
241
|
+
* in embed mode; `popup` and `slider` are one button plus the platform's own embed script
|
|
242
|
+
* (`<origin>/embed/form.js`), which opens the same iframe in a centred window or a side panel.
|
|
243
|
+
* Nothing in either needs a cookie: the form keeps its place in its own storage and posts to its
|
|
244
|
+
* own origin, so it keeps working with third-party cookies blocked.
|
|
245
|
+
*/
|
|
246
|
+
declare function formEmbedSnippet(kind: FormEmbed, formUrl: string, options?: {
|
|
247
|
+
label?: string | null;
|
|
248
|
+
height?: number | null;
|
|
249
|
+
}): string;
|
|
250
|
+
/** `presentation.look` both directions. Nothing set is `null`, one spelling on both sides. */
|
|
251
|
+
declare function formLookDocument(look: FormLook | null): Record<string, unknown> | null;
|
|
252
|
+
declare function formLookFromDocument(raw: unknown): FormLook | null;
|
|
253
|
+
/**
|
|
254
|
+
* THE THANK-YOU SCREEN, BOTH DIRECTIONS, IN ONE PLACE. The store holds it as
|
|
255
|
+
* `presentation.thank_you = {title, body, redirect_url}`; the screen reads it as
|
|
256
|
+
* `FormThankYou`. A thank-you with nothing in it is `null`, so "nothing set"
|
|
257
|
+
* has one spelling on both sides.
|
|
258
|
+
*/
|
|
259
|
+
declare function thankYouDocument(thankYou: FormThankYou | null): Record<string, unknown> | null;
|
|
260
|
+
/** `presentation.thank_you` as the store (or `custom.form_public`) answers it, for a screen. */
|
|
261
|
+
declare function thankYouFromDocument(raw: unknown): FormThankYou | null;
|
|
262
|
+
/** The exact arguments `custom.form_declare` is called with, for a new form or a re-statement. */
|
|
263
|
+
declare function formDeclareArgs(form: FormSpec | SavedForm): {
|
|
264
|
+
table_id: Uuid;
|
|
265
|
+
title: string;
|
|
266
|
+
questions: FormQuestionSpec[];
|
|
267
|
+
presentation: Record<string, unknown>;
|
|
268
|
+
submission_cap: number | null;
|
|
269
|
+
quarantine_rule_id: Uuid | null;
|
|
270
|
+
notify_rule_id: Uuid | null;
|
|
271
|
+
form_id: Uuid | null;
|
|
272
|
+
slug: string | null;
|
|
273
|
+
};
|
|
274
|
+
/** One row of `custom.forms` back into the spec a screen and an agent both read. */
|
|
275
|
+
declare function formFromSummary(summary: FormSummary): SavedForm;
|
|
276
|
+
/**
|
|
277
|
+
* THE SOURCE STAMP every submission carries. A record that arrived through a
|
|
278
|
+
* form is not indistinguishable from one somebody typed into the grid: it says
|
|
279
|
+
* which form, which version of it, when, and who was acting. `_source` is a
|
|
280
|
+
* stamp on the document beside the answers, so it travels with the record
|
|
281
|
+
* through export, History and the agent's context without a parallel table.
|
|
282
|
+
*/
|
|
283
|
+
declare function submissionStamp(args: {
|
|
284
|
+
formId: Uuid | null;
|
|
285
|
+
formName: string;
|
|
286
|
+
actor: string;
|
|
287
|
+
onBehalfOf?: string | null;
|
|
288
|
+
}): Record<string, unknown>;
|
|
289
|
+
|
|
290
|
+
interface PublicBindingShape {
|
|
291
|
+
render_mode: string;
|
|
292
|
+
resource_id: Uuid;
|
|
293
|
+
/** What the door says the address holds. */
|
|
294
|
+
kind: string | null | undefined;
|
|
295
|
+
/** The table a list reads: the table itself, a view's subject, a record's table. */
|
|
296
|
+
table_id: Uuid | null | undefined;
|
|
297
|
+
}
|
|
298
|
+
type PublicRead = {
|
|
299
|
+
read: "table";
|
|
300
|
+
tableId: Uuid;
|
|
301
|
+
} | {
|
|
302
|
+
read: "view";
|
|
303
|
+
tableId: Uuid;
|
|
304
|
+
viewId: Uuid;
|
|
305
|
+
} | {
|
|
306
|
+
read: "record";
|
|
307
|
+
recordId: Uuid;
|
|
308
|
+
} | {
|
|
309
|
+
read: "unknown";
|
|
310
|
+
};
|
|
311
|
+
declare function publicReadOf(binding: PublicBindingShape): PublicRead;
|
|
312
|
+
|
|
313
|
+
interface TypedAnswers {
|
|
314
|
+
/** Ready for the door. */
|
|
315
|
+
values: Record<string, unknown>;
|
|
316
|
+
/**
|
|
317
|
+
* The sentences, in the order the page asks its questions, or null when
|
|
318
|
+
* every answer became a value. Each one names its Field in plain words.
|
|
319
|
+
*/
|
|
320
|
+
refusal: string | null;
|
|
321
|
+
/** Field key → its sentence, so a screen can point at the question. */
|
|
322
|
+
byKey: Record<string, string>;
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Coerce what a public page collected against the Fields that page published.
|
|
326
|
+
*
|
|
327
|
+
* `fields` is exactly what `custom.form_public` / `custom.booking_public`
|
|
328
|
+
* already hand back — the Field definitions of the questions being asked — so
|
|
329
|
+
* nothing new is read and no door is opened to work this out.
|
|
330
|
+
*/
|
|
331
|
+
declare function typedAnswersFor(fields: Array<Record<string, unknown>> | null | undefined, values: Record<string, unknown>): TypedAnswers;
|
|
332
|
+
|
|
333
|
+
export { FORM_EMBEDS, FORM_FLOWS, FORM_STATE_WORDS, type FormEmbed, type FormEnding, type FormFlow, type FormJump, type FormLook, type FormNotify, type FormQuestionSpec, type FormSpec, type FormThankYou, type FormTheme, type FormWelcome, type PublicBindingShape, type PublicRead, type SavedForm, type TypedAnswers, answerRefusal, endingDocument, endingsFromDocument, formDeclareArgs, formEmbedSnippet, formFromSummary, formLookDocument, formLookFromDocument, formPresentation, formRoutes, hiddenFromLink, notifyFromDocument, pipeAnswers, publicReadOf, submissionStamp, thankYouDocument, thankYouFromDocument, themeDocument, themeFromDocument, typedAnswersFor, welcomeDocument, welcomeFromDocument };
|
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
import { k as PortalAccent } from '../portal-Db4CYyHe.js';
|
|
2
|
+
import { F as FormSummary, R as RuleExpression } from '../rule-B8kR0l01.js';
|
|
3
|
+
import { U as Uuid } from '../record-BQi92d4-.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* THE WORDS FOR EACH STATE, SAID ONCE, FOR EVERY SCREEN THAT SHOWS A FORM.
|
|
7
|
+
*
|
|
8
|
+
* `FormsPanel` and `FormBuilder` both put a form in front of a person and both
|
|
9
|
+
* offer the one act that changes this (`custom.anon_publish`). Two copies of
|
|
10
|
+
* these four sentences is two places for them to drift, and a person who reads
|
|
11
|
+
* "Not published" on one screen and something else on the other has been lied
|
|
12
|
+
* to by one of them. The store owns the state; this owns the sentence.
|
|
13
|
+
*/
|
|
14
|
+
declare const FORM_STATE_WORDS: Record<FormSummary["state"], string>;
|
|
15
|
+
/** How a form is put in front of a person. */
|
|
16
|
+
declare const FORM_FLOWS: readonly ["one-at-a-time", "single-page"];
|
|
17
|
+
type FormFlow = (typeof FORM_FLOWS)[number];
|
|
18
|
+
/** One question. It ASKS FOR one Field of the subject Table — never its own column. */
|
|
19
|
+
interface FormQuestionSpec {
|
|
20
|
+
/** The Field's key on the subject Table. */
|
|
21
|
+
field: string;
|
|
22
|
+
/** Ask it in the form's own words. Left out, the Field's own label is the question. */
|
|
23
|
+
ask?: string | null;
|
|
24
|
+
/** One line under the question. */
|
|
25
|
+
help?: string | null;
|
|
26
|
+
/** Override the Field's own `required`. Left out, the Field decides. */
|
|
27
|
+
required?: boolean | null;
|
|
28
|
+
/**
|
|
29
|
+
* CONDITIONAL LOGIC, AS A RULE. `{"op":"eq","args":[{"field":"<field id>"},{"const":"Yes"}]}`
|
|
30
|
+
* — the store answers it, this package never does. An UNDECIDED answer (the
|
|
31
|
+
* store's `null`, which is what an unanswered question gives) SHOWS the
|
|
32
|
+
* question: a person is never silently skipped past something.
|
|
33
|
+
*/
|
|
34
|
+
showIf?: RuleExpression | null;
|
|
35
|
+
/**
|
|
36
|
+
* LOGIC JUMPS (lane TYPEFORM-DUP). After this question, the FIRST jump whose `when` the store
|
|
37
|
+
* answers true is taken — to a later question or to one of the form's endings. A jump with no
|
|
38
|
+
* `when` is "always". Undecided falls through to the next question. The store judges the route
|
|
39
|
+
* (`custom._form_route`); this package never does.
|
|
40
|
+
*/
|
|
41
|
+
jumps?: FormJump[] | null;
|
|
42
|
+
/** SCORING: what each answer is worth (`{"Yes": 5}`); a list answer adds each of its parts. */
|
|
43
|
+
points?: Record<string, number> | null;
|
|
44
|
+
}
|
|
45
|
+
/** One logic jump: when the Rule is true, go to a later question or to an ending. */
|
|
46
|
+
interface FormJump {
|
|
47
|
+
when?: RuleExpression | null;
|
|
48
|
+
to: {
|
|
49
|
+
question: string;
|
|
50
|
+
} | {
|
|
51
|
+
ending: string;
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* ONE ENDING (lane TYPEFORM-DUP). A form may have several; a jump picks one, or the first whose
|
|
56
|
+
* condition holds (`when`, `scoreMin`, `scoreMax`), or else the first with no condition.
|
|
57
|
+
*/
|
|
58
|
+
interface FormEnding {
|
|
59
|
+
/** A short name, lower-case letters, digits, - and _. Jumps point at it. */
|
|
60
|
+
id: string;
|
|
61
|
+
title?: string | null;
|
|
62
|
+
body?: string | null;
|
|
63
|
+
/** One of the organization's public pictures (the builder's side). */
|
|
64
|
+
pictureFileId?: Uuid | null;
|
|
65
|
+
/** The picture's public address (the store resolves it for the public page). */
|
|
66
|
+
pictureUrl?: string | null;
|
|
67
|
+
buttonLabel?: string | null;
|
|
68
|
+
/** A secure page on the organization's own sites — the thank-you's own rule. */
|
|
69
|
+
redirectUrl?: string | null;
|
|
70
|
+
when?: RuleExpression | null;
|
|
71
|
+
scoreMin?: number | null;
|
|
72
|
+
scoreMax?: number | null;
|
|
73
|
+
}
|
|
74
|
+
/** THE WELCOME SCREEN, before question one: a title, a message, a picture and a Start button. */
|
|
75
|
+
interface FormWelcome {
|
|
76
|
+
title?: string | null;
|
|
77
|
+
body?: string | null;
|
|
78
|
+
pictureFileId?: Uuid | null;
|
|
79
|
+
pictureUrl?: string | null;
|
|
80
|
+
buttonLabel?: string | null;
|
|
81
|
+
}
|
|
82
|
+
/** The look. Tokens, so light and dark both come out right without a second theme. */
|
|
83
|
+
interface FormTheme {
|
|
84
|
+
/** A design-system accent class or a CSS color. Left out, the app's own accent. */
|
|
85
|
+
accent?: string | null;
|
|
86
|
+
align?: "left" | "center" | null;
|
|
87
|
+
/** One of design-system `FORM_FONTS`. */
|
|
88
|
+
font?: string | null;
|
|
89
|
+
/** One of design-system `FORM_BUTTON_STYLES`. */
|
|
90
|
+
button?: string | null;
|
|
91
|
+
/** One of design-system `FORM_BACKGROUNDS`. */
|
|
92
|
+
background?: string | null;
|
|
93
|
+
/** The picture for the `picture` background: a public picture of the organization. */
|
|
94
|
+
backgroundFileId?: Uuid | null;
|
|
95
|
+
/** Its public address, as the store resolved it for the public page. */
|
|
96
|
+
backgroundUrl?: string | null;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* THE FORM'S OWN LOOK, in the portal's words (`custom._portal_style` resolves both): a colour of
|
|
100
|
+
* the app's own palette and two of the organization's PUBLIC pictures. Each part left out is the
|
|
101
|
+
* organization's look — its newest open portal's, then its own name and logo. `custom.form_declare`
|
|
102
|
+
* refuses a colour the app does not have or a picture a stranger could not see, by name.
|
|
103
|
+
*/
|
|
104
|
+
interface FormLook {
|
|
105
|
+
accent?: PortalAccent | null;
|
|
106
|
+
logoFileId?: Uuid | null;
|
|
107
|
+
coverFileId?: Uuid | null;
|
|
108
|
+
}
|
|
109
|
+
/** The screen after sending: the form's words, and optionally where to go next. */
|
|
110
|
+
interface FormThankYou {
|
|
111
|
+
title?: string | null;
|
|
112
|
+
body?: string | null;
|
|
113
|
+
/** A secure page on one of the organization's own sites. The store judges it. */
|
|
114
|
+
redirectUrl?: string | null;
|
|
115
|
+
}
|
|
116
|
+
/** THE COMPLETE DECLARATIVE SPEC. One `record_write` and the form exists. */
|
|
117
|
+
interface FormSpec {
|
|
118
|
+
name: string;
|
|
119
|
+
/** The Table a submission lands in. */
|
|
120
|
+
subject: Uuid;
|
|
121
|
+
intro?: string | null;
|
|
122
|
+
questions: FormQuestionSpec[];
|
|
123
|
+
flow?: FormFlow | null;
|
|
124
|
+
theme?: FormTheme | null;
|
|
125
|
+
/** Colour, logo and cover a stranger sees. Left out, the organization's look. */
|
|
126
|
+
look?: FormLook | null;
|
|
127
|
+
/**
|
|
128
|
+
* WHAT THE PERSON SEES AFTER SENDING. `title` and `body` are the form's own
|
|
129
|
+
* words for the next step ("You are all set" / "Next, book your first visit").
|
|
130
|
+
* `redirectUrl` optionally sends them on to a page instead — and only ever to
|
|
131
|
+
* one of the organization's own sites: `custom.form_declare` refuses anything
|
|
132
|
+
* else by name, and `custom.form_public` stops handing it out the moment its
|
|
133
|
+
* site leaves the organization's list (lane S7-PRIME).
|
|
134
|
+
*/
|
|
135
|
+
thankYou?: FormThankYou | null;
|
|
136
|
+
submitLabel?: string | null;
|
|
137
|
+
/** A separate first screen with a Start button (lane TYPEFORM-DUP). */
|
|
138
|
+
welcome?: FormWelcome | null;
|
|
139
|
+
/** Several endings, each picked by the answers (lane TYPEFORM-DUP). */
|
|
140
|
+
endings?: FormEnding[] | null;
|
|
141
|
+
/**
|
|
142
|
+
* HIDDEN FIELDS: names read from the link (`?utm_source=…&ref=…`), kept on the submission and
|
|
143
|
+
* never shown. Not questions — a question with the same key is prefilled instead.
|
|
144
|
+
*/
|
|
145
|
+
hiddenFields?: string[] | null;
|
|
146
|
+
/**
|
|
147
|
+
* Is this form meant to be answerable by someone who is not signed in? The
|
|
148
|
+
* runner does NOT make that true by itself — it needs the anonymous write
|
|
149
|
+
* door, and until that door exists it says so BY NAME rather than writing as
|
|
150
|
+
* whoever happens to be signed in and calling it public.
|
|
151
|
+
*/
|
|
152
|
+
isPublic?: boolean;
|
|
153
|
+
/**
|
|
154
|
+
* THE OWNER'S LOGO AND NAME ABOVE THE FORM (lane TYPEFORM-2). Left out, the organization's knob
|
|
155
|
+
* `forms/show_owner_header` (default on); false hides the agency's brand on a client's form.
|
|
156
|
+
*/
|
|
157
|
+
showOwnerHeader?: boolean | null;
|
|
158
|
+
/** A single choice goes on to the next question when picked. Left out, knob `forms/choice_auto_advance`. */
|
|
159
|
+
autoAdvance?: boolean | null;
|
|
160
|
+
/** NOTIFY ON ANSWER, the builder's words (lane TYPEFORM-2): a webhook and the automation that sends it. */
|
|
161
|
+
notify?: FormNotify | null;
|
|
162
|
+
}
|
|
163
|
+
/** Where an answer is sent besides the owner's own subscription (lane TYPEFORM-2). */
|
|
164
|
+
interface FormNotify {
|
|
165
|
+
webhookUrl?: string | null;
|
|
166
|
+
/** The `custom.automation_declare` row that posts to `webhookUrl` (trigger form_answered). */
|
|
167
|
+
webhookAutomationId?: Uuid | null;
|
|
168
|
+
/**
|
|
169
|
+
* EMAIL THE RESPONDENT (TYPEFORM-2), off unless set: one email to the address the person typed
|
|
170
|
+
* in `respondentField` (an email question), worded from the ending reached — sent by
|
|
171
|
+
* `custom.form_respondent_copy` through the platform's notification sender.
|
|
172
|
+
*/
|
|
173
|
+
emailRespondent?: boolean | null;
|
|
174
|
+
respondentField?: string | null;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* A form as `custom.forms` reports it — the spec a screen renders, plus the
|
|
178
|
+
* things only the STORE knows about it.
|
|
179
|
+
*
|
|
180
|
+
* The four store-side ids are carried on purpose. `custom.form_declare` is a
|
|
181
|
+
* RE-STATEMENT of the whole form, so a save that left `notifyRuleId` out would
|
|
182
|
+
* set it to null and the owner would quietly stop being told when somebody
|
|
183
|
+
* answers — the exact silent failure the notify Rule exists to prevent. They are
|
|
184
|
+
* read here and handed straight back by `formDeclareArgs`.
|
|
185
|
+
*/
|
|
186
|
+
interface SavedForm extends FormSpec {
|
|
187
|
+
id: Uuid;
|
|
188
|
+
/** draft · open · closed · full — the store's own word, never derived on a screen. */
|
|
189
|
+
state: FormSummary["state"];
|
|
190
|
+
/** The form's readable name in the store. `form_declare` keeps it across saves. */
|
|
191
|
+
slug: string;
|
|
192
|
+
/** Stops taking answers at this many. Null is no ceiling. */
|
|
193
|
+
submissionCap: number | null;
|
|
194
|
+
/** The accept Rule: what counts as a complete answer. Null holds every answer for a person. */
|
|
195
|
+
quarantineRuleId: Uuid | null;
|
|
196
|
+
/** The subscription Rule that tells somebody an answer arrived. */
|
|
197
|
+
notifyRuleId: Uuid | null;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* The spec as `custom.anon_form.presentation` holds it.
|
|
201
|
+
*
|
|
202
|
+
* `questions` is deliberately NOT here: the door writes it itself from the
|
|
203
|
+
* argument it validated (`presentation || {"questions": p_questions}`), so the
|
|
204
|
+
* words a form is asked in and the keys it is allowed to accept can never be two
|
|
205
|
+
* different lists.
|
|
206
|
+
*/
|
|
207
|
+
declare function formPresentation(spec: FormSpec): Record<string, unknown>;
|
|
208
|
+
/** `presentation.notify` back into the screen's words. */
|
|
209
|
+
declare function notifyFromDocument(raw: unknown): FormNotify | null;
|
|
210
|
+
/**
|
|
211
|
+
* WHAT A QUESTION REFUSES BEFORE IT GOES ON (lane TYPEFORM-2) — Typeform's words, one per case.
|
|
212
|
+
* `null` is "may go on". A required question with no answer is refused; an answer of the email,
|
|
213
|
+
* phone or link kind is refused when it cannot be one. The store judges again on send.
|
|
214
|
+
*/
|
|
215
|
+
declare function answerRefusal(kind: string, required: boolean, value: unknown): string | null;
|
|
216
|
+
/**
|
|
217
|
+
* ANSWER PIPING — Typeform's recall (lane TYPEFORM-2). `{{key}}` or `{{Question words}}` in a later
|
|
218
|
+
* question, a help line or an ending becomes that question's answer as the person gave it; a
|
|
219
|
+
* choice reads as its label. Unanswered, it becomes nothing.
|
|
220
|
+
*/
|
|
221
|
+
declare function pipeAnswers(text: string, answers: Readonly<Record<string, unknown>>, questions: ReadonlyArray<{
|
|
222
|
+
key: string;
|
|
223
|
+
ask?: string | null;
|
|
224
|
+
}>, labelOf?: (key: string, value: unknown) => string | null): string;
|
|
225
|
+
/** `presentation.theme` from the screen's words: camelCase out, the store's snake_case in. */
|
|
226
|
+
declare function themeDocument(theme: FormTheme | null): Record<string, unknown>;
|
|
227
|
+
declare function themeFromDocument(raw: unknown): FormTheme | null;
|
|
228
|
+
declare function welcomeDocument(welcome: FormWelcome | null): Record<string, unknown> | null;
|
|
229
|
+
declare function welcomeFromDocument(raw: unknown): FormWelcome | null;
|
|
230
|
+
declare function endingDocument(ending: FormEnding): Record<string, unknown>;
|
|
231
|
+
declare function endingsFromDocument(raw: unknown): FormEnding[];
|
|
232
|
+
/** The hidden fields' values out of a link's query, narrowed to the names the form declares. */
|
|
233
|
+
declare function hiddenFromLink(hiddenFields: readonly string[] | null | undefined, params: Record<string, string | string[] | undefined>): Record<string, string>;
|
|
234
|
+
/** Does this form route at all — conditions, jumps, endings or points the store must judge? */
|
|
235
|
+
declare function formRoutes(form: Pick<FormSpec, "questions" | "endings">): boolean;
|
|
236
|
+
/** HOW A FORM GOES INTO SOMEBODY ELSE'S PAGE. */
|
|
237
|
+
declare const FORM_EMBEDS: readonly ["inline", "popup", "slider"];
|
|
238
|
+
type FormEmbed = (typeof FORM_EMBEDS)[number];
|
|
239
|
+
/**
|
|
240
|
+
* THE SNIPPET THE OWNER COPIES (lane TYPEFORM-DUP). `inline` is a plain iframe of the public link
|
|
241
|
+
* in embed mode; `popup` and `slider` are one button plus the platform's own embed script
|
|
242
|
+
* (`<origin>/embed/form.js`), which opens the same iframe in a centred window or a side panel.
|
|
243
|
+
* Nothing in either needs a cookie: the form keeps its place in its own storage and posts to its
|
|
244
|
+
* own origin, so it keeps working with third-party cookies blocked.
|
|
245
|
+
*/
|
|
246
|
+
declare function formEmbedSnippet(kind: FormEmbed, formUrl: string, options?: {
|
|
247
|
+
label?: string | null;
|
|
248
|
+
height?: number | null;
|
|
249
|
+
}): string;
|
|
250
|
+
/** `presentation.look` both directions. Nothing set is `null`, one spelling on both sides. */
|
|
251
|
+
declare function formLookDocument(look: FormLook | null): Record<string, unknown> | null;
|
|
252
|
+
declare function formLookFromDocument(raw: unknown): FormLook | null;
|
|
253
|
+
/**
|
|
254
|
+
* THE THANK-YOU SCREEN, BOTH DIRECTIONS, IN ONE PLACE. The store holds it as
|
|
255
|
+
* `presentation.thank_you = {title, body, redirect_url}`; the screen reads it as
|
|
256
|
+
* `FormThankYou`. A thank-you with nothing in it is `null`, so "nothing set"
|
|
257
|
+
* has one spelling on both sides.
|
|
258
|
+
*/
|
|
259
|
+
declare function thankYouDocument(thankYou: FormThankYou | null): Record<string, unknown> | null;
|
|
260
|
+
/** `presentation.thank_you` as the store (or `custom.form_public`) answers it, for a screen. */
|
|
261
|
+
declare function thankYouFromDocument(raw: unknown): FormThankYou | null;
|
|
262
|
+
/** The exact arguments `custom.form_declare` is called with, for a new form or a re-statement. */
|
|
263
|
+
declare function formDeclareArgs(form: FormSpec | SavedForm): {
|
|
264
|
+
table_id: Uuid;
|
|
265
|
+
title: string;
|
|
266
|
+
questions: FormQuestionSpec[];
|
|
267
|
+
presentation: Record<string, unknown>;
|
|
268
|
+
submission_cap: number | null;
|
|
269
|
+
quarantine_rule_id: Uuid | null;
|
|
270
|
+
notify_rule_id: Uuid | null;
|
|
271
|
+
form_id: Uuid | null;
|
|
272
|
+
slug: string | null;
|
|
273
|
+
};
|
|
274
|
+
/** One row of `custom.forms` back into the spec a screen and an agent both read. */
|
|
275
|
+
declare function formFromSummary(summary: FormSummary): SavedForm;
|
|
276
|
+
/**
|
|
277
|
+
* THE SOURCE STAMP every submission carries. A record that arrived through a
|
|
278
|
+
* form is not indistinguishable from one somebody typed into the grid: it says
|
|
279
|
+
* which form, which version of it, when, and who was acting. `_source` is a
|
|
280
|
+
* stamp on the document beside the answers, so it travels with the record
|
|
281
|
+
* through export, History and the agent's context without a parallel table.
|
|
282
|
+
*/
|
|
283
|
+
declare function submissionStamp(args: {
|
|
284
|
+
formId: Uuid | null;
|
|
285
|
+
formName: string;
|
|
286
|
+
actor: string;
|
|
287
|
+
onBehalfOf?: string | null;
|
|
288
|
+
}): Record<string, unknown>;
|
|
289
|
+
|
|
290
|
+
interface PublicBindingShape {
|
|
291
|
+
render_mode: string;
|
|
292
|
+
resource_id: Uuid;
|
|
293
|
+
/** What the door says the address holds. */
|
|
294
|
+
kind: string | null | undefined;
|
|
295
|
+
/** The table a list reads: the table itself, a view's subject, a record's table. */
|
|
296
|
+
table_id: Uuid | null | undefined;
|
|
297
|
+
}
|
|
298
|
+
type PublicRead = {
|
|
299
|
+
read: "table";
|
|
300
|
+
tableId: Uuid;
|
|
301
|
+
} | {
|
|
302
|
+
read: "view";
|
|
303
|
+
tableId: Uuid;
|
|
304
|
+
viewId: Uuid;
|
|
305
|
+
} | {
|
|
306
|
+
read: "record";
|
|
307
|
+
recordId: Uuid;
|
|
308
|
+
} | {
|
|
309
|
+
read: "unknown";
|
|
310
|
+
};
|
|
311
|
+
declare function publicReadOf(binding: PublicBindingShape): PublicRead;
|
|
312
|
+
|
|
313
|
+
interface TypedAnswers {
|
|
314
|
+
/** Ready for the door. */
|
|
315
|
+
values: Record<string, unknown>;
|
|
316
|
+
/**
|
|
317
|
+
* The sentences, in the order the page asks its questions, or null when
|
|
318
|
+
* every answer became a value. Each one names its Field in plain words.
|
|
319
|
+
*/
|
|
320
|
+
refusal: string | null;
|
|
321
|
+
/** Field key → its sentence, so a screen can point at the question. */
|
|
322
|
+
byKey: Record<string, string>;
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Coerce what a public page collected against the Fields that page published.
|
|
326
|
+
*
|
|
327
|
+
* `fields` is exactly what `custom.form_public` / `custom.booking_public`
|
|
328
|
+
* already hand back — the Field definitions of the questions being asked — so
|
|
329
|
+
* nothing new is read and no door is opened to work this out.
|
|
330
|
+
*/
|
|
331
|
+
declare function typedAnswersFor(fields: Array<Record<string, unknown>> | null | undefined, values: Record<string, unknown>): TypedAnswers;
|
|
332
|
+
|
|
333
|
+
export { FORM_EMBEDS, FORM_FLOWS, FORM_STATE_WORDS, type FormEmbed, type FormEnding, type FormFlow, type FormJump, type FormLook, type FormNotify, type FormQuestionSpec, type FormSpec, type FormThankYou, type FormTheme, type FormWelcome, type PublicBindingShape, type PublicRead, type SavedForm, type TypedAnswers, answerRefusal, endingDocument, endingsFromDocument, formDeclareArgs, formEmbedSnippet, formFromSummary, formLookDocument, formLookFromDocument, formPresentation, formRoutes, hiddenFromLink, notifyFromDocument, pipeAnswers, publicReadOf, submissionStamp, thankYouDocument, thankYouFromDocument, themeDocument, themeFromDocument, typedAnswersFor, welcomeDocument, welcomeFromDocument };
|