@qwik.dev/router 2.0.0-beta.36 → 2.0.0-beta.37
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/lib/adapters/cloudflare-pages/vite/index.mjs +2 -4
- package/lib/adapters/shared/vite/index.mjs +10 -13
- package/lib/chunks/action-handler.mjs +782 -0
- package/lib/chunks/deepFreeze.qwik.mjs +591 -1
- package/lib/chunks/format.mjs +31 -0
- package/lib/chunks/fs.mjs +4 -6
- package/lib/chunks/{routing.qwik.mjs → head.qwik.mjs} +299 -416
- package/lib/chunks/http-error.qwik.mjs +2 -2
- package/lib/chunks/not-found-wrapper.qwik.mjs +2 -2
- package/lib/chunks/pathname.mjs +3 -32
- package/lib/chunks/request-path.mjs +60 -0
- package/lib/chunks/system.mjs +6 -7
- package/lib/chunks/use-functions.qwik.mjs +3 -12
- package/lib/chunks/worker-thread.qwik.mjs +431 -425
- package/lib/index.d.ts +176 -10
- package/lib/index.qwik.mjs +631 -443
- package/lib/middleware/aws-lambda/index.mjs +2 -1
- package/lib/middleware/request-handler/index.d.ts +56 -16
- package/lib/middleware/request-handler/index.mjs +193 -754
- package/lib/ssg/index.d.ts +3 -3
- package/lib/ssg/index.mjs +4 -3
- package/lib/vite/index.d.ts +15 -0
- package/lib/vite/index.mjs +145 -23
- package/package.json +3 -3
- package/lib/chunks/redirect-handler.mjs +0 -6
|
@@ -1,73 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { R as
|
|
5
|
-
|
|
1
|
+
import { n as getRouteLoaderCtx, o as getRouteLoaderValues, i as Q_ROUTE, p as loadRouteLoader, q as setRouteLoaders, S as ServerError, t as RedirectMessage, k as QFN_KEY, Q as QACTION_KEY, A as AbortMessage, l as QDATA_KEY, _ as _asyncRequestStore, F as FULLPATH_HEADER } from '../../chunks/deepFreeze.qwik.mjs';
|
|
2
|
+
import { d as resolveRouteConfig, e as isPromise, l as loadRoute } from '../../chunks/head.qwik.mjs';
|
|
3
|
+
import { I as IsQLoader, Q as QLoaderId, a as QActionId, b as IsQAction, t as trimRecognizedInternalPathname, r as recognizeRequest, c as resolveValidInternalFullPathname, d as trimInternalPathname, L as LOADER_REGEX } from '../../chunks/request-path.mjs';
|
|
4
|
+
import { g as getRequestRoute, a as getRequestMode, R as RequestRouteName, b as RequestEvSharedNonce, c as RequestEvSharedActionId, d as RequestEvSharedActionFormData, e as RequestEvHttpStatusMessage, j as jsonRequestWrapper, l as loaderHandler, f as actionHandler, h as hash, n as normalizeETag, p as performETagMatch, s as setETagHeader, i as setCachedLoader, k as setCachedSsr, r as resolveETag, m as resolveCacheKey, M as MAX_CACHE_SIZE, o as getCachedLoader, q as getCachedSsr, t as defaultLoaderCacheKey, u as defaultSsrCacheKey, v as RequestEvShareServerTiming, w as RequestEvETagCacheKey, x as createRequestEventWithDeps } from '../../chunks/action-handler.mjs';
|
|
5
|
+
export { y as clearLoaderCache, z as clearSsrCache } from '../../chunks/action-handler.mjs';
|
|
6
|
+
import { isDev, inlinedQrl } from '@qwik.dev/core';
|
|
7
|
+
import { _verifySerializable, _serialize, isDev as isDev$1 } from '@qwik.dev/core/internal';
|
|
8
|
+
import { e as ensureSlash } from '../../chunks/pathname.mjs';
|
|
6
9
|
import { g as getErrorHtml, m as minimalHtmlResponse } from '../../chunks/error-handler.mjs';
|
|
7
10
|
|
|
8
|
-
const IsQData = "@isQData";
|
|
9
|
-
const QDATA_JSON = "/q-data.json";
|
|
10
|
-
function getRouteMatchPathname(pathname) {
|
|
11
|
-
const isInternal = pathname.endsWith(QDATA_JSON);
|
|
12
|
-
if (isInternal) {
|
|
13
|
-
const trimEnd = pathname.length - QDATA_JSON.length + (globalThis.__NO_TRAILING_SLASH__ ? 0 : 1);
|
|
14
|
-
pathname = pathname.slice(0, trimEnd);
|
|
15
|
-
if (pathname === "") {
|
|
16
|
-
pathname = "/";
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
return {
|
|
20
|
-
pathname,
|
|
21
|
-
isInternal
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const MAX_CACHE_SIZE = typeof globalThis.__SSR_CACHE_SIZE__ === "number" ? globalThis.__SSR_CACHE_SIZE__ : 50;
|
|
26
|
-
const ssrCache = /* @__PURE__ */ new Map();
|
|
27
|
-
function resolveETag(eTagExport, headProps) {
|
|
28
|
-
if (eTagExport === void 0) {
|
|
29
|
-
return null;
|
|
30
|
-
}
|
|
31
|
-
if (typeof eTagExport === "function") {
|
|
32
|
-
return eTagExport(headProps);
|
|
33
|
-
}
|
|
34
|
-
return eTagExport;
|
|
35
|
-
}
|
|
36
|
-
function resolveCacheKey(cacheKeyExport, status, eTag, pathname) {
|
|
37
|
-
if (cacheKeyExport === true) {
|
|
38
|
-
return `${status}|${eTag}|${pathname}`;
|
|
39
|
-
}
|
|
40
|
-
if (typeof cacheKeyExport !== "function") {
|
|
41
|
-
return null;
|
|
42
|
-
}
|
|
43
|
-
return cacheKeyExport(status, eTag, pathname);
|
|
44
|
-
}
|
|
45
|
-
function getCachedHtml(key) {
|
|
46
|
-
const html = ssrCache.get(key);
|
|
47
|
-
if (html !== void 0) {
|
|
48
|
-
ssrCache.delete(key);
|
|
49
|
-
ssrCache.set(key, html);
|
|
50
|
-
}
|
|
51
|
-
return html;
|
|
52
|
-
}
|
|
53
|
-
function setCachedHtml(key, html) {
|
|
54
|
-
if (MAX_CACHE_SIZE <= 0) {
|
|
55
|
-
return;
|
|
56
|
-
}
|
|
57
|
-
if (ssrCache.size >= MAX_CACHE_SIZE) {
|
|
58
|
-
const firstKey = ssrCache.keys().next().value;
|
|
59
|
-
ssrCache.delete(firstKey);
|
|
60
|
-
}
|
|
61
|
-
ssrCache.set(key, html);
|
|
62
|
-
}
|
|
63
|
-
function clearSsrCache(cacheKey) {
|
|
64
|
-
if (cacheKey != null) {
|
|
65
|
-
ssrCache.delete(cacheKey);
|
|
66
|
-
} else {
|
|
67
|
-
ssrCache.clear();
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
11
|
var HttpStatus = /* @__PURE__ */ (function(HttpStatus2) {
|
|
72
12
|
HttpStatus2[HttpStatus2["Continue"] = 100] = "Continue";
|
|
73
13
|
HttpStatus2[HttpStatus2["SwitchingProtocols"] = 101] = "SwitchingProtocols";
|
|
@@ -133,457 +73,12 @@ var HttpStatus = /* @__PURE__ */ (function(HttpStatus2) {
|
|
|
133
73
|
return HttpStatus2;
|
|
134
74
|
})({});
|
|
135
75
|
|
|
136
|
-
const RequestEvLoaders = /* @__PURE__ */ Symbol("RequestEvLoaders");
|
|
137
|
-
const RequestEvMode = /* @__PURE__ */ Symbol("RequestEvMode");
|
|
138
|
-
const RequestEvRoute = /* @__PURE__ */ Symbol("RequestEvRoute");
|
|
139
|
-
const RequestEvLoaderSerializationStrategyMap = /* @__PURE__ */ Symbol("RequestEvLoaderSerializationStrategyMap");
|
|
140
|
-
const RequestRouteName = "@routeName";
|
|
141
|
-
const RequestEvSharedActionId = "@actionId";
|
|
142
|
-
const RequestEvSharedActionFormData = "@actionFormData";
|
|
143
|
-
const RequestEvSharedNonce = "@nonce";
|
|
144
|
-
const RequestEvIsRewrite = "@rewrite";
|
|
145
|
-
const RequestEvShareServerTiming = "@serverTiming";
|
|
146
|
-
const RequestEvETagCacheKey = "@eTagCacheKey";
|
|
147
|
-
const RequestEvHttpStatusMessage = "@httpStatusMessage";
|
|
148
|
-
const RequestEvShareQData = "qData";
|
|
149
|
-
function getRequestLoaders(requestEv) {
|
|
150
|
-
return requestEv[RequestEvLoaders];
|
|
151
|
-
}
|
|
152
|
-
function getRequestLoaderSerializationStrategyMap(requestEv) {
|
|
153
|
-
return requestEv[RequestEvLoaderSerializationStrategyMap];
|
|
154
|
-
}
|
|
155
|
-
function getRequestRoute(requestEv) {
|
|
156
|
-
return requestEv[RequestEvRoute];
|
|
157
|
-
}
|
|
158
|
-
function getRequestMode(requestEv) {
|
|
159
|
-
return requestEv[RequestEvMode];
|
|
160
|
-
}
|
|
161
|
-
const ABORT_INDEX = Number.MAX_SAFE_INTEGER;
|
|
162
|
-
const isDangerousKey = (k) => k === "__proto__" || k === "constructor" || k === "prototype";
|
|
163
|
-
const isArrayIndexKey = (k) => /^(0|[1-9]\d*)$/.test(k);
|
|
164
|
-
const getArrayPaths = (formData) => {
|
|
165
|
-
const arrayCandidates = /* @__PURE__ */ new Map();
|
|
166
|
-
for (const [name] of formData) {
|
|
167
|
-
const keys = name.split(".");
|
|
168
|
-
let hasDangerousKey = false;
|
|
169
|
-
for (const key of keys) {
|
|
170
|
-
if (isDangerousKey(key)) {
|
|
171
|
-
hasDangerousKey = true;
|
|
172
|
-
break;
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
if (hasDangerousKey) {
|
|
176
|
-
continue;
|
|
177
|
-
}
|
|
178
|
-
let path = "";
|
|
179
|
-
for (let i = 0; i < keys.length - 1; i++) {
|
|
180
|
-
const key = keys[i];
|
|
181
|
-
if (key.endsWith("[]")) {
|
|
182
|
-
break;
|
|
183
|
-
}
|
|
184
|
-
path = path ? `${path}.${key}` : key;
|
|
185
|
-
if (!arrayCandidates.has(path)) {
|
|
186
|
-
arrayCandidates.set(path, true);
|
|
187
|
-
}
|
|
188
|
-
if (!isArrayIndexKey(keys[i + 1])) {
|
|
189
|
-
arrayCandidates.set(path, false);
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
return new Set(Array.from(arrayCandidates.entries()).filter(([, isArrayPath]) => isArrayPath).map(([path]) => path));
|
|
194
|
-
};
|
|
195
|
-
const formToObj = (formData) => {
|
|
196
|
-
const values = /* @__PURE__ */ Object.create(null);
|
|
197
|
-
const arrayPaths = getArrayPaths(formData);
|
|
198
|
-
for (const [name, value] of formData) {
|
|
199
|
-
const keys = name.split(".");
|
|
200
|
-
let hasDangerousKey = false;
|
|
201
|
-
for (let i = 0; i < keys.length; i++) {
|
|
202
|
-
if (isDangerousKey(keys[i])) {
|
|
203
|
-
hasDangerousKey = true;
|
|
204
|
-
break;
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
if (hasDangerousKey) {
|
|
208
|
-
continue;
|
|
209
|
-
}
|
|
210
|
-
let object = values;
|
|
211
|
-
let path = "";
|
|
212
|
-
for (let i = 0; i < keys.length; i++) {
|
|
213
|
-
const key = keys[i];
|
|
214
|
-
if (key.endsWith("[]")) {
|
|
215
|
-
const arrayKey = key.slice(0, -2);
|
|
216
|
-
if (isDangerousKey(arrayKey)) {
|
|
217
|
-
break;
|
|
218
|
-
}
|
|
219
|
-
const existingValue = object[arrayKey];
|
|
220
|
-
if (existingValue !== void 0 && !Array.isArray(existingValue)) {
|
|
221
|
-
break;
|
|
222
|
-
}
|
|
223
|
-
object[arrayKey] = existingValue || [];
|
|
224
|
-
object[arrayKey].push(value);
|
|
225
|
-
break;
|
|
226
|
-
}
|
|
227
|
-
if (Array.isArray(object) && !isArrayIndexKey(key)) {
|
|
228
|
-
break;
|
|
229
|
-
}
|
|
230
|
-
if (i < keys.length - 1) {
|
|
231
|
-
path = path ? `${path}.${key}` : key;
|
|
232
|
-
const nextValue = object[key];
|
|
233
|
-
if (nextValue !== void 0) {
|
|
234
|
-
object = nextValue;
|
|
235
|
-
continue;
|
|
236
|
-
}
|
|
237
|
-
object = object[key] = arrayPaths.has(path) ? [] : /* @__PURE__ */ Object.create(null);
|
|
238
|
-
} else {
|
|
239
|
-
object[key] = value;
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
return values;
|
|
244
|
-
};
|
|
245
|
-
const parseRequest = async (deps, { request, method, query }, sharedMap) => {
|
|
246
|
-
const type = deps.getContentType(request.headers);
|
|
247
|
-
if (type === "application/x-www-form-urlencoded" || type === "multipart/form-data") {
|
|
248
|
-
const formData = await request.formData();
|
|
249
|
-
sharedMap.set(RequestEvSharedActionFormData, formData);
|
|
250
|
-
return formToObj(formData);
|
|
251
|
-
} else if (type === "application/json") {
|
|
252
|
-
const data = await request.json();
|
|
253
|
-
return data;
|
|
254
|
-
} else if (type === "application/qwik-json") {
|
|
255
|
-
if (method === "GET" && query.has(deps.QDATA_KEY)) {
|
|
256
|
-
const data = query.get(deps.QDATA_KEY);
|
|
257
|
-
if (data) {
|
|
258
|
-
try {
|
|
259
|
-
return _deserialize(decodeURIComponent(data));
|
|
260
|
-
} catch {
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
return _deserialize(await request.text());
|
|
265
|
-
}
|
|
266
|
-
return void 0;
|
|
267
|
-
};
|
|
268
|
-
function createRequestEventWithDeps(deps, serverRequestEv, loadedRoute, requestHandlers, basePathname, resolved) {
|
|
269
|
-
const { request, platform, env } = serverRequestEv;
|
|
270
|
-
const sharedMap = /* @__PURE__ */ new Map();
|
|
271
|
-
const cookie = new deps.Cookie(request.headers.get("cookie"));
|
|
272
|
-
const headers = new Headers();
|
|
273
|
-
const url = new URL(request.url);
|
|
274
|
-
const { pathname, isInternal } = deps.getRouteMatchPathname(url.pathname);
|
|
275
|
-
if (isInternal) {
|
|
276
|
-
url.pathname = pathname;
|
|
277
|
-
sharedMap.set(deps.IsQData, true);
|
|
278
|
-
}
|
|
279
|
-
let routeModuleIndex = -1;
|
|
280
|
-
let writableStream = null;
|
|
281
|
-
let requestData = void 0;
|
|
282
|
-
let locale = serverRequestEv.locale;
|
|
283
|
-
let status = loadedRoute?.$notFound$ ? 404 : 200;
|
|
284
|
-
const next = async () => {
|
|
285
|
-
routeModuleIndex++;
|
|
286
|
-
while (routeModuleIndex < requestHandlers.length) {
|
|
287
|
-
const moduleRequestHandler = requestHandlers[routeModuleIndex];
|
|
288
|
-
const result = moduleRequestHandler(requestEv);
|
|
289
|
-
if (deps.isPromise(result)) {
|
|
290
|
-
await result;
|
|
291
|
-
}
|
|
292
|
-
routeModuleIndex++;
|
|
293
|
-
}
|
|
294
|
-
};
|
|
295
|
-
const resetRoute = (_loadedRoute, _requestHandlers, _url = url) => {
|
|
296
|
-
loadedRoute = _loadedRoute;
|
|
297
|
-
status = loadedRoute?.$notFound$ ? 404 : 200;
|
|
298
|
-
requestHandlers = _requestHandlers;
|
|
299
|
-
url.pathname = _url.pathname;
|
|
300
|
-
url.search = _url.search;
|
|
301
|
-
routeModuleIndex = -1;
|
|
302
|
-
};
|
|
303
|
-
const check = () => {
|
|
304
|
-
if (writableStream !== null) {
|
|
305
|
-
throw new Error("Response already sent");
|
|
306
|
-
}
|
|
307
|
-
};
|
|
308
|
-
const send = (statusOrResponse, body) => {
|
|
309
|
-
check();
|
|
310
|
-
if (typeof statusOrResponse === "number") {
|
|
311
|
-
status = statusOrResponse;
|
|
312
|
-
const writableStream2 = requestEv.getWritableStream();
|
|
313
|
-
const writer = writableStream2.getWriter();
|
|
314
|
-
writer.write(typeof body === "string" ? deps.encoder.encode(body) : body);
|
|
315
|
-
writer.close();
|
|
316
|
-
} else {
|
|
317
|
-
status = statusOrResponse.status;
|
|
318
|
-
statusOrResponse.headers.forEach((value, key) => {
|
|
319
|
-
if (key.toLowerCase() === "set-cookie") {
|
|
320
|
-
return;
|
|
321
|
-
}
|
|
322
|
-
headers.append(key, value);
|
|
323
|
-
});
|
|
324
|
-
statusOrResponse.headers.getSetCookie().forEach((ck) => {
|
|
325
|
-
const index = ck.indexOf("=");
|
|
326
|
-
if (index === -1) {
|
|
327
|
-
return;
|
|
328
|
-
}
|
|
329
|
-
const key = ck.slice(0, index).trim();
|
|
330
|
-
const value = ck.slice(index + 1).trim();
|
|
331
|
-
cookie.set(key, value);
|
|
332
|
-
});
|
|
333
|
-
if (statusOrResponse.body) {
|
|
334
|
-
const writableStream2 = requestEv.getWritableStream();
|
|
335
|
-
statusOrResponse.body.pipeTo(writableStream2);
|
|
336
|
-
} else {
|
|
337
|
-
requestEv.getWritableStream().getWriter().close();
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
return exit();
|
|
341
|
-
};
|
|
342
|
-
const exit = (message = new deps.AbortMessage()) => {
|
|
343
|
-
routeModuleIndex = ABORT_INDEX;
|
|
344
|
-
return message;
|
|
345
|
-
};
|
|
346
|
-
const loaders = {};
|
|
347
|
-
const requestEv = {
|
|
348
|
-
[RequestEvLoaders]: loaders,
|
|
349
|
-
[RequestEvLoaderSerializationStrategyMap]: /* @__PURE__ */ new Map(),
|
|
350
|
-
[RequestEvMode]: serverRequestEv.mode,
|
|
351
|
-
get [RequestEvRoute]() {
|
|
352
|
-
return loadedRoute;
|
|
353
|
-
},
|
|
354
|
-
cookie,
|
|
355
|
-
headers,
|
|
356
|
-
env,
|
|
357
|
-
method: request.method,
|
|
358
|
-
signal: request.signal,
|
|
359
|
-
originalUrl: new URL(url),
|
|
360
|
-
get params() {
|
|
361
|
-
return loadedRoute?.$params$ ?? {};
|
|
362
|
-
},
|
|
363
|
-
get pathname() {
|
|
364
|
-
return url.pathname;
|
|
365
|
-
},
|
|
366
|
-
platform,
|
|
367
|
-
get query() {
|
|
368
|
-
return url.searchParams;
|
|
369
|
-
},
|
|
370
|
-
request,
|
|
371
|
-
url,
|
|
372
|
-
basePathname,
|
|
373
|
-
sharedMap,
|
|
374
|
-
get headersSent() {
|
|
375
|
-
return writableStream !== null;
|
|
376
|
-
},
|
|
377
|
-
get exited() {
|
|
378
|
-
return routeModuleIndex >= ABORT_INDEX;
|
|
379
|
-
},
|
|
380
|
-
get clientConn() {
|
|
381
|
-
return serverRequestEv.getClientConn();
|
|
382
|
-
},
|
|
383
|
-
next,
|
|
384
|
-
resetRoute,
|
|
385
|
-
exit,
|
|
386
|
-
cacheControl: (cacheControl, target = "Cache-Control") => {
|
|
387
|
-
check();
|
|
388
|
-
headers.set(target, deps.createCacheControl(cacheControl));
|
|
389
|
-
},
|
|
390
|
-
resolveValue: async (loaderOrAction) => {
|
|
391
|
-
const id = loaderOrAction.__id;
|
|
392
|
-
if (loaderOrAction.__brand === "server_loader") {
|
|
393
|
-
if (!(id in loaders)) {
|
|
394
|
-
throw new Error("You can not get the returned data of a loader that has not been executed for this request.");
|
|
395
|
-
}
|
|
396
|
-
if (loaders[id] === _UNINITIALIZED) {
|
|
397
|
-
await deps.getRouteLoaderPromise(loaderOrAction, loaders, requestEv[RequestEvLoaderSerializationStrategyMap], requestEv);
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
return loaders[id];
|
|
401
|
-
},
|
|
402
|
-
status: (statusCode) => {
|
|
403
|
-
if (typeof statusCode === "number") {
|
|
404
|
-
check();
|
|
405
|
-
status = statusCode;
|
|
406
|
-
return statusCode;
|
|
407
|
-
}
|
|
408
|
-
return status;
|
|
409
|
-
},
|
|
410
|
-
locale: (_locale) => {
|
|
411
|
-
if (typeof _locale === "string") {
|
|
412
|
-
locale = _locale;
|
|
413
|
-
}
|
|
414
|
-
return locale || "";
|
|
415
|
-
},
|
|
416
|
-
error: (statusCode, message) => {
|
|
417
|
-
status = statusCode;
|
|
418
|
-
headers.delete("Cache-Control");
|
|
419
|
-
return new deps.ServerError(statusCode, message);
|
|
420
|
-
},
|
|
421
|
-
redirect: (statusCode, url2) => {
|
|
422
|
-
check();
|
|
423
|
-
status = statusCode;
|
|
424
|
-
if (url2) {
|
|
425
|
-
if (
|
|
426
|
-
// //test.com
|
|
427
|
-
/^\/\//.test(url2) || // /test//path
|
|
428
|
-
/([^:])\/\/+/.test(url2)
|
|
429
|
-
) {
|
|
430
|
-
const fixedURL = url2.replace(/^\/\/+/, "/").replace(/([^:])\/\/+/g, "$1/");
|
|
431
|
-
console.warn(`Redirect URL ${url2} is invalid, fixing to ${fixedURL}`);
|
|
432
|
-
url2 = fixedURL;
|
|
433
|
-
}
|
|
434
|
-
headers.set("Location", url2);
|
|
435
|
-
}
|
|
436
|
-
headers.delete("Cache-Control");
|
|
437
|
-
if (statusCode > 301) {
|
|
438
|
-
headers.set("Cache-Control", "no-store");
|
|
439
|
-
}
|
|
440
|
-
return exit(new deps.RedirectMessage());
|
|
441
|
-
},
|
|
442
|
-
rewrite: (pathname2) => {
|
|
443
|
-
check();
|
|
444
|
-
if (pathname2.startsWith("http")) {
|
|
445
|
-
throw new deps.ServerError(400, isDev ? "Rewrite does not support absolute urls" : "Bad Request");
|
|
446
|
-
}
|
|
447
|
-
sharedMap.set(RequestEvIsRewrite, true);
|
|
448
|
-
return exit(new deps.RewriteMessage(pathname2.replace(/\/+/g, "/")));
|
|
449
|
-
},
|
|
450
|
-
defer: (returnData) => {
|
|
451
|
-
return typeof returnData === "function" ? returnData : () => returnData;
|
|
452
|
-
},
|
|
453
|
-
fail: (statusCode, data) => {
|
|
454
|
-
check();
|
|
455
|
-
status = statusCode;
|
|
456
|
-
headers.delete("Cache-Control");
|
|
457
|
-
return {
|
|
458
|
-
failed: true,
|
|
459
|
-
...data
|
|
460
|
-
};
|
|
461
|
-
},
|
|
462
|
-
text: (statusCode, text) => {
|
|
463
|
-
headers.set("Content-Type", "text/plain; charset=utf-8");
|
|
464
|
-
return send(statusCode, text);
|
|
465
|
-
},
|
|
466
|
-
html: (statusCode, html) => {
|
|
467
|
-
headers.set("Content-Type", "text/html; charset=utf-8");
|
|
468
|
-
return send(statusCode, html);
|
|
469
|
-
},
|
|
470
|
-
parseBody: async () => {
|
|
471
|
-
if (requestData !== void 0) {
|
|
472
|
-
return requestData;
|
|
473
|
-
}
|
|
474
|
-
return requestData = parseRequest(deps, requestEv, sharedMap);
|
|
475
|
-
},
|
|
476
|
-
json: (statusCode, data) => {
|
|
477
|
-
headers.set("Content-Type", "application/json; charset=utf-8");
|
|
478
|
-
return send(statusCode, JSON.stringify(data));
|
|
479
|
-
},
|
|
480
|
-
send,
|
|
481
|
-
isDirty: () => {
|
|
482
|
-
return writableStream !== null;
|
|
483
|
-
},
|
|
484
|
-
getWritableStream: () => {
|
|
485
|
-
if (writableStream === null) {
|
|
486
|
-
if (isDev) {
|
|
487
|
-
const serverTiming = sharedMap.get(RequestEvShareServerTiming);
|
|
488
|
-
if (serverTiming) {
|
|
489
|
-
headers.set("Server-Timing", serverTiming.map(([name, duration]) => `${name};dur=${duration}`).join(","));
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
writableStream = serverRequestEv.getWritableStream(status, headers, cookie, resolved, requestEv);
|
|
493
|
-
}
|
|
494
|
-
return writableStream;
|
|
495
|
-
}
|
|
496
|
-
};
|
|
497
|
-
return requestEv;
|
|
498
|
-
}
|
|
499
|
-
|
|
500
|
-
function verifySerializable(data, qrl) {
|
|
501
|
-
try {
|
|
502
|
-
_verifySerializable(data, void 0);
|
|
503
|
-
} catch (e) {
|
|
504
|
-
if (e instanceof Error && qrl.dev) {
|
|
505
|
-
e.loc = qrl.dev;
|
|
506
|
-
}
|
|
507
|
-
throw e;
|
|
508
|
-
}
|
|
509
|
-
}
|
|
510
|
-
function now() {
|
|
511
|
-
return typeof performance !== "undefined" ? performance.now() : 0;
|
|
512
|
-
}
|
|
513
|
-
async function measure(requestEv, name, fn) {
|
|
514
|
-
const start = now();
|
|
515
|
-
try {
|
|
516
|
-
return await fn();
|
|
517
|
-
} finally {
|
|
518
|
-
const duration = now() - start;
|
|
519
|
-
let measurements = requestEv.sharedMap.get("@serverTiming");
|
|
520
|
-
if (!measurements) {
|
|
521
|
-
requestEv.sharedMap.set("@serverTiming", measurements = []);
|
|
522
|
-
}
|
|
523
|
-
measurements.push([
|
|
524
|
-
name,
|
|
525
|
-
duration
|
|
526
|
-
]);
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
|
-
async function runValidators(requestEv, validators, data) {
|
|
530
|
-
let lastResult = {
|
|
531
|
-
success: true,
|
|
532
|
-
data
|
|
533
|
-
};
|
|
534
|
-
if (validators) {
|
|
535
|
-
for (const validator of validators) {
|
|
536
|
-
if (isDev) {
|
|
537
|
-
lastResult = await measure(requestEv, `validator$`, () => validator.validate(requestEv, data));
|
|
538
|
-
} else {
|
|
539
|
-
lastResult = await validator.validate(requestEv, data);
|
|
540
|
-
}
|
|
541
|
-
if (!lastResult.success) {
|
|
542
|
-
return lastResult;
|
|
543
|
-
} else {
|
|
544
|
-
data = lastResult.data;
|
|
545
|
-
}
|
|
546
|
-
}
|
|
547
|
-
}
|
|
548
|
-
return lastResult;
|
|
549
|
-
}
|
|
550
|
-
async function getRouteLoaderPromise(loader, loaders, loadersSerializationStrategy, requestEv) {
|
|
551
|
-
const loaderId = loader.__id;
|
|
552
|
-
loaders[loaderId] = runValidators(
|
|
553
|
-
requestEv,
|
|
554
|
-
loader.__validators,
|
|
555
|
-
void 0
|
|
556
|
-
// data
|
|
557
|
-
).then((res) => {
|
|
558
|
-
if (res.success) {
|
|
559
|
-
if (isDev) {
|
|
560
|
-
return measure(requestEv, loader.__qrl.getHash(), () => loader.__qrl.call(requestEv, requestEv));
|
|
561
|
-
} else {
|
|
562
|
-
return loader.__qrl.call(requestEv, requestEv);
|
|
563
|
-
}
|
|
564
|
-
} else {
|
|
565
|
-
return requestEv.fail(res.status ?? 500, res.error);
|
|
566
|
-
}
|
|
567
|
-
}).then((resolvedLoader) => {
|
|
568
|
-
if (typeof resolvedLoader === "function") {
|
|
569
|
-
loaders[loaderId] = resolvedLoader();
|
|
570
|
-
} else {
|
|
571
|
-
if (isDev) {
|
|
572
|
-
verifySerializable(resolvedLoader, loader.__qrl);
|
|
573
|
-
}
|
|
574
|
-
loaders[loaderId] = resolvedLoader;
|
|
575
|
-
}
|
|
576
|
-
return resolvedLoader;
|
|
577
|
-
});
|
|
578
|
-
loadersSerializationStrategy.set(loaderId, loader.__serializationStrategy);
|
|
579
|
-
return loaders[loaderId];
|
|
580
|
-
}
|
|
581
|
-
|
|
582
76
|
function getQwikRouterServerDataWithDeps(deps, requestEv) {
|
|
583
77
|
const { params, request, status, locale, originalUrl } = requestEv;
|
|
584
78
|
const requestHeaders = {};
|
|
585
79
|
request.headers.forEach((value, key) => requestHeaders[key] = value);
|
|
586
80
|
const action = requestEv.sharedMap.get(deps.RequestEvSharedActionId);
|
|
81
|
+
const actionResult = requestEv.sharedMap.get("@actionResult");
|
|
587
82
|
const formData = requestEv.sharedMap.get(deps.RequestEvSharedActionFormData);
|
|
588
83
|
const routeName = requestEv.sharedMap.get(deps.RequestRouteName);
|
|
589
84
|
const nonce = requestEv.sharedMap.get(deps.RequestEvSharedNonce);
|
|
@@ -598,8 +93,8 @@ function getQwikRouterServerDataWithDeps(deps, requestEv) {
|
|
|
598
93
|
if (protocol) {
|
|
599
94
|
reconstructedUrl.protocol = protocol;
|
|
600
95
|
}
|
|
601
|
-
const
|
|
602
|
-
const
|
|
96
|
+
const routeLoaderCtx = getRouteLoaderCtx(requestEv);
|
|
97
|
+
const loaderValues = getRouteLoaderValues(requestEv);
|
|
603
98
|
return {
|
|
604
99
|
url: reconstructedUrl.href,
|
|
605
100
|
requestHeaders,
|
|
@@ -616,12 +111,13 @@ function getQwikRouterServerDataWithDeps(deps, requestEv) {
|
|
|
616
111
|
...params
|
|
617
112
|
},
|
|
618
113
|
loadedRoute: deps.getRequestRoute(requestEv),
|
|
114
|
+
routeLoaderCtx,
|
|
115
|
+
loaderValues,
|
|
619
116
|
response: {
|
|
620
117
|
status: status(),
|
|
621
118
|
statusMessage: requestEv.sharedMap.get(deps.RequestEvHttpStatusMessage),
|
|
622
|
-
loaders,
|
|
623
|
-
loadersSerializationStrategy,
|
|
624
119
|
action,
|
|
120
|
+
actionResult,
|
|
625
121
|
formData
|
|
626
122
|
}
|
|
627
123
|
}
|
|
@@ -635,8 +131,6 @@ const responsePageDeps = {
|
|
|
635
131
|
RequestEvSharedActionId,
|
|
636
132
|
RequestEvSharedNonce,
|
|
637
133
|
RequestRouteName,
|
|
638
|
-
getRequestLoaders,
|
|
639
|
-
getRequestLoaderSerializationStrategyMap,
|
|
640
134
|
getRequestMode,
|
|
641
135
|
getRequestRoute
|
|
642
136
|
};
|
|
@@ -645,22 +139,20 @@ function getQwikRouterServerData(...args) {
|
|
|
645
139
|
}
|
|
646
140
|
|
|
647
141
|
function createResolveRequestHandlers(deps) {
|
|
648
|
-
const resolveRequestHandlers = (serverPlugins, route, method, checkOrigin, renderHandler
|
|
142
|
+
const resolveRequestHandlers = (serverPlugins, route, method, checkOrigin, renderHandler) => {
|
|
649
143
|
const routeLoaders = [];
|
|
650
144
|
const routeActions = [];
|
|
651
145
|
const requestHandlers = [];
|
|
652
146
|
const isPageRoute = !!isLastModulePageRoute(route.$mods$);
|
|
653
|
-
if (isInternal) {
|
|
654
|
-
requestHandlers.push(handleQDataRedirect);
|
|
655
|
-
}
|
|
656
147
|
if (isPageRoute) {
|
|
148
|
+
requestHandlers.push(jsonRequestWrapper());
|
|
657
149
|
requestHandlers.push(serverErrorMiddleware(route, renderHandler));
|
|
658
150
|
}
|
|
659
151
|
if (serverPlugins) {
|
|
660
152
|
_resolveRequestHandlers(routeLoaders, routeActions, requestHandlers, serverPlugins, isPageRoute, method);
|
|
661
153
|
}
|
|
662
154
|
const routeModules = route.$mods$;
|
|
663
|
-
_resolveRequestHandlers(routeLoaders, routeActions, requestHandlers, routeModules, isPageRoute, method);
|
|
155
|
+
_resolveRequestHandlers(routeLoaders, routeActions, requestHandlers, routeModules, isPageRoute, method, isPageRoute);
|
|
664
156
|
const routeName = route.$routeName$;
|
|
665
157
|
if (checkOrigin && (method === "POST" || method === "PUT" || method === "PATCH" || method === "DELETE")) {
|
|
666
158
|
if (checkOrigin === "lax-proto") {
|
|
@@ -670,70 +162,32 @@ function createResolveRequestHandlers(deps) {
|
|
|
670
162
|
}
|
|
671
163
|
}
|
|
672
164
|
if (isPageRoute) {
|
|
165
|
+
requestHandlers.push(loaderHandler(routeLoaders, route.$loaderPaths$));
|
|
166
|
+
requestHandlers.push(actionHandler(routeActions));
|
|
673
167
|
if (method === "POST" || method === "GET") {
|
|
674
168
|
requestHandlers.push(runServerFunction);
|
|
675
169
|
}
|
|
676
170
|
if (!route.$notFound$) {
|
|
677
171
|
requestHandlers.push(fixTrailingSlash);
|
|
678
172
|
}
|
|
679
|
-
if (isInternal) {
|
|
680
|
-
requestHandlers.push(renderQData);
|
|
681
|
-
}
|
|
682
173
|
}
|
|
683
174
|
if (isPageRoute) {
|
|
684
175
|
requestHandlers.push((ev) => {
|
|
685
176
|
ev.sharedMap.set(deps.RequestRouteName, routeName);
|
|
686
177
|
});
|
|
687
178
|
requestHandlers.push(actionsMiddleware(routeActions));
|
|
688
|
-
requestHandlers.push(loadersMiddleware(routeLoaders));
|
|
179
|
+
requestHandlers.push(loadersMiddleware(routeLoaders, route));
|
|
689
180
|
requestHandlers.push(eTagMiddleware(route));
|
|
690
181
|
requestHandlers.push(renderHandler);
|
|
691
182
|
}
|
|
692
183
|
return requestHandlers;
|
|
693
184
|
};
|
|
694
|
-
|
|
695
|
-
for (
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
}
|
|
701
|
-
let methodReqHandler;
|
|
702
|
-
switch (method) {
|
|
703
|
-
case "GET": {
|
|
704
|
-
methodReqHandler = routeModule.onGet;
|
|
705
|
-
break;
|
|
706
|
-
}
|
|
707
|
-
case "POST": {
|
|
708
|
-
methodReqHandler = routeModule.onPost;
|
|
709
|
-
break;
|
|
710
|
-
}
|
|
711
|
-
case "PUT": {
|
|
712
|
-
methodReqHandler = routeModule.onPut;
|
|
713
|
-
break;
|
|
714
|
-
}
|
|
715
|
-
case "PATCH": {
|
|
716
|
-
methodReqHandler = routeModule.onPatch;
|
|
717
|
-
break;
|
|
718
|
-
}
|
|
719
|
-
case "DELETE": {
|
|
720
|
-
methodReqHandler = routeModule.onDelete;
|
|
721
|
-
break;
|
|
722
|
-
}
|
|
723
|
-
case "OPTIONS": {
|
|
724
|
-
methodReqHandler = routeModule.onOptions;
|
|
725
|
-
break;
|
|
726
|
-
}
|
|
727
|
-
case "HEAD": {
|
|
728
|
-
methodReqHandler = routeModule.onHead;
|
|
729
|
-
break;
|
|
730
|
-
}
|
|
731
|
-
}
|
|
732
|
-
if (typeof methodReqHandler === "function") {
|
|
733
|
-
requestHandlers.push(methodReqHandler);
|
|
734
|
-
} else if (Array.isArray(methodReqHandler)) {
|
|
735
|
-
requestHandlers.push(...methodReqHandler);
|
|
736
|
-
}
|
|
185
|
+
function _resolveRequestHandlers(routeLoaders, routeActions, requestHandlers, routeModules, collectActions, method, guardPageHandlersForLoader = false) {
|
|
186
|
+
for (let i = 0; i < routeModules.length; i++) {
|
|
187
|
+
const routeModule = routeModules[i];
|
|
188
|
+
const moduleHandlers = getModuleRequestHandlers(routeModule, method);
|
|
189
|
+
const shouldGuardPageHandlers = guardPageHandlersForLoader && i === routeModules.length - 1;
|
|
190
|
+
requestHandlers.push(...shouldGuardPageHandlers ? moduleHandlers.map((handler) => guardPageHandlerForLoader(routeModule, handler)) : moduleHandlers);
|
|
737
191
|
if (collectActions) {
|
|
738
192
|
for (const module of Object.values(routeModule)) {
|
|
739
193
|
if (typeof module === "function") {
|
|
@@ -746,7 +200,73 @@ function createResolveRequestHandlers(deps) {
|
|
|
746
200
|
}
|
|
747
201
|
}
|
|
748
202
|
}
|
|
749
|
-
}
|
|
203
|
+
}
|
|
204
|
+
function getModuleRequestHandlers(routeModule, method) {
|
|
205
|
+
const handlers = [];
|
|
206
|
+
addRequestHandlers(handlers, routeModule.onRequest);
|
|
207
|
+
let methodReqHandler;
|
|
208
|
+
switch (method) {
|
|
209
|
+
case "GET": {
|
|
210
|
+
methodReqHandler = routeModule.onGet;
|
|
211
|
+
break;
|
|
212
|
+
}
|
|
213
|
+
case "POST": {
|
|
214
|
+
methodReqHandler = routeModule.onPost;
|
|
215
|
+
break;
|
|
216
|
+
}
|
|
217
|
+
case "PUT": {
|
|
218
|
+
methodReqHandler = routeModule.onPut;
|
|
219
|
+
break;
|
|
220
|
+
}
|
|
221
|
+
case "PATCH": {
|
|
222
|
+
methodReqHandler = routeModule.onPatch;
|
|
223
|
+
break;
|
|
224
|
+
}
|
|
225
|
+
case "DELETE": {
|
|
226
|
+
methodReqHandler = routeModule.onDelete;
|
|
227
|
+
break;
|
|
228
|
+
}
|
|
229
|
+
case "OPTIONS": {
|
|
230
|
+
methodReqHandler = routeModule.onOptions;
|
|
231
|
+
break;
|
|
232
|
+
}
|
|
233
|
+
case "HEAD": {
|
|
234
|
+
methodReqHandler = routeModule.onHead;
|
|
235
|
+
break;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
addRequestHandlers(handlers, methodReqHandler);
|
|
239
|
+
return handlers;
|
|
240
|
+
}
|
|
241
|
+
function addRequestHandlers(handlers, handler) {
|
|
242
|
+
if (typeof handler === "function") {
|
|
243
|
+
handlers.push(handler);
|
|
244
|
+
} else if (Array.isArray(handler)) {
|
|
245
|
+
handlers.push(...handler);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
function guardPageHandlerForLoader(routeModule, handler) {
|
|
249
|
+
return (requestEv) => {
|
|
250
|
+
if (requestEv.sharedMap.has(IsQLoader)) {
|
|
251
|
+
const loaderId = requestEv.sharedMap.get(QLoaderId);
|
|
252
|
+
if (!moduleHasLoader(routeModule, loaderId)) {
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
return handler(requestEv);
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
function moduleHasLoader(routeModule, loaderId) {
|
|
260
|
+
if (typeof loaderId !== "string") {
|
|
261
|
+
return false;
|
|
262
|
+
}
|
|
263
|
+
for (const value of Object.values(routeModule)) {
|
|
264
|
+
if (checkBrand(value, "server_loader") && value.__id === loaderId) {
|
|
265
|
+
return true;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
return false;
|
|
269
|
+
}
|
|
750
270
|
const checkBrand = (obj, brand) => {
|
|
751
271
|
return obj && typeof obj === "function" && obj.__brand === brand;
|
|
752
272
|
};
|
|
@@ -758,7 +278,6 @@ function createResolveRequestHandlers(deps) {
|
|
|
758
278
|
return;
|
|
759
279
|
}
|
|
760
280
|
const { method } = requestEv;
|
|
761
|
-
const loaders = deps.getRequestLoaders(requestEv);
|
|
762
281
|
if (isDev && method === "GET") {
|
|
763
282
|
if (requestEv.query.has(deps.QACTION_KEY)) {
|
|
764
283
|
console.warn('Seems like you are submitting a Qwik Action via GET request. Qwik Actions should be submitted via POST request.\nMake sure your <form> has method="POST" attribute, like this: <form method="POST">');
|
|
@@ -776,66 +295,79 @@ function createResolveRequestHandlers(deps) {
|
|
|
776
295
|
throw new Error(`Expected request data for the action id ${selectedActionId} to be an object`);
|
|
777
296
|
}
|
|
778
297
|
const result = await runValidators(requestEv, action.__validators, data);
|
|
298
|
+
let actionResult;
|
|
779
299
|
if (!result.success) {
|
|
780
|
-
|
|
300
|
+
actionResult = requestEv.fail(result.status ?? 500, result.error);
|
|
781
301
|
} else {
|
|
782
302
|
const actionResolved = isDev ? await measure(requestEv, action.__qrl.getHash(), () => action.__qrl.call(requestEv, result.data, requestEv)) : await action.__qrl.call(requestEv, result.data, requestEv);
|
|
783
303
|
if (isDev) {
|
|
784
304
|
verifySerializable(actionResolved, action.__qrl);
|
|
785
305
|
}
|
|
786
|
-
|
|
306
|
+
actionResult = actionResolved;
|
|
787
307
|
}
|
|
308
|
+
requestEv.sharedMap.set("@actionResult", actionResult);
|
|
788
309
|
}
|
|
789
310
|
}
|
|
790
311
|
}
|
|
791
312
|
};
|
|
792
313
|
}
|
|
793
|
-
function loadersMiddleware(routeLoaders) {
|
|
314
|
+
function loadersMiddleware(routeLoaders, route) {
|
|
794
315
|
return async (requestEvent) => {
|
|
795
316
|
const requestEv = requestEvent;
|
|
796
317
|
if (requestEv.headersSent) {
|
|
797
318
|
requestEv.exit();
|
|
798
319
|
return;
|
|
799
320
|
}
|
|
800
|
-
const loaders = deps.getRequestLoaders(requestEv);
|
|
801
|
-
const loadersSerializationStrategy = deps.getRequestLoaderSerializationStrategyMap(requestEv);
|
|
802
321
|
if (routeLoaders.length > 0) {
|
|
803
|
-
|
|
804
|
-
|
|
322
|
+
setLoaderData(requestEv, routeLoaders, route);
|
|
323
|
+
const loaderValues = getRouteLoaderValues(requestEv);
|
|
324
|
+
await Promise.all(routeLoaders.map(async (loader) => {
|
|
325
|
+
loaderValues[loader.__id] = await loadRouteLoader(loader, requestEv);
|
|
326
|
+
}));
|
|
805
327
|
}
|
|
806
328
|
};
|
|
807
329
|
}
|
|
330
|
+
function setLoaderData(requestEv, routeLoaders, route) {
|
|
331
|
+
if (routeLoaders.length === 0) {
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
const routeLoaderCtx = getRouteLoaderCtx(requestEv);
|
|
335
|
+
if (route.$loaderPaths$) {
|
|
336
|
+
Object.assign(routeLoaderCtx.loaderPaths, route.$loaderPaths$);
|
|
337
|
+
}
|
|
338
|
+
setRouteLoaders(requestEv, routeLoaders);
|
|
339
|
+
}
|
|
808
340
|
function eTagMiddleware(route) {
|
|
809
341
|
return (requestEv) => {
|
|
810
342
|
if (requestEv.headersSent) {
|
|
811
343
|
return;
|
|
812
344
|
}
|
|
813
|
-
if (requestEv.method !== "GET"
|
|
345
|
+
if (requestEv.method !== "GET") {
|
|
814
346
|
return;
|
|
815
347
|
}
|
|
816
348
|
const mods = route.$mods$;
|
|
817
|
-
const
|
|
349
|
+
const hasCachingConfig = mods.some((m) => {
|
|
818
350
|
if (!m) {
|
|
819
351
|
return false;
|
|
820
352
|
}
|
|
821
353
|
if (m.routeConfig) {
|
|
822
|
-
return typeof m.routeConfig === "function" || m.routeConfig.eTag !== void 0;
|
|
354
|
+
return typeof m.routeConfig === "function" || m.routeConfig.eTag !== void 0 || m.routeConfig.cacheKey !== void 0;
|
|
823
355
|
}
|
|
824
|
-
return m.eTag !== void 0;
|
|
356
|
+
return m.eTag !== void 0 || m.cacheKey !== void 0;
|
|
825
357
|
});
|
|
826
|
-
if (!
|
|
358
|
+
if (!hasCachingConfig) {
|
|
827
359
|
return;
|
|
828
360
|
}
|
|
829
|
-
const
|
|
361
|
+
const loaderValues = getRouteLoaderValues(requestEv);
|
|
830
362
|
const getData = (loaderOrAction) => {
|
|
831
363
|
const id = loaderOrAction.__id;
|
|
832
|
-
if (loaderOrAction.__brand === "server_loader"
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
364
|
+
if (loaderOrAction.__brand === "server_loader") {
|
|
365
|
+
if (!(id in loaderValues)) {
|
|
366
|
+
throw new Error("Loader not executed for this request.");
|
|
367
|
+
}
|
|
368
|
+
return loaderValues[id];
|
|
837
369
|
}
|
|
838
|
-
return
|
|
370
|
+
return requestEv.sharedMap.get(deps.RequestEvSharedActionId) === id ? requestEv.sharedMap.get("@actionResult") : void 0;
|
|
839
371
|
};
|
|
840
372
|
const routeLocation = {
|
|
841
373
|
params: requestEv.params,
|
|
@@ -852,32 +384,36 @@ function createResolveRequestHandlers(deps) {
|
|
|
852
384
|
resolveValue: getData,
|
|
853
385
|
...routeLocation
|
|
854
386
|
};
|
|
855
|
-
const
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
}
|
|
859
|
-
requestEv.headers.set("ETag", eTag);
|
|
860
|
-
const ifNoneMatch = requestEv.request.headers.get("If-None-Match");
|
|
861
|
-
if (ifNoneMatch && (ifNoneMatch === eTag || ifNoneMatch === `W/${eTag}` || `W/${ifNoneMatch}` === eTag)) {
|
|
862
|
-
requestEv.status(304);
|
|
863
|
-
requestEv.send(304, "");
|
|
387
|
+
const resolvedETag = deps.resolveETag(config.eTag, headProps);
|
|
388
|
+
const normalizedETag = resolvedETag !== null ? normalizeETag(resolvedETag) : "";
|
|
389
|
+
if (normalizedETag && performETagMatch(requestEv, normalizedETag)) {
|
|
864
390
|
return;
|
|
865
391
|
}
|
|
866
392
|
if (deps.MAX_CACHE_SIZE <= 0) {
|
|
867
393
|
return;
|
|
868
394
|
}
|
|
869
|
-
const cacheKey = deps.resolveCacheKey(config.cacheKey,
|
|
395
|
+
const cacheKey = deps.resolveCacheKey(config.cacheKey, deps.defaultSsrCacheKey, requestEv, normalizedETag);
|
|
870
396
|
if (!cacheKey) {
|
|
871
397
|
return;
|
|
872
398
|
}
|
|
873
|
-
const
|
|
874
|
-
if (
|
|
399
|
+
const cached = deps.getCachedSsr(cacheKey);
|
|
400
|
+
if (cached) {
|
|
875
401
|
requestEv.headers.set("Content-Type", "text/html; charset=utf-8");
|
|
876
402
|
requestEv.headers.set("X-SSR-Cache", "HIT");
|
|
877
|
-
|
|
403
|
+
if (!normalizedETag) {
|
|
404
|
+
if (performETagMatch(requestEv, cached.eTag)) {
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
407
|
+
} else {
|
|
408
|
+
setETagHeader(requestEv, cached.eTag);
|
|
409
|
+
}
|
|
410
|
+
requestEv.send(status, cached.body);
|
|
878
411
|
return;
|
|
879
412
|
}
|
|
880
|
-
requestEv.sharedMap.set(deps.RequestEvETagCacheKey,
|
|
413
|
+
requestEv.sharedMap.set(deps.RequestEvETagCacheKey, {
|
|
414
|
+
key: cacheKey,
|
|
415
|
+
eTag: normalizedETag
|
|
416
|
+
});
|
|
881
417
|
};
|
|
882
418
|
}
|
|
883
419
|
function serverErrorMiddleware(route, renderHandler) {
|
|
@@ -888,9 +424,6 @@ function createResolveRequestHandlers(deps) {
|
|
|
888
424
|
if (!(e instanceof deps.ServerError) || requestEv.headersSent) {
|
|
889
425
|
throw e;
|
|
890
426
|
}
|
|
891
|
-
if (requestEv.sharedMap.has(deps.IsQData)) {
|
|
892
|
-
throw e;
|
|
893
|
-
}
|
|
894
427
|
const accept = requestEv.request.headers.get("Accept");
|
|
895
428
|
if (accept && !accept.includes("text/html")) {
|
|
896
429
|
throw e;
|
|
@@ -980,16 +513,15 @@ function createResolveRequestHandlers(deps) {
|
|
|
980
513
|
}
|
|
981
514
|
}
|
|
982
515
|
function fixTrailingSlash(ev) {
|
|
983
|
-
const { basePathname, originalUrl
|
|
516
|
+
const { basePathname, originalUrl } = ev;
|
|
984
517
|
const { pathname, search } = originalUrl;
|
|
985
|
-
const isQData = sharedMap.has(deps.IsQData);
|
|
986
518
|
if (!pathname.startsWith("/") || pathname.startsWith("//")) {
|
|
987
519
|
return;
|
|
988
520
|
}
|
|
989
|
-
if (
|
|
521
|
+
if (pathname !== basePathname && !pathname.endsWith(".html")) {
|
|
990
522
|
if (!globalThis.__NO_TRAILING_SLASH__) {
|
|
991
523
|
if (!pathname.endsWith("/")) {
|
|
992
|
-
throw ev.redirect(deps.HttpStatus.MovedPermanently, pathname +
|
|
524
|
+
throw ev.redirect(deps.HttpStatus.MovedPermanently, ensureSlash(pathname) + search);
|
|
993
525
|
}
|
|
994
526
|
} else {
|
|
995
527
|
if (pathname.endsWith("/")) {
|
|
@@ -1017,12 +549,9 @@ function createResolveRequestHandlers(deps) {
|
|
|
1017
549
|
}
|
|
1018
550
|
function getPathname(url) {
|
|
1019
551
|
url = new URL(url);
|
|
1020
|
-
if (url.pathname.endsWith(deps.QDATA_JSON)) {
|
|
1021
|
-
url.pathname = url.pathname.slice(0, -deps.QDATA_JSON.length);
|
|
1022
|
-
}
|
|
1023
552
|
if (!globalThis.__NO_TRAILING_SLASH__) {
|
|
1024
553
|
if (!url.pathname.endsWith("/")) {
|
|
1025
|
-
url.pathname
|
|
554
|
+
url.pathname = ensureSlash(url.pathname);
|
|
1026
555
|
}
|
|
1027
556
|
} else {
|
|
1028
557
|
if (url.pathname.endsWith("/")) {
|
|
@@ -1059,19 +588,16 @@ The request origin "${inputOrigin}" does not match the server origin "${origin}"
|
|
|
1059
588
|
if (requestEv.headersSent) {
|
|
1060
589
|
return;
|
|
1061
590
|
}
|
|
1062
|
-
if (requestEv.sharedMap.has(deps.IsQData)) {
|
|
1063
|
-
return;
|
|
1064
|
-
}
|
|
1065
591
|
const responseHeaders = requestEv.headers;
|
|
1066
592
|
if (!responseHeaders.has("Content-Type")) {
|
|
1067
593
|
responseHeaders.set("Content-Type", "text/html; charset=utf-8");
|
|
1068
594
|
}
|
|
1069
|
-
const
|
|
595
|
+
const cachePlan = requestEv.sharedMap.get(deps.RequestEvETagCacheKey);
|
|
1070
596
|
const { readable, writable } = new TextEncoderStream();
|
|
1071
597
|
const writableStream = requestEv.getWritableStream();
|
|
1072
598
|
let cacheChunks;
|
|
1073
599
|
let pipeSource = readable;
|
|
1074
|
-
if (
|
|
600
|
+
if (cachePlan) {
|
|
1075
601
|
cacheChunks = [];
|
|
1076
602
|
const capture = new TransformStream({
|
|
1077
603
|
transform(chunk, controller) {
|
|
@@ -1088,7 +614,6 @@ The request origin "${inputOrigin}" does not match the server origin "${origin}"
|
|
|
1088
614
|
pipeError = error;
|
|
1089
615
|
});
|
|
1090
616
|
const stream = writable.getWriter();
|
|
1091
|
-
const status = requestEv.status();
|
|
1092
617
|
try {
|
|
1093
618
|
const isStatic = deps.getRequestMode(requestEv) === "static";
|
|
1094
619
|
const serverData = deps.getQwikRouterServerData(requestEv);
|
|
@@ -1104,16 +629,9 @@ The request origin "${inputOrigin}" does not match the server origin "${origin}"
|
|
|
1104
629
|
...serverData.containerAttributes
|
|
1105
630
|
}
|
|
1106
631
|
});
|
|
1107
|
-
const qData = {
|
|
1108
|
-
loaders: deps.getRequestLoaders(requestEv),
|
|
1109
|
-
action: requestEv.sharedMap.get(deps.RequestEvSharedActionId),
|
|
1110
|
-
status: status !== 200 ? status : 200,
|
|
1111
|
-
href: getPathname(requestEv.url)
|
|
1112
|
-
};
|
|
1113
632
|
if (typeof result.html === "string") {
|
|
1114
633
|
await stream.write(result.html);
|
|
1115
634
|
}
|
|
1116
|
-
requestEv.sharedMap.set(deps.RequestEvShareQData, qData);
|
|
1117
635
|
} finally {
|
|
1118
636
|
await stream.ready;
|
|
1119
637
|
await stream.close();
|
|
@@ -1122,7 +640,7 @@ The request origin "${inputOrigin}" does not match the server origin "${origin}"
|
|
|
1122
640
|
if (pipeError) {
|
|
1123
641
|
throw pipeError;
|
|
1124
642
|
}
|
|
1125
|
-
if (
|
|
643
|
+
if (cachePlan && cacheChunks && cacheChunks.length > 0) {
|
|
1126
644
|
const totalLength = cacheChunks.reduce((sum, chunk) => sum + chunk.length, 0);
|
|
1127
645
|
const combined = new Uint8Array(totalLength);
|
|
1128
646
|
let offset = 0;
|
|
@@ -1130,86 +648,16 @@ The request origin "${inputOrigin}" does not match the server origin "${origin}"
|
|
|
1130
648
|
combined.set(chunk, offset);
|
|
1131
649
|
offset += chunk.length;
|
|
1132
650
|
}
|
|
1133
|
-
|
|
651
|
+
const html = new TextDecoder().decode(combined);
|
|
652
|
+
const cachedETag = cachePlan.eTag || hash(html);
|
|
653
|
+
deps.setCachedSsr(cachePlan.key, {
|
|
654
|
+
eTag: cachedETag,
|
|
655
|
+
body: html
|
|
656
|
+
});
|
|
1134
657
|
}
|
|
1135
658
|
await writableStream.close();
|
|
1136
659
|
};
|
|
1137
660
|
}
|
|
1138
|
-
async function handleQDataRedirect(requestEv) {
|
|
1139
|
-
try {
|
|
1140
|
-
await requestEv.next();
|
|
1141
|
-
} catch (err) {
|
|
1142
|
-
if (!(err instanceof deps.RedirectMessage)) {
|
|
1143
|
-
throw err;
|
|
1144
|
-
}
|
|
1145
|
-
}
|
|
1146
|
-
if (requestEv.headersSent) {
|
|
1147
|
-
return;
|
|
1148
|
-
}
|
|
1149
|
-
const status = requestEv.status();
|
|
1150
|
-
const location = requestEv.headers.get("Location");
|
|
1151
|
-
const isRedirect = status >= 301 && status <= 308 && location;
|
|
1152
|
-
if (isRedirect) {
|
|
1153
|
-
const adaptedLocation = makeQDataPath(location);
|
|
1154
|
-
if (adaptedLocation) {
|
|
1155
|
-
requestEv.headers.set("Location", adaptedLocation);
|
|
1156
|
-
requestEv.getWritableStream().close();
|
|
1157
|
-
return;
|
|
1158
|
-
} else {
|
|
1159
|
-
requestEv.status(200);
|
|
1160
|
-
requestEv.headers.delete("Location");
|
|
1161
|
-
}
|
|
1162
|
-
}
|
|
1163
|
-
}
|
|
1164
|
-
async function renderQData(requestEv) {
|
|
1165
|
-
await requestEv.next();
|
|
1166
|
-
if (requestEv.headersSent || requestEv.exited) {
|
|
1167
|
-
return;
|
|
1168
|
-
}
|
|
1169
|
-
const status = requestEv.status();
|
|
1170
|
-
const redirectLocation = requestEv.headers.get("Location");
|
|
1171
|
-
requestEv.headers.set("Content-Type", "application/json; charset=utf-8");
|
|
1172
|
-
let loaders = deps.getRequestLoaders(requestEv);
|
|
1173
|
-
const selectedLoaderIds = requestEv.query.getAll(deps.QLOADER_KEY);
|
|
1174
|
-
const hasCustomLoaders = selectedLoaderIds.length > 0;
|
|
1175
|
-
if (hasCustomLoaders) {
|
|
1176
|
-
const selectedLoaders = {};
|
|
1177
|
-
for (const loaderId of selectedLoaderIds) {
|
|
1178
|
-
const loader = loaders[loaderId];
|
|
1179
|
-
selectedLoaders[loaderId] = loader;
|
|
1180
|
-
}
|
|
1181
|
-
loaders = selectedLoaders;
|
|
1182
|
-
}
|
|
1183
|
-
const qData = hasCustomLoaders ? {
|
|
1184
|
-
loaders,
|
|
1185
|
-
status: status !== 200 ? status : 200,
|
|
1186
|
-
href: getPathname(requestEv.url)
|
|
1187
|
-
} : {
|
|
1188
|
-
loaders,
|
|
1189
|
-
action: requestEv.sharedMap.get(deps.RequestEvSharedActionId),
|
|
1190
|
-
status: status !== 200 ? status : 200,
|
|
1191
|
-
href: getPathname(requestEv.url),
|
|
1192
|
-
redirect: redirectLocation ?? void 0,
|
|
1193
|
-
isRewrite: requestEv.sharedMap.get(deps.RequestEvIsRewrite)
|
|
1194
|
-
};
|
|
1195
|
-
const writer = requestEv.getWritableStream().getWriter();
|
|
1196
|
-
const data = await _serialize(qData);
|
|
1197
|
-
writer.write(deps.encoder.encode(data));
|
|
1198
|
-
requestEv.sharedMap.set(deps.RequestEvShareQData, qData);
|
|
1199
|
-
writer.close();
|
|
1200
|
-
}
|
|
1201
|
-
function makeQDataPath(href) {
|
|
1202
|
-
if (href.startsWith("/")) {
|
|
1203
|
-
if (!href.includes(deps.QDATA_JSON)) {
|
|
1204
|
-
const url = new URL(href, "http://localhost");
|
|
1205
|
-
const pathname = url.pathname.endsWith("/") ? url.pathname.slice(0, -1) : url.pathname;
|
|
1206
|
-
return pathname + deps.QDATA_JSON + url.search;
|
|
1207
|
-
}
|
|
1208
|
-
return href;
|
|
1209
|
-
} else {
|
|
1210
|
-
return void 0;
|
|
1211
|
-
}
|
|
1212
|
-
}
|
|
1213
661
|
function now() {
|
|
1214
662
|
return typeof performance !== "undefined" ? performance.now() : 0;
|
|
1215
663
|
}
|
|
@@ -1259,24 +707,11 @@ function isContentType(headers, ...types) {
|
|
|
1259
707
|
return false;
|
|
1260
708
|
}
|
|
1261
709
|
|
|
1262
|
-
class ServerError extends Error {
|
|
1263
|
-
status;
|
|
1264
|
-
data;
|
|
1265
|
-
constructor(status, data) {
|
|
1266
|
-
super(typeof data === "string" ? data : void 0), this.status = status, this.data = data;
|
|
1267
|
-
}
|
|
1268
|
-
}
|
|
1269
|
-
|
|
1270
710
|
const requestHandlers = createResolveRequestHandlers({
|
|
1271
711
|
QACTION_KEY,
|
|
1272
712
|
QFN_KEY,
|
|
1273
|
-
QLOADER_KEY,
|
|
1274
|
-
QDATA_JSON,
|
|
1275
|
-
IsQData,
|
|
1276
713
|
RequestEvETagCacheKey,
|
|
1277
714
|
RequestEvHttpStatusMessage,
|
|
1278
|
-
RequestEvIsRewrite,
|
|
1279
|
-
RequestEvShareQData,
|
|
1280
715
|
RequestEvShareServerTiming,
|
|
1281
716
|
RequestEvSharedActionId,
|
|
1282
717
|
RequestRouteName,
|
|
@@ -1285,31 +720,22 @@ const requestHandlers = createResolveRequestHandlers({
|
|
|
1285
720
|
HttpStatus,
|
|
1286
721
|
encoder,
|
|
1287
722
|
isContentType,
|
|
1288
|
-
|
|
723
|
+
defaultSsrCacheKey,
|
|
724
|
+
defaultLoaderCacheKey,
|
|
725
|
+
getCachedSsr,
|
|
726
|
+
getCachedLoader,
|
|
1289
727
|
getQwikRouterServerData,
|
|
1290
|
-
getRequestLoaderSerializationStrategyMap,
|
|
1291
|
-
getRequestLoaders,
|
|
1292
728
|
getRequestMode,
|
|
1293
|
-
getRouteLoaderPromise,
|
|
1294
729
|
loadHttpError: () => import('../../chunks/http-error.qwik.mjs'),
|
|
1295
730
|
MAX_CACHE_SIZE,
|
|
1296
731
|
resolveCacheKey,
|
|
1297
732
|
resolveETag,
|
|
1298
733
|
resolveRouteConfig,
|
|
1299
|
-
|
|
734
|
+
setCachedSsr,
|
|
735
|
+
setCachedLoader
|
|
1300
736
|
});
|
|
1301
737
|
const { renderQwikMiddleware, resolveRequestHandlers} = requestHandlers;
|
|
1302
738
|
|
|
1303
|
-
let _asyncRequestStore;
|
|
1304
|
-
if (isServer) {
|
|
1305
|
-
const AsyncLocalStorage = _getAsyncLocalStorage();
|
|
1306
|
-
if (AsyncLocalStorage) {
|
|
1307
|
-
_asyncRequestStore = new AsyncLocalStorage();
|
|
1308
|
-
} else {
|
|
1309
|
-
console.warn("\n=====================\n Qwik Router Warning:\n AsyncLocalStorage is not available, continuing without it.\n This impacts concurrent async server calls, where they lose access to the ServerRequestEv object.\n=====================\n\n");
|
|
1310
|
-
}
|
|
1311
|
-
}
|
|
1312
|
-
|
|
1313
739
|
function createCacheControl(cacheControl) {
|
|
1314
740
|
const controls = [];
|
|
1315
741
|
if (cacheControl === "day") {
|
|
@@ -1530,6 +956,7 @@ class RewriteMessage extends AbortMessage {
|
|
|
1530
956
|
|
|
1531
957
|
const requestEventDeps = {
|
|
1532
958
|
QDATA_KEY,
|
|
959
|
+
QACTION_KEY,
|
|
1533
960
|
isPromise,
|
|
1534
961
|
createCacheControl,
|
|
1535
962
|
Cookie,
|
|
@@ -1537,9 +964,12 @@ const requestEventDeps = {
|
|
|
1537
964
|
RedirectMessage,
|
|
1538
965
|
RewriteMessage,
|
|
1539
966
|
ServerError,
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
967
|
+
recognizeRequest,
|
|
968
|
+
trimRecognizedInternalPathname,
|
|
969
|
+
IsQLoader,
|
|
970
|
+
IsQAction,
|
|
971
|
+
QLoaderId,
|
|
972
|
+
QActionId,
|
|
1543
973
|
encoder,
|
|
1544
974
|
getContentType
|
|
1545
975
|
};
|
|
@@ -1590,7 +1020,7 @@ async function runNextWithDeps(requestEv, rebuildRouteInfo, resolve, deps) {
|
|
|
1590
1020
|
}
|
|
1591
1021
|
return e;
|
|
1592
1022
|
}
|
|
1593
|
-
if (!isDev) {
|
|
1023
|
+
if (!isDev$1) {
|
|
1594
1024
|
try {
|
|
1595
1025
|
if (!requestEv.headersSent) {
|
|
1596
1026
|
requestEv.headers.set("content-type", "text/html; charset=utf-8");
|
|
@@ -1651,10 +1081,21 @@ async function getConfig() {
|
|
|
1651
1081
|
}
|
|
1652
1082
|
return qwikRouterConfig;
|
|
1653
1083
|
}
|
|
1654
|
-
|
|
1084
|
+
function getRequestHandlerPathname(serverRequestEv) {
|
|
1085
|
+
const recognized = recognizeRequest(serverRequestEv.url.pathname);
|
|
1086
|
+
if (!recognized) {
|
|
1087
|
+
return serverRequestEv.url.pathname;
|
|
1088
|
+
}
|
|
1089
|
+
const loaderPathname = trimRecognizedInternalPathname(serverRequestEv.url.pathname, recognized);
|
|
1090
|
+
if (recognized.type !== IsQLoader) {
|
|
1091
|
+
return loaderPathname;
|
|
1092
|
+
}
|
|
1093
|
+
return resolveValidInternalFullPathname(loaderPathname, serverRequestEv.request.headers.get(FULLPATH_HEADER)) ?? loaderPathname;
|
|
1094
|
+
}
|
|
1095
|
+
async function loadRequestHandlers(qwikRouterConfig2, pathname, method, checkOrigin, renderFn) {
|
|
1655
1096
|
const { routes, serverPlugins, cacheModules } = qwikRouterConfig2;
|
|
1656
|
-
const loadedRoute = await loadRoute(routes, cacheModules, pathname
|
|
1657
|
-
const requestHandlers = resolveRequestHandlers(serverPlugins, loadedRoute, method, checkOrigin, renderQwikMiddleware(renderFn)
|
|
1097
|
+
const loadedRoute = await loadRoute(routes, cacheModules, pathname);
|
|
1098
|
+
const requestHandlers = resolveRequestHandlers(serverPlugins, loadedRoute, method, checkOrigin, renderQwikMiddleware(renderFn));
|
|
1658
1099
|
return {
|
|
1659
1100
|
loadedRoute,
|
|
1660
1101
|
requestHandlers
|
|
@@ -1663,17 +1104,17 @@ async function loadRequestHandlers(qwikRouterConfig2, pathname, method, checkOri
|
|
|
1663
1104
|
async function requestHandler(serverRequestEv, opts) {
|
|
1664
1105
|
const { render, checkOrigin } = opts;
|
|
1665
1106
|
const config = await getConfig();
|
|
1666
|
-
const
|
|
1107
|
+
const pathname = getRequestHandlerPathname(serverRequestEv);
|
|
1667
1108
|
if (pathname === "/.well-known" || pathname.startsWith("/.well-known/")) {
|
|
1668
1109
|
return null;
|
|
1669
1110
|
}
|
|
1670
|
-
const { loadedRoute, requestHandlers } = await loadRequestHandlers(config, pathname, serverRequestEv.request.method, checkOrigin ?? true, render
|
|
1111
|
+
const { loadedRoute, requestHandlers } = await loadRequestHandlers(config, pathname, serverRequestEv.request.method, checkOrigin ?? true, render);
|
|
1671
1112
|
if (config.fallthrough && loadedRoute.$notFound$) {
|
|
1672
1113
|
return null;
|
|
1673
1114
|
}
|
|
1674
1115
|
const rebuildRouteInfo = async (url) => {
|
|
1675
|
-
const
|
|
1676
|
-
return loadRequestHandlers(config,
|
|
1116
|
+
const cleanPathname = trimInternalPathname(url.pathname);
|
|
1117
|
+
return loadRequestHandlers(config, cleanPathname, serverRequestEv.request.method, checkOrigin ?? true, render);
|
|
1677
1118
|
};
|
|
1678
1119
|
return runQwikRouter(serverRequestEv, loadedRoute, requestHandlers, rebuildRouteInfo, config.basePathname);
|
|
1679
1120
|
}
|
|
@@ -1708,12 +1149,10 @@ function isStaticPath(method, url) {
|
|
|
1708
1149
|
if (staticPaths.has(p)) {
|
|
1709
1150
|
return true;
|
|
1710
1151
|
}
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
}
|
|
1716
|
-
if (staticPaths.has(pWithoutQdata)) {
|
|
1152
|
+
const loaderMatch = p.match(LOADER_REGEX);
|
|
1153
|
+
if (loaderMatch) {
|
|
1154
|
+
const pWithoutLoader = p.slice(0, p.length - loaderMatch[0].length);
|
|
1155
|
+
if (staticPaths.has(pWithoutLoader + "/") || staticPaths.has(pWithoutLoader)) {
|
|
1717
1156
|
return true;
|
|
1718
1157
|
}
|
|
1719
1158
|
}
|
|
@@ -1777,4 +1216,4 @@ class _TextEncoderStream_polyfill {
|
|
|
1777
1216
|
}
|
|
1778
1217
|
}
|
|
1779
1218
|
|
|
1780
|
-
export { AbortMessage, RedirectMessage,
|
|
1219
|
+
export { AbortMessage, RedirectMessage, RewriteMessage, ServerError, _TextEncoderStream_polyfill, _asyncRequestStore, getErrorHtml, getNotFound, isStaticPath, mergeHeadersCookies, requestHandler };
|