@qwik.dev/router 2.0.0-beta.37 → 2.0.0-beta.39

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