@getquick/content 0.3.2 → 0.4.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 +6 -0
- package/dist/consent-astro.js +1 -1
- package/dist/consent-server.js +4 -37
- package/dist/consent.js +1 -1
- package/dist/copy-DLto_bWj.js +163 -0
- package/dist/descriptor-B-e7gHi1.d.ts +143 -0
- package/dist/descriptor-x8kHFQ79.js +205 -0
- package/dist/forms-astro.d.ts +50 -0
- package/dist/forms-astro.js +193 -0
- package/dist/forms-server.d.ts +80 -0
- package/dist/forms-server.js +294 -0
- package/dist/forms-testing.d.ts +66 -0
- package/dist/forms-testing.js +334 -0
- package/dist/forms.d.ts +25 -0
- package/dist/forms.js +4 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/request-guards-BUPr_vA4.js +46 -0
- package/dist/server.d.ts +1 -1
- package/dist/server.js +158 -9
- package/dist/{site-language-BcPac0Ia.js → site-language-BCGjkpWY.js} +67780 -46785
- package/dist/state-CsMFLUUO.d.ts +66 -0
- package/dist/validate-wRgYUNxN.js +130 -0
- package/dist/{version-DkpQm85L.js → version-D81MsCZU.js} +1 -1
- package/dist/{wordpress-C1xs3xHN.d.ts → wordpress-BvkTDMA0.d.ts} +67 -2
- package/package.json +17 -1
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
import { u as parseFormDescriptor } from "./descriptor-x8kHFQ79.js";
|
|
2
|
+
//#region frontend/src/forms/testing.ts
|
|
3
|
+
/** A contact form like Nomia's form 1: name, email, subject, message and privacy consent. */
|
|
4
|
+
const CONTACT_FORM = {
|
|
5
|
+
schema: 1,
|
|
6
|
+
id: 1,
|
|
7
|
+
available: true,
|
|
8
|
+
title: "Contactos",
|
|
9
|
+
description: "Envie-nos uma mensagem.",
|
|
10
|
+
submitLabel: "Enviar",
|
|
11
|
+
fields: [
|
|
12
|
+
{
|
|
13
|
+
id: 1,
|
|
14
|
+
type: "name",
|
|
15
|
+
label: "Nome",
|
|
16
|
+
description: "",
|
|
17
|
+
required: true,
|
|
18
|
+
visibility: "visible",
|
|
19
|
+
inputs: [{
|
|
20
|
+
id: "1.3",
|
|
21
|
+
name: "input_1_3",
|
|
22
|
+
label: "Nome próprio",
|
|
23
|
+
autocomplete: "given-name"
|
|
24
|
+
}, {
|
|
25
|
+
id: "1.6",
|
|
26
|
+
name: "input_1_6",
|
|
27
|
+
label: "Apelido",
|
|
28
|
+
autocomplete: "family-name"
|
|
29
|
+
}]
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
id: 2,
|
|
33
|
+
type: "email",
|
|
34
|
+
label: "Email",
|
|
35
|
+
description: "",
|
|
36
|
+
required: true,
|
|
37
|
+
visibility: "visible",
|
|
38
|
+
inputs: [{
|
|
39
|
+
id: "2",
|
|
40
|
+
name: "input_2",
|
|
41
|
+
label: "Email"
|
|
42
|
+
}]
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
id: 3,
|
|
46
|
+
type: "text",
|
|
47
|
+
label: "Assunto",
|
|
48
|
+
description: "",
|
|
49
|
+
required: false,
|
|
50
|
+
visibility: "visible",
|
|
51
|
+
maxLength: 120,
|
|
52
|
+
inputs: [{
|
|
53
|
+
id: "3",
|
|
54
|
+
name: "input_3",
|
|
55
|
+
label: "Assunto"
|
|
56
|
+
}]
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
id: 4,
|
|
60
|
+
type: "textarea",
|
|
61
|
+
label: "Mensagem",
|
|
62
|
+
description: "",
|
|
63
|
+
required: true,
|
|
64
|
+
visibility: "visible",
|
|
65
|
+
inputs: [{
|
|
66
|
+
id: "4",
|
|
67
|
+
name: "input_4",
|
|
68
|
+
label: "Mensagem"
|
|
69
|
+
}]
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
id: 5,
|
|
73
|
+
type: "consent",
|
|
74
|
+
label: "Privacidade",
|
|
75
|
+
description: "",
|
|
76
|
+
required: true,
|
|
77
|
+
visibility: "visible",
|
|
78
|
+
inputs: [
|
|
79
|
+
{
|
|
80
|
+
id: "5.1",
|
|
81
|
+
name: "input_5_1",
|
|
82
|
+
label: "Consentimento"
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
id: "5.2",
|
|
86
|
+
name: "input_5_2",
|
|
87
|
+
label: "Texto"
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
id: "5.3",
|
|
91
|
+
name: "input_5_3",
|
|
92
|
+
label: "Descrição"
|
|
93
|
+
}
|
|
94
|
+
],
|
|
95
|
+
consent: {
|
|
96
|
+
checkboxLabel: "Aceito o tratamento dos meus dados para responder a este contacto.",
|
|
97
|
+
description: "Os dados são usados apenas para responder à sua mensagem.",
|
|
98
|
+
revisionId: "7"
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
],
|
|
102
|
+
honeypot: { name: "input_6" },
|
|
103
|
+
confirmation: {
|
|
104
|
+
type: "message",
|
|
105
|
+
message: "Obrigado pelo seu contacto."
|
|
106
|
+
},
|
|
107
|
+
diagnostics: []
|
|
108
|
+
};
|
|
109
|
+
/** A form readiness must fail: Gravity Forms' CAPTCHA, a file upload, a payment field and a page break. */
|
|
110
|
+
const UNSUPPORTED_FORM = {
|
|
111
|
+
...CONTACT_FORM,
|
|
112
|
+
id: 2,
|
|
113
|
+
title: "Candidatura",
|
|
114
|
+
fields: CONTACT_FORM.fields.slice(0, 2),
|
|
115
|
+
diagnostics: [
|
|
116
|
+
{
|
|
117
|
+
code: "unsupported-captcha",
|
|
118
|
+
fieldId: 10,
|
|
119
|
+
type: "captcha",
|
|
120
|
+
message: "CAPTCHA"
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
code: "unsupported-file-upload",
|
|
124
|
+
fieldId: 11,
|
|
125
|
+
type: "fileupload",
|
|
126
|
+
message: "File upload"
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
code: "unsupported-payment",
|
|
130
|
+
fieldId: 12,
|
|
131
|
+
type: "product",
|
|
132
|
+
message: "Payment"
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
code: "unsupported-multi-page",
|
|
136
|
+
fieldId: 13,
|
|
137
|
+
type: "page",
|
|
138
|
+
message: "Multi-page"
|
|
139
|
+
}
|
|
140
|
+
]
|
|
141
|
+
};
|
|
142
|
+
/** A referenced form that is missing, inactive or trashed. */
|
|
143
|
+
const UNAVAILABLE_FORM = {
|
|
144
|
+
...CONTACT_FORM,
|
|
145
|
+
id: 3,
|
|
146
|
+
available: false,
|
|
147
|
+
fields: [],
|
|
148
|
+
honeypot: null,
|
|
149
|
+
diagnostics: [{
|
|
150
|
+
code: "unavailable",
|
|
151
|
+
message: "Form 3 is inactive."
|
|
152
|
+
}]
|
|
153
|
+
};
|
|
154
|
+
/** Keys that must never appear anywhere in a delivered descriptor. */
|
|
155
|
+
const PRIVATE_FORM_KEYS = [
|
|
156
|
+
"notifications",
|
|
157
|
+
"notification",
|
|
158
|
+
"confirmations",
|
|
159
|
+
"entries",
|
|
160
|
+
"entry",
|
|
161
|
+
"entry_id",
|
|
162
|
+
"feeds",
|
|
163
|
+
"feed",
|
|
164
|
+
"settings",
|
|
165
|
+
"personalData",
|
|
166
|
+
"routing",
|
|
167
|
+
"to",
|
|
168
|
+
"bcc",
|
|
169
|
+
"from",
|
|
170
|
+
"fromName",
|
|
171
|
+
"replyTo",
|
|
172
|
+
"save",
|
|
173
|
+
"limitEntries",
|
|
174
|
+
"scheduleForm",
|
|
175
|
+
"requireLogin",
|
|
176
|
+
"consumer_key",
|
|
177
|
+
"consumer_secret"
|
|
178
|
+
];
|
|
179
|
+
function keysOf(value, path = "", found = []) {
|
|
180
|
+
if (Array.isArray(value)) value.forEach((each, index) => keysOf(each, `${path}[${index}]`, found));
|
|
181
|
+
else if (typeof value === "object" && value !== null) for (const [key, each] of Object.entries(value)) {
|
|
182
|
+
found.push(`${path}.${key}`);
|
|
183
|
+
keysOf(each, `${path}.${key}`, found);
|
|
184
|
+
}
|
|
185
|
+
return found;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Throws unless a delivered descriptor is public: it parses, and nothing in it
|
|
189
|
+
* is a notification, entry, feed or admin setting (by key, at any depth).
|
|
190
|
+
*/
|
|
191
|
+
function assertPublicDescriptor(value) {
|
|
192
|
+
const descriptor = parseFormDescriptor(value);
|
|
193
|
+
if (!descriptor) throw new Error("Not a form descriptor");
|
|
194
|
+
const forbidden = keysOf(value).filter((path) => PRIVATE_FORM_KEYS.includes(path.slice(path.lastIndexOf(".") + 1)));
|
|
195
|
+
if (forbidden.length) throw new Error(`The descriptor carries private form data: ${forbidden.join(", ")}`);
|
|
196
|
+
return descriptor;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Throws unless rendered form HTML is accessible: every visible control has a
|
|
200
|
+
* label (`for`) or is in a labelled fieldset, every `aria-describedby` id
|
|
201
|
+
* exists, invalid controls are described by their error, an error summary is
|
|
202
|
+
* an alert and a confirmation is a status.
|
|
203
|
+
*/
|
|
204
|
+
function assertAccessibleForm(html) {
|
|
205
|
+
const ids = new Set([...html.matchAll(/\sid="([^"]+)"/g)].map((match) => match[1]));
|
|
206
|
+
const labelled = new Set([...html.matchAll(/<label[^>]*\sfor="([^"]+)"/g)].map((m) => m[1]));
|
|
207
|
+
const problems = [];
|
|
208
|
+
for (const match of html.matchAll(/<(input|select|textarea)\b([^>]*)>/g)) {
|
|
209
|
+
const attributes = match[2];
|
|
210
|
+
if (/\stype="hidden"/.test(attributes)) continue;
|
|
211
|
+
const id = /\sid="([^"]+)"/.exec(attributes)?.[1];
|
|
212
|
+
if (!id || !labelled.has(id)) problems.push(`a ${match[1]} without a label (${id ?? "no id"})`);
|
|
213
|
+
const describedBy = /\saria-describedby="([^"]+)"/.exec(attributes)?.[1];
|
|
214
|
+
for (const reference of describedBy?.split(/\s+/) ?? []) if (!ids.has(reference)) problems.push(`${id} is described by a missing #${reference}`);
|
|
215
|
+
if (/\saria-invalid="true"/.test(attributes) && !/-error\b/.test(describedBy ?? "")) problems.push(`${id} is invalid without its error in aria-describedby`);
|
|
216
|
+
}
|
|
217
|
+
if (/gq-form__errors/.test(html) && !/class="gq-form__errors" role="alert"/.test(html)) problems.push("the error summary isn't an alert");
|
|
218
|
+
if (/gq-form__status--sent/.test(html) && !/gq-form__status--sent" role="status"/.test(html)) problems.push("the confirmation isn't a status message");
|
|
219
|
+
if (/<form\b/.test(html) && !/<button type="submit"/.test(html)) problems.push("the form has no submit button");
|
|
220
|
+
if (problems.length) throw new Error(`Inaccessible form: ${problems.join("; ")}`);
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* A stand-in for Gravity Forms' REST API on a CMS: `POST
|
|
224
|
+
* /wp-json/gf/v2/forms/<id>/submissions` as Gravity Forms 3.2 answers it,
|
|
225
|
+
* validating required fields and storing entries for the given descriptors.
|
|
226
|
+
* A filled honeypot is stored as spam, Gravity Forms' default honeypot
|
|
227
|
+
* action. Anything else is a 404. `requests` records every request.
|
|
228
|
+
*/
|
|
229
|
+
function gravityFormsStub(forms) {
|
|
230
|
+
const entries = [];
|
|
231
|
+
const requests = [];
|
|
232
|
+
async function handle(request) {
|
|
233
|
+
const url = new URL(request.url);
|
|
234
|
+
let body = null;
|
|
235
|
+
try {
|
|
236
|
+
body = request.method === "POST" ? await request.json() : null;
|
|
237
|
+
} catch {
|
|
238
|
+
body = null;
|
|
239
|
+
}
|
|
240
|
+
requests.push({
|
|
241
|
+
method: request.method,
|
|
242
|
+
url: url.pathname + url.search,
|
|
243
|
+
headers: Object.fromEntries(request.headers),
|
|
244
|
+
body
|
|
245
|
+
});
|
|
246
|
+
const match = /^\/wp-json\/gf\/v2\/forms\/(\d+)\/submissions$/.exec(url.pathname);
|
|
247
|
+
const form = match && forms.find((each) => each.id === Number(match[1]));
|
|
248
|
+
if (!match || request.method !== "POST") return Response.json({ code: "rest_no_route" }, { status: 404 });
|
|
249
|
+
if (!form || !form.available) return Response.json({
|
|
250
|
+
code: "form_not_found",
|
|
251
|
+
message: "Your form could not be found"
|
|
252
|
+
}, { status: 400 });
|
|
253
|
+
const values = body ?? {};
|
|
254
|
+
const messages = {};
|
|
255
|
+
for (const field of form.fields) {
|
|
256
|
+
if (!field.required) continue;
|
|
257
|
+
if ((field.type === "consent" ? [field.inputs[0].name] : field.inputs.map((input) => input.name)).every((name) => !values[name])) messages[field.id] = "This field is required.";
|
|
258
|
+
}
|
|
259
|
+
if (Object.keys(messages).length) return Response.json({
|
|
260
|
+
is_valid: false,
|
|
261
|
+
validation_messages: messages,
|
|
262
|
+
page_number: 1,
|
|
263
|
+
source_page_number: 1
|
|
264
|
+
}, { status: 400 });
|
|
265
|
+
const spam = Boolean(form.honeypot && values[form.honeypot.name]);
|
|
266
|
+
entries.push({
|
|
267
|
+
formId: form.id,
|
|
268
|
+
values,
|
|
269
|
+
spam
|
|
270
|
+
});
|
|
271
|
+
return Response.json({
|
|
272
|
+
is_valid: true,
|
|
273
|
+
page_number: 0,
|
|
274
|
+
source_page_number: 1,
|
|
275
|
+
confirmation_type: "message",
|
|
276
|
+
confirmation_message: `<div id='gform_confirmation_wrapper_${form.id}' class='gform_confirmation_wrapper '><div id='gform_confirmation_message_${form.id}' class='gform_confirmation_message_${form.id} gform_confirmation_message'>${form.confirmation.type === "message" ? form.confirmation.message : ""}</div></div>`,
|
|
277
|
+
is_spam: spam
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
return {
|
|
281
|
+
entries,
|
|
282
|
+
requests,
|
|
283
|
+
handle,
|
|
284
|
+
/** A `fetch` that answers the CMS's requests at `origin` and refuses any other. */
|
|
285
|
+
fetchFor(origin) {
|
|
286
|
+
return async (input, init) => {
|
|
287
|
+
const request = new Request(input, init);
|
|
288
|
+
if (new URL(request.url).origin !== origin) throw new TypeError(`Unexpected request to ${new URL(request.url).origin}`);
|
|
289
|
+
return handle(request);
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
/** Throws if any request asked for entries, or carried a Gravity Forms credential. */
|
|
295
|
+
function assertNoEntryReadsOrCredentials(requests) {
|
|
296
|
+
for (const request of requests) {
|
|
297
|
+
if (/\/entries\b/.test(request.url)) throw new Error(`An entry read reached the CMS: ${request.method} ${request.url}`);
|
|
298
|
+
if (request.headers.authorization) throw new Error(`A credential reached the CMS: ${request.method} ${request.url}`);
|
|
299
|
+
if (/consumer_(key|secret)|oauth_/i.test(request.url)) throw new Error(`A consumer key reached the CMS: ${request.method} ${request.url}`);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
/** Throws if a module exports anything that reads entries (by name; these assertions aside). */
|
|
303
|
+
function assertNoEntryExports(module) {
|
|
304
|
+
const names = Object.keys(module).filter((name) => /entr(y|ies)/i.test(name) && !name.startsWith("assertNo"));
|
|
305
|
+
if (names.length) throw new Error(`Exports that read entries: ${names.join(", ")}`);
|
|
306
|
+
}
|
|
307
|
+
/** A form body as a browser posts it (application/x-www-form-urlencoded). */
|
|
308
|
+
function formBody(values) {
|
|
309
|
+
return new URLSearchParams(values).toString();
|
|
310
|
+
}
|
|
311
|
+
/** A filled-in, valid submission of CONTACT_FORM from `source`. */
|
|
312
|
+
function contactSubmission(source = "/contactos/") {
|
|
313
|
+
return {
|
|
314
|
+
gq_source: source,
|
|
315
|
+
input_1_3: "Ana",
|
|
316
|
+
input_1_6: "Silva",
|
|
317
|
+
input_2: "ana@example.com",
|
|
318
|
+
input_3: "Pergunta",
|
|
319
|
+
input_4: "Olá, gostava de saber mais.",
|
|
320
|
+
input_5_1: "1",
|
|
321
|
+
input_6: ""
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
/** Cloudflare's Turnstile test keys: always pass, always fail. */
|
|
325
|
+
const TURNSTILE_TEST_KEYS = {
|
|
326
|
+
passingSiteKey: "1x00000000000000000000AA",
|
|
327
|
+
failingSiteKey: "2x00000000000000000000AB",
|
|
328
|
+
passingSecretKey: "1x0000000000000000000000000000000AA",
|
|
329
|
+
failingSecretKey: "2x0000000000000000000000000000000AA",
|
|
330
|
+
/** The token the test site keys produce. */
|
|
331
|
+
dummyToken: "XXXX.DUMMY.TOKEN.XXXX"
|
|
332
|
+
};
|
|
333
|
+
//#endregion
|
|
334
|
+
export { CONTACT_FORM, PRIVATE_FORM_KEYS, TURNSTILE_TEST_KEYS, UNAVAILABLE_FORM, UNSUPPORTED_FORM, assertAccessibleForm, assertNoEntryExports, assertNoEntryReadsOrCredentials, assertPublicDescriptor, contactSubmission, formBody, gravityFormsStub };
|
package/dist/forms.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { S as parseFormDescriptors, _ as findForm, a as FormConsent, b as formsReadiness, c as FormDiagnosticCode, d as FormInput, f as FormSpamControl, g as blockFormId, h as SUPPORTED_FIELD_TYPES, i as FormConfirmation, l as FormField, m as GRAVITY_FORMS_BLOCK, n as FORM_DESCRIPTOR_SCHEMA, o as FormDescriptor, p as FormsReadiness, r as FormChoice, s as FormDiagnostic, t as FORMS_PATH, u as FormFieldType, v as formAction, x as parseFormDescriptor, y as formDiagnostics } from "./descriptor-B-e7gHi1.js";
|
|
2
|
+
import { a as clearFormStateCookie, c as formStateLocation, d as FormErrorCode, f as FormsCopy, i as FormStatus, l as readFormState, m as formsCopyLanguage, n as FORM_STATE_PARAM, o as formStateCookie, p as FormsCopyLanguage, r as FormState, s as formStateCookieName, t as FORM_STATE_MAX_AGE, u as FORMS_COPY } from "./state-CsMFLUUO.js";
|
|
3
|
+
//#region frontend/src/forms/validate.d.ts
|
|
4
|
+
/** No single value is longer (characters). */
|
|
5
|
+
export declare const MAX_VALUE_LENGTH = 10000;
|
|
6
|
+
/** What the visitor posted: a form body's values by name. */
|
|
7
|
+
type SubmittedValues = Pick<URLSearchParams, "get">;
|
|
8
|
+
interface SubmissionCheck {
|
|
9
|
+
/** Each input's value, by Gravity Forms' input name, for the CMS. */
|
|
10
|
+
input: Record<string, string>;
|
|
11
|
+
/** Field errors, by field id. */
|
|
12
|
+
errors: Record<number, FormErrorCode>;
|
|
13
|
+
/** What to show again in the form after errors (visible fields only). */
|
|
14
|
+
values: Record<string, string>;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Checks a submission against the descriptor: required fields, formats,
|
|
18
|
+
* choices and lengths. Only the descriptor's inputs are kept; the honeypot is
|
|
19
|
+
* passed through, empty, for Gravity Forms' own check.
|
|
20
|
+
*/
|
|
21
|
+
export declare function validateSubmission(descriptor: FormDescriptor, values: SubmittedValues): SubmissionCheck;
|
|
22
|
+
/** Whether the honeypot was filled in: a bot. Such a submission never reaches the CMS. */
|
|
23
|
+
export declare function honeypotFilled(descriptor: FormDescriptor, values: SubmittedValues): boolean;
|
|
24
|
+
//#endregion
|
|
25
|
+
export { FORMS_COPY, FORMS_PATH, FORM_DESCRIPTOR_SCHEMA, FORM_STATE_MAX_AGE, FORM_STATE_PARAM, type FormChoice, type FormConfirmation, type FormConsent, type FormDescriptor, type FormDiagnostic, type FormDiagnosticCode, type FormErrorCode, type FormField, type FormFieldType, type FormInput, type FormSpamControl, type FormState, type FormStatus, type FormsCopy, type FormsCopyLanguage, type FormsReadiness, GRAVITY_FORMS_BLOCK, SUPPORTED_FIELD_TYPES, type SubmissionCheck, type SubmittedValues, blockFormId, clearFormStateCookie, findForm, formAction, formDiagnostics, formStateCookie, formStateCookieName, formStateLocation, formsCopyLanguage, formsReadiness, parseFormDescriptor, parseFormDescriptors, readFormState };
|
package/dist/forms.js
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { a as blockFormId, c as formDiagnostics, d as parseFormDescriptors, i as SUPPORTED_FIELD_TYPES, l as formsReadiness, n as FORM_DESCRIPTOR_SCHEMA, o as findForm, r as GRAVITY_FORMS_BLOCK, s as formAction, t as FORMS_PATH, u as parseFormDescriptor } from "./descriptor-x8kHFQ79.js";
|
|
2
|
+
import { n as honeypotFilled, r as validateSubmission, t as MAX_VALUE_LENGTH } from "./validate-wRgYUNxN.js";
|
|
3
|
+
import { a as clearFormStateCookie, c as formStateLocation, i as FORM_STATE_PARAM, l as readFormState, n as formsCopyLanguage, o as formStateCookie, r as FORM_STATE_MAX_AGE, s as formStateCookieName, t as FORMS_COPY } from "./copy-DLto_bWj.js";
|
|
4
|
+
export { FORMS_COPY, FORMS_PATH, FORM_DESCRIPTOR_SCHEMA, FORM_STATE_MAX_AGE, FORM_STATE_PARAM, GRAVITY_FORMS_BLOCK, MAX_VALUE_LENGTH, SUPPORTED_FIELD_TYPES, blockFormId, clearFormStateCookie, findForm, formAction, formDiagnostics, formStateCookie, formStateCookieName, formStateLocation, formsCopyLanguage, formsReadiness, honeypotFilled, parseFormDescriptor, parseFormDescriptors, readFormState, validateSubmission };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as
|
|
1
|
+
import { $ as Delivery, A as SqlDatabase, At as DesignPostContext, B as DesignBlockRenderer, Bt as renderDesignQuery, C as Moved, Ct as presentationVariables, D as SearchPage, Dt as designThemeVariables, E as SearchItem, Et as designThemeStyleSheet, F as isLanguageHome, Ft as DesignQueryResolverOptions, G as escapeHtml, H as DesignRenderContext, Ht as renderDesignText, I as languageSubject, It as designPostContext, J as Archives, K as parseDesignBlocks, L as routeLanguage, Lt as designQueryItems, M as SiteLanguage, Mt as DesignPreloadedPosts, N as WordPressLanguages, Nt as DesignQueryItem, O as SearchQuery, Ot as resolveDesignTheme, P as htmlLang, Pt as DesignQueryRenderContext, Q as CollectionTerm, R as siteLanguages, Rt as preloadDesignQueryPosts, S as HomePublication, St as presentationStyleSheet, T as SearchDelivery, Tt as DesignThemeOverrides, U as DesignRenderOptions, Ut as safeDesignRichText, V as DesignPattern, Vt as DesignTextContext, W as designMenuItems, X as CmsFailureReason, Y as CmsFailure, Z as CollectionMembership, _ as EntryDelivery, _t as PresentationTargets, a as ContentExtension, at as Missing, b as HomeDelivery, bt as createPresentationModel, ct as Translation, d as CollectionListing, dt as WordPressMenuItem, et as DesignPresets, f as CollectionPage, ft as WordPressPost, g as DeliveryFailureReason, gt as PresentationModel, h as CollectionTermListing, ht as PresentationBreakpoint, i as ContentConsentConfig, it as HomeContent, j as SqlStatement, jt as DesignPostRecord, k as ContentBindings, kt as resolvePresentationToken, l as Alternate, lt as Unavailable, m as CollectionTermCount, mt as Presentation, n as CollectionConfig, nt as Extended, o as ContentRuntime, ot as PublishedEntry, p as CollectionQuery, pt as WordPressSettings, q as renderDesignPattern, r as ContentConfig, rt as Found, s as ExtensionNode, st as SiteChrome, t as WordPressClient, tt as EntryContent, u as CollectionItem, ut as WordPressImage, v as EntryPage, vt as PresentationTheme, w as NotServed, wt as DesignTheme, x as HomePage, xt as presentationModel, y as EntryPublication, yt as Property, z as DesignBlock, zt as renderDesignPostBlock } from "./wordpress-BvkTDMA0.js";
|
|
2
2
|
//#region frontend/src/cover-video-html.d.ts
|
|
3
3
|
/** Native decorative Cover video must not start before motion preferences are
|
|
4
4
|
* known. Retain every source, poster, child and independent video attribute. */
|
|
@@ -201,4 +201,4 @@ export declare function renderDesignNavigation(name: string, attrs: Attributes,
|
|
|
201
201
|
/** Interaction styles only. Include canonical presentationStyleSheet separately. */
|
|
202
202
|
export declare function navigationStyleSheet(theme?: DesignThemeOverrides): string;
|
|
203
203
|
//#endregion
|
|
204
|
-
export { Alternate, Archives, CmsFailure, CmsFailureReason, type CollectionConfig, CollectionItem, CollectionListing, CollectionMembership, CollectionPage, CollectionQuery, CollectionTerm, CollectionTermCount, CollectionTermListing, ContentBindings, type ContentConfig, type ContentConsentConfig, type ContentExtension, type ContentRuntime, Delivery, DeliveryFailureReason, DesignBlock, DesignBlockRenderer, DesignPattern, type DesignPostContext, type DesignPostRecord, type DesignPreloadedPosts, DesignPresets, type DesignQueryItem, type DesignQueryRenderContext, type DesignQueryResolverOptions, DesignRenderContext, DesignRenderOptions, type DesignTextContext, type DesignTheme, type DesignThemeOverrides, EntryContent, EntryDelivery, EntryPage, EntryPublication, Extended, type ExtensionNode, Found, HomeContent, HomeDelivery, HomePage, HomePublication, Missing, Moved, NotServed, type Presentation, type PresentationBreakpoint, type PresentationModel, type Property as PresentationProperty, type PresentationTargets, type PresentationTheme, PublishedEntry, SiteChrome, SiteLanguage, SqlDatabase, SqlStatement, Translation, Unavailable, type VideoHeroFit, type VideoHeroPosition, type WordPressClient, WordPressImage, WordPressLanguages, WordPressMenuItem, WordPressPost, WordPressSettings, createPresentationModel, designMenuItems, designPostContext, designQueryItems, designThemeStyleSheet, designThemeVariables, escapeHtml, htmlLang, isLanguageHome, languageSubject, parseDesignBlocks, preloadDesignQueryPosts, presentationModel, presentationStyleSheet, presentationVariables, renderDesignPattern, renderDesignPostBlock, renderDesignQuery, renderDesignText, resolveDesignTheme, resolvePresentationToken, routeLanguage, safeDesignRichText, siteLanguages };
|
|
204
|
+
export { Alternate, Archives, CmsFailure, CmsFailureReason, type CollectionConfig, CollectionItem, CollectionListing, CollectionMembership, CollectionPage, CollectionQuery, CollectionTerm, CollectionTermCount, CollectionTermListing, ContentBindings, type ContentConfig, type ContentConsentConfig, type ContentExtension, type ContentRuntime, Delivery, DeliveryFailureReason, DesignBlock, DesignBlockRenderer, DesignPattern, type DesignPostContext, type DesignPostRecord, type DesignPreloadedPosts, DesignPresets, type DesignQueryItem, type DesignQueryRenderContext, type DesignQueryResolverOptions, DesignRenderContext, DesignRenderOptions, type DesignTextContext, type DesignTheme, type DesignThemeOverrides, EntryContent, EntryDelivery, EntryPage, EntryPublication, Extended, type ExtensionNode, Found, HomeContent, HomeDelivery, HomePage, HomePublication, Missing, Moved, NotServed, type Presentation, type PresentationBreakpoint, type PresentationModel, type Property as PresentationProperty, type PresentationTargets, type PresentationTheme, PublishedEntry, SearchDelivery, SearchItem, SearchPage, SearchQuery, SiteChrome, SiteLanguage, SqlDatabase, SqlStatement, Translation, Unavailable, type VideoHeroFit, type VideoHeroPosition, type WordPressClient, WordPressImage, WordPressLanguages, WordPressMenuItem, WordPressPost, WordPressSettings, createPresentationModel, designMenuItems, designPostContext, designQueryItems, designThemeStyleSheet, designThemeVariables, escapeHtml, htmlLang, isLanguageHome, languageSubject, parseDesignBlocks, preloadDesignQueryPosts, presentationModel, presentationStyleSheet, presentationVariables, renderDesignPattern, renderDesignPostBlock, renderDesignQuery, renderDesignText, resolveDesignTheme, resolvePresentationToken, routeLanguage, safeDesignRichText, siteLanguages };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as selectSiteLogo, A as DESIGN_CAROUSEL_ITEM, B as safeDesignRichText, C as renderDesignQuery, D as renderWordPressBlocks, E as parseWordPressBlocks, F as VIDEO_HERO_BLOCK, G as createPresentationModel, H as navigationStyleSheet, I as renderDesignVideoHero, J as presentationVariables, K as presentationModel, L as youtubeVideoId, M as designCarouselStyle, N as renderDesignCarousel, O as designGridStyle, P as renderDesignCarouselItem, Q as resolvePresentationToken, R as renderDesignImage, S as renderDesignPostBlock, T as hasVideoHero, U as renderDesignNavigation, V as enhanceDesignNavigationHtml, W as presentationHtml, X as designThemeVariables, Y as designThemeStyleSheet, Z as resolveDesignTheme, _ as uriPath, a as siteLanguages, b as designQueryItems, c as parseDesignBlocks, d as decodeEntities, f as formatDate, g as stripHtml, h as routeOf, i as routeLanguage, j as DESIGN_CAROUSEL_NAVIGATION, k as DESIGN_CAROUSEL, l as renderDesignPattern, m as responseStatus, n as isLanguageHome, o as designMenuItems, p as menuItemHref, q as presentationStyleSheet, r as languageSubject, s as escapeHtml, t as htmlLang, tt as enhanceDesignCoverVideosHtml, u as cmsTime, v as renderDesignCover, w as hasDesignCarousel, x as preloadDesignQueryPosts, y as designPostContext, z as renderDesignText } from "./site-language-
|
|
1
|
+
import { $ as selectSiteLogo, A as DESIGN_CAROUSEL_ITEM, B as safeDesignRichText, C as renderDesignQuery, D as renderWordPressBlocks, E as parseWordPressBlocks, F as VIDEO_HERO_BLOCK, G as createPresentationModel, H as navigationStyleSheet, I as renderDesignVideoHero, J as presentationVariables, K as presentationModel, L as youtubeVideoId, M as designCarouselStyle, N as renderDesignCarousel, O as designGridStyle, P as renderDesignCarouselItem, Q as resolvePresentationToken, R as renderDesignImage, S as renderDesignPostBlock, T as hasVideoHero, U as renderDesignNavigation, V as enhanceDesignNavigationHtml, W as presentationHtml, X as designThemeVariables, Y as designThemeStyleSheet, Z as resolveDesignTheme, _ as uriPath, a as siteLanguages, b as designQueryItems, c as parseDesignBlocks, d as decodeEntities, f as formatDate, g as stripHtml, h as routeOf, i as routeLanguage, j as DESIGN_CAROUSEL_NAVIGATION, k as DESIGN_CAROUSEL, l as renderDesignPattern, m as responseStatus, n as isLanguageHome, o as designMenuItems, p as menuItemHref, q as presentationStyleSheet, r as languageSubject, s as escapeHtml, t as htmlLang, tt as enhanceDesignCoverVideosHtml, u as cmsTime, v as renderDesignCover, w as hasDesignCarousel, x as preloadDesignQueryPosts, y as designPostContext, z as renderDesignText } from "./site-language-BCGjkpWY.js";
|
|
2
2
|
import { n as videoHeroStyleSheet, t as videoHeroFrameGeometry } from "./video-hero-D8AcMR4q.js";
|
|
3
3
|
//#region frontend/src/wp-block-styles.ts
|
|
4
4
|
const validSlug = (slug) => /^[a-z0-9][a-z0-9-]*$/.test(slug);
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
//#region frontend/src/request-guards.ts
|
|
2
|
+
/**
|
|
3
|
+
* Whether a browser posted from the Site itself. A cross-site post carries
|
|
4
|
+
* its Origin (and Sec-Fetch-Site); `origins` are the Site's public origins
|
|
5
|
+
* when the Worker sees another (a proxy). The request's own origin is always
|
|
6
|
+
* accepted.
|
|
7
|
+
*/
|
|
8
|
+
function isSameOrigin(request, origins) {
|
|
9
|
+
const origin = request.headers.get("Origin");
|
|
10
|
+
const site = request.headers.get("Sec-Fetch-Site");
|
|
11
|
+
if (site && site !== "same-origin") return false;
|
|
12
|
+
if (!origin) return false;
|
|
13
|
+
if (origin === new URL(request.url).origin || origins.has(origin)) return true;
|
|
14
|
+
try {
|
|
15
|
+
return new URL(origin).host === request.headers.get("Host");
|
|
16
|
+
} catch {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/** The body as text, or null once it exceeds `limit` bytes (declared or read). */
|
|
21
|
+
async function readBoundedBody(request, limit) {
|
|
22
|
+
if (Number(request.headers.get("Content-Length") ?? "0") > limit) return null;
|
|
23
|
+
if (!request.body) return "";
|
|
24
|
+
const reader = request.body.getReader();
|
|
25
|
+
const chunks = [];
|
|
26
|
+
let size = 0;
|
|
27
|
+
for (;;) {
|
|
28
|
+
const { done, value } = await reader.read();
|
|
29
|
+
if (done) break;
|
|
30
|
+
size += value.byteLength;
|
|
31
|
+
if (size > limit) {
|
|
32
|
+
await reader.cancel();
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
chunks.push(value);
|
|
36
|
+
}
|
|
37
|
+
const bytes = new Uint8Array(size);
|
|
38
|
+
let offset = 0;
|
|
39
|
+
for (const chunk of chunks) {
|
|
40
|
+
bytes.set(chunk, offset);
|
|
41
|
+
offset += chunk.byteLength;
|
|
42
|
+
}
|
|
43
|
+
return new TextDecoder().decode(bytes);
|
|
44
|
+
}
|
|
45
|
+
//#endregion
|
|
46
|
+
export { readBoundedBody as n, isSameOrigin as t };
|
package/dist/server.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { a as ContentExtension, c as createContentRuntime, i as ContentConsentConfig, k as ContentBindings, n as CollectionConfig, o as ContentRuntime, r as ContentConfig, s as ExtensionNode, t as WordPressClient } from "./wordpress-BvkTDMA0.js";
|
|
2
2
|
export { CollectionConfig, type ContentBindings, ContentConfig, ContentConsentConfig, ContentExtension, ContentRuntime, ExtensionNode, type WordPressClient, createContentRuntime };
|