@qwik.dev/router 2.0.0-beta.43 → 2.0.0-beta.45

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 (38) hide show
  1. package/lib/adapters/azure-swa/vite/index.mjs +2 -1
  2. package/lib/adapters/bun-server/vite/index.mjs +2 -1
  3. package/lib/adapters/cloud-run/vite/index.mjs +2 -1
  4. package/lib/adapters/cloudflare-pages/vite/index.mjs +2 -1
  5. package/lib/adapters/deno-server/vite/index.mjs +2 -1
  6. package/lib/adapters/netlify-edge/vite/index.mjs +2 -1
  7. package/lib/adapters/node-server/vite/index.mjs +2 -1
  8. package/lib/adapters/shared/vite/index.mjs +35 -31
  9. package/lib/adapters/ssg/vite/index.mjs +4 -2
  10. package/lib/adapters/vercel-edge/vite/index.mjs +18 -15
  11. package/lib/chunks/fs.mjs +26 -23
  12. package/lib/chunks/head.qwik.mjs +611 -445
  13. package/lib/chunks/http-error.qwik.mjs +8 -7
  14. package/lib/chunks/pathname.mjs +9 -8
  15. package/lib/chunks/request-path.mjs +8 -4
  16. package/lib/chunks/routes.mjs +14 -14
  17. package/lib/chunks/server-error.mjs +11 -5
  18. package/lib/chunks/{url.mjs → static-file.mjs} +12 -2
  19. package/lib/chunks/system.mjs +18 -17
  20. package/lib/chunks/user-response.mjs +419 -323
  21. package/lib/chunks/worker-thread.mjs +87 -86
  22. package/lib/index.d.ts +47 -59
  23. package/lib/index.qwik.mjs +550 -496
  24. package/lib/middleware/aws-lambda/index.mjs +6 -3
  25. package/lib/middleware/azure-swa/index.mjs +4 -2
  26. package/lib/middleware/bun/index.mjs +12 -12
  27. package/lib/middleware/cloudflare-pages/index.mjs +19 -4
  28. package/lib/middleware/deno/index.mjs +12 -12
  29. package/lib/middleware/firebase/index.mjs +4 -2
  30. package/lib/middleware/netlify-edge/index.mjs +4 -2
  31. package/lib/middleware/node/index.mjs +16 -15
  32. package/lib/middleware/request-handler/index.mjs +35 -24
  33. package/lib/middleware/vercel-edge/index.mjs +4 -2
  34. package/lib/service-worker/index.mjs +2 -1
  35. package/lib/ssg/index.mjs +20 -16
  36. package/lib/vite/index.d.ts +1 -1
  37. package/lib/vite/index.mjs +596 -586
  38. package/package.json +5 -5
@@ -1,5 +1,5 @@
1
+ import { A as matchesRouteLoaderId, E as getRouteLoaderValues, J as QACTION_KEY, L as setRouteLoaders, M as resolveRouteLoaderByHash, Q as _asyncRequestStore, T as getRouteLoaderResponse, X as QFN_KEY, Y as QDATA_KEY, Z as Q_ROUTE, a as isPromise, f as FULLPATH_HEADER, g as clearRouteLoaderData, k as loadRouteLoader, r as resolveRouteConfig, w as getRouteLoaderCtx, x as getLoaderRequestEvent } from "./head.qwik.mjs";
1
2
  import { t as ensureSlash } from "./pathname.mjs";
2
- import { C as getRouteLoaderValues, D as loadRouteLoader, G as QACTION_KEY, J as Q_ROUTE, K as QDATA_KEY, N as setRouteLoaders, O as matchesRouteLoaderId, S as getRouteLoaderResponse, Y as _asyncRequestStore, a as isPromise, f as FULLPATH_HEADER, h as clearRouteLoaderData, k as resolveRouteLoaderByHash, q as QFN_KEY, r as resolveRouteConfig, v as getLoaderRequestEvent, x as getRouteLoaderCtx } from "./head.qwik.mjs";
3
3
  import { a as QLoaderId, c as resolveValidInternalFullPathname, i as QActionId, s as recognizeRequest, t as IsQAction, u as trimRecognizedInternalPathname } from "./request-path.mjs";
4
4
  import { i as RedirectMessage, n as throwIfControlFlowSignal, r as AbortMessage, t as ServerError } from "./server-error.mjs";
5
5
  import { inlinedQrl, isDev } from "@qwik.dev/core";
@@ -7,7 +7,8 @@ import { _deserialize, _serialize, _verifySerializable, isDev as isDev$1 } from
7
7
  /**
8
8
  * FNV-1a 32-bit hash for generating eTags from response data. Cheap to compute, sufficient
9
9
  * collision resistance for cache validation (not cryptographic).
10
- */ function hash(str) {
10
+ */
11
+ function hash(str) {
11
12
  let hash = 2166136261;
12
13
  for (let i = 0; i < str.length; i++) {
13
14
  hash ^= str.charCodeAt(i);
@@ -21,7 +22,8 @@ import { _deserialize, _serialize, _verifySerializable, isDev as isDev$1 } from
21
22
  * character outside RFC 7232's `etagc` grammar (printable ASCII except DQUOTE — no escape mechanism
22
23
  * exists, and non-ASCII bytes are mangled by many HTTP stacks even though `obs-text` technically
23
24
  * permits them). Idempotent.
24
- */ function normalizeETag(raw) {
25
+ */
26
+ function normalizeETag(raw) {
25
27
  let tag = raw.trim();
26
28
  if (tag.endsWith("\"") && tag.startsWith("W/\"")) tag = tag.slice(3);
27
29
  tag = tag.replace(/[^!#-~]/g, "");
@@ -35,7 +37,8 @@ function setETagHeader(requestEv, normalizedETag) {
35
37
  * Set the strong ETag header on the response and check the request's `If-None-Match` against it.
36
38
  * The eTag argument must already be normalized. Returns true if a 304 was sent (caller should stop
37
39
  * processing).
38
- */ function performETagMatch(requestEv, normalizedETag) {
40
+ */
41
+ function performETagMatch(requestEv, normalizedETag) {
39
42
  setETagHeader(requestEv, normalizedETag);
40
43
  const ifNoneMatch = requestEv.request.headers.get("If-None-Match");
41
44
  if (ifNoneMatch) {
@@ -100,6 +103,20 @@ var UNIT = {
100
103
  days: 86400,
101
104
  weeks: 604800
102
105
  };
106
+ var createSetCookieValue = (cookieName, cookieValue, options) => {
107
+ const c = [`${cookieName}=${cookieValue}`];
108
+ if (typeof options.domain === "string") c.push(`Domain=${options.domain}`);
109
+ if (typeof options.maxAge === "number") c.push(`Max-Age=${options.maxAge}`);
110
+ else if (Array.isArray(options.maxAge)) c.push(`Max-Age=${options.maxAge[0] * UNIT[options.maxAge[1]]}`);
111
+ else if (typeof options.expires === "number" || typeof options.expires == "string") c.push(`Expires=${options.expires}`);
112
+ else if (options.expires instanceof Date) c.push(`Expires=${options.expires.toUTCString()}`);
113
+ if (options.httpOnly) c.push("HttpOnly");
114
+ if (typeof options.path === "string") c.push(`Path=${options.path}`);
115
+ const sameSite = resolveSameSite(options.sameSite);
116
+ if (sameSite) c.push(`SameSite=${sameSite}`);
117
+ if (options.secure) c.push("Secure");
118
+ return c.join("; ");
119
+ };
103
120
  function tryDecodeUriComponent(str) {
104
121
  try {
105
122
  return decodeURIComponent(str);
@@ -123,20 +140,6 @@ function resolveSameSite(sameSite) {
123
140
  if (sameSite === false) return "None";
124
141
  if (sameSite) return SAMESITE[sameSite];
125
142
  }
126
- var createSetCookieValue = (cookieName, cookieValue, options) => {
127
- const c = [`${cookieName}=${cookieValue}`];
128
- if (typeof options.domain === "string") c.push(`Domain=${options.domain}`);
129
- if (typeof options.maxAge === "number") c.push(`Max-Age=${options.maxAge}`);
130
- else if (Array.isArray(options.maxAge)) c.push(`Max-Age=${options.maxAge[0] * UNIT[options.maxAge[1]]}`);
131
- else if (typeof options.expires === "number" || typeof options.expires == "string") c.push(`Expires=${options.expires}`);
132
- else if (options.expires instanceof Date) c.push(`Expires=${options.expires.toUTCString()}`);
133
- if (options.httpOnly) c.push("HttpOnly");
134
- if (typeof options.path === "string") c.push(`Path=${options.path}`);
135
- const sameSite = resolveSameSite(options.sameSite);
136
- if (sameSite) c.push(`SameSite=${sameSite}`);
137
- if (options.secure) c.push("Secure");
138
- return c.join("; ");
139
- };
140
143
  var REQ_COOKIE = Symbol("request-cookies");
141
144
  var RES_COOKIE = Symbol("response-cookies");
142
145
  var LIVE_COOKIE = Symbol("live-cookies");
@@ -192,7 +195,8 @@ var Cookie = class {
192
195
  return Object.values(this[RES_COOKIE]);
193
196
  }
194
197
  };
195
- /** @public */ var mergeHeadersCookies = (headers, cookies) => {
198
+ /** @public */
199
+ var mergeHeadersCookies = (headers, cookies) => {
196
200
  const cookieHeaders = cookies.headers();
197
201
  if (cookieHeaders.length > 0) {
198
202
  const newHeaders = new Headers(headers);
@@ -201,10 +205,12 @@ var Cookie = class {
201
205
  }
202
206
  return headers;
203
207
  };
204
- /** @public */ var RewriteMessage = class extends AbortMessage {
208
+ /** @public */
209
+ var RewriteMessage = class extends AbortMessage {
205
210
  pathname;
206
211
  constructor(pathname) {
207
- super(), this.pathname = pathname;
212
+ super();
213
+ this.pathname = pathname;
208
214
  }
209
215
  };
210
216
  var encoder = /*#__PURE__*/ new TextEncoder();
@@ -227,105 +233,6 @@ var RequestEvShareServerTiming = "@serverTiming";
227
233
  var RequestEvETagCacheKey = "@eTagCacheKey";
228
234
  var RequestEvErrorBoundaryCaught = "@errorBoundaryCaught";
229
235
  var RequestEvHttpStatusMessage = "@httpStatusMessage";
230
- function getRequestRoute(requestEv) {
231
- return requestEv[RequestEvRoute];
232
- }
233
- function getRequestMode(requestEv) {
234
- return requestEv[RequestEvMode];
235
- }
236
- var ABORT_INDEX = Number.MAX_SAFE_INTEGER;
237
- var isDangerousKey = (k) => k === "__proto__" || k === "constructor" || k === "prototype";
238
- var isArrayIndexKey = (k) => /^(0|[1-9]\d*)$/.test(k);
239
- var createFormPathNode = () => ({
240
- children: /* @__PURE__ */ new Map(),
241
- isArray: true
242
- });
243
- var getFormPathTree = (formData) => {
244
- const root = createFormPathNode();
245
- for (const [name] of formData) {
246
- const keys = name.split(".");
247
- let hasDangerousKey = false;
248
- for (const key of keys) if (isDangerousKey(key)) {
249
- hasDangerousKey = true;
250
- break;
251
- }
252
- if (hasDangerousKey) continue;
253
- let pathNode = root;
254
- for (let i = 0; i < keys.length - 1; i++) {
255
- const key = keys[i];
256
- if (key.endsWith("[]")) break;
257
- let childNode = pathNode.children.get(key);
258
- if (!childNode) {
259
- childNode = createFormPathNode();
260
- pathNode.children.set(key, childNode);
261
- }
262
- if (!isArrayIndexKey(keys[i + 1])) childNode.isArray = false;
263
- pathNode = childNode;
264
- }
265
- }
266
- return root;
267
- };
268
- var formToObj = (formData) => {
269
- /**
270
- * Convert FormData to object Handle nested form input using dot notation Handle array input using
271
- * indexed dot notation (name.0, name.0) or bracket notation (name[]), the later is needed for
272
- * multiselects Create values object by form data entries
273
- */ const values = Object.create(null);
274
- const pathTree = getFormPathTree(formData);
275
- for (const [name, value] of formData) {
276
- const keys = name.split(".");
277
- let hasDangerousKey = false;
278
- for (let i = 0; i < keys.length; i++) if (isDangerousKey(keys[i])) {
279
- hasDangerousKey = true;
280
- break;
281
- }
282
- if (hasDangerousKey) continue;
283
- let object = values;
284
- let pathNode = pathTree;
285
- for (let i = 0; i < keys.length; i++) {
286
- const key = keys[i];
287
- if (key.endsWith("[]")) {
288
- const arrayKey = key.slice(0, -2);
289
- if (isDangerousKey(arrayKey)) break;
290
- const existingValue = object[arrayKey];
291
- if (existingValue !== void 0 && !Array.isArray(existingValue)) break;
292
- object[arrayKey] = existingValue || [];
293
- object[arrayKey].push(value);
294
- break;
295
- }
296
- if (Array.isArray(object) && !isArrayIndexKey(key)) break;
297
- if (i < keys.length - 1) {
298
- const childNode = pathNode.children.get(key);
299
- const nextValue = object[key];
300
- if (nextValue !== void 0) {
301
- object = nextValue;
302
- pathNode = childNode;
303
- continue;
304
- }
305
- object = object[key] = childNode.isArray ? [] : Object.create(null);
306
- pathNode = childNode;
307
- } else object[key] = value;
308
- }
309
- }
310
- return values;
311
- };
312
- var parseRequest = async ({ request, method, query }, sharedMap) => {
313
- const type = getContentType(request.headers);
314
- if (type === "application/x-www-form-urlencoded" || type === "multipart/form-data") {
315
- const formData = await request.formData();
316
- sharedMap.set(RequestEvSharedActionFormData, formData);
317
- return formToObj(formData);
318
- } else if (type === "application/json") return await request.json();
319
- else if (type === "application/qwik-json") {
320
- if (method === "GET" && query.has("qdata")) {
321
- const data = query.get(QDATA_KEY);
322
- if (data) try {
323
- return await _deserialize(decodeURIComponent(data));
324
- } catch {}
325
- }
326
- return await _deserialize(await request.text());
327
- }
328
- };
329
236
  function createRequestEvent(serverRequestEv, loadedRoute, requestHandlers, basePathname, resolved) {
330
237
  const { request, platform, env } = serverRequestEv;
331
238
  const sharedMap = /* @__PURE__ */ new Map();
@@ -444,13 +351,13 @@ function createRequestEvent(serverRequestEv, loadedRoute, requestHandlers, baseP
444
351
  check();
445
352
  headers.set(target, createCacheControl(cacheControl));
446
353
  },
447
- resolveValue: async (loaderOrAction) => {
354
+ resolveValue: (async (loaderOrAction) => {
448
355
  if (loaderOrAction.__brand === "server_loader") {
449
356
  const loaderValues = getRouteLoaderValues(requestEv);
450
357
  if (loaderOrAction.__id in loaderValues) return loaderValues[loaderOrAction.__id];
451
358
  return loadRouteLoader(loaderOrAction, requestEv);
452
359
  }
453
- },
360
+ }),
454
361
  status: (statusCode) => {
455
362
  if (typeof statusCode === "number") {
456
363
  check();
@@ -472,8 +379,8 @@ function createRequestEvent(serverRequestEv, loadedRoute, requestHandlers, baseP
472
379
  check();
473
380
  status = statusCode;
474
381
  if (url) {
475
- if (/^\/\//.test(url) || /([^:])\/\/+/.test(url)) {
476
- const fixedURL = url.replace(/^\/\/+/, "/").replace(/([^:])\/\/+/g, "$1/");
382
+ if (/^[/\\]{2,}/.test(url) || /([^:])[/\\]{2,}/.test(url)) {
383
+ const fixedURL = url.replace(/^[/\\]{2,}/, "/").replace(/([^:])[/\\]{2,}/g, "$1/");
477
384
  console.warn(`Redirect URL ${url} is invalid, fixing to ${fixedURL}`);
478
385
  url = fixedURL;
479
386
  }
@@ -535,6 +442,107 @@ function createRequestEvent(serverRequestEv, loadedRoute, requestHandlers, baseP
535
442
  };
536
443
  return requestEv;
537
444
  }
445
+ function getRequestRoute(requestEv) {
446
+ return requestEv[RequestEvRoute];
447
+ }
448
+ function getRequestMode(requestEv) {
449
+ return requestEv[RequestEvMode];
450
+ }
451
+ var ABORT_INDEX = Number.MAX_SAFE_INTEGER;
452
+ var parseRequest = async ({ request, method, query }, sharedMap) => {
453
+ const type = getContentType(request.headers);
454
+ if (type === "application/x-www-form-urlencoded" || type === "multipart/form-data") {
455
+ const formData = await request.formData();
456
+ sharedMap.set(RequestEvSharedActionFormData, formData);
457
+ return formToObj(formData);
458
+ } else if (type === "application/json") return await request.json();
459
+ else if (type === "application/qwik-json") {
460
+ if (method === "GET" && query.has("qdata")) {
461
+ const data = query.get(QDATA_KEY);
462
+ if (data) try {
463
+ return await _deserialize(decodeURIComponent(data));
464
+ } catch {}
465
+ }
466
+ return await _deserialize(await request.text());
467
+ }
468
+ };
469
+ var isDangerousKey = (k) => k === "__proto__" || k === "constructor" || k === "prototype";
470
+ var MAX_FORM_ARRAY_LENGTH = 1e4;
471
+ var isArrayIndexKey = (k) => /^(0|[1-9]\d*)$/.test(k) && Number(k) < MAX_FORM_ARRAY_LENGTH;
472
+ var createFormPathNode = () => ({
473
+ children: /* @__PURE__ */ new Map(),
474
+ isArray: true
475
+ });
476
+ var getFormPathTree = (formData) => {
477
+ const root = createFormPathNode();
478
+ for (const [name] of formData) {
479
+ const keys = name.split(".");
480
+ let hasDangerousKey = false;
481
+ for (const key of keys) if (isDangerousKey(key)) {
482
+ hasDangerousKey = true;
483
+ break;
484
+ }
485
+ if (hasDangerousKey) continue;
486
+ let pathNode = root;
487
+ for (let i = 0; i < keys.length - 1; i++) {
488
+ const key = keys[i];
489
+ if (key.endsWith("[]")) break;
490
+ let childNode = pathNode.children.get(key);
491
+ if (!childNode) {
492
+ childNode = createFormPathNode();
493
+ pathNode.children.set(key, childNode);
494
+ }
495
+ if (!isArrayIndexKey(keys[i + 1])) childNode.isArray = false;
496
+ pathNode = childNode;
497
+ }
498
+ }
499
+ return root;
500
+ };
501
+ var formToObj = (formData) => {
502
+ /**
503
+ * Convert FormData to object Handle nested form input using dot notation Handle array input using
504
+ * indexed dot notation (name.0, name.0) or bracket notation (name[]), the later is needed for
505
+ * multiselects Create values object by form data entries
506
+ */
507
+ const values = Object.create(null);
508
+ const pathTree = getFormPathTree(formData);
509
+ for (const [name, value] of formData) {
510
+ const keys = name.split(".");
511
+ let hasDangerousKey = false;
512
+ for (let i = 0; i < keys.length; i++) if (isDangerousKey(keys[i])) {
513
+ hasDangerousKey = true;
514
+ break;
515
+ }
516
+ if (hasDangerousKey) continue;
517
+ let object = values;
518
+ let pathNode = pathTree;
519
+ for (let i = 0; i < keys.length; i++) {
520
+ const key = keys[i];
521
+ if (key.endsWith("[]")) {
522
+ const arrayKey = key.slice(0, -2);
523
+ if (isDangerousKey(arrayKey)) break;
524
+ const existingValue = object[arrayKey];
525
+ if (existingValue !== void 0 && !Array.isArray(existingValue)) break;
526
+ object[arrayKey] = existingValue || [];
527
+ object[arrayKey].push(value);
528
+ break;
529
+ }
530
+ if (Array.isArray(object) && !isArrayIndexKey(key)) break;
531
+ if (i < keys.length - 1) {
532
+ const childNode = pathNode.children.get(key);
533
+ const nextValue = object[key];
534
+ if (nextValue !== void 0) {
535
+ object = nextValue;
536
+ pathNode = childNode;
537
+ continue;
538
+ }
539
+ object = object[key] = childNode.isArray ? [] : Object.create(null);
540
+ pathNode = childNode;
541
+ } else object[key] = value;
542
+ }
543
+ }
544
+ return values;
545
+ };
538
546
  var MAX_CACHE_SIZE = typeof globalThis.__SSR_CACHE_SIZE__ === "number" ? globalThis.__SSR_CACHE_SIZE__ : 50;
539
547
  function createLruCache() {
540
548
  const cache = /* @__PURE__ */ new Map();
@@ -566,7 +574,8 @@ var loaderCache = createLruCache();
566
574
  /**
567
575
  * Resolve an eTag value from a ContentModuleETag (string, function, or undefined). Returns the eTag
568
576
  * string or null.
569
- */ function resolveETag(eTagExport, headProps) {
577
+ */
578
+ function resolveETag(eTagExport, headProps) {
570
579
  if (eTagExport === void 0) return null;
571
580
  if (typeof eTagExport === "function") return eTagExport(headProps);
572
581
  return eTagExport;
@@ -574,31 +583,38 @@ var loaderCache = createLruCache();
574
583
  /**
575
584
  * Resolve a cache key from a CacheKeyFn. The default key callback is only called when `cacheKey ===
576
585
  * true`.
577
- */ function resolveCacheKey(cacheKeyExport, defaultKey, requestEv, eTag) {
586
+ */
587
+ function resolveCacheKey(cacheKeyExport, defaultKey, requestEv, eTag) {
578
588
  if (cacheKeyExport === true) return defaultKey(requestEv, eTag);
579
589
  if (typeof cacheKeyExport !== "function") return "";
580
590
  return cacheKeyExport(requestEv, eTag) || "";
581
591
  }
582
- /** Build the default SSR cache key. eTag slot is dropped when no eTag was resolved. */ function defaultSsrCacheKey(requestEv, eTag) {
592
+ /** Build the default SSR cache key. eTag slot is dropped when no eTag was resolved. */
593
+ function defaultSsrCacheKey(requestEv, eTag) {
583
594
  const status = requestEv.status();
584
595
  const pathname = requestEv.url.pathname;
585
596
  return eTag ? `${status}|${eTag}|${pathname}` : `${status}|${pathname}`;
586
597
  }
587
- /** Build the default loader cache key. eTag slot is dropped when no eTag was resolved. */ function defaultLoaderCacheKey(requestEv, eTag) {
598
+ /** Build the default loader cache key. eTag slot is dropped when no eTag was resolved. */
599
+ function defaultLoaderCacheKey(requestEv, eTag) {
588
600
  const loaderId = requestEv.sharedMap.get(QLoaderId);
589
601
  const base = `${requestEv.url.pathname}|${requestEv.url.search}|${loaderId}`;
590
602
  return eTag ? `${base}|${eTag}` : base;
591
603
  }
592
- /** Get a cached SSR entry by key (LRU touch). */ function getCachedSsr(key) {
604
+ /** Get a cached SSR entry by key (LRU touch). */
605
+ function getCachedSsr(key) {
593
606
  return ssrCache.get(key);
594
607
  }
595
- /** Cache an SSR entry by key, evicting the least recently used entry if at capacity. */ function setCachedSsr(key, entry) {
608
+ /** Cache an SSR entry by key, evicting the least recently used entry if at capacity. */
609
+ function setCachedSsr(key, entry) {
596
610
  ssrCache.set(key, entry);
597
611
  }
598
- /** Get a cached loader entry by key (LRU touch). */ function getCachedLoader(key) {
612
+ /** Get a cached loader entry by key (LRU touch). */
613
+ function getCachedLoader(key) {
599
614
  return loaderCache.get(key);
600
615
  }
601
- /** Cache a loader entry by key, evicting the least recently used entry if at capacity. */ function setCachedLoader(key, entry) {
616
+ /** Cache a loader entry by key, evicting the least recently used entry if at capacity. */
617
+ function setCachedLoader(key, entry) {
602
618
  loaderCache.set(key, entry);
603
619
  }
604
620
  /**
@@ -608,7 +624,8 @@ var loaderCache = createLruCache();
608
624
  * cleared.
609
625
  *
610
626
  * @public
611
- */ function clearSsrCache(cacheKey) {
627
+ */
628
+ function clearSsrCache(cacheKey) {
612
629
  ssrCache.clear(cacheKey);
613
630
  }
614
631
  /**
@@ -618,59 +635,25 @@ var loaderCache = createLruCache();
618
635
  * cleared.
619
636
  *
620
637
  * @public
621
- */ function clearLoaderCache(cacheKey) {
638
+ */
639
+ function clearLoaderCache(cacheKey) {
622
640
  loaderCache.clear(cacheKey);
623
641
  }
624
642
  /**
625
643
  * Create per-loader request event views. Loader-specific URL/search data is scoped to the view,
626
644
  * while request-wide state (headers, cookies, loader value maps, etc.) still delegates to the
627
645
  * original request event.
628
- */ function createLoaderRequestEventFactory(requestEv) {
646
+ */
647
+ function createLoaderRequestEventFactory(requestEv) {
629
648
  return (loader) => getLoaderRequestEvent(loader, requestEv);
630
649
  }
631
650
  /**
632
- * Resolve the loader's cacheControl option. Loaders default to `no-cache` so the browser always
633
- * revalidates; pair with `eTag` for cheap 304s. A function form may return `null` to skip the
634
- * header entirely.
635
- */ function resolveLoaderCacheControl(option, requestEv) {
636
- const value = typeof option === "function" ? option(requestEv) : option;
637
- return value === void 0 ? "no-cache" : value;
638
- }
639
- async function runBlockingLoadersBeforeTarget(routeLoaders, targetLoader, requestEv) {
640
- for (const loader of routeLoaders) {
641
- if (loader === targetLoader) return;
642
- if (loader.__blockSSR) await loadRouteLoader(loader, requestEv);
643
- }
644
- }
645
- function setLoaderData(requestEv, routeLoaders, loaderPaths) {
646
- if (loaderPaths) Object.assign(getRouteLoaderCtx(requestEv).loaderPaths, loaderPaths);
647
- setRouteLoaders(requestEv, routeLoaders);
648
- }
649
- /** Resolve eTag from a static string or function (before running the loader). */ function resolvePreETag(eTagOption, requestEv) {
650
- if (typeof eTagOption === "string") return normalizeETag(eTagOption);
651
- const result = eTagOption(requestEv);
652
- return result ? normalizeETag(result) : "";
653
- }
654
- function addVaryHeader(requestEv, value) {
655
- const vary = requestEv.headers.get("Vary");
656
- if (!vary) {
657
- requestEv.headers.set("Vary", value);
658
- return;
659
- }
660
- if (!vary.split(",").map((item) => item.trim().toLowerCase()).includes(value.toLowerCase())) requestEv.headers.set("Vary", `${vary}, ${value}`);
661
- }
662
- async function sendLoaderResponse(requestEv, data, cacheControl) {
663
- requestEv.headers.set("Content-Type", "application/json; charset=utf-8");
664
- addVaryHeader(requestEv, FULLPATH_HEADER);
665
- if (cacheControl !== null && !requestEv.headers.has("Cache-Control")) requestEv.cacheControl(cacheControl);
666
- requestEv.send(200, data);
667
- }
668
- /**
669
651
  * Handler that executes the requested loader and returns the result as JSON. Runs AFTER
670
652
  * plugin/route middleware, so middleware redirects/errors are handled by `jsonRequestWrapper`. The
671
653
  * loader function's own redirects/errors are caught by getRouteLoaderResponse and serialized in the
672
654
  * LoaderResponse envelope ({ d, r, e }).
673
- */ function loaderHandler(routeLoaders, loaderPaths) {
655
+ */
656
+ function loaderHandler(routeLoaders, loaderPaths) {
674
657
  return async (requestEvent) => {
675
658
  const requestEv = requestEvent;
676
659
  if (!requestEv.sharedMap.has("@isQLoader")) return;
@@ -712,7 +695,47 @@ async function sendLoaderResponse(requestEv, data, cacheControl) {
712
695
  await sendLoaderResponse(requestEv, data, cacheControl);
713
696
  };
714
697
  }
715
- /** Serialize and send a JSON response (used by error/redirect paths in jsonRequestWrapper). */ async function sendJsonResponse(requestEv, responseData, status = 200) {
698
+ /**
699
+ * Resolve the loader's cacheControl option. Loaders default to `no-cache` so the browser always
700
+ * revalidates; pair with `eTag` for cheap 304s. A function form may return `null` to skip the
701
+ * header entirely.
702
+ */
703
+ function resolveLoaderCacheControl(option, requestEv) {
704
+ const value = typeof option === "function" ? option(requestEv) : option;
705
+ return value === void 0 ? "no-cache" : value;
706
+ }
707
+ async function runBlockingLoadersBeforeTarget(routeLoaders, targetLoader, requestEv) {
708
+ for (const loader of routeLoaders) {
709
+ if (loader === targetLoader) return;
710
+ if (loader.__blockSSR) await loadRouteLoader(loader, requestEv);
711
+ }
712
+ }
713
+ function setLoaderData(requestEv, routeLoaders, loaderPaths) {
714
+ if (loaderPaths) Object.assign(getRouteLoaderCtx(requestEv).loaderPaths, loaderPaths);
715
+ setRouteLoaders(requestEv, routeLoaders);
716
+ }
717
+ /** Resolve eTag from a static string or function (before running the loader). */
718
+ function resolvePreETag(eTagOption, requestEv) {
719
+ if (typeof eTagOption === "string") return normalizeETag(eTagOption);
720
+ const result = eTagOption(requestEv);
721
+ return result ? normalizeETag(result) : "";
722
+ }
723
+ async function sendLoaderResponse(requestEv, data, cacheControl) {
724
+ requestEv.headers.set("Content-Type", "application/json; charset=utf-8");
725
+ addVaryHeader(requestEv, FULLPATH_HEADER);
726
+ if (cacheControl !== null && !requestEv.headers.has("Cache-Control")) requestEv.cacheControl(cacheControl);
727
+ requestEv.send(200, data);
728
+ }
729
+ function addVaryHeader(requestEv, value) {
730
+ const vary = requestEv.headers.get("Vary");
731
+ if (!vary) {
732
+ requestEv.headers.set("Vary", value);
733
+ return;
734
+ }
735
+ if (!vary.split(",").map((item) => item.trim().toLowerCase()).includes(value.toLowerCase())) requestEv.headers.set("Vary", `${vary}, ${value}`);
736
+ }
737
+ /** Serialize and send a JSON response (used by error/redirect paths in jsonRequestWrapper). */
738
+ async function sendJsonResponse(requestEv, responseData, status = 200) {
716
739
  const data = await _serialize(responseData);
717
740
  requestEv.headers.set("Content-Type", "application/json; charset=utf-8");
718
741
  requestEv.send(status, data);
@@ -731,7 +754,8 @@ async function sendActionResponse(requestEv, responseData) {
731
754
  * By calling `await next()` inside a try/catch, middleware redirects and errors are captured and
732
755
  * returned as JSON envelopes instead of HTTP redirects/error pages. This keeps SPA navigation
733
756
  * intact on the client.
734
- */ function jsonRequestWrapper() {
757
+ */
758
+ function jsonRequestWrapper() {
735
759
  return async (requestEvent) => {
736
760
  const requestEv = requestEvent;
737
761
  const isLoader = requestEv.internalRequest === "loader";
@@ -771,38 +795,6 @@ async function sendActionResponse(requestEv, responseData) {
771
795
  }
772
796
  };
773
797
  }
774
- function verifySerializable$1(data, qrl) {
775
- try {
776
- _verifySerializable(data, void 0);
777
- } catch (e) {
778
- if (e instanceof Error && qrl.dev) e.loc = qrl.dev;
779
- throw e;
780
- }
781
- }
782
- async function measure$1(requestEv, name, fn) {
783
- const start = performance.now();
784
- try {
785
- return await fn();
786
- } finally {
787
- const duration = performance.now() - start;
788
- let measurements = requestEv.sharedMap.get("@serverTiming");
789
- if (!measurements) requestEv.sharedMap.set("@serverTiming", measurements = []);
790
- measurements.push([name, duration]);
791
- }
792
- }
793
- async function runValidators(requestEv, validators, data, devMode) {
794
- let lastResult = {
795
- success: true,
796
- data
797
- };
798
- if (validators) for (const validator of validators) {
799
- if (devMode) lastResult = await measure$1(requestEv, `validator$`, () => validator.validate(requestEv, data));
800
- else lastResult = await validator.validate(requestEv, data);
801
- if (!lastResult.success) return lastResult;
802
- else data = lastResult.data;
803
- }
804
- return lastResult;
805
- }
806
798
  /**
807
799
  * Handler for action requests (`?qaction={actionId}`).
808
800
  *
@@ -812,7 +804,8 @@ async function runValidators(requestEv, validators, data, devMode) {
812
804
  * If the action has no `invalidate` list, the client invalidates all current route loaders unless
813
805
  * strict loaders mode treats it as `invalidate: []`. If `invalidate` is specified, only those
814
806
  * loader hashes are sent for the client to re-fetch.
815
- */ function actionHandler(routeActions) {
807
+ */
808
+ function actionHandler(routeActions) {
816
809
  return async (requestEvent) => {
817
810
  const requestEv = requestEvent;
818
811
  if (!requestEv.sharedMap.has("@isQAction")) return;
@@ -852,10 +845,43 @@ async function runValidators(requestEv, validators, data, devMode) {
852
845
  requestEv.send(requestEv.status(), serialized);
853
846
  };
854
847
  }
848
+ async function runValidators(requestEv, validators, data, devMode) {
849
+ let lastResult = {
850
+ success: true,
851
+ data
852
+ };
853
+ if (validators) for (const validator of validators) {
854
+ if (devMode) lastResult = await measure$1(requestEv, `validator$`, () => validator.validate(requestEv, data));
855
+ else lastResult = await validator.validate(requestEv, data);
856
+ if (!lastResult.success) return lastResult;
857
+ else data = lastResult.data;
858
+ }
859
+ return lastResult;
860
+ }
861
+ function verifySerializable$1(data, qrl) {
862
+ try {
863
+ _verifySerializable(data, void 0);
864
+ } catch (e) {
865
+ if (e instanceof Error && qrl.dev) e.loc = qrl.dev;
866
+ throw e;
867
+ }
868
+ }
869
+ async function measure$1(requestEv, name, fn) {
870
+ const start = performance.now();
871
+ try {
872
+ return await fn();
873
+ } finally {
874
+ const duration = performance.now() - start;
875
+ let measurements = requestEv.sharedMap.get("@serverTiming");
876
+ if (!measurements) requestEv.sharedMap.set("@serverTiming", measurements = []);
877
+ measurements.push([name, duration]);
878
+ }
879
+ }
855
880
  /**
856
881
  * A set of static paths generated by the SSG, including loader json. Routes always have a trailing
857
882
  * slash, short for `.../index.html`
858
- */ var staticPaths = /* @__PURE__ */ new Set(["__QWIK_ROUTER_STATIC_PATHS_ARRAY__"]);
883
+ */
884
+ var staticPaths = /* @__PURE__ */ new Set(["__QWIK_ROUTER_STATIC_PATHS_ARRAY__"]);
859
885
  /**
860
886
  * Check if the current pathname needs a redirect due to trailing slash mismatch. If we're not sure,
861
887
  * we fall through.
@@ -864,7 +890,8 @@ async function runValidators(requestEv, validators, data, devMode) {
864
890
  *
865
891
  * @returns The canonical path with the correct trailing slash if a redirect is needed, otherwise
866
892
  * `undefined`.
867
- */ function getStaticPathRedirect(method, url) {
893
+ */
894
+ function getStaticPathRedirect(method, url) {
868
895
  const { pathname, search } = url;
869
896
  if (method.toUpperCase() !== "GET" || pathname === "/" || !pathname.startsWith("/") || pathname.startsWith("//")) return;
870
897
  const hasTrailingSlash = pathname.endsWith("/");
@@ -877,12 +904,14 @@ async function runValidators(requestEv, validators, data, devMode) {
877
904
  * Decide whether a given request path is a static path, for optimizing file access.
878
905
  *
879
906
  * @internal
880
- */ function isStaticPath(method, url) {
907
+ */
908
+ function isStaticPath(method, url) {
881
909
  method = method.toUpperCase();
882
910
  if (method !== "GET" && method !== "HEAD") return false;
883
911
  const p = url.pathname;
884
- if (p.startsWith("/" + (globalThis.__QWIK_BUILD_DIR__ || "build") + "/")) return true;
885
- if (p.startsWith("/" + (globalThis.__QWIK_ASSETS_DIR__ || "assets") + "/")) return true;
912
+ const basePathname = globalThis.__QWIK_ROUTER_BASE_PATHNAME__ || "/";
913
+ if (p.startsWith(basePathname + (globalThis.__QWIK_BUILD_DIR__ || "build") + "/")) return true;
914
+ if (p.startsWith(basePathname + (globalThis.__QWIK_ASSETS_DIR__ || "assets") + "/")) return true;
886
915
  if (globalThis.__NO_TRAILING_SLASH__ && p !== "/") return !p.endsWith("/") && (staticPaths.has(p) || staticPaths.has(p + "/"));
887
916
  return staticPaths.has(p);
888
917
  }
@@ -890,7 +919,8 @@ async function runValidators(requestEv, validators, data, devMode) {
890
919
  * Hypertext Transfer Protocol (HTTP) response status codes.
891
920
  *
892
921
  * @see {@link https://en.wikipedia.org/wiki/List_of_HTTP_status_codes}
893
- */ var HttpStatus = /*#__PURE__*/ function(HttpStatus) {
922
+ */
923
+ var HttpStatus = /* @__PURE__ */ function(HttpStatus) {
894
924
  /**
895
925
  * The server has received the request headers and the client should proceed to send the request
896
926
  * body (in the case of a request for which a body needs to be sent; for example, a POST request).
@@ -899,59 +929,74 @@ async function runValidators(requestEv, validators, data, devMode) {
899
929
  * Expect: 100-continue as a header in its initial request and receive a 100 Continue status code
900
930
  * in response before sending the body. The response 417 Expectation Failed indicates the request
901
931
  * should not be continued.
902
- */ HttpStatus[HttpStatus["Continue"] = 100] = "Continue";
903
- /** The requester has asked the server to switch protocols and the server has agreed to do so. */ HttpStatus[HttpStatus["SwitchingProtocols"] = 101] = "SwitchingProtocols";
932
+ */
933
+ HttpStatus[HttpStatus["Continue"] = 100] = "Continue";
934
+ /** The requester has asked the server to switch protocols and the server has agreed to do so. */
935
+ HttpStatus[HttpStatus["SwitchingProtocols"] = 101] = "SwitchingProtocols";
904
936
  /**
905
937
  * A WebDAV request may contain many sub-requests involving file operations, requiring a long time
906
938
  * to complete the request. This code indicates that the server has received and is processing the
907
939
  * request, but no response is available yet. This prevents the client from timing out and
908
940
  * assuming the request was lost.
909
- */ HttpStatus[HttpStatus["Processing"] = 102] = "Processing";
941
+ */
942
+ HttpStatus[HttpStatus["Processing"] = 102] = "Processing";
910
943
  /**
911
944
  * Standard response for successful HTTP requests. The actual response will depend on the request
912
945
  * method used. In a GET request, the response will contain an entity corresponding to the
913
946
  * requested resource. In a POST request, the response will contain an entity describing or
914
947
  * containing the result of the action.
915
- */ HttpStatus[HttpStatus["Ok"] = 200] = "Ok";
916
- /** The request has been fulfilled, resulting in the creation of a new resource. */ HttpStatus[HttpStatus["Created"] = 201] = "Created";
948
+ */
949
+ HttpStatus[HttpStatus["Ok"] = 200] = "Ok";
950
+ /** The request has been fulfilled, resulting in the creation of a new resource. */
951
+ HttpStatus[HttpStatus["Created"] = 201] = "Created";
917
952
  /**
918
953
  * The request has been accepted for processing, but the processing has not been completed. The
919
954
  * request might or might not be eventually acted upon, and may be disallowed when processing
920
955
  * occurs.
921
- */ HttpStatus[HttpStatus["Accepted"] = 202] = "Accepted";
956
+ */
957
+ HttpStatus[HttpStatus["Accepted"] = 202] = "Accepted";
922
958
  /**
923
959
  * SINCE HTTP/1.1 The server is a transforming proxy that received a 200 OK from its origin, but
924
960
  * is returning a modified version of the origin's response.
925
- */ HttpStatus[HttpStatus["NonAuthoritativeInformation"] = 203] = "NonAuthoritativeInformation";
926
- /** The server successfully processed the request and is not returning any content. */ HttpStatus[HttpStatus["NoContent"] = 204] = "NoContent";
961
+ */
962
+ HttpStatus[HttpStatus["NonAuthoritativeInformation"] = 203] = "NonAuthoritativeInformation";
963
+ /** The server successfully processed the request and is not returning any content. */
964
+ HttpStatus[HttpStatus["NoContent"] = 204] = "NoContent";
927
965
  /**
928
966
  * The server successfully processed the request, but is not returning any content. Unlike a 204
929
967
  * response, this response requires that the requester reset the document view.
930
- */ HttpStatus[HttpStatus["ResetContent"] = 205] = "ResetContent";
968
+ */
969
+ HttpStatus[HttpStatus["ResetContent"] = 205] = "ResetContent";
931
970
  /**
932
971
  * The server is delivering only part of the resource (byte serving) due to a range header sent by
933
972
  * the client. The range header is used by HTTP clients to enable resuming of interrupted
934
973
  * downloads, or split a download into multiple simultaneous streams.
935
- */ HttpStatus[HttpStatus["PartialContent"] = 206] = "PartialContent";
974
+ */
975
+ HttpStatus[HttpStatus["PartialContent"] = 206] = "PartialContent";
936
976
  /**
937
977
  * The message body that follows is an XML message and can contain a number of separate response
938
978
  * codes, depending on how many sub-requests were made.
939
- */ HttpStatus[HttpStatus["MultiStatus"] = 207] = "MultiStatus";
979
+ */
980
+ HttpStatus[HttpStatus["MultiStatus"] = 207] = "MultiStatus";
940
981
  /**
941
982
  * The members of a DAV binding have already been enumerated in a preceding part of the
942
983
  * (multistatus) response, and are not being included again.
943
- */ HttpStatus[HttpStatus["AlreadyReported"] = 208] = "AlreadyReported";
984
+ */
985
+ HttpStatus[HttpStatus["AlreadyReported"] = 208] = "AlreadyReported";
944
986
  /**
945
987
  * The server has fulfilled a request for the resource, and the response is a representation of
946
988
  * the result of one or more instance-manipulations applied to the current instance.
947
- */ HttpStatus[HttpStatus["ImUsed"] = 226] = "ImUsed";
989
+ */
990
+ HttpStatus[HttpStatus["ImUsed"] = 226] = "ImUsed";
948
991
  /**
949
992
  * Indicates multiple options for the resource from which the client may choose (via agent-driven
950
993
  * content negotiation). For example, this code could be used to present multiple video format
951
994
  * options, to list files with different filename extensions, or to suggest word-sense
952
995
  * disambiguation.
953
- */ HttpStatus[HttpStatus["MultipleChoices"] = 300] = "MultipleChoices";
954
- /** This and all future requests should be directed to the given URI. */ HttpStatus[HttpStatus["MovedPermanently"] = 301] = "MovedPermanently";
996
+ */
997
+ HttpStatus[HttpStatus["MultipleChoices"] = 300] = "MultipleChoices";
998
+ /** This and all future requests should be directed to the given URI. */
999
+ HttpStatus[HttpStatus["MovedPermanently"] = 301] = "MovedPermanently";
955
1000
  /**
956
1001
  * This is an example of industry practice contradicting the standard. The HTTP/1.0 specification
957
1002
  * (RFC 1945) required the client to perform a temporary redirect (the original describing phrase
@@ -959,78 +1004,95 @@ async function runValidators(requestEv, validators, data, devMode) {
959
1004
  * See Other. Therefore, HTTP/1.1 added status codes 303 and 307 to distinguish between the two
960
1005
  * behaviors. However, some Web applications and frameworks use the 302 status code as if it were
961
1006
  * the 303.
962
- */ HttpStatus[HttpStatus["Found"] = 302] = "Found";
1007
+ */
1008
+ HttpStatus[HttpStatus["Found"] = 302] = "Found";
963
1009
  /**
964
1010
  * SINCE HTTP/1.1 The response to the request can be found under another URI using a GET method.
965
1011
  * When received in response to a POST (or PUT/DELETE), the client should presume that the server
966
1012
  * has received the data and should issue a redirect with a separate GET message.
967
- */ HttpStatus[HttpStatus["SeeOther"] = 303] = "SeeOther";
1013
+ */
1014
+ HttpStatus[HttpStatus["SeeOther"] = 303] = "SeeOther";
968
1015
  /**
969
1016
  * Indicates that the resource has not been modified since the version specified by the request
970
1017
  * headers If-Modified-Since or If-None-Match. In such case, there is no need to retransmit the
971
1018
  * resource since the client still has a previously-downloaded copy.
972
- */ HttpStatus[HttpStatus["NotModified"] = 304] = "NotModified";
1019
+ */
1020
+ HttpStatus[HttpStatus["NotModified"] = 304] = "NotModified";
973
1021
  /**
974
1022
  * SINCE HTTP/1.1 The requested resource is available only through a proxy, the address for which
975
1023
  * is provided in the response. Many HTTP clients (such as Mozilla and Internet Explorer) do not
976
1024
  * correctly handle responses with this status code, primarily for security reasons.
977
- */ HttpStatus[HttpStatus["UseProxy"] = 305] = "UseProxy";
978
- /** No longer used. Originally meant "Subsequent requests should use the specified proxy." */ HttpStatus[HttpStatus["SwitchProxy"] = 306] = "SwitchProxy";
1025
+ */
1026
+ HttpStatus[HttpStatus["UseProxy"] = 305] = "UseProxy";
1027
+ /** No longer used. Originally meant "Subsequent requests should use the specified proxy." */
1028
+ HttpStatus[HttpStatus["SwitchProxy"] = 306] = "SwitchProxy";
979
1029
  /**
980
1030
  * SINCE HTTP/1.1 In this case, the request should be repeated with another URI; however, future
981
1031
  * requests should still use the original URI. In contrast to how 302 was historically
982
1032
  * implemented, the request method is not allowed to be changed when reissuing the original
983
1033
  * request. For example, a POST request should be repeated using another POST request.
984
- */ HttpStatus[HttpStatus["TemporaryRedirect"] = 307] = "TemporaryRedirect";
1034
+ */
1035
+ HttpStatus[HttpStatus["TemporaryRedirect"] = 307] = "TemporaryRedirect";
985
1036
  /**
986
1037
  * The request and all future requests should be repeated using another URI. 307 and 308 parallel
987
1038
  * the behaviors of 302 and 301, but do not allow the HTTP method to change. So, for example,
988
1039
  * submitting a form to a permanently redirected resource may continue smoothly.
989
- */ HttpStatus[HttpStatus["PermanentRedirect"] = 308] = "PermanentRedirect";
1040
+ */
1041
+ HttpStatus[HttpStatus["PermanentRedirect"] = 308] = "PermanentRedirect";
990
1042
  /**
991
1043
  * The server cannot or will not process the request due to an apparent client error (e.g.,
992
1044
  * malformed request syntax, too large size, invalid request message framing, or deceptive request
993
1045
  * routing).
994
- */ HttpStatus[HttpStatus["BadRequest"] = 400] = "BadRequest";
1046
+ */
1047
+ HttpStatus[HttpStatus["BadRequest"] = 400] = "BadRequest";
995
1048
  /**
996
1049
  * Similar to 403 Forbidden, but specifically for use when authentication is required and has
997
1050
  * failed or has not yet been provided. The response must include a WWW-Authenticate header field
998
1051
  * containing a challenge applicable to the requested resource. See Basic access authentication
999
1052
  * and Digest access authentication. 401 semantically means "unauthenticated",i.e. the user does
1000
1053
  * not have the necessary credentials.
1001
- */ HttpStatus[HttpStatus["Unauthorized"] = 401] = "Unauthorized";
1054
+ */
1055
+ HttpStatus[HttpStatus["Unauthorized"] = 401] = "Unauthorized";
1002
1056
  /**
1003
1057
  * Reserved for future use. The original intention was that this code might be used as part of
1004
1058
  * some form of digital cash or micro payment scheme, but that has not happened, and this code is
1005
1059
  * not usually used. Google Developers API uses this status if a particular developer has exceeded
1006
1060
  * the daily limit on requests.
1007
- */ HttpStatus[HttpStatus["PaymentRequired"] = 402] = "PaymentRequired";
1061
+ */
1062
+ HttpStatus[HttpStatus["PaymentRequired"] = 402] = "PaymentRequired";
1008
1063
  /**
1009
1064
  * The request was valid, but the server is refusing action. The user might not have the necessary
1010
1065
  * permissions for a resource.
1011
- */ HttpStatus[HttpStatus["Forbidden"] = 403] = "Forbidden";
1066
+ */
1067
+ HttpStatus[HttpStatus["Forbidden"] = 403] = "Forbidden";
1012
1068
  /**
1013
1069
  * The requested resource could not be found but may be available in the future. Subsequent
1014
1070
  * requests by the client are permissible.
1015
- */ HttpStatus[HttpStatus["NotFound"] = 404] = "NotFound";
1071
+ */
1072
+ HttpStatus[HttpStatus["NotFound"] = 404] = "NotFound";
1016
1073
  /**
1017
1074
  * A request method is not supported for the requested resource; for example, a GET request on a
1018
1075
  * form that requires data to be presented via POST, or a PUT request on a read-only resource.
1019
- */ HttpStatus[HttpStatus["MethodNotAllowed"] = 405] = "MethodNotAllowed";
1076
+ */
1077
+ HttpStatus[HttpStatus["MethodNotAllowed"] = 405] = "MethodNotAllowed";
1020
1078
  /**
1021
1079
  * The requested resource is capable of generating only content not acceptable according to the
1022
1080
  * Accept headers sent in the request.
1023
- */ HttpStatus[HttpStatus["NotAcceptable"] = 406] = "NotAcceptable";
1024
- /** The client must first authenticate itself with the proxy. */ HttpStatus[HttpStatus["ProxyAuthenticationRequired"] = 407] = "ProxyAuthenticationRequired";
1081
+ */
1082
+ HttpStatus[HttpStatus["NotAcceptable"] = 406] = "NotAcceptable";
1083
+ /** The client must first authenticate itself with the proxy. */
1084
+ HttpStatus[HttpStatus["ProxyAuthenticationRequired"] = 407] = "ProxyAuthenticationRequired";
1025
1085
  /**
1026
1086
  * The server timed out waiting for the request. According to HTTP specifications: "The client did
1027
1087
  * not produce a request within the time that the server was prepared to wait. The client MAY
1028
1088
  * repeat the request without modifications at any later time."
1029
- */ HttpStatus[HttpStatus["RequestTimeout"] = 408] = "RequestTimeout";
1089
+ */
1090
+ HttpStatus[HttpStatus["RequestTimeout"] = 408] = "RequestTimeout";
1030
1091
  /**
1031
1092
  * Indicates that the request could not be processed because of conflict in the request, such as
1032
1093
  * an edit conflict between multiple simultaneous updates.
1033
- */ HttpStatus[HttpStatus["Conflict"] = 409] = "Conflict";
1094
+ */
1095
+ HttpStatus[HttpStatus["Conflict"] = 409] = "Conflict";
1034
1096
  /**
1035
1097
  * Indicates that the resource requested is no longer available and will not be available again.
1036
1098
  * This should be used when a resource has been intentionally removed and the resource should be
@@ -1038,98 +1100,127 @@ async function runValidators(requestEv, validators, data, devMode) {
1038
1100
  * future. Clients such as search engines should remove the resource from their indices. Most use
1039
1101
  * cases do not require clients and search engines to purge the resource, and a "404 Not Found"
1040
1102
  * may be used instead.
1041
- */ HttpStatus[HttpStatus["Gone"] = 410] = "Gone";
1103
+ */
1104
+ HttpStatus[HttpStatus["Gone"] = 410] = "Gone";
1042
1105
  /**
1043
1106
  * The request did not specify the length of its content, which is required by the requested
1044
1107
  * resource.
1045
- */ HttpStatus[HttpStatus["LengthRequired"] = 411] = "LengthRequired";
1046
- /** The server does not meet one of the preconditions that the requester put on the request. */ HttpStatus[HttpStatus["PreconditionFailed"] = 412] = "PreconditionFailed";
1108
+ */
1109
+ HttpStatus[HttpStatus["LengthRequired"] = 411] = "LengthRequired";
1110
+ /** The server does not meet one of the preconditions that the requester put on the request. */
1111
+ HttpStatus[HttpStatus["PreconditionFailed"] = 412] = "PreconditionFailed";
1047
1112
  /**
1048
1113
  * The request is larger than the server is willing or able to process. Previously called "Request
1049
1114
  * Entity Too Large".
1050
- */ HttpStatus[HttpStatus["PayloadTooLarge"] = 413] = "PayloadTooLarge";
1115
+ */
1116
+ HttpStatus[HttpStatus["PayloadTooLarge"] = 413] = "PayloadTooLarge";
1051
1117
  /**
1052
1118
  * The URI provided was too long for the server to process. Often the result of too much data
1053
1119
  * being encoded as a query-string of a GET request, in which case it should be converted to a
1054
1120
  * POST request. Called "Request-URI Too Long" previously.
1055
- */ HttpStatus[HttpStatus["UriTooLong"] = 414] = "UriTooLong";
1121
+ */
1122
+ HttpStatus[HttpStatus["UriTooLong"] = 414] = "UriTooLong";
1056
1123
  /**
1057
1124
  * The request entity has a media type which the server or resource does not support. For example,
1058
1125
  * the client uploads an image as image/svg+xml, but the server requires that images use a
1059
1126
  * different format.
1060
- */ HttpStatus[HttpStatus["UnsupportedMediaType"] = 415] = "UnsupportedMediaType";
1127
+ */
1128
+ HttpStatus[HttpStatus["UnsupportedMediaType"] = 415] = "UnsupportedMediaType";
1061
1129
  /**
1062
1130
  * The client has asked for a portion of the file (byte serving), but the server cannot supply
1063
1131
  * that portion. For example, if the client asked for a part of the file that lies beyond the end
1064
1132
  * of the file. Called "Requested Range Not Satisfiable" previously.
1065
- */ HttpStatus[HttpStatus["RangeNotSatisfiable"] = 416] = "RangeNotSatisfiable";
1066
- /** The server cannot meet the requirements of the Expect request-header field. */ HttpStatus[HttpStatus["ExpectationFailed"] = 417] = "ExpectationFailed";
1133
+ */
1134
+ HttpStatus[HttpStatus["RangeNotSatisfiable"] = 416] = "RangeNotSatisfiable";
1135
+ /** The server cannot meet the requirements of the Expect request-header field. */
1136
+ HttpStatus[HttpStatus["ExpectationFailed"] = 417] = "ExpectationFailed";
1067
1137
  /**
1068
1138
  * This code was defined in 1998 as one of the traditional IETF April Fools' jokes, in RFC 2324,
1069
1139
  * Hyper Text Coffee Pot Control Protocol, and is not expected to be implemented by actual HTTP
1070
1140
  * servers. The RFC specifies this code should be returned by teapots requested to brew coffee.
1071
1141
  * This HTTP status is used as an Easter egg in some websites, including Google.com.
1072
- */ HttpStatus[HttpStatus["IAmATeapot"] = 418] = "IAmATeapot";
1142
+ */
1143
+ HttpStatus[HttpStatus["IAmATeapot"] = 418] = "IAmATeapot";
1073
1144
  /**
1074
1145
  * The request was directed at a server that is not able to produce a response (for example
1075
1146
  * because a connection reuse).
1076
- */ HttpStatus[HttpStatus["MisdirectedRequest"] = 421] = "MisdirectedRequest";
1077
- /** The request was well-formed but was unable to be followed due to semantic errors. */ HttpStatus[HttpStatus["UnprocessableEntity"] = 422] = "UnprocessableEntity";
1078
- /** The resource that is being accessed is locked. */ HttpStatus[HttpStatus["Locked"] = 423] = "Locked";
1079
- /** The request failed due to failure of a previous request (e.g., a PROPPATCH). */ HttpStatus[HttpStatus["FailedDependency"] = 424] = "FailedDependency";
1147
+ */
1148
+ HttpStatus[HttpStatus["MisdirectedRequest"] = 421] = "MisdirectedRequest";
1149
+ /** The request was well-formed but was unable to be followed due to semantic errors. */
1150
+ HttpStatus[HttpStatus["UnprocessableEntity"] = 422] = "UnprocessableEntity";
1151
+ /** The resource that is being accessed is locked. */
1152
+ HttpStatus[HttpStatus["Locked"] = 423] = "Locked";
1153
+ /** The request failed due to failure of a previous request (e.g., a PROPPATCH). */
1154
+ HttpStatus[HttpStatus["FailedDependency"] = 424] = "FailedDependency";
1080
1155
  /**
1081
1156
  * The client should switch to a different protocol such as TLS/1.0, given in the Upgrade header
1082
1157
  * field.
1083
- */ HttpStatus[HttpStatus["UpgradeRequired"] = 426] = "UpgradeRequired";
1158
+ */
1159
+ HttpStatus[HttpStatus["UpgradeRequired"] = 426] = "UpgradeRequired";
1084
1160
  /**
1085
1161
  * The origin server requires the request to be conditional. Intended to prevent "the 'lost
1086
1162
  * update' problem, where a client GETs a resource's state, modifies it, and PUTs it back to the
1087
1163
  * server, when meanwhile a third party has modified the state on the server, leading to a
1088
1164
  * conflict."
1089
- */ HttpStatus[HttpStatus["PreconditionRequired"] = 428] = "PreconditionRequired";
1165
+ */
1166
+ HttpStatus[HttpStatus["PreconditionRequired"] = 428] = "PreconditionRequired";
1090
1167
  /**
1091
1168
  * The user has sent too many requests in a given amount of time. Intended for use with
1092
1169
  * rate-limiting schemes.
1093
- */ HttpStatus[HttpStatus["TooManyRequests"] = 429] = "TooManyRequests";
1170
+ */
1171
+ HttpStatus[HttpStatus["TooManyRequests"] = 429] = "TooManyRequests";
1094
1172
  /**
1095
1173
  * The server is unwilling to process the request because either an individual header field, or
1096
1174
  * all the header fields collectively, are too large.
1097
- */ HttpStatus[HttpStatus["RequestHeaderFieldsTooLarge"] = 431] = "RequestHeaderFieldsTooLarge";
1175
+ */
1176
+ HttpStatus[HttpStatus["RequestHeaderFieldsTooLarge"] = 431] = "RequestHeaderFieldsTooLarge";
1098
1177
  /**
1099
1178
  * A server operator has received a legal demand to deny access to a resource or to a set of
1100
1179
  * resources that includes the requested resource. The code 451 was chosen as a reference to the
1101
1180
  * novel Fahrenheit 451.
1102
- */ HttpStatus[HttpStatus["UnavailableForLegalReasons"] = 451] = "UnavailableForLegalReasons";
1181
+ */
1182
+ HttpStatus[HttpStatus["UnavailableForLegalReasons"] = 451] = "UnavailableForLegalReasons";
1103
1183
  /**
1104
1184
  * A generic error message, given when an unexpected condition was encountered and no more
1105
1185
  * specific message is suitable.
1106
- */ HttpStatus[HttpStatus["InternalServerError"] = 500] = "InternalServerError";
1186
+ */
1187
+ HttpStatus[HttpStatus["InternalServerError"] = 500] = "InternalServerError";
1107
1188
  /**
1108
1189
  * The server either does not recognize the request method, or it lacks the ability to fulfill the
1109
1190
  * request. Usually this implies future availability (e.g., a new feature of a web-service API).
1110
- */ HttpStatus[HttpStatus["NotImplemented"] = 501] = "NotImplemented";
1191
+ */
1192
+ HttpStatus[HttpStatus["NotImplemented"] = 501] = "NotImplemented";
1111
1193
  /**
1112
1194
  * The server was acting as a gateway or proxy and received an invalid response from the upstream
1113
1195
  * server.
1114
- */ HttpStatus[HttpStatus["BadGateway"] = 502] = "BadGateway";
1196
+ */
1197
+ HttpStatus[HttpStatus["BadGateway"] = 502] = "BadGateway";
1115
1198
  /**
1116
1199
  * The server is currently unavailable (because it is overloaded or down for maintenance).
1117
1200
  * Generally, this is a temporary state.
1118
- */ HttpStatus[HttpStatus["ServiceUnavailable"] = 503] = "ServiceUnavailable";
1201
+ */
1202
+ HttpStatus[HttpStatus["ServiceUnavailable"] = 503] = "ServiceUnavailable";
1119
1203
  /**
1120
1204
  * The server was acting as a gateway or proxy and did not receive a timely response from the
1121
1205
  * upstream server.
1122
- */ HttpStatus[HttpStatus["GatewayTimeout"] = 504] = "GatewayTimeout";
1123
- /** The server does not support the HTTP protocol version used in the request */ HttpStatus[HttpStatus["HttpVersionNotSupported"] = 505] = "HttpVersionNotSupported";
1124
- /** Transparent content negotiation for the request results in a circular reference. */ HttpStatus[HttpStatus["VariantAlsoNegotiates"] = 506] = "VariantAlsoNegotiates";
1125
- /** The server is unable to store the representation needed to complete the request. */ HttpStatus[HttpStatus["InsufficientStorage"] = 507] = "InsufficientStorage";
1126
- /** The server detected an infinite loop while processing the request. */ HttpStatus[HttpStatus["LoopDetected"] = 508] = "LoopDetected";
1127
- /** Further extensions to the request are required for the server to fulfill it. */ HttpStatus[HttpStatus["NotExtended"] = 510] = "NotExtended";
1206
+ */
1207
+ HttpStatus[HttpStatus["GatewayTimeout"] = 504] = "GatewayTimeout";
1208
+ /** The server does not support the HTTP protocol version used in the request */
1209
+ HttpStatus[HttpStatus["HttpVersionNotSupported"] = 505] = "HttpVersionNotSupported";
1210
+ /** Transparent content negotiation for the request results in a circular reference. */
1211
+ HttpStatus[HttpStatus["VariantAlsoNegotiates"] = 506] = "VariantAlsoNegotiates";
1212
+ /** The server is unable to store the representation needed to complete the request. */
1213
+ HttpStatus[HttpStatus["InsufficientStorage"] = 507] = "InsufficientStorage";
1214
+ /** The server detected an infinite loop while processing the request. */
1215
+ HttpStatus[HttpStatus["LoopDetected"] = 508] = "LoopDetected";
1216
+ /** Further extensions to the request are required for the server to fulfill it. */
1217
+ HttpStatus[HttpStatus["NotExtended"] = 510] = "NotExtended";
1128
1218
  /**
1129
1219
  * The client needs to authenticate to gain network access. Intended for use by intercepting
1130
1220
  * proxies used to control access to the network (e.g., "captive portals" used to require
1131
1221
  * agreement to Terms of Service before granting full Internet access via a Wi-Fi hotspot).
1132
- */ HttpStatus[HttpStatus["NetworkAuthenticationRequired"] = 511] = "NetworkAuthenticationRequired";
1222
+ */
1223
+ HttpStatus[HttpStatus["NetworkAuthenticationRequired"] = 511] = "NetworkAuthenticationRequired";
1133
1224
  return HttpStatus;
1134
1225
  }({});
1135
1226
  function getQwikRouterServerData(requestEv) {
@@ -1187,7 +1278,8 @@ function createResolveRequestHandlers() {
1187
1278
  /**
1188
1279
  * JSON request wrapper must be before all middleware so it can rewrite the URL and catch
1189
1280
  * redirects/errors from plugin/route middleware via try/catch on next()
1190
- */ requestHandlers.push(jsonRequestWrapper());
1281
+ */
1282
+ requestHandlers.push(jsonRequestWrapper());
1191
1283
  requestHandlers.push(serverErrorMiddleware(route, renderHandler));
1192
1284
  }
1193
1285
  if (serverPlugins) _resolveRequestHandlers(routeLoaders, routeActions, requestHandlers, serverPlugins, isPageRoute, method);
@@ -1314,16 +1406,17 @@ function createResolveRequestHandlers() {
1314
1406
  }
1315
1407
  function loadersMiddleware(routeLoaders, route) {
1316
1408
  return (requestEvent) => {
1317
- if (requestEvent.headersSent) {
1318
- requestEvent.exit();
1409
+ const requestEv = requestEvent;
1410
+ if (requestEv.headersSent) {
1411
+ requestEv.exit();
1319
1412
  return;
1320
1413
  }
1321
1414
  if (routeLoaders.length === 0) return;
1322
- setLoaderData(requestEvent, routeLoaders, route);
1415
+ setLoaderData(requestEv, routeLoaders, route);
1323
1416
  let allBlockSSRLoaders;
1324
1417
  for (let i = 0; i < routeLoaders.length; i++) {
1325
1418
  const loader = routeLoaders[i];
1326
- const promise = loadRouteLoader(loader, requestEvent);
1419
+ const promise = loadRouteLoader(loader, requestEv);
1327
1420
  promise.catch(() => {});
1328
1421
  if (loader.__blockSSR) allBlockSSRLoaders = allBlockSSRLoaders ? allBlockSSRLoaders.then(() => promise) : promise;
1329
1422
  }
@@ -1344,17 +1437,18 @@ function createResolveRequestHandlers() {
1344
1437
  if (!mods.some((m) => {
1345
1438
  if (!m) return false;
1346
1439
  if (m.routeConfig) return typeof m.routeConfig === "function" || m.routeConfig.eTag !== void 0 || m.routeConfig.cacheKey !== void 0;
1347
- return m.eTag !== void 0 || m.cacheKey !== void 0;
1440
+ const page = m;
1441
+ return page.eTag !== void 0 || page.cacheKey !== void 0;
1348
1442
  })) return;
1349
1443
  const loaderValues = getRouteLoaderValues(requestEv);
1350
- const getData = (loaderOrAction) => {
1444
+ const getData = ((loaderOrAction) => {
1351
1445
  const id = loaderOrAction.__id;
1352
1446
  if (loaderOrAction.__brand === "server_loader") {
1353
1447
  if (!(id in loaderValues)) throw new Error("Loader not executed for this request.");
1354
1448
  return loaderValues[id];
1355
1449
  }
1356
1450
  return requestEv.sharedMap.get("@actionId") === id ? requestEv.sharedMap.get("@actionResult") : void 0;
1357
- };
1451
+ });
1358
1452
  const routeLocation = {
1359
1453
  params: requestEv.params,
1360
1454
  url: requestEv.url,
@@ -1490,7 +1584,8 @@ function createResolveRequestHandlers() {
1490
1584
  * Prerendered pages are pruned from the production server route plan, so a request missing the
1491
1585
  * canonical trailing slash lands here as not found. Redirect it when the canonical path was
1492
1586
  * prerendered, and leave a genuine 404 alone.
1493
- */ function fixStaticTrailingSlash(ev) {
1587
+ */
1588
+ function fixStaticTrailingSlash(ev) {
1494
1589
  const canonicalUrl = new URL(ev.originalUrl);
1495
1590
  canonicalUrl.pathname = globalThis.__NO_TRAILING_SLASH__ ? canonicalUrl.pathname.replace(/\/$/, "") : ensureSlash(canonicalUrl.pathname);
1496
1591
  if (isStaticPath(ev.request.method, canonicalUrl)) fixTrailingSlash(ev);
@@ -1649,19 +1744,15 @@ The request origin "${inputOrigin}" does not match the server origin "${origin}"
1649
1744
  };
1650
1745
  }
1651
1746
  var { actionsMiddleware, checkBrand, checkCSRF, fixStaticTrailingSlash, fixTrailingSlash, getPathname, isLastModulePageRoute, isQrl, loadersMiddleware, measure, renderQwikMiddleware, resolveRequestHandlers, streamServerFunctionResult, verifySerializable } = createResolveRequestHandlers();
1652
- /** @public */ var ESCAPE_HTML = /[&<>]/g;
1653
- var escapeHtml = (s) => {
1654
- return s.replace(ESCAPE_HTML, (c) => {
1655
- switch (c) {
1656
- case "&": return "&amp;";
1657
- case "<": return "&lt;";
1658
- case ">": return "&gt;";
1659
- default: return "";
1660
- }
1661
- });
1662
- };
1663
- var COLOR_400 = "#006ce9";
1664
- var COLOR_500 = "#713fc2";
1747
+ /** @public */
1748
+ function getErrorHtml(status, e) {
1749
+ let message = "Server Error";
1750
+ if (e != null) {
1751
+ if (typeof e.message === "string") message = e.message;
1752
+ else message = String(e);
1753
+ }
1754
+ return `<html>` + minimalHtmlResponse(status, message) + `</html>`;
1755
+ }
1665
1756
  function minimalHtmlResponse(status, message) {
1666
1757
  if (typeof status !== "number") status = 500;
1667
1758
  if (typeof message === "string") message = escapeHtml(message);
@@ -1684,15 +1775,39 @@ function minimalHtmlResponse(status, message) {
1684
1775
  <body><p><strong>${status}</strong> <span>${message}</span></p></body>
1685
1776
  `;
1686
1777
  }
1687
- function getErrorHtml(status, e) {
1688
- let message = "Server Error";
1689
- if (e != null) {
1690
- if (typeof e.message === "string") message = e.message;
1691
- else message = String(e);
1778
+ var ESCAPE_HTML = /[&<>]/g;
1779
+ var escapeHtml = (s) => {
1780
+ return s.replace(ESCAPE_HTML, (c) => {
1781
+ switch (c) {
1782
+ case "&": return "&amp;";
1783
+ case "<": return "&lt;";
1784
+ case ">": return "&gt;";
1785
+ default: return "";
1786
+ }
1787
+ });
1788
+ };
1789
+ var COLOR_400 = "#006ce9";
1790
+ var COLOR_500 = "#713fc2";
1791
+ var ensureError = (e) => e instanceof Error || typeof e === "object" && e !== null ? e : new Error(String(e));
1792
+ function runQwikRouter(serverRequestEv, loadedRoute, requestHandlers, rebuildRouteInfo, basePathname = "/") {
1793
+ let resolve;
1794
+ const responsePromise = new Promise((r) => resolve = r);
1795
+ try {
1796
+ const requestEv = createRequestEvent(serverRequestEv, loadedRoute, requestHandlers, basePathname, resolve);
1797
+ return {
1798
+ response: responsePromise,
1799
+ requestEv,
1800
+ completion: _asyncRequestStore ? _asyncRequestStore.run(requestEv, runNext, requestEv, rebuildRouteInfo, resolve) : runNext(requestEv, rebuildRouteInfo, resolve)
1801
+ };
1802
+ } catch (e) {
1803
+ resolve(null);
1804
+ return {
1805
+ response: responsePromise,
1806
+ requestEv: { headersSent: false },
1807
+ completion: Promise.resolve(ensureError(e))
1808
+ };
1692
1809
  }
1693
- return `<html>` + minimalHtmlResponse(status, message) + `</html>`;
1694
1810
  }
1695
- var ensureError = (e) => e instanceof Error || typeof e === "object" && e !== null ? e : new Error(String(e));
1696
1811
  async function runNext(requestEv, rebuildRouteInfo, resolve) {
1697
1812
  try {
1698
1813
  const isValidURL = (url) => new URL(url.pathname + url.search, url);
@@ -1754,23 +1869,4 @@ async function runNext(requestEv, rebuildRouteInfo, resolve) {
1754
1869
  if (!requestEv.isDirty()) resolve(null);
1755
1870
  }
1756
1871
  }
1757
- function runQwikRouter(serverRequestEv, loadedRoute, requestHandlers, rebuildRouteInfo, basePathname = "/") {
1758
- let resolve;
1759
- const responsePromise = new Promise((r) => resolve = r);
1760
- try {
1761
- const requestEv = createRequestEvent(serverRequestEv, loadedRoute, requestHandlers, basePathname, resolve);
1762
- return {
1763
- response: responsePromise,
1764
- requestEv,
1765
- completion: _asyncRequestStore ? _asyncRequestStore.run(requestEv, runNext, requestEv, rebuildRouteInfo, resolve) : runNext(requestEv, rebuildRouteInfo, resolve)
1766
- };
1767
- } catch (e) {
1768
- resolve(null);
1769
- return {
1770
- response: responsePromise,
1771
- requestEv: { headersSent: false },
1772
- completion: Promise.resolve(ensureError(e))
1773
- };
1774
- }
1775
- }
1776
1872
  export { getStaticPathRedirect as a, clearSsrCache as c, mergeHeadersCookies as d, resolveRequestHandlers as i, RequestEvErrorBoundaryCaught as l, getErrorHtml as n, isStaticPath as o, renderQwikMiddleware as r, clearLoaderCache as s, runQwikRouter as t, RewriteMessage as u };