@qwik.dev/router 2.0.0-alpha.9 → 2.0.0-beta.2

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 -810
  25. package/lib/index.qwik.cjs +110 -48
  26. package/lib/index.qwik.mjs +112 -50
  27. package/lib/middleware/aws-lambda/index.d.ts +48 -48
  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 -64
  36. package/lib/middleware/request-handler/index.cjs +142 -73
  37. package/lib/middleware/request-handler/index.d.ts +710 -676
  38. package/lib/middleware/request-handler/index.mjs +138 -70
  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 -96
  45. package/lib/static/node.cjs +3 -3
  46. package/lib/vite/index.cjs +209 -261
  47. package/lib/vite/index.d.ts +154 -154
  48. package/lib/vite/index.mjs +207 -259
  49. package/package.json +7 -7
@@ -28,17 +28,18 @@ 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 {
@@ -260,6 +261,14 @@ var AbortMessage = class {
260
261
  var RedirectMessage = class extends AbortMessage {
261
262
  };
262
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
+
263
272
  // packages/qwik-router/src/runtime/src/constants.ts
264
273
  var MODULE_CACHE = /* @__PURE__ */ new WeakMap();
265
274
  var QACTION_KEY = "qaction";
@@ -495,8 +504,7 @@ function createCacheControl(cacheControl) {
495
504
  cacheControl = {
496
505
  public: true,
497
506
  immutable: true,
498
- maxAge: 60 * 60 * 24 * 365,
499
- staleWhileRevalidate: 60 * 60 * 24 * 365
507
+ maxAge: 60 * 60 * 24 * 365
500
508
  };
501
509
  } else if (cacheControl === "no-cache") {
502
510
  cacheControl = {
@@ -506,8 +514,7 @@ function createCacheControl(cacheControl) {
506
514
  if (typeof cacheControl === "number") {
507
515
  cacheControl = {
508
516
  maxAge: cacheControl,
509
- sMaxAge: cacheControl,
510
- staleWhileRevalidate: cacheControl
517
+ sMaxAge: cacheControl
511
518
  };
512
519
  }
513
520
  if (cacheControl.immutable) {
@@ -552,14 +559,13 @@ import("node:async_hooks").then((module2) => {
552
559
  err
553
560
  );
554
561
  });
555
- function runQwikRouter(serverRequestEv, loadedRoute, requestHandlers, manifest, trailingSlash = true, basePathname = "/", qwikSerializer) {
562
+ function runQwikRouter(serverRequestEv, loadedRoute, requestHandlers, rebuildRouteInfo, trailingSlash = true, basePathname = "/", qwikSerializer) {
556
563
  let resolve;
557
564
  const responsePromise = new Promise((r) => resolve = r);
558
565
  const requestEv = createRequestEvent(
559
566
  serverRequestEv,
560
567
  loadedRoute,
561
568
  requestHandlers,
562
- manifest,
563
569
  trailingSlash,
564
570
  basePathname,
565
571
  qwikSerializer,
@@ -568,55 +574,71 @@ function runQwikRouter(serverRequestEv, loadedRoute, requestHandlers, manifest,
568
574
  return {
569
575
  response: responsePromise,
570
576
  requestEv,
571
- 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)
572
578
  };
573
579
  }
574
- async function runNext(requestEv, resolve) {
575
- try {
576
- await requestEv.next();
577
- } catch (e) {
578
- if (e instanceof RedirectMessage) {
579
- const stream = requestEv.getWritableStream();
580
- await stream.close();
581
- } else if (e instanceof ServerError) {
582
- if (!requestEv.headersSent) {
583
- const status = e.status;
584
- const accept = requestEv.request.headers.get("Accept");
585
- if (accept && !accept.includes("text/html")) {
586
- const qwikSerializer = requestEv[RequestEvQwikSerializer];
587
- requestEv.headers.set("Content-Type", "application/qwik-json");
588
- requestEv.send(status, await qwikSerializer._serialize([e.data]));
589
- } else {
590
- const html = getErrorHtml(e.status, e.data);
591
- requestEv.html(status, html);
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
592
  }
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);
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();
@@ -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
  },
@@ -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) {
@@ -1182,14 +1225,21 @@ async function pureServerFunction(ev) {
1182
1225
  const [qrl, ...args] = data;
1183
1226
  if (isQrl(qrl) && qrl.getHash() === fn) {
1184
1227
  let result;
1185
- if (isDev) {
1186
- result = await measure(
1187
- ev,
1188
- `server_${qrl.getSymbol()}`,
1189
- () => qrl.apply(ev, args)
1190
- );
1191
- } else {
1192
- result = await qrl.apply(ev, args);
1228
+ try {
1229
+ if (isDev) {
1230
+ result = await measure(
1231
+ ev,
1232
+ `server_${qrl.getSymbol()}`,
1233
+ () => qrl.apply(ev, args)
1234
+ );
1235
+ } else {
1236
+ result = await qrl.apply(ev, args);
1237
+ }
1238
+ } catch (err) {
1239
+ if (err instanceof ServerError) {
1240
+ throw ev.error(err.status, err.data);
1241
+ }
1242
+ throw ev.error(500, "Invalid request");
1193
1243
  }
1194
1244
  if (isAsyncIterator(result)) {
1195
1245
  ev.headers.set("Content-Type", "text/qwik-json-stream");
@@ -1221,18 +1271,19 @@ async function pureServerFunction(ev) {
1221
1271
  }
1222
1272
  function fixTrailingSlash(ev) {
1223
1273
  const trailingSlash = getRequestTrailingSlash(ev);
1224
- const { basePathname, pathname, url, sharedMap } = ev;
1274
+ const { basePathname, originalUrl, sharedMap } = ev;
1275
+ const { pathname, search } = originalUrl;
1225
1276
  const isQData = sharedMap.has(IsQData);
1226
1277
  if (!isQData && pathname !== basePathname && !pathname.endsWith(".html")) {
1227
1278
  if (trailingSlash) {
1228
1279
  if (!pathname.endsWith("/")) {
1229
- throw ev.redirect(301 /* MovedPermanently */, pathname + "/" + url.search);
1280
+ throw ev.redirect(301 /* MovedPermanently */, pathname + "/" + search);
1230
1281
  }
1231
1282
  } else {
1232
1283
  if (pathname.endsWith("/")) {
1233
1284
  throw ev.redirect(
1234
1285
  301 /* MovedPermanently */,
1235
- pathname.slice(0, pathname.length - 1) + url.search
1286
+ pathname.slice(0, pathname.length - 1) + search
1236
1287
  );
1237
1288
  }
1238
1289
  }
@@ -1384,7 +1435,7 @@ async function renderQData(requestEv) {
1384
1435
  return;
1385
1436
  }
1386
1437
  const status = requestEv.status();
1387
- const location = requestEv.headers.get("Location");
1438
+ const redirectLocation = requestEv.headers.get("Location");
1388
1439
  const trailingSlash = getRequestTrailingSlash(requestEv);
1389
1440
  const requestHeaders = {};
1390
1441
  requestEv.request.headers.forEach((value, key) => requestHeaders[key] = value);
@@ -1394,7 +1445,8 @@ async function renderQData(requestEv) {
1394
1445
  action: requestEv.sharedMap.get(RequestEvSharedActionId),
1395
1446
  status: status !== 200 ? status : 200,
1396
1447
  href: getPathname(requestEv.url, trailingSlash),
1397
- redirect: location ?? void 0
1448
+ redirect: redirectLocation ?? void 0,
1449
+ isRewrite: requestEv.sharedMap.get(RequestEvIsRewrite)
1398
1450
  };
1399
1451
  const writer = requestEv.getWritableStream().getWriter();
1400
1452
  const qwikSerializer = requestEv[RequestEvQwikSerializer];
@@ -1437,7 +1489,7 @@ function isContentType(headers, ...types) {
1437
1489
 
1438
1490
  // packages/qwik-router/src/middleware/request-handler/request-handler.ts
1439
1491
  async function requestHandler(serverRequestEv, opts, qwikSerializer) {
1440
- const { render, qwikRouterConfig, manifest, checkOrigin } = opts;
1492
+ const { render, qwikRouterConfig, checkOrigin } = opts;
1441
1493
  if (!qwikRouterConfig) {
1442
1494
  throw new Error("qwikRouterConfig is required.");
1443
1495
  }
@@ -1452,11 +1504,27 @@ async function requestHandler(serverRequestEv, opts, qwikSerializer) {
1452
1504
  );
1453
1505
  if (routeAndHandlers) {
1454
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
+ };
1455
1523
  return runQwikRouter(
1456
1524
  serverRequestEv,
1457
1525
  route,
1458
1526
  requestHandlers,
1459
- manifest,
1527
+ rebuildRouteInfo,
1460
1528
  qwikRouterConfig.trailingSlash,
1461
1529
  qwikRouterConfig.basePathname,
1462
1530
  qwikSerializer
@@ -1537,6 +1605,7 @@ var _TextEncoderStream_polyfill = class {
1537
1605
  0 && (module.exports = {
1538
1606
  AbortMessage,
1539
1607
  RedirectMessage,
1608
+ RewriteMessage,
1540
1609
  ServerError,
1541
1610
  _TextEncoderStream_polyfill,
1542
1611
  getErrorHtml,