@vercel/microfrontends 2.3.4 → 2.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # @vercel/microfrontends
2
2
 
3
+ ## 2.3.5
4
+
5
+ ### Patch Changes
6
+
7
+ - 5fbc4e3: Preserve absolute URLs in query parameters when the local proxy normalizes request URLs and rewrites redirect Location headers.
8
+ - 9a01e16: Route Vercel Toolbar well-known requests through the local proxy to the locally running application that served the page. This supports `@vercel/toolbar@0.2.6+`, which uses `/.well-known/vercel-toolbar/*` for local dev server access.
9
+
3
10
  ## 2.3.4
4
11
 
5
12
  ### Patch Changes
package/dist/bin/cli.cjs CHANGED
@@ -30,7 +30,7 @@ var import_commander = require("commander");
30
30
  // package.json
31
31
  var package_default = {
32
32
  name: "@vercel/microfrontends",
33
- version: "2.3.4",
33
+ version: "2.3.5",
34
34
  private: false,
35
35
  description: "Defines configuration and utilities for microfrontends development",
36
36
  keywords: [
@@ -2370,6 +2370,20 @@ var localAuthHtml = ({
2370
2370
  var MFE_LOCAL_PROXY_HEADER = "x-vercel-mfe-local-proxy-origin";
2371
2371
  var MFE_FLAG_VALUE = "vercel-mfe-flag-value";
2372
2372
  var MFE_FLAG_VALUE_HEADER = `x-${MFE_FLAG_VALUE}`;
2373
+ var VERCEL_TOOLBAR_PROXY_BASE_PATH = "/.well-known/vercel-toolbar";
2374
+ function normalizeRepeatedSlashesInPath(url) {
2375
+ const searchStart = url.indexOf("?");
2376
+ const path7 = searchStart === -1 ? url : url.slice(0, searchStart);
2377
+ const search = searchStart === -1 ? "" : url.slice(searchStart);
2378
+ return `${path7.replaceAll(/\/[\\/]+/g, "/")}${search}`;
2379
+ }
2380
+ function rewriteRedirectLocation(locationHeader, localhost) {
2381
+ const redirectUrl = new import_node_url.URL(locationHeader, localhost);
2382
+ const localUrl = new import_node_url.URL(localhost);
2383
+ redirectUrl.protocol = localUrl.protocol;
2384
+ redirectUrl.host = localUrl.host;
2385
+ return redirectUrl.toString();
2386
+ }
2373
2387
  var ProxyRequestRouter = class {
2374
2388
  constructor(config, {
2375
2389
  localApps
@@ -2494,6 +2508,15 @@ var ProxyRequestRouter = class {
2494
2508
  middlewareMfeZone = void 0,
2495
2509
  mfeFlagValue = void 0
2496
2510
  }) {
2511
+ const toolbarTarget = this.checkVercelToolbar({
2512
+ path: path7,
2513
+ url,
2514
+ referer,
2515
+ applications
2516
+ });
2517
+ if (toolbarTarget) {
2518
+ return toolbarTarget;
2519
+ }
2497
2520
  for (const application of Object.values(applications)) {
2498
2521
  const target = this.getApplicationTarget(application);
2499
2522
  if (middlewareMfeZone) {
@@ -2606,6 +2629,46 @@ var ProxyRequestRouter = class {
2606
2629
  path: `${url.pathname}${url.search}`
2607
2630
  };
2608
2631
  }
2632
+ checkVercelToolbar({
2633
+ path: path7,
2634
+ url,
2635
+ referer = void 0,
2636
+ applications
2637
+ }) {
2638
+ const isVercelToolbarRequest = url.pathname === VERCEL_TOOLBAR_PROXY_BASE_PATH || url.pathname.startsWith(`${VERCEL_TOOLBAR_PROXY_BASE_PATH}/`);
2639
+ if (!isVercelToolbarRequest) {
2640
+ return null;
2641
+ }
2642
+ if (referer) {
2643
+ const refererURL = new import_node_url.URL(referer);
2644
+ const refererTarget = this.findMatchingApplication({
2645
+ path: `${refererURL.pathname}${refererURL.search}`,
2646
+ url: refererURL,
2647
+ applications
2648
+ }) ?? this.getDefaultHost(this.config);
2649
+ if (refererTarget.isLocal) {
2650
+ logger.debug(
2651
+ ` ${path7} - Routing Vercel Toolbar request to referring application: ${formatProxyTarget(refererTarget)}`
2652
+ );
2653
+ return {
2654
+ ...refererTarget,
2655
+ path: `${url.pathname}${url.search}`
2656
+ };
2657
+ }
2658
+ }
2659
+ const localApp = this.getSingleLocalApp();
2660
+ if (!localApp) {
2661
+ return null;
2662
+ }
2663
+ const target = this.getApplicationTarget(localApp);
2664
+ logger.debug(
2665
+ ` ${path7} - Routing Vercel Toolbar request to only locally running application: ${formatProxyTarget(target)}`
2666
+ );
2667
+ return {
2668
+ ...target,
2669
+ path: `${url.pathname}${url.search}`
2670
+ };
2671
+ }
2609
2672
  checkNextSourceMap({ url }) {
2610
2673
  const isSourceMap = (0, import_path_to_regexp3.pathToRegexp)("/__nextjs_source-map").test(url.pathname);
2611
2674
  if (!isSourceMap) {
@@ -2662,20 +2725,26 @@ var ProxyRequestRouter = class {
2662
2725
  }
2663
2726
  isDefaultAppLocal() {
2664
2727
  const defaultApp = this.config.getDefaultApplication();
2665
- return Boolean(
2666
- this.localApps.find(
2667
- (name) => name === defaultApp.name || name === defaultApp.packageName
2668
- )
2669
- );
2728
+ return this.isApplicationLocal(defaultApp);
2670
2729
  }
2671
2730
  getArbitraryLocalApp() {
2672
2731
  for (const application of this.config.getAllApplications()) {
2673
- const name = application.name;
2674
- if (this.localApps.includes(name)) {
2732
+ if (this.isApplicationLocal(application)) {
2675
2733
  return application;
2676
2734
  }
2677
2735
  }
2678
2736
  }
2737
+ getSingleLocalApp() {
2738
+ const localApplications = this.config.getAllApplications().filter((application) => this.isApplicationLocal(application));
2739
+ return localApplications.length === 1 ? localApplications[0] : void 0;
2740
+ }
2741
+ isApplicationLocal(application) {
2742
+ return Boolean(
2743
+ this.localApps.find(
2744
+ (name) => name === application.name || name === application.packageName
2745
+ )
2746
+ );
2747
+ }
2679
2748
  };
2680
2749
  var LocalProxy = class {
2681
2750
  constructor(config, {
@@ -2778,7 +2847,7 @@ var LocalProxy = class {
2778
2847
  if (req.url?.includes("//")) {
2779
2848
  const originalUrl = req.url;
2780
2849
  if (originalUrl) {
2781
- const normalizedUrl = originalUrl.replaceAll(/\/[\\/]+/g, "/");
2850
+ const normalizedUrl = normalizeRepeatedSlashesInPath(originalUrl);
2782
2851
  if (normalizedUrl !== originalUrl) {
2783
2852
  res.writeHead(307, {
2784
2853
  Location: normalizedUrl,
@@ -2851,11 +2920,10 @@ var LocalProxy = class {
2851
2920
  if (realRes.statusCode === 307 || realRes.statusCode === 308 || realRes.statusCode === 302 || realRes.statusCode === 301) {
2852
2921
  const locationHeader = realRes.headers.location;
2853
2922
  if (locationHeader) {
2854
- const redirectUrl = new import_node_url.URL(
2855
- locationHeader.replace(/https:\/\/[^/]+\//, "/"),
2923
+ realRes.headers.location = rewriteRedirectLocation(
2924
+ locationHeader,
2856
2925
  localhost
2857
2926
  );
2858
- realRes.headers.location = redirectUrl.toString();
2859
2927
  }
2860
2928
  }
2861
2929
  res.writeHead(realRes.statusCode || 200, realRes.headers);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vercel/microfrontends",
3
- "version": "2.3.4",
3
+ "version": "2.3.5",
4
4
  "private": false,
5
5
  "description": "Defines configuration and utilities for microfrontends development",
6
6
  "keywords": [