@qwik.dev/router 2.0.0-beta.3 → 2.0.0-beta.30
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/adapters/static/vite.d.ts +1 -1
- package/lib/adapters/azure-swa/vite/index.d.ts +2 -2
- package/lib/adapters/azure-swa/vite/index.mjs +39 -44
- package/lib/adapters/bun-server/vite/index.d.ts +2 -2
- package/lib/adapters/bun-server/vite/index.mjs +6 -7
- package/lib/adapters/cloud-run/vite/index.d.ts +2 -2
- package/lib/adapters/cloud-run/vite/index.mjs +6 -7
- package/lib/adapters/cloudflare-pages/vite/index.d.ts +2 -2
- package/lib/adapters/cloudflare-pages/vite/index.mjs +23 -32
- package/lib/adapters/deno-server/vite/index.d.ts +2 -2
- package/lib/adapters/deno-server/vite/index.mjs +13 -9
- package/lib/adapters/netlify-edge/vite/index.d.ts +2 -2
- package/lib/adapters/netlify-edge/vite/index.mjs +22 -36
- package/lib/adapters/node-server/vite/index.d.ts +2 -2
- package/lib/adapters/node-server/vite/index.mjs +6 -7
- package/lib/adapters/shared/vite/index.d.ts +7 -19
- package/lib/adapters/shared/vite/index.mjs +244 -233
- package/lib/adapters/ssg/vite/index.d.ts +13 -0
- package/lib/adapters/ssg/vite/index.mjs +17 -0
- package/lib/adapters/vercel-edge/vite/index.d.ts +3 -3
- package/lib/adapters/vercel-edge/vite/index.mjs +33 -19
- package/lib/chunks/deepFreeze.qwik.mjs +18 -0
- package/lib/chunks/error-handler.mjs +57 -0
- package/lib/chunks/fs.mjs +144 -0
- package/lib/chunks/http-error.qwik.mjs +35 -0
- package/lib/chunks/mime-types.mjs +52 -0
- package/lib/chunks/not-found-wrapper.qwik.mjs +25 -0
- package/lib/chunks/pathname.mjs +105 -0
- package/lib/chunks/redirect-handler.mjs +6 -0
- package/lib/chunks/routing.qwik.mjs +820 -0
- package/lib/chunks/system.mjs +333 -0
- package/lib/chunks/use-functions.qwik.mjs +35 -0
- package/lib/chunks/worker-thread.qwik.mjs +2572 -0
- package/lib/index.d.ts +358 -141
- package/lib/index.qwik.mjs +865 -1156
- package/lib/middleware/aws-lambda/index.d.ts +3 -2
- package/lib/middleware/aws-lambda/index.mjs +15 -13
- package/lib/middleware/azure-swa/index.mjs +17 -218
- package/lib/middleware/bun/index.d.ts +11 -0
- package/lib/middleware/bun/index.mjs +51 -94
- package/lib/middleware/cloudflare-pages/index.mjs +23 -28
- package/lib/middleware/deno/index.d.ts +11 -0
- package/lib/middleware/deno/index.mjs +50 -94
- package/lib/middleware/firebase/index.mjs +7 -11
- package/lib/middleware/netlify-edge/index.mjs +23 -29
- package/lib/middleware/node/index.mjs +31 -100
- package/lib/middleware/request-handler/index.d.ts +161 -83
- package/lib/middleware/request-handler/index.mjs +1458 -1257
- package/lib/middleware/vercel-edge/index.mjs +28 -33
- package/lib/modules.d.ts +11 -16
- package/lib/service-worker/index.mjs +4 -0
- package/lib/{static → ssg}/index.d.ts +45 -13
- package/lib/ssg/index.mjs +336 -0
- package/lib/vite/index.d.ts +38 -10
- package/lib/vite/index.mjs +2067 -26841
- package/modules.d.ts +11 -16
- package/package.json +62 -67
- package/ssg.d.ts +2 -0
- package/static.d.ts +1 -1
- package/lib/adapters/azure-swa/vite/index.cjs +0 -96
- package/lib/adapters/bun-server/vite/index.cjs +0 -50
- package/lib/adapters/cloud-run/vite/index.cjs +0 -47
- package/lib/adapters/cloudflare-pages/vite/index.cjs +0 -115
- package/lib/adapters/deno-server/vite/index.cjs +0 -62
- package/lib/adapters/netlify-edge/vite/index.cjs +0 -129
- package/lib/adapters/node-server/vite/index.cjs +0 -50
- package/lib/adapters/shared/vite/index.cjs +0 -378
- package/lib/adapters/static/vite/index.cjs +0 -368
- package/lib/adapters/static/vite/index.d.ts +0 -10
- package/lib/adapters/static/vite/index.mjs +0 -331
- package/lib/adapters/vercel-edge/vite/index.cjs +0 -118
- package/lib/index.qwik.cjs +0 -1947
- package/lib/middleware/node/index.cjs +0 -314
- package/lib/middleware/request-handler/index.cjs +0 -1614
- package/lib/service-worker.cjs +0 -17
- package/lib/service-worker.mjs +0 -15
- package/lib/static/deno.mjs +0 -8
- package/lib/static/index.cjs +0 -67
- package/lib/static/index.mjs +0 -48
- package/lib/static/node.cjs +0 -1124
- package/lib/static/node.mjs +0 -1086
- package/lib/vite/index.cjs +0 -27445
- package/middleware/request-handler/generated/not-found-paths.ts +0 -7
- package/middleware/request-handler/generated/static-paths.ts +0 -35
|
@@ -0,0 +1,2572 @@
|
|
|
1
|
+
import { parentPort } from 'node:worker_threads';
|
|
2
|
+
import { isDev, _UNINITIALIZED, _deserialize, _verifySerializable, _serialize } from '@qwik.dev/core/internal';
|
|
3
|
+
import { withLocale, inlinedQrl } from '@qwik.dev/core';
|
|
4
|
+
import { A as AbortMessage$1 } from './redirect-handler.mjs';
|
|
5
|
+
import { isServer } from '@qwik.dev/core/build';
|
|
6
|
+
import { d as deepFreeze } from './deepFreeze.qwik.mjs';
|
|
7
|
+
|
|
8
|
+
const QACTION_KEY = "qaction";
|
|
9
|
+
const QLOADER_KEY = "qloaders";
|
|
10
|
+
const QFN_KEY = "qfunc";
|
|
11
|
+
const QDATA_KEY = "qdata";
|
|
12
|
+
const Q_ROUTE = "q:route";
|
|
13
|
+
|
|
14
|
+
const mergeArray = (existingArr, newArr) => {
|
|
15
|
+
if (Array.isArray(newArr)) {
|
|
16
|
+
for (const newItem of newArr) {
|
|
17
|
+
if (typeof newItem.key === "string") {
|
|
18
|
+
const existingIndex = existingArr.findIndex((i) => i.key === newItem.key);
|
|
19
|
+
if (existingIndex > -1) {
|
|
20
|
+
existingArr[existingIndex] = newItem;
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
existingArr.push(newItem);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
const resolveDocumentHead = (resolvedHead, updatedHead) => {
|
|
29
|
+
if (typeof updatedHead.title === "string") {
|
|
30
|
+
resolvedHead.title = updatedHead.title;
|
|
31
|
+
}
|
|
32
|
+
mergeArray(resolvedHead.meta, updatedHead.meta);
|
|
33
|
+
mergeArray(resolvedHead.links, updatedHead.links);
|
|
34
|
+
mergeArray(resolvedHead.styles, updatedHead.styles);
|
|
35
|
+
mergeArray(resolvedHead.scripts, updatedHead.scripts);
|
|
36
|
+
Object.assign(resolvedHead.frontmatter, updatedHead.frontmatter);
|
|
37
|
+
};
|
|
38
|
+
const createDocumentHead = (defaults) => ({
|
|
39
|
+
title: defaults?.title || "",
|
|
40
|
+
meta: [
|
|
41
|
+
...defaults?.meta || []
|
|
42
|
+
],
|
|
43
|
+
links: [
|
|
44
|
+
...defaults?.links || []
|
|
45
|
+
],
|
|
46
|
+
styles: [
|
|
47
|
+
...defaults?.styles || []
|
|
48
|
+
],
|
|
49
|
+
scripts: [
|
|
50
|
+
...defaults?.scripts || []
|
|
51
|
+
],
|
|
52
|
+
frontmatter: {
|
|
53
|
+
...defaults?.frontmatter
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
const resolveRouteConfig = (resolveValue, routeLocation, contentModules, locale, status, defaults) => withLocale(locale, () => {
|
|
57
|
+
const head = createDocumentHead(defaults);
|
|
58
|
+
let eTag;
|
|
59
|
+
let cacheKey;
|
|
60
|
+
const fns = [];
|
|
61
|
+
for (let i = 0; i < contentModules.length; i++) {
|
|
62
|
+
const contentModule = contentModules[i];
|
|
63
|
+
if (!contentModule) {
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
const isLast = i === contentModules.length - 1;
|
|
67
|
+
let config;
|
|
68
|
+
if (contentModule.routeConfig) {
|
|
69
|
+
config = contentModule.routeConfig;
|
|
70
|
+
} else if (contentModule.head) {
|
|
71
|
+
const synthetic = {
|
|
72
|
+
head: void 0
|
|
73
|
+
};
|
|
74
|
+
const headExport = contentModule.head;
|
|
75
|
+
if (typeof headExport === "function") {
|
|
76
|
+
const mod = contentModule;
|
|
77
|
+
config = (props) => ({
|
|
78
|
+
head: headExport(props),
|
|
79
|
+
eTag: mod.eTag,
|
|
80
|
+
cacheKey: mod.cacheKey
|
|
81
|
+
});
|
|
82
|
+
} else {
|
|
83
|
+
synthetic.head = headExport;
|
|
84
|
+
const mod = contentModule;
|
|
85
|
+
if (mod.eTag !== void 0) {
|
|
86
|
+
synthetic.eTag = mod.eTag;
|
|
87
|
+
}
|
|
88
|
+
if (mod.cacheKey !== void 0) {
|
|
89
|
+
synthetic.cacheKey = mod.cacheKey;
|
|
90
|
+
}
|
|
91
|
+
config = synthetic;
|
|
92
|
+
}
|
|
93
|
+
} else {
|
|
94
|
+
const mod = contentModule;
|
|
95
|
+
if (mod.eTag !== void 0 || mod.cacheKey !== void 0) {
|
|
96
|
+
config = {
|
|
97
|
+
eTag: mod.eTag,
|
|
98
|
+
cacheKey: mod.cacheKey
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
if (!config) {
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
if (typeof config === "function") {
|
|
106
|
+
fns.unshift({
|
|
107
|
+
fn: config,
|
|
108
|
+
isLast
|
|
109
|
+
});
|
|
110
|
+
} else {
|
|
111
|
+
if (config.head) {
|
|
112
|
+
resolveDocumentHead(head, config.head);
|
|
113
|
+
}
|
|
114
|
+
if (config.eTag !== void 0) {
|
|
115
|
+
eTag = config.eTag;
|
|
116
|
+
}
|
|
117
|
+
if (config.cacheKey !== void 0) {
|
|
118
|
+
cacheKey = config.cacheKey;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
if (fns.length) {
|
|
123
|
+
const headProps = {
|
|
124
|
+
head,
|
|
125
|
+
status,
|
|
126
|
+
withLocale: (fn) => fn(),
|
|
127
|
+
resolveValue,
|
|
128
|
+
...routeLocation
|
|
129
|
+
};
|
|
130
|
+
for (const { fn } of fns) {
|
|
131
|
+
const result = fn(headProps);
|
|
132
|
+
if (result.head) {
|
|
133
|
+
resolveDocumentHead(head, result.head);
|
|
134
|
+
}
|
|
135
|
+
if (result.eTag !== void 0) {
|
|
136
|
+
eTag = result.eTag;
|
|
137
|
+
}
|
|
138
|
+
if (result.cacheKey !== void 0) {
|
|
139
|
+
cacheKey = result.cacheKey;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return {
|
|
144
|
+
head,
|
|
145
|
+
eTag,
|
|
146
|
+
cacheKey
|
|
147
|
+
};
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
const MODULE_CACHE = /* @__PURE__ */ new WeakMap();
|
|
151
|
+
const httpErrorLoader = () => import('./http-error.qwik.mjs');
|
|
152
|
+
function walkTrieKeys(root, keys) {
|
|
153
|
+
let node = root;
|
|
154
|
+
const layouts = [];
|
|
155
|
+
if (node._L) {
|
|
156
|
+
layouts.push(node._L);
|
|
157
|
+
}
|
|
158
|
+
for (const key of keys) {
|
|
159
|
+
let next = node[key];
|
|
160
|
+
if (!next && node._M) {
|
|
161
|
+
for (const group of node._M) {
|
|
162
|
+
next = group[key];
|
|
163
|
+
if (next) {
|
|
164
|
+
if (group._L) {
|
|
165
|
+
layouts.push(group._L);
|
|
166
|
+
}
|
|
167
|
+
break;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
if (!next) {
|
|
172
|
+
return void 0;
|
|
173
|
+
}
|
|
174
|
+
node = next;
|
|
175
|
+
if (node._L) {
|
|
176
|
+
layouts.push(node._L);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return {
|
|
180
|
+
node,
|
|
181
|
+
layouts
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
function collectNodeMeta(node, groups, layouts, errorLoaderRef, notFoundLoaderRef, menuLoaderRef) {
|
|
185
|
+
for (const g of groups) {
|
|
186
|
+
if (g._L) {
|
|
187
|
+
layouts.push(g._L);
|
|
188
|
+
}
|
|
189
|
+
if (g._E) {
|
|
190
|
+
errorLoaderRef.v = g._E;
|
|
191
|
+
}
|
|
192
|
+
if (g._4) {
|
|
193
|
+
notFoundLoaderRef.v = g._4;
|
|
194
|
+
}
|
|
195
|
+
if (g._N) {
|
|
196
|
+
menuLoaderRef.v = g._N;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
if (node._L) {
|
|
200
|
+
layouts.push(node._L);
|
|
201
|
+
}
|
|
202
|
+
if (node._E) {
|
|
203
|
+
errorLoaderRef.v = node._E;
|
|
204
|
+
}
|
|
205
|
+
if (node._4) {
|
|
206
|
+
notFoundLoaderRef.v = node._4;
|
|
207
|
+
}
|
|
208
|
+
if (node._N) {
|
|
209
|
+
menuLoaderRef.v = node._N;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
function tryWildcardMatch(node, part, partLower, parts, partIndex, params) {
|
|
213
|
+
let next = node._W;
|
|
214
|
+
if (next) {
|
|
215
|
+
const prefix = next._0;
|
|
216
|
+
const suffix = next._9;
|
|
217
|
+
if (prefix || suffix) {
|
|
218
|
+
const pre = prefix || "";
|
|
219
|
+
const suf = suffix || "";
|
|
220
|
+
if (partLower.length > pre.length + suf.length && (!pre || partLower.startsWith(pre.toLowerCase())) && (!suf || partLower.endsWith(suf.toLowerCase()))) {
|
|
221
|
+
const paramName = next._P;
|
|
222
|
+
const value = part.slice(pre.length, suf ? part.length - suf.length : void 0);
|
|
223
|
+
params[paramName] = value;
|
|
224
|
+
return {
|
|
225
|
+
next,
|
|
226
|
+
routePart: `${pre}[${paramName}]${suf}`,
|
|
227
|
+
done: false
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
} else {
|
|
231
|
+
const paramName = next._P;
|
|
232
|
+
params[paramName] = part;
|
|
233
|
+
return {
|
|
234
|
+
next,
|
|
235
|
+
routePart: `[${paramName}]`,
|
|
236
|
+
done: false
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
next = node._A;
|
|
241
|
+
if (next) {
|
|
242
|
+
const paramName = next._P;
|
|
243
|
+
const restValue = parts.slice(partIndex).join("/");
|
|
244
|
+
params[paramName] = restValue;
|
|
245
|
+
return {
|
|
246
|
+
next,
|
|
247
|
+
routePart: `[...${paramName}]`,
|
|
248
|
+
done: true
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
return void 0;
|
|
252
|
+
}
|
|
253
|
+
function findChild(node, part, partLower, parts, partIndex, params) {
|
|
254
|
+
const exact = node[partLower];
|
|
255
|
+
if (exact) {
|
|
256
|
+
return {
|
|
257
|
+
next: exact,
|
|
258
|
+
groups: [],
|
|
259
|
+
routePart: part,
|
|
260
|
+
done: false
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
if (node._M) {
|
|
264
|
+
for (const group of node._M) {
|
|
265
|
+
const groupResult = findChild(group, part, partLower, parts, partIndex, params);
|
|
266
|
+
if (groupResult) {
|
|
267
|
+
groupResult.groups.unshift(group);
|
|
268
|
+
return groupResult;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
const wildcard = tryWildcardMatch(node, part, partLower, parts, partIndex, params);
|
|
273
|
+
if (wildcard) {
|
|
274
|
+
return {
|
|
275
|
+
...wildcard,
|
|
276
|
+
groups: []
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
return void 0;
|
|
280
|
+
}
|
|
281
|
+
function findIndexNode(node) {
|
|
282
|
+
if (node._I || node._G) {
|
|
283
|
+
return {
|
|
284
|
+
target: node,
|
|
285
|
+
groups: []
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
if (node._M) {
|
|
289
|
+
for (const group of node._M) {
|
|
290
|
+
const result = findIndexNode(group);
|
|
291
|
+
if (result) {
|
|
292
|
+
if (result.target !== group) {
|
|
293
|
+
result.groups.unshift(group);
|
|
294
|
+
}
|
|
295
|
+
return result;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
return void 0;
|
|
300
|
+
}
|
|
301
|
+
function resolveLoaders(root, node, gatheredLayouts) {
|
|
302
|
+
if (node._G) {
|
|
303
|
+
const keys = node._G.split("/").filter((p) => p.length > 0);
|
|
304
|
+
const target = walkTrieKeys(root, keys);
|
|
305
|
+
if (!target) {
|
|
306
|
+
return void 0;
|
|
307
|
+
}
|
|
308
|
+
let targetNode = target.node;
|
|
309
|
+
const targetLayouts = target.layouts;
|
|
310
|
+
if (!targetNode._I && !targetNode._G) {
|
|
311
|
+
const indexResult = findIndexNode(targetNode);
|
|
312
|
+
if (indexResult) {
|
|
313
|
+
for (const g of indexResult.groups) {
|
|
314
|
+
if (g._L) {
|
|
315
|
+
targetLayouts.push(g._L);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
targetNode = indexResult.target;
|
|
319
|
+
if (targetNode._L) {
|
|
320
|
+
targetLayouts.push(targetNode._L);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
return resolveLoaders(root, targetNode, targetLayouts);
|
|
325
|
+
}
|
|
326
|
+
const index = node._I;
|
|
327
|
+
if (!index) {
|
|
328
|
+
return void 0;
|
|
329
|
+
}
|
|
330
|
+
if (Array.isArray(index)) {
|
|
331
|
+
return index;
|
|
332
|
+
}
|
|
333
|
+
return [
|
|
334
|
+
...gatheredLayouts,
|
|
335
|
+
index
|
|
336
|
+
];
|
|
337
|
+
}
|
|
338
|
+
function findRestNode(node) {
|
|
339
|
+
if (node._A) {
|
|
340
|
+
return {
|
|
341
|
+
next: node._A,
|
|
342
|
+
groups: []
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
if (node._M) {
|
|
346
|
+
for (const group of node._M) {
|
|
347
|
+
const result = findRestNode(group);
|
|
348
|
+
if (result) {
|
|
349
|
+
result.groups.unshift(group);
|
|
350
|
+
return result;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
return void 0;
|
|
355
|
+
}
|
|
356
|
+
function matchRouteTree(root = {}, pathname) {
|
|
357
|
+
let node = root;
|
|
358
|
+
const params = {};
|
|
359
|
+
const routeParts = [];
|
|
360
|
+
const layouts = [];
|
|
361
|
+
const errorLoaderRef = {
|
|
362
|
+
v: void 0
|
|
363
|
+
};
|
|
364
|
+
const notFoundLoaderRef = {
|
|
365
|
+
v: void 0
|
|
366
|
+
};
|
|
367
|
+
const menuLoaderRef = {
|
|
368
|
+
v: void 0
|
|
369
|
+
};
|
|
370
|
+
if (root._L) {
|
|
371
|
+
layouts.push(root._L);
|
|
372
|
+
}
|
|
373
|
+
if (root._E) {
|
|
374
|
+
errorLoaderRef.v = root._E;
|
|
375
|
+
}
|
|
376
|
+
if (root._4) {
|
|
377
|
+
notFoundLoaderRef.v = root._4;
|
|
378
|
+
}
|
|
379
|
+
if (root._N) {
|
|
380
|
+
menuLoaderRef.v = root._N;
|
|
381
|
+
}
|
|
382
|
+
let done = false;
|
|
383
|
+
let matched = true;
|
|
384
|
+
const parts = pathname.split("/").filter((p) => p.length > 0).map(decodeURIComponent);
|
|
385
|
+
let restFallback;
|
|
386
|
+
let i = 0;
|
|
387
|
+
const len = parts.length;
|
|
388
|
+
for (; !done && i < len; i++) {
|
|
389
|
+
const part = parts[i];
|
|
390
|
+
const partLower = part.toLowerCase();
|
|
391
|
+
const restInfo = findRestNode(node);
|
|
392
|
+
if (restInfo) {
|
|
393
|
+
restFallback = {
|
|
394
|
+
aNode: restInfo.next,
|
|
395
|
+
groups: restInfo.groups,
|
|
396
|
+
paramName: restInfo.next._P,
|
|
397
|
+
restValue: parts.slice(i).join("/"),
|
|
398
|
+
routeParts: [
|
|
399
|
+
...routeParts
|
|
400
|
+
],
|
|
401
|
+
params: {
|
|
402
|
+
...params
|
|
403
|
+
},
|
|
404
|
+
layouts: [
|
|
405
|
+
...layouts
|
|
406
|
+
],
|
|
407
|
+
errorLoader: errorLoaderRef.v,
|
|
408
|
+
notFoundLoader: notFoundLoaderRef.v,
|
|
409
|
+
menuLoader: menuLoaderRef.v
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
const found = findChild(node, part, partLower, parts, i, params);
|
|
413
|
+
if (!found) {
|
|
414
|
+
matched = false;
|
|
415
|
+
break;
|
|
416
|
+
}
|
|
417
|
+
routeParts.push(found.routePart);
|
|
418
|
+
done = found.done;
|
|
419
|
+
node = found.next;
|
|
420
|
+
collectNodeMeta(node, found.groups, layouts, errorLoaderRef, notFoundLoaderRef, menuLoaderRef);
|
|
421
|
+
}
|
|
422
|
+
if (matched && !done && i === len) {
|
|
423
|
+
if (!node._I && !node._G) {
|
|
424
|
+
const indexResult = findIndexNode(node);
|
|
425
|
+
if (indexResult) {
|
|
426
|
+
collectNodeMeta(indexResult.target, indexResult.groups, layouts, errorLoaderRef, notFoundLoaderRef, menuLoaderRef);
|
|
427
|
+
node = indexResult.target;
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
if (!node._I && !node._G && node._A) {
|
|
431
|
+
const next = node._A;
|
|
432
|
+
const paramName = next._P;
|
|
433
|
+
params[paramName] = "";
|
|
434
|
+
routeParts.push(`[...${paramName}]`);
|
|
435
|
+
node = next;
|
|
436
|
+
if (node._L) {
|
|
437
|
+
layouts.push(node._L);
|
|
438
|
+
}
|
|
439
|
+
if (node._N) {
|
|
440
|
+
menuLoaderRef.v = node._N;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
if (!node._I && !node._G) {
|
|
444
|
+
const restInfo = findRestNode(node);
|
|
445
|
+
if (restInfo) {
|
|
446
|
+
const next = restInfo.next;
|
|
447
|
+
const paramName = next._P;
|
|
448
|
+
params[paramName] = "";
|
|
449
|
+
routeParts.push(`[...${paramName}]`);
|
|
450
|
+
collectNodeMeta(next, restInfo.groups, layouts, errorLoaderRef, notFoundLoaderRef, menuLoaderRef);
|
|
451
|
+
node = next;
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
const loaders = matched && (done || i >= len) ? resolveLoaders(root, node, layouts) : void 0;
|
|
456
|
+
if (!loaders && restFallback) {
|
|
457
|
+
const fb = restFallback;
|
|
458
|
+
const fbParams = {
|
|
459
|
+
...fb.params,
|
|
460
|
+
[fb.paramName]: fb.restValue
|
|
461
|
+
};
|
|
462
|
+
const fbRouteParts = [
|
|
463
|
+
...fb.routeParts,
|
|
464
|
+
`[...${fb.paramName}]`
|
|
465
|
+
];
|
|
466
|
+
const fbLayouts = [
|
|
467
|
+
...fb.layouts
|
|
468
|
+
];
|
|
469
|
+
const fbErrorRef = {
|
|
470
|
+
v: fb.errorLoader
|
|
471
|
+
};
|
|
472
|
+
const fbNotFoundRef = {
|
|
473
|
+
v: fb.notFoundLoader
|
|
474
|
+
};
|
|
475
|
+
const fbMenuRef = {
|
|
476
|
+
v: fb.menuLoader
|
|
477
|
+
};
|
|
478
|
+
collectNodeMeta(fb.aNode, fb.groups, fbLayouts, fbErrorRef, fbNotFoundRef, fbMenuRef);
|
|
479
|
+
const fbLoaders = resolveLoaders(root, fb.aNode, fbLayouts);
|
|
480
|
+
if (fbLoaders) {
|
|
481
|
+
return {
|
|
482
|
+
loaders: fbLoaders,
|
|
483
|
+
params: fbParams,
|
|
484
|
+
routeParts: fbRouteParts,
|
|
485
|
+
notFound: false,
|
|
486
|
+
routeBundleNames: fb.aNode._B,
|
|
487
|
+
menuLoader: fbMenuRef.v,
|
|
488
|
+
errorLoader: fbErrorRef.v,
|
|
489
|
+
notFoundLoader: fbNotFoundRef.v
|
|
490
|
+
};
|
|
491
|
+
}
|
|
492
|
+
errorLoaderRef.v = fbErrorRef.v;
|
|
493
|
+
notFoundLoaderRef.v = fbNotFoundRef.v;
|
|
494
|
+
menuLoaderRef.v = fbMenuRef.v;
|
|
495
|
+
}
|
|
496
|
+
if (!loaders) {
|
|
497
|
+
const loader = notFoundLoaderRef.v || errorLoaderRef.v || httpErrorLoader;
|
|
498
|
+
return {
|
|
499
|
+
loaders: [
|
|
500
|
+
loader
|
|
501
|
+
],
|
|
502
|
+
params,
|
|
503
|
+
routeParts,
|
|
504
|
+
notFound: true,
|
|
505
|
+
routeBundleNames: void 0,
|
|
506
|
+
menuLoader: menuLoaderRef.v,
|
|
507
|
+
errorLoader: errorLoaderRef.v,
|
|
508
|
+
notFoundLoader: notFoundLoaderRef.v
|
|
509
|
+
};
|
|
510
|
+
}
|
|
511
|
+
return {
|
|
512
|
+
loaders,
|
|
513
|
+
params,
|
|
514
|
+
routeParts,
|
|
515
|
+
notFound: false,
|
|
516
|
+
routeBundleNames: node._B,
|
|
517
|
+
menuLoader: menuLoaderRef.v,
|
|
518
|
+
errorLoader: errorLoaderRef.v,
|
|
519
|
+
notFoundLoader: notFoundLoaderRef.v
|
|
520
|
+
};
|
|
521
|
+
}
|
|
522
|
+
const loadModule = (moduleLoader, pendingLoads, moduleSetter, cacheModules) => {
|
|
523
|
+
if (typeof moduleLoader === "function") {
|
|
524
|
+
const loadedModule = MODULE_CACHE.get(moduleLoader);
|
|
525
|
+
if (loadedModule) {
|
|
526
|
+
moduleSetter(loadedModule);
|
|
527
|
+
} else {
|
|
528
|
+
const moduleOrPromise = moduleLoader();
|
|
529
|
+
if (typeof moduleOrPromise.then === "function") {
|
|
530
|
+
pendingLoads.push(moduleOrPromise.then((loadedModule2) => {
|
|
531
|
+
if (cacheModules !== false) {
|
|
532
|
+
MODULE_CACHE.set(moduleLoader, loadedModule2);
|
|
533
|
+
}
|
|
534
|
+
moduleSetter(loadedModule2);
|
|
535
|
+
}));
|
|
536
|
+
} else if (moduleOrPromise) {
|
|
537
|
+
moduleSetter(moduleOrPromise);
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
};
|
|
542
|
+
const loadRoute = async (routes, cacheModules, pathname, isInternal) => {
|
|
543
|
+
const result = matchRouteTree(routes, pathname);
|
|
544
|
+
const { loaders, params, routeParts, notFound, routeBundleNames, menuLoader, errorLoader, notFoundLoader } = result;
|
|
545
|
+
const routeName = "/" + routeParts.join("/");
|
|
546
|
+
const modules = new Array(loaders.length);
|
|
547
|
+
const pendingLoads = [];
|
|
548
|
+
loaders.forEach((moduleLoader, i) => {
|
|
549
|
+
loadModule(moduleLoader, pendingLoads, (routeModule) => modules[i] = routeModule, cacheModules);
|
|
550
|
+
});
|
|
551
|
+
let menu = void 0;
|
|
552
|
+
if (!isInternal) {
|
|
553
|
+
loadModule(menuLoader, pendingLoads, (menuModule) => menu = menuModule?.default, cacheModules);
|
|
554
|
+
}
|
|
555
|
+
if (notFound && notFoundLoader) {
|
|
556
|
+
let notFoundMod;
|
|
557
|
+
let errorMod;
|
|
558
|
+
loadModule(notFoundLoader, pendingLoads, (mod) => notFoundMod = mod, cacheModules);
|
|
559
|
+
loadModule(errorLoader || httpErrorLoader, pendingLoads, (mod) => errorMod = mod, cacheModules);
|
|
560
|
+
if (pendingLoads.length > 0) {
|
|
561
|
+
await Promise.all(pendingLoads);
|
|
562
|
+
}
|
|
563
|
+
const { createNotFoundWrapper } = await import('./not-found-wrapper.qwik.mjs');
|
|
564
|
+
const wrapperModule = createNotFoundWrapper(notFoundMod, errorMod);
|
|
565
|
+
return {
|
|
566
|
+
$routeName$: routeName,
|
|
567
|
+
$params$: params,
|
|
568
|
+
$mods$: [
|
|
569
|
+
wrapperModule
|
|
570
|
+
],
|
|
571
|
+
$menu$: deepFreeze(menu),
|
|
572
|
+
$routeBundleNames$: routeBundleNames,
|
|
573
|
+
$notFound$: notFound,
|
|
574
|
+
$errorLoader$: errorLoader
|
|
575
|
+
};
|
|
576
|
+
}
|
|
577
|
+
if (pendingLoads.length > 0) {
|
|
578
|
+
await Promise.all(pendingLoads);
|
|
579
|
+
}
|
|
580
|
+
return {
|
|
581
|
+
$routeName$: routeName,
|
|
582
|
+
$params$: params,
|
|
583
|
+
$mods$: modules,
|
|
584
|
+
$menu$: deepFreeze(menu),
|
|
585
|
+
$routeBundleNames$: routeBundleNames,
|
|
586
|
+
$notFound$: notFound,
|
|
587
|
+
$errorLoader$: errorLoader
|
|
588
|
+
};
|
|
589
|
+
};
|
|
590
|
+
|
|
591
|
+
const isPromise = (value) => {
|
|
592
|
+
return value && typeof value.then === "function";
|
|
593
|
+
};
|
|
594
|
+
|
|
595
|
+
const MAX_CACHE_SIZE = typeof globalThis.__SSR_CACHE_SIZE__ === "number" ? globalThis.__SSR_CACHE_SIZE__ : 50;
|
|
596
|
+
const ssrCache = /* @__PURE__ */ new Map();
|
|
597
|
+
function resolveETag(eTagExport, headProps) {
|
|
598
|
+
if (eTagExport === void 0) {
|
|
599
|
+
return null;
|
|
600
|
+
}
|
|
601
|
+
if (typeof eTagExport === "function") {
|
|
602
|
+
return eTagExport(headProps);
|
|
603
|
+
}
|
|
604
|
+
return eTagExport;
|
|
605
|
+
}
|
|
606
|
+
function resolveCacheKey(cacheKeyExport, status, eTag, pathname) {
|
|
607
|
+
if (cacheKeyExport === true) {
|
|
608
|
+
return `${status}|${eTag}|${pathname}`;
|
|
609
|
+
}
|
|
610
|
+
if (typeof cacheKeyExport !== "function") {
|
|
611
|
+
return null;
|
|
612
|
+
}
|
|
613
|
+
return cacheKeyExport(status, eTag, pathname);
|
|
614
|
+
}
|
|
615
|
+
function getCachedHtml(key) {
|
|
616
|
+
const html = ssrCache.get(key);
|
|
617
|
+
if (html !== void 0) {
|
|
618
|
+
ssrCache.delete(key);
|
|
619
|
+
ssrCache.set(key, html);
|
|
620
|
+
}
|
|
621
|
+
return html;
|
|
622
|
+
}
|
|
623
|
+
function setCachedHtml(key, html) {
|
|
624
|
+
if (MAX_CACHE_SIZE <= 0) {
|
|
625
|
+
return;
|
|
626
|
+
}
|
|
627
|
+
if (ssrCache.size >= MAX_CACHE_SIZE) {
|
|
628
|
+
const firstKey = ssrCache.keys().next().value;
|
|
629
|
+
ssrCache.delete(firstKey);
|
|
630
|
+
}
|
|
631
|
+
ssrCache.set(key, html);
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
var HttpStatus = /* @__PURE__ */ (function(HttpStatus2) {
|
|
635
|
+
HttpStatus2[HttpStatus2["Continue"] = 100] = "Continue";
|
|
636
|
+
HttpStatus2[HttpStatus2["SwitchingProtocols"] = 101] = "SwitchingProtocols";
|
|
637
|
+
HttpStatus2[HttpStatus2["Processing"] = 102] = "Processing";
|
|
638
|
+
HttpStatus2[HttpStatus2["Ok"] = 200] = "Ok";
|
|
639
|
+
HttpStatus2[HttpStatus2["Created"] = 201] = "Created";
|
|
640
|
+
HttpStatus2[HttpStatus2["Accepted"] = 202] = "Accepted";
|
|
641
|
+
HttpStatus2[HttpStatus2["NonAuthoritativeInformation"] = 203] = "NonAuthoritativeInformation";
|
|
642
|
+
HttpStatus2[HttpStatus2["NoContent"] = 204] = "NoContent";
|
|
643
|
+
HttpStatus2[HttpStatus2["ResetContent"] = 205] = "ResetContent";
|
|
644
|
+
HttpStatus2[HttpStatus2["PartialContent"] = 206] = "PartialContent";
|
|
645
|
+
HttpStatus2[HttpStatus2["MultiStatus"] = 207] = "MultiStatus";
|
|
646
|
+
HttpStatus2[HttpStatus2["AlreadyReported"] = 208] = "AlreadyReported";
|
|
647
|
+
HttpStatus2[HttpStatus2["ImUsed"] = 226] = "ImUsed";
|
|
648
|
+
HttpStatus2[HttpStatus2["MultipleChoices"] = 300] = "MultipleChoices";
|
|
649
|
+
HttpStatus2[HttpStatus2["MovedPermanently"] = 301] = "MovedPermanently";
|
|
650
|
+
HttpStatus2[HttpStatus2["Found"] = 302] = "Found";
|
|
651
|
+
HttpStatus2[HttpStatus2["SeeOther"] = 303] = "SeeOther";
|
|
652
|
+
HttpStatus2[HttpStatus2["NotModified"] = 304] = "NotModified";
|
|
653
|
+
HttpStatus2[HttpStatus2["UseProxy"] = 305] = "UseProxy";
|
|
654
|
+
HttpStatus2[HttpStatus2["SwitchProxy"] = 306] = "SwitchProxy";
|
|
655
|
+
HttpStatus2[HttpStatus2["TemporaryRedirect"] = 307] = "TemporaryRedirect";
|
|
656
|
+
HttpStatus2[HttpStatus2["PermanentRedirect"] = 308] = "PermanentRedirect";
|
|
657
|
+
HttpStatus2[HttpStatus2["BadRequest"] = 400] = "BadRequest";
|
|
658
|
+
HttpStatus2[HttpStatus2["Unauthorized"] = 401] = "Unauthorized";
|
|
659
|
+
HttpStatus2[HttpStatus2["PaymentRequired"] = 402] = "PaymentRequired";
|
|
660
|
+
HttpStatus2[HttpStatus2["Forbidden"] = 403] = "Forbidden";
|
|
661
|
+
HttpStatus2[HttpStatus2["NotFound"] = 404] = "NotFound";
|
|
662
|
+
HttpStatus2[HttpStatus2["MethodNotAllowed"] = 405] = "MethodNotAllowed";
|
|
663
|
+
HttpStatus2[HttpStatus2["NotAcceptable"] = 406] = "NotAcceptable";
|
|
664
|
+
HttpStatus2[HttpStatus2["ProxyAuthenticationRequired"] = 407] = "ProxyAuthenticationRequired";
|
|
665
|
+
HttpStatus2[HttpStatus2["RequestTimeout"] = 408] = "RequestTimeout";
|
|
666
|
+
HttpStatus2[HttpStatus2["Conflict"] = 409] = "Conflict";
|
|
667
|
+
HttpStatus2[HttpStatus2["Gone"] = 410] = "Gone";
|
|
668
|
+
HttpStatus2[HttpStatus2["LengthRequired"] = 411] = "LengthRequired";
|
|
669
|
+
HttpStatus2[HttpStatus2["PreconditionFailed"] = 412] = "PreconditionFailed";
|
|
670
|
+
HttpStatus2[HttpStatus2["PayloadTooLarge"] = 413] = "PayloadTooLarge";
|
|
671
|
+
HttpStatus2[HttpStatus2["UriTooLong"] = 414] = "UriTooLong";
|
|
672
|
+
HttpStatus2[HttpStatus2["UnsupportedMediaType"] = 415] = "UnsupportedMediaType";
|
|
673
|
+
HttpStatus2[HttpStatus2["RangeNotSatisfiable"] = 416] = "RangeNotSatisfiable";
|
|
674
|
+
HttpStatus2[HttpStatus2["ExpectationFailed"] = 417] = "ExpectationFailed";
|
|
675
|
+
HttpStatus2[HttpStatus2["IAmATeapot"] = 418] = "IAmATeapot";
|
|
676
|
+
HttpStatus2[HttpStatus2["MisdirectedRequest"] = 421] = "MisdirectedRequest";
|
|
677
|
+
HttpStatus2[HttpStatus2["UnprocessableEntity"] = 422] = "UnprocessableEntity";
|
|
678
|
+
HttpStatus2[HttpStatus2["Locked"] = 423] = "Locked";
|
|
679
|
+
HttpStatus2[HttpStatus2["FailedDependency"] = 424] = "FailedDependency";
|
|
680
|
+
HttpStatus2[HttpStatus2["UpgradeRequired"] = 426] = "UpgradeRequired";
|
|
681
|
+
HttpStatus2[HttpStatus2["PreconditionRequired"] = 428] = "PreconditionRequired";
|
|
682
|
+
HttpStatus2[HttpStatus2["TooManyRequests"] = 429] = "TooManyRequests";
|
|
683
|
+
HttpStatus2[HttpStatus2["RequestHeaderFieldsTooLarge"] = 431] = "RequestHeaderFieldsTooLarge";
|
|
684
|
+
HttpStatus2[HttpStatus2["UnavailableForLegalReasons"] = 451] = "UnavailableForLegalReasons";
|
|
685
|
+
HttpStatus2[HttpStatus2["InternalServerError"] = 500] = "InternalServerError";
|
|
686
|
+
HttpStatus2[HttpStatus2["NotImplemented"] = 501] = "NotImplemented";
|
|
687
|
+
HttpStatus2[HttpStatus2["BadGateway"] = 502] = "BadGateway";
|
|
688
|
+
HttpStatus2[HttpStatus2["ServiceUnavailable"] = 503] = "ServiceUnavailable";
|
|
689
|
+
HttpStatus2[HttpStatus2["GatewayTimeout"] = 504] = "GatewayTimeout";
|
|
690
|
+
HttpStatus2[HttpStatus2["HttpVersionNotSupported"] = 505] = "HttpVersionNotSupported";
|
|
691
|
+
HttpStatus2[HttpStatus2["VariantAlsoNegotiates"] = 506] = "VariantAlsoNegotiates";
|
|
692
|
+
HttpStatus2[HttpStatus2["InsufficientStorage"] = 507] = "InsufficientStorage";
|
|
693
|
+
HttpStatus2[HttpStatus2["LoopDetected"] = 508] = "LoopDetected";
|
|
694
|
+
HttpStatus2[HttpStatus2["NotExtended"] = 510] = "NotExtended";
|
|
695
|
+
HttpStatus2[HttpStatus2["NetworkAuthenticationRequired"] = 511] = "NetworkAuthenticationRequired";
|
|
696
|
+
return HttpStatus2;
|
|
697
|
+
})({});
|
|
698
|
+
|
|
699
|
+
const RequestEvLoaders = /* @__PURE__ */ Symbol("RequestEvLoaders");
|
|
700
|
+
const RequestEvMode = /* @__PURE__ */ Symbol("RequestEvMode");
|
|
701
|
+
const RequestEvRoute = /* @__PURE__ */ Symbol("RequestEvRoute");
|
|
702
|
+
const RequestEvLoaderSerializationStrategyMap = /* @__PURE__ */ Symbol("RequestEvLoaderSerializationStrategyMap");
|
|
703
|
+
const RequestRouteName = "@routeName";
|
|
704
|
+
const RequestEvSharedActionId = "@actionId";
|
|
705
|
+
const RequestEvSharedActionFormData = "@actionFormData";
|
|
706
|
+
const RequestEvSharedNonce = "@nonce";
|
|
707
|
+
const RequestEvIsRewrite = "@rewrite";
|
|
708
|
+
const RequestEvShareServerTiming = "@serverTiming";
|
|
709
|
+
const RequestEvETagCacheKey = "@eTagCacheKey";
|
|
710
|
+
const RequestEvHttpStatusMessage = "@httpStatusMessage";
|
|
711
|
+
const RequestEvShareQData = "qData";
|
|
712
|
+
function getRequestLoaders(requestEv) {
|
|
713
|
+
return requestEv[RequestEvLoaders];
|
|
714
|
+
}
|
|
715
|
+
function getRequestLoaderSerializationStrategyMap(requestEv) {
|
|
716
|
+
return requestEv[RequestEvLoaderSerializationStrategyMap];
|
|
717
|
+
}
|
|
718
|
+
function getRequestRoute(requestEv) {
|
|
719
|
+
return requestEv[RequestEvRoute];
|
|
720
|
+
}
|
|
721
|
+
function getRequestMode(requestEv) {
|
|
722
|
+
return requestEv[RequestEvMode];
|
|
723
|
+
}
|
|
724
|
+
const ABORT_INDEX = Number.MAX_SAFE_INTEGER;
|
|
725
|
+
const isDangerousKey = (k) => k === "__proto__" || k === "constructor" || k === "prototype";
|
|
726
|
+
const isArrayIndexKey = (k) => /^(0|[1-9]\d*)$/.test(k);
|
|
727
|
+
const getArrayPaths = (formData) => {
|
|
728
|
+
const arrayCandidates = /* @__PURE__ */ new Map();
|
|
729
|
+
for (const [name] of formData) {
|
|
730
|
+
const keys = name.split(".");
|
|
731
|
+
let hasDangerousKey = false;
|
|
732
|
+
for (const key of keys) {
|
|
733
|
+
if (isDangerousKey(key)) {
|
|
734
|
+
hasDangerousKey = true;
|
|
735
|
+
break;
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
if (hasDangerousKey) {
|
|
739
|
+
continue;
|
|
740
|
+
}
|
|
741
|
+
let path = "";
|
|
742
|
+
for (let i = 0; i < keys.length - 1; i++) {
|
|
743
|
+
const key = keys[i];
|
|
744
|
+
if (key.endsWith("[]")) {
|
|
745
|
+
break;
|
|
746
|
+
}
|
|
747
|
+
path = path ? `${path}.${key}` : key;
|
|
748
|
+
if (!arrayCandidates.has(path)) {
|
|
749
|
+
arrayCandidates.set(path, true);
|
|
750
|
+
}
|
|
751
|
+
if (!isArrayIndexKey(keys[i + 1])) {
|
|
752
|
+
arrayCandidates.set(path, false);
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
return new Set(Array.from(arrayCandidates.entries()).filter(([, isArrayPath]) => isArrayPath).map(([path]) => path));
|
|
757
|
+
};
|
|
758
|
+
const formToObj = (formData) => {
|
|
759
|
+
const values = /* @__PURE__ */ Object.create(null);
|
|
760
|
+
const arrayPaths = getArrayPaths(formData);
|
|
761
|
+
for (const [name, value] of formData) {
|
|
762
|
+
const keys = name.split(".");
|
|
763
|
+
let hasDangerousKey = false;
|
|
764
|
+
for (let i = 0; i < keys.length; i++) {
|
|
765
|
+
if (isDangerousKey(keys[i])) {
|
|
766
|
+
hasDangerousKey = true;
|
|
767
|
+
break;
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
if (hasDangerousKey) {
|
|
771
|
+
continue;
|
|
772
|
+
}
|
|
773
|
+
let object = values;
|
|
774
|
+
let path = "";
|
|
775
|
+
for (let i = 0; i < keys.length; i++) {
|
|
776
|
+
const key = keys[i];
|
|
777
|
+
if (key.endsWith("[]")) {
|
|
778
|
+
const arrayKey = key.slice(0, -2);
|
|
779
|
+
if (isDangerousKey(arrayKey)) {
|
|
780
|
+
break;
|
|
781
|
+
}
|
|
782
|
+
const existingValue = object[arrayKey];
|
|
783
|
+
if (existingValue !== void 0 && !Array.isArray(existingValue)) {
|
|
784
|
+
break;
|
|
785
|
+
}
|
|
786
|
+
object[arrayKey] = existingValue || [];
|
|
787
|
+
object[arrayKey].push(value);
|
|
788
|
+
break;
|
|
789
|
+
}
|
|
790
|
+
if (Array.isArray(object) && !isArrayIndexKey(key)) {
|
|
791
|
+
break;
|
|
792
|
+
}
|
|
793
|
+
if (i < keys.length - 1) {
|
|
794
|
+
path = path ? `${path}.${key}` : key;
|
|
795
|
+
const nextValue = object[key];
|
|
796
|
+
if (nextValue !== void 0) {
|
|
797
|
+
object = nextValue;
|
|
798
|
+
continue;
|
|
799
|
+
}
|
|
800
|
+
object = object[key] = arrayPaths.has(path) ? [] : /* @__PURE__ */ Object.create(null);
|
|
801
|
+
} else {
|
|
802
|
+
object[key] = value;
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
return values;
|
|
807
|
+
};
|
|
808
|
+
const parseRequest = async (deps, { request, method, query }, sharedMap) => {
|
|
809
|
+
const type = deps.getContentType(request.headers);
|
|
810
|
+
if (type === "application/x-www-form-urlencoded" || type === "multipart/form-data") {
|
|
811
|
+
const formData = await request.formData();
|
|
812
|
+
sharedMap.set(RequestEvSharedActionFormData, formData);
|
|
813
|
+
return formToObj(formData);
|
|
814
|
+
} else if (type === "application/json") {
|
|
815
|
+
const data = await request.json();
|
|
816
|
+
return data;
|
|
817
|
+
} else if (type === "application/qwik-json") {
|
|
818
|
+
if (method === "GET" && query.has(deps.QDATA_KEY)) {
|
|
819
|
+
const data = query.get(deps.QDATA_KEY);
|
|
820
|
+
if (data) {
|
|
821
|
+
try {
|
|
822
|
+
return _deserialize(decodeURIComponent(data));
|
|
823
|
+
} catch {
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
return _deserialize(await request.text());
|
|
828
|
+
}
|
|
829
|
+
return void 0;
|
|
830
|
+
};
|
|
831
|
+
function createRequestEventWithDeps(deps, serverRequestEv, loadedRoute, requestHandlers, basePathname, resolved) {
|
|
832
|
+
const { request, platform, env } = serverRequestEv;
|
|
833
|
+
const sharedMap = /* @__PURE__ */ new Map();
|
|
834
|
+
const cookie = new deps.Cookie(request.headers.get("cookie"));
|
|
835
|
+
const headers = new Headers();
|
|
836
|
+
const url = new URL(request.url);
|
|
837
|
+
const { pathname, isInternal } = deps.getRouteMatchPathname(url.pathname);
|
|
838
|
+
if (isInternal) {
|
|
839
|
+
url.pathname = pathname;
|
|
840
|
+
sharedMap.set(deps.IsQData, true);
|
|
841
|
+
}
|
|
842
|
+
let routeModuleIndex = -1;
|
|
843
|
+
let writableStream = null;
|
|
844
|
+
let requestData = void 0;
|
|
845
|
+
let locale = serverRequestEv.locale;
|
|
846
|
+
let status = loadedRoute?.$notFound$ ? 404 : 200;
|
|
847
|
+
const next = async () => {
|
|
848
|
+
routeModuleIndex++;
|
|
849
|
+
while (routeModuleIndex < requestHandlers.length) {
|
|
850
|
+
const moduleRequestHandler = requestHandlers[routeModuleIndex];
|
|
851
|
+
const result = moduleRequestHandler(requestEv);
|
|
852
|
+
if (deps.isPromise(result)) {
|
|
853
|
+
await result;
|
|
854
|
+
}
|
|
855
|
+
routeModuleIndex++;
|
|
856
|
+
}
|
|
857
|
+
};
|
|
858
|
+
const resetRoute = (_loadedRoute, _requestHandlers, _url = url) => {
|
|
859
|
+
loadedRoute = _loadedRoute;
|
|
860
|
+
status = loadedRoute?.$notFound$ ? 404 : 200;
|
|
861
|
+
requestHandlers = _requestHandlers;
|
|
862
|
+
url.pathname = _url.pathname;
|
|
863
|
+
url.search = _url.search;
|
|
864
|
+
routeModuleIndex = -1;
|
|
865
|
+
};
|
|
866
|
+
const check = () => {
|
|
867
|
+
if (writableStream !== null) {
|
|
868
|
+
throw new Error("Response already sent");
|
|
869
|
+
}
|
|
870
|
+
};
|
|
871
|
+
const send = (statusOrResponse, body) => {
|
|
872
|
+
check();
|
|
873
|
+
if (typeof statusOrResponse === "number") {
|
|
874
|
+
status = statusOrResponse;
|
|
875
|
+
const writableStream2 = requestEv.getWritableStream();
|
|
876
|
+
const writer = writableStream2.getWriter();
|
|
877
|
+
writer.write(typeof body === "string" ? deps.encoder.encode(body) : body);
|
|
878
|
+
writer.close();
|
|
879
|
+
} else {
|
|
880
|
+
status = statusOrResponse.status;
|
|
881
|
+
statusOrResponse.headers.forEach((value, key) => {
|
|
882
|
+
if (key.toLowerCase() === "set-cookie") {
|
|
883
|
+
return;
|
|
884
|
+
}
|
|
885
|
+
headers.append(key, value);
|
|
886
|
+
});
|
|
887
|
+
statusOrResponse.headers.getSetCookie().forEach((ck) => {
|
|
888
|
+
const index = ck.indexOf("=");
|
|
889
|
+
if (index === -1) {
|
|
890
|
+
return;
|
|
891
|
+
}
|
|
892
|
+
const key = ck.slice(0, index).trim();
|
|
893
|
+
const value = ck.slice(index + 1).trim();
|
|
894
|
+
cookie.set(key, value);
|
|
895
|
+
});
|
|
896
|
+
if (statusOrResponse.body) {
|
|
897
|
+
const writableStream2 = requestEv.getWritableStream();
|
|
898
|
+
statusOrResponse.body.pipeTo(writableStream2);
|
|
899
|
+
} else {
|
|
900
|
+
requestEv.getWritableStream().getWriter().close();
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
return exit();
|
|
904
|
+
};
|
|
905
|
+
const exit = (message = new deps.AbortMessage()) => {
|
|
906
|
+
routeModuleIndex = ABORT_INDEX;
|
|
907
|
+
return message;
|
|
908
|
+
};
|
|
909
|
+
const loaders = {};
|
|
910
|
+
const requestEv = {
|
|
911
|
+
[RequestEvLoaders]: loaders,
|
|
912
|
+
[RequestEvLoaderSerializationStrategyMap]: /* @__PURE__ */ new Map(),
|
|
913
|
+
[RequestEvMode]: serverRequestEv.mode,
|
|
914
|
+
get [RequestEvRoute]() {
|
|
915
|
+
return loadedRoute;
|
|
916
|
+
},
|
|
917
|
+
cookie,
|
|
918
|
+
headers,
|
|
919
|
+
env,
|
|
920
|
+
method: request.method,
|
|
921
|
+
signal: request.signal,
|
|
922
|
+
originalUrl: new URL(url),
|
|
923
|
+
get params() {
|
|
924
|
+
return loadedRoute?.$params$ ?? {};
|
|
925
|
+
},
|
|
926
|
+
get pathname() {
|
|
927
|
+
return url.pathname;
|
|
928
|
+
},
|
|
929
|
+
platform,
|
|
930
|
+
get query() {
|
|
931
|
+
return url.searchParams;
|
|
932
|
+
},
|
|
933
|
+
request,
|
|
934
|
+
url,
|
|
935
|
+
basePathname,
|
|
936
|
+
sharedMap,
|
|
937
|
+
get headersSent() {
|
|
938
|
+
return writableStream !== null;
|
|
939
|
+
},
|
|
940
|
+
get exited() {
|
|
941
|
+
return routeModuleIndex >= ABORT_INDEX;
|
|
942
|
+
},
|
|
943
|
+
get clientConn() {
|
|
944
|
+
return serverRequestEv.getClientConn();
|
|
945
|
+
},
|
|
946
|
+
next,
|
|
947
|
+
resetRoute,
|
|
948
|
+
exit,
|
|
949
|
+
cacheControl: (cacheControl, target = "Cache-Control") => {
|
|
950
|
+
check();
|
|
951
|
+
headers.set(target, deps.createCacheControl(cacheControl));
|
|
952
|
+
},
|
|
953
|
+
resolveValue: async (loaderOrAction) => {
|
|
954
|
+
const id = loaderOrAction.__id;
|
|
955
|
+
if (loaderOrAction.__brand === "server_loader") {
|
|
956
|
+
if (!(id in loaders)) {
|
|
957
|
+
throw new Error("You can not get the returned data of a loader that has not been executed for this request.");
|
|
958
|
+
}
|
|
959
|
+
if (loaders[id] === _UNINITIALIZED) {
|
|
960
|
+
await deps.getRouteLoaderPromise(loaderOrAction, loaders, requestEv[RequestEvLoaderSerializationStrategyMap], requestEv);
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
return loaders[id];
|
|
964
|
+
},
|
|
965
|
+
status: (statusCode) => {
|
|
966
|
+
if (typeof statusCode === "number") {
|
|
967
|
+
check();
|
|
968
|
+
status = statusCode;
|
|
969
|
+
return statusCode;
|
|
970
|
+
}
|
|
971
|
+
return status;
|
|
972
|
+
},
|
|
973
|
+
locale: (_locale) => {
|
|
974
|
+
if (typeof _locale === "string") {
|
|
975
|
+
locale = _locale;
|
|
976
|
+
}
|
|
977
|
+
return locale || "";
|
|
978
|
+
},
|
|
979
|
+
error: (statusCode, message) => {
|
|
980
|
+
status = statusCode;
|
|
981
|
+
headers.delete("Cache-Control");
|
|
982
|
+
return new deps.ServerError(statusCode, message);
|
|
983
|
+
},
|
|
984
|
+
redirect: (statusCode, url2) => {
|
|
985
|
+
check();
|
|
986
|
+
status = statusCode;
|
|
987
|
+
if (url2) {
|
|
988
|
+
if (
|
|
989
|
+
// //test.com
|
|
990
|
+
/^\/\//.test(url2) || // /test//path
|
|
991
|
+
/([^:])\/\/+/.test(url2)
|
|
992
|
+
) {
|
|
993
|
+
const fixedURL = url2.replace(/^\/\/+/, "/").replace(/([^:])\/\/+/g, "$1/");
|
|
994
|
+
console.warn(`Redirect URL ${url2} is invalid, fixing to ${fixedURL}`);
|
|
995
|
+
url2 = fixedURL;
|
|
996
|
+
}
|
|
997
|
+
headers.set("Location", url2);
|
|
998
|
+
}
|
|
999
|
+
headers.delete("Cache-Control");
|
|
1000
|
+
if (statusCode > 301) {
|
|
1001
|
+
headers.set("Cache-Control", "no-store");
|
|
1002
|
+
}
|
|
1003
|
+
return exit(new deps.RedirectMessage());
|
|
1004
|
+
},
|
|
1005
|
+
rewrite: (pathname2) => {
|
|
1006
|
+
check();
|
|
1007
|
+
if (pathname2.startsWith("http")) {
|
|
1008
|
+
throw new deps.ServerError(400, isDev ? "Rewrite does not support absolute urls" : "Bad Request");
|
|
1009
|
+
}
|
|
1010
|
+
sharedMap.set(RequestEvIsRewrite, true);
|
|
1011
|
+
return exit(new deps.RewriteMessage(pathname2.replace(/\/+/g, "/")));
|
|
1012
|
+
},
|
|
1013
|
+
defer: (returnData) => {
|
|
1014
|
+
return typeof returnData === "function" ? returnData : () => returnData;
|
|
1015
|
+
},
|
|
1016
|
+
fail: (statusCode, data) => {
|
|
1017
|
+
check();
|
|
1018
|
+
status = statusCode;
|
|
1019
|
+
headers.delete("Cache-Control");
|
|
1020
|
+
return {
|
|
1021
|
+
failed: true,
|
|
1022
|
+
...data
|
|
1023
|
+
};
|
|
1024
|
+
},
|
|
1025
|
+
text: (statusCode, text) => {
|
|
1026
|
+
headers.set("Content-Type", "text/plain; charset=utf-8");
|
|
1027
|
+
return send(statusCode, text);
|
|
1028
|
+
},
|
|
1029
|
+
html: (statusCode, html) => {
|
|
1030
|
+
headers.set("Content-Type", "text/html; charset=utf-8");
|
|
1031
|
+
return send(statusCode, html);
|
|
1032
|
+
},
|
|
1033
|
+
parseBody: async () => {
|
|
1034
|
+
if (requestData !== void 0) {
|
|
1035
|
+
return requestData;
|
|
1036
|
+
}
|
|
1037
|
+
return requestData = parseRequest(deps, requestEv, sharedMap);
|
|
1038
|
+
},
|
|
1039
|
+
json: (statusCode, data) => {
|
|
1040
|
+
headers.set("Content-Type", "application/json; charset=utf-8");
|
|
1041
|
+
return send(statusCode, JSON.stringify(data));
|
|
1042
|
+
},
|
|
1043
|
+
send,
|
|
1044
|
+
isDirty: () => {
|
|
1045
|
+
return writableStream !== null;
|
|
1046
|
+
},
|
|
1047
|
+
getWritableStream: () => {
|
|
1048
|
+
if (writableStream === null) {
|
|
1049
|
+
if (isDev) {
|
|
1050
|
+
const serverTiming = sharedMap.get(RequestEvShareServerTiming);
|
|
1051
|
+
if (serverTiming) {
|
|
1052
|
+
headers.set("Server-Timing", serverTiming.map(([name, duration]) => `${name};dur=${duration}`).join(","));
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
writableStream = serverRequestEv.getWritableStream(status, headers, cookie, resolved, requestEv);
|
|
1056
|
+
}
|
|
1057
|
+
return writableStream;
|
|
1058
|
+
}
|
|
1059
|
+
};
|
|
1060
|
+
return requestEv;
|
|
1061
|
+
}
|
|
1062
|
+
|
|
1063
|
+
function verifySerializable(data, qrl) {
|
|
1064
|
+
try {
|
|
1065
|
+
_verifySerializable(data, void 0);
|
|
1066
|
+
} catch (e) {
|
|
1067
|
+
if (e instanceof Error && qrl.dev) {
|
|
1068
|
+
e.loc = qrl.dev;
|
|
1069
|
+
}
|
|
1070
|
+
throw e;
|
|
1071
|
+
}
|
|
1072
|
+
}
|
|
1073
|
+
function now() {
|
|
1074
|
+
return typeof performance !== "undefined" ? performance.now() : 0;
|
|
1075
|
+
}
|
|
1076
|
+
async function measure(requestEv, name, fn) {
|
|
1077
|
+
const start = now();
|
|
1078
|
+
try {
|
|
1079
|
+
return await fn();
|
|
1080
|
+
} finally {
|
|
1081
|
+
const duration = now() - start;
|
|
1082
|
+
let measurements = requestEv.sharedMap.get("@serverTiming");
|
|
1083
|
+
if (!measurements) {
|
|
1084
|
+
requestEv.sharedMap.set("@serverTiming", measurements = []);
|
|
1085
|
+
}
|
|
1086
|
+
measurements.push([
|
|
1087
|
+
name,
|
|
1088
|
+
duration
|
|
1089
|
+
]);
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
async function runValidators(requestEv, validators, data) {
|
|
1093
|
+
let lastResult = {
|
|
1094
|
+
success: true,
|
|
1095
|
+
data
|
|
1096
|
+
};
|
|
1097
|
+
if (validators) {
|
|
1098
|
+
for (const validator of validators) {
|
|
1099
|
+
if (isDev) {
|
|
1100
|
+
lastResult = await measure(requestEv, `validator$`, () => validator.validate(requestEv, data));
|
|
1101
|
+
} else {
|
|
1102
|
+
lastResult = await validator.validate(requestEv, data);
|
|
1103
|
+
}
|
|
1104
|
+
if (!lastResult.success) {
|
|
1105
|
+
return lastResult;
|
|
1106
|
+
} else {
|
|
1107
|
+
data = lastResult.data;
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
return lastResult;
|
|
1112
|
+
}
|
|
1113
|
+
async function getRouteLoaderPromise(loader, loaders, loadersSerializationStrategy, requestEv) {
|
|
1114
|
+
const loaderId = loader.__id;
|
|
1115
|
+
loaders[loaderId] = runValidators(
|
|
1116
|
+
requestEv,
|
|
1117
|
+
loader.__validators,
|
|
1118
|
+
void 0
|
|
1119
|
+
// data
|
|
1120
|
+
).then((res) => {
|
|
1121
|
+
if (res.success) {
|
|
1122
|
+
if (isDev) {
|
|
1123
|
+
return measure(requestEv, loader.__qrl.getHash(), () => loader.__qrl.call(requestEv, requestEv));
|
|
1124
|
+
} else {
|
|
1125
|
+
return loader.__qrl.call(requestEv, requestEv);
|
|
1126
|
+
}
|
|
1127
|
+
} else {
|
|
1128
|
+
return requestEv.fail(res.status ?? 500, res.error);
|
|
1129
|
+
}
|
|
1130
|
+
}).then((resolvedLoader) => {
|
|
1131
|
+
if (typeof resolvedLoader === "function") {
|
|
1132
|
+
loaders[loaderId] = resolvedLoader();
|
|
1133
|
+
} else {
|
|
1134
|
+
if (isDev) {
|
|
1135
|
+
verifySerializable(resolvedLoader, loader.__qrl);
|
|
1136
|
+
}
|
|
1137
|
+
loaders[loaderId] = resolvedLoader;
|
|
1138
|
+
}
|
|
1139
|
+
return resolvedLoader;
|
|
1140
|
+
});
|
|
1141
|
+
loadersSerializationStrategy.set(loaderId, loader.__serializationStrategy);
|
|
1142
|
+
return loaders[loaderId];
|
|
1143
|
+
}
|
|
1144
|
+
|
|
1145
|
+
const IsQData = "@isQData";
|
|
1146
|
+
const QDATA_JSON = "/q-data.json";
|
|
1147
|
+
function getRouteMatchPathname(pathname) {
|
|
1148
|
+
const isInternal = pathname.endsWith(QDATA_JSON);
|
|
1149
|
+
if (isInternal) {
|
|
1150
|
+
const trimEnd = pathname.length - QDATA_JSON.length + (globalThis.__NO_TRAILING_SLASH__ ? 0 : 1);
|
|
1151
|
+
pathname = pathname.slice(0, trimEnd);
|
|
1152
|
+
if (pathname === "") {
|
|
1153
|
+
pathname = "/";
|
|
1154
|
+
}
|
|
1155
|
+
}
|
|
1156
|
+
return {
|
|
1157
|
+
pathname,
|
|
1158
|
+
isInternal
|
|
1159
|
+
};
|
|
1160
|
+
}
|
|
1161
|
+
|
|
1162
|
+
const encoder = /* @__PURE__ */ new TextEncoder();
|
|
1163
|
+
function getContentType(headers) {
|
|
1164
|
+
return (headers.get("content-type")?.split(/[;,]/, 1)[0].trim() ?? "").toLowerCase();
|
|
1165
|
+
}
|
|
1166
|
+
function isContentType(headers, ...types) {
|
|
1167
|
+
const type = getContentType(headers);
|
|
1168
|
+
for (let i = 0; i < types.length; i++) {
|
|
1169
|
+
if (types[i].toLowerCase() === type) {
|
|
1170
|
+
return true;
|
|
1171
|
+
}
|
|
1172
|
+
}
|
|
1173
|
+
return false;
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1176
|
+
class AbortMessage {
|
|
1177
|
+
}
|
|
1178
|
+
class RedirectMessage extends AbortMessage {
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1181
|
+
function createResolveRequestHandlers(deps) {
|
|
1182
|
+
const resolveRequestHandlers = (serverPlugins, route, method, checkOrigin, renderHandler, isInternal) => {
|
|
1183
|
+
const routeLoaders = [];
|
|
1184
|
+
const routeActions = [];
|
|
1185
|
+
const requestHandlers = [];
|
|
1186
|
+
const isPageRoute = !!(route && isLastModulePageRoute(route.$mods$));
|
|
1187
|
+
if (isInternal) {
|
|
1188
|
+
requestHandlers.push(handleQDataRedirect);
|
|
1189
|
+
}
|
|
1190
|
+
if (isPageRoute) {
|
|
1191
|
+
requestHandlers.push(serverErrorMiddleware(route, renderHandler));
|
|
1192
|
+
}
|
|
1193
|
+
if (serverPlugins) {
|
|
1194
|
+
_resolveRequestHandlers(routeLoaders, routeActions, requestHandlers, serverPlugins, isPageRoute, method);
|
|
1195
|
+
}
|
|
1196
|
+
if (route) {
|
|
1197
|
+
const routeModules = route.$mods$;
|
|
1198
|
+
_resolveRequestHandlers(routeLoaders, routeActions, requestHandlers, routeModules, isPageRoute, method);
|
|
1199
|
+
const routeName = route.$routeName$;
|
|
1200
|
+
if (checkOrigin && (method === "POST" || method === "PUT" || method === "PATCH" || method === "DELETE")) {
|
|
1201
|
+
if (checkOrigin === "lax-proto") {
|
|
1202
|
+
requestHandlers.unshift(csrfLaxProtoCheckMiddleware);
|
|
1203
|
+
} else {
|
|
1204
|
+
requestHandlers.unshift(csrfCheckMiddleware);
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
if (isPageRoute) {
|
|
1208
|
+
if (method === "POST" || method === "GET") {
|
|
1209
|
+
requestHandlers.push(runServerFunction);
|
|
1210
|
+
}
|
|
1211
|
+
requestHandlers.push(fixTrailingSlash);
|
|
1212
|
+
if (isInternal) {
|
|
1213
|
+
requestHandlers.push(renderQData);
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1216
|
+
if (isPageRoute) {
|
|
1217
|
+
requestHandlers.push((ev) => {
|
|
1218
|
+
ev.sharedMap.set(deps.RequestRouteName, routeName);
|
|
1219
|
+
});
|
|
1220
|
+
requestHandlers.push(actionsMiddleware(routeActions));
|
|
1221
|
+
requestHandlers.push(loadersMiddleware(routeLoaders));
|
|
1222
|
+
requestHandlers.push(eTagMiddleware(route));
|
|
1223
|
+
requestHandlers.push(renderHandler);
|
|
1224
|
+
}
|
|
1225
|
+
}
|
|
1226
|
+
return requestHandlers;
|
|
1227
|
+
};
|
|
1228
|
+
const _resolveRequestHandlers = (routeLoaders, routeActions, requestHandlers, routeModules, collectActions, method) => {
|
|
1229
|
+
for (const routeModule of routeModules) {
|
|
1230
|
+
if (typeof routeModule.onRequest === "function") {
|
|
1231
|
+
requestHandlers.push(routeModule.onRequest);
|
|
1232
|
+
} else if (Array.isArray(routeModule.onRequest)) {
|
|
1233
|
+
requestHandlers.push(...routeModule.onRequest);
|
|
1234
|
+
}
|
|
1235
|
+
let methodReqHandler;
|
|
1236
|
+
switch (method) {
|
|
1237
|
+
case "GET": {
|
|
1238
|
+
methodReqHandler = routeModule.onGet;
|
|
1239
|
+
break;
|
|
1240
|
+
}
|
|
1241
|
+
case "POST": {
|
|
1242
|
+
methodReqHandler = routeModule.onPost;
|
|
1243
|
+
break;
|
|
1244
|
+
}
|
|
1245
|
+
case "PUT": {
|
|
1246
|
+
methodReqHandler = routeModule.onPut;
|
|
1247
|
+
break;
|
|
1248
|
+
}
|
|
1249
|
+
case "PATCH": {
|
|
1250
|
+
methodReqHandler = routeModule.onPatch;
|
|
1251
|
+
break;
|
|
1252
|
+
}
|
|
1253
|
+
case "DELETE": {
|
|
1254
|
+
methodReqHandler = routeModule.onDelete;
|
|
1255
|
+
break;
|
|
1256
|
+
}
|
|
1257
|
+
case "OPTIONS": {
|
|
1258
|
+
methodReqHandler = routeModule.onOptions;
|
|
1259
|
+
break;
|
|
1260
|
+
}
|
|
1261
|
+
case "HEAD": {
|
|
1262
|
+
methodReqHandler = routeModule.onHead;
|
|
1263
|
+
break;
|
|
1264
|
+
}
|
|
1265
|
+
}
|
|
1266
|
+
if (typeof methodReqHandler === "function") {
|
|
1267
|
+
requestHandlers.push(methodReqHandler);
|
|
1268
|
+
} else if (Array.isArray(methodReqHandler)) {
|
|
1269
|
+
requestHandlers.push(...methodReqHandler);
|
|
1270
|
+
}
|
|
1271
|
+
if (collectActions) {
|
|
1272
|
+
for (const module of Object.values(routeModule)) {
|
|
1273
|
+
if (typeof module === "function") {
|
|
1274
|
+
if (module.__brand === "server_loader") {
|
|
1275
|
+
routeLoaders.push(module);
|
|
1276
|
+
} else if (module.__brand === "server_action") {
|
|
1277
|
+
routeActions.push(module);
|
|
1278
|
+
}
|
|
1279
|
+
}
|
|
1280
|
+
}
|
|
1281
|
+
}
|
|
1282
|
+
}
|
|
1283
|
+
};
|
|
1284
|
+
const checkBrand = (obj, brand) => {
|
|
1285
|
+
return obj && typeof obj === "function" && obj.__brand === brand;
|
|
1286
|
+
};
|
|
1287
|
+
function actionsMiddleware(routeActions) {
|
|
1288
|
+
return async (requestEvent) => {
|
|
1289
|
+
const requestEv = requestEvent;
|
|
1290
|
+
if (requestEv.headersSent) {
|
|
1291
|
+
requestEv.exit();
|
|
1292
|
+
return;
|
|
1293
|
+
}
|
|
1294
|
+
const { method } = requestEv;
|
|
1295
|
+
const loaders = deps.getRequestLoaders(requestEv);
|
|
1296
|
+
if (isDev && method === "GET") {
|
|
1297
|
+
if (requestEv.query.has(deps.QACTION_KEY)) {
|
|
1298
|
+
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">');
|
|
1299
|
+
}
|
|
1300
|
+
}
|
|
1301
|
+
if (method === "POST") {
|
|
1302
|
+
const selectedActionId = requestEv.query.get(deps.QACTION_KEY);
|
|
1303
|
+
if (selectedActionId) {
|
|
1304
|
+
const serverActionsMap = globalThis._qwikActionsMap;
|
|
1305
|
+
const action = routeActions.find((action2) => action2.__id === selectedActionId) ?? serverActionsMap?.get(selectedActionId);
|
|
1306
|
+
if (action) {
|
|
1307
|
+
requestEv.sharedMap.set(deps.RequestEvSharedActionId, selectedActionId);
|
|
1308
|
+
const data = await requestEv.parseBody();
|
|
1309
|
+
if (!data || typeof data !== "object") {
|
|
1310
|
+
throw new Error(`Expected request data for the action id ${selectedActionId} to be an object`);
|
|
1311
|
+
}
|
|
1312
|
+
const result = await runValidators(requestEv, action.__validators, data);
|
|
1313
|
+
if (!result.success) {
|
|
1314
|
+
loaders[selectedActionId] = requestEv.fail(result.status ?? 500, result.error);
|
|
1315
|
+
} else {
|
|
1316
|
+
const actionResolved = isDev ? await measure(requestEv, action.__qrl.getHash(), () => action.__qrl.call(requestEv, result.data, requestEv)) : await action.__qrl.call(requestEv, result.data, requestEv);
|
|
1317
|
+
if (isDev) {
|
|
1318
|
+
verifySerializable(actionResolved, action.__qrl);
|
|
1319
|
+
}
|
|
1320
|
+
loaders[selectedActionId] = actionResolved;
|
|
1321
|
+
}
|
|
1322
|
+
}
|
|
1323
|
+
}
|
|
1324
|
+
}
|
|
1325
|
+
};
|
|
1326
|
+
}
|
|
1327
|
+
function loadersMiddleware(routeLoaders) {
|
|
1328
|
+
return async (requestEvent) => {
|
|
1329
|
+
const requestEv = requestEvent;
|
|
1330
|
+
if (requestEv.headersSent) {
|
|
1331
|
+
requestEv.exit();
|
|
1332
|
+
return;
|
|
1333
|
+
}
|
|
1334
|
+
const loaders = deps.getRequestLoaders(requestEv);
|
|
1335
|
+
const loadersSerializationStrategy = deps.getRequestLoaderSerializationStrategyMap(requestEv);
|
|
1336
|
+
if (routeLoaders.length > 0) {
|
|
1337
|
+
const resolvedLoadersPromises = routeLoaders.map((loader) => deps.getRouteLoaderPromise(loader, loaders, loadersSerializationStrategy, requestEv));
|
|
1338
|
+
await Promise.all(resolvedLoadersPromises);
|
|
1339
|
+
}
|
|
1340
|
+
};
|
|
1341
|
+
}
|
|
1342
|
+
function eTagMiddleware(route) {
|
|
1343
|
+
return (requestEv) => {
|
|
1344
|
+
if (requestEv.headersSent) {
|
|
1345
|
+
return;
|
|
1346
|
+
}
|
|
1347
|
+
if (requestEv.method !== "GET" || requestEv.sharedMap.has(deps.IsQData)) {
|
|
1348
|
+
return;
|
|
1349
|
+
}
|
|
1350
|
+
const mods = route.$mods$;
|
|
1351
|
+
const hasETag = mods.some((m) => {
|
|
1352
|
+
if (!m) {
|
|
1353
|
+
return false;
|
|
1354
|
+
}
|
|
1355
|
+
if (m.routeConfig) {
|
|
1356
|
+
return typeof m.routeConfig === "function" || m.routeConfig.eTag !== void 0;
|
|
1357
|
+
}
|
|
1358
|
+
return m.eTag !== void 0;
|
|
1359
|
+
});
|
|
1360
|
+
if (!hasETag) {
|
|
1361
|
+
return;
|
|
1362
|
+
}
|
|
1363
|
+
const loaders = deps.getRequestLoaders(requestEv);
|
|
1364
|
+
const getData = (loaderOrAction) => {
|
|
1365
|
+
const id = loaderOrAction.__id;
|
|
1366
|
+
if (loaderOrAction.__brand === "server_loader" && !(id in loaders)) {
|
|
1367
|
+
throw new Error("Loader not executed for this request.");
|
|
1368
|
+
}
|
|
1369
|
+
if (loaders[id] instanceof Promise) {
|
|
1370
|
+
throw new Error("Loaders returning a promise cannot be resolved for the eTag function.");
|
|
1371
|
+
}
|
|
1372
|
+
return loaders[id];
|
|
1373
|
+
};
|
|
1374
|
+
const routeLocation = {
|
|
1375
|
+
params: requestEv.params,
|
|
1376
|
+
url: requestEv.url,
|
|
1377
|
+
isNavigating: false,
|
|
1378
|
+
prevUrl: void 0
|
|
1379
|
+
};
|
|
1380
|
+
const status = requestEv.status();
|
|
1381
|
+
const config = deps.resolveRouteConfig(getData, routeLocation, mods, "", status);
|
|
1382
|
+
const headProps = {
|
|
1383
|
+
head: config.head,
|
|
1384
|
+
status,
|
|
1385
|
+
withLocale: (fn) => fn(),
|
|
1386
|
+
resolveValue: getData,
|
|
1387
|
+
...routeLocation
|
|
1388
|
+
};
|
|
1389
|
+
const eTag = deps.resolveETag(config.eTag, headProps);
|
|
1390
|
+
if (!eTag) {
|
|
1391
|
+
return;
|
|
1392
|
+
}
|
|
1393
|
+
requestEv.headers.set("ETag", eTag);
|
|
1394
|
+
const ifNoneMatch = requestEv.request.headers.get("If-None-Match");
|
|
1395
|
+
if (ifNoneMatch && (ifNoneMatch === eTag || ifNoneMatch === `W/${eTag}` || `W/${ifNoneMatch}` === eTag)) {
|
|
1396
|
+
requestEv.status(304);
|
|
1397
|
+
requestEv.send(304, "");
|
|
1398
|
+
return;
|
|
1399
|
+
}
|
|
1400
|
+
if (deps.MAX_CACHE_SIZE <= 0) {
|
|
1401
|
+
return;
|
|
1402
|
+
}
|
|
1403
|
+
const cacheKey = deps.resolveCacheKey(config.cacheKey, status, eTag, requestEv.url.pathname);
|
|
1404
|
+
if (!cacheKey) {
|
|
1405
|
+
return;
|
|
1406
|
+
}
|
|
1407
|
+
const cachedHtml = deps.getCachedHtml(cacheKey);
|
|
1408
|
+
if (cachedHtml) {
|
|
1409
|
+
requestEv.headers.set("Content-Type", "text/html; charset=utf-8");
|
|
1410
|
+
requestEv.headers.set("X-SSR-Cache", "HIT");
|
|
1411
|
+
requestEv.send(status, cachedHtml);
|
|
1412
|
+
return;
|
|
1413
|
+
}
|
|
1414
|
+
requestEv.sharedMap.set(deps.RequestEvETagCacheKey, cacheKey);
|
|
1415
|
+
};
|
|
1416
|
+
}
|
|
1417
|
+
function serverErrorMiddleware(route, renderHandler) {
|
|
1418
|
+
return async (requestEv) => {
|
|
1419
|
+
try {
|
|
1420
|
+
await requestEv.next();
|
|
1421
|
+
} catch (e) {
|
|
1422
|
+
if (!(e instanceof deps.ServerError) || requestEv.headersSent) {
|
|
1423
|
+
throw e;
|
|
1424
|
+
}
|
|
1425
|
+
if (requestEv.sharedMap.has(deps.IsQData)) {
|
|
1426
|
+
throw e;
|
|
1427
|
+
}
|
|
1428
|
+
const accept = requestEv.request.headers.get("Accept");
|
|
1429
|
+
if (accept && !accept.includes("text/html")) {
|
|
1430
|
+
throw e;
|
|
1431
|
+
}
|
|
1432
|
+
const status = e.status;
|
|
1433
|
+
requestEv.status(status);
|
|
1434
|
+
const errorLoader = route.$errorLoader$;
|
|
1435
|
+
const errorModule = errorLoader ? await errorLoader() : await deps.loadHttpError();
|
|
1436
|
+
route.$mods$ = [
|
|
1437
|
+
errorModule
|
|
1438
|
+
];
|
|
1439
|
+
requestEv.sharedMap.set(deps.RequestEvHttpStatusMessage, typeof e.data === "string" ? e.data : "Server Error");
|
|
1440
|
+
await renderHandler(requestEv);
|
|
1441
|
+
}
|
|
1442
|
+
};
|
|
1443
|
+
}
|
|
1444
|
+
async function runValidators(requestEv, validators, data) {
|
|
1445
|
+
let lastResult = {
|
|
1446
|
+
success: true,
|
|
1447
|
+
data
|
|
1448
|
+
};
|
|
1449
|
+
if (validators) {
|
|
1450
|
+
for (const validator of validators) {
|
|
1451
|
+
if (isDev) {
|
|
1452
|
+
lastResult = await measure(requestEv, `validator$`, () => validator.validate(requestEv, data));
|
|
1453
|
+
} else {
|
|
1454
|
+
lastResult = await validator.validate(requestEv, data);
|
|
1455
|
+
}
|
|
1456
|
+
if (!lastResult.success) {
|
|
1457
|
+
return lastResult;
|
|
1458
|
+
} else {
|
|
1459
|
+
data = lastResult.data;
|
|
1460
|
+
}
|
|
1461
|
+
}
|
|
1462
|
+
}
|
|
1463
|
+
return lastResult;
|
|
1464
|
+
}
|
|
1465
|
+
function isAsyncIterator(obj) {
|
|
1466
|
+
return obj ? typeof obj === "object" && Symbol.asyncIterator in obj : false;
|
|
1467
|
+
}
|
|
1468
|
+
async function runServerFunction(ev) {
|
|
1469
|
+
const serverFnHash = ev.query.get(deps.QFN_KEY);
|
|
1470
|
+
if (serverFnHash && ev.request.headers.get("X-QRL") === serverFnHash && ev.request.headers.get("Content-Type") === "application/qwik-json") {
|
|
1471
|
+
ev.exit();
|
|
1472
|
+
const data = await ev.parseBody();
|
|
1473
|
+
if (!Array.isArray(data) || !(Array.isArray(data[0]) || data[0] === void 0)) {
|
|
1474
|
+
throw ev.error(500, "Invalid request");
|
|
1475
|
+
}
|
|
1476
|
+
const qrl = inlinedQrl(null, serverFnHash, data.slice(1));
|
|
1477
|
+
let result;
|
|
1478
|
+
try {
|
|
1479
|
+
if (isDev) {
|
|
1480
|
+
result = await measure(ev, `server_${serverFnHash}`, () => qrl.apply(ev, data[0]));
|
|
1481
|
+
} else {
|
|
1482
|
+
result = await qrl.apply(ev, data[0]);
|
|
1483
|
+
}
|
|
1484
|
+
} catch (err) {
|
|
1485
|
+
if (err instanceof deps.ServerError) {
|
|
1486
|
+
throw ev.error(err.status, err.data);
|
|
1487
|
+
}
|
|
1488
|
+
console.error(`Server function ${serverFnHash} failed:`, err);
|
|
1489
|
+
throw ev.error(500, "Invalid request");
|
|
1490
|
+
}
|
|
1491
|
+
if (isAsyncIterator(result)) {
|
|
1492
|
+
ev.headers.set("Content-Type", "text/qwik-json-stream");
|
|
1493
|
+
const writable = ev.getWritableStream();
|
|
1494
|
+
const stream = writable.getWriter();
|
|
1495
|
+
for await (const item of result) {
|
|
1496
|
+
if (isDev) {
|
|
1497
|
+
verifySerializable(item, qrl);
|
|
1498
|
+
}
|
|
1499
|
+
const message = await _serialize(item);
|
|
1500
|
+
if (ev.signal.aborted) {
|
|
1501
|
+
break;
|
|
1502
|
+
}
|
|
1503
|
+
await stream.write(deps.encoder.encode(`${message}
|
|
1504
|
+
`));
|
|
1505
|
+
}
|
|
1506
|
+
stream.close();
|
|
1507
|
+
} else {
|
|
1508
|
+
verifySerializable(result, qrl);
|
|
1509
|
+
ev.headers.set("Content-Type", "application/qwik-json");
|
|
1510
|
+
const message = await _serialize(result);
|
|
1511
|
+
ev.send(200, message);
|
|
1512
|
+
}
|
|
1513
|
+
return;
|
|
1514
|
+
}
|
|
1515
|
+
}
|
|
1516
|
+
function fixTrailingSlash(ev) {
|
|
1517
|
+
const { basePathname, originalUrl, sharedMap } = ev;
|
|
1518
|
+
const { pathname, search } = originalUrl;
|
|
1519
|
+
const isQData = sharedMap.has(deps.IsQData);
|
|
1520
|
+
if (!pathname.startsWith("/") || pathname.startsWith("//")) {
|
|
1521
|
+
return;
|
|
1522
|
+
}
|
|
1523
|
+
if (!isQData && pathname !== basePathname && !pathname.endsWith(".html")) {
|
|
1524
|
+
if (!globalThis.__NO_TRAILING_SLASH__) {
|
|
1525
|
+
if (!pathname.endsWith("/")) {
|
|
1526
|
+
throw ev.redirect(deps.HttpStatus.MovedPermanently, pathname + "/" + search);
|
|
1527
|
+
}
|
|
1528
|
+
} else {
|
|
1529
|
+
if (pathname.endsWith("/")) {
|
|
1530
|
+
throw ev.redirect(deps.HttpStatus.MovedPermanently, pathname.slice(0, pathname.length - 1) + search);
|
|
1531
|
+
}
|
|
1532
|
+
}
|
|
1533
|
+
}
|
|
1534
|
+
}
|
|
1535
|
+
function verifySerializable(data, qrl) {
|
|
1536
|
+
try {
|
|
1537
|
+
_verifySerializable(data, void 0);
|
|
1538
|
+
} catch (e) {
|
|
1539
|
+
if (e instanceof Error && qrl.dev) {
|
|
1540
|
+
e.loc = qrl.dev;
|
|
1541
|
+
}
|
|
1542
|
+
throw e;
|
|
1543
|
+
}
|
|
1544
|
+
}
|
|
1545
|
+
const isQrl = (value) => {
|
|
1546
|
+
return typeof value === "function" && typeof value.getSymbol === "function";
|
|
1547
|
+
};
|
|
1548
|
+
function isLastModulePageRoute(routeModules) {
|
|
1549
|
+
const lastRouteModule = routeModules[routeModules.length - 1];
|
|
1550
|
+
return lastRouteModule && typeof lastRouteModule.default === "function";
|
|
1551
|
+
}
|
|
1552
|
+
function getPathname(url) {
|
|
1553
|
+
url = new URL(url);
|
|
1554
|
+
if (url.pathname.endsWith(deps.QDATA_JSON)) {
|
|
1555
|
+
url.pathname = url.pathname.slice(0, -deps.QDATA_JSON.length);
|
|
1556
|
+
}
|
|
1557
|
+
if (!globalThis.__NO_TRAILING_SLASH__) {
|
|
1558
|
+
if (!url.pathname.endsWith("/")) {
|
|
1559
|
+
url.pathname += "/";
|
|
1560
|
+
}
|
|
1561
|
+
} else {
|
|
1562
|
+
if (url.pathname.endsWith("/")) {
|
|
1563
|
+
url.pathname = url.pathname.slice(0, -1);
|
|
1564
|
+
}
|
|
1565
|
+
}
|
|
1566
|
+
const search = url.search.slice(1).replaceAll(/&?q(action|data|func|loaders)=[^&]+/g, "");
|
|
1567
|
+
return `${url.pathname}${search ? `?${search}` : ""}${url.hash}`;
|
|
1568
|
+
}
|
|
1569
|
+
function csrfLaxProtoCheckMiddleware(requestEv) {
|
|
1570
|
+
checkCSRF(requestEv, "lax-proto");
|
|
1571
|
+
}
|
|
1572
|
+
function csrfCheckMiddleware(requestEv) {
|
|
1573
|
+
checkCSRF(requestEv);
|
|
1574
|
+
}
|
|
1575
|
+
function checkCSRF(requestEv, laxProto) {
|
|
1576
|
+
const contentType = requestEv.request.headers.get("content-type");
|
|
1577
|
+
const isSimpleRequest = !contentType || deps.isContentType(requestEv.request.headers, "application/x-www-form-urlencoded", "multipart/form-data", "text/plain");
|
|
1578
|
+
if (isSimpleRequest) {
|
|
1579
|
+
const inputOrigin = requestEv.request.headers.get("origin");
|
|
1580
|
+
const origin = requestEv.url.origin;
|
|
1581
|
+
let forbidden = inputOrigin !== origin;
|
|
1582
|
+
if (forbidden && laxProto && inputOrigin?.replace(/^http(s)?/g, "") === origin.replace(/^http(s)?/g, "")) {
|
|
1583
|
+
forbidden = false;
|
|
1584
|
+
}
|
|
1585
|
+
if (forbidden) {
|
|
1586
|
+
throw requestEv.error(403, `CSRF check failed. Cross-site ${requestEv.method} form submissions are forbidden.
|
|
1587
|
+
The request origin "${inputOrigin}" does not match the server origin "${origin}".`);
|
|
1588
|
+
}
|
|
1589
|
+
}
|
|
1590
|
+
}
|
|
1591
|
+
function renderQwikMiddleware(render) {
|
|
1592
|
+
return async (requestEv) => {
|
|
1593
|
+
if (requestEv.headersSent) {
|
|
1594
|
+
return;
|
|
1595
|
+
}
|
|
1596
|
+
if (requestEv.sharedMap.has(deps.IsQData)) {
|
|
1597
|
+
return;
|
|
1598
|
+
}
|
|
1599
|
+
const responseHeaders = requestEv.headers;
|
|
1600
|
+
if (!responseHeaders.has("Content-Type")) {
|
|
1601
|
+
responseHeaders.set("Content-Type", "text/html; charset=utf-8");
|
|
1602
|
+
}
|
|
1603
|
+
const eTagCacheKey = requestEv.sharedMap.get(deps.RequestEvETagCacheKey);
|
|
1604
|
+
const { readable, writable } = new TextEncoderStream();
|
|
1605
|
+
const writableStream = requestEv.getWritableStream();
|
|
1606
|
+
let cacheChunks;
|
|
1607
|
+
let pipeSource = readable;
|
|
1608
|
+
if (eTagCacheKey) {
|
|
1609
|
+
cacheChunks = [];
|
|
1610
|
+
const capture = new TransformStream({
|
|
1611
|
+
transform(chunk, controller) {
|
|
1612
|
+
cacheChunks.push(chunk);
|
|
1613
|
+
controller.enqueue(chunk);
|
|
1614
|
+
}
|
|
1615
|
+
});
|
|
1616
|
+
pipeSource = readable.pipeThrough(capture);
|
|
1617
|
+
}
|
|
1618
|
+
const pipe = pipeSource.pipeTo(writableStream, {
|
|
1619
|
+
preventClose: true
|
|
1620
|
+
});
|
|
1621
|
+
const stream = writable.getWriter();
|
|
1622
|
+
const status = requestEv.status();
|
|
1623
|
+
try {
|
|
1624
|
+
const isStatic = deps.getRequestMode(requestEv) === "static";
|
|
1625
|
+
const serverData = deps.getQwikRouterServerData(requestEv);
|
|
1626
|
+
const result = await render({
|
|
1627
|
+
base: requestEv.basePathname + "build/",
|
|
1628
|
+
stream,
|
|
1629
|
+
serverData,
|
|
1630
|
+
containerAttributes: {
|
|
1631
|
+
["q:render"]: isStatic ? "static" : "",
|
|
1632
|
+
...serverData.containerAttributes
|
|
1633
|
+
}
|
|
1634
|
+
});
|
|
1635
|
+
const qData = {
|
|
1636
|
+
loaders: deps.getRequestLoaders(requestEv),
|
|
1637
|
+
action: requestEv.sharedMap.get(deps.RequestEvSharedActionId),
|
|
1638
|
+
status: status !== 200 ? status : 200,
|
|
1639
|
+
href: getPathname(requestEv.url)
|
|
1640
|
+
};
|
|
1641
|
+
if (typeof result.html === "string") {
|
|
1642
|
+
await stream.write(result.html);
|
|
1643
|
+
}
|
|
1644
|
+
requestEv.sharedMap.set(deps.RequestEvShareQData, qData);
|
|
1645
|
+
} finally {
|
|
1646
|
+
await stream.ready;
|
|
1647
|
+
await stream.close();
|
|
1648
|
+
await pipe;
|
|
1649
|
+
}
|
|
1650
|
+
if (eTagCacheKey && cacheChunks && cacheChunks.length > 0) {
|
|
1651
|
+
const totalLength = cacheChunks.reduce((sum, chunk) => sum + chunk.length, 0);
|
|
1652
|
+
const combined = new Uint8Array(totalLength);
|
|
1653
|
+
let offset = 0;
|
|
1654
|
+
for (const chunk of cacheChunks) {
|
|
1655
|
+
combined.set(chunk, offset);
|
|
1656
|
+
offset += chunk.length;
|
|
1657
|
+
}
|
|
1658
|
+
deps.setCachedHtml(eTagCacheKey, new TextDecoder().decode(combined));
|
|
1659
|
+
}
|
|
1660
|
+
await writableStream.close();
|
|
1661
|
+
};
|
|
1662
|
+
}
|
|
1663
|
+
async function handleQDataRedirect(requestEv) {
|
|
1664
|
+
try {
|
|
1665
|
+
await requestEv.next();
|
|
1666
|
+
} catch (err) {
|
|
1667
|
+
if (!(err instanceof deps.RedirectMessage)) {
|
|
1668
|
+
throw err;
|
|
1669
|
+
}
|
|
1670
|
+
}
|
|
1671
|
+
if (requestEv.headersSent) {
|
|
1672
|
+
return;
|
|
1673
|
+
}
|
|
1674
|
+
const status = requestEv.status();
|
|
1675
|
+
const location = requestEv.headers.get("Location");
|
|
1676
|
+
const isRedirect = status >= 301 && status <= 308 && location;
|
|
1677
|
+
if (isRedirect) {
|
|
1678
|
+
const adaptedLocation = makeQDataPath(location);
|
|
1679
|
+
if (adaptedLocation) {
|
|
1680
|
+
requestEv.headers.set("Location", adaptedLocation);
|
|
1681
|
+
requestEv.getWritableStream().close();
|
|
1682
|
+
return;
|
|
1683
|
+
} else {
|
|
1684
|
+
requestEv.status(200);
|
|
1685
|
+
requestEv.headers.delete("Location");
|
|
1686
|
+
}
|
|
1687
|
+
}
|
|
1688
|
+
}
|
|
1689
|
+
async function renderQData(requestEv) {
|
|
1690
|
+
await requestEv.next();
|
|
1691
|
+
if (requestEv.headersSent || requestEv.exited) {
|
|
1692
|
+
return;
|
|
1693
|
+
}
|
|
1694
|
+
const status = requestEv.status();
|
|
1695
|
+
const redirectLocation = requestEv.headers.get("Location");
|
|
1696
|
+
requestEv.headers.set("Content-Type", "application/json; charset=utf-8");
|
|
1697
|
+
let loaders = deps.getRequestLoaders(requestEv);
|
|
1698
|
+
const selectedLoaderIds = requestEv.query.getAll(deps.QLOADER_KEY);
|
|
1699
|
+
const hasCustomLoaders = selectedLoaderIds.length > 0;
|
|
1700
|
+
if (hasCustomLoaders) {
|
|
1701
|
+
const selectedLoaders = {};
|
|
1702
|
+
for (const loaderId of selectedLoaderIds) {
|
|
1703
|
+
const loader = loaders[loaderId];
|
|
1704
|
+
selectedLoaders[loaderId] = loader;
|
|
1705
|
+
}
|
|
1706
|
+
loaders = selectedLoaders;
|
|
1707
|
+
}
|
|
1708
|
+
const qData = hasCustomLoaders ? {
|
|
1709
|
+
loaders,
|
|
1710
|
+
status: status !== 200 ? status : 200,
|
|
1711
|
+
href: getPathname(requestEv.url)
|
|
1712
|
+
} : {
|
|
1713
|
+
loaders,
|
|
1714
|
+
action: requestEv.sharedMap.get(deps.RequestEvSharedActionId),
|
|
1715
|
+
status: status !== 200 ? status : 200,
|
|
1716
|
+
href: getPathname(requestEv.url),
|
|
1717
|
+
redirect: redirectLocation ?? void 0,
|
|
1718
|
+
isRewrite: requestEv.sharedMap.get(deps.RequestEvIsRewrite)
|
|
1719
|
+
};
|
|
1720
|
+
const writer = requestEv.getWritableStream().getWriter();
|
|
1721
|
+
const data = await _serialize(qData);
|
|
1722
|
+
writer.write(deps.encoder.encode(data));
|
|
1723
|
+
requestEv.sharedMap.set(deps.RequestEvShareQData, qData);
|
|
1724
|
+
writer.close();
|
|
1725
|
+
}
|
|
1726
|
+
function makeQDataPath(href) {
|
|
1727
|
+
if (href.startsWith("/")) {
|
|
1728
|
+
if (!href.includes(deps.QDATA_JSON)) {
|
|
1729
|
+
const url = new URL(href, "http://localhost");
|
|
1730
|
+
const pathname = url.pathname.endsWith("/") ? url.pathname.slice(0, -1) : url.pathname;
|
|
1731
|
+
return pathname + deps.QDATA_JSON + url.search;
|
|
1732
|
+
}
|
|
1733
|
+
return href;
|
|
1734
|
+
} else {
|
|
1735
|
+
return void 0;
|
|
1736
|
+
}
|
|
1737
|
+
}
|
|
1738
|
+
function now() {
|
|
1739
|
+
return typeof performance !== "undefined" ? performance.now() : 0;
|
|
1740
|
+
}
|
|
1741
|
+
async function measure(requestEv, name, fn) {
|
|
1742
|
+
const start = now();
|
|
1743
|
+
try {
|
|
1744
|
+
return await fn();
|
|
1745
|
+
} finally {
|
|
1746
|
+
const duration = now() - start;
|
|
1747
|
+
let measurements = requestEv.sharedMap.get(deps.RequestEvShareServerTiming);
|
|
1748
|
+
if (!measurements) {
|
|
1749
|
+
requestEv.sharedMap.set(deps.RequestEvShareServerTiming, measurements = []);
|
|
1750
|
+
}
|
|
1751
|
+
measurements.push([
|
|
1752
|
+
name,
|
|
1753
|
+
duration
|
|
1754
|
+
]);
|
|
1755
|
+
}
|
|
1756
|
+
}
|
|
1757
|
+
return {
|
|
1758
|
+
actionsMiddleware,
|
|
1759
|
+
checkBrand,
|
|
1760
|
+
checkCSRF,
|
|
1761
|
+
fixTrailingSlash,
|
|
1762
|
+
getPathname,
|
|
1763
|
+
isLastModulePageRoute,
|
|
1764
|
+
isQrl,
|
|
1765
|
+
loadersMiddleware,
|
|
1766
|
+
measure,
|
|
1767
|
+
renderQwikMiddleware,
|
|
1768
|
+
resolveRequestHandlers,
|
|
1769
|
+
verifySerializable
|
|
1770
|
+
};
|
|
1771
|
+
}
|
|
1772
|
+
|
|
1773
|
+
class ServerError extends Error {
|
|
1774
|
+
status;
|
|
1775
|
+
data;
|
|
1776
|
+
constructor(status, data) {
|
|
1777
|
+
super(typeof data === "string" ? data : void 0), this.status = status, this.data = data;
|
|
1778
|
+
}
|
|
1779
|
+
}
|
|
1780
|
+
|
|
1781
|
+
function getQwikRouterServerDataWithDeps(deps, requestEv) {
|
|
1782
|
+
const { params, request, status, locale, originalUrl } = requestEv;
|
|
1783
|
+
const requestHeaders = {};
|
|
1784
|
+
request.headers.forEach((value, key) => requestHeaders[key] = value);
|
|
1785
|
+
const action = requestEv.sharedMap.get(deps.RequestEvSharedActionId);
|
|
1786
|
+
const formData = requestEv.sharedMap.get(deps.RequestEvSharedActionFormData);
|
|
1787
|
+
const routeName = requestEv.sharedMap.get(deps.RequestRouteName);
|
|
1788
|
+
const nonce = requestEv.sharedMap.get(deps.RequestEvSharedNonce);
|
|
1789
|
+
const headers = requestEv.request.headers;
|
|
1790
|
+
const reconstructedUrl = new URL(originalUrl.pathname + originalUrl.search, originalUrl);
|
|
1791
|
+
const host = headers.get("X-Forwarded-Host");
|
|
1792
|
+
const protocol = headers.get("X-Forwarded-Proto");
|
|
1793
|
+
if (host) {
|
|
1794
|
+
reconstructedUrl.port = "";
|
|
1795
|
+
reconstructedUrl.host = host;
|
|
1796
|
+
}
|
|
1797
|
+
if (protocol) {
|
|
1798
|
+
reconstructedUrl.protocol = protocol;
|
|
1799
|
+
}
|
|
1800
|
+
const loaders = deps.getRequestLoaders(requestEv);
|
|
1801
|
+
const loadersSerializationStrategy = deps.getRequestLoaderSerializationStrategyMap(requestEv);
|
|
1802
|
+
return {
|
|
1803
|
+
url: reconstructedUrl.href,
|
|
1804
|
+
requestHeaders,
|
|
1805
|
+
locale: locale(),
|
|
1806
|
+
nonce,
|
|
1807
|
+
containerAttributes: {
|
|
1808
|
+
[deps.Q_ROUTE]: routeName
|
|
1809
|
+
},
|
|
1810
|
+
qwikrouter: {
|
|
1811
|
+
routeName,
|
|
1812
|
+
ev: requestEv,
|
|
1813
|
+
params: {
|
|
1814
|
+
...params
|
|
1815
|
+
},
|
|
1816
|
+
loadedRoute: deps.getRequestRoute(requestEv),
|
|
1817
|
+
response: {
|
|
1818
|
+
status: status(),
|
|
1819
|
+
statusMessage: requestEv.sharedMap.get(deps.RequestEvHttpStatusMessage),
|
|
1820
|
+
loaders,
|
|
1821
|
+
loadersSerializationStrategy,
|
|
1822
|
+
action,
|
|
1823
|
+
formData
|
|
1824
|
+
}
|
|
1825
|
+
}
|
|
1826
|
+
};
|
|
1827
|
+
}
|
|
1828
|
+
|
|
1829
|
+
const responsePageDeps = {
|
|
1830
|
+
Q_ROUTE,
|
|
1831
|
+
RequestEvHttpStatusMessage,
|
|
1832
|
+
RequestEvSharedActionFormData,
|
|
1833
|
+
RequestEvSharedActionId,
|
|
1834
|
+
RequestEvSharedNonce,
|
|
1835
|
+
RequestRouteName,
|
|
1836
|
+
getRequestLoaders,
|
|
1837
|
+
getRequestLoaderSerializationStrategyMap,
|
|
1838
|
+
getRequestRoute
|
|
1839
|
+
};
|
|
1840
|
+
function getQwikRouterServerData(...args) {
|
|
1841
|
+
return getQwikRouterServerDataWithDeps(responsePageDeps, ...args);
|
|
1842
|
+
}
|
|
1843
|
+
|
|
1844
|
+
const requestHandlers = createResolveRequestHandlers({
|
|
1845
|
+
QACTION_KEY,
|
|
1846
|
+
QFN_KEY,
|
|
1847
|
+
QLOADER_KEY,
|
|
1848
|
+
QDATA_JSON,
|
|
1849
|
+
IsQData,
|
|
1850
|
+
RequestEvETagCacheKey,
|
|
1851
|
+
RequestEvHttpStatusMessage,
|
|
1852
|
+
RequestEvIsRewrite,
|
|
1853
|
+
RequestEvShareQData,
|
|
1854
|
+
RequestEvShareServerTiming,
|
|
1855
|
+
RequestEvSharedActionId,
|
|
1856
|
+
RequestRouteName,
|
|
1857
|
+
RedirectMessage,
|
|
1858
|
+
ServerError,
|
|
1859
|
+
HttpStatus,
|
|
1860
|
+
encoder,
|
|
1861
|
+
isContentType,
|
|
1862
|
+
getCachedHtml,
|
|
1863
|
+
getQwikRouterServerData,
|
|
1864
|
+
getRequestLoaderSerializationStrategyMap,
|
|
1865
|
+
getRequestLoaders,
|
|
1866
|
+
getRequestMode,
|
|
1867
|
+
getRouteLoaderPromise,
|
|
1868
|
+
loadHttpError: () => import('./http-error.qwik.mjs'),
|
|
1869
|
+
MAX_CACHE_SIZE,
|
|
1870
|
+
resolveCacheKey,
|
|
1871
|
+
resolveETag,
|
|
1872
|
+
resolveRouteConfig,
|
|
1873
|
+
setCachedHtml
|
|
1874
|
+
});
|
|
1875
|
+
const { renderQwikMiddleware, resolveRequestHandlers} = requestHandlers;
|
|
1876
|
+
|
|
1877
|
+
function createCacheControl(cacheControl) {
|
|
1878
|
+
const controls = [];
|
|
1879
|
+
if (cacheControl === "day") {
|
|
1880
|
+
cacheControl = 60 * 60 * 24;
|
|
1881
|
+
} else if (cacheControl === "week") {
|
|
1882
|
+
cacheControl = 60 * 60 * 24 * 7;
|
|
1883
|
+
} else if (cacheControl === "month") {
|
|
1884
|
+
cacheControl = 60 * 60 * 24 * 30;
|
|
1885
|
+
} else if (cacheControl === "year") {
|
|
1886
|
+
cacheControl = 60 * 60 * 24 * 365;
|
|
1887
|
+
} else if (cacheControl === "private") {
|
|
1888
|
+
cacheControl = {
|
|
1889
|
+
private: true,
|
|
1890
|
+
noCache: true
|
|
1891
|
+
};
|
|
1892
|
+
} else if (cacheControl === "immutable") {
|
|
1893
|
+
cacheControl = {
|
|
1894
|
+
public: true,
|
|
1895
|
+
immutable: true,
|
|
1896
|
+
maxAge: 60 * 60 * 24 * 365
|
|
1897
|
+
};
|
|
1898
|
+
} else if (cacheControl === "no-cache") {
|
|
1899
|
+
cacheControl = {
|
|
1900
|
+
noCache: true
|
|
1901
|
+
};
|
|
1902
|
+
}
|
|
1903
|
+
if (typeof cacheControl === "number") {
|
|
1904
|
+
cacheControl = {
|
|
1905
|
+
maxAge: cacheControl,
|
|
1906
|
+
sMaxAge: cacheControl
|
|
1907
|
+
};
|
|
1908
|
+
}
|
|
1909
|
+
if (cacheControl.immutable) {
|
|
1910
|
+
controls.push("immutable");
|
|
1911
|
+
}
|
|
1912
|
+
if (cacheControl.maxAge) {
|
|
1913
|
+
controls.push(`max-age=${cacheControl.maxAge}`);
|
|
1914
|
+
}
|
|
1915
|
+
if (cacheControl.sMaxAge) {
|
|
1916
|
+
controls.push(`s-maxage=${cacheControl.sMaxAge}`);
|
|
1917
|
+
}
|
|
1918
|
+
if (cacheControl.noStore) {
|
|
1919
|
+
controls.push("no-store");
|
|
1920
|
+
}
|
|
1921
|
+
if (cacheControl.noCache) {
|
|
1922
|
+
controls.push("no-cache");
|
|
1923
|
+
}
|
|
1924
|
+
if (cacheControl.private) {
|
|
1925
|
+
controls.push("private");
|
|
1926
|
+
}
|
|
1927
|
+
if (cacheControl.public) {
|
|
1928
|
+
controls.push("public");
|
|
1929
|
+
}
|
|
1930
|
+
if (cacheControl.staleWhileRevalidate) {
|
|
1931
|
+
controls.push(`stale-while-revalidate=${cacheControl.staleWhileRevalidate}`);
|
|
1932
|
+
}
|
|
1933
|
+
if (cacheControl.staleIfError) {
|
|
1934
|
+
controls.push(`stale-if-error=${cacheControl.staleIfError}`);
|
|
1935
|
+
}
|
|
1936
|
+
return controls.join(", ");
|
|
1937
|
+
}
|
|
1938
|
+
|
|
1939
|
+
const SAMESITE = {
|
|
1940
|
+
lax: "Lax",
|
|
1941
|
+
Lax: "Lax",
|
|
1942
|
+
None: "None",
|
|
1943
|
+
none: "None",
|
|
1944
|
+
strict: "Strict",
|
|
1945
|
+
Strict: "Strict"
|
|
1946
|
+
};
|
|
1947
|
+
const UNIT = {
|
|
1948
|
+
seconds: 1,
|
|
1949
|
+
minutes: 1 * 60,
|
|
1950
|
+
hours: 1 * 60 * 60,
|
|
1951
|
+
days: 1 * 60 * 60 * 24,
|
|
1952
|
+
weeks: 1 * 60 * 60 * 24 * 7
|
|
1953
|
+
};
|
|
1954
|
+
function tryDecodeUriComponent(str) {
|
|
1955
|
+
try {
|
|
1956
|
+
return decodeURIComponent(str);
|
|
1957
|
+
} catch {
|
|
1958
|
+
return str;
|
|
1959
|
+
}
|
|
1960
|
+
}
|
|
1961
|
+
const parseCookieString = (cookieString) => {
|
|
1962
|
+
const cookie = {};
|
|
1963
|
+
if (typeof cookieString === "string" && cookieString !== "") {
|
|
1964
|
+
const cookieSegments = cookieString.split(";");
|
|
1965
|
+
for (const cookieSegment of cookieSegments) {
|
|
1966
|
+
const separatorIndex = cookieSegment.indexOf("=");
|
|
1967
|
+
if (separatorIndex !== -1) {
|
|
1968
|
+
cookie[tryDecodeUriComponent(cookieSegment.slice(0, separatorIndex).trim())] = tryDecodeUriComponent(cookieSegment.slice(separatorIndex + 1).trim());
|
|
1969
|
+
}
|
|
1970
|
+
}
|
|
1971
|
+
}
|
|
1972
|
+
return cookie;
|
|
1973
|
+
};
|
|
1974
|
+
function resolveSameSite(sameSite) {
|
|
1975
|
+
if (sameSite === true) {
|
|
1976
|
+
return "Strict";
|
|
1977
|
+
}
|
|
1978
|
+
if (sameSite === false) {
|
|
1979
|
+
return "None";
|
|
1980
|
+
}
|
|
1981
|
+
if (sameSite) {
|
|
1982
|
+
return SAMESITE[sameSite];
|
|
1983
|
+
}
|
|
1984
|
+
return void 0;
|
|
1985
|
+
}
|
|
1986
|
+
const createSetCookieValue = (cookieName, cookieValue, options) => {
|
|
1987
|
+
const c = [
|
|
1988
|
+
`${cookieName}=${cookieValue}`
|
|
1989
|
+
];
|
|
1990
|
+
if (typeof options.domain === "string") {
|
|
1991
|
+
c.push(`Domain=${options.domain}`);
|
|
1992
|
+
}
|
|
1993
|
+
if (typeof options.maxAge === "number") {
|
|
1994
|
+
c.push(`Max-Age=${options.maxAge}`);
|
|
1995
|
+
} else if (Array.isArray(options.maxAge)) {
|
|
1996
|
+
c.push(`Max-Age=${options.maxAge[0] * UNIT[options.maxAge[1]]}`);
|
|
1997
|
+
} else if (typeof options.expires === "number" || typeof options.expires == "string") {
|
|
1998
|
+
c.push(`Expires=${options.expires}`);
|
|
1999
|
+
} else if (options.expires instanceof Date) {
|
|
2000
|
+
c.push(`Expires=${options.expires.toUTCString()}`);
|
|
2001
|
+
}
|
|
2002
|
+
if (options.httpOnly) {
|
|
2003
|
+
c.push("HttpOnly");
|
|
2004
|
+
}
|
|
2005
|
+
if (typeof options.path === "string") {
|
|
2006
|
+
c.push(`Path=${options.path}`);
|
|
2007
|
+
}
|
|
2008
|
+
const sameSite = resolveSameSite(options.sameSite);
|
|
2009
|
+
if (sameSite) {
|
|
2010
|
+
c.push(`SameSite=${sameSite}`);
|
|
2011
|
+
}
|
|
2012
|
+
if (options.secure) {
|
|
2013
|
+
c.push("Secure");
|
|
2014
|
+
}
|
|
2015
|
+
return c.join("; ");
|
|
2016
|
+
};
|
|
2017
|
+
const REQ_COOKIE = /* @__PURE__ */ Symbol("request-cookies");
|
|
2018
|
+
const RES_COOKIE = /* @__PURE__ */ Symbol("response-cookies");
|
|
2019
|
+
const LIVE_COOKIE = /* @__PURE__ */ Symbol("live-cookies");
|
|
2020
|
+
class Cookie {
|
|
2021
|
+
[REQ_COOKIE];
|
|
2022
|
+
[RES_COOKIE] = {};
|
|
2023
|
+
[LIVE_COOKIE] = {};
|
|
2024
|
+
appendCounter = 0;
|
|
2025
|
+
constructor(cookieString) {
|
|
2026
|
+
this[REQ_COOKIE] = parseCookieString(cookieString);
|
|
2027
|
+
this[LIVE_COOKIE] = {
|
|
2028
|
+
...this[REQ_COOKIE]
|
|
2029
|
+
};
|
|
2030
|
+
}
|
|
2031
|
+
get(cookieName, live = true) {
|
|
2032
|
+
const value = this[live ? LIVE_COOKIE : REQ_COOKIE][cookieName];
|
|
2033
|
+
if (!value) {
|
|
2034
|
+
return null;
|
|
2035
|
+
}
|
|
2036
|
+
return {
|
|
2037
|
+
value,
|
|
2038
|
+
json() {
|
|
2039
|
+
return JSON.parse(value);
|
|
2040
|
+
},
|
|
2041
|
+
number() {
|
|
2042
|
+
return Number(value);
|
|
2043
|
+
}
|
|
2044
|
+
};
|
|
2045
|
+
}
|
|
2046
|
+
getAll(live = true) {
|
|
2047
|
+
return Object.keys(this[live ? LIVE_COOKIE : REQ_COOKIE]).reduce((cookies, cookieName) => {
|
|
2048
|
+
cookies[cookieName] = this.get(cookieName);
|
|
2049
|
+
return cookies;
|
|
2050
|
+
}, {});
|
|
2051
|
+
}
|
|
2052
|
+
has(cookieName, live = true) {
|
|
2053
|
+
return !!this[live ? LIVE_COOKIE : REQ_COOKIE][cookieName];
|
|
2054
|
+
}
|
|
2055
|
+
set(cookieName, cookieValue, options = {}) {
|
|
2056
|
+
this[LIVE_COOKIE][cookieName] = typeof cookieValue === "string" ? cookieValue : JSON.stringify(cookieValue);
|
|
2057
|
+
const resolvedValue = typeof cookieValue === "string" ? cookieValue : encodeURIComponent(JSON.stringify(cookieValue));
|
|
2058
|
+
this[RES_COOKIE][cookieName] = createSetCookieValue(cookieName, resolvedValue, options);
|
|
2059
|
+
}
|
|
2060
|
+
append(cookieName, cookieValue, options = {}) {
|
|
2061
|
+
this[LIVE_COOKIE][cookieName] = typeof cookieValue === "string" ? cookieValue : JSON.stringify(cookieValue);
|
|
2062
|
+
const resolvedValue = typeof cookieValue === "string" ? cookieValue : encodeURIComponent(JSON.stringify(cookieValue));
|
|
2063
|
+
this[RES_COOKIE][++this.appendCounter] = createSetCookieValue(cookieName, resolvedValue, options);
|
|
2064
|
+
}
|
|
2065
|
+
delete(name, options) {
|
|
2066
|
+
this.set(name, "deleted", {
|
|
2067
|
+
...options,
|
|
2068
|
+
maxAge: 0
|
|
2069
|
+
});
|
|
2070
|
+
this[LIVE_COOKIE][name] = null;
|
|
2071
|
+
}
|
|
2072
|
+
headers() {
|
|
2073
|
+
return Object.values(this[RES_COOKIE]);
|
|
2074
|
+
}
|
|
2075
|
+
}
|
|
2076
|
+
|
|
2077
|
+
class RewriteMessage extends AbortMessage$1 {
|
|
2078
|
+
pathname;
|
|
2079
|
+
constructor(pathname) {
|
|
2080
|
+
super(), this.pathname = pathname;
|
|
2081
|
+
}
|
|
2082
|
+
}
|
|
2083
|
+
|
|
2084
|
+
const requestEventDeps = {
|
|
2085
|
+
QDATA_KEY,
|
|
2086
|
+
isPromise,
|
|
2087
|
+
createCacheControl,
|
|
2088
|
+
Cookie,
|
|
2089
|
+
AbortMessage,
|
|
2090
|
+
RedirectMessage,
|
|
2091
|
+
RewriteMessage,
|
|
2092
|
+
ServerError,
|
|
2093
|
+
getRouteLoaderPromise,
|
|
2094
|
+
getRouteMatchPathname,
|
|
2095
|
+
IsQData,
|
|
2096
|
+
encoder,
|
|
2097
|
+
getContentType
|
|
2098
|
+
};
|
|
2099
|
+
function createRequestEvent(...args) {
|
|
2100
|
+
return createRequestEventWithDeps(requestEventDeps, ...args);
|
|
2101
|
+
}
|
|
2102
|
+
|
|
2103
|
+
let _asyncRequestStore;
|
|
2104
|
+
if (isServer) {
|
|
2105
|
+
import('node:async_hooks').then((module) => {
|
|
2106
|
+
_asyncRequestStore = new module.AsyncLocalStorage();
|
|
2107
|
+
}).catch((err) => {
|
|
2108
|
+
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", err);
|
|
2109
|
+
});
|
|
2110
|
+
}
|
|
2111
|
+
|
|
2112
|
+
const ESCAPE_HTML = /[&<>]/g;
|
|
2113
|
+
const escapeHtml = (s) => {
|
|
2114
|
+
return s.replace(ESCAPE_HTML, (c) => {
|
|
2115
|
+
switch (c) {
|
|
2116
|
+
case "&":
|
|
2117
|
+
return "&";
|
|
2118
|
+
case "<":
|
|
2119
|
+
return "<";
|
|
2120
|
+
case ">":
|
|
2121
|
+
return ">";
|
|
2122
|
+
default:
|
|
2123
|
+
return "";
|
|
2124
|
+
}
|
|
2125
|
+
});
|
|
2126
|
+
};
|
|
2127
|
+
const COLOR_400 = "#006ce9";
|
|
2128
|
+
const COLOR_500 = "#713fc2";
|
|
2129
|
+
function minimalHtmlResponse(status, message) {
|
|
2130
|
+
if (typeof status !== "number") {
|
|
2131
|
+
status = 500;
|
|
2132
|
+
}
|
|
2133
|
+
if (typeof message === "string") {
|
|
2134
|
+
message = escapeHtml(message);
|
|
2135
|
+
} else {
|
|
2136
|
+
message = "";
|
|
2137
|
+
}
|
|
2138
|
+
const width = typeof message === "string" ? "600px" : "300px";
|
|
2139
|
+
const color = status >= 500 ? COLOR_500 : COLOR_400;
|
|
2140
|
+
return `
|
|
2141
|
+
<head>
|
|
2142
|
+
<meta charset="utf-8">
|
|
2143
|
+
<meta http-equiv="Status" content="${status}">
|
|
2144
|
+
<title>${status} ${message}</title>
|
|
2145
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
2146
|
+
<style>
|
|
2147
|
+
body { color: ${color}; background-color: #fafafa; padding: 30px; font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, Roboto, sans-serif; }
|
|
2148
|
+
p { max-width: ${width}; margin: 60px auto 30px auto; background: white; border-radius: 4px; box-shadow: 0px 0px 50px -20px ${color}; overflow: hidden; }
|
|
2149
|
+
strong { display: inline-block; padding: 15px; background: ${color}; color: white; }
|
|
2150
|
+
span { display: inline-block; padding: 15px; }
|
|
2151
|
+
</style>
|
|
2152
|
+
</head>
|
|
2153
|
+
<body><p><strong>${status}</strong> <span>${message}</span></p></body>
|
|
2154
|
+
`;
|
|
2155
|
+
}
|
|
2156
|
+
function getErrorHtml(status, e) {
|
|
2157
|
+
let message = "Server Error";
|
|
2158
|
+
if (e != null) {
|
|
2159
|
+
if (typeof e.message === "string") {
|
|
2160
|
+
message = e.message;
|
|
2161
|
+
} else {
|
|
2162
|
+
message = String(e);
|
|
2163
|
+
}
|
|
2164
|
+
}
|
|
2165
|
+
return `<html>` + minimalHtmlResponse(status, message) + `</html>`;
|
|
2166
|
+
}
|
|
2167
|
+
|
|
2168
|
+
async function runNextWithDeps(requestEv, rebuildRouteInfo, resolve, deps) {
|
|
2169
|
+
try {
|
|
2170
|
+
const isValidURL = (url) => new URL(url.pathname + url.search, url);
|
|
2171
|
+
isValidURL(requestEv.originalUrl);
|
|
2172
|
+
} catch {
|
|
2173
|
+
const status = 404;
|
|
2174
|
+
const message = "Resource Not Found";
|
|
2175
|
+
requestEv.status(status);
|
|
2176
|
+
requestEv.html(status, deps.getErrorHtml(status, message));
|
|
2177
|
+
return new deps.ServerError(status, message);
|
|
2178
|
+
}
|
|
2179
|
+
let rewriteAttempt = 1;
|
|
2180
|
+
async function runOnce() {
|
|
2181
|
+
try {
|
|
2182
|
+
await requestEv.next();
|
|
2183
|
+
} catch (e) {
|
|
2184
|
+
if (e instanceof deps.RedirectMessage) {
|
|
2185
|
+
const stream = requestEv.getWritableStream();
|
|
2186
|
+
await stream.close();
|
|
2187
|
+
return e;
|
|
2188
|
+
} else if (e instanceof deps.RewriteMessage) {
|
|
2189
|
+
if (rewriteAttempt > 50) {
|
|
2190
|
+
return new Error(`Infinite rewrite loop`);
|
|
2191
|
+
}
|
|
2192
|
+
rewriteAttempt += 1;
|
|
2193
|
+
const url = new URL(requestEv.url);
|
|
2194
|
+
url.pathname = e.pathname;
|
|
2195
|
+
const { loadedRoute, requestHandlers } = await rebuildRouteInfo(url);
|
|
2196
|
+
requestEv.resetRoute(loadedRoute, requestHandlers, url);
|
|
2197
|
+
return await runOnce();
|
|
2198
|
+
} else if (e instanceof deps.AbortMessage) {
|
|
2199
|
+
return;
|
|
2200
|
+
} else if (e instanceof deps.ServerError && !requestEv.headersSent) {
|
|
2201
|
+
const status = e.status;
|
|
2202
|
+
const accept = requestEv.request.headers.get("Accept");
|
|
2203
|
+
if (accept && !accept.includes("text/html")) {
|
|
2204
|
+
requestEv.headers.set("Content-Type", "application/qwik-json");
|
|
2205
|
+
requestEv.send(status, await _serialize(e.data));
|
|
2206
|
+
} else {
|
|
2207
|
+
requestEv.html(status, deps.getErrorHtml(status, e.data));
|
|
2208
|
+
}
|
|
2209
|
+
return e;
|
|
2210
|
+
}
|
|
2211
|
+
if (!isDev) {
|
|
2212
|
+
try {
|
|
2213
|
+
if (!requestEv.headersSent) {
|
|
2214
|
+
requestEv.headers.set("content-type", "text/html; charset=utf-8");
|
|
2215
|
+
requestEv.cacheControl({
|
|
2216
|
+
noCache: true
|
|
2217
|
+
});
|
|
2218
|
+
requestEv.status(500);
|
|
2219
|
+
}
|
|
2220
|
+
const stream = requestEv.getWritableStream();
|
|
2221
|
+
if (!stream.locked) {
|
|
2222
|
+
const writer = stream.getWriter();
|
|
2223
|
+
await writer.write(deps.encoder.encode(deps.getErrorHtml(500, "Internal Server Error")));
|
|
2224
|
+
await writer.close();
|
|
2225
|
+
}
|
|
2226
|
+
} catch {
|
|
2227
|
+
console.error("Unable to render error page");
|
|
2228
|
+
}
|
|
2229
|
+
}
|
|
2230
|
+
return e instanceof Error || typeof e === "object" && e !== null ? e : new Error(String(e));
|
|
2231
|
+
}
|
|
2232
|
+
}
|
|
2233
|
+
try {
|
|
2234
|
+
return await runOnce();
|
|
2235
|
+
} finally {
|
|
2236
|
+
if (!requestEv.isDirty()) {
|
|
2237
|
+
resolve(null);
|
|
2238
|
+
}
|
|
2239
|
+
}
|
|
2240
|
+
}
|
|
2241
|
+
function runQwikRouterWithDeps(serverRequestEv, loadedRoute, requestHandlers, rebuildRouteInfo, basePathname, deps) {
|
|
2242
|
+
let resolve;
|
|
2243
|
+
const responsePromise = new Promise((r) => resolve = r);
|
|
2244
|
+
const requestEv = deps.createRequestEvent(serverRequestEv, loadedRoute, requestHandlers, basePathname, resolve);
|
|
2245
|
+
return {
|
|
2246
|
+
response: responsePromise,
|
|
2247
|
+
requestEv,
|
|
2248
|
+
completion: deps.asyncRequestStore ? deps.asyncRequestStore.run(requestEv, runNextWithDeps, requestEv, rebuildRouteInfo, resolve, deps) : runNextWithDeps(requestEv, rebuildRouteInfo, resolve, deps)
|
|
2249
|
+
};
|
|
2250
|
+
}
|
|
2251
|
+
|
|
2252
|
+
function runQwikRouter(serverRequestEv, loadedRoute, requestHandlers, rebuildRouteInfo, basePathname = "/") {
|
|
2253
|
+
return runQwikRouterWithDeps(serverRequestEv, loadedRoute, requestHandlers, rebuildRouteInfo, basePathname, {
|
|
2254
|
+
AbortMessage,
|
|
2255
|
+
RedirectMessage,
|
|
2256
|
+
RewriteMessage,
|
|
2257
|
+
ServerError,
|
|
2258
|
+
asyncRequestStore: _asyncRequestStore,
|
|
2259
|
+
createRequestEvent,
|
|
2260
|
+
encoder,
|
|
2261
|
+
getErrorHtml
|
|
2262
|
+
});
|
|
2263
|
+
}
|
|
2264
|
+
|
|
2265
|
+
const staticWorkerThreadDeps = {
|
|
2266
|
+
RequestEvShareQData,
|
|
2267
|
+
loadRoute,
|
|
2268
|
+
renderQwikMiddleware,
|
|
2269
|
+
resolveRequestHandlers,
|
|
2270
|
+
getRouteMatchPathname,
|
|
2271
|
+
runQwikRouter
|
|
2272
|
+
};
|
|
2273
|
+
const createNoopWritableStream = () => new WritableStream();
|
|
2274
|
+
async function loadSerialize() {
|
|
2275
|
+
const { _serialize: serialize } = await import('@qwik.dev/core/internal');
|
|
2276
|
+
return serialize;
|
|
2277
|
+
}
|
|
2278
|
+
function isRedirectMessage(value) {
|
|
2279
|
+
return typeof value === "object" && value !== null && value.constructor?.name === "RedirectMessage";
|
|
2280
|
+
}
|
|
2281
|
+
async function requestHandlerForSsg(serverRequestEv, opts, deps) {
|
|
2282
|
+
const { render, checkOrigin, qwikRouterConfig } = opts;
|
|
2283
|
+
if (!qwikRouterConfig) {
|
|
2284
|
+
throw new Error("qwikRouterConfig is required.");
|
|
2285
|
+
}
|
|
2286
|
+
const { pathname, isInternal } = deps.getRouteMatchPathname(serverRequestEv.url.pathname);
|
|
2287
|
+
if (pathname === "/.well-known" || pathname.startsWith("/.well-known/")) {
|
|
2288
|
+
return null;
|
|
2289
|
+
}
|
|
2290
|
+
const { routes, serverPlugins, cacheModules } = qwikRouterConfig;
|
|
2291
|
+
const loadedRoute = await deps.loadRoute(routes, cacheModules, pathname, isInternal);
|
|
2292
|
+
const requestHandlers = deps.resolveRequestHandlers(serverPlugins, loadedRoute, serverRequestEv.request.method, checkOrigin ?? true, deps.renderQwikMiddleware(render), isInternal);
|
|
2293
|
+
if (qwikRouterConfig.fallthrough && loadedRoute.$notFound$) {
|
|
2294
|
+
return null;
|
|
2295
|
+
}
|
|
2296
|
+
const rebuildRouteInfo = async (url) => {
|
|
2297
|
+
const { pathname: pathname2 } = deps.getRouteMatchPathname(url.pathname);
|
|
2298
|
+
const loadedRoute2 = await deps.loadRoute(routes, cacheModules, pathname2, isInternal);
|
|
2299
|
+
const requestHandlers2 = deps.resolveRequestHandlers(serverPlugins, loadedRoute2, serverRequestEv.request.method, checkOrigin ?? true, deps.renderQwikMiddleware(render), isInternal);
|
|
2300
|
+
return {
|
|
2301
|
+
loadedRoute: loadedRoute2,
|
|
2302
|
+
requestHandlers: requestHandlers2
|
|
2303
|
+
};
|
|
2304
|
+
};
|
|
2305
|
+
return deps.runQwikRouter(serverRequestEv, loadedRoute, requestHandlers, rebuildRouteInfo, qwikRouterConfig.basePathname);
|
|
2306
|
+
}
|
|
2307
|
+
async function workerRender(sys, opts, staticRoute, pendingPromises, callback, deps) {
|
|
2308
|
+
const url = new URL(staticRoute.pathname, opts.origin);
|
|
2309
|
+
const result = {
|
|
2310
|
+
type: "render",
|
|
2311
|
+
pathname: staticRoute.pathname,
|
|
2312
|
+
url: url.href,
|
|
2313
|
+
ok: false,
|
|
2314
|
+
error: null,
|
|
2315
|
+
filePath: null,
|
|
2316
|
+
contentType: null,
|
|
2317
|
+
resourceType: null
|
|
2318
|
+
};
|
|
2319
|
+
try {
|
|
2320
|
+
let routeWriter = null;
|
|
2321
|
+
let closeResolved;
|
|
2322
|
+
const closePromise = new Promise((closePromiseResolve) => {
|
|
2323
|
+
closeResolved = closePromiseResolve;
|
|
2324
|
+
});
|
|
2325
|
+
const request = new Request(url);
|
|
2326
|
+
const requestCtx = {
|
|
2327
|
+
mode: "static",
|
|
2328
|
+
locale: void 0,
|
|
2329
|
+
url,
|
|
2330
|
+
request,
|
|
2331
|
+
env: {
|
|
2332
|
+
get(key) {
|
|
2333
|
+
return sys.getEnv(key);
|
|
2334
|
+
}
|
|
2335
|
+
},
|
|
2336
|
+
platform: sys.platform,
|
|
2337
|
+
getClientConn: () => {
|
|
2338
|
+
return {};
|
|
2339
|
+
},
|
|
2340
|
+
getWritableStream: (status, headers, _, _r, requestEv) => {
|
|
2341
|
+
result.ok = status >= 200 && status < 300;
|
|
2342
|
+
if (!result.ok) {
|
|
2343
|
+
return createNoopWritableStream();
|
|
2344
|
+
}
|
|
2345
|
+
result.contentType = (headers.get("Content-Type") || "").toLowerCase();
|
|
2346
|
+
const isHtml = result.contentType.includes("text/html");
|
|
2347
|
+
const is404ErrorPage = url.pathname.endsWith("/404.html");
|
|
2348
|
+
const routeFilePath = sys.getRouteFilePath(url.pathname, isHtml);
|
|
2349
|
+
if (is404ErrorPage) {
|
|
2350
|
+
result.resourceType = "404";
|
|
2351
|
+
} else if (isHtml) {
|
|
2352
|
+
result.resourceType = "page";
|
|
2353
|
+
}
|
|
2354
|
+
const hasRouteWriter = isHtml ? opts.emitHtml !== false : true;
|
|
2355
|
+
const writeQDataEnabled = isHtml && opts.emitData !== false;
|
|
2356
|
+
const stream = new WritableStream({
|
|
2357
|
+
async start() {
|
|
2358
|
+
try {
|
|
2359
|
+
if (hasRouteWriter || writeQDataEnabled) {
|
|
2360
|
+
await sys.ensureDir(routeFilePath);
|
|
2361
|
+
}
|
|
2362
|
+
if (hasRouteWriter) {
|
|
2363
|
+
routeWriter = sys.createWriteStream(routeFilePath);
|
|
2364
|
+
routeWriter.on("error", (e) => {
|
|
2365
|
+
console.error(e);
|
|
2366
|
+
routeWriter = null;
|
|
2367
|
+
result.error = {
|
|
2368
|
+
message: e.message,
|
|
2369
|
+
stack: e.stack
|
|
2370
|
+
};
|
|
2371
|
+
});
|
|
2372
|
+
}
|
|
2373
|
+
} catch (e) {
|
|
2374
|
+
console.error("Error during stream start", staticRoute.pathname, e);
|
|
2375
|
+
routeWriter = null;
|
|
2376
|
+
result.error = {
|
|
2377
|
+
message: String(e),
|
|
2378
|
+
stack: e.stack || ""
|
|
2379
|
+
};
|
|
2380
|
+
}
|
|
2381
|
+
},
|
|
2382
|
+
write(chunk) {
|
|
2383
|
+
try {
|
|
2384
|
+
if (routeWriter) {
|
|
2385
|
+
routeWriter.write(Buffer.from(chunk.buffer));
|
|
2386
|
+
}
|
|
2387
|
+
} catch (e) {
|
|
2388
|
+
console.error("Error during stream write", staticRoute.pathname, e);
|
|
2389
|
+
routeWriter = null;
|
|
2390
|
+
result.error = {
|
|
2391
|
+
message: String(e),
|
|
2392
|
+
stack: e.stack || ""
|
|
2393
|
+
};
|
|
2394
|
+
}
|
|
2395
|
+
},
|
|
2396
|
+
async close() {
|
|
2397
|
+
const writePromises = [];
|
|
2398
|
+
try {
|
|
2399
|
+
if (writeQDataEnabled) {
|
|
2400
|
+
const qData = requestEv.sharedMap.get(deps.RequestEvShareQData);
|
|
2401
|
+
if (qData && !is404ErrorPage) {
|
|
2402
|
+
const qDataFilePath = sys.getDataFilePath(url.pathname);
|
|
2403
|
+
const dataWriter = sys.createWriteStream(qDataFilePath);
|
|
2404
|
+
dataWriter.on("error", (e) => {
|
|
2405
|
+
console.error(e);
|
|
2406
|
+
result.error = {
|
|
2407
|
+
message: e.message,
|
|
2408
|
+
stack: e.stack
|
|
2409
|
+
};
|
|
2410
|
+
});
|
|
2411
|
+
const serialized = await deps.serialize(qData);
|
|
2412
|
+
dataWriter.write(serialized);
|
|
2413
|
+
writePromises.push(new Promise((resolve) => {
|
|
2414
|
+
result.filePath = routeFilePath;
|
|
2415
|
+
dataWriter.end(resolve);
|
|
2416
|
+
}));
|
|
2417
|
+
}
|
|
2418
|
+
}
|
|
2419
|
+
if (routeWriter) {
|
|
2420
|
+
writePromises.push(new Promise((resolve) => {
|
|
2421
|
+
result.filePath = routeFilePath;
|
|
2422
|
+
routeWriter.end(resolve);
|
|
2423
|
+
}).finally(closeResolved));
|
|
2424
|
+
}
|
|
2425
|
+
if (writePromises.length > 0) {
|
|
2426
|
+
await Promise.all(writePromises);
|
|
2427
|
+
}
|
|
2428
|
+
} catch (e) {
|
|
2429
|
+
console.error("Error during stream close", staticRoute.pathname, e);
|
|
2430
|
+
routeWriter = null;
|
|
2431
|
+
result.error = {
|
|
2432
|
+
message: String(e),
|
|
2433
|
+
stack: e.stack || ""
|
|
2434
|
+
};
|
|
2435
|
+
}
|
|
2436
|
+
}
|
|
2437
|
+
});
|
|
2438
|
+
return stream;
|
|
2439
|
+
}
|
|
2440
|
+
};
|
|
2441
|
+
const promise = requestHandlerForSsg(requestCtx, opts, deps).then((rsp) => {
|
|
2442
|
+
if (rsp != null) {
|
|
2443
|
+
return rsp.completion.then((r) => {
|
|
2444
|
+
if (routeWriter) {
|
|
2445
|
+
return closePromise.then(() => r);
|
|
2446
|
+
}
|
|
2447
|
+
return r;
|
|
2448
|
+
});
|
|
2449
|
+
}
|
|
2450
|
+
}).then((e) => {
|
|
2451
|
+
if (e !== void 0) {
|
|
2452
|
+
if (isRedirectMessage(e)) {
|
|
2453
|
+
return;
|
|
2454
|
+
}
|
|
2455
|
+
if (e instanceof Error) {
|
|
2456
|
+
result.error = {
|
|
2457
|
+
message: e.message,
|
|
2458
|
+
stack: e.stack
|
|
2459
|
+
};
|
|
2460
|
+
} else {
|
|
2461
|
+
result.error = {
|
|
2462
|
+
message: String(e),
|
|
2463
|
+
stack: void 0
|
|
2464
|
+
};
|
|
2465
|
+
}
|
|
2466
|
+
console.error("Error during request handling", staticRoute.pathname, e);
|
|
2467
|
+
}
|
|
2468
|
+
}).catch((e) => {
|
|
2469
|
+
console.error("Unhandled error during request handling", staticRoute.pathname, e);
|
|
2470
|
+
result.error = {
|
|
2471
|
+
message: String(e),
|
|
2472
|
+
stack: e.stack || ""
|
|
2473
|
+
};
|
|
2474
|
+
}).finally(() => {
|
|
2475
|
+
pendingPromises.delete(promise);
|
|
2476
|
+
callback(result);
|
|
2477
|
+
});
|
|
2478
|
+
pendingPromises.add(promise);
|
|
2479
|
+
} catch (e) {
|
|
2480
|
+
console.error("Error during render", staticRoute.pathname, e);
|
|
2481
|
+
if (e instanceof Error) {
|
|
2482
|
+
result.error = {
|
|
2483
|
+
message: e.message,
|
|
2484
|
+
stack: e.stack
|
|
2485
|
+
};
|
|
2486
|
+
} else {
|
|
2487
|
+
result.error = {
|
|
2488
|
+
message: String(e),
|
|
2489
|
+
stack: void 0
|
|
2490
|
+
};
|
|
2491
|
+
}
|
|
2492
|
+
callback(result);
|
|
2493
|
+
}
|
|
2494
|
+
}
|
|
2495
|
+
async function workerThread(sys) {
|
|
2496
|
+
delete globalThis.__qwik;
|
|
2497
|
+
const opts = sys.getOptions();
|
|
2498
|
+
const pendingPromises = /* @__PURE__ */ new Set();
|
|
2499
|
+
const deps = {
|
|
2500
|
+
...staticWorkerThreadDeps,
|
|
2501
|
+
serialize: await loadSerialize()
|
|
2502
|
+
};
|
|
2503
|
+
process.on("uncaughtException", (e) => {
|
|
2504
|
+
console.error("Worker uncaught exception (suppressed):", e.message);
|
|
2505
|
+
});
|
|
2506
|
+
process.on("unhandledRejection", (e) => {
|
|
2507
|
+
console.error("Worker unhandled rejection (suppressed):", e instanceof Error ? e.message : e);
|
|
2508
|
+
});
|
|
2509
|
+
const onMessage = async (msg) => {
|
|
2510
|
+
switch (msg.type) {
|
|
2511
|
+
case "render": {
|
|
2512
|
+
return new Promise((resolve) => {
|
|
2513
|
+
workerRender(sys, opts, msg, pendingPromises, resolve, deps).catch((e) => {
|
|
2514
|
+
console.error("Error during render", msg.pathname, e);
|
|
2515
|
+
resolve({
|
|
2516
|
+
type: "render",
|
|
2517
|
+
pathname: msg.pathname,
|
|
2518
|
+
url: "",
|
|
2519
|
+
ok: false,
|
|
2520
|
+
error: {
|
|
2521
|
+
message: e instanceof Error ? e.message : String(e),
|
|
2522
|
+
stack: e instanceof Error ? e.stack : void 0
|
|
2523
|
+
},
|
|
2524
|
+
filePath: null,
|
|
2525
|
+
contentType: null,
|
|
2526
|
+
resourceType: null
|
|
2527
|
+
});
|
|
2528
|
+
});
|
|
2529
|
+
});
|
|
2530
|
+
}
|
|
2531
|
+
case "close": {
|
|
2532
|
+
if (pendingPromises.size) {
|
|
2533
|
+
const promises = Array.from(pendingPromises);
|
|
2534
|
+
pendingPromises.clear();
|
|
2535
|
+
await Promise.all(promises);
|
|
2536
|
+
}
|
|
2537
|
+
return {
|
|
2538
|
+
type: "close"
|
|
2539
|
+
};
|
|
2540
|
+
}
|
|
2541
|
+
}
|
|
2542
|
+
};
|
|
2543
|
+
parentPort?.on("message", async (msg) => {
|
|
2544
|
+
try {
|
|
2545
|
+
parentPort?.postMessage(await onMessage(msg));
|
|
2546
|
+
} catch (e) {
|
|
2547
|
+
if (msg.type === "render") {
|
|
2548
|
+
const error = e instanceof Error ? e : new Error(String(e));
|
|
2549
|
+
parentPort?.postMessage({
|
|
2550
|
+
type: "render",
|
|
2551
|
+
pathname: msg.pathname,
|
|
2552
|
+
url: "",
|
|
2553
|
+
ok: false,
|
|
2554
|
+
error: {
|
|
2555
|
+
message: error.message,
|
|
2556
|
+
stack: error.stack
|
|
2557
|
+
},
|
|
2558
|
+
filePath: null,
|
|
2559
|
+
contentType: null,
|
|
2560
|
+
resourceType: null
|
|
2561
|
+
});
|
|
2562
|
+
} else {
|
|
2563
|
+
console.error("Worker message handler error", e);
|
|
2564
|
+
}
|
|
2565
|
+
}
|
|
2566
|
+
if (msg.type === "close") {
|
|
2567
|
+
parentPort?.close();
|
|
2568
|
+
}
|
|
2569
|
+
});
|
|
2570
|
+
}
|
|
2571
|
+
|
|
2572
|
+
export { workerThread };
|