@qwik.dev/router 2.0.0-beta.35 → 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 +26 -23
- 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 -15
- package/lib/chunks/worker-thread.qwik.mjs +436 -425
- package/lib/index.d.ts +180 -13
- package/lib/index.qwik.mjs +640 -447
- 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 +198 -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,11 +93,12 @@ 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,
|
|
101
|
+
renderMode: deps.getRequestMode(requestEv),
|
|
606
102
|
locale: locale(),
|
|
607
103
|
nonce,
|
|
608
104
|
containerAttributes: {
|
|
@@ -615,12 +111,13 @@ function getQwikRouterServerDataWithDeps(deps, requestEv) {
|
|
|
615
111
|
...params
|
|
616
112
|
},
|
|
617
113
|
loadedRoute: deps.getRequestRoute(requestEv),
|
|
114
|
+
routeLoaderCtx,
|
|
115
|
+
loaderValues,
|
|
618
116
|
response: {
|
|
619
117
|
status: status(),
|
|
620
118
|
statusMessage: requestEv.sharedMap.get(deps.RequestEvHttpStatusMessage),
|
|
621
|
-
loaders,
|
|
622
|
-
loadersSerializationStrategy,
|
|
623
119
|
action,
|
|
120
|
+
actionResult,
|
|
624
121
|
formData
|
|
625
122
|
}
|
|
626
123
|
}
|
|
@@ -634,8 +131,7 @@ const responsePageDeps = {
|
|
|
634
131
|
RequestEvSharedActionId,
|
|
635
132
|
RequestEvSharedNonce,
|
|
636
133
|
RequestRouteName,
|
|
637
|
-
|
|
638
|
-
getRequestLoaderSerializationStrategyMap,
|
|
134
|
+
getRequestMode,
|
|
639
135
|
getRequestRoute
|
|
640
136
|
};
|
|
641
137
|
function getQwikRouterServerData(...args) {
|
|
@@ -643,22 +139,20 @@ function getQwikRouterServerData(...args) {
|
|
|
643
139
|
}
|
|
644
140
|
|
|
645
141
|
function createResolveRequestHandlers(deps) {
|
|
646
|
-
const resolveRequestHandlers = (serverPlugins, route, method, checkOrigin, renderHandler
|
|
142
|
+
const resolveRequestHandlers = (serverPlugins, route, method, checkOrigin, renderHandler) => {
|
|
647
143
|
const routeLoaders = [];
|
|
648
144
|
const routeActions = [];
|
|
649
145
|
const requestHandlers = [];
|
|
650
146
|
const isPageRoute = !!isLastModulePageRoute(route.$mods$);
|
|
651
|
-
if (isInternal) {
|
|
652
|
-
requestHandlers.push(handleQDataRedirect);
|
|
653
|
-
}
|
|
654
147
|
if (isPageRoute) {
|
|
148
|
+
requestHandlers.push(jsonRequestWrapper());
|
|
655
149
|
requestHandlers.push(serverErrorMiddleware(route, renderHandler));
|
|
656
150
|
}
|
|
657
151
|
if (serverPlugins) {
|
|
658
152
|
_resolveRequestHandlers(routeLoaders, routeActions, requestHandlers, serverPlugins, isPageRoute, method);
|
|
659
153
|
}
|
|
660
154
|
const routeModules = route.$mods$;
|
|
661
|
-
_resolveRequestHandlers(routeLoaders, routeActions, requestHandlers, routeModules, isPageRoute, method);
|
|
155
|
+
_resolveRequestHandlers(routeLoaders, routeActions, requestHandlers, routeModules, isPageRoute, method, isPageRoute);
|
|
662
156
|
const routeName = route.$routeName$;
|
|
663
157
|
if (checkOrigin && (method === "POST" || method === "PUT" || method === "PATCH" || method === "DELETE")) {
|
|
664
158
|
if (checkOrigin === "lax-proto") {
|
|
@@ -668,70 +162,32 @@ function createResolveRequestHandlers(deps) {
|
|
|
668
162
|
}
|
|
669
163
|
}
|
|
670
164
|
if (isPageRoute) {
|
|
165
|
+
requestHandlers.push(loaderHandler(routeLoaders, route.$loaderPaths$));
|
|
166
|
+
requestHandlers.push(actionHandler(routeActions));
|
|
671
167
|
if (method === "POST" || method === "GET") {
|
|
672
168
|
requestHandlers.push(runServerFunction);
|
|
673
169
|
}
|
|
674
170
|
if (!route.$notFound$) {
|
|
675
171
|
requestHandlers.push(fixTrailingSlash);
|
|
676
172
|
}
|
|
677
|
-
if (isInternal) {
|
|
678
|
-
requestHandlers.push(renderQData);
|
|
679
|
-
}
|
|
680
173
|
}
|
|
681
174
|
if (isPageRoute) {
|
|
682
175
|
requestHandlers.push((ev) => {
|
|
683
176
|
ev.sharedMap.set(deps.RequestRouteName, routeName);
|
|
684
177
|
});
|
|
685
178
|
requestHandlers.push(actionsMiddleware(routeActions));
|
|
686
|
-
requestHandlers.push(loadersMiddleware(routeLoaders));
|
|
179
|
+
requestHandlers.push(loadersMiddleware(routeLoaders, route));
|
|
687
180
|
requestHandlers.push(eTagMiddleware(route));
|
|
688
181
|
requestHandlers.push(renderHandler);
|
|
689
182
|
}
|
|
690
183
|
return requestHandlers;
|
|
691
184
|
};
|
|
692
|
-
|
|
693
|
-
for (
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
}
|
|
699
|
-
let methodReqHandler;
|
|
700
|
-
switch (method) {
|
|
701
|
-
case "GET": {
|
|
702
|
-
methodReqHandler = routeModule.onGet;
|
|
703
|
-
break;
|
|
704
|
-
}
|
|
705
|
-
case "POST": {
|
|
706
|
-
methodReqHandler = routeModule.onPost;
|
|
707
|
-
break;
|
|
708
|
-
}
|
|
709
|
-
case "PUT": {
|
|
710
|
-
methodReqHandler = routeModule.onPut;
|
|
711
|
-
break;
|
|
712
|
-
}
|
|
713
|
-
case "PATCH": {
|
|
714
|
-
methodReqHandler = routeModule.onPatch;
|
|
715
|
-
break;
|
|
716
|
-
}
|
|
717
|
-
case "DELETE": {
|
|
718
|
-
methodReqHandler = routeModule.onDelete;
|
|
719
|
-
break;
|
|
720
|
-
}
|
|
721
|
-
case "OPTIONS": {
|
|
722
|
-
methodReqHandler = routeModule.onOptions;
|
|
723
|
-
break;
|
|
724
|
-
}
|
|
725
|
-
case "HEAD": {
|
|
726
|
-
methodReqHandler = routeModule.onHead;
|
|
727
|
-
break;
|
|
728
|
-
}
|
|
729
|
-
}
|
|
730
|
-
if (typeof methodReqHandler === "function") {
|
|
731
|
-
requestHandlers.push(methodReqHandler);
|
|
732
|
-
} else if (Array.isArray(methodReqHandler)) {
|
|
733
|
-
requestHandlers.push(...methodReqHandler);
|
|
734
|
-
}
|
|
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);
|
|
735
191
|
if (collectActions) {
|
|
736
192
|
for (const module of Object.values(routeModule)) {
|
|
737
193
|
if (typeof module === "function") {
|
|
@@ -744,7 +200,73 @@ function createResolveRequestHandlers(deps) {
|
|
|
744
200
|
}
|
|
745
201
|
}
|
|
746
202
|
}
|
|
747
|
-
}
|
|
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
|
+
}
|
|
748
270
|
const checkBrand = (obj, brand) => {
|
|
749
271
|
return obj && typeof obj === "function" && obj.__brand === brand;
|
|
750
272
|
};
|
|
@@ -756,7 +278,6 @@ function createResolveRequestHandlers(deps) {
|
|
|
756
278
|
return;
|
|
757
279
|
}
|
|
758
280
|
const { method } = requestEv;
|
|
759
|
-
const loaders = deps.getRequestLoaders(requestEv);
|
|
760
281
|
if (isDev && method === "GET") {
|
|
761
282
|
if (requestEv.query.has(deps.QACTION_KEY)) {
|
|
762
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">');
|
|
@@ -774,66 +295,79 @@ function createResolveRequestHandlers(deps) {
|
|
|
774
295
|
throw new Error(`Expected request data for the action id ${selectedActionId} to be an object`);
|
|
775
296
|
}
|
|
776
297
|
const result = await runValidators(requestEv, action.__validators, data);
|
|
298
|
+
let actionResult;
|
|
777
299
|
if (!result.success) {
|
|
778
|
-
|
|
300
|
+
actionResult = requestEv.fail(result.status ?? 500, result.error);
|
|
779
301
|
} else {
|
|
780
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);
|
|
781
303
|
if (isDev) {
|
|
782
304
|
verifySerializable(actionResolved, action.__qrl);
|
|
783
305
|
}
|
|
784
|
-
|
|
306
|
+
actionResult = actionResolved;
|
|
785
307
|
}
|
|
308
|
+
requestEv.sharedMap.set("@actionResult", actionResult);
|
|
786
309
|
}
|
|
787
310
|
}
|
|
788
311
|
}
|
|
789
312
|
};
|
|
790
313
|
}
|
|
791
|
-
function loadersMiddleware(routeLoaders) {
|
|
314
|
+
function loadersMiddleware(routeLoaders, route) {
|
|
792
315
|
return async (requestEvent) => {
|
|
793
316
|
const requestEv = requestEvent;
|
|
794
317
|
if (requestEv.headersSent) {
|
|
795
318
|
requestEv.exit();
|
|
796
319
|
return;
|
|
797
320
|
}
|
|
798
|
-
const loaders = deps.getRequestLoaders(requestEv);
|
|
799
|
-
const loadersSerializationStrategy = deps.getRequestLoaderSerializationStrategyMap(requestEv);
|
|
800
321
|
if (routeLoaders.length > 0) {
|
|
801
|
-
|
|
802
|
-
|
|
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
|
+
}));
|
|
803
327
|
}
|
|
804
328
|
};
|
|
805
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
|
+
}
|
|
806
340
|
function eTagMiddleware(route) {
|
|
807
341
|
return (requestEv) => {
|
|
808
342
|
if (requestEv.headersSent) {
|
|
809
343
|
return;
|
|
810
344
|
}
|
|
811
|
-
if (requestEv.method !== "GET"
|
|
345
|
+
if (requestEv.method !== "GET") {
|
|
812
346
|
return;
|
|
813
347
|
}
|
|
814
348
|
const mods = route.$mods$;
|
|
815
|
-
const
|
|
349
|
+
const hasCachingConfig = mods.some((m) => {
|
|
816
350
|
if (!m) {
|
|
817
351
|
return false;
|
|
818
352
|
}
|
|
819
353
|
if (m.routeConfig) {
|
|
820
|
-
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;
|
|
821
355
|
}
|
|
822
|
-
return m.eTag !== void 0;
|
|
356
|
+
return m.eTag !== void 0 || m.cacheKey !== void 0;
|
|
823
357
|
});
|
|
824
|
-
if (!
|
|
358
|
+
if (!hasCachingConfig) {
|
|
825
359
|
return;
|
|
826
360
|
}
|
|
827
|
-
const
|
|
361
|
+
const loaderValues = getRouteLoaderValues(requestEv);
|
|
828
362
|
const getData = (loaderOrAction) => {
|
|
829
363
|
const id = loaderOrAction.__id;
|
|
830
|
-
if (loaderOrAction.__brand === "server_loader"
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
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];
|
|
835
369
|
}
|
|
836
|
-
return
|
|
370
|
+
return requestEv.sharedMap.get(deps.RequestEvSharedActionId) === id ? requestEv.sharedMap.get("@actionResult") : void 0;
|
|
837
371
|
};
|
|
838
372
|
const routeLocation = {
|
|
839
373
|
params: requestEv.params,
|
|
@@ -850,32 +384,36 @@ function createResolveRequestHandlers(deps) {
|
|
|
850
384
|
resolveValue: getData,
|
|
851
385
|
...routeLocation
|
|
852
386
|
};
|
|
853
|
-
const
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
}
|
|
857
|
-
requestEv.headers.set("ETag", eTag);
|
|
858
|
-
const ifNoneMatch = requestEv.request.headers.get("If-None-Match");
|
|
859
|
-
if (ifNoneMatch && (ifNoneMatch === eTag || ifNoneMatch === `W/${eTag}` || `W/${ifNoneMatch}` === eTag)) {
|
|
860
|
-
requestEv.status(304);
|
|
861
|
-
requestEv.send(304, "");
|
|
387
|
+
const resolvedETag = deps.resolveETag(config.eTag, headProps);
|
|
388
|
+
const normalizedETag = resolvedETag !== null ? normalizeETag(resolvedETag) : "";
|
|
389
|
+
if (normalizedETag && performETagMatch(requestEv, normalizedETag)) {
|
|
862
390
|
return;
|
|
863
391
|
}
|
|
864
392
|
if (deps.MAX_CACHE_SIZE <= 0) {
|
|
865
393
|
return;
|
|
866
394
|
}
|
|
867
|
-
const cacheKey = deps.resolveCacheKey(config.cacheKey,
|
|
395
|
+
const cacheKey = deps.resolveCacheKey(config.cacheKey, deps.defaultSsrCacheKey, requestEv, normalizedETag);
|
|
868
396
|
if (!cacheKey) {
|
|
869
397
|
return;
|
|
870
398
|
}
|
|
871
|
-
const
|
|
872
|
-
if (
|
|
399
|
+
const cached = deps.getCachedSsr(cacheKey);
|
|
400
|
+
if (cached) {
|
|
873
401
|
requestEv.headers.set("Content-Type", "text/html; charset=utf-8");
|
|
874
402
|
requestEv.headers.set("X-SSR-Cache", "HIT");
|
|
875
|
-
|
|
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);
|
|
876
411
|
return;
|
|
877
412
|
}
|
|
878
|
-
requestEv.sharedMap.set(deps.RequestEvETagCacheKey,
|
|
413
|
+
requestEv.sharedMap.set(deps.RequestEvETagCacheKey, {
|
|
414
|
+
key: cacheKey,
|
|
415
|
+
eTag: normalizedETag
|
|
416
|
+
});
|
|
879
417
|
};
|
|
880
418
|
}
|
|
881
419
|
function serverErrorMiddleware(route, renderHandler) {
|
|
@@ -886,9 +424,6 @@ function createResolveRequestHandlers(deps) {
|
|
|
886
424
|
if (!(e instanceof deps.ServerError) || requestEv.headersSent) {
|
|
887
425
|
throw e;
|
|
888
426
|
}
|
|
889
|
-
if (requestEv.sharedMap.has(deps.IsQData)) {
|
|
890
|
-
throw e;
|
|
891
|
-
}
|
|
892
427
|
const accept = requestEv.request.headers.get("Accept");
|
|
893
428
|
if (accept && !accept.includes("text/html")) {
|
|
894
429
|
throw e;
|
|
@@ -978,16 +513,15 @@ function createResolveRequestHandlers(deps) {
|
|
|
978
513
|
}
|
|
979
514
|
}
|
|
980
515
|
function fixTrailingSlash(ev) {
|
|
981
|
-
const { basePathname, originalUrl
|
|
516
|
+
const { basePathname, originalUrl } = ev;
|
|
982
517
|
const { pathname, search } = originalUrl;
|
|
983
|
-
const isQData = sharedMap.has(deps.IsQData);
|
|
984
518
|
if (!pathname.startsWith("/") || pathname.startsWith("//")) {
|
|
985
519
|
return;
|
|
986
520
|
}
|
|
987
|
-
if (
|
|
521
|
+
if (pathname !== basePathname && !pathname.endsWith(".html")) {
|
|
988
522
|
if (!globalThis.__NO_TRAILING_SLASH__) {
|
|
989
523
|
if (!pathname.endsWith("/")) {
|
|
990
|
-
throw ev.redirect(deps.HttpStatus.MovedPermanently, pathname +
|
|
524
|
+
throw ev.redirect(deps.HttpStatus.MovedPermanently, ensureSlash(pathname) + search);
|
|
991
525
|
}
|
|
992
526
|
} else {
|
|
993
527
|
if (pathname.endsWith("/")) {
|
|
@@ -1015,12 +549,9 @@ function createResolveRequestHandlers(deps) {
|
|
|
1015
549
|
}
|
|
1016
550
|
function getPathname(url) {
|
|
1017
551
|
url = new URL(url);
|
|
1018
|
-
if (url.pathname.endsWith(deps.QDATA_JSON)) {
|
|
1019
|
-
url.pathname = url.pathname.slice(0, -deps.QDATA_JSON.length);
|
|
1020
|
-
}
|
|
1021
552
|
if (!globalThis.__NO_TRAILING_SLASH__) {
|
|
1022
553
|
if (!url.pathname.endsWith("/")) {
|
|
1023
|
-
url.pathname
|
|
554
|
+
url.pathname = ensureSlash(url.pathname);
|
|
1024
555
|
}
|
|
1025
556
|
} else {
|
|
1026
557
|
if (url.pathname.endsWith("/")) {
|
|
@@ -1057,19 +588,16 @@ The request origin "${inputOrigin}" does not match the server origin "${origin}"
|
|
|
1057
588
|
if (requestEv.headersSent) {
|
|
1058
589
|
return;
|
|
1059
590
|
}
|
|
1060
|
-
if (requestEv.sharedMap.has(deps.IsQData)) {
|
|
1061
|
-
return;
|
|
1062
|
-
}
|
|
1063
591
|
const responseHeaders = requestEv.headers;
|
|
1064
592
|
if (!responseHeaders.has("Content-Type")) {
|
|
1065
593
|
responseHeaders.set("Content-Type", "text/html; charset=utf-8");
|
|
1066
594
|
}
|
|
1067
|
-
const
|
|
595
|
+
const cachePlan = requestEv.sharedMap.get(deps.RequestEvETagCacheKey);
|
|
1068
596
|
const { readable, writable } = new TextEncoderStream();
|
|
1069
597
|
const writableStream = requestEv.getWritableStream();
|
|
1070
598
|
let cacheChunks;
|
|
1071
599
|
let pipeSource = readable;
|
|
1072
|
-
if (
|
|
600
|
+
if (cachePlan) {
|
|
1073
601
|
cacheChunks = [];
|
|
1074
602
|
const capture = new TransformStream({
|
|
1075
603
|
transform(chunk, controller) {
|
|
@@ -1086,29 +614,24 @@ The request origin "${inputOrigin}" does not match the server origin "${origin}"
|
|
|
1086
614
|
pipeError = error;
|
|
1087
615
|
});
|
|
1088
616
|
const stream = writable.getWriter();
|
|
1089
|
-
const status = requestEv.status();
|
|
1090
617
|
try {
|
|
1091
618
|
const isStatic = deps.getRequestMode(requestEv) === "static";
|
|
1092
619
|
const serverData = deps.getQwikRouterServerData(requestEv);
|
|
1093
620
|
const result = await render({
|
|
1094
621
|
base: requestEv.basePathname + "build/",
|
|
1095
622
|
stream,
|
|
623
|
+
streaming: isStatic ? {
|
|
624
|
+
outOfOrder: false
|
|
625
|
+
} : void 0,
|
|
1096
626
|
serverData,
|
|
1097
627
|
containerAttributes: {
|
|
1098
628
|
["q:render"]: isStatic ? "static" : "",
|
|
1099
629
|
...serverData.containerAttributes
|
|
1100
630
|
}
|
|
1101
631
|
});
|
|
1102
|
-
const qData = {
|
|
1103
|
-
loaders: deps.getRequestLoaders(requestEv),
|
|
1104
|
-
action: requestEv.sharedMap.get(deps.RequestEvSharedActionId),
|
|
1105
|
-
status: status !== 200 ? status : 200,
|
|
1106
|
-
href: getPathname(requestEv.url)
|
|
1107
|
-
};
|
|
1108
632
|
if (typeof result.html === "string") {
|
|
1109
633
|
await stream.write(result.html);
|
|
1110
634
|
}
|
|
1111
|
-
requestEv.sharedMap.set(deps.RequestEvShareQData, qData);
|
|
1112
635
|
} finally {
|
|
1113
636
|
await stream.ready;
|
|
1114
637
|
await stream.close();
|
|
@@ -1117,7 +640,7 @@ The request origin "${inputOrigin}" does not match the server origin "${origin}"
|
|
|
1117
640
|
if (pipeError) {
|
|
1118
641
|
throw pipeError;
|
|
1119
642
|
}
|
|
1120
|
-
if (
|
|
643
|
+
if (cachePlan && cacheChunks && cacheChunks.length > 0) {
|
|
1121
644
|
const totalLength = cacheChunks.reduce((sum, chunk) => sum + chunk.length, 0);
|
|
1122
645
|
const combined = new Uint8Array(totalLength);
|
|
1123
646
|
let offset = 0;
|
|
@@ -1125,86 +648,16 @@ The request origin "${inputOrigin}" does not match the server origin "${origin}"
|
|
|
1125
648
|
combined.set(chunk, offset);
|
|
1126
649
|
offset += chunk.length;
|
|
1127
650
|
}
|
|
1128
|
-
|
|
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
|
+
});
|
|
1129
657
|
}
|
|
1130
658
|
await writableStream.close();
|
|
1131
659
|
};
|
|
1132
660
|
}
|
|
1133
|
-
async function handleQDataRedirect(requestEv) {
|
|
1134
|
-
try {
|
|
1135
|
-
await requestEv.next();
|
|
1136
|
-
} catch (err) {
|
|
1137
|
-
if (!(err instanceof deps.RedirectMessage)) {
|
|
1138
|
-
throw err;
|
|
1139
|
-
}
|
|
1140
|
-
}
|
|
1141
|
-
if (requestEv.headersSent) {
|
|
1142
|
-
return;
|
|
1143
|
-
}
|
|
1144
|
-
const status = requestEv.status();
|
|
1145
|
-
const location = requestEv.headers.get("Location");
|
|
1146
|
-
const isRedirect = status >= 301 && status <= 308 && location;
|
|
1147
|
-
if (isRedirect) {
|
|
1148
|
-
const adaptedLocation = makeQDataPath(location);
|
|
1149
|
-
if (adaptedLocation) {
|
|
1150
|
-
requestEv.headers.set("Location", adaptedLocation);
|
|
1151
|
-
requestEv.getWritableStream().close();
|
|
1152
|
-
return;
|
|
1153
|
-
} else {
|
|
1154
|
-
requestEv.status(200);
|
|
1155
|
-
requestEv.headers.delete("Location");
|
|
1156
|
-
}
|
|
1157
|
-
}
|
|
1158
|
-
}
|
|
1159
|
-
async function renderQData(requestEv) {
|
|
1160
|
-
await requestEv.next();
|
|
1161
|
-
if (requestEv.headersSent || requestEv.exited) {
|
|
1162
|
-
return;
|
|
1163
|
-
}
|
|
1164
|
-
const status = requestEv.status();
|
|
1165
|
-
const redirectLocation = requestEv.headers.get("Location");
|
|
1166
|
-
requestEv.headers.set("Content-Type", "application/json; charset=utf-8");
|
|
1167
|
-
let loaders = deps.getRequestLoaders(requestEv);
|
|
1168
|
-
const selectedLoaderIds = requestEv.query.getAll(deps.QLOADER_KEY);
|
|
1169
|
-
const hasCustomLoaders = selectedLoaderIds.length > 0;
|
|
1170
|
-
if (hasCustomLoaders) {
|
|
1171
|
-
const selectedLoaders = {};
|
|
1172
|
-
for (const loaderId of selectedLoaderIds) {
|
|
1173
|
-
const loader = loaders[loaderId];
|
|
1174
|
-
selectedLoaders[loaderId] = loader;
|
|
1175
|
-
}
|
|
1176
|
-
loaders = selectedLoaders;
|
|
1177
|
-
}
|
|
1178
|
-
const qData = hasCustomLoaders ? {
|
|
1179
|
-
loaders,
|
|
1180
|
-
status: status !== 200 ? status : 200,
|
|
1181
|
-
href: getPathname(requestEv.url)
|
|
1182
|
-
} : {
|
|
1183
|
-
loaders,
|
|
1184
|
-
action: requestEv.sharedMap.get(deps.RequestEvSharedActionId),
|
|
1185
|
-
status: status !== 200 ? status : 200,
|
|
1186
|
-
href: getPathname(requestEv.url),
|
|
1187
|
-
redirect: redirectLocation ?? void 0,
|
|
1188
|
-
isRewrite: requestEv.sharedMap.get(deps.RequestEvIsRewrite)
|
|
1189
|
-
};
|
|
1190
|
-
const writer = requestEv.getWritableStream().getWriter();
|
|
1191
|
-
const data = await _serialize(qData);
|
|
1192
|
-
writer.write(deps.encoder.encode(data));
|
|
1193
|
-
requestEv.sharedMap.set(deps.RequestEvShareQData, qData);
|
|
1194
|
-
writer.close();
|
|
1195
|
-
}
|
|
1196
|
-
function makeQDataPath(href) {
|
|
1197
|
-
if (href.startsWith("/")) {
|
|
1198
|
-
if (!href.includes(deps.QDATA_JSON)) {
|
|
1199
|
-
const url = new URL(href, "http://localhost");
|
|
1200
|
-
const pathname = url.pathname.endsWith("/") ? url.pathname.slice(0, -1) : url.pathname;
|
|
1201
|
-
return pathname + deps.QDATA_JSON + url.search;
|
|
1202
|
-
}
|
|
1203
|
-
return href;
|
|
1204
|
-
} else {
|
|
1205
|
-
return void 0;
|
|
1206
|
-
}
|
|
1207
|
-
}
|
|
1208
661
|
function now() {
|
|
1209
662
|
return typeof performance !== "undefined" ? performance.now() : 0;
|
|
1210
663
|
}
|
|
@@ -1254,24 +707,11 @@ function isContentType(headers, ...types) {
|
|
|
1254
707
|
return false;
|
|
1255
708
|
}
|
|
1256
709
|
|
|
1257
|
-
class ServerError extends Error {
|
|
1258
|
-
status;
|
|
1259
|
-
data;
|
|
1260
|
-
constructor(status, data) {
|
|
1261
|
-
super(typeof data === "string" ? data : void 0), this.status = status, this.data = data;
|
|
1262
|
-
}
|
|
1263
|
-
}
|
|
1264
|
-
|
|
1265
710
|
const requestHandlers = createResolveRequestHandlers({
|
|
1266
711
|
QACTION_KEY,
|
|
1267
712
|
QFN_KEY,
|
|
1268
|
-
QLOADER_KEY,
|
|
1269
|
-
QDATA_JSON,
|
|
1270
|
-
IsQData,
|
|
1271
713
|
RequestEvETagCacheKey,
|
|
1272
714
|
RequestEvHttpStatusMessage,
|
|
1273
|
-
RequestEvIsRewrite,
|
|
1274
|
-
RequestEvShareQData,
|
|
1275
715
|
RequestEvShareServerTiming,
|
|
1276
716
|
RequestEvSharedActionId,
|
|
1277
717
|
RequestRouteName,
|
|
@@ -1280,31 +720,22 @@ const requestHandlers = createResolveRequestHandlers({
|
|
|
1280
720
|
HttpStatus,
|
|
1281
721
|
encoder,
|
|
1282
722
|
isContentType,
|
|
1283
|
-
|
|
723
|
+
defaultSsrCacheKey,
|
|
724
|
+
defaultLoaderCacheKey,
|
|
725
|
+
getCachedSsr,
|
|
726
|
+
getCachedLoader,
|
|
1284
727
|
getQwikRouterServerData,
|
|
1285
|
-
getRequestLoaderSerializationStrategyMap,
|
|
1286
|
-
getRequestLoaders,
|
|
1287
728
|
getRequestMode,
|
|
1288
|
-
getRouteLoaderPromise,
|
|
1289
729
|
loadHttpError: () => import('../../chunks/http-error.qwik.mjs'),
|
|
1290
730
|
MAX_CACHE_SIZE,
|
|
1291
731
|
resolveCacheKey,
|
|
1292
732
|
resolveETag,
|
|
1293
733
|
resolveRouteConfig,
|
|
1294
|
-
|
|
734
|
+
setCachedSsr,
|
|
735
|
+
setCachedLoader
|
|
1295
736
|
});
|
|
1296
737
|
const { renderQwikMiddleware, resolveRequestHandlers} = requestHandlers;
|
|
1297
738
|
|
|
1298
|
-
let _asyncRequestStore;
|
|
1299
|
-
if (isServer) {
|
|
1300
|
-
const AsyncLocalStorage = _getAsyncLocalStorage();
|
|
1301
|
-
if (AsyncLocalStorage) {
|
|
1302
|
-
_asyncRequestStore = new AsyncLocalStorage();
|
|
1303
|
-
} else {
|
|
1304
|
-
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");
|
|
1305
|
-
}
|
|
1306
|
-
}
|
|
1307
|
-
|
|
1308
739
|
function createCacheControl(cacheControl) {
|
|
1309
740
|
const controls = [];
|
|
1310
741
|
if (cacheControl === "day") {
|
|
@@ -1525,6 +956,7 @@ class RewriteMessage extends AbortMessage {
|
|
|
1525
956
|
|
|
1526
957
|
const requestEventDeps = {
|
|
1527
958
|
QDATA_KEY,
|
|
959
|
+
QACTION_KEY,
|
|
1528
960
|
isPromise,
|
|
1529
961
|
createCacheControl,
|
|
1530
962
|
Cookie,
|
|
@@ -1532,9 +964,12 @@ const requestEventDeps = {
|
|
|
1532
964
|
RedirectMessage,
|
|
1533
965
|
RewriteMessage,
|
|
1534
966
|
ServerError,
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
967
|
+
recognizeRequest,
|
|
968
|
+
trimRecognizedInternalPathname,
|
|
969
|
+
IsQLoader,
|
|
970
|
+
IsQAction,
|
|
971
|
+
QLoaderId,
|
|
972
|
+
QActionId,
|
|
1538
973
|
encoder,
|
|
1539
974
|
getContentType
|
|
1540
975
|
};
|
|
@@ -1585,7 +1020,7 @@ async function runNextWithDeps(requestEv, rebuildRouteInfo, resolve, deps) {
|
|
|
1585
1020
|
}
|
|
1586
1021
|
return e;
|
|
1587
1022
|
}
|
|
1588
|
-
if (!isDev) {
|
|
1023
|
+
if (!isDev$1) {
|
|
1589
1024
|
try {
|
|
1590
1025
|
if (!requestEv.headersSent) {
|
|
1591
1026
|
requestEv.headers.set("content-type", "text/html; charset=utf-8");
|
|
@@ -1646,10 +1081,21 @@ async function getConfig() {
|
|
|
1646
1081
|
}
|
|
1647
1082
|
return qwikRouterConfig;
|
|
1648
1083
|
}
|
|
1649
|
-
|
|
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) {
|
|
1650
1096
|
const { routes, serverPlugins, cacheModules } = qwikRouterConfig2;
|
|
1651
|
-
const loadedRoute = await loadRoute(routes, cacheModules, pathname
|
|
1652
|
-
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));
|
|
1653
1099
|
return {
|
|
1654
1100
|
loadedRoute,
|
|
1655
1101
|
requestHandlers
|
|
@@ -1658,17 +1104,17 @@ async function loadRequestHandlers(qwikRouterConfig2, pathname, method, checkOri
|
|
|
1658
1104
|
async function requestHandler(serverRequestEv, opts) {
|
|
1659
1105
|
const { render, checkOrigin } = opts;
|
|
1660
1106
|
const config = await getConfig();
|
|
1661
|
-
const
|
|
1107
|
+
const pathname = getRequestHandlerPathname(serverRequestEv);
|
|
1662
1108
|
if (pathname === "/.well-known" || pathname.startsWith("/.well-known/")) {
|
|
1663
1109
|
return null;
|
|
1664
1110
|
}
|
|
1665
|
-
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);
|
|
1666
1112
|
if (config.fallthrough && loadedRoute.$notFound$) {
|
|
1667
1113
|
return null;
|
|
1668
1114
|
}
|
|
1669
1115
|
const rebuildRouteInfo = async (url) => {
|
|
1670
|
-
const
|
|
1671
|
-
return loadRequestHandlers(config,
|
|
1116
|
+
const cleanPathname = trimInternalPathname(url.pathname);
|
|
1117
|
+
return loadRequestHandlers(config, cleanPathname, serverRequestEv.request.method, checkOrigin ?? true, render);
|
|
1672
1118
|
};
|
|
1673
1119
|
return runQwikRouter(serverRequestEv, loadedRoute, requestHandlers, rebuildRouteInfo, config.basePathname);
|
|
1674
1120
|
}
|
|
@@ -1703,12 +1149,10 @@ function isStaticPath(method, url) {
|
|
|
1703
1149
|
if (staticPaths.has(p)) {
|
|
1704
1150
|
return true;
|
|
1705
1151
|
}
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
}
|
|
1711
|
-
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)) {
|
|
1712
1156
|
return true;
|
|
1713
1157
|
}
|
|
1714
1158
|
}
|
|
@@ -1772,4 +1216,4 @@ class _TextEncoderStream_polyfill {
|
|
|
1772
1216
|
}
|
|
1773
1217
|
}
|
|
1774
1218
|
|
|
1775
|
-
export { AbortMessage, RedirectMessage,
|
|
1219
|
+
export { AbortMessage, RedirectMessage, RewriteMessage, ServerError, _TextEncoderStream_polyfill, _asyncRequestStore, getErrorHtml, getNotFound, isStaticPath, mergeHeadersCookies, requestHandler };
|