@qwik.dev/router 2.0.0-alpha.8 → 2.0.0-beta.1

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 (49) hide show
  1. package/README.md +1 -1
  2. package/lib/adapters/azure-swa/vite/index.cjs +3 -3
  3. package/lib/adapters/azure-swa/vite/index.d.ts +13 -13
  4. package/lib/adapters/bun-server/vite/index.cjs +3 -3
  5. package/lib/adapters/bun-server/vite/index.d.ts +14 -14
  6. package/lib/adapters/cloud-run/vite/index.cjs +3 -3
  7. package/lib/adapters/cloud-run/vite/index.d.ts +13 -13
  8. package/lib/adapters/cloudflare-pages/vite/index.cjs +3 -3
  9. package/lib/adapters/cloudflare-pages/vite/index.d.ts +27 -27
  10. package/lib/adapters/deno-server/vite/index.cjs +3 -3
  11. package/lib/adapters/deno-server/vite/index.d.ts +14 -14
  12. package/lib/adapters/netlify-edge/vite/index.cjs +3 -3
  13. package/lib/adapters/netlify-edge/vite/index.d.ts +44 -44
  14. package/lib/adapters/node-server/vite/index.cjs +3 -3
  15. package/lib/adapters/node-server/vite/index.d.ts +14 -14
  16. package/lib/adapters/shared/vite/index.cjs +10 -3
  17. package/lib/adapters/shared/vite/index.d.ts +114 -114
  18. package/lib/adapters/shared/vite/index.mjs +7 -0
  19. package/lib/adapters/static/vite/index.cjs +10 -3
  20. package/lib/adapters/static/vite/index.d.ts +10 -10
  21. package/lib/adapters/static/vite/index.mjs +7 -0
  22. package/lib/adapters/vercel-edge/vite/index.cjs +3 -3
  23. package/lib/adapters/vercel-edge/vite/index.d.ts +45 -45
  24. package/lib/index.d.ts +878 -801
  25. package/lib/index.qwik.cjs +127 -51
  26. package/lib/index.qwik.mjs +130 -54
  27. package/lib/middleware/aws-lambda/index.d.ts +48 -50
  28. package/lib/middleware/azure-swa/index.d.ts +28 -28
  29. package/lib/middleware/bun/index.d.ts +35 -35
  30. package/lib/middleware/cloudflare-pages/index.d.ts +35 -35
  31. package/lib/middleware/deno/index.d.ts +47 -47
  32. package/lib/middleware/firebase/index.d.ts +26 -26
  33. package/lib/middleware/netlify-edge/index.d.ts +27 -27
  34. package/lib/middleware/node/index.cjs +3 -3
  35. package/lib/middleware/node/index.d.ts +64 -66
  36. package/lib/middleware/request-handler/index.cjs +133 -75
  37. package/lib/middleware/request-handler/index.d.ts +710 -681
  38. package/lib/middleware/request-handler/index.mjs +129 -72
  39. package/lib/middleware/vercel-edge/index.d.ts +26 -26
  40. package/lib/service-worker.cjs +13 -263
  41. package/lib/service-worker.d.ts +15 -4
  42. package/lib/service-worker.mjs +13 -263
  43. package/lib/static/index.cjs +3 -3
  44. package/lib/static/index.d.ts +96 -98
  45. package/lib/static/node.cjs +3 -3
  46. package/lib/vite/index.cjs +199 -262
  47. package/lib/vite/index.d.ts +154 -154
  48. package/lib/vite/index.mjs +197 -260
  49. package/package.json +8 -8
@@ -1,66 +1,64 @@
1
- /// <reference types="node" />
2
-
3
- import type { ClientConn } from '@qwik.dev/router/middleware/request-handler';
4
- import type { Http2ServerRequest } from 'node:http2';
5
- import type { IncomingMessage } from 'node:http';
6
- import type { ServerRenderOptions } from '@qwik.dev/router/middleware/request-handler';
7
- import type { ServerResponse } from 'node:http';
8
-
9
- /**
10
- * @deprecated Use `createQwikRouter` instead. Will be removed in V3
11
- * @public
12
- */
13
- export declare const createQwikCity: typeof createQwikRouter;
14
-
15
- /** @public */
16
- export declare function createQwikRouter(opts: QwikRouterNodeRequestOptions | QwikCityNodeRequestOptions): {
17
- router: (req: IncomingMessage | Http2ServerRequest, res: ServerResponse, next: NodeRequestNextFunction) => Promise<void>;
18
- notFound: (req: IncomingMessage | Http2ServerRequest, res: ServerResponse, next: (e: any) => void) => Promise<void>;
19
- staticFile: (req: IncomingMessage | Http2ServerRequest, res: ServerResponse, next: (e?: any) => void) => Promise<void>;
20
- };
21
-
22
- /** @public */
23
- export declare interface NodeRequestNextFunction {
24
- (err?: any): void;
25
- }
26
-
27
- /** @public */
28
- export declare interface PlatformNode {
29
- ssr?: true;
30
- incomingMessage?: IncomingMessage | Http2ServerRequest;
31
- node?: string;
32
- }
33
-
34
- /**
35
- * @deprecated Use `QwikRouterNodeRequestOptions` instead. Will be removed in V3
36
- * @public
37
- */
38
- export declare type QwikCityNodeRequestOptions = QwikRouterNodeRequestOptions;
39
-
40
- /** @public */
41
- export declare interface QwikRouterNodeRequestOptions extends ServerRenderOptions {
42
- /** Options for serving static files */
43
- static?: {
44
- /** The root folder for statics files. Defaults to /dist */
45
- root?: string;
46
- /** Set the Cache-Control header for all static files */
47
- cacheControl?: string;
48
- };
49
- /**
50
- * Provide a function that computes the origin of the server, used to resolve relative URLs and
51
- * validate the request origin against CSRF attacks.
52
- *
53
- * When not specified, it defaults to the `ORIGIN` environment variable (if set).
54
- *
55
- * If `ORIGIN` is not set, it's derived from the incoming request, which is not recommended for
56
- * production use. You can specify the `PROTOCOL_HEADER`, `HOST_HEADER` to `X-Forwarded-Proto` and
57
- * `X-Forwarded-Host` respectively to override the default behavior.
58
- */
59
- getOrigin?: (req: IncomingMessage | Http2ServerRequest) => string | null;
60
- /** Provide a function that returns a `ClientConn` for the given request. */
61
- getClientConn?: (req: IncomingMessage | Http2ServerRequest) => ClientConn;
62
- /** @deprecated Use `getOrigin` instead. Will be removed in V3 */
63
- origin?: string;
64
- }
65
-
66
- export { }
1
+ import type { ClientConn } from '@qwik.dev/router/middleware/request-handler';
2
+ import type { Http2ServerRequest } from 'node:http2';
3
+ import type { IncomingMessage } from 'node:http';
4
+ import type { ServerRenderOptions } from '@qwik.dev/router/middleware/request-handler';
5
+ import type { ServerResponse } from 'node:http';
6
+
7
+ /**
8
+ * @deprecated Use `createQwikRouter` instead. Will be removed in V3
9
+ * @public
10
+ */
11
+ export declare const createQwikCity: typeof createQwikRouter;
12
+
13
+ /** @public */
14
+ export declare function createQwikRouter(opts: QwikRouterNodeRequestOptions | QwikCityNodeRequestOptions): {
15
+ router: (req: IncomingMessage | Http2ServerRequest, res: ServerResponse, next: NodeRequestNextFunction) => Promise<void>;
16
+ notFound: (req: IncomingMessage | Http2ServerRequest, res: ServerResponse, next: (e: any) => void) => Promise<void>;
17
+ staticFile: (req: IncomingMessage | Http2ServerRequest, res: ServerResponse, next: (e?: any) => void) => Promise<void>;
18
+ };
19
+
20
+ /** @public */
21
+ export declare interface NodeRequestNextFunction {
22
+ (err?: any): void;
23
+ }
24
+
25
+ /** @public */
26
+ export declare interface PlatformNode {
27
+ ssr?: true;
28
+ incomingMessage?: IncomingMessage | Http2ServerRequest;
29
+ node?: string;
30
+ }
31
+
32
+ /**
33
+ * @deprecated Use `QwikRouterNodeRequestOptions` instead. Will be removed in V3
34
+ * @public
35
+ */
36
+ export declare type QwikCityNodeRequestOptions = QwikRouterNodeRequestOptions;
37
+
38
+ /** @public */
39
+ export declare interface QwikRouterNodeRequestOptions extends ServerRenderOptions {
40
+ /** Options for serving static files */
41
+ static?: {
42
+ /** The root folder for statics files. Defaults to /dist */
43
+ root?: string;
44
+ /** Set the Cache-Control header for all static files */
45
+ cacheControl?: string;
46
+ };
47
+ /**
48
+ * Provide a function that computes the origin of the server, used to resolve relative URLs and
49
+ * validate the request origin against CSRF attacks.
50
+ *
51
+ * When not specified, it defaults to the `ORIGIN` environment variable (if set).
52
+ *
53
+ * If `ORIGIN` is not set, it's derived from the incoming request, which is not recommended for
54
+ * production use. You can specify the `PROTOCOL_HEADER`, `HOST_HEADER` to `X-Forwarded-Proto` and
55
+ * `X-Forwarded-Host` respectively to override the default behavior.
56
+ */
57
+ getOrigin?: (req: IncomingMessage | Http2ServerRequest) => string | null;
58
+ /** Provide a function that returns a `ClientConn` for the given request. */
59
+ getClientConn?: (req: IncomingMessage | Http2ServerRequest) => ClientConn;
60
+ /** @deprecated Use `getOrigin` instead. Will be removed in V3 */
61
+ origin?: string;
62
+ }
63
+
64
+ export { }
@@ -28,32 +28,27 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
29
 
30
30
  // packages/qwik-router/src/middleware/request-handler/index.ts
31
- var request_handler_exports = {};
32
- __export(request_handler_exports, {
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
33
  AbortMessage: () => AbortMessage,
34
34
  RedirectMessage: () => RedirectMessage,
35
+ RewriteMessage: () => RewriteMessage,
35
36
  ServerError: () => ServerError,
36
37
  _TextEncoderStream_polyfill: () => _TextEncoderStream_polyfill,
37
38
  getErrorHtml: () => getErrorHtml,
38
39
  mergeHeadersCookies: () => mergeHeadersCookies,
39
40
  requestHandler: () => requestHandler
40
41
  });
41
- module.exports = __toCommonJS(request_handler_exports);
42
+ module.exports = __toCommonJS(index_exports);
42
43
 
43
44
  // packages/qwik-router/src/middleware/request-handler/error-handler.ts
44
45
  var ServerError = class extends Error {
45
46
  constructor(status, data) {
46
- super();
47
+ super(typeof data === "string" ? data : void 0);
47
48
  this.status = status;
48
49
  this.data = data;
49
50
  }
50
51
  };
51
- var ErrorResponse = class extends Error {
52
- constructor(status, message) {
53
- super(message);
54
- this.status = status;
55
- }
56
- };
57
52
  function getErrorHtml(status, e) {
58
53
  let message = "Server Error";
59
54
  if (e != null) {
@@ -266,6 +261,14 @@ var AbortMessage = class {
266
261
  var RedirectMessage = class extends AbortMessage {
267
262
  };
268
263
 
264
+ // packages/qwik-router/src/middleware/request-handler/rewrite-handler.ts
265
+ var RewriteMessage = class extends AbortMessage {
266
+ constructor(pathname) {
267
+ super();
268
+ this.pathname = pathname;
269
+ }
270
+ };
271
+
269
272
  // packages/qwik-router/src/runtime/src/constants.ts
270
273
  var MODULE_CACHE = /* @__PURE__ */ new WeakMap();
271
274
  var QACTION_KEY = "qaction";
@@ -501,8 +504,7 @@ function createCacheControl(cacheControl) {
501
504
  cacheControl = {
502
505
  public: true,
503
506
  immutable: true,
504
- maxAge: 60 * 60 * 24 * 365,
505
- staleWhileRevalidate: 60 * 60 * 24 * 365
507
+ maxAge: 60 * 60 * 24 * 365
506
508
  };
507
509
  } else if (cacheControl === "no-cache") {
508
510
  cacheControl = {
@@ -512,8 +514,7 @@ function createCacheControl(cacheControl) {
512
514
  if (typeof cacheControl === "number") {
513
515
  cacheControl = {
514
516
  maxAge: cacheControl,
515
- sMaxAge: cacheControl,
516
- staleWhileRevalidate: cacheControl
517
+ sMaxAge: cacheControl
517
518
  };
518
519
  }
519
520
  if (cacheControl.immutable) {
@@ -558,14 +559,13 @@ import("node:async_hooks").then((module2) => {
558
559
  err
559
560
  );
560
561
  });
561
- function runQwikRouter(serverRequestEv, loadedRoute, requestHandlers, manifest, trailingSlash = true, basePathname = "/", qwikSerializer) {
562
+ function runQwikRouter(serverRequestEv, loadedRoute, requestHandlers, rebuildRouteInfo, trailingSlash = true, basePathname = "/", qwikSerializer) {
562
563
  let resolve;
563
564
  const responsePromise = new Promise((r) => resolve = r);
564
565
  const requestEv = createRequestEvent(
565
566
  serverRequestEv,
566
567
  loadedRoute,
567
568
  requestHandlers,
568
- manifest,
569
569
  trailingSlash,
570
570
  basePathname,
571
571
  qwikSerializer,
@@ -574,49 +574,71 @@ function runQwikRouter(serverRequestEv, loadedRoute, requestHandlers, manifest,
574
574
  return {
575
575
  response: responsePromise,
576
576
  requestEv,
577
- completion: asyncStore ? asyncStore.run(requestEv, runNext, requestEv, resolve) : runNext(requestEv, resolve)
577
+ completion: asyncStore ? asyncStore.run(requestEv, runNext, requestEv, rebuildRouteInfo, resolve) : runNext(requestEv, rebuildRouteInfo, resolve)
578
578
  };
579
579
  }
580
- async function runNext(requestEv, resolve) {
581
- try {
582
- await requestEv.next();
583
- } catch (e) {
584
- if (e instanceof RedirectMessage) {
585
- const stream = requestEv.getWritableStream();
586
- await stream.close();
587
- } else if (e instanceof ErrorResponse) {
588
- console.error(e);
589
- if (!requestEv.headersSent) {
590
- const html = getErrorHtml(e.status, e);
591
- const status = e.status;
592
- requestEv.html(status, html);
593
- }
594
- } else if (!(e instanceof AbortMessage)) {
595
- if (getRequestMode(requestEv) !== "dev") {
596
- try {
597
- if (!requestEv.headersSent) {
598
- requestEv.headers.set("content-type", "text/html; charset=utf-8");
599
- requestEv.cacheControl({ noCache: true });
600
- requestEv.status(500);
580
+ async function runNext(requestEv, rebuildRouteInfo, resolve) {
581
+ let rewriteAttempt = 1;
582
+ async function _runNext() {
583
+ try {
584
+ await requestEv.next();
585
+ } catch (e) {
586
+ if (e instanceof RedirectMessage) {
587
+ const stream = requestEv.getWritableStream();
588
+ await stream.close();
589
+ } else if (e instanceof RewriteMessage) {
590
+ if (rewriteAttempt > 50) {
591
+ throw new Error(`Infinite rewrite loop`);
592
+ }
593
+ rewriteAttempt += 1;
594
+ const url = new URL(requestEv.url);
595
+ url.pathname = e.pathname;
596
+ const { loadedRoute, requestHandlers } = await rebuildRouteInfo(url);
597
+ requestEv.resetRoute(loadedRoute, requestHandlers, url);
598
+ return await _runNext();
599
+ } else if (e instanceof ServerError) {
600
+ if (!requestEv.headersSent) {
601
+ const status = e.status;
602
+ const accept = requestEv.request.headers.get("Accept");
603
+ if (accept && !accept.includes("text/html")) {
604
+ const qwikSerializer = requestEv[RequestEvQwikSerializer];
605
+ requestEv.headers.set("Content-Type", "application/qwik-json");
606
+ requestEv.send(status, await qwikSerializer._serialize([e.data]));
607
+ } else {
608
+ const html = getErrorHtml(e.status, e.data);
609
+ requestEv.html(status, html);
601
610
  }
602
- const stream = requestEv.getWritableStream();
603
- if (!stream.locked) {
604
- const writer = stream.getWriter();
605
- await writer.write(encoder.encode(minimalHtmlResponse(500, "Internal Server Error")));
606
- await writer.close();
611
+ }
612
+ } else if (!(e instanceof AbortMessage)) {
613
+ if (getRequestMode(requestEv) !== "dev") {
614
+ try {
615
+ if (!requestEv.headersSent) {
616
+ requestEv.headers.set("content-type", "text/html; charset=utf-8");
617
+ requestEv.cacheControl({ noCache: true });
618
+ requestEv.status(500);
619
+ }
620
+ const stream = requestEv.getWritableStream();
621
+ if (!stream.locked) {
622
+ const writer = stream.getWriter();
623
+ await writer.write(encoder.encode(minimalHtmlResponse(500, "Internal Server Error")));
624
+ await writer.close();
625
+ }
626
+ } catch {
627
+ console.error("Unable to render error page");
607
628
  }
608
- } catch {
609
- console.error("Unable to render error page");
610
629
  }
630
+ return e;
611
631
  }
612
- return e;
613
632
  }
633
+ return void 0;
634
+ }
635
+ try {
636
+ return await _runNext();
614
637
  } finally {
615
638
  if (!requestEv.isDirty()) {
616
639
  resolve(null);
617
640
  }
618
641
  }
619
- return void 0;
620
642
  }
621
643
  function getRouteMatchPathname(pathname, trailingSlash) {
622
644
  if (pathname.endsWith(QDATA_JSON)) {
@@ -642,7 +664,8 @@ var RequestRouteName = "@routeName";
642
664
  var RequestEvSharedActionId = "@actionId";
643
665
  var RequestEvSharedActionFormData = "@actionFormData";
644
666
  var RequestEvSharedNonce = "@nonce";
645
- function createRequestEvent(serverRequestEv, loadedRoute, requestHandlers, manifest, trailingSlash, basePathname, qwikSerializer, resolved) {
667
+ var RequestEvIsRewrite = "@rewrite";
668
+ function createRequestEvent(serverRequestEv, loadedRoute, requestHandlers, trailingSlash, basePathname, qwikSerializer, resolved) {
646
669
  const { request, platform, env } = serverRequestEv;
647
670
  const sharedMap = /* @__PURE__ */ new Map();
648
671
  const cookie = new Cookie(request.headers.get("cookie"));
@@ -655,7 +678,6 @@ function createRequestEvent(serverRequestEv, loadedRoute, requestHandlers, manif
655
678
  }
656
679
  sharedMap.set(IsQData, true);
657
680
  }
658
- sharedMap.set("@manifest", manifest);
659
681
  let routeModuleIndex = -1;
660
682
  let writableStream = null;
661
683
  let requestData = void 0;
@@ -673,6 +695,13 @@ function createRequestEvent(serverRequestEv, loadedRoute, requestHandlers, manif
673
695
  routeModuleIndex++;
674
696
  }
675
697
  };
698
+ const resetRoute = (_loadedRoute, _requestHandlers, _url = url) => {
699
+ loadedRoute = _loadedRoute;
700
+ requestHandlers = _requestHandlers;
701
+ url.pathname = _url.pathname;
702
+ url.search = _url.search;
703
+ routeModuleIndex = -1;
704
+ };
676
705
  const check = () => {
677
706
  if (writableStream !== null) {
678
707
  throw new Error("Response already sent");
@@ -707,11 +736,7 @@ function createRequestEvent(serverRequestEv, loadedRoute, requestHandlers, manif
707
736
  const writableStream2 = requestEv.getWritableStream();
708
737
  statusOrResponse.body.pipeTo(writableStream2);
709
738
  } else {
710
- if (status >= 300 && status < 400) {
711
- return new RedirectMessage();
712
- } else {
713
- requestEv.getWritableStream().getWriter().close();
714
- }
739
+ requestEv.getWritableStream().getWriter().close();
715
740
  }
716
741
  }
717
742
  return exit();
@@ -725,17 +750,26 @@ function createRequestEvent(serverRequestEv, loadedRoute, requestHandlers, manif
725
750
  [RequestEvLoaders]: loaders,
726
751
  [RequestEvMode]: serverRequestEv.mode,
727
752
  [RequestEvTrailingSlash]: trailingSlash,
728
- [RequestEvRoute]: loadedRoute,
753
+ get [RequestEvRoute]() {
754
+ return loadedRoute;
755
+ },
729
756
  [RequestEvQwikSerializer]: qwikSerializer,
730
757
  cookie,
731
758
  headers,
732
759
  env,
733
760
  method: request.method,
734
761
  signal: request.signal,
735
- params: (loadedRoute == null ? void 0 : loadedRoute[1]) ?? {},
736
- pathname: url.pathname,
762
+ originalUrl: new URL(url),
763
+ get params() {
764
+ return (loadedRoute == null ? void 0 : loadedRoute[1]) ?? {};
765
+ },
766
+ get pathname() {
767
+ return url.pathname;
768
+ },
737
769
  platform,
738
- query: url.searchParams,
770
+ get query() {
771
+ return url.searchParams;
772
+ },
739
773
  request,
740
774
  url,
741
775
  basePathname,
@@ -750,6 +784,7 @@ function createRequestEvent(serverRequestEv, loadedRoute, requestHandlers, manif
750
784
  return serverRequestEv.getClientConn();
751
785
  },
752
786
  next,
787
+ resetRoute,
753
788
  exit,
754
789
  cacheControl: (cacheControl, target = "Cache-Control") => {
755
790
  check();
@@ -782,7 +817,7 @@ function createRequestEvent(serverRequestEv, loadedRoute, requestHandlers, manif
782
817
  },
783
818
  error: (statusCode, message) => {
784
819
  status = statusCode;
785
- return new ErrorResponse(statusCode, message);
820
+ return new ServerError(statusCode, message);
786
821
  },
787
822
  redirect: (statusCode, url2) => {
788
823
  check();
@@ -800,6 +835,14 @@ function createRequestEvent(serverRequestEv, loadedRoute, requestHandlers, manif
800
835
  exit();
801
836
  return new RedirectMessage();
802
837
  },
838
+ rewrite: (pathname) => {
839
+ check();
840
+ if (pathname.startsWith("http")) {
841
+ throw new Error("Rewrite does not support absolute urls");
842
+ }
843
+ sharedMap.set(RequestEvIsRewrite, true);
844
+ return new RewriteMessage(pathname.replace(/\/+/g, "/"));
845
+ },
803
846
  defer: (returnData) => {
804
847
  return typeof returnData === "function" ? returnData : () => returnData;
805
848
  },
@@ -883,7 +926,7 @@ var parseRequest = async ({ request, method, query }, sharedMap, qwikSerializer)
883
926
  if (data) {
884
927
  try {
885
928
  return qwikSerializer._deserialize(decodeURIComponent(data));
886
- } catch (err) {
929
+ } catch {
887
930
  }
888
931
  }
889
932
  }
@@ -911,7 +954,7 @@ var formToObj = (formData) => {
911
954
 
912
955
  // packages/qwik-router/src/middleware/request-handler/response-page.ts
913
956
  function getQwikRouterServerData(requestEv) {
914
- const { url, params, request, status, locale } = requestEv;
957
+ const { params, request, status, locale, originalUrl } = requestEv;
915
958
  const requestHeaders = {};
916
959
  request.headers.forEach((value, key) => requestHeaders[key] = value);
917
960
  const action = requestEv.sharedMap.get(RequestEvSharedActionId);
@@ -919,7 +962,7 @@ function getQwikRouterServerData(requestEv) {
919
962
  const routeName = requestEv.sharedMap.get(RequestRouteName);
920
963
  const nonce = requestEv.sharedMap.get(RequestEvSharedNonce);
921
964
  const headers = requestEv.request.headers;
922
- const reconstructedUrl = new URL(url.pathname + url.search, url);
965
+ const reconstructedUrl = new URL(originalUrl.pathname + originalUrl.search, originalUrl);
923
966
  const host = headers.get("X-Forwarded-Host");
924
967
  const protocol = headers.get("X-Forwarded-Proto");
925
968
  if (host) {
@@ -1194,13 +1237,9 @@ async function pureServerFunction(ev) {
1194
1237
  }
1195
1238
  } catch (err) {
1196
1239
  if (err instanceof ServerError) {
1197
- ev.headers.set("Content-Type", "application/qwik-json");
1198
- ev.send(err.status, await qwikSerializer._serialize([err.data]));
1199
- return;
1240
+ throw ev.error(err.status, err.data);
1200
1241
  }
1201
- ev.headers.set("Content-Type", "application/qwik-json");
1202
- ev.send(500, await qwikSerializer._serialize([err]));
1203
- return;
1242
+ throw ev.error(500, "Invalid request");
1204
1243
  }
1205
1244
  if (isAsyncIterator(result)) {
1206
1245
  ev.headers.set("Content-Type", "text/qwik-json-stream");
@@ -1232,18 +1271,19 @@ async function pureServerFunction(ev) {
1232
1271
  }
1233
1272
  function fixTrailingSlash(ev) {
1234
1273
  const trailingSlash = getRequestTrailingSlash(ev);
1235
- const { basePathname, pathname, url, sharedMap } = ev;
1274
+ const { basePathname, originalUrl, sharedMap } = ev;
1275
+ const { pathname, search } = originalUrl;
1236
1276
  const isQData = sharedMap.has(IsQData);
1237
1277
  if (!isQData && pathname !== basePathname && !pathname.endsWith(".html")) {
1238
1278
  if (trailingSlash) {
1239
1279
  if (!pathname.endsWith("/")) {
1240
- throw ev.redirect(301 /* MovedPermanently */, pathname + "/" + url.search);
1280
+ throw ev.redirect(301 /* MovedPermanently */, pathname + "/" + search);
1241
1281
  }
1242
1282
  } else {
1243
1283
  if (pathname.endsWith("/")) {
1244
1284
  throw ev.redirect(
1245
1285
  301 /* MovedPermanently */,
1246
- pathname.slice(0, pathname.length - 1) + url.search
1286
+ pathname.slice(0, pathname.length - 1) + search
1247
1287
  );
1248
1288
  }
1249
1289
  }
@@ -1395,7 +1435,7 @@ async function renderQData(requestEv) {
1395
1435
  return;
1396
1436
  }
1397
1437
  const status = requestEv.status();
1398
- const location = requestEv.headers.get("Location");
1438
+ const redirectLocation = requestEv.headers.get("Location");
1399
1439
  const trailingSlash = getRequestTrailingSlash(requestEv);
1400
1440
  const requestHeaders = {};
1401
1441
  requestEv.request.headers.forEach((value, key) => requestHeaders[key] = value);
@@ -1405,7 +1445,8 @@ async function renderQData(requestEv) {
1405
1445
  action: requestEv.sharedMap.get(RequestEvSharedActionId),
1406
1446
  status: status !== 200 ? status : 200,
1407
1447
  href: getPathname(requestEv.url, trailingSlash),
1408
- redirect: location ?? void 0
1448
+ redirect: redirectLocation ?? void 0,
1449
+ isRewrite: requestEv.sharedMap.get(RequestEvIsRewrite)
1409
1450
  };
1410
1451
  const writer = requestEv.getWritableStream().getWriter();
1411
1452
  const qwikSerializer = requestEv[RequestEvQwikSerializer];
@@ -1448,7 +1489,7 @@ function isContentType(headers, ...types) {
1448
1489
 
1449
1490
  // packages/qwik-router/src/middleware/request-handler/request-handler.ts
1450
1491
  async function requestHandler(serverRequestEv, opts, qwikSerializer) {
1451
- const { render, qwikRouterConfig, manifest, checkOrigin } = opts;
1492
+ const { render, qwikRouterConfig, checkOrigin } = opts;
1452
1493
  if (!qwikRouterConfig) {
1453
1494
  throw new Error("qwikRouterConfig is required.");
1454
1495
  }
@@ -1463,11 +1504,27 @@ async function requestHandler(serverRequestEv, opts, qwikSerializer) {
1463
1504
  );
1464
1505
  if (routeAndHandlers) {
1465
1506
  const [route, requestHandlers] = routeAndHandlers;
1507
+ const rebuildRouteInfo = async (url) => {
1508
+ const matchPathname2 = getRouteMatchPathname(url.pathname, qwikRouterConfig.trailingSlash);
1509
+ const routeAndHandlers2 = await loadRequestHandlers(
1510
+ qwikRouterConfig,
1511
+ matchPathname2,
1512
+ serverRequestEv.request.method,
1513
+ checkOrigin ?? true,
1514
+ render
1515
+ );
1516
+ if (routeAndHandlers2) {
1517
+ const [loadedRoute, requestHandlers2] = routeAndHandlers2;
1518
+ return { loadedRoute, requestHandlers: requestHandlers2 };
1519
+ } else {
1520
+ return { loadedRoute: null, requestHandlers: [] };
1521
+ }
1522
+ };
1466
1523
  return runQwikRouter(
1467
1524
  serverRequestEv,
1468
1525
  route,
1469
1526
  requestHandlers,
1470
- manifest,
1527
+ rebuildRouteInfo,
1471
1528
  qwikRouterConfig.trailingSlash,
1472
1529
  qwikRouterConfig.basePathname,
1473
1530
  qwikSerializer
@@ -1548,6 +1605,7 @@ var _TextEncoderStream_polyfill = class {
1548
1605
  0 && (module.exports = {
1549
1606
  AbortMessage,
1550
1607
  RedirectMessage,
1608
+ RewriteMessage,
1551
1609
  ServerError,
1552
1610
  _TextEncoderStream_polyfill,
1553
1611
  getErrorHtml,