@qwik.dev/router 2.0.0-beta.36 → 2.0.0-beta.38
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 +3 -5
- package/lib/adapters/shared/vite/index.d.ts +3 -4
- package/lib/adapters/shared/vite/index.mjs +167 -155
- package/lib/chunks/dev-preloaded-route-loader.mjs +3 -0
- package/lib/chunks/format.mjs +31 -0
- package/lib/chunks/fs.mjs +10 -8
- package/lib/chunks/head.qwik.mjs +1425 -0
- package/lib/chunks/http-error.qwik.mjs +2 -2
- package/lib/chunks/pathname.mjs +3 -32
- package/lib/chunks/request-body-limit.mjs +37 -0
- package/lib/chunks/request-path.mjs +60 -0
- package/lib/chunks/routes.mjs +47 -0
- package/lib/chunks/server-error.mjs +19 -0
- package/lib/chunks/system.mjs +8 -8
- package/lib/chunks/use-functions.qwik.mjs +3 -12
- package/lib/chunks/user-response.mjs +1875 -0
- package/lib/chunks/worker-thread.mjs +317 -0
- package/lib/index.d.ts +251 -44
- package/lib/index.qwik.mjs +734 -485
- package/lib/middleware/aws-lambda/index.mjs +2 -1
- package/lib/middleware/azure-swa/index.mjs +13 -9
- package/lib/middleware/cloudflare-pages/index.mjs +2 -2
- package/lib/middleware/deno/index.d.ts +2 -0
- package/lib/middleware/deno/index.mjs +2 -1
- package/lib/middleware/netlify-edge/index.mjs +2 -2
- package/lib/middleware/node/index.d.ts +9 -1
- package/lib/middleware/node/index.mjs +28 -3
- package/lib/middleware/request-handler/index.d.ts +65 -26
- package/lib/middleware/request-handler/index.mjs +38 -1679
- package/lib/middleware/vercel-edge/index.mjs +2 -2
- package/lib/ssg/index.d.ts +5 -13
- package/lib/ssg/index.mjs +14 -53
- package/lib/vite/index.d.ts +23 -0
- package/lib/vite/index.mjs +533 -122
- package/package.json +4 -3
- package/lib/chunks/deepFreeze.qwik.mjs +0 -18
- package/lib/chunks/error-handler.mjs +0 -57
- package/lib/chunks/not-found-wrapper.qwik.mjs +0 -25
- package/lib/chunks/redirect-handler.mjs +0 -6
- package/lib/chunks/routing.qwik.mjs +0 -821
- package/lib/chunks/worker-thread.qwik.mjs +0 -2585
|
@@ -1,1660 +1,44 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
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
|
-
var HttpStatus = /* @__PURE__ */ (function(HttpStatus2) {
|
|
72
|
-
HttpStatus2[HttpStatus2["Continue"] = 100] = "Continue";
|
|
73
|
-
HttpStatus2[HttpStatus2["SwitchingProtocols"] = 101] = "SwitchingProtocols";
|
|
74
|
-
HttpStatus2[HttpStatus2["Processing"] = 102] = "Processing";
|
|
75
|
-
HttpStatus2[HttpStatus2["Ok"] = 200] = "Ok";
|
|
76
|
-
HttpStatus2[HttpStatus2["Created"] = 201] = "Created";
|
|
77
|
-
HttpStatus2[HttpStatus2["Accepted"] = 202] = "Accepted";
|
|
78
|
-
HttpStatus2[HttpStatus2["NonAuthoritativeInformation"] = 203] = "NonAuthoritativeInformation";
|
|
79
|
-
HttpStatus2[HttpStatus2["NoContent"] = 204] = "NoContent";
|
|
80
|
-
HttpStatus2[HttpStatus2["ResetContent"] = 205] = "ResetContent";
|
|
81
|
-
HttpStatus2[HttpStatus2["PartialContent"] = 206] = "PartialContent";
|
|
82
|
-
HttpStatus2[HttpStatus2["MultiStatus"] = 207] = "MultiStatus";
|
|
83
|
-
HttpStatus2[HttpStatus2["AlreadyReported"] = 208] = "AlreadyReported";
|
|
84
|
-
HttpStatus2[HttpStatus2["ImUsed"] = 226] = "ImUsed";
|
|
85
|
-
HttpStatus2[HttpStatus2["MultipleChoices"] = 300] = "MultipleChoices";
|
|
86
|
-
HttpStatus2[HttpStatus2["MovedPermanently"] = 301] = "MovedPermanently";
|
|
87
|
-
HttpStatus2[HttpStatus2["Found"] = 302] = "Found";
|
|
88
|
-
HttpStatus2[HttpStatus2["SeeOther"] = 303] = "SeeOther";
|
|
89
|
-
HttpStatus2[HttpStatus2["NotModified"] = 304] = "NotModified";
|
|
90
|
-
HttpStatus2[HttpStatus2["UseProxy"] = 305] = "UseProxy";
|
|
91
|
-
HttpStatus2[HttpStatus2["SwitchProxy"] = 306] = "SwitchProxy";
|
|
92
|
-
HttpStatus2[HttpStatus2["TemporaryRedirect"] = 307] = "TemporaryRedirect";
|
|
93
|
-
HttpStatus2[HttpStatus2["PermanentRedirect"] = 308] = "PermanentRedirect";
|
|
94
|
-
HttpStatus2[HttpStatus2["BadRequest"] = 400] = "BadRequest";
|
|
95
|
-
HttpStatus2[HttpStatus2["Unauthorized"] = 401] = "Unauthorized";
|
|
96
|
-
HttpStatus2[HttpStatus2["PaymentRequired"] = 402] = "PaymentRequired";
|
|
97
|
-
HttpStatus2[HttpStatus2["Forbidden"] = 403] = "Forbidden";
|
|
98
|
-
HttpStatus2[HttpStatus2["NotFound"] = 404] = "NotFound";
|
|
99
|
-
HttpStatus2[HttpStatus2["MethodNotAllowed"] = 405] = "MethodNotAllowed";
|
|
100
|
-
HttpStatus2[HttpStatus2["NotAcceptable"] = 406] = "NotAcceptable";
|
|
101
|
-
HttpStatus2[HttpStatus2["ProxyAuthenticationRequired"] = 407] = "ProxyAuthenticationRequired";
|
|
102
|
-
HttpStatus2[HttpStatus2["RequestTimeout"] = 408] = "RequestTimeout";
|
|
103
|
-
HttpStatus2[HttpStatus2["Conflict"] = 409] = "Conflict";
|
|
104
|
-
HttpStatus2[HttpStatus2["Gone"] = 410] = "Gone";
|
|
105
|
-
HttpStatus2[HttpStatus2["LengthRequired"] = 411] = "LengthRequired";
|
|
106
|
-
HttpStatus2[HttpStatus2["PreconditionFailed"] = 412] = "PreconditionFailed";
|
|
107
|
-
HttpStatus2[HttpStatus2["PayloadTooLarge"] = 413] = "PayloadTooLarge";
|
|
108
|
-
HttpStatus2[HttpStatus2["UriTooLong"] = 414] = "UriTooLong";
|
|
109
|
-
HttpStatus2[HttpStatus2["UnsupportedMediaType"] = 415] = "UnsupportedMediaType";
|
|
110
|
-
HttpStatus2[HttpStatus2["RangeNotSatisfiable"] = 416] = "RangeNotSatisfiable";
|
|
111
|
-
HttpStatus2[HttpStatus2["ExpectationFailed"] = 417] = "ExpectationFailed";
|
|
112
|
-
HttpStatus2[HttpStatus2["IAmATeapot"] = 418] = "IAmATeapot";
|
|
113
|
-
HttpStatus2[HttpStatus2["MisdirectedRequest"] = 421] = "MisdirectedRequest";
|
|
114
|
-
HttpStatus2[HttpStatus2["UnprocessableEntity"] = 422] = "UnprocessableEntity";
|
|
115
|
-
HttpStatus2[HttpStatus2["Locked"] = 423] = "Locked";
|
|
116
|
-
HttpStatus2[HttpStatus2["FailedDependency"] = 424] = "FailedDependency";
|
|
117
|
-
HttpStatus2[HttpStatus2["UpgradeRequired"] = 426] = "UpgradeRequired";
|
|
118
|
-
HttpStatus2[HttpStatus2["PreconditionRequired"] = 428] = "PreconditionRequired";
|
|
119
|
-
HttpStatus2[HttpStatus2["TooManyRequests"] = 429] = "TooManyRequests";
|
|
120
|
-
HttpStatus2[HttpStatus2["RequestHeaderFieldsTooLarge"] = 431] = "RequestHeaderFieldsTooLarge";
|
|
121
|
-
HttpStatus2[HttpStatus2["UnavailableForLegalReasons"] = 451] = "UnavailableForLegalReasons";
|
|
122
|
-
HttpStatus2[HttpStatus2["InternalServerError"] = 500] = "InternalServerError";
|
|
123
|
-
HttpStatus2[HttpStatus2["NotImplemented"] = 501] = "NotImplemented";
|
|
124
|
-
HttpStatus2[HttpStatus2["BadGateway"] = 502] = "BadGateway";
|
|
125
|
-
HttpStatus2[HttpStatus2["ServiceUnavailable"] = 503] = "ServiceUnavailable";
|
|
126
|
-
HttpStatus2[HttpStatus2["GatewayTimeout"] = 504] = "GatewayTimeout";
|
|
127
|
-
HttpStatus2[HttpStatus2["HttpVersionNotSupported"] = 505] = "HttpVersionNotSupported";
|
|
128
|
-
HttpStatus2[HttpStatus2["VariantAlsoNegotiates"] = 506] = "VariantAlsoNegotiates";
|
|
129
|
-
HttpStatus2[HttpStatus2["InsufficientStorage"] = 507] = "InsufficientStorage";
|
|
130
|
-
HttpStatus2[HttpStatus2["LoopDetected"] = 508] = "LoopDetected";
|
|
131
|
-
HttpStatus2[HttpStatus2["NotExtended"] = 510] = "NotExtended";
|
|
132
|
-
HttpStatus2[HttpStatus2["NetworkAuthenticationRequired"] = 511] = "NetworkAuthenticationRequired";
|
|
133
|
-
return HttpStatus2;
|
|
134
|
-
})({});
|
|
135
|
-
|
|
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
|
-
function getQwikRouterServerDataWithDeps(deps, requestEv) {
|
|
583
|
-
const { params, request, status, locale, originalUrl } = requestEv;
|
|
584
|
-
const requestHeaders = {};
|
|
585
|
-
request.headers.forEach((value, key) => requestHeaders[key] = value);
|
|
586
|
-
const action = requestEv.sharedMap.get(deps.RequestEvSharedActionId);
|
|
587
|
-
const formData = requestEv.sharedMap.get(deps.RequestEvSharedActionFormData);
|
|
588
|
-
const routeName = requestEv.sharedMap.get(deps.RequestRouteName);
|
|
589
|
-
const nonce = requestEv.sharedMap.get(deps.RequestEvSharedNonce);
|
|
590
|
-
const headers = requestEv.request.headers;
|
|
591
|
-
const reconstructedUrl = new URL(originalUrl.pathname + originalUrl.search, originalUrl);
|
|
592
|
-
const host = headers.get("X-Forwarded-Host");
|
|
593
|
-
const protocol = headers.get("X-Forwarded-Proto");
|
|
594
|
-
if (host) {
|
|
595
|
-
reconstructedUrl.port = "";
|
|
596
|
-
reconstructedUrl.host = host;
|
|
597
|
-
}
|
|
598
|
-
if (protocol) {
|
|
599
|
-
reconstructedUrl.protocol = protocol;
|
|
600
|
-
}
|
|
601
|
-
const loaders = deps.getRequestLoaders(requestEv);
|
|
602
|
-
const loadersSerializationStrategy = deps.getRequestLoaderSerializationStrategyMap(requestEv);
|
|
603
|
-
return {
|
|
604
|
-
url: reconstructedUrl.href,
|
|
605
|
-
requestHeaders,
|
|
606
|
-
renderMode: deps.getRequestMode(requestEv),
|
|
607
|
-
locale: locale(),
|
|
608
|
-
nonce,
|
|
609
|
-
containerAttributes: {
|
|
610
|
-
[deps.Q_ROUTE]: routeName
|
|
611
|
-
},
|
|
612
|
-
qwikrouter: {
|
|
613
|
-
routeName,
|
|
614
|
-
ev: requestEv,
|
|
615
|
-
params: {
|
|
616
|
-
...params
|
|
617
|
-
},
|
|
618
|
-
loadedRoute: deps.getRequestRoute(requestEv),
|
|
619
|
-
response: {
|
|
620
|
-
status: status(),
|
|
621
|
-
statusMessage: requestEv.sharedMap.get(deps.RequestEvHttpStatusMessage),
|
|
622
|
-
loaders,
|
|
623
|
-
loadersSerializationStrategy,
|
|
624
|
-
action,
|
|
625
|
-
formData
|
|
626
|
-
}
|
|
627
|
-
}
|
|
628
|
-
};
|
|
629
|
-
}
|
|
630
|
-
|
|
631
|
-
const responsePageDeps = {
|
|
632
|
-
Q_ROUTE,
|
|
633
|
-
RequestEvHttpStatusMessage,
|
|
634
|
-
RequestEvSharedActionFormData,
|
|
635
|
-
RequestEvSharedActionId,
|
|
636
|
-
RequestEvSharedNonce,
|
|
637
|
-
RequestRouteName,
|
|
638
|
-
getRequestLoaders,
|
|
639
|
-
getRequestLoaderSerializationStrategyMap,
|
|
640
|
-
getRequestMode,
|
|
641
|
-
getRequestRoute
|
|
642
|
-
};
|
|
643
|
-
function getQwikRouterServerData(...args) {
|
|
644
|
-
return getQwikRouterServerDataWithDeps(responsePageDeps, ...args);
|
|
645
|
-
}
|
|
646
|
-
|
|
647
|
-
function createResolveRequestHandlers(deps) {
|
|
648
|
-
const resolveRequestHandlers = (serverPlugins, route, method, checkOrigin, renderHandler, isInternal) => {
|
|
649
|
-
const routeLoaders = [];
|
|
650
|
-
const routeActions = [];
|
|
651
|
-
const requestHandlers = [];
|
|
652
|
-
const isPageRoute = !!isLastModulePageRoute(route.$mods$);
|
|
653
|
-
if (isInternal) {
|
|
654
|
-
requestHandlers.push(handleQDataRedirect);
|
|
655
|
-
}
|
|
656
|
-
if (isPageRoute) {
|
|
657
|
-
requestHandlers.push(serverErrorMiddleware(route, renderHandler));
|
|
658
|
-
}
|
|
659
|
-
if (serverPlugins) {
|
|
660
|
-
_resolveRequestHandlers(routeLoaders, routeActions, requestHandlers, serverPlugins, isPageRoute, method);
|
|
661
|
-
}
|
|
662
|
-
const routeModules = route.$mods$;
|
|
663
|
-
_resolveRequestHandlers(routeLoaders, routeActions, requestHandlers, routeModules, isPageRoute, method);
|
|
664
|
-
const routeName = route.$routeName$;
|
|
665
|
-
if (checkOrigin && (method === "POST" || method === "PUT" || method === "PATCH" || method === "DELETE")) {
|
|
666
|
-
if (checkOrigin === "lax-proto") {
|
|
667
|
-
requestHandlers.unshift(csrfLaxProtoCheckMiddleware);
|
|
668
|
-
} else {
|
|
669
|
-
requestHandlers.unshift(csrfCheckMiddleware);
|
|
670
|
-
}
|
|
671
|
-
}
|
|
672
|
-
if (isPageRoute) {
|
|
673
|
-
if (method === "POST" || method === "GET") {
|
|
674
|
-
requestHandlers.push(runServerFunction);
|
|
675
|
-
}
|
|
676
|
-
if (!route.$notFound$) {
|
|
677
|
-
requestHandlers.push(fixTrailingSlash);
|
|
678
|
-
}
|
|
679
|
-
if (isInternal) {
|
|
680
|
-
requestHandlers.push(renderQData);
|
|
681
|
-
}
|
|
682
|
-
}
|
|
683
|
-
if (isPageRoute) {
|
|
684
|
-
requestHandlers.push((ev) => {
|
|
685
|
-
ev.sharedMap.set(deps.RequestRouteName, routeName);
|
|
686
|
-
});
|
|
687
|
-
requestHandlers.push(actionsMiddleware(routeActions));
|
|
688
|
-
requestHandlers.push(loadersMiddleware(routeLoaders));
|
|
689
|
-
requestHandlers.push(eTagMiddleware(route));
|
|
690
|
-
requestHandlers.push(renderHandler);
|
|
691
|
-
}
|
|
692
|
-
return requestHandlers;
|
|
693
|
-
};
|
|
694
|
-
const _resolveRequestHandlers = (routeLoaders, routeActions, requestHandlers, routeModules, collectActions, method) => {
|
|
695
|
-
for (const routeModule of routeModules) {
|
|
696
|
-
if (typeof routeModule.onRequest === "function") {
|
|
697
|
-
requestHandlers.push(routeModule.onRequest);
|
|
698
|
-
} else if (Array.isArray(routeModule.onRequest)) {
|
|
699
|
-
requestHandlers.push(...routeModule.onRequest);
|
|
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
|
-
}
|
|
737
|
-
if (collectActions) {
|
|
738
|
-
for (const module of Object.values(routeModule)) {
|
|
739
|
-
if (typeof module === "function") {
|
|
740
|
-
if (module.__brand === "server_loader") {
|
|
741
|
-
routeLoaders.push(module);
|
|
742
|
-
} else if (module.__brand === "server_action") {
|
|
743
|
-
routeActions.push(module);
|
|
744
|
-
}
|
|
745
|
-
}
|
|
746
|
-
}
|
|
747
|
-
}
|
|
748
|
-
}
|
|
749
|
-
};
|
|
750
|
-
const checkBrand = (obj, brand) => {
|
|
751
|
-
return obj && typeof obj === "function" && obj.__brand === brand;
|
|
752
|
-
};
|
|
753
|
-
function actionsMiddleware(routeActions) {
|
|
754
|
-
return async (requestEvent) => {
|
|
755
|
-
const requestEv = requestEvent;
|
|
756
|
-
if (requestEv.headersSent) {
|
|
757
|
-
requestEv.exit();
|
|
758
|
-
return;
|
|
759
|
-
}
|
|
760
|
-
const { method } = requestEv;
|
|
761
|
-
const loaders = deps.getRequestLoaders(requestEv);
|
|
762
|
-
if (isDev && method === "GET") {
|
|
763
|
-
if (requestEv.query.has(deps.QACTION_KEY)) {
|
|
764
|
-
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">');
|
|
765
|
-
}
|
|
766
|
-
}
|
|
767
|
-
if (method === "POST") {
|
|
768
|
-
const selectedActionId = requestEv.query.get(deps.QACTION_KEY);
|
|
769
|
-
if (selectedActionId) {
|
|
770
|
-
const serverActionsMap = globalThis._qwikActionsMap;
|
|
771
|
-
const action = routeActions.find((action2) => action2.__id === selectedActionId) ?? serverActionsMap?.get(selectedActionId);
|
|
772
|
-
if (action) {
|
|
773
|
-
requestEv.sharedMap.set(deps.RequestEvSharedActionId, selectedActionId);
|
|
774
|
-
const data = await requestEv.parseBody();
|
|
775
|
-
if (!data || typeof data !== "object") {
|
|
776
|
-
throw new Error(`Expected request data for the action id ${selectedActionId} to be an object`);
|
|
777
|
-
}
|
|
778
|
-
const result = await runValidators(requestEv, action.__validators, data);
|
|
779
|
-
if (!result.success) {
|
|
780
|
-
loaders[selectedActionId] = requestEv.fail(result.status ?? 500, result.error);
|
|
781
|
-
} else {
|
|
782
|
-
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
|
-
if (isDev) {
|
|
784
|
-
verifySerializable(actionResolved, action.__qrl);
|
|
785
|
-
}
|
|
786
|
-
loaders[selectedActionId] = actionResolved;
|
|
787
|
-
}
|
|
788
|
-
}
|
|
789
|
-
}
|
|
790
|
-
}
|
|
791
|
-
};
|
|
792
|
-
}
|
|
793
|
-
function loadersMiddleware(routeLoaders) {
|
|
794
|
-
return async (requestEvent) => {
|
|
795
|
-
const requestEv = requestEvent;
|
|
796
|
-
if (requestEv.headersSent) {
|
|
797
|
-
requestEv.exit();
|
|
798
|
-
return;
|
|
799
|
-
}
|
|
800
|
-
const loaders = deps.getRequestLoaders(requestEv);
|
|
801
|
-
const loadersSerializationStrategy = deps.getRequestLoaderSerializationStrategyMap(requestEv);
|
|
802
|
-
if (routeLoaders.length > 0) {
|
|
803
|
-
const resolvedLoadersPromises = routeLoaders.map((loader) => deps.getRouteLoaderPromise(loader, loaders, loadersSerializationStrategy, requestEv));
|
|
804
|
-
await Promise.all(resolvedLoadersPromises);
|
|
805
|
-
}
|
|
806
|
-
};
|
|
807
|
-
}
|
|
808
|
-
function eTagMiddleware(route) {
|
|
809
|
-
return (requestEv) => {
|
|
810
|
-
if (requestEv.headersSent) {
|
|
811
|
-
return;
|
|
812
|
-
}
|
|
813
|
-
if (requestEv.method !== "GET" || requestEv.sharedMap.has(deps.IsQData)) {
|
|
814
|
-
return;
|
|
815
|
-
}
|
|
816
|
-
const mods = route.$mods$;
|
|
817
|
-
const hasETag = mods.some((m) => {
|
|
818
|
-
if (!m) {
|
|
819
|
-
return false;
|
|
820
|
-
}
|
|
821
|
-
if (m.routeConfig) {
|
|
822
|
-
return typeof m.routeConfig === "function" || m.routeConfig.eTag !== void 0;
|
|
823
|
-
}
|
|
824
|
-
return m.eTag !== void 0;
|
|
825
|
-
});
|
|
826
|
-
if (!hasETag) {
|
|
827
|
-
return;
|
|
828
|
-
}
|
|
829
|
-
const loaders = deps.getRequestLoaders(requestEv);
|
|
830
|
-
const getData = (loaderOrAction) => {
|
|
831
|
-
const id = loaderOrAction.__id;
|
|
832
|
-
if (loaderOrAction.__brand === "server_loader" && !(id in loaders)) {
|
|
833
|
-
throw new Error("Loader not executed for this request.");
|
|
834
|
-
}
|
|
835
|
-
if (loaders[id] instanceof Promise) {
|
|
836
|
-
throw new Error("Loaders returning a promise cannot be resolved for the eTag function.");
|
|
837
|
-
}
|
|
838
|
-
return loaders[id];
|
|
839
|
-
};
|
|
840
|
-
const routeLocation = {
|
|
841
|
-
params: requestEv.params,
|
|
842
|
-
url: requestEv.url,
|
|
843
|
-
isNavigating: false,
|
|
844
|
-
prevUrl: void 0
|
|
845
|
-
};
|
|
846
|
-
const status = requestEv.status();
|
|
847
|
-
const config = deps.resolveRouteConfig(getData, routeLocation, mods, "", status);
|
|
848
|
-
const headProps = {
|
|
849
|
-
head: config.head,
|
|
850
|
-
status,
|
|
851
|
-
withLocale: (fn) => fn(),
|
|
852
|
-
resolveValue: getData,
|
|
853
|
-
...routeLocation
|
|
854
|
-
};
|
|
855
|
-
const eTag = deps.resolveETag(config.eTag, headProps);
|
|
856
|
-
if (!eTag) {
|
|
857
|
-
return;
|
|
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, "");
|
|
864
|
-
return;
|
|
865
|
-
}
|
|
866
|
-
if (deps.MAX_CACHE_SIZE <= 0) {
|
|
867
|
-
return;
|
|
868
|
-
}
|
|
869
|
-
const cacheKey = deps.resolveCacheKey(config.cacheKey, status, eTag, requestEv.url.pathname);
|
|
870
|
-
if (!cacheKey) {
|
|
871
|
-
return;
|
|
872
|
-
}
|
|
873
|
-
const cachedHtml = deps.getCachedHtml(cacheKey);
|
|
874
|
-
if (cachedHtml) {
|
|
875
|
-
requestEv.headers.set("Content-Type", "text/html; charset=utf-8");
|
|
876
|
-
requestEv.headers.set("X-SSR-Cache", "HIT");
|
|
877
|
-
requestEv.send(status, cachedHtml);
|
|
878
|
-
return;
|
|
879
|
-
}
|
|
880
|
-
requestEv.sharedMap.set(deps.RequestEvETagCacheKey, cacheKey);
|
|
881
|
-
};
|
|
882
|
-
}
|
|
883
|
-
function serverErrorMiddleware(route, renderHandler) {
|
|
884
|
-
return async (requestEv) => {
|
|
885
|
-
try {
|
|
886
|
-
await requestEv.next();
|
|
887
|
-
} catch (e) {
|
|
888
|
-
if (!(e instanceof deps.ServerError) || requestEv.headersSent) {
|
|
889
|
-
throw e;
|
|
890
|
-
}
|
|
891
|
-
if (requestEv.sharedMap.has(deps.IsQData)) {
|
|
892
|
-
throw e;
|
|
893
|
-
}
|
|
894
|
-
const accept = requestEv.request.headers.get("Accept");
|
|
895
|
-
if (accept && !accept.includes("text/html")) {
|
|
896
|
-
throw e;
|
|
897
|
-
}
|
|
898
|
-
const status = e.status;
|
|
899
|
-
requestEv.status(status);
|
|
900
|
-
const errorLoader = route.$errorLoader$;
|
|
901
|
-
const errorModule = errorLoader ? await errorLoader() : await deps.loadHttpError();
|
|
902
|
-
route.$mods$ = [
|
|
903
|
-
errorModule
|
|
904
|
-
];
|
|
905
|
-
requestEv.sharedMap.set(deps.RequestEvHttpStatusMessage, typeof e.data === "string" ? e.data : "Server Error");
|
|
906
|
-
await renderHandler(requestEv);
|
|
907
|
-
}
|
|
908
|
-
};
|
|
909
|
-
}
|
|
910
|
-
async function runValidators(requestEv, validators, data) {
|
|
911
|
-
let lastResult = {
|
|
912
|
-
success: true,
|
|
913
|
-
data
|
|
914
|
-
};
|
|
915
|
-
if (validators) {
|
|
916
|
-
for (const validator of validators) {
|
|
917
|
-
if (isDev) {
|
|
918
|
-
lastResult = await measure(requestEv, `validator$`, () => validator.validate(requestEv, data));
|
|
919
|
-
} else {
|
|
920
|
-
lastResult = await validator.validate(requestEv, data);
|
|
921
|
-
}
|
|
922
|
-
if (!lastResult.success) {
|
|
923
|
-
return lastResult;
|
|
924
|
-
} else {
|
|
925
|
-
data = lastResult.data;
|
|
926
|
-
}
|
|
927
|
-
}
|
|
928
|
-
}
|
|
929
|
-
return lastResult;
|
|
930
|
-
}
|
|
931
|
-
function isAsyncIterator(obj) {
|
|
932
|
-
return obj ? typeof obj === "object" && Symbol.asyncIterator in obj : false;
|
|
933
|
-
}
|
|
934
|
-
async function runServerFunction(ev) {
|
|
935
|
-
const serverFnHash = ev.query.get(deps.QFN_KEY);
|
|
936
|
-
if (serverFnHash && ev.request.headers.get("X-QRL") === serverFnHash && ev.request.headers.get("Content-Type") === "application/qwik-json") {
|
|
937
|
-
ev.exit();
|
|
938
|
-
const data = await ev.parseBody();
|
|
939
|
-
if (!Array.isArray(data) || !(Array.isArray(data[0]) || data[0] === void 0)) {
|
|
940
|
-
throw ev.error(500, "Invalid request");
|
|
941
|
-
}
|
|
942
|
-
const qrl = inlinedQrl(null, serverFnHash, data.slice(1));
|
|
943
|
-
let result;
|
|
944
|
-
try {
|
|
945
|
-
if (isDev) {
|
|
946
|
-
result = await measure(ev, `server_${serverFnHash}`, () => qrl.apply(ev, data[0]));
|
|
947
|
-
} else {
|
|
948
|
-
result = await qrl.apply(ev, data[0]);
|
|
949
|
-
}
|
|
950
|
-
} catch (err) {
|
|
951
|
-
if (err instanceof deps.ServerError) {
|
|
952
|
-
throw ev.error(err.status, err.data);
|
|
953
|
-
}
|
|
954
|
-
console.error(`Server function ${serverFnHash} failed:`, err);
|
|
955
|
-
throw ev.error(500, "Invalid request");
|
|
956
|
-
}
|
|
957
|
-
if (isAsyncIterator(result)) {
|
|
958
|
-
ev.headers.set("Content-Type", "text/qwik-json-stream");
|
|
959
|
-
const writable = ev.getWritableStream();
|
|
960
|
-
const stream = writable.getWriter();
|
|
961
|
-
for await (const item of result) {
|
|
962
|
-
if (isDev) {
|
|
963
|
-
verifySerializable(item, qrl);
|
|
964
|
-
}
|
|
965
|
-
const message = await _serialize(item);
|
|
966
|
-
if (ev.signal.aborted) {
|
|
967
|
-
break;
|
|
968
|
-
}
|
|
969
|
-
await stream.write(deps.encoder.encode(`${message}
|
|
970
|
-
`));
|
|
971
|
-
}
|
|
972
|
-
stream.close();
|
|
973
|
-
} else {
|
|
974
|
-
verifySerializable(result, qrl);
|
|
975
|
-
ev.headers.set("Content-Type", "application/qwik-json");
|
|
976
|
-
const message = await _serialize(result);
|
|
977
|
-
ev.send(200, message);
|
|
978
|
-
}
|
|
979
|
-
return;
|
|
980
|
-
}
|
|
981
|
-
}
|
|
982
|
-
function fixTrailingSlash(ev) {
|
|
983
|
-
const { basePathname, originalUrl, sharedMap } = ev;
|
|
984
|
-
const { pathname, search } = originalUrl;
|
|
985
|
-
const isQData = sharedMap.has(deps.IsQData);
|
|
986
|
-
if (!pathname.startsWith("/") || pathname.startsWith("//")) {
|
|
987
|
-
return;
|
|
988
|
-
}
|
|
989
|
-
if (!isQData && pathname !== basePathname && !pathname.endsWith(".html")) {
|
|
990
|
-
if (!globalThis.__NO_TRAILING_SLASH__) {
|
|
991
|
-
if (!pathname.endsWith("/")) {
|
|
992
|
-
throw ev.redirect(deps.HttpStatus.MovedPermanently, pathname + "/" + search);
|
|
993
|
-
}
|
|
994
|
-
} else {
|
|
995
|
-
if (pathname.endsWith("/")) {
|
|
996
|
-
throw ev.redirect(deps.HttpStatus.MovedPermanently, pathname.slice(0, pathname.length - 1) + search);
|
|
997
|
-
}
|
|
998
|
-
}
|
|
999
|
-
}
|
|
1000
|
-
}
|
|
1001
|
-
function verifySerializable(data, qrl) {
|
|
1002
|
-
try {
|
|
1003
|
-
_verifySerializable(data, void 0);
|
|
1004
|
-
} catch (e) {
|
|
1005
|
-
if (e instanceof Error && qrl.dev) {
|
|
1006
|
-
e.loc = qrl.dev;
|
|
1007
|
-
}
|
|
1008
|
-
throw e;
|
|
1009
|
-
}
|
|
1010
|
-
}
|
|
1011
|
-
const isQrl = (value) => {
|
|
1012
|
-
return typeof value === "function" && typeof value.getSymbol === "function";
|
|
1013
|
-
};
|
|
1014
|
-
function isLastModulePageRoute(routeModules) {
|
|
1015
|
-
const lastRouteModule = routeModules[routeModules.length - 1];
|
|
1016
|
-
return lastRouteModule && typeof lastRouteModule.default === "function";
|
|
1017
|
-
}
|
|
1018
|
-
function getPathname(url) {
|
|
1019
|
-
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
|
-
if (!globalThis.__NO_TRAILING_SLASH__) {
|
|
1024
|
-
if (!url.pathname.endsWith("/")) {
|
|
1025
|
-
url.pathname += "/";
|
|
1026
|
-
}
|
|
1027
|
-
} else {
|
|
1028
|
-
if (url.pathname.endsWith("/")) {
|
|
1029
|
-
url.pathname = url.pathname.slice(0, -1);
|
|
1030
|
-
}
|
|
1031
|
-
}
|
|
1032
|
-
const search = url.search.slice(1).replaceAll(/&?q(action|data|func|loaders)=[^&]+/g, "");
|
|
1033
|
-
return `${url.pathname}${search ? `?${search}` : ""}${url.hash}`;
|
|
1034
|
-
}
|
|
1035
|
-
function csrfLaxProtoCheckMiddleware(requestEv) {
|
|
1036
|
-
checkCSRF(requestEv, "lax-proto");
|
|
1037
|
-
}
|
|
1038
|
-
function csrfCheckMiddleware(requestEv) {
|
|
1039
|
-
checkCSRF(requestEv);
|
|
1040
|
-
}
|
|
1041
|
-
function checkCSRF(requestEv, laxProto) {
|
|
1042
|
-
const contentType = requestEv.request.headers.get("content-type");
|
|
1043
|
-
const isSimpleRequest = !contentType || deps.isContentType(requestEv.request.headers, "application/x-www-form-urlencoded", "multipart/form-data", "text/plain");
|
|
1044
|
-
if (isSimpleRequest) {
|
|
1045
|
-
const inputOrigin = requestEv.request.headers.get("origin");
|
|
1046
|
-
const origin = requestEv.url.origin;
|
|
1047
|
-
let forbidden = inputOrigin !== origin;
|
|
1048
|
-
if (forbidden && laxProto && inputOrigin?.replace(/^http(s)?/g, "") === origin.replace(/^http(s)?/g, "")) {
|
|
1049
|
-
forbidden = false;
|
|
1050
|
-
}
|
|
1051
|
-
if (forbidden) {
|
|
1052
|
-
throw requestEv.error(403, `CSRF check failed. Cross-site ${requestEv.method} form submissions are forbidden.
|
|
1053
|
-
The request origin "${inputOrigin}" does not match the server origin "${origin}".`);
|
|
1054
|
-
}
|
|
1055
|
-
}
|
|
1056
|
-
}
|
|
1057
|
-
function renderQwikMiddleware(render) {
|
|
1058
|
-
return async (requestEv) => {
|
|
1059
|
-
if (requestEv.headersSent) {
|
|
1060
|
-
return;
|
|
1061
|
-
}
|
|
1062
|
-
if (requestEv.sharedMap.has(deps.IsQData)) {
|
|
1063
|
-
return;
|
|
1064
|
-
}
|
|
1065
|
-
const responseHeaders = requestEv.headers;
|
|
1066
|
-
if (!responseHeaders.has("Content-Type")) {
|
|
1067
|
-
responseHeaders.set("Content-Type", "text/html; charset=utf-8");
|
|
1068
|
-
}
|
|
1069
|
-
const eTagCacheKey = requestEv.sharedMap.get(deps.RequestEvETagCacheKey);
|
|
1070
|
-
const { readable, writable } = new TextEncoderStream();
|
|
1071
|
-
const writableStream = requestEv.getWritableStream();
|
|
1072
|
-
let cacheChunks;
|
|
1073
|
-
let pipeSource = readable;
|
|
1074
|
-
if (eTagCacheKey) {
|
|
1075
|
-
cacheChunks = [];
|
|
1076
|
-
const capture = new TransformStream({
|
|
1077
|
-
transform(chunk, controller) {
|
|
1078
|
-
cacheChunks.push(chunk);
|
|
1079
|
-
controller.enqueue(chunk);
|
|
1080
|
-
}
|
|
1081
|
-
});
|
|
1082
|
-
pipeSource = readable.pipeThrough(capture);
|
|
1083
|
-
}
|
|
1084
|
-
let pipeError;
|
|
1085
|
-
const pipe = pipeSource.pipeTo(writableStream, {
|
|
1086
|
-
preventClose: true
|
|
1087
|
-
}).catch((error) => {
|
|
1088
|
-
pipeError = error;
|
|
1089
|
-
});
|
|
1090
|
-
const stream = writable.getWriter();
|
|
1091
|
-
const status = requestEv.status();
|
|
1092
|
-
try {
|
|
1093
|
-
const isStatic = deps.getRequestMode(requestEv) === "static";
|
|
1094
|
-
const serverData = deps.getQwikRouterServerData(requestEv);
|
|
1095
|
-
const result = await render({
|
|
1096
|
-
base: requestEv.basePathname + "build/",
|
|
1097
|
-
stream,
|
|
1098
|
-
streaming: isStatic ? {
|
|
1099
|
-
outOfOrder: false
|
|
1100
|
-
} : void 0,
|
|
1101
|
-
serverData,
|
|
1102
|
-
containerAttributes: {
|
|
1103
|
-
["q:render"]: isStatic ? "static" : "",
|
|
1104
|
-
...serverData.containerAttributes
|
|
1105
|
-
}
|
|
1106
|
-
});
|
|
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
|
-
if (typeof result.html === "string") {
|
|
1114
|
-
await stream.write(result.html);
|
|
1115
|
-
}
|
|
1116
|
-
requestEv.sharedMap.set(deps.RequestEvShareQData, qData);
|
|
1117
|
-
} finally {
|
|
1118
|
-
await stream.ready;
|
|
1119
|
-
await stream.close();
|
|
1120
|
-
await pipe;
|
|
1121
|
-
}
|
|
1122
|
-
if (pipeError) {
|
|
1123
|
-
throw pipeError;
|
|
1124
|
-
}
|
|
1125
|
-
if (eTagCacheKey && cacheChunks && cacheChunks.length > 0) {
|
|
1126
|
-
const totalLength = cacheChunks.reduce((sum, chunk) => sum + chunk.length, 0);
|
|
1127
|
-
const combined = new Uint8Array(totalLength);
|
|
1128
|
-
let offset = 0;
|
|
1129
|
-
for (const chunk of cacheChunks) {
|
|
1130
|
-
combined.set(chunk, offset);
|
|
1131
|
-
offset += chunk.length;
|
|
1132
|
-
}
|
|
1133
|
-
deps.setCachedHtml(eTagCacheKey, new TextDecoder().decode(combined));
|
|
1134
|
-
}
|
|
1135
|
-
await writableStream.close();
|
|
1136
|
-
};
|
|
1137
|
-
}
|
|
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
|
-
function now() {
|
|
1214
|
-
return typeof performance !== "undefined" ? performance.now() : 0;
|
|
1215
|
-
}
|
|
1216
|
-
async function measure(requestEv, name, fn) {
|
|
1217
|
-
const start = now();
|
|
1218
|
-
try {
|
|
1219
|
-
return await fn();
|
|
1220
|
-
} finally {
|
|
1221
|
-
const duration = now() - start;
|
|
1222
|
-
let measurements = requestEv.sharedMap.get(deps.RequestEvShareServerTiming);
|
|
1223
|
-
if (!measurements) {
|
|
1224
|
-
requestEv.sharedMap.set(deps.RequestEvShareServerTiming, measurements = []);
|
|
1225
|
-
}
|
|
1226
|
-
measurements.push([
|
|
1227
|
-
name,
|
|
1228
|
-
duration
|
|
1229
|
-
]);
|
|
1230
|
-
}
|
|
1231
|
-
}
|
|
1232
|
-
return {
|
|
1233
|
-
actionsMiddleware,
|
|
1234
|
-
checkBrand,
|
|
1235
|
-
checkCSRF,
|
|
1236
|
-
fixTrailingSlash,
|
|
1237
|
-
getPathname,
|
|
1238
|
-
isLastModulePageRoute,
|
|
1239
|
-
isQrl,
|
|
1240
|
-
loadersMiddleware,
|
|
1241
|
-
measure,
|
|
1242
|
-
renderQwikMiddleware,
|
|
1243
|
-
resolveRequestHandlers,
|
|
1244
|
-
verifySerializable
|
|
1245
|
-
};
|
|
1246
|
-
}
|
|
1247
|
-
|
|
1248
|
-
const encoder = /* @__PURE__ */ new TextEncoder();
|
|
1249
|
-
function getContentType(headers) {
|
|
1250
|
-
return (headers.get("content-type")?.split(/[;,]/, 1)[0].trim() ?? "").toLowerCase();
|
|
1251
|
-
}
|
|
1252
|
-
function isContentType(headers, ...types) {
|
|
1253
|
-
const type = getContentType(headers);
|
|
1254
|
-
for (let i = 0; i < types.length; i++) {
|
|
1255
|
-
if (types[i].toLowerCase() === type) {
|
|
1256
|
-
return true;
|
|
1257
|
-
}
|
|
1258
|
-
}
|
|
1259
|
-
return false;
|
|
1260
|
-
}
|
|
1261
|
-
|
|
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
|
-
const requestHandlers = createResolveRequestHandlers({
|
|
1271
|
-
QACTION_KEY,
|
|
1272
|
-
QFN_KEY,
|
|
1273
|
-
QLOADER_KEY,
|
|
1274
|
-
QDATA_JSON,
|
|
1275
|
-
IsQData,
|
|
1276
|
-
RequestEvETagCacheKey,
|
|
1277
|
-
RequestEvHttpStatusMessage,
|
|
1278
|
-
RequestEvIsRewrite,
|
|
1279
|
-
RequestEvShareQData,
|
|
1280
|
-
RequestEvShareServerTiming,
|
|
1281
|
-
RequestEvSharedActionId,
|
|
1282
|
-
RequestRouteName,
|
|
1283
|
-
RedirectMessage,
|
|
1284
|
-
ServerError,
|
|
1285
|
-
HttpStatus,
|
|
1286
|
-
encoder,
|
|
1287
|
-
isContentType,
|
|
1288
|
-
getCachedHtml,
|
|
1289
|
-
getQwikRouterServerData,
|
|
1290
|
-
getRequestLoaderSerializationStrategyMap,
|
|
1291
|
-
getRequestLoaders,
|
|
1292
|
-
getRequestMode,
|
|
1293
|
-
getRouteLoaderPromise,
|
|
1294
|
-
loadHttpError: () => import('../../chunks/http-error.qwik.mjs'),
|
|
1295
|
-
MAX_CACHE_SIZE,
|
|
1296
|
-
resolveCacheKey,
|
|
1297
|
-
resolveETag,
|
|
1298
|
-
resolveRouteConfig,
|
|
1299
|
-
setCachedHtml
|
|
1300
|
-
});
|
|
1301
|
-
const { renderQwikMiddleware, resolveRequestHandlers} = requestHandlers;
|
|
1302
|
-
|
|
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
|
-
function createCacheControl(cacheControl) {
|
|
1314
|
-
const controls = [];
|
|
1315
|
-
if (cacheControl === "day") {
|
|
1316
|
-
cacheControl = 60 * 60 * 24;
|
|
1317
|
-
} else if (cacheControl === "week") {
|
|
1318
|
-
cacheControl = 60 * 60 * 24 * 7;
|
|
1319
|
-
} else if (cacheControl === "month") {
|
|
1320
|
-
cacheControl = 60 * 60 * 24 * 30;
|
|
1321
|
-
} else if (cacheControl === "year") {
|
|
1322
|
-
cacheControl = 60 * 60 * 24 * 365;
|
|
1323
|
-
} else if (cacheControl === "private") {
|
|
1324
|
-
cacheControl = {
|
|
1325
|
-
private: true,
|
|
1326
|
-
noCache: true
|
|
1327
|
-
};
|
|
1328
|
-
} else if (cacheControl === "immutable") {
|
|
1329
|
-
cacheControl = {
|
|
1330
|
-
public: true,
|
|
1331
|
-
immutable: true,
|
|
1332
|
-
maxAge: 60 * 60 * 24 * 365
|
|
1333
|
-
};
|
|
1334
|
-
} else if (cacheControl === "no-cache") {
|
|
1335
|
-
cacheControl = {
|
|
1336
|
-
noCache: true
|
|
1337
|
-
};
|
|
1338
|
-
}
|
|
1339
|
-
if (typeof cacheControl === "number") {
|
|
1340
|
-
cacheControl = {
|
|
1341
|
-
maxAge: cacheControl,
|
|
1342
|
-
sMaxAge: cacheControl
|
|
1343
|
-
};
|
|
1344
|
-
}
|
|
1345
|
-
if (cacheControl.immutable) {
|
|
1346
|
-
controls.push("immutable");
|
|
1347
|
-
}
|
|
1348
|
-
if (cacheControl.maxAge) {
|
|
1349
|
-
controls.push(`max-age=${cacheControl.maxAge}`);
|
|
1350
|
-
}
|
|
1351
|
-
if (cacheControl.sMaxAge) {
|
|
1352
|
-
controls.push(`s-maxage=${cacheControl.sMaxAge}`);
|
|
1353
|
-
}
|
|
1354
|
-
if (cacheControl.noStore) {
|
|
1355
|
-
controls.push("no-store");
|
|
1356
|
-
}
|
|
1357
|
-
if (cacheControl.noCache) {
|
|
1358
|
-
controls.push("no-cache");
|
|
1359
|
-
}
|
|
1360
|
-
if (cacheControl.private) {
|
|
1361
|
-
controls.push("private");
|
|
1362
|
-
}
|
|
1363
|
-
if (cacheControl.public) {
|
|
1364
|
-
controls.push("public");
|
|
1365
|
-
}
|
|
1366
|
-
if (cacheControl.staleWhileRevalidate) {
|
|
1367
|
-
controls.push(`stale-while-revalidate=${cacheControl.staleWhileRevalidate}`);
|
|
1368
|
-
}
|
|
1369
|
-
if (cacheControl.staleIfError) {
|
|
1370
|
-
controls.push(`stale-if-error=${cacheControl.staleIfError}`);
|
|
1371
|
-
}
|
|
1372
|
-
return controls.join(", ");
|
|
1373
|
-
}
|
|
1374
|
-
|
|
1375
|
-
const SAMESITE = {
|
|
1376
|
-
lax: "Lax",
|
|
1377
|
-
Lax: "Lax",
|
|
1378
|
-
None: "None",
|
|
1379
|
-
none: "None",
|
|
1380
|
-
strict: "Strict",
|
|
1381
|
-
Strict: "Strict"
|
|
1382
|
-
};
|
|
1383
|
-
const UNIT = {
|
|
1384
|
-
seconds: 1,
|
|
1385
|
-
minutes: 1 * 60,
|
|
1386
|
-
hours: 1 * 60 * 60,
|
|
1387
|
-
days: 1 * 60 * 60 * 24,
|
|
1388
|
-
weeks: 1 * 60 * 60 * 24 * 7
|
|
1389
|
-
};
|
|
1390
|
-
function tryDecodeUriComponent(str) {
|
|
1391
|
-
try {
|
|
1392
|
-
return decodeURIComponent(str);
|
|
1393
|
-
} catch {
|
|
1394
|
-
return str;
|
|
1395
|
-
}
|
|
1396
|
-
}
|
|
1397
|
-
const parseCookieString = (cookieString) => {
|
|
1398
|
-
const cookie = {};
|
|
1399
|
-
if (typeof cookieString === "string" && cookieString !== "") {
|
|
1400
|
-
const cookieSegments = cookieString.split(";");
|
|
1401
|
-
for (const cookieSegment of cookieSegments) {
|
|
1402
|
-
const separatorIndex = cookieSegment.indexOf("=");
|
|
1403
|
-
if (separatorIndex !== -1) {
|
|
1404
|
-
cookie[tryDecodeUriComponent(cookieSegment.slice(0, separatorIndex).trim())] = tryDecodeUriComponent(cookieSegment.slice(separatorIndex + 1).trim());
|
|
1405
|
-
}
|
|
1406
|
-
}
|
|
1407
|
-
}
|
|
1408
|
-
return cookie;
|
|
1409
|
-
};
|
|
1410
|
-
function resolveSameSite(sameSite) {
|
|
1411
|
-
if (sameSite === true) {
|
|
1412
|
-
return "Strict";
|
|
1413
|
-
}
|
|
1414
|
-
if (sameSite === false) {
|
|
1415
|
-
return "None";
|
|
1416
|
-
}
|
|
1417
|
-
if (sameSite) {
|
|
1418
|
-
return SAMESITE[sameSite];
|
|
1419
|
-
}
|
|
1420
|
-
return void 0;
|
|
1421
|
-
}
|
|
1422
|
-
const createSetCookieValue = (cookieName, cookieValue, options) => {
|
|
1423
|
-
const c = [
|
|
1424
|
-
`${cookieName}=${cookieValue}`
|
|
1425
|
-
];
|
|
1426
|
-
if (typeof options.domain === "string") {
|
|
1427
|
-
c.push(`Domain=${options.domain}`);
|
|
1428
|
-
}
|
|
1429
|
-
if (typeof options.maxAge === "number") {
|
|
1430
|
-
c.push(`Max-Age=${options.maxAge}`);
|
|
1431
|
-
} else if (Array.isArray(options.maxAge)) {
|
|
1432
|
-
c.push(`Max-Age=${options.maxAge[0] * UNIT[options.maxAge[1]]}`);
|
|
1433
|
-
} else if (typeof options.expires === "number" || typeof options.expires == "string") {
|
|
1434
|
-
c.push(`Expires=${options.expires}`);
|
|
1435
|
-
} else if (options.expires instanceof Date) {
|
|
1436
|
-
c.push(`Expires=${options.expires.toUTCString()}`);
|
|
1437
|
-
}
|
|
1438
|
-
if (options.httpOnly) {
|
|
1439
|
-
c.push("HttpOnly");
|
|
1440
|
-
}
|
|
1441
|
-
if (typeof options.path === "string") {
|
|
1442
|
-
c.push(`Path=${options.path}`);
|
|
1443
|
-
}
|
|
1444
|
-
const sameSite = resolveSameSite(options.sameSite);
|
|
1445
|
-
if (sameSite) {
|
|
1446
|
-
c.push(`SameSite=${sameSite}`);
|
|
1447
|
-
}
|
|
1448
|
-
if (options.secure) {
|
|
1449
|
-
c.push("Secure");
|
|
1450
|
-
}
|
|
1451
|
-
return c.join("; ");
|
|
1452
|
-
};
|
|
1453
|
-
const REQ_COOKIE = /* @__PURE__ */ Symbol("request-cookies");
|
|
1454
|
-
const RES_COOKIE = /* @__PURE__ */ Symbol("response-cookies");
|
|
1455
|
-
const LIVE_COOKIE = /* @__PURE__ */ Symbol("live-cookies");
|
|
1456
|
-
class Cookie {
|
|
1457
|
-
[REQ_COOKIE];
|
|
1458
|
-
[RES_COOKIE] = {};
|
|
1459
|
-
[LIVE_COOKIE] = {};
|
|
1460
|
-
appendCounter = 0;
|
|
1461
|
-
constructor(cookieString) {
|
|
1462
|
-
this[REQ_COOKIE] = parseCookieString(cookieString);
|
|
1463
|
-
this[LIVE_COOKIE] = {
|
|
1464
|
-
...this[REQ_COOKIE]
|
|
1465
|
-
};
|
|
1466
|
-
}
|
|
1467
|
-
get(cookieName, live = true) {
|
|
1468
|
-
const value = this[live ? LIVE_COOKIE : REQ_COOKIE][cookieName];
|
|
1469
|
-
if (!value) {
|
|
1470
|
-
return null;
|
|
1471
|
-
}
|
|
1472
|
-
return {
|
|
1473
|
-
value,
|
|
1474
|
-
json() {
|
|
1475
|
-
return JSON.parse(value);
|
|
1476
|
-
},
|
|
1477
|
-
number() {
|
|
1478
|
-
return Number(value);
|
|
1479
|
-
}
|
|
1480
|
-
};
|
|
1481
|
-
}
|
|
1482
|
-
getAll(live = true) {
|
|
1483
|
-
return Object.keys(this[live ? LIVE_COOKIE : REQ_COOKIE]).reduce((cookies, cookieName) => {
|
|
1484
|
-
cookies[cookieName] = this.get(cookieName);
|
|
1485
|
-
return cookies;
|
|
1486
|
-
}, {});
|
|
1487
|
-
}
|
|
1488
|
-
has(cookieName, live = true) {
|
|
1489
|
-
return !!this[live ? LIVE_COOKIE : REQ_COOKIE][cookieName];
|
|
1490
|
-
}
|
|
1491
|
-
set(cookieName, cookieValue, options = {}) {
|
|
1492
|
-
this[LIVE_COOKIE][cookieName] = typeof cookieValue === "string" ? cookieValue : JSON.stringify(cookieValue);
|
|
1493
|
-
const resolvedValue = typeof cookieValue === "string" ? cookieValue : encodeURIComponent(JSON.stringify(cookieValue));
|
|
1494
|
-
this[RES_COOKIE][cookieName] = createSetCookieValue(cookieName, resolvedValue, options);
|
|
1495
|
-
}
|
|
1496
|
-
append(cookieName, cookieValue, options = {}) {
|
|
1497
|
-
this[LIVE_COOKIE][cookieName] = typeof cookieValue === "string" ? cookieValue : JSON.stringify(cookieValue);
|
|
1498
|
-
const resolvedValue = typeof cookieValue === "string" ? cookieValue : encodeURIComponent(JSON.stringify(cookieValue));
|
|
1499
|
-
this[RES_COOKIE][++this.appendCounter] = createSetCookieValue(cookieName, resolvedValue, options);
|
|
1500
|
-
}
|
|
1501
|
-
delete(name, options) {
|
|
1502
|
-
this.set(name, "deleted", {
|
|
1503
|
-
...options,
|
|
1504
|
-
maxAge: 0
|
|
1505
|
-
});
|
|
1506
|
-
this[LIVE_COOKIE][name] = null;
|
|
1507
|
-
}
|
|
1508
|
-
headers() {
|
|
1509
|
-
return Object.values(this[RES_COOKIE]);
|
|
1510
|
-
}
|
|
1511
|
-
}
|
|
1512
|
-
const mergeHeadersCookies = (headers, cookies) => {
|
|
1513
|
-
const cookieHeaders = cookies.headers();
|
|
1514
|
-
if (cookieHeaders.length > 0) {
|
|
1515
|
-
const newHeaders = new Headers(headers);
|
|
1516
|
-
for (const cookie of cookieHeaders) {
|
|
1517
|
-
newHeaders.append("Set-Cookie", cookie);
|
|
1518
|
-
}
|
|
1519
|
-
return newHeaders;
|
|
1520
|
-
}
|
|
1521
|
-
return headers;
|
|
1522
|
-
};
|
|
1523
|
-
|
|
1524
|
-
class RewriteMessage extends AbortMessage {
|
|
1525
|
-
pathname;
|
|
1526
|
-
constructor(pathname) {
|
|
1527
|
-
super(), this.pathname = pathname;
|
|
1528
|
-
}
|
|
1529
|
-
}
|
|
1530
|
-
|
|
1531
|
-
const requestEventDeps = {
|
|
1532
|
-
QDATA_KEY,
|
|
1533
|
-
isPromise,
|
|
1534
|
-
createCacheControl,
|
|
1535
|
-
Cookie,
|
|
1536
|
-
AbortMessage,
|
|
1537
|
-
RedirectMessage,
|
|
1538
|
-
RewriteMessage,
|
|
1539
|
-
ServerError,
|
|
1540
|
-
getRouteLoaderPromise,
|
|
1541
|
-
getRouteMatchPathname,
|
|
1542
|
-
IsQData,
|
|
1543
|
-
encoder,
|
|
1544
|
-
getContentType
|
|
1545
|
-
};
|
|
1546
|
-
function createRequestEvent(...args) {
|
|
1547
|
-
return createRequestEventWithDeps(requestEventDeps, ...args);
|
|
1548
|
-
}
|
|
1549
|
-
|
|
1550
|
-
async function runNextWithDeps(requestEv, rebuildRouteInfo, resolve, deps) {
|
|
1551
|
-
try {
|
|
1552
|
-
const isValidURL = (url) => new URL(url.pathname + url.search, url);
|
|
1553
|
-
isValidURL(requestEv.originalUrl);
|
|
1554
|
-
} catch {
|
|
1555
|
-
const status = 404;
|
|
1556
|
-
const message = "Resource Not Found";
|
|
1557
|
-
requestEv.status(status);
|
|
1558
|
-
requestEv.html(status, deps.getErrorHtml(status, message));
|
|
1559
|
-
return new deps.ServerError(status, message);
|
|
1560
|
-
}
|
|
1561
|
-
let rewriteAttempt = 1;
|
|
1562
|
-
async function runOnce() {
|
|
1563
|
-
try {
|
|
1564
|
-
await requestEv.next();
|
|
1565
|
-
} catch (e) {
|
|
1566
|
-
if (e instanceof deps.RedirectMessage) {
|
|
1567
|
-
const stream = requestEv.getWritableStream();
|
|
1568
|
-
await stream.close();
|
|
1569
|
-
return e;
|
|
1570
|
-
} else if (e instanceof deps.RewriteMessage) {
|
|
1571
|
-
if (rewriteAttempt > 50) {
|
|
1572
|
-
return new Error(`Infinite rewrite loop`);
|
|
1573
|
-
}
|
|
1574
|
-
rewriteAttempt += 1;
|
|
1575
|
-
const url = new URL(requestEv.url);
|
|
1576
|
-
url.pathname = e.pathname;
|
|
1577
|
-
const { loadedRoute, requestHandlers } = await rebuildRouteInfo(url);
|
|
1578
|
-
requestEv.resetRoute(loadedRoute, requestHandlers, url);
|
|
1579
|
-
return await runOnce();
|
|
1580
|
-
} else if (e instanceof deps.AbortMessage) {
|
|
1581
|
-
return;
|
|
1582
|
-
} else if (e instanceof deps.ServerError && !requestEv.headersSent) {
|
|
1583
|
-
const status = e.status;
|
|
1584
|
-
const accept = requestEv.request.headers.get("Accept");
|
|
1585
|
-
if (accept && !accept.includes("text/html")) {
|
|
1586
|
-
requestEv.headers.set("Content-Type", "application/qwik-json");
|
|
1587
|
-
requestEv.send(status, await _serialize(e.data));
|
|
1588
|
-
} else {
|
|
1589
|
-
requestEv.html(status, deps.getErrorHtml(status, e.data));
|
|
1590
|
-
}
|
|
1591
|
-
return e;
|
|
1592
|
-
}
|
|
1593
|
-
if (!isDev) {
|
|
1594
|
-
try {
|
|
1595
|
-
if (!requestEv.headersSent) {
|
|
1596
|
-
requestEv.headers.set("content-type", "text/html; charset=utf-8");
|
|
1597
|
-
requestEv.cacheControl({
|
|
1598
|
-
noCache: true
|
|
1599
|
-
});
|
|
1600
|
-
requestEv.status(500);
|
|
1601
|
-
}
|
|
1602
|
-
const stream = requestEv.getWritableStream();
|
|
1603
|
-
if (!stream.locked) {
|
|
1604
|
-
const writer = stream.getWriter();
|
|
1605
|
-
await writer.write(deps.encoder.encode(deps.getErrorHtml(500, "Internal Server Error")));
|
|
1606
|
-
await writer.close();
|
|
1607
|
-
}
|
|
1608
|
-
} catch {
|
|
1609
|
-
console.error("Unable to render error page");
|
|
1610
|
-
}
|
|
1611
|
-
}
|
|
1612
|
-
return e instanceof Error || typeof e === "object" && e !== null ? e : new Error(String(e));
|
|
1613
|
-
}
|
|
1614
|
-
}
|
|
1615
|
-
try {
|
|
1616
|
-
return await runOnce();
|
|
1617
|
-
} finally {
|
|
1618
|
-
if (!requestEv.isDirty()) {
|
|
1619
|
-
resolve(null);
|
|
1620
|
-
}
|
|
1621
|
-
}
|
|
1622
|
-
}
|
|
1623
|
-
function runQwikRouterWithDeps(serverRequestEv, loadedRoute, requestHandlers, rebuildRouteInfo, basePathname, deps) {
|
|
1624
|
-
let resolve;
|
|
1625
|
-
const responsePromise = new Promise((r) => resolve = r);
|
|
1626
|
-
const requestEv = deps.createRequestEvent(serverRequestEv, loadedRoute, requestHandlers, basePathname, resolve);
|
|
1627
|
-
return {
|
|
1628
|
-
response: responsePromise,
|
|
1629
|
-
requestEv,
|
|
1630
|
-
completion: deps.asyncRequestStore ? deps.asyncRequestStore.run(requestEv, runNextWithDeps, requestEv, rebuildRouteInfo, resolve, deps) : runNextWithDeps(requestEv, rebuildRouteInfo, resolve, deps)
|
|
1631
|
-
};
|
|
1632
|
-
}
|
|
1633
|
-
|
|
1634
|
-
function runQwikRouter(serverRequestEv, loadedRoute, requestHandlers, rebuildRouteInfo, basePathname = "/") {
|
|
1635
|
-
return runQwikRouterWithDeps(serverRequestEv, loadedRoute, requestHandlers, rebuildRouteInfo, basePathname, {
|
|
1636
|
-
AbortMessage,
|
|
1637
|
-
RedirectMessage,
|
|
1638
|
-
RewriteMessage,
|
|
1639
|
-
ServerError,
|
|
1640
|
-
asyncRequestStore: _asyncRequestStore,
|
|
1641
|
-
createRequestEvent,
|
|
1642
|
-
encoder,
|
|
1643
|
-
getErrorHtml
|
|
1644
|
-
});
|
|
1645
|
-
}
|
|
1
|
+
import { F as FULLPATH_HEADER, R as ROUTE_PATH_HEADER, l as loadRoute } from '../../chunks/head.qwik.mjs';
|
|
2
|
+
export { _ as _asyncRequestStore } from '../../chunks/head.qwik.mjs';
|
|
3
|
+
import { isDev } from '@qwik.dev/core';
|
|
4
|
+
import { d as devPreloadedRouteLoaders } from '../../chunks/dev-preloaded-route-loader.mjs';
|
|
5
|
+
import { r as recognizeRequest, t as trimRecognizedInternalPathname, I as IsQLoader, a as resolveValidInternalFullPathname, b as trimInternalPathname } from '../../chunks/request-path.mjs';
|
|
6
|
+
import { r as runQwikRouter, a as resolveRequestHandlers, b as renderQwikMiddleware } from '../../chunks/user-response.mjs';
|
|
7
|
+
export { R as RewriteMessage, c as clearLoaderCache, d as clearSsrCache, g as getErrorHtml, m as mergeHeadersCookies } from '../../chunks/user-response.mjs';
|
|
8
|
+
export { A as AbortMessage, R as RedirectMessage, S as ServerError } from '../../chunks/server-error.mjs';
|
|
1646
9
|
|
|
1647
10
|
let qwikRouterConfig;
|
|
1648
11
|
async function getConfig() {
|
|
12
|
+
if (isDev) {
|
|
13
|
+
return await import('@qwik-router-config');
|
|
14
|
+
}
|
|
1649
15
|
if (!qwikRouterConfig) {
|
|
1650
16
|
qwikRouterConfig = await import('@qwik-router-config');
|
|
1651
17
|
}
|
|
1652
18
|
return qwikRouterConfig;
|
|
1653
19
|
}
|
|
1654
|
-
|
|
20
|
+
function getRequestHandlerPathname(serverRequestEv) {
|
|
21
|
+
const recognized = recognizeRequest(serverRequestEv.url.pathname);
|
|
22
|
+
if (!recognized) {
|
|
23
|
+
return serverRequestEv.url.pathname;
|
|
24
|
+
}
|
|
25
|
+
const loaderPathname = trimRecognizedInternalPathname(serverRequestEv.url.pathname, recognized);
|
|
26
|
+
if (recognized.type !== IsQLoader) {
|
|
27
|
+
return loaderPathname;
|
|
28
|
+
}
|
|
29
|
+
return resolveValidInternalFullPathname(loaderPathname, serverRequestEv.request.headers.get(FULLPATH_HEADER) ?? serverRequestEv.request.headers.get(ROUTE_PATH_HEADER)) ?? loaderPathname;
|
|
30
|
+
}
|
|
31
|
+
async function loadRequestHandlers(qwikRouterConfig2, pathname, method, checkOrigin, renderFn, serverRequestEv) {
|
|
1655
32
|
const { routes, serverPlugins, cacheModules } = qwikRouterConfig2;
|
|
1656
|
-
const loadedRoute = await loadRoute(routes, cacheModules, pathname
|
|
1657
|
-
const
|
|
33
|
+
const loadedRoute = await loadRoute(routes, cacheModules, pathname);
|
|
34
|
+
const loader = isDev ? devPreloadedRouteLoaders.get(serverRequestEv.request) : void 0;
|
|
35
|
+
const lastModule = loadedRoute.$mods$[loadedRoute.$mods$.length - 1];
|
|
36
|
+
if (loader && lastModule) {
|
|
37
|
+
loadedRoute.$mods$[loadedRoute.$mods$.length - 1] = Object.assign({}, lastModule, {
|
|
38
|
+
__preloadedRouteLoader: loader
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
const requestHandlers = resolveRequestHandlers(serverPlugins, loadedRoute, method, checkOrigin, renderQwikMiddleware(renderFn));
|
|
1658
42
|
return {
|
|
1659
43
|
loadedRoute,
|
|
1660
44
|
requestHandlers
|
|
@@ -1663,34 +47,21 @@ async function loadRequestHandlers(qwikRouterConfig2, pathname, method, checkOri
|
|
|
1663
47
|
async function requestHandler(serverRequestEv, opts) {
|
|
1664
48
|
const { render, checkOrigin } = opts;
|
|
1665
49
|
const config = await getConfig();
|
|
1666
|
-
const
|
|
50
|
+
const pathname = getRequestHandlerPathname(serverRequestEv);
|
|
1667
51
|
if (pathname === "/.well-known" || pathname.startsWith("/.well-known/")) {
|
|
1668
52
|
return null;
|
|
1669
53
|
}
|
|
1670
|
-
const { loadedRoute, requestHandlers } = await loadRequestHandlers(config, pathname, serverRequestEv.request.method, checkOrigin ?? true, render,
|
|
54
|
+
const { loadedRoute, requestHandlers } = await loadRequestHandlers(config, pathname, serverRequestEv.request.method, checkOrigin ?? true, render, serverRequestEv);
|
|
1671
55
|
if (config.fallthrough && loadedRoute.$notFound$) {
|
|
1672
56
|
return null;
|
|
1673
57
|
}
|
|
1674
58
|
const rebuildRouteInfo = async (url) => {
|
|
1675
|
-
const
|
|
1676
|
-
return loadRequestHandlers(config,
|
|
59
|
+
const cleanPathname = trimInternalPathname(url.pathname);
|
|
60
|
+
return loadRequestHandlers(config, cleanPathname, serverRequestEv.request.method, checkOrigin ?? true, render, serverRequestEv);
|
|
1677
61
|
};
|
|
1678
62
|
return runQwikRouter(serverRequestEv, loadedRoute, requestHandlers, rebuildRouteInfo, config.basePathname);
|
|
1679
63
|
}
|
|
1680
64
|
|
|
1681
|
-
const notFounds = [
|
|
1682
|
-
// Will be replaced in post-build with the 404s generated by SSG
|
|
1683
|
-
"__QWIK_ROUTER_NOT_FOUND_ARRAY__"
|
|
1684
|
-
];
|
|
1685
|
-
function getNotFound(prefix) {
|
|
1686
|
-
for (const [path, html] of notFounds) {
|
|
1687
|
-
if (prefix.startsWith(path)) {
|
|
1688
|
-
return html;
|
|
1689
|
-
}
|
|
1690
|
-
}
|
|
1691
|
-
return minimalHtmlResponse(404, "Resource Not Found");
|
|
1692
|
-
}
|
|
1693
|
-
|
|
1694
65
|
const staticPaths = /* @__PURE__ */ new Set([
|
|
1695
66
|
"__QWIK_ROUTER_STATIC_PATHS_ARRAY__"
|
|
1696
67
|
]);
|
|
@@ -1705,19 +76,7 @@ function isStaticPath(method, url) {
|
|
|
1705
76
|
if (p.startsWith("/" + (globalThis.__QWIK_ASSETS_DIR__ || "assets") + "/")) {
|
|
1706
77
|
return true;
|
|
1707
78
|
}
|
|
1708
|
-
|
|
1709
|
-
return true;
|
|
1710
|
-
}
|
|
1711
|
-
if (p.endsWith("/q-data.json")) {
|
|
1712
|
-
const pWithoutQdata = p.replace(/\/q-data.json$/, "");
|
|
1713
|
-
if (staticPaths.has(pWithoutQdata + "/")) {
|
|
1714
|
-
return true;
|
|
1715
|
-
}
|
|
1716
|
-
if (staticPaths.has(pWithoutQdata)) {
|
|
1717
|
-
return true;
|
|
1718
|
-
}
|
|
1719
|
-
}
|
|
1720
|
-
return false;
|
|
79
|
+
return staticPaths.has(p);
|
|
1721
80
|
}
|
|
1722
81
|
|
|
1723
82
|
class _TextEncoderStream_polyfill {
|
|
@@ -1777,4 +136,4 @@ class _TextEncoderStream_polyfill {
|
|
|
1777
136
|
}
|
|
1778
137
|
}
|
|
1779
138
|
|
|
1780
|
-
export {
|
|
139
|
+
export { _TextEncoderStream_polyfill, isStaticPath, requestHandler };
|