@seamlet/astro 1.2.0 → 1.3.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 +12 -0
- package/README.md +65 -0
- package/components/RequestForm.astro +192 -0
- package/dist/bridge.js +2 -2
- package/dist/{chunk-Y4R4YV5O.js → chunk-2GZZHXP5.js} +1 -1
- package/dist/chunk-2IK7D2AA.js +6 -0
- package/dist/{chunk-UL2C2IB2.js → chunk-ENMUO442.js} +262 -4
- package/dist/{chunk-OCA2WYK3.js → chunk-MFD4TJPV.js} +2 -2
- package/dist/{chunk-HFPZVDST.js → chunk-VQKAWFCQ.js} +1 -1
- package/dist/cli.js +1 -1
- package/dist/client.js +8 -0
- package/dist/index.js +3 -3
- package/dist/preview-requests.d.ts +1 -1
- package/dist/preview-requests.js +3 -3
- package/dist/protocol.js +2 -2
- package/dist/request-sending-Y6L55IIM.js +251 -0
- package/dist/routes/media.js +3 -3
- package/dist/schema.d.ts +101 -2
- package/dist/schema.js +61 -1
- package/dist/{site-description-BnHrODQX.d.ts → site-description-DSHyBrAL.d.ts} +99 -1
- package/dist/site.d.ts +11 -6
- package/dist/site.js +19 -3
- package/package.json +3 -2
package/dist/client.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import {
|
|
2
|
+
REQUEST_FORM_SELECTOR
|
|
3
|
+
} from "./chunk-2IK7D2AA.js";
|
|
1
4
|
import {
|
|
2
5
|
PREVIEW_PATH
|
|
3
6
|
} from "./chunk-QCVWHHJC.js";
|
|
@@ -12,3 +15,8 @@ if (isFramed && isPreview) {
|
|
|
12
15
|
connectToEditor({ editorOrigin: cmsOrigin });
|
|
13
16
|
});
|
|
14
17
|
}
|
|
18
|
+
if (document.querySelector(REQUEST_FORM_SELECTOR) !== null) {
|
|
19
|
+
void import("./request-sending-Y6L55IIM.js").then(({ connectRequestForms }) => {
|
|
20
|
+
connectRequestForms(document, { isPreview });
|
|
21
|
+
});
|
|
22
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -8,14 +8,14 @@ import {
|
|
|
8
8
|
} from "./chunk-QCVWHHJC.js";
|
|
9
9
|
import {
|
|
10
10
|
isUploadedPhoto
|
|
11
|
-
} from "./chunk-
|
|
12
|
-
import "./chunk-
|
|
11
|
+
} from "./chunk-MFD4TJPV.js";
|
|
12
|
+
import "./chunk-VQKAWFCQ.js";
|
|
13
13
|
import {
|
|
14
14
|
SITE_CONFIG_FILE,
|
|
15
15
|
SITE_DESCRIPTION_PATH,
|
|
16
16
|
isJsonObject,
|
|
17
17
|
readSiteConfig
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-ENMUO442.js";
|
|
19
19
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
import process from "process";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { C as Content } from './parse-content-Bnn6Wa-l.js';
|
|
2
|
-
import { S as SiteDescription } from './site-description-
|
|
2
|
+
import { S as SiteDescription } from './site-description-DSHyBrAL.js';
|
|
3
3
|
|
|
4
4
|
/** Far more than the content of a site ever takes; a bigger body is not a draft. */
|
|
5
5
|
declare const MAX_DRAFT_BYTES: number;
|
package/dist/preview-requests.js
CHANGED
|
@@ -5,9 +5,9 @@ import {
|
|
|
5
5
|
previewContentAt,
|
|
6
6
|
previewHeadersOf,
|
|
7
7
|
readDraft
|
|
8
|
-
} from "./chunk-
|
|
9
|
-
import "./chunk-
|
|
10
|
-
import "./chunk-
|
|
8
|
+
} from "./chunk-MFD4TJPV.js";
|
|
9
|
+
import "./chunk-VQKAWFCQ.js";
|
|
10
|
+
import "./chunk-ENMUO442.js";
|
|
11
11
|
export {
|
|
12
12
|
MAX_DRAFT_BYTES,
|
|
13
13
|
isPageAddress,
|
package/dist/protocol.js
CHANGED
|
@@ -22,9 +22,9 @@ import {
|
|
|
22
22
|
shortcutOf,
|
|
23
23
|
toggleList,
|
|
24
24
|
toggleMark
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-2GZZHXP5.js";
|
|
26
26
|
import "./chunk-QCVWHHJC.js";
|
|
27
|
-
import "./chunk-
|
|
27
|
+
import "./chunk-ENMUO442.js";
|
|
28
28
|
export {
|
|
29
29
|
OWN_PHOTOS_PATH,
|
|
30
30
|
PROTOCOL_VERSION,
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
import {
|
|
2
|
+
REQUEST_FORM_SELECTOR
|
|
3
|
+
} from "./chunk-2IK7D2AA.js";
|
|
4
|
+
import {
|
|
5
|
+
CONSENT_REQUIRED_TEXT,
|
|
6
|
+
REQUEST_CONSENT_KEY,
|
|
7
|
+
REQUEST_FAILED_EVENT,
|
|
8
|
+
REQUEST_ISSUE_TEXTS,
|
|
9
|
+
REQUEST_SEND_EVENT,
|
|
10
|
+
REQUEST_SENT_EVENT,
|
|
11
|
+
isConsentGiven,
|
|
12
|
+
isJsonObject,
|
|
13
|
+
readRequestForm,
|
|
14
|
+
readRequestValues
|
|
15
|
+
} from "./chunk-ENMUO442.js";
|
|
16
|
+
|
|
17
|
+
// src/request-sending.ts
|
|
18
|
+
var STATUS_CREATED = 201;
|
|
19
|
+
var STATUS_UNPROCESSABLE = 422;
|
|
20
|
+
var STATUS_CONFLICT = 409;
|
|
21
|
+
var STATUS_TOO_MANY = 429;
|
|
22
|
+
var ANSWER_TIMEOUT_MS = 15e3;
|
|
23
|
+
var ISSUE_CODES = [
|
|
24
|
+
"required",
|
|
25
|
+
"too-long",
|
|
26
|
+
"invalid-phone",
|
|
27
|
+
"invalid-email",
|
|
28
|
+
"unknown-option"
|
|
29
|
+
];
|
|
30
|
+
function connectRequestForms(root, options) {
|
|
31
|
+
const elements = root.querySelectorAll(
|
|
32
|
+
REQUEST_FORM_SELECTOR
|
|
33
|
+
);
|
|
34
|
+
for (const element of elements) {
|
|
35
|
+
if (options.isPreview) keepFromSending(element);
|
|
36
|
+
else connectRequestForm(element);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function keepFromSending(element) {
|
|
40
|
+
element.addEventListener("submit", (event) => {
|
|
41
|
+
event.preventDefault();
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
function connectRequestForm(element) {
|
|
45
|
+
const form = formOf(element);
|
|
46
|
+
if (form === void 0) return;
|
|
47
|
+
element.noValidate = true;
|
|
48
|
+
element.addEventListener("submit", (event) => {
|
|
49
|
+
event.preventDefault();
|
|
50
|
+
const isSending = element.dataset["seamletState"] === "sending";
|
|
51
|
+
if (!isSending) void sendRequest(element, form);
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
function formOf(element) {
|
|
55
|
+
const declared = element.dataset["seamletRequestForm"];
|
|
56
|
+
if (declared === void 0) return void 0;
|
|
57
|
+
try {
|
|
58
|
+
const reading = readRequestForm(JSON.parse(declared));
|
|
59
|
+
return reading.status === "read" ? reading.form : void 0;
|
|
60
|
+
} catch {
|
|
61
|
+
return void 0;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
async function sendRequest(element, form) {
|
|
65
|
+
showState(element, "editing");
|
|
66
|
+
const entries = entriesOf(element);
|
|
67
|
+
const issues = issuesOf(form, entries);
|
|
68
|
+
showIssues(element, issues);
|
|
69
|
+
if (issues.length > 0) {
|
|
70
|
+
focusFirstIssue(element, issues);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const isSentBySite = !element.dispatchEvent(
|
|
74
|
+
new CustomEvent(REQUEST_SEND_EVENT, {
|
|
75
|
+
bubbles: true,
|
|
76
|
+
cancelable: true,
|
|
77
|
+
detail: { form: form.id, entries }
|
|
78
|
+
})
|
|
79
|
+
);
|
|
80
|
+
if (isSentBySite) return;
|
|
81
|
+
showState(element, "sending");
|
|
82
|
+
const outcome = await post(element.getAttribute("action") ?? "", entries);
|
|
83
|
+
settle(element, { form, entries, outcome });
|
|
84
|
+
}
|
|
85
|
+
function settle(element, sending) {
|
|
86
|
+
const { form, entries, outcome } = sending;
|
|
87
|
+
switch (outcome.kind) {
|
|
88
|
+
case "received":
|
|
89
|
+
showState(element, "sent");
|
|
90
|
+
HTMLFormElement.prototype.reset.call(element);
|
|
91
|
+
announceSent(element, { form: form.id, entries, id: outcome.id });
|
|
92
|
+
return;
|
|
93
|
+
case "refused":
|
|
94
|
+
showState(element, "failed");
|
|
95
|
+
showIssues(element, outcome.issues);
|
|
96
|
+
focusFirstIssue(element, outcome.issues);
|
|
97
|
+
announceFailure(element, {
|
|
98
|
+
form: form.id,
|
|
99
|
+
reason: outcome.reason,
|
|
100
|
+
issues: outcome.issues
|
|
101
|
+
});
|
|
102
|
+
return;
|
|
103
|
+
case "blocked":
|
|
104
|
+
HTMLFormElement.prototype.submit.call(element);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
function announceSent(element, detail) {
|
|
108
|
+
element.dispatchEvent(
|
|
109
|
+
new CustomEvent(REQUEST_SENT_EVENT, {
|
|
110
|
+
bubbles: true,
|
|
111
|
+
detail
|
|
112
|
+
})
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
function announceFailure(element, detail) {
|
|
116
|
+
element.dispatchEvent(
|
|
117
|
+
new CustomEvent(REQUEST_FAILED_EVENT, {
|
|
118
|
+
bubbles: true,
|
|
119
|
+
detail
|
|
120
|
+
})
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
function entriesOf(element) {
|
|
124
|
+
const data = new FormData(element);
|
|
125
|
+
const pairs = [...data].flatMap(
|
|
126
|
+
([name, value]) => typeof value === "string" ? [[name, value]] : []
|
|
127
|
+
);
|
|
128
|
+
return Object.fromEntries(pairs);
|
|
129
|
+
}
|
|
130
|
+
function issuesOf(form, entries) {
|
|
131
|
+
const reading = readRequestValues(form, entries);
|
|
132
|
+
const fieldIssues = reading.status === "invalid" ? reading.issues : [];
|
|
133
|
+
const consentIssues = isConsentGiven(entries) ? [] : [{ field: REQUEST_CONSENT_KEY, code: "required" }];
|
|
134
|
+
return [...fieldIssues, ...consentIssues];
|
|
135
|
+
}
|
|
136
|
+
async function post(action, entries) {
|
|
137
|
+
const blocked = watchBlocking(action);
|
|
138
|
+
try {
|
|
139
|
+
const answer = await fetch(action, {
|
|
140
|
+
method: "POST",
|
|
141
|
+
headers: {
|
|
142
|
+
"Content-Type": "application/json",
|
|
143
|
+
Accept: "application/json"
|
|
144
|
+
},
|
|
145
|
+
body: JSON.stringify(entries),
|
|
146
|
+
signal: AbortSignal.timeout(ANSWER_TIMEOUT_MS)
|
|
147
|
+
});
|
|
148
|
+
return await outcomeOf(answer);
|
|
149
|
+
} catch {
|
|
150
|
+
return blocked.isBlocked() ? { kind: "blocked" } : { kind: "refused", reason: "unavailable", issues: [] };
|
|
151
|
+
} finally {
|
|
152
|
+
blocked.stop();
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
function watchBlocking(action) {
|
|
156
|
+
const target = new URL(action, document.baseURI).origin;
|
|
157
|
+
let isBlocked = false;
|
|
158
|
+
const hear = (event) => {
|
|
159
|
+
if (originOf(event.blockedURI) === target) isBlocked = true;
|
|
160
|
+
};
|
|
161
|
+
document.addEventListener("securitypolicyviolation", hear);
|
|
162
|
+
return {
|
|
163
|
+
isBlocked: () => isBlocked,
|
|
164
|
+
stop: () => {
|
|
165
|
+
document.removeEventListener("securitypolicyviolation", hear);
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
function originOf(address) {
|
|
170
|
+
try {
|
|
171
|
+
return new URL(address).origin;
|
|
172
|
+
} catch {
|
|
173
|
+
return void 0;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
async function outcomeOf(answer) {
|
|
177
|
+
const body = await answer.json().catch(() => void 0);
|
|
178
|
+
const record = isJsonObject(body) ? body : {};
|
|
179
|
+
const id = record["id"];
|
|
180
|
+
if (answer.status === STATUS_CREATED && typeof id === "string") {
|
|
181
|
+
return { kind: "received", id };
|
|
182
|
+
}
|
|
183
|
+
if (answer.status === STATUS_UNPROCESSABLE) {
|
|
184
|
+
const issues = readIssues(record["issues"]);
|
|
185
|
+
return { kind: "refused", reason: "invalid", issues };
|
|
186
|
+
}
|
|
187
|
+
return { kind: "refused", reason: failureOf(answer.status), issues: [] };
|
|
188
|
+
}
|
|
189
|
+
function failureOf(status) {
|
|
190
|
+
if (status === STATUS_CONFLICT) return "closed";
|
|
191
|
+
if (status === STATUS_TOO_MANY) return "too-many";
|
|
192
|
+
return "unavailable";
|
|
193
|
+
}
|
|
194
|
+
function readIssues(input) {
|
|
195
|
+
if (!Array.isArray(input)) return [];
|
|
196
|
+
const entries = input;
|
|
197
|
+
return entries.flatMap((entry) => {
|
|
198
|
+
if (!isJsonObject(entry)) return [];
|
|
199
|
+
const { field, code } = entry;
|
|
200
|
+
const isIssue = typeof field === "string" && isIssueCode(code);
|
|
201
|
+
return isIssue ? [{ field, code }] : [];
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
function isIssueCode(value) {
|
|
205
|
+
return ISSUE_CODES.some((code) => code === value);
|
|
206
|
+
}
|
|
207
|
+
function showIssues(element, issues) {
|
|
208
|
+
const messages = element.querySelectorAll(
|
|
209
|
+
"[data-seamlet-issue]"
|
|
210
|
+
);
|
|
211
|
+
for (const message of messages) {
|
|
212
|
+
const field = message.dataset["seamletIssue"] ?? "";
|
|
213
|
+
const issue = issues.find((candidate) => candidate.field === field);
|
|
214
|
+
message.textContent = issue === void 0 ? "" : issueText(issue);
|
|
215
|
+
message.hidden = issue === void 0;
|
|
216
|
+
markControl(element, field, issue !== void 0);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
function issueText(issue) {
|
|
220
|
+
return issue.field === REQUEST_CONSENT_KEY ? CONSENT_REQUIRED_TEXT : REQUEST_ISSUE_TEXTS[issue.code];
|
|
221
|
+
}
|
|
222
|
+
function controlOf(element, field) {
|
|
223
|
+
const control = element.querySelector(`[name="${field}"]`);
|
|
224
|
+
return control instanceof HTMLElement ? control : void 0;
|
|
225
|
+
}
|
|
226
|
+
function markControl(element, field, isInvalid) {
|
|
227
|
+
const control = controlOf(element, field);
|
|
228
|
+
if (isInvalid) control?.setAttribute("aria-invalid", "true");
|
|
229
|
+
else control?.removeAttribute("aria-invalid");
|
|
230
|
+
}
|
|
231
|
+
function focusFirstIssue(element, issues) {
|
|
232
|
+
const [first] = issues;
|
|
233
|
+
if (first !== void 0) controlOf(element, first.field)?.focus();
|
|
234
|
+
}
|
|
235
|
+
function showState(element, state) {
|
|
236
|
+
element.dataset["seamletState"] = state;
|
|
237
|
+
const submit = element.querySelector("[type=submit]");
|
|
238
|
+
if (submit !== null) submit.disabled = state === "sending";
|
|
239
|
+
const sent = element.querySelector("[data-seamlet-sent]");
|
|
240
|
+
const failure = element.querySelector("[data-seamlet-failed]");
|
|
241
|
+
say(sent, state === "sent");
|
|
242
|
+
say(failure, state === "failed");
|
|
243
|
+
if (state === "sent") sent?.focus();
|
|
244
|
+
}
|
|
245
|
+
function say(message, isSaid) {
|
|
246
|
+
if (message === null) return;
|
|
247
|
+
message.textContent = isSaid ? message.dataset["seamletText"] ?? "" : "";
|
|
248
|
+
}
|
|
249
|
+
export {
|
|
250
|
+
connectRequestForms
|
|
251
|
+
};
|
package/dist/routes/media.js
CHANGED
|
@@ -3,9 +3,9 @@ import {
|
|
|
3
3
|
} from "../chunk-QCVWHHJC.js";
|
|
4
4
|
import {
|
|
5
5
|
isUploadedPhoto
|
|
6
|
-
} from "../chunk-
|
|
7
|
-
import "../chunk-
|
|
8
|
-
import "../chunk-
|
|
6
|
+
} from "../chunk-MFD4TJPV.js";
|
|
7
|
+
import "../chunk-VQKAWFCQ.js";
|
|
8
|
+
import "../chunk-ENMUO442.js";
|
|
9
9
|
|
|
10
10
|
// src/routes/media.ts
|
|
11
11
|
import { cmsOrigin } from "virtual:seamlet/config";
|
package/dist/schema.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { h as ImageValue, L as LinkValue, d as CollectionField, C as Content, F as Fields, e as RecordFields, b as ContentOf, G as GroupField, i as LinkField, T as TextField, U as UrlField, j as ChoicesField, k as TimeField, S as SlugField, I as ImageField, l as RichTextField, N as NumberField, m as ToggleField } from './parse-content-Bnn6Wa-l.js';
|
|
2
2
|
export { n as ChoiceField, o as ChoiceOption, g as ContentIssue, D as DateField, c as Field, p as FieldKind, a as FieldPath, q as FieldValue, r as ImageFocus, O as OptionValue, P as ParsedContent, f as RecordOf, s as ReferenceField, t as ReferencesField, u as RichBlock, v as RichLine, w as RichSpan, R as RichText, V as ValueOf, x as asOneParagraph, y as choice, z as choices, A as collection, B as countCharacters, E as date, H as defaultContent, J as defaultValue, K as defineSchema, M as formatFieldPath, Q as group, W as image, X as linesOf, Y as link, Z as normalizedLine, _ as number, $ as parseContent, a0 as plainTextOf, a1 as readRichText, a2 as reference, a3 as references, a4 as richText, a5 as richTextOf, a6 as slug, a7 as text, a8 as time, a9 as toggle, aa as url } from './parse-content-Bnn6Wa-l.js';
|
|
3
|
-
|
|
3
|
+
import { R as RequestForm } from './site-description-DSHyBrAL.js';
|
|
4
|
+
export { C as CollectionPath, D as DEFAULT_LONG_TEXT_LENGTH, b as DEFAULT_TEXT_LENGTH, F as FIELD_PATH_SEPARATOR, c as FieldTarget, d as FieldsReading, H as HOME_PAGE_PATH, M as MAX_REQUEST_FIELD_LENGTH, P as PAGE_PATH_SEPARATOR, e as PageProblemReason, f as PlacedRecord, g as RECORD_PLACEHOLDER, h as RecordFieldsAt, i as RecordPagePath, j as RecordPageProblemReason, k as RecordPages, l as RequestChoiceField, m as RequestEmailField, n as RequestField, o as RequestFieldKind, p as RequestFields, q as RequestFormProblemReason, r as RequestFormReading, s as RequestLongTextField, t as RequestPhoneField, u as RequestTextField, v as SITE_DESCRIPTION_PATH, w as SchemaProblem, x as SchemaProblemReason, S as SiteDescription, y as SiteDescriptionProblem, z as SiteDescriptionReading, A as SitePageDescription, B as SiteRecordPageDescription, a as SiteRecordPages, E as checkFields, G as checkSiteDescription, I as isFormId, J as isRecordPagePath, K as isSearchTextsGroup, L as maxLengthOf, N as readFields, O as readRequestForm, Q as readSiteDescription, T as recordAddressOf, U as recordAt, V as recordPageAt, W as recordPagePath, X as recordPages, Y as requestChoice, Z as requestEmail, _ as requestForm, $ as requestLongText, a0 as requestPhone, a1 as requestText, a2 as resolveFieldPath } from './site-description-DSHyBrAL.js';
|
|
4
5
|
|
|
5
6
|
declare const FIELD_PATH_ATTRIBUTE = "data-cms-path";
|
|
6
7
|
interface FieldMarker {
|
|
@@ -234,4 +235,102 @@ declare function slugOf(words: string): string;
|
|
|
234
235
|
/** The name of the slug of a record of the collection, if its records have one. */
|
|
235
236
|
declare function slugFieldOf(item: RecordFields): string | undefined;
|
|
236
237
|
|
|
237
|
-
|
|
238
|
+
/** The id of the form the request is sent with. */
|
|
239
|
+
declare const REQUEST_FORM_KEY = "seamlet-form";
|
|
240
|
+
/** The address of the page the request is sent from: `/catalog/banya-6x4`. */
|
|
241
|
+
declare const REQUEST_PAGE_KEY = "seamlet-page";
|
|
242
|
+
/** The visitor's consent to the processing of what they send, given with the form's checkbox. */
|
|
243
|
+
declare const REQUEST_CONSENT_KEY = "seamlet-consent";
|
|
244
|
+
/**
|
|
245
|
+
* A field a person never sees and a program filling every field fills: a request that has words in
|
|
246
|
+
* it is not a person's.
|
|
247
|
+
*/
|
|
248
|
+
declare const REQUEST_TRAP_KEY = "seamlet-check";
|
|
249
|
+
/** The words of a request as they come: the names of the form's fields and its own keys. */
|
|
250
|
+
type RequestEntries = Readonly<Record<string, string>>;
|
|
251
|
+
/** A field the visitor filled in, as the business reads it. */
|
|
252
|
+
interface RequestValue {
|
|
253
|
+
/** The field's name in the form: `phone`. */
|
|
254
|
+
readonly field: string;
|
|
255
|
+
/** The field's label: «Телефон». */
|
|
256
|
+
readonly label: string;
|
|
257
|
+
readonly value: string;
|
|
258
|
+
}
|
|
259
|
+
type RequestIssueCode = "required" | "too-long" | "invalid-phone" | "invalid-email" | "unknown-option";
|
|
260
|
+
/** A field whose words the form cannot take, and why. */
|
|
261
|
+
interface RequestIssue {
|
|
262
|
+
readonly field: string;
|
|
263
|
+
readonly code: RequestIssueCode;
|
|
264
|
+
}
|
|
265
|
+
type RequestReading = {
|
|
266
|
+
readonly status: "read";
|
|
267
|
+
/** The fields the visitor filled in, in the form's order. */
|
|
268
|
+
readonly values: readonly RequestValue[];
|
|
269
|
+
} | {
|
|
270
|
+
readonly status: "invalid";
|
|
271
|
+
readonly issues: readonly RequestIssue[];
|
|
272
|
+
};
|
|
273
|
+
/** What a visitor reads under a field whose words the form cannot take. */
|
|
274
|
+
declare const REQUEST_ISSUE_TEXTS: Readonly<Record<RequestIssueCode, string>>;
|
|
275
|
+
/** What a visitor reads when the consent's checkbox is left empty. */
|
|
276
|
+
declare const CONSENT_REQUIRED_TEXT = "\u041E\u0442\u043C\u0435\u0442\u044C\u0442\u0435 \u0441\u043E\u0433\u043B\u0430\u0441\u0438\u0435 \u043D\u0430 \u043E\u0431\u0440\u0430\u0431\u043E\u0442\u043A\u0443 \u043F\u0435\u0440\u0441\u043E\u043D\u0430\u043B\u044C\u043D\u044B\u0445 \u0434\u0430\u043D\u043D\u044B\u0445";
|
|
277
|
+
/** The fields of the request as the form takes them, or every field it cannot take. */
|
|
278
|
+
declare function readRequestValues(form: RequestForm, entries: RequestEntries): RequestReading;
|
|
279
|
+
/**
|
|
280
|
+
* The entries a request's body gives: its own string values only, so a value of another type, or a
|
|
281
|
+
* name of an object's prototype, never reaches a reader.
|
|
282
|
+
*/
|
|
283
|
+
declare function readRequestEntries(input: unknown): RequestEntries;
|
|
284
|
+
/** Whether the visitor checked the consent's checkbox. */
|
|
285
|
+
declare function isConsentGiven(entries: RequestEntries): boolean;
|
|
286
|
+
/** Whether the field a person never sees was filled in: a program sent the request. */
|
|
287
|
+
declare function isTrapFilled(entries: RequestEntries): boolean;
|
|
288
|
+
/** The page the request was sent from, or the home page when the request names no page. */
|
|
289
|
+
declare function requestPageOf(entries: RequestEntries): string;
|
|
290
|
+
/** The number as typed, when it is one: `+7 (912) 345-67-89`. */
|
|
291
|
+
declare function isPhoneNumber(typed: string): boolean;
|
|
292
|
+
declare function isEmailAddress(typed: string): boolean;
|
|
293
|
+
|
|
294
|
+
/** The two texts a form's visitor reads before sending: the consent and the operator's policy. */
|
|
295
|
+
type LegalDocument = "consent" | "privacy";
|
|
296
|
+
/** Where the site's forms send their requests, on the CMS's origin. */
|
|
297
|
+
declare function requestsPathOf(siteId: string): string;
|
|
298
|
+
/** Where the CMS shows a text of the business that owns the site, to anyone. */
|
|
299
|
+
declare function legalPagePathOf(siteId: string, document: LegalDocument): string;
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Before the request is sent, once the form takes what was typed. Cancelable: a site that calls
|
|
303
|
+
* `preventDefault()` sends the request its own way, and the package sends nothing.
|
|
304
|
+
*/
|
|
305
|
+
declare const REQUEST_SEND_EVENT = "seamlet:request-send";
|
|
306
|
+
/** The CMS has kept the request. */
|
|
307
|
+
declare const REQUEST_SENT_EVENT = "seamlet:request-sent";
|
|
308
|
+
/** The CMS has not kept the request: what was typed is still in the form. */
|
|
309
|
+
declare const REQUEST_FAILED_EVENT = "seamlet:request-failed";
|
|
310
|
+
interface RequestSendDetail {
|
|
311
|
+
/** The id of the form: `callback`. */
|
|
312
|
+
readonly form: string;
|
|
313
|
+
/** What the request sends: the fields by their names, and the request's own keys. */
|
|
314
|
+
readonly entries: RequestEntries;
|
|
315
|
+
}
|
|
316
|
+
interface RequestSentDetail extends RequestSendDetail {
|
|
317
|
+
/** The id the CMS gave the request. */
|
|
318
|
+
readonly id: string;
|
|
319
|
+
}
|
|
320
|
+
/** Why the CMS did not keep the request. */
|
|
321
|
+
type RequestFailure =
|
|
322
|
+
/** A field the CMS could not take; `issues` names them. */
|
|
323
|
+
"invalid"
|
|
324
|
+
/** The business does not take requests yet: its texts of consent are not confirmed. */
|
|
325
|
+
| "closed"
|
|
326
|
+
/** Too many requests from the same visitor; a later one is taken. */
|
|
327
|
+
| "too-many"
|
|
328
|
+
/** The CMS could not be reached, or answered with an error. */
|
|
329
|
+
| "unavailable";
|
|
330
|
+
interface RequestFailedDetail {
|
|
331
|
+
readonly form: string;
|
|
332
|
+
readonly reason: RequestFailure;
|
|
333
|
+
readonly issues: readonly RequestIssue[];
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
export { CONSENT_REQUIRED_TEXT, ChoicesField, CollectionField, type CollectionRecords, Content, ContentOf, type ContentPath, FIELD_PATH_ATTRIBUTE, type FieldMarker, Fields, GroupField, ImageField, ImageValue, type JsonObject, type LegalDocument, LinkField, type LinkKind, type LinkTarget, LinkValue, MAX_SLUG_LENGTH, NumberField, RECORD_ID_KEY, REQUEST_CONSENT_KEY, REQUEST_FAILED_EVENT, REQUEST_FORM_KEY, REQUEST_ISSUE_TEXTS, REQUEST_PAGE_KEY, REQUEST_SEND_EVENT, REQUEST_SENT_EVENT, REQUEST_TRAP_KEY, REVEALED_ATTRIBUTE, REVEAL_ATTRIBUTE, REVEAL_EVENT, RecordFields, type RequestEntries, type RequestFailedDetail, type RequestFailure, RequestForm, type RequestIssue, type RequestIssueCode, type RequestReading, type RequestSendDetail, type RequestSentDetail, type RequestValue, RichTextField, SITE_CONFIG_FILE, type SiteConfig, type SiteConfigField, type SiteConfigReading, SlugField, TextField, TimeField, ToggleField, UrlField, WEEKDAYS, collectionAt, collectionFieldAt, contactsFields, editable, findRecord, hrefOf, imagePosition, isConsentGiven, isContentObject, isEmailAddress, isJsonObject, isPhoneNumber, isRecordId, isSiteId, isSlug, isTrapFilled, legalPagePathOf, linkTargetOf, newRecord, openingHoursField, productFields, readRequestEntries, readRequestValues, readSiteConfig, requestPageOf, requestsPathOf, safeHref, seoFields, slugFieldOf, slugOf, withRecordIds };
|
package/dist/schema.js
CHANGED
|
@@ -1,11 +1,23 @@
|
|
|
1
1
|
import {
|
|
2
|
+
CONSENT_REQUIRED_TEXT,
|
|
3
|
+
DEFAULT_LONG_TEXT_LENGTH,
|
|
4
|
+
DEFAULT_TEXT_LENGTH,
|
|
2
5
|
FIELD_PATH_ATTRIBUTE,
|
|
3
6
|
FIELD_PATH_SEPARATOR,
|
|
4
7
|
HOME_PAGE_PATH,
|
|
8
|
+
MAX_REQUEST_FIELD_LENGTH,
|
|
5
9
|
MAX_SLUG_LENGTH,
|
|
6
10
|
PAGE_PATH_SEPARATOR,
|
|
7
11
|
RECORD_ID_KEY,
|
|
8
12
|
RECORD_PLACEHOLDER,
|
|
13
|
+
REQUEST_CONSENT_KEY,
|
|
14
|
+
REQUEST_FAILED_EVENT,
|
|
15
|
+
REQUEST_FORM_KEY,
|
|
16
|
+
REQUEST_ISSUE_TEXTS,
|
|
17
|
+
REQUEST_PAGE_KEY,
|
|
18
|
+
REQUEST_SEND_EVENT,
|
|
19
|
+
REQUEST_SENT_EVENT,
|
|
20
|
+
REQUEST_TRAP_KEY,
|
|
9
21
|
REVEALED_ATTRIBUTE,
|
|
10
22
|
REVEAL_ATTRIBUTE,
|
|
11
23
|
REVEAL_EVENT,
|
|
@@ -33,16 +45,23 @@ import {
|
|
|
33
45
|
hrefOf,
|
|
34
46
|
image,
|
|
35
47
|
imagePosition,
|
|
48
|
+
isConsentGiven,
|
|
36
49
|
isContentObject,
|
|
50
|
+
isEmailAddress,
|
|
51
|
+
isFormId,
|
|
37
52
|
isJsonObject,
|
|
53
|
+
isPhoneNumber,
|
|
38
54
|
isRecordId,
|
|
39
55
|
isRecordPagePath,
|
|
40
56
|
isSearchTextsGroup,
|
|
41
57
|
isSiteId,
|
|
42
58
|
isSlug,
|
|
59
|
+
isTrapFilled,
|
|
60
|
+
legalPagePathOf,
|
|
43
61
|
linesOf,
|
|
44
62
|
link,
|
|
45
63
|
linkTargetOf,
|
|
64
|
+
maxLengthOf,
|
|
46
65
|
newRecord,
|
|
47
66
|
normalizedLine,
|
|
48
67
|
number,
|
|
@@ -51,6 +70,9 @@ import {
|
|
|
51
70
|
plainTextOf,
|
|
52
71
|
productFields,
|
|
53
72
|
readFields,
|
|
73
|
+
readRequestEntries,
|
|
74
|
+
readRequestForm,
|
|
75
|
+
readRequestValues,
|
|
54
76
|
readRichText,
|
|
55
77
|
readSiteConfig,
|
|
56
78
|
readSiteDescription,
|
|
@@ -61,6 +83,14 @@ import {
|
|
|
61
83
|
recordPages,
|
|
62
84
|
reference,
|
|
63
85
|
references,
|
|
86
|
+
requestChoice,
|
|
87
|
+
requestEmail,
|
|
88
|
+
requestForm,
|
|
89
|
+
requestLongText,
|
|
90
|
+
requestPageOf,
|
|
91
|
+
requestPhone,
|
|
92
|
+
requestText,
|
|
93
|
+
requestsPathOf,
|
|
64
94
|
resolveFieldPath,
|
|
65
95
|
richText,
|
|
66
96
|
richTextOf,
|
|
@@ -74,15 +104,27 @@ import {
|
|
|
74
104
|
toggle,
|
|
75
105
|
url,
|
|
76
106
|
withRecordIds
|
|
77
|
-
} from "./chunk-
|
|
107
|
+
} from "./chunk-ENMUO442.js";
|
|
78
108
|
export {
|
|
109
|
+
CONSENT_REQUIRED_TEXT,
|
|
110
|
+
DEFAULT_LONG_TEXT_LENGTH,
|
|
111
|
+
DEFAULT_TEXT_LENGTH,
|
|
79
112
|
FIELD_PATH_ATTRIBUTE,
|
|
80
113
|
FIELD_PATH_SEPARATOR,
|
|
81
114
|
HOME_PAGE_PATH,
|
|
115
|
+
MAX_REQUEST_FIELD_LENGTH,
|
|
82
116
|
MAX_SLUG_LENGTH,
|
|
83
117
|
PAGE_PATH_SEPARATOR,
|
|
84
118
|
RECORD_ID_KEY,
|
|
85
119
|
RECORD_PLACEHOLDER,
|
|
120
|
+
REQUEST_CONSENT_KEY,
|
|
121
|
+
REQUEST_FAILED_EVENT,
|
|
122
|
+
REQUEST_FORM_KEY,
|
|
123
|
+
REQUEST_ISSUE_TEXTS,
|
|
124
|
+
REQUEST_PAGE_KEY,
|
|
125
|
+
REQUEST_SEND_EVENT,
|
|
126
|
+
REQUEST_SENT_EVENT,
|
|
127
|
+
REQUEST_TRAP_KEY,
|
|
86
128
|
REVEALED_ATTRIBUTE,
|
|
87
129
|
REVEAL_ATTRIBUTE,
|
|
88
130
|
REVEAL_EVENT,
|
|
@@ -110,16 +152,23 @@ export {
|
|
|
110
152
|
hrefOf,
|
|
111
153
|
image,
|
|
112
154
|
imagePosition,
|
|
155
|
+
isConsentGiven,
|
|
113
156
|
isContentObject,
|
|
157
|
+
isEmailAddress,
|
|
158
|
+
isFormId,
|
|
114
159
|
isJsonObject,
|
|
160
|
+
isPhoneNumber,
|
|
115
161
|
isRecordId,
|
|
116
162
|
isRecordPagePath,
|
|
117
163
|
isSearchTextsGroup,
|
|
118
164
|
isSiteId,
|
|
119
165
|
isSlug,
|
|
166
|
+
isTrapFilled,
|
|
167
|
+
legalPagePathOf,
|
|
120
168
|
linesOf,
|
|
121
169
|
link,
|
|
122
170
|
linkTargetOf,
|
|
171
|
+
maxLengthOf,
|
|
123
172
|
newRecord,
|
|
124
173
|
normalizedLine,
|
|
125
174
|
number,
|
|
@@ -128,6 +177,9 @@ export {
|
|
|
128
177
|
plainTextOf,
|
|
129
178
|
productFields,
|
|
130
179
|
readFields,
|
|
180
|
+
readRequestEntries,
|
|
181
|
+
readRequestForm,
|
|
182
|
+
readRequestValues,
|
|
131
183
|
readRichText,
|
|
132
184
|
readSiteConfig,
|
|
133
185
|
readSiteDescription,
|
|
@@ -138,6 +190,14 @@ export {
|
|
|
138
190
|
recordPages,
|
|
139
191
|
reference,
|
|
140
192
|
references,
|
|
193
|
+
requestChoice,
|
|
194
|
+
requestEmail,
|
|
195
|
+
requestForm,
|
|
196
|
+
requestLongText,
|
|
197
|
+
requestPageOf,
|
|
198
|
+
requestPhone,
|
|
199
|
+
requestText,
|
|
200
|
+
requestsPathOf,
|
|
141
201
|
resolveFieldPath,
|
|
142
202
|
richText,
|
|
143
203
|
richTextOf,
|