@vercel/microfrontends 0.9.0 → 0.10.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 (90) hide show
  1. package/README.md +7 -7
  2. package/dist/bin/cli.cjs +1604 -221
  3. package/dist/config/client.d.ts +1 -1
  4. package/dist/config/edge.cjs +47 -47
  5. package/dist/config/edge.cjs.map +1 -1
  6. package/dist/config/edge.d.ts +6 -6
  7. package/dist/config/edge.js +46 -46
  8. package/dist/config/edge.js.map +1 -1
  9. package/dist/config.cjs +67 -66
  10. package/dist/config.cjs.map +1 -1
  11. package/dist/config.d.ts +4 -4
  12. package/dist/config.js +66 -65
  13. package/dist/config.js.map +1 -1
  14. package/dist/{index-eff254d8.d.ts → index-acb44057.d.ts} +12 -23
  15. package/dist/{micro-frontend-config-42886104.d.ts → microfrontend-config-983a5139.d.ts} +13 -13
  16. package/dist/next/client.cjs +1 -1
  17. package/dist/next/client.cjs.map +1 -1
  18. package/dist/next/client.js +1 -1
  19. package/dist/next/client.js.map +1 -1
  20. package/dist/next/config.cjs +86 -87
  21. package/dist/next/config.cjs.map +1 -1
  22. package/dist/next/config.d.ts +3 -3
  23. package/dist/next/config.js +85 -86
  24. package/dist/next/config.js.map +1 -1
  25. package/dist/next/middleware.cjs +60 -62
  26. package/dist/next/middleware.cjs.map +1 -1
  27. package/dist/next/middleware.d.ts +11 -11
  28. package/dist/next/middleware.js +58 -60
  29. package/dist/next/middleware.js.map +1 -1
  30. package/dist/next/testing.cjs +80 -79
  31. package/dist/next/testing.cjs.map +1 -1
  32. package/dist/next/testing.d.ts +10 -10
  33. package/dist/next/testing.js +80 -79
  34. package/dist/next/testing.js.map +1 -1
  35. package/dist/overrides.cjs +9 -9
  36. package/dist/overrides.cjs.map +1 -1
  37. package/dist/overrides.d.ts +2 -2
  38. package/dist/overrides.js +9 -9
  39. package/dist/overrides.js.map +1 -1
  40. package/dist/{schema-83a75e61.d.ts → schema-2922d49e.d.ts} +1 -7
  41. package/dist/{types-4fd1c7c6.d.ts → types-7b1cd9f7.d.ts} +1 -7
  42. package/dist/types-c3d15d04.d.ts +15 -0
  43. package/dist/v2/config.cjs +39 -39
  44. package/dist/v2/config.cjs.map +1 -1
  45. package/dist/v2/config.d.ts +3 -2
  46. package/dist/v2/config.js +38 -38
  47. package/dist/v2/config.js.map +1 -1
  48. package/dist/v2/microfrontends/server.cjs +223 -96
  49. package/dist/v2/microfrontends/server.cjs.map +1 -1
  50. package/dist/v2/microfrontends/server.d.ts +11 -3
  51. package/dist/v2/microfrontends/server.js +223 -96
  52. package/dist/v2/microfrontends/server.js.map +1 -1
  53. package/dist/v2/microfrontends.cjs +44 -44
  54. package/dist/v2/microfrontends.cjs.map +1 -1
  55. package/dist/v2/microfrontends.d.ts +6 -5
  56. package/dist/v2/microfrontends.js +44 -44
  57. package/dist/v2/microfrontends.js.map +1 -1
  58. package/dist/v2/next/client.cjs +1 -1
  59. package/dist/v2/next/client.cjs.map +1 -1
  60. package/dist/v2/next/client.js +1 -1
  61. package/dist/v2/next/client.js.map +1 -1
  62. package/dist/v2/next/config.cjs +247 -122
  63. package/dist/v2/next/config.cjs.map +1 -1
  64. package/dist/v2/next/config.d.ts +4 -4
  65. package/dist/v2/next/config.js +246 -121
  66. package/dist/v2/next/config.js.map +1 -1
  67. package/dist/v2/next/endpoints.cjs +5 -5
  68. package/dist/v2/next/endpoints.cjs.map +1 -1
  69. package/dist/v2/next/endpoints.js +5 -5
  70. package/dist/v2/next/endpoints.js.map +1 -1
  71. package/dist/v2/next/middleware.cjs +55 -55
  72. package/dist/v2/next/middleware.cjs.map +1 -1
  73. package/dist/v2/next/middleware.d.ts +8 -8
  74. package/dist/v2/next/middleware.js +53 -53
  75. package/dist/v2/next/middleware.js.map +1 -1
  76. package/dist/v2/overrides.cjs +75 -0
  77. package/dist/v2/overrides.cjs.map +1 -0
  78. package/dist/v2/overrides.d.ts +24 -0
  79. package/dist/v2/overrides.js +45 -0
  80. package/dist/v2/overrides.js.map +1 -0
  81. package/dist/v2/schema.cjs.map +1 -1
  82. package/dist/v2/schema.d.ts +1 -1
  83. package/dist/validation.cjs +20 -28
  84. package/dist/validation.cjs.map +1 -1
  85. package/dist/validation.d.ts +2 -8
  86. package/dist/validation.js +20 -28
  87. package/dist/validation.js.map +1 -1
  88. package/package.json +15 -7
  89. package/schema/schema-v2.json +0 -4
  90. package/schema/schema.json +0 -4
package/dist/bin/cli.cjs CHANGED
@@ -29,7 +29,7 @@ var import_commander = require("commander");
29
29
  // package.json
30
30
  var package_default = {
31
31
  name: "@vercel/microfrontends",
32
- version: "0.9.0",
32
+ version: "0.10.1",
33
33
  private: false,
34
34
  description: "Defines configuration and utilities for micro-frontend development",
35
35
  repository: {
@@ -87,6 +87,10 @@ var package_default = {
87
87
  import: "./dist/v2/microfrontends.js",
88
88
  require: "./dist/v2/microfrontends.cjs"
89
89
  },
90
+ "./v2/overrides": {
91
+ import: "./dist/v2/overrides.js",
92
+ require: "./dist/v2/overrides.cjs"
93
+ },
90
94
  "./v2/microfrontends/server": {
91
95
  import: "./dist/v2/microfrontends/server.js",
92
96
  require: "./dist/v2/microfrontends/server.cjs"
@@ -129,6 +133,7 @@ var package_default = {
129
133
  "next/testing": ["./dist/next/testing.d.ts"],
130
134
  "v2/config": ["./dist/v2/config.d.ts"],
131
135
  "v2/microfrontends": ["./dist/v2/microfrontends.d.ts"],
136
+ "v2/overrides": ["./dist/v2/overrides.d.ts"],
132
137
  "v2/microfrontends/server": ["./dist/v2/microfrontends/server.d.ts"],
133
138
  "v2/schema": ["./dist/v2/schema.d.ts"],
134
139
  "v2/next/config": ["./dist/v2/next/config.d.ts"],
@@ -156,6 +161,7 @@ var package_default = {
156
161
  ajv: "^8.17.1",
157
162
  commander: "^12.1.0",
158
163
  cookie: "0.4.0",
164
+ "fast-glob": "^3.3.2",
159
165
  "http-proxy": "^1.18.1",
160
166
  "jsonc-parser": "^3.3.1",
161
167
  "path-to-regexp": "6.2.1"
@@ -175,9 +181,9 @@ var package_default = {
175
181
  "@vercel-private/conformance": "^1.12.2-canary.0",
176
182
  jest: "^29.7.0",
177
183
  "jest-environment-jsdom": "29.2.2",
178
- next: "15.0.4-canary.17",
179
- react: "19.0.0-rc-380f5d67-20241113",
180
- "react-dom": "19.0.0-rc-380f5d67-20241113",
184
+ next: "15.0.4-canary.41",
185
+ react: "19.0.0-rc-de68d2f4-20241204",
186
+ "react-dom": "19.0.0-rc-de68d2f4-20241204",
181
187
  "ts-json-schema-generator": "^1.1.2",
182
188
  tsup: "^6.6.2",
183
189
  tsx: "^4.6.2",
@@ -185,9 +191,9 @@ var package_default = {
185
191
  webpack: "5"
186
192
  },
187
193
  peerDependencies: {
188
- next: "15.0.4-canary.17",
189
- react: "19.0.0-rc-380f5d67-20241113",
190
- "react-dom": "19.0.0-rc-380f5d67-20241113"
194
+ next: "15.0.4-canary.41",
195
+ react: "19.0.0-rc-de68d2f4-20241204",
196
+ "react-dom": "19.0.0-rc-de68d2f4-20241204"
191
197
  },
192
198
  publishConfig: {
193
199
  access: "restricted"
@@ -197,14 +203,15 @@ var package_default = {
197
203
  // src/bin/local-proxy.ts
198
204
  var http = __toESM(require("http"), 1);
199
205
  var https = __toESM(require("https"), 1);
206
+ var import_types2 = require("util/types");
200
207
  var import_cookie = require("cookie");
201
- var import_path_to_regexp2 = require("path-to-regexp");
208
+ var import_path_to_regexp4 = require("path-to-regexp");
202
209
  var import_http_proxy = __toESM(require("http-proxy"), 1);
203
210
 
204
211
  // src/config/types.ts
205
212
  var isDefaultApplicationConfig = (app) => app.default && typeof app.routing === "undefined";
206
213
 
207
- // src/config/micro-frontend-config.ts
214
+ // src/config/microfrontend-config.ts
208
215
  var import_node_fs2 = __toESM(require("fs"), 1);
209
216
 
210
217
  // src/config-v2/microfrontends/server/utils/get-output-file-path.ts
@@ -232,14 +239,14 @@ function getOutputFilePath() {
232
239
  }
233
240
 
234
241
  // src/config/errors.ts
235
- var MicroFrontendError = class extends Error {
242
+ var MicrofrontendError = class extends Error {
236
243
  constructor(message, opts) {
237
244
  super(message);
238
- this.name = "MicroFrontendsError";
239
- this.source = (opts == null ? void 0 : opts.source) ?? "@vercel/micro-frontends";
245
+ this.name = "MicrofrontendsError";
246
+ this.source = (opts == null ? void 0 : opts.source) ?? "@vercel/microfrontends";
240
247
  this.type = (opts == null ? void 0 : opts.type) ?? "unknown";
241
248
  this.subtype = opts == null ? void 0 : opts.subtype;
242
- Error.captureStackTrace(this, MicroFrontendError);
249
+ Error.captureStackTrace(this, MicrofrontendError);
243
250
  }
244
251
  isKnown() {
245
252
  return this.type !== "unknown";
@@ -248,13 +255,13 @@ var MicroFrontendError = class extends Error {
248
255
  return !this.isKnown();
249
256
  }
250
257
  /**
251
- * Converts an error to a MicroFrontendsError.
258
+ * Converts an error to a MicrofrontendsError.
252
259
  * @param original - The original error to convert.
253
- * @returns The converted MicroFrontendsError.
260
+ * @returns The converted MicrofrontendsError.
254
261
  */
255
262
  static convert(original, opts) {
256
263
  if (opts == null ? void 0 : opts.fileName) {
257
- const err = MicroFrontendError.convertFSError(original, opts.fileName);
264
+ const err = MicrofrontendError.convertFSError(original, opts.fileName);
258
265
  if (err) {
259
266
  return err;
260
267
  }
@@ -262,25 +269,25 @@ var MicroFrontendError = class extends Error {
262
269
  if (original.message.includes(
263
270
  "Code generation from strings disallowed for this context"
264
271
  )) {
265
- return new MicroFrontendError(original.message, {
272
+ return new MicrofrontendError(original.message, {
266
273
  type: "config",
267
274
  subtype: "unsupported_validation_env",
268
275
  source: "ajv"
269
276
  });
270
277
  }
271
- return new MicroFrontendError(original.message);
278
+ return new MicrofrontendError(original.message);
272
279
  }
273
280
  static convertFSError(original, fileName) {
274
281
  if (original instanceof Error && "code" in original) {
275
282
  if (original.code === "ENOENT") {
276
- return new MicroFrontendError(`Could not find "${fileName}"`, {
283
+ return new MicrofrontendError(`Could not find "${fileName}"`, {
277
284
  type: "config",
278
285
  subtype: "unable_to_read_file",
279
286
  source: "fs"
280
287
  });
281
288
  }
282
289
  if (original.code === "EACCES") {
283
- return new MicroFrontendError(
290
+ return new MicrofrontendError(
284
291
  `Permission denied while accessing "${fileName}"`,
285
292
  {
286
293
  type: "config",
@@ -291,7 +298,7 @@ var MicroFrontendError = class extends Error {
291
298
  }
292
299
  }
293
300
  if (original instanceof SyntaxError) {
294
- return new MicroFrontendError(
301
+ return new MicrofrontendError(
295
302
  `Failed to parse "${fileName}": Invalid JSON format.`,
296
303
  {
297
304
  type: "config",
@@ -303,23 +310,23 @@ var MicroFrontendError = class extends Error {
303
310
  return null;
304
311
  }
305
312
  /**
306
- * Handles an unknown error and returns a MicroFrontendsError instance.
313
+ * Handles an unknown error and returns a MicrofrontendsError instance.
307
314
  * @param err - The error to handle.
308
- * @returns A MicroFrontendsError instance.
315
+ * @returns A MicrofrontendsError instance.
309
316
  */
310
317
  static handle(err, opts) {
311
- if (err instanceof MicroFrontendError) {
318
+ if (err instanceof MicrofrontendError) {
312
319
  return err;
313
320
  }
314
321
  if (err instanceof Error) {
315
- return MicroFrontendError.convert(err, opts);
322
+ return MicrofrontendError.convert(err, opts);
316
323
  }
317
324
  if (typeof err === "object" && err !== null) {
318
325
  if ("message" in err && typeof err.message === "string") {
319
- return MicroFrontendError.convert(new Error(err.message), opts);
326
+ return MicrofrontendError.convert(new Error(err.message), opts);
320
327
  }
321
328
  }
322
- return new MicroFrontendError("An unknown error occurred");
329
+ return new MicrofrontendError("An unknown error occurred");
323
330
  }
324
331
  };
325
332
 
@@ -402,27 +409,27 @@ var _Overrides = class {
402
409
  });
403
410
  return overridesConfig;
404
411
  }
405
- static validOverrideDomainsForZone(microFrontendConfig, zone) {
412
+ static validOverrideDomainsForZone(microfrontendConfig, zone) {
406
413
  var _a, _b, _c, _d, _e;
407
- const projectName = (_a = microFrontendConfig.getZone(zone).vercel) == null ? void 0 : _a.projectName;
414
+ const projectName = (_a = microfrontendConfig.getZone(zone).vercel) == null ? void 0 : _a.projectName;
408
415
  if (!projectName) {
409
- return [microFrontendConfig.getZone(zone).production.host];
416
+ return [microfrontendConfig.getZone(zone).production.host];
410
417
  }
411
418
  const parsedProjectName = makeUrlSafe(projectName);
412
- const previewDeploymentSuffix = (_c = (_b = microFrontendConfig.options) == null ? void 0 : _b.vercel) == null ? void 0 : _c.previewDeploymentSuffix;
413
- const teamSlug = (_e = (_d = microFrontendConfig.options) == null ? void 0 : _d.vercel) == null ? void 0 : _e.teamSlug;
419
+ const previewDeploymentSuffix = (_c = (_b = microfrontendConfig.options) == null ? void 0 : _b.vercel) == null ? void 0 : _c.previewDeploymentSuffix;
420
+ const teamSlug = (_e = (_d = microfrontendConfig.options) == null ? void 0 : _d.vercel) == null ? void 0 : _e.teamSlug;
414
421
  if (!teamSlug && !previewDeploymentSuffix) {
415
- return [microFrontendConfig.getZone(zone).production.host];
422
+ return [microfrontendConfig.getZone(zone).production.host];
416
423
  }
417
424
  const suffix = previewDeploymentSuffix ? `.${previewDeploymentSuffix}` : `-${teamSlug}.vercel.app`;
418
425
  return [
419
426
  `${parsedProjectName}-git-([a-zA-Z0-9-]+)${suffix}`,
420
- microFrontendConfig.getZone(zone).production.host
427
+ microfrontendConfig.getZone(zone).production.host
421
428
  ];
422
429
  }
423
- static validateOverrideDomain(microFrontendConfig, zone, domain) {
430
+ static validateOverrideDomain(microfrontendConfig, zone, domain) {
424
431
  return new RegExp(
425
- `^${_Overrides.validOverrideDomainsForZone(microFrontendConfig, zone).join(
432
+ `^${_Overrides.validOverrideDomainsForZone(microfrontendConfig, zone).join(
426
433
  "|"
427
434
  )}$`
428
435
  ).test(domain);
@@ -504,7 +511,7 @@ var Application = class {
504
511
  static validate(name, app) {
505
512
  var _a, _b, _c, _d, _e;
506
513
  if (((_b = (_a = app.routing) == null ? void 0 : _a.assetPrefix) == null ? void 0 : _b.startsWith("/")) || ((_d = (_c = app.routing) == null ? void 0 : _c.assetPrefix) == null ? void 0 : _d.endsWith("/"))) {
507
- throw new MicroFrontendError(
514
+ throw new MicrofrontendError(
508
515
  `Invalid assetPrefix for application "${name}". Must not start or end with a slash.`,
509
516
  { type: "zone", subtype: "invalid_asset_prefix" }
510
517
  );
@@ -515,13 +522,13 @@ var Application = class {
515
522
  continue;
516
523
  }
517
524
  if (p.endsWith("/")) {
518
- throw new MicroFrontendError(
525
+ throw new MicrofrontendError(
519
526
  `Invalid path for application "${name}". ${p} must not end with a slash.`,
520
527
  { type: "zone", subtype: "invalid_path" }
521
528
  );
522
529
  }
523
530
  if (!p.startsWith("/")) {
524
- throw new MicroFrontendError(
531
+ throw new MicrofrontendError(
525
532
  `Invalid path for application "${name}". ${p} must start with a slash.`,
526
533
  { type: "zone", subtype: "invalid_path" }
527
534
  );
@@ -555,10 +562,10 @@ var Application = class {
555
562
  }
556
563
  };
557
564
 
558
- // src/config/common/micro-frontend-config.ts
565
+ // src/config/common/microfrontend-config.ts
559
566
  var SUPPORTED_VERSIONS = ["1"];
560
567
  var DEFAULT_LOCAL_PROXY_PORT = 3024;
561
- var MicroFrontendConfigCommon = class {
568
+ var MicrofrontendConfigCommon = class {
562
569
  constructor({
563
570
  config,
564
571
  overrides
@@ -566,7 +573,7 @@ var MicroFrontendConfigCommon = class {
566
573
  this.zones = {};
567
574
  var _a, _b, _c;
568
575
  if (!SUPPORTED_VERSIONS.includes(config.version)) {
569
- throw new MicroFrontendError(
576
+ throw new MicrofrontendError(
570
577
  `Unsupported version: ${config.version}. Supported versions are: ${SUPPORTED_VERSIONS.join(
571
578
  ", "
572
579
  )}`,
@@ -594,7 +601,7 @@ var MicroFrontendConfigCommon = class {
594
601
  static getConfigFromEnv() {
595
602
  const config = process.env.MFE_CONFIG;
596
603
  if (!config) {
597
- throw new MicroFrontendError(`Missing "MFE_CONFIG" in environment.`, {
604
+ throw new MicrofrontendError(`Missing "MFE_CONFIG" in environment.`, {
598
605
  type: "config",
599
606
  subtype: "not_found_in_env"
600
607
  });
@@ -613,8 +620,8 @@ var MicroFrontendConfigCommon = class {
613
620
  getZone(name) {
614
621
  const zone = this.zones[name];
615
622
  if (!zone) {
616
- throw new MicroFrontendError(
617
- `Could not find micro-frontends configuration for application "${name}"`,
623
+ throw new MicrofrontendError(
624
+ `Could not find microfrontends configuration for application "${name}"`,
618
625
  {
619
626
  type: "zone",
620
627
  subtype: "not_found"
@@ -634,8 +641,8 @@ var MicroFrontendConfigCommon = class {
634
641
  getDefaultZone() {
635
642
  const zone = Object.values(this.zones).find((z) => z.default);
636
643
  if (!zone) {
637
- throw new MicroFrontendError(
638
- `Could not find default zone in micro-frontends configuration`,
644
+ throw new MicrofrontendError(
645
+ `Could not find default zone in microfrontends configuration`,
639
646
  {
640
647
  type: "zone",
641
648
  subtype: "not_found"
@@ -687,8 +694,8 @@ var MicroFrontendConfigCommon = class {
687
694
  };
688
695
  }
689
696
  write(_) {
690
- throw new MicroFrontendError(
691
- `Writing to file to disk requires using an instance of "MicroFrontendConfig".`,
697
+ throw new MicrofrontendError(
698
+ `Writing to file to disk requires using an instance of "MicrofrontendConfig".`,
692
699
  { type: "config", subtype: "unsupported_operation" }
693
700
  );
694
701
  }
@@ -867,10 +874,6 @@ var schema_default = {
867
874
  flag: {
868
875
  type: "string",
869
876
  description: "flag name that can be used to enable/disable all paths in the group"
870
- },
871
- routeToDefaultApplication: {
872
- type: "boolean",
873
- description: "True to route the request to the default application for this micro-frontends set-up. This must be `true` when using `flag` or when you want to use custom logic to make the routing decision for this group of paths."
874
877
  }
875
878
  }
876
879
  },
@@ -1049,7 +1052,7 @@ var validateSchema = (configString) => {
1049
1052
  const validate = ajv.compile(SCHEMA);
1050
1053
  const isValid = validate(parsedConfig);
1051
1054
  if (!isValid) {
1052
- throw new MicroFrontendError(
1055
+ throw new MicrofrontendError(
1053
1056
  `Invalid config: ${ajv.errorsText(validate.errors)}`,
1054
1057
  { type: "config", subtype: "does_not_match_schema" }
1055
1058
  );
@@ -1059,7 +1062,7 @@ var validateSchema = (configString) => {
1059
1062
  var SUPPORTED_VERSIONS2 = ["1"];
1060
1063
  var validateVersion = (version) => {
1061
1064
  if (!SUPPORTED_VERSIONS2.includes(version)) {
1062
- throw new MicroFrontendError(
1065
+ throw new MicrofrontendError(
1063
1066
  `Unsupported version: ${version}. Supported versions are: ${SUPPORTED_VERSIONS2.join(
1064
1067
  ", "
1065
1068
  )}`,
@@ -1087,12 +1090,12 @@ function validateMainPath(applicationConfigsById) {
1087
1090
  });
1088
1091
  }
1089
1092
  for (const { id: otherId, paths } of pathsWithApp) {
1090
- const isValid = paths.every((path3) => {
1091
- const matcher = (0, import_path_to_regexp.pathToRegexp)(path3);
1093
+ const isValid = paths.every((path4) => {
1094
+ const matcher = (0, import_path_to_regexp.pathToRegexp)(path4);
1092
1095
  return !matcher.test(defaultRoute);
1093
1096
  });
1094
1097
  if (!isValid) {
1095
- throw new MicroFrontendError(
1098
+ throw new MicrofrontendError(
1096
1099
  `default route "${defaultRoute}" cannot be used for "${id}" because it is matched by "${otherId}"`,
1097
1100
  { type: "config", subtype: "invalid_main_path" }
1098
1101
  );
@@ -1100,12 +1103,12 @@ function validateMainPath(applicationConfigsById) {
1100
1103
  }
1101
1104
  } else {
1102
1105
  const allPaths = app.routing.matches.flatMap((match) => match.paths);
1103
- const isValid = allPaths.some((path3) => {
1104
- const matcher = (0, import_path_to_regexp.pathToRegexp)(path3);
1106
+ const isValid = allPaths.some((path4) => {
1107
+ const matcher = (0, import_path_to_regexp.pathToRegexp)(path4);
1105
1108
  return matcher.test(defaultRoute);
1106
1109
  });
1107
1110
  if (!isValid) {
1108
- throw new MicroFrontendError(
1111
+ throw new MicrofrontendError(
1109
1112
  `default route "${defaultRoute}" is not included by the routing config for application "${id}"`,
1110
1113
  { type: "config", subtype: "invalid_main_path" }
1111
1114
  );
@@ -1121,18 +1124,18 @@ var validatePaths = (applicationConfigsById) => {
1121
1124
  continue;
1122
1125
  }
1123
1126
  for (const pathMatch of app.routing.matches) {
1124
- for (const path3 of pathMatch.paths) {
1125
- const maybeError = validatePathExpression(path3);
1127
+ for (const path4 of pathMatch.paths) {
1128
+ const maybeError = validatePathExpression(path4);
1126
1129
  if (maybeError) {
1127
1130
  errors.push(maybeError);
1128
1131
  }
1129
- const existing = pathsByApplicationId.get(path3);
1132
+ const existing = pathsByApplicationId.get(path4);
1130
1133
  if (existing) {
1131
1134
  existing.applications.push(id);
1132
1135
  } else {
1133
- pathsByApplicationId.set(path3, {
1136
+ pathsByApplicationId.set(path4, {
1134
1137
  applications: [id],
1135
- matcher: (0, import_path_to_regexp.pathToRegexp)(path3),
1138
+ matcher: (0, import_path_to_regexp.pathToRegexp)(path4),
1136
1139
  applicationId: id
1137
1140
  });
1138
1141
  }
@@ -1140,10 +1143,10 @@ var validatePaths = (applicationConfigsById) => {
1140
1143
  }
1141
1144
  }
1142
1145
  const entries = Array.from(pathsByApplicationId.entries());
1143
- entries.forEach(([path3, { applications: ids, matcher, applicationId }]) => {
1146
+ entries.forEach(([path4, { applications: ids, matcher, applicationId }]) => {
1144
1147
  if (ids.length > 1) {
1145
1148
  errors.push(
1146
- `Duplicate path "${path3}" for applications "${ids.join(", ")}"`
1149
+ `Duplicate path "${path4}" for applications "${ids.join(", ")}"`
1147
1150
  );
1148
1151
  }
1149
1152
  entries.forEach(
@@ -1151,14 +1154,14 @@ var validatePaths = (applicationConfigsById) => {
1151
1154
  matchPath,
1152
1155
  { applications: matchIds, applicationId: matchApplicationId }
1153
1156
  ]) => {
1154
- if (path3 === matchPath) {
1157
+ if (path4 === matchPath) {
1155
1158
  return;
1156
1159
  }
1157
1160
  if (applicationId === matchApplicationId) {
1158
1161
  return;
1159
1162
  }
1160
1163
  if (matcher.test(matchPath)) {
1161
- const source = `"${path3}" of application${ids.length > 0 ? "s" : ""} ${ids.join(", ")}`;
1164
+ const source = `"${path4}" of application${ids.length > 0 ? "s" : ""} ${ids.join(", ")}`;
1162
1165
  const destination = `"${matchPath}" of application${matchIds.length > 0 ? "s" : ""} ${matchIds.join(", ")}`;
1163
1166
  errors.push(
1164
1167
  `Overlapping path detected between ${source} and ${destination}`
@@ -1168,32 +1171,32 @@ var validatePaths = (applicationConfigsById) => {
1168
1171
  );
1169
1172
  });
1170
1173
  if (errors.length) {
1171
- throw new MicroFrontendError(`Invalid paths: ${errors.join(", ")}`, {
1174
+ throw new MicrofrontendError(`Invalid paths: ${errors.join(", ")}`, {
1172
1175
  type: "config",
1173
1176
  subtype: "conflicting_paths"
1174
1177
  });
1175
1178
  }
1176
1179
  };
1177
1180
  var PATH_DEFAULT_PATTERN = "[^\\/#\\?]+?";
1178
- function validatePathExpression(path3) {
1179
- const tokens = (0, import_path_to_regexp.parse)(path3);
1181
+ function validatePathExpression(path4) {
1182
+ const tokens = (0, import_path_to_regexp.parse)(path4);
1180
1183
  for (let i = 0; i < tokens.length; i++) {
1181
1184
  const token = tokens[i];
1182
1185
  if (token === void 0) {
1183
- return `token ${i} in ${path3} is undefined, this shouldn't happen`;
1186
+ return `token ${i} in ${path4} is undefined, this shouldn't happen`;
1184
1187
  }
1185
1188
  if (typeof token !== "string") {
1186
1189
  if (token.pattern !== PATH_DEFAULT_PATTERN) {
1187
- return `Path ${path3} cannot use a regular expression wildcard`;
1190
+ return `Path ${path4} cannot use a regular expression wildcard`;
1188
1191
  }
1189
1192
  if (token.prefix !== "/") {
1190
- return `Wildcard :${token.name} must be immediately after a / in ${path3}`;
1193
+ return `Wildcard :${token.name} must be immediately after a / in ${path4}`;
1191
1194
  }
1192
1195
  if (token.suffix) {
1193
1196
  return `Wildcard suffix on :${token.name} is not allowed. Suffixes are not supported`;
1194
1197
  }
1195
1198
  if (token.modifier && i !== tokens.length - 1) {
1196
- return `Modifier ${token.modifier} is not allowed on wildcard :${token.name} in ${path3}. Modifiers are only allowed in the last path component`;
1199
+ return `Modifier ${token.modifier} is not allowed on wildcard :${token.name} in ${path4}. Modifiers are only allowed in the last path component`;
1197
1200
  }
1198
1201
  }
1199
1202
  }
@@ -1202,13 +1205,13 @@ function validatePathExpression(path3) {
1202
1205
  var validateDefaults = (applicationConfigsById) => {
1203
1206
  const defaultApplicationIds = Object.entries(applicationConfigsById).reduce((acc, [id, app]) => app.default ? [...acc, id] : acc, []);
1204
1207
  if (defaultApplicationIds.length === 0) {
1205
- throw new MicroFrontendError(
1208
+ throw new MicrofrontendError(
1206
1209
  `No default application found. At least one application must be marked as default.`,
1207
1210
  { type: "config", subtype: "no_default_application" }
1208
1211
  );
1209
1212
  }
1210
1213
  if (defaultApplicationIds.length > 1) {
1211
- throw new MicroFrontendError(
1214
+ throw new MicrofrontendError(
1212
1215
  `Only one default application is allowed. Found ${defaultApplicationIds.join(", ")}.`,
1213
1216
  { type: "config", subtype: "multiple_default_applications" }
1214
1217
  );
@@ -1220,7 +1223,7 @@ var validateOptions = (options) => {
1220
1223
  if (!/^[a-zA-Z]{2,}\.[a-zA-Z]{2,}$/.test(
1221
1224
  options.vercel.previewDeploymentSuffix
1222
1225
  )) {
1223
- throw new MicroFrontendError(
1226
+ throw new MicrofrontendError(
1224
1227
  `Invalid preview deployment suffix: ${options.vercel.previewDeploymentSuffix}. Should have be formatted like "vercel.app".`,
1225
1228
  { type: "config", subtype: "invalid_preview_deployment_suffix" }
1226
1229
  );
@@ -1231,11 +1234,10 @@ var validateOptions = (options) => {
1231
1234
  // src/config/utils/convert.ts
1232
1235
  function convertV1RoutingToV2Routing(routing) {
1233
1236
  return routing.matches.map((group) => {
1234
- var _a, _b;
1237
+ var _a;
1235
1238
  return {
1236
1239
  group: group.group,
1237
1240
  flag: (_a = group.options) == null ? void 0 : _a.flag,
1238
- routeToDefaultApplication: (_b = group.options) == null ? void 0 : _b.routeToDefaultApplication,
1239
1241
  paths: group.paths
1240
1242
  };
1241
1243
  });
@@ -1275,9 +1277,15 @@ function convertV1ConfigToV2Config(config, fromApp) {
1275
1277
  )
1276
1278
  };
1277
1279
  }
1280
+ const defaultApplication = Object.entries(config.applications).find(
1281
+ ([, application]) => application.default
1282
+ );
1283
+ if (!defaultApplication) {
1284
+ throw new Error("No default application found in the config");
1285
+ }
1278
1286
  return {
1279
1287
  ...common,
1280
- partOf: fromApp
1288
+ partOf: defaultApplication[0]
1281
1289
  };
1282
1290
  }
1283
1291
 
@@ -1292,8 +1300,8 @@ function writeFile(outputPath, config, prettify) {
1292
1300
  );
1293
1301
  }
1294
1302
 
1295
- // src/config/micro-frontend-config.ts
1296
- var MicroFrontendConfig = class extends MicroFrontendConfigCommon {
1303
+ // src/config/microfrontend-config.ts
1304
+ var MicrofrontendConfig = class extends MicrofrontendConfigCommon {
1297
1305
  static validate(configString) {
1298
1306
  const config = validateSchema(configString);
1299
1307
  validateVersion(config.version);
@@ -1306,9 +1314,9 @@ var MicroFrontendConfig = class extends MicroFrontendConfigCommon {
1306
1314
  static fromEnv({
1307
1315
  cookies
1308
1316
  }) {
1309
- return new MicroFrontendConfigCommon({
1310
- config: MicroFrontendConfig.validate(
1311
- MicroFrontendConfigCommon.getConfigFromEnv()
1317
+ return new MicrofrontendConfigCommon({
1318
+ config: MicrofrontendConfig.validate(
1319
+ MicrofrontendConfigCommon.getConfigFromEnv()
1312
1320
  ),
1313
1321
  overrides: Overrides.parseOverrides(cookies)
1314
1322
  });
@@ -1318,11 +1326,11 @@ var MicroFrontendConfig = class extends MicroFrontendConfigCommon {
1318
1326
  }) {
1319
1327
  try {
1320
1328
  const config = import_node_fs2.default.readFileSync(filePath, "utf-8");
1321
- return new MicroFrontendConfig({
1322
- config: MicroFrontendConfig.validate(config)
1329
+ return new MicrofrontendConfig({
1330
+ config: MicrofrontendConfig.validate(config)
1323
1331
  });
1324
1332
  } catch (e) {
1325
- throw MicroFrontendError.handle(e, {
1333
+ throw MicrofrontendError.handle(e, {
1326
1334
  fileName: filePath
1327
1335
  });
1328
1336
  }
@@ -1345,158 +1353,1533 @@ var MicroFrontendConfig = class extends MicroFrontendConfigCommon {
1345
1353
  }
1346
1354
  };
1347
1355
 
1348
- // src/bin/local-proxy.ts
1349
- var MFE_DEBUG = process.env.MFE_DEBUG;
1350
- var mfeDebug = (message) => {
1351
- if (MFE_DEBUG === "true" || MFE_DEBUG === "1") {
1352
- console.log(message);
1356
+ // src/config-v2/schema/utils/is-default-app.ts
1357
+ function isDefaultApp(a) {
1358
+ return !("routing" in a);
1359
+ }
1360
+
1361
+ // src/config-v2/errors.ts
1362
+ var MicrofrontendError2 = class extends Error {
1363
+ constructor(message, opts) {
1364
+ super(message);
1365
+ this.name = "MicrofrontendsError";
1366
+ this.source = (opts == null ? void 0 : opts.source) ?? "@vercel/microfrontends";
1367
+ this.type = (opts == null ? void 0 : opts.type) ?? "unknown";
1368
+ this.subtype = opts == null ? void 0 : opts.subtype;
1369
+ Error.captureStackTrace(this, MicrofrontendError2);
1353
1370
  }
1354
- };
1355
- var LocalProxy = class {
1356
- constructor(config, {
1357
- localApps,
1358
- proxyPort
1359
- }) {
1360
- this.config = config;
1361
- this.localApps = localApps;
1362
- this.proxyPort = proxyPort ?? this.config.getLocalProxyPort();
1363
- this.proxy = import_http_proxy.default.createProxyServer({ secure: true });
1364
- this.proxy.on("error", (err, req, res) => {
1365
- if (res instanceof http.ServerResponse) {
1366
- res.writeHead(500, {
1367
- "Content-Type": "text/plain"
1368
- });
1369
- }
1370
- const target = this.getTarget(req);
1371
- res.end(
1372
- `Error proxying request to ${target.application}. Is the server running locally on port ${target.port}?`
1373
- );
1374
- console.error(`Error proxying request for ${target.application}: `, err);
1375
- });
1371
+ isKnown() {
1372
+ return this.type !== "unknown";
1376
1373
  }
1377
- static fromFile(filePath, {
1378
- localApps,
1379
- proxyPort
1380
- }) {
1381
- const config = MicroFrontendConfig.fromFile({ filePath });
1382
- return new LocalProxy(config, { localApps, proxyPort });
1374
+ isUnknown() {
1375
+ return !this.isKnown();
1383
1376
  }
1384
- getDefaultHost(config) {
1385
- const defaultApp = config.getDefaultZone();
1386
- return this.getApplicationTarget(defaultApp);
1377
+ /**
1378
+ * Converts an error to a MicrofrontendsError.
1379
+ * @param original - The original error to convert.
1380
+ * @returns The converted MicrofrontendsError.
1381
+ */
1382
+ static convert(original, opts) {
1383
+ if (opts == null ? void 0 : opts.fileName) {
1384
+ const err = MicrofrontendError2.convertFSError(original, opts.fileName);
1385
+ if (err) {
1386
+ return err;
1387
+ }
1388
+ }
1389
+ if (original.message.includes(
1390
+ "Code generation from strings disallowed for this context"
1391
+ )) {
1392
+ return new MicrofrontendError2(original.message, {
1393
+ type: "config",
1394
+ subtype: "unsupported_validation_env",
1395
+ source: "ajv"
1396
+ });
1397
+ }
1398
+ return new MicrofrontendError2(original.message);
1387
1399
  }
1388
- getApplicationTarget(application) {
1389
- var _a, _b;
1390
- const useDev = this.localApps.includes(application.name);
1391
- let host = useDev ? application.development.local : application.production;
1392
- if ((_b = (_a = application.overrides) == null ? void 0 : _a.environment) == null ? void 0 : _b.host) {
1393
- host = application.overrides.environment;
1400
+ static convertFSError(original, fileName) {
1401
+ if (original instanceof Error && "code" in original) {
1402
+ if (original.code === "ENOENT") {
1403
+ return new MicrofrontendError2(`Could not find "${fileName}"`, {
1404
+ type: "config",
1405
+ subtype: "unable_to_read_file",
1406
+ source: "fs"
1407
+ });
1408
+ }
1409
+ if (original.code === "EACCES") {
1410
+ return new MicrofrontendError2(
1411
+ `Permission denied while accessing "${fileName}"`,
1412
+ {
1413
+ type: "config",
1414
+ subtype: "invalid_permissions",
1415
+ source: "fs"
1416
+ }
1417
+ );
1418
+ }
1394
1419
  }
1395
- const protocol = host.protocol;
1396
- const hostname = host.host;
1397
- const port = host.port;
1398
- return {
1399
- url: host.toUrl(),
1400
- protocol,
1401
- hostname,
1402
- port,
1403
- application: application.name
1404
- };
1420
+ if (original instanceof SyntaxError) {
1421
+ return new MicrofrontendError2(
1422
+ `Failed to parse "${fileName}": Invalid JSON format.`,
1423
+ {
1424
+ type: "config",
1425
+ subtype: "invalid_syntax",
1426
+ source: "fs"
1427
+ }
1428
+ );
1429
+ }
1430
+ return null;
1405
1431
  }
1406
1432
  /**
1407
- * To enable preview deployments in localhost, we need to intercept some auth requests
1408
- * and make sure they proxy to the correct domain. The toolbar will initiate the `vercel-auth-redirect`
1409
- * with a `_host_override` param so that we can properly trigger the redirect flow for the
1410
- * protected host.
1433
+ * Handles an unknown error and returns a MicrofrontendsError instance.
1434
+ * @param err - The error to handle.
1435
+ * @returns A MicrofrontendsError instance.
1411
1436
  */
1412
- getAuthTarget(request2, config) {
1413
- var _a, _b;
1414
- const url = new URL(request2.url ?? "", `http://${request2.headers.host}`);
1415
- const isAuthRedirect = (_a = request2.url) == null ? void 0 : _a.startsWith(
1416
- "/.well-known/vercel-auth-redirect"
1417
- );
1418
- const isSsoRedirect = (_b = request2.url) == null ? void 0 : _b.startsWith("/sso-api");
1419
- const isJWTRedirect = url.searchParams.has("_vercel_jwt");
1420
- const defaultHost = this.getDefaultHost(config);
1421
- let hostname = null;
1422
- let path3 = request2.url;
1423
- if (isAuthRedirect) {
1424
- hostname = url.searchParams.get("_host_override");
1425
- }
1426
- if (isSsoRedirect) {
1427
- hostname = "vercel.com";
1437
+ static handle(err, opts) {
1438
+ if (err instanceof MicrofrontendError2) {
1439
+ return err;
1428
1440
  }
1429
- if (isJWTRedirect) {
1430
- hostname = url.searchParams.get("_host_override");
1431
- url.searchParams.delete("_host_override");
1432
- path3 = `${url.pathname}${url.search}`;
1441
+ if (err instanceof Error) {
1442
+ return MicrofrontendError2.convert(err, opts);
1433
1443
  }
1434
- if (!hostname) {
1435
- return void 0;
1444
+ if (typeof err === "object" && err !== null) {
1445
+ if ("message" in err && typeof err.message === "string") {
1446
+ return MicrofrontendError2.convert(new Error(err.message), opts);
1447
+ }
1436
1448
  }
1437
- return { ...defaultHost, path: path3, hostname, protocol: "https", port: 443 };
1449
+ return new MicrofrontendError2("An unknown error occurred");
1438
1450
  }
1439
- getTarget(request2) {
1440
- const cookies = (0, import_cookie.parse)(request2.headers.cookie || "");
1441
- const cookieOverrides = Overrides.parseOverrides(
1442
- Object.entries(cookies).map(([name, value]) => ({ name, value }))
1451
+ };
1452
+
1453
+ // src/config-v2/microfrontends-config/isomorphic/validation.ts
1454
+ var import_path_to_regexp2 = require("path-to-regexp");
1455
+ var SUPPORTED_VERSIONS3 = ["2"];
1456
+ var validateConfigVersion = (version) => {
1457
+ if (!SUPPORTED_VERSIONS3.includes(version)) {
1458
+ throw new MicrofrontendError2(
1459
+ `Unsupported version: ${version}. Supported versions are: ${SUPPORTED_VERSIONS3.join(
1460
+ ", "
1461
+ )}`,
1462
+ { type: "config", subtype: "unsupported_version" }
1443
1463
  );
1444
- const hasOverrides = Object.keys(cookieOverrides.applications).length > 0;
1445
- const config = hasOverrides ? new MicroFrontendConfig({
1446
- config: this.config.serialize().config,
1447
- overrides: cookieOverrides
1448
- }) : this.config;
1449
- const path3 = request2.url;
1450
- if (!path3) {
1451
- return this.getDefaultHost(config);
1452
- }
1453
- const authTarget = this.getAuthTarget(request2, config);
1454
- if (authTarget) {
1455
- return authTarget;
1464
+ }
1465
+ };
1466
+ var validateConfigPaths = (applicationConfigsById) => {
1467
+ if (!applicationConfigsById) {
1468
+ return;
1469
+ }
1470
+ const pathsByApplicationId = /* @__PURE__ */ new Map();
1471
+ const errors = [];
1472
+ for (const [id, app] of Object.entries(applicationConfigsById)) {
1473
+ if (isDefaultApp(app)) {
1474
+ continue;
1456
1475
  }
1457
- const url = new URL(`http://example.com${path3}`);
1458
- const pathname = url.pathname;
1459
- for (const application of Object.values(config.getAllApplications())) {
1460
- if (application.routing) {
1461
- for (const group of application.routing.matches) {
1462
- for (const childPath of group.paths) {
1463
- const regexp = (0, import_path_to_regexp2.pathToRegexp)(childPath);
1464
- if (regexp.test(pathname)) {
1465
- const target = this.getApplicationTarget(application);
1466
- mfeDebug(
1467
- `routing ${path3} to '${target.application}' at ${target.hostname}`
1468
- );
1469
- return { path: path3, ...target };
1470
- }
1471
- }
1472
- if (application.routing.assetPrefix) {
1473
- const pattern = (0, import_path_to_regexp2.pathToRegexp)(
1474
- `/${application.routing.assetPrefix}/:path+`
1476
+ for (const pathMatch of app.routing) {
1477
+ for (const path4 of pathMatch.paths) {
1478
+ const tokens = (0, import_path_to_regexp2.parse)(path4);
1479
+ for (const token of tokens.slice(0, -1)) {
1480
+ if (typeof token !== "string") {
1481
+ errors.push(
1482
+ `Path ${path4} may only have a :wildcard in the last path component`
1475
1483
  );
1476
- if (pattern.test(pathname)) {
1477
- const target = this.getApplicationTarget(application);
1478
- mfeDebug(
1479
- `routing ${path3} to '${target.application}' at ${target.hostname}`
1480
- );
1481
- return { path: path3, ...target };
1482
- }
1483
1484
  }
1484
1485
  }
1486
+ const existing = pathsByApplicationId.get(path4);
1487
+ if (existing) {
1488
+ existing.applications.push(id);
1489
+ } else {
1490
+ pathsByApplicationId.set(path4, {
1491
+ applications: [id],
1492
+ matcher: (0, import_path_to_regexp2.pathToRegexp)(path4),
1493
+ applicationId: id
1494
+ });
1495
+ }
1485
1496
  }
1486
1497
  }
1487
- const defaultHost = this.getDefaultHost(config);
1488
- mfeDebug(
1489
- `no matching routes, routing ${path3} to default application: ${JSON.stringify(defaultHost)}`
1498
+ }
1499
+ const entries = Array.from(pathsByApplicationId.entries());
1500
+ entries.forEach(([path4, { applications: ids, matcher, applicationId }]) => {
1501
+ if (ids.length > 1) {
1502
+ errors.push(
1503
+ `Duplicate path "${path4}" for applications "${ids.join(", ")}"`
1504
+ );
1505
+ }
1506
+ entries.forEach(
1507
+ ([
1508
+ matchPath,
1509
+ { applications: matchIds, applicationId: matchApplicationId }
1510
+ ]) => {
1511
+ if (path4 === matchPath) {
1512
+ return;
1513
+ }
1514
+ if (applicationId === matchApplicationId) {
1515
+ return;
1516
+ }
1517
+ if (matcher.test(matchPath)) {
1518
+ const source = `"${path4}" of application${ids.length > 0 ? "s" : ""} ${ids.join(", ")}`;
1519
+ const destination = `"${matchPath}" of application${matchIds.length > 0 ? "s" : ""} ${matchIds.join(", ")}`;
1520
+ errors.push(
1521
+ `Overlapping path detected between ${source} and ${destination}`
1522
+ );
1523
+ }
1524
+ }
1525
+ );
1526
+ });
1527
+ if (errors.length) {
1528
+ throw new MicrofrontendError2(`Invalid paths: ${errors.join(", ")}`, {
1529
+ type: "config",
1530
+ subtype: "conflicting_paths"
1531
+ });
1532
+ }
1533
+ };
1534
+ var validateAppPaths = (name, app) => {
1535
+ for (const group of app.routing) {
1536
+ for (const p of group.paths) {
1537
+ if (p === "/") {
1538
+ continue;
1539
+ }
1540
+ if (p.endsWith("/")) {
1541
+ throw new MicrofrontendError2(
1542
+ `Invalid path for application "${name}". ${p} must not end with a slash.`,
1543
+ { type: "application", subtype: "invalid_path" }
1544
+ );
1545
+ }
1546
+ if (!p.startsWith("/")) {
1547
+ throw new MicrofrontendError2(
1548
+ `Invalid path for application "${name}". ${p} must start with a slash.`,
1549
+ { type: "application", subtype: "invalid_path" }
1550
+ );
1551
+ }
1552
+ }
1553
+ }
1554
+ };
1555
+ var validateConfigDefaultApplication = (applicationConfigsById) => {
1556
+ if (!applicationConfigsById) {
1557
+ return;
1558
+ }
1559
+ const applicationsWithRouting = Object.entries(applicationConfigsById).filter(
1560
+ ([, app]) => !isDefaultApp(app)
1561
+ );
1562
+ const applicationsWithRoutingNames = applicationsWithRouting.map(
1563
+ ([key]) => key
1564
+ );
1565
+ const numApplications = Object.keys(applicationConfigsById).length;
1566
+ const numApplicationsWithRouting = applicationsWithRoutingNames.length;
1567
+ const numApplicationsWithoutRouting = numApplications - numApplicationsWithRouting;
1568
+ if (numApplicationsWithoutRouting === 0) {
1569
+ throw new MicrofrontendError2(
1570
+ `No default application found. At least one application needs to be the default by omitting routing.`,
1571
+ { type: "config", subtype: "no_default_application" }
1490
1572
  );
1491
- return { path: path3, ...defaultHost };
1573
+ }
1574
+ if (numApplicationsWithoutRouting > 1) {
1575
+ throw new MicrofrontendError2(
1576
+ `Only one application can omit "routing". Found ${applicationsWithRoutingNames.length - Object.keys(applicationConfigsById).length > 1}.`,
1577
+ { type: "config", subtype: "multiple_default_applications" }
1578
+ );
1579
+ }
1580
+ };
1581
+ var validateConfigOptions = (options) => {
1582
+ var _a;
1583
+ if ((_a = options == null ? void 0 : options.vercel) == null ? void 0 : _a.previewDeploymentSuffix) {
1584
+ if (!/^[a-zA-Z]{2,}\.[a-zA-Z]{2,}$/.test(
1585
+ options.vercel.previewDeploymentSuffix
1586
+ )) {
1587
+ throw new MicrofrontendError2(
1588
+ `Invalid preview deployment suffix: ${options.vercel.previewDeploymentSuffix}. Should have be formatted like "vercel.app".`,
1589
+ { type: "config", subtype: "invalid_preview_deployment_suffix" }
1590
+ );
1591
+ }
1592
+ }
1593
+ };
1594
+
1595
+ // src/config-v2/microfrontends-config/isomorphic/utils/generate-asset-prefix.ts
1596
+ var PREFIX = "vc-ap";
1597
+ function generateAssetPrefixFromName({
1598
+ name
1599
+ }) {
1600
+ if (!name) {
1601
+ throw new Error("Name is required to generate an asset prefix");
1602
+ }
1603
+ return `${PREFIX}-${name}`;
1604
+ }
1605
+
1606
+ // src/config-v2/microfrontends-config/isomorphic/utils/generate-port.ts
1607
+ function generatePortFromName({
1608
+ name,
1609
+ minPort = 3e3,
1610
+ maxPort = 8e3
1611
+ }) {
1612
+ if (!name) {
1613
+ throw new Error("Name is required to generate a port");
1614
+ }
1615
+ let hash = 0;
1616
+ for (let i = 0; i < name.length; i++) {
1617
+ hash = (hash << 5) - hash + name.charCodeAt(i);
1618
+ hash |= 0;
1619
+ }
1620
+ hash = Math.abs(hash);
1621
+ const range = maxPort - minPort;
1622
+ const port = minPort + hash % range;
1623
+ return port;
1624
+ }
1625
+
1626
+ // src/config-v2/microfrontends-config/isomorphic/host.ts
1627
+ var Host2 = class {
1628
+ constructor(hostConfig, options) {
1629
+ const { protocol = "https", host, port } = hostConfig;
1630
+ this.protocol = protocol;
1631
+ this.host = host;
1632
+ this.port = Host2.getPort({ port, protocol: this.protocol });
1633
+ this.local = options == null ? void 0 : options.isLocal;
1634
+ }
1635
+ isLocal() {
1636
+ return this.local || this.host === "localhost" || this.host === "127.0.0.1";
1637
+ }
1638
+ static getPort({
1639
+ protocol,
1640
+ port
1641
+ }) {
1642
+ if (!port) {
1643
+ if (protocol === "http") {
1644
+ return 80;
1645
+ }
1646
+ return 443;
1647
+ }
1648
+ return port;
1649
+ }
1650
+ isDefaultPort() {
1651
+ return this.port === Host2.getPort({ protocol: this.protocol });
1652
+ }
1653
+ toString(opts = {}) {
1654
+ const url = this.toUrl(opts);
1655
+ return url.toString().replace(/\/$/, "");
1656
+ }
1657
+ toUrl(opts = {}) {
1658
+ const { includeDefaultPort } = opts;
1659
+ const url = `${this.protocol}://${this.host}${this.isDefaultPort() && !includeDefaultPort ? "" : `:${this.port}`}`;
1660
+ return new URL(url);
1661
+ }
1662
+ };
1663
+ var LocalHost = class extends Host2 {
1664
+ constructor({
1665
+ appName,
1666
+ ...hostConfig
1667
+ }) {
1668
+ const host = hostConfig.host ?? "localhost";
1669
+ const port = hostConfig.port ?? generatePortFromName({ name: appName });
1670
+ const protocol = hostConfig.protocol ?? "http";
1671
+ super({ protocol, host, port });
1672
+ }
1673
+ };
1674
+
1675
+ // src/config-v2/microfrontends-config/isomorphic/application.ts
1676
+ var Application2 = class {
1677
+ constructor(name, {
1678
+ app,
1679
+ overrides,
1680
+ isDefault
1681
+ }) {
1682
+ var _a, _b;
1683
+ this.name = name;
1684
+ this.development = {
1685
+ local: new LocalHost({
1686
+ appName: name,
1687
+ ...(_a = app.development) == null ? void 0 : _a.local
1688
+ }),
1689
+ fallback: ((_b = app.development) == null ? void 0 : _b.fallback) ? new Host2(app.development.fallback) : void 0
1690
+ };
1691
+ this.production = app.production ? new Host2(app.production) : void 0;
1692
+ this.vercel = app.vercel;
1693
+ this.overrides = (overrides == null ? void 0 : overrides.environment) ? {
1694
+ environment: new Host2(overrides.environment)
1695
+ } : void 0;
1696
+ this.default = isDefault ?? false;
1697
+ this.serialized = app;
1698
+ }
1699
+ isDefault() {
1700
+ return this.default;
1701
+ }
1702
+ getAssetPrefix() {
1703
+ return generateAssetPrefixFromName({ name: this.name });
1704
+ }
1705
+ serialize() {
1706
+ return this.serialized;
1707
+ }
1708
+ };
1709
+ var DefaultApplication = class extends Application2 {
1710
+ constructor(name, {
1711
+ app,
1712
+ overrides
1713
+ }) {
1714
+ super(name, {
1715
+ app,
1716
+ overrides,
1717
+ isDefault: true
1718
+ });
1719
+ this.default = true;
1720
+ this.production = new Host2(app.production);
1721
+ }
1722
+ };
1723
+ var ChildApplication = class extends Application2 {
1724
+ constructor(name, {
1725
+ app,
1726
+ overrides
1727
+ }) {
1728
+ ChildApplication.validate(name, app);
1729
+ super(name, {
1730
+ app,
1731
+ overrides,
1732
+ isDefault: false
1733
+ });
1734
+ this.default = false;
1735
+ this.routing = app.routing;
1736
+ }
1737
+ static validate(name, app) {
1738
+ validateAppPaths(name, app);
1739
+ }
1740
+ };
1741
+
1742
+ // src/config-v2/microfrontends-config/isomorphic/index.ts
1743
+ var import_jsonc_parser2 = require("jsonc-parser");
1744
+
1745
+ // src/config-v2/microfrontends-config/utils/get-config-from-env.ts
1746
+ function getConfigStringFromEnv() {
1747
+ const config = process.env.MFE_CONFIG;
1748
+ if (!config) {
1749
+ throw new MicrofrontendError2(`Missing "MFE_CONFIG" in environment.`, {
1750
+ type: "config",
1751
+ subtype: "not_found_in_env"
1752
+ });
1753
+ }
1754
+ return config;
1755
+ }
1756
+
1757
+ // src/config-v2/schema/utils/is-main-config.ts
1758
+ function isMainConfig(c) {
1759
+ return !("partOf" in c);
1760
+ }
1761
+
1762
+ // src/config-v2/microfrontends-config/client/index.ts
1763
+ var import_path_to_regexp3 = require("path-to-regexp");
1764
+ var MicrofrontendConfigClient = class {
1765
+ constructor(config, opts) {
1766
+ this.pathCache = {};
1767
+ this.serialized = config;
1768
+ if (opts == null ? void 0 : opts.removeFlaggedPaths) {
1769
+ for (const app of Object.values(config.applications)) {
1770
+ if (app.routing) {
1771
+ app.routing = app.routing.filter((match) => !match.flag);
1772
+ }
1773
+ }
1774
+ }
1775
+ this.applications = config.applications;
1776
+ }
1777
+ /**
1778
+ * Create a new `MicrofrontendConfigClient` from a JSON string.
1779
+ * Config must be passed in to remain framework agnostic
1780
+ */
1781
+ static fromEnv(config, opts) {
1782
+ if (!config) {
1783
+ throw new Error("No microfrontends configuration found");
1784
+ }
1785
+ return new MicrofrontendConfigClient(
1786
+ JSON.parse(config),
1787
+ opts
1788
+ );
1789
+ }
1790
+ isEqual(other) {
1791
+ return JSON.stringify(this.applications) === JSON.stringify(other.applications);
1792
+ }
1793
+ getApplicationNameForPath(path4) {
1794
+ if (!path4.startsWith("/")) {
1795
+ throw new Error(`Path must start with a /`);
1796
+ }
1797
+ if (this.pathCache[path4]) {
1798
+ return this.pathCache[path4];
1799
+ }
1800
+ const pathname = new URL(path4, "https://example.com").pathname;
1801
+ for (const [name, application] of Object.entries(this.applications)) {
1802
+ if (application.routing) {
1803
+ for (const group of application.routing) {
1804
+ for (const childPath of group.paths) {
1805
+ const regexp = (0, import_path_to_regexp3.pathToRegexp)(childPath);
1806
+ if (regexp.test(pathname)) {
1807
+ this.pathCache[path4] = name;
1808
+ return name;
1809
+ }
1810
+ }
1811
+ }
1812
+ }
1813
+ }
1814
+ const defaultApplication = Object.entries(this.applications).find(
1815
+ ([, application]) => application.default
1816
+ );
1817
+ if (!defaultApplication) {
1818
+ return null;
1819
+ }
1820
+ this.pathCache[path4] = defaultApplication[0];
1821
+ return defaultApplication[0];
1822
+ }
1823
+ serialize() {
1824
+ return this.serialized;
1825
+ }
1826
+ };
1827
+
1828
+ // src/config-v2/overrides/constants.ts
1829
+ var OVERRIDES_COOKIE_PREFIX2 = "vercel-microfrontends-override";
1830
+ var OVERRIDES_ENV_COOKIE_PREFIX = `${OVERRIDES_COOKIE_PREFIX2}:env:`;
1831
+
1832
+ // src/config-v2/overrides/is-override-cookie.ts
1833
+ function isOverrideCookie(cookie) {
1834
+ var _a;
1835
+ return Boolean((_a = cookie.name) == null ? void 0 : _a.startsWith(OVERRIDES_COOKIE_PREFIX2));
1836
+ }
1837
+
1838
+ // src/config-v2/overrides/get-override-from-cookie.ts
1839
+ function getOverrideFromCookie(cookie) {
1840
+ if (!isOverrideCookie(cookie) || !cookie.value)
1841
+ return;
1842
+ return {
1843
+ application: cookie.name.replace(OVERRIDES_ENV_COOKIE_PREFIX, ""),
1844
+ host: cookie.value
1845
+ };
1846
+ }
1847
+
1848
+ // src/config-v2/overrides/parse-overrides.ts
1849
+ function parseOverrides(cookies) {
1850
+ const overridesConfig = { applications: {} };
1851
+ cookies.forEach((cookie) => {
1852
+ const override = getOverrideFromCookie(cookie);
1853
+ if (!override)
1854
+ return;
1855
+ overridesConfig.applications[override.application] = {
1856
+ environment: { host: override.host }
1857
+ };
1858
+ });
1859
+ return overridesConfig;
1860
+ }
1861
+
1862
+ // src/config-v2/microfrontends-config/isomorphic/constants.ts
1863
+ var DEFAULT_LOCAL_PROXY_PORT2 = 3024;
1864
+
1865
+ // src/config-v2/microfrontends-config/isomorphic/index.ts
1866
+ var MicrofrontendConfigIsomorphic = class {
1867
+ constructor({
1868
+ config,
1869
+ overrides,
1870
+ meta
1871
+ }) {
1872
+ this.childApplications = {};
1873
+ var _a, _b, _c, _d;
1874
+ MicrofrontendConfigIsomorphic.validate(config);
1875
+ const disableOverrides = ((_b = (_a = config.options) == null ? void 0 : _a.vercel) == null ? void 0 : _b.disableOverrides) ?? false;
1876
+ this.overrides = overrides && !disableOverrides ? overrides : void 0;
1877
+ this.isMainConfig = isMainConfig(config);
1878
+ if (isMainConfig(config)) {
1879
+ for (const [appId, appConfig] of Object.entries(config.applications)) {
1880
+ const appOverrides = !disableOverrides ? (_c = this.overrides) == null ? void 0 : _c.applications[appId] : void 0;
1881
+ if (isDefaultApp(appConfig)) {
1882
+ this.defaultApplication = new DefaultApplication(appId, {
1883
+ app: appConfig,
1884
+ overrides: appOverrides
1885
+ });
1886
+ } else {
1887
+ this.childApplications[appId] = new ChildApplication(appId, {
1888
+ app: appConfig,
1889
+ overrides: appOverrides
1890
+ });
1891
+ }
1892
+ }
1893
+ } else {
1894
+ this.partOf = config.partOf;
1895
+ const appOverrides = !disableOverrides ? (_d = this.overrides) == null ? void 0 : _d.applications[meta.fromApp] : void 0;
1896
+ this.childApplications[meta.fromApp] = new ChildApplication(
1897
+ meta.fromApp,
1898
+ {
1899
+ // we don't know routing because we're not in the main config
1900
+ app: { routing: [] },
1901
+ overrides: appOverrides
1902
+ }
1903
+ );
1904
+ }
1905
+ if (isMainConfig(config) && !this.defaultApplication) {
1906
+ throw new MicrofrontendError2(
1907
+ `Could not find default application in microfrontends configuration`,
1908
+ {
1909
+ type: "application",
1910
+ subtype: "not_found"
1911
+ }
1912
+ );
1913
+ }
1914
+ this.config = config;
1915
+ this.options = config.options;
1916
+ this.serialized = {
1917
+ config,
1918
+ overrides,
1919
+ meta
1920
+ };
1921
+ }
1922
+ static validate(config) {
1923
+ const c = typeof config === "string" ? (0, import_jsonc_parser2.parse)(config) : config;
1924
+ if (isMainConfig(c)) {
1925
+ validateConfigVersion(c.version);
1926
+ validateConfigPaths(c.applications);
1927
+ validateConfigDefaultApplication(c.applications);
1928
+ }
1929
+ validateConfigOptions(c.options);
1930
+ return c;
1931
+ }
1932
+ static fromEnv({
1933
+ meta,
1934
+ cookies
1935
+ }) {
1936
+ return new MicrofrontendConfigIsomorphic({
1937
+ config: (0, import_jsonc_parser2.parse)(getConfigStringFromEnv()),
1938
+ overrides: parseOverrides(cookies ?? []),
1939
+ meta
1940
+ });
1941
+ }
1942
+ isOverridesDisabled() {
1943
+ var _a, _b;
1944
+ return ((_b = (_a = this.options) == null ? void 0 : _a.vercel) == null ? void 0 : _b.disableOverrides) ?? false;
1945
+ }
1946
+ getConfig() {
1947
+ return this.config;
1948
+ }
1949
+ getApplicationsByType() {
1950
+ return {
1951
+ defaultApplication: this.defaultApplication,
1952
+ applications: Object.values(this.childApplications)
1953
+ };
1954
+ }
1955
+ getChildApplications() {
1956
+ return Object.values(this.childApplications);
1957
+ }
1958
+ getAllApplications() {
1959
+ return [
1960
+ this.defaultApplication,
1961
+ ...Object.values(this.childApplications)
1962
+ ].filter(Boolean);
1963
+ }
1964
+ getApplication(name) {
1965
+ var _a;
1966
+ if (((_a = this.defaultApplication) == null ? void 0 : _a.name) === name) {
1967
+ return this.defaultApplication;
1968
+ }
1969
+ const app = this.childApplications[name];
1970
+ if (!app) {
1971
+ throw new MicrofrontendError2(
1972
+ `Could not find microfrontends configuration for application "${name}"`,
1973
+ {
1974
+ type: "application",
1975
+ subtype: "not_found"
1976
+ }
1977
+ );
1978
+ }
1979
+ return app;
1980
+ }
1981
+ getApplicationByProjectId(projectId) {
1982
+ var _a, _b;
1983
+ if (((_b = (_a = this.defaultApplication) == null ? void 0 : _a.vercel) == null ? void 0 : _b.projectId) === projectId) {
1984
+ return this.defaultApplication;
1985
+ }
1986
+ return Object.values(this.childApplications).find(
1987
+ (app) => {
1988
+ var _a2;
1989
+ return ((_a2 = app.vercel) == null ? void 0 : _a2.projectId) === projectId;
1990
+ }
1991
+ );
1992
+ }
1993
+ /**
1994
+ * Returns the default application. This can throw if the default application
1995
+ * is undefined ( )
1996
+ */
1997
+ getDefaultApplication() {
1998
+ if (!this.defaultApplication) {
1999
+ throw new MicrofrontendError2(
2000
+ `Could not find default application in microfrontends configuration`,
2001
+ {
2002
+ type: "application",
2003
+ subtype: "not_found"
2004
+ }
2005
+ );
2006
+ }
2007
+ return this.defaultApplication;
2008
+ }
2009
+ /**
2010
+ * Returns the configured port for the local proxy
2011
+ */
2012
+ getLocalProxyPort() {
2013
+ var _a, _b;
2014
+ return ((_b = (_a = this.config.options) == null ? void 0 : _a.localProxy) == null ? void 0 : _b.port) ?? DEFAULT_LOCAL_PROXY_PORT2;
2015
+ }
2016
+ /**
2017
+ * Serializes the class back to the Schema type.
2018
+ *
2019
+ * NOTE: This is used when writing the config to disk and must always match the input Schema
2020
+ */
2021
+ toSchemaJson() {
2022
+ return this.serialized.config;
2023
+ }
2024
+ toClientConfig() {
2025
+ const applications = Object.fromEntries(
2026
+ Object.entries(this.childApplications).map(([name, application]) => [
2027
+ name,
2028
+ {
2029
+ default: false,
2030
+ routing: application.routing
2031
+ }
2032
+ ])
2033
+ );
2034
+ if (this.defaultApplication) {
2035
+ applications[this.defaultApplication.name] = {
2036
+ default: true
2037
+ };
2038
+ }
2039
+ return new MicrofrontendConfigClient({
2040
+ applications
2041
+ });
2042
+ }
2043
+ serialize() {
2044
+ return this.serialized;
2045
+ }
2046
+ };
2047
+
2048
+ // src/config-v2/microfrontends-config/isomorphic/main.ts
2049
+ var MicrofrontendMainConfig = class extends MicrofrontendConfigIsomorphic {
2050
+ constructor({
2051
+ config,
2052
+ overrides,
2053
+ meta
2054
+ }) {
2055
+ var _a, _b, _c;
2056
+ super({ config, overrides, meta });
2057
+ this.isMainConfig = true;
2058
+ this.provider = config.provider;
2059
+ const disableOverrides = ((_b = (_a = config.options) == null ? void 0 : _a.vercel) == null ? void 0 : _b.disableOverrides) ?? false;
2060
+ let defaultApplication;
2061
+ for (const [appId, appConfig] of Object.entries(config.applications)) {
2062
+ const appOverrides = !disableOverrides ? (_c = this.overrides) == null ? void 0 : _c.applications[appId] : void 0;
2063
+ if (isDefaultApp(appConfig)) {
2064
+ defaultApplication = new DefaultApplication(appId, {
2065
+ app: appConfig,
2066
+ overrides: appOverrides
2067
+ });
2068
+ } else {
2069
+ this.childApplications[appId] = new ChildApplication(appId, {
2070
+ app: appConfig,
2071
+ overrides: appOverrides
2072
+ });
2073
+ }
2074
+ }
2075
+ if (!defaultApplication) {
2076
+ throw new MicrofrontendError2(
2077
+ `Could not find default application in microfrontends configuration`,
2078
+ {
2079
+ type: "application",
2080
+ subtype: "not_found"
2081
+ }
2082
+ );
2083
+ }
2084
+ this.defaultApplication = defaultApplication;
2085
+ }
2086
+ };
2087
+
2088
+ // src/config-v2/microfrontends/utils/is-main-config.ts
2089
+ function isMainConfig2(c) {
2090
+ return !("partOf" in c);
2091
+ }
2092
+
2093
+ // src/config-v2/microfrontends/server/index.ts
2094
+ var import_node_fs5 = __toESM(require("fs"), 1);
2095
+ var import_node_path6 = require("path");
2096
+
2097
+ // src/config-v2/microfrontends-config/isomorphic/child.ts
2098
+ var MicrofrontendChildConfig = class extends MicrofrontendConfigIsomorphic {
2099
+ constructor({
2100
+ config,
2101
+ overrides,
2102
+ meta
2103
+ }) {
2104
+ super({ config, overrides, meta });
2105
+ this.isMainConfig = false;
2106
+ this.partOf = config.partOf;
2107
+ }
2108
+ };
2109
+
2110
+ // src/config-v2/microfrontends/isomorphic/index.ts
2111
+ var Microfrontends = class {
2112
+ constructor({
2113
+ config,
2114
+ overrides,
2115
+ meta
2116
+ }) {
2117
+ if (isMainConfig(config)) {
2118
+ this.config = new MicrofrontendMainConfig({ config, overrides, meta });
2119
+ } else {
2120
+ this.config = new MicrofrontendChildConfig({ config, overrides, meta });
2121
+ }
2122
+ }
2123
+ isChildConfig() {
2124
+ return this.config instanceof MicrofrontendChildConfig;
2125
+ }
2126
+ static fromEnv({
2127
+ cookies,
2128
+ meta
2129
+ }) {
2130
+ const config = MicrofrontendConfigIsomorphic.fromEnv({
2131
+ cookies,
2132
+ meta
2133
+ });
2134
+ return new Microfrontends(config.serialize());
2135
+ }
2136
+ };
2137
+
2138
+ // src/config-v2/microfrontends/utils/find-repository-root.ts
2139
+ var import_node_fs3 = __toESM(require("fs"), 1);
2140
+ var import_node_path4 = __toESM(require("path"), 1);
2141
+ var GIT_DIRECTORY = ".git";
2142
+ function findRepositoryRoot(startDir) {
2143
+ let currentDir = startDir || process.cwd();
2144
+ while (currentDir !== import_node_path4.default.parse(currentDir).root) {
2145
+ const gitPath = import_node_path4.default.join(currentDir, GIT_DIRECTORY);
2146
+ if (import_node_fs3.default.existsSync(gitPath) && import_node_fs3.default.statSync(gitPath).isDirectory()) {
2147
+ return currentDir;
2148
+ }
2149
+ currentDir = import_node_path4.default.dirname(currentDir);
2150
+ }
2151
+ throw new Error(
2152
+ "Repository root not found. Specify the root of the repository with the `repository.root` option."
2153
+ );
2154
+ }
2155
+
2156
+ // src/config-v2/microfrontends/utils/find-package-path.ts
2157
+ var import_node_path5 = require("path");
2158
+ var import_node_fs4 = require("fs");
2159
+ var import_fast_glob = __toESM(require("fast-glob"), 1);
2160
+ var configCache = {};
2161
+ function findPackagePathWithGlob({
2162
+ repositoryRoot,
2163
+ name
2164
+ }) {
2165
+ try {
2166
+ const packageJsonPaths = import_fast_glob.default.globSync("**/package.json", {
2167
+ cwd: repositoryRoot,
2168
+ absolute: true,
2169
+ onlyFiles: true,
2170
+ followSymbolicLinks: false,
2171
+ ignore: ["**/node_modules/**", "**/.git/**"]
2172
+ });
2173
+ const matchingPaths = [];
2174
+ for (const packageJsonPath2 of packageJsonPaths) {
2175
+ const packageJsonContent = (0, import_node_fs4.readFileSync)(packageJsonPath2, "utf-8");
2176
+ const packageJson = JSON.parse(packageJsonContent);
2177
+ if (packageJson.name === name) {
2178
+ matchingPaths.push(packageJsonPath2);
2179
+ }
2180
+ }
2181
+ if (matchingPaths.length > 1) {
2182
+ throw new Error(
2183
+ `Found multiple packages with the name "${name}" in the repository: ${matchingPaths.join(", ")}`
2184
+ );
2185
+ }
2186
+ if (matchingPaths.length === 0) {
2187
+ throw new Error(
2188
+ `Could not find package with the name "${name}" in the repository`
2189
+ );
2190
+ }
2191
+ const [packageJsonPath] = matchingPaths;
2192
+ return (0, import_node_path5.dirname)(packageJsonPath);
2193
+ } catch (error) {
2194
+ return null;
2195
+ }
2196
+ }
2197
+ function findPackagePath(opts) {
2198
+ const cacheKey = `${opts.repositoryRoot}-${opts.name}`;
2199
+ if (configCache[cacheKey]) {
2200
+ return configCache[cacheKey];
2201
+ }
2202
+ const result = findPackagePathWithGlob(opts);
2203
+ if (!result) {
2204
+ throw new Error(
2205
+ `Could not find package with the name "${opts.name}" in the repository`
2206
+ );
2207
+ }
2208
+ configCache[cacheKey] = result;
2209
+ return result;
2210
+ }
2211
+
2212
+ // src/config-v2/microfrontends/server/validation.ts
2213
+ var import_jsonc_parser3 = require("jsonc-parser");
2214
+ var import_ajv2 = require("ajv");
2215
+
2216
+ // schema/schema-v2.json
2217
+ var schema_v2_default = {
2218
+ $schema: "http://json-schema.org/draft-07/schema#",
2219
+ $ref: "#/definitions/Config",
2220
+ definitions: {
2221
+ Config: {
2222
+ anyOf: [
2223
+ {
2224
+ $ref: "#/definitions/MainConfig"
2225
+ },
2226
+ {
2227
+ $ref: "#/definitions/ChildConfig"
2228
+ }
2229
+ ]
2230
+ },
2231
+ MainConfig: {
2232
+ type: "object",
2233
+ properties: {
2234
+ $schema: {
2235
+ type: "string"
2236
+ },
2237
+ version: {
2238
+ type: "string",
2239
+ const: "2"
2240
+ },
2241
+ options: {
2242
+ $ref: "#/definitions/Options"
2243
+ },
2244
+ remotes: {
2245
+ type: "object",
2246
+ additionalProperties: {
2247
+ $ref: "#/definitions/Application"
2248
+ },
2249
+ description: "Applications that only serve a subset of the microfrontend routes only need to reference the name of the primary application that owns the full microfrontends configuration."
2250
+ },
2251
+ provider: {
2252
+ $ref: "#/definitions/Provider"
2253
+ },
2254
+ applications: {
2255
+ $ref: "#/definitions/ApplicationRouting",
2256
+ description: "Mapping of application names to the routes that they host. Only needs to be defined in the application that owns the primary microfrontend domain"
2257
+ }
2258
+ },
2259
+ required: ["applications", "provider", "version"]
2260
+ },
2261
+ Options: {
2262
+ type: "object",
2263
+ properties: {
2264
+ vercel: {
2265
+ $ref: "#/definitions/VercelOptions",
2266
+ description: "Micro-Frontends wide options for Vercel."
2267
+ },
2268
+ localProxy: {
2269
+ $ref: "#/definitions/LocalProxyOptions",
2270
+ description: "Options for local proxy."
2271
+ }
2272
+ }
2273
+ },
2274
+ VercelOptions: {
2275
+ type: "object",
2276
+ properties: {
2277
+ previewDeploymentSuffix: {
2278
+ type: "string",
2279
+ description: "If your team uses a custom Preview Deployment Suffix, please specify it here. See https://vercel.com/docs/deployments/preview-deployment-suffix. The default is `vercel.app`."
2280
+ },
2281
+ teamSlug: {
2282
+ type: "string",
2283
+ description: "Team slug for the Vercel team"
2284
+ },
2285
+ disableOverrides: {
2286
+ type: "boolean",
2287
+ description: "If you want to disable the overrides for the site. For example, if you are managing rewrites between applications externally, you may wish to disable the overrides on the toolbar as they will have no effect."
2288
+ }
2289
+ }
2290
+ },
2291
+ LocalProxyOptions: {
2292
+ type: "object",
2293
+ properties: {
2294
+ port: {
2295
+ type: "number",
2296
+ description: "The port number used by the local proxy server.\n\nThe default is `3024`."
2297
+ }
2298
+ }
2299
+ },
2300
+ Application: {
2301
+ anyOf: [
2302
+ {
2303
+ $ref: "#/definitions/DefaultApplication"
2304
+ },
2305
+ {
2306
+ $ref: "#/definitions/ChildApplication"
2307
+ }
2308
+ ]
2309
+ },
2310
+ DefaultApplication: {
2311
+ type: "object",
2312
+ properties: {
2313
+ vercel: {
2314
+ $ref: "#/definitions/Vercel"
2315
+ },
2316
+ development: {
2317
+ $ref: "#/definitions/Development"
2318
+ },
2319
+ production: {
2320
+ $ref: "#/definitions/HostConfig"
2321
+ }
2322
+ },
2323
+ required: ["production"]
2324
+ },
2325
+ Vercel: {
2326
+ type: "object",
2327
+ properties: {
2328
+ projectId: {
2329
+ type: "string",
2330
+ description: "Vercel project ID"
2331
+ },
2332
+ routeSpeedInsightsToDefaultZone: {
2333
+ type: "boolean"
2334
+ }
2335
+ },
2336
+ required: ["projectId"]
2337
+ },
2338
+ Development: {
2339
+ type: "object",
2340
+ properties: {
2341
+ local: {
2342
+ $ref: "#/definitions/LocalHostConfig"
2343
+ },
2344
+ fallback: {
2345
+ $ref: "#/definitions/HostConfig",
2346
+ description: "Fallback for local development, could be a host config that points to any environment. If this is not provided, or the application is not running - requests to the application in local development will error."
2347
+ },
2348
+ task: {
2349
+ type: "string",
2350
+ description: "Optional task to run when starting the development server. Should reference a script in the package.json of the application."
2351
+ }
2352
+ }
2353
+ },
2354
+ LocalHostConfig: {
2355
+ type: "object",
2356
+ properties: {
2357
+ host: {
2358
+ type: "string",
2359
+ description: "The hostname or IP address of the server. This can be a domain name (e.g., `example.com`) or an IP address (e.g., `192.168.1.1`)."
2360
+ },
2361
+ protocol: {
2362
+ type: "string",
2363
+ enum: ["http", "https"],
2364
+ description: 'The protocol to be used for the connection.\n- `http`: Hypertext Transfer Protocol (HTTP).\n- `https`: Secure Hypertext Transfer Protocol (HTTPS).\n\n* @defaultValue "http" for local development, "https" for otherwise'
2365
+ },
2366
+ port: {
2367
+ type: "number",
2368
+ description: "The port number to be used for the connection. Common values include `80` for HTTP and `443` for HTTPS."
2369
+ }
2370
+ }
2371
+ },
2372
+ HostConfig: {
2373
+ type: "object",
2374
+ properties: {
2375
+ protocol: {
2376
+ type: "string",
2377
+ enum: ["http", "https"],
2378
+ description: 'The protocol to be used for the connection.\n- `http`: Hypertext Transfer Protocol (HTTP).\n- `https`: Secure Hypertext Transfer Protocol (HTTPS).\n\n* @defaultValue "http" for local development, "https" for otherwise'
2379
+ },
2380
+ host: {
2381
+ type: "string",
2382
+ description: "The hostname or IP address of the server. This can be a domain name (e.g., `example.com`) or an IP address (e.g., `192.168.1.1`)."
2383
+ },
2384
+ port: {
2385
+ type: "number",
2386
+ description: "The port number to be used for the connection. Common values include `80` for HTTP and `443` for HTTPS."
2387
+ }
2388
+ },
2389
+ required: ["host"]
2390
+ },
2391
+ ChildApplication: {
2392
+ type: "object",
2393
+ properties: {
2394
+ vercel: {
2395
+ $ref: "#/definitions/Vercel"
2396
+ },
2397
+ development: {
2398
+ $ref: "#/definitions/Development"
2399
+ },
2400
+ routing: {
2401
+ $ref: "#/definitions/Routing",
2402
+ description: "Groups of path expressions that are routed to this application."
2403
+ },
2404
+ production: {
2405
+ $ref: "#/definitions/HostConfig"
2406
+ }
2407
+ },
2408
+ required: ["routing"]
2409
+ },
2410
+ Routing: {
2411
+ type: "array",
2412
+ items: {
2413
+ $ref: "#/definitions/PathGroup"
2414
+ }
2415
+ },
2416
+ PathGroup: {
2417
+ type: "object",
2418
+ properties: {
2419
+ group: {
2420
+ type: "string",
2421
+ description: "Optional group name for the paths"
2422
+ },
2423
+ flag: {
2424
+ type: "string",
2425
+ description: "flag name that can be used to enable/disable all paths in the group"
2426
+ },
2427
+ paths: {
2428
+ type: "array",
2429
+ items: {
2430
+ type: "string"
2431
+ }
2432
+ }
2433
+ },
2434
+ required: ["paths"]
2435
+ },
2436
+ Provider: {
2437
+ type: "string",
2438
+ enum: ["vercel", "other"]
2439
+ },
2440
+ ApplicationRouting: {
2441
+ type: "object",
2442
+ additionalProperties: {
2443
+ $ref: "#/definitions/Application"
2444
+ }
2445
+ },
2446
+ ChildConfig: {
2447
+ type: "object",
2448
+ properties: {
2449
+ $schema: {
2450
+ type: "string"
2451
+ },
2452
+ version: {
2453
+ type: "string",
2454
+ const: "2"
2455
+ },
2456
+ options: {
2457
+ $ref: "#/definitions/Options"
2458
+ },
2459
+ remotes: {
2460
+ type: "object",
2461
+ additionalProperties: {
2462
+ $ref: "#/definitions/Application"
2463
+ },
2464
+ description: "Applications that only serve a subset of the microfrontend routes only need to reference the name of the primary application that owns the full microfrontends configuration."
2465
+ },
2466
+ partOf: {
2467
+ type: "string",
2468
+ description: "Applications that only serve a subset of the microfrontend routes only need to reference the name of the primary application that owns the full microfrontends configuration."
2469
+ }
2470
+ },
2471
+ required: ["partOf", "version"]
2472
+ }
2473
+ }
2474
+ };
2475
+
2476
+ // src/config-v2/schema/utils/load.ts
2477
+ var SCHEMA2 = schema_v2_default;
2478
+
2479
+ // src/config-v2/microfrontends/server/validation.ts
2480
+ function validateSchema2(configString) {
2481
+ const parsedConfig = (0, import_jsonc_parser3.parse)(configString);
2482
+ const ajv = new import_ajv2.Ajv();
2483
+ const validate = ajv.compile(SCHEMA2);
2484
+ const isValid = validate(parsedConfig);
2485
+ if (!isValid) {
2486
+ throw new MicrofrontendError(
2487
+ `Invalid config: ${ajv.errorsText(validate.errors)}`,
2488
+ { type: "config", subtype: "does_not_match_schema" }
2489
+ );
2490
+ }
2491
+ return parsedConfig;
2492
+ }
2493
+
2494
+ // src/config-v2/microfrontends/server/index.ts
2495
+ var MicrofrontendsServer = class extends Microfrontends {
2496
+ /**
2497
+ * Writes the configuration to a file.
2498
+ */
2499
+ writeConfig(opts = {
2500
+ pretty: true
2501
+ }) {
2502
+ const outputPath = getOutputFilePath();
2503
+ import_node_fs5.default.mkdirSync((0, import_node_path6.dirname)(outputPath), { recursive: true });
2504
+ import_node_fs5.default.writeFileSync(
2505
+ outputPath,
2506
+ JSON.stringify(
2507
+ this.config.toSchemaJson(),
2508
+ null,
2509
+ opts.pretty ?? true ? 2 : void 0
2510
+ )
2511
+ );
2512
+ }
2513
+ // --------- Static Methods ---------
2514
+ /**
2515
+ * Generates a MicrofrontendsServer instance from an unknown object.
2516
+ */
2517
+ static fromUnknown({
2518
+ config,
2519
+ cookies,
2520
+ meta
2521
+ }) {
2522
+ const overrides = cookies ? parseOverrides(cookies) : void 0;
2523
+ if (typeof config === "string") {
2524
+ return new MicrofrontendsServer({
2525
+ config: MicrofrontendsServer.validate(config),
2526
+ overrides,
2527
+ meta
2528
+ });
2529
+ }
2530
+ if (typeof config === "object") {
2531
+ return new MicrofrontendsServer({
2532
+ config,
2533
+ overrides,
2534
+ meta
2535
+ });
2536
+ }
2537
+ throw new MicrofrontendError2(
2538
+ "Invalid config: must be a string or an object",
2539
+ { type: "config", subtype: "does_not_match_schema" }
2540
+ );
2541
+ }
2542
+ /**
2543
+ * Generates a MicrofrontendsServer instance from the environment.
2544
+ * Uses additional validation that is only available when in a node runtime
2545
+ */
2546
+ static fromEnv({
2547
+ cookies,
2548
+ meta
2549
+ }) {
2550
+ return new MicrofrontendsServer({
2551
+ config: MicrofrontendsServer.validate(getConfigStringFromEnv()),
2552
+ overrides: parseOverrides(cookies),
2553
+ meta
2554
+ });
2555
+ }
2556
+ /**
2557
+ * Validates the configuration against the JSON schema
2558
+ */
2559
+ static validate(config) {
2560
+ if (typeof config === "string") {
2561
+ const c = validateSchema2(config);
2562
+ return c;
2563
+ }
2564
+ return config;
2565
+ }
2566
+ /*
2567
+ * Generates a MicrofrontendsServer instance from a file.
2568
+ */
2569
+ static fromFile({
2570
+ filePath,
2571
+ cookies,
2572
+ meta,
2573
+ options
2574
+ }) {
2575
+ try {
2576
+ const configJson = import_node_fs5.default.readFileSync(filePath, "utf-8");
2577
+ const config = MicrofrontendsServer.validate(configJson);
2578
+ if (!isMainConfig(config) && (options == null ? void 0 : options.resolveMainConfig)) {
2579
+ const repositoryRoot = findRepositoryRoot();
2580
+ const packagePath = findPackagePath({
2581
+ repositoryRoot,
2582
+ name: config.partOf
2583
+ });
2584
+ if (!packagePath) {
2585
+ throw new MicrofrontendError2(
2586
+ `Could not find default application "${config.partOf}" in the repository`,
2587
+ { type: "config", subtype: "not_found" }
2588
+ );
2589
+ }
2590
+ const mainConfigPath = (0, import_node_path6.join)(packagePath, "microfrontends.json");
2591
+ return MicrofrontendsServer.fromMainConfigFile({
2592
+ filePath: mainConfigPath,
2593
+ overrides: cookies ? parseOverrides(cookies) : void 0
2594
+ });
2595
+ }
2596
+ return new MicrofrontendsServer({
2597
+ config,
2598
+ overrides: cookies ? parseOverrides(cookies) : void 0,
2599
+ meta
2600
+ });
2601
+ } catch (e) {
2602
+ throw MicrofrontendError2.handle(e, {
2603
+ fileName: filePath
2604
+ });
2605
+ }
2606
+ }
2607
+ /*
2608
+ * Generates a MicrofrontendMainConfig instance from a file.
2609
+ */
2610
+ static fromMainConfigFile({
2611
+ filePath,
2612
+ overrides
2613
+ }) {
2614
+ try {
2615
+ const config = import_node_fs5.default.readFileSync(filePath, "utf-8");
2616
+ const validatedConfig = MicrofrontendsServer.validate(config);
2617
+ if (!isMainConfig(validatedConfig)) {
2618
+ throw new MicrofrontendError2(
2619
+ `${filePath} is not a main microfrontend config`,
2620
+ {
2621
+ type: "config",
2622
+ subtype: "invalid_main_path"
2623
+ }
2624
+ );
2625
+ }
2626
+ const [defaultApplication] = Object.entries(validatedConfig.applications).filter(([, app]) => isDefaultApp(app)).map(([name]) => name);
2627
+ if (!defaultApplication) {
2628
+ throw new MicrofrontendError2(
2629
+ `No default application found. At least one application needs to be the default by omitting routing.`,
2630
+ { type: "config", subtype: "no_default_application" }
2631
+ );
2632
+ }
2633
+ return new MicrofrontendsServer({
2634
+ config: validatedConfig,
2635
+ overrides,
2636
+ meta: { fromApp: defaultApplication }
2637
+ });
2638
+ } catch (e) {
2639
+ throw MicrofrontendError2.handle(e, {
2640
+ fileName: filePath
2641
+ });
2642
+ }
2643
+ }
2644
+ };
2645
+
2646
+ // src/bin/local-proxy.ts
2647
+ var MFE_DEBUG = process.env.MFE_DEBUG;
2648
+ var mfeDebug = (message) => {
2649
+ if (MFE_DEBUG === "true" || MFE_DEBUG === "1") {
2650
+ console.log(message);
2651
+ }
2652
+ };
2653
+ function isV2Config(c) {
2654
+ return "isMainConfig" in c;
2655
+ }
2656
+ var LocalProxy = class {
2657
+ constructor(config, {
2658
+ localApps,
2659
+ proxyPort
2660
+ }) {
2661
+ this.config = config;
2662
+ this.localApps = localApps;
2663
+ this.proxyPort = proxyPort ?? this.config.getLocalProxyPort();
2664
+ this.proxy = import_http_proxy.default.createProxyServer({ secure: true });
2665
+ this.proxy.on("error", (err, req, res) => {
2666
+ if (res instanceof http.ServerResponse) {
2667
+ res.writeHead(500, {
2668
+ "Content-Type": "text/plain"
2669
+ });
2670
+ }
2671
+ const target = this.getTarget(req);
2672
+ res.end(
2673
+ `Error proxying request to ${target.application}. Is the server running locally on port ${target.port}?`
2674
+ );
2675
+ console.error(`Error proxying request for ${target.application}: `, err);
2676
+ });
2677
+ }
2678
+ static fromFile(filePath, {
2679
+ localApps,
2680
+ proxyPort
2681
+ }) {
2682
+ let configV2;
2683
+ try {
2684
+ configV2 = MicrofrontendsServer.fromMainConfigFile({
2685
+ filePath
2686
+ });
2687
+ } catch (error) {
2688
+ if ((0, import_types2.isNativeError)(error)) {
2689
+ mfeDebug(`unable to parse v2 version: ${error.toString()}`);
2690
+ }
2691
+ }
2692
+ if (configV2) {
2693
+ if (isMainConfig2(configV2.config)) {
2694
+ return new LocalProxy(configV2.config, { localApps, proxyPort });
2695
+ }
2696
+ throw new Error("Got child config after parsing main config");
2697
+ }
2698
+ const configV1 = MicrofrontendConfig.fromFile({ filePath });
2699
+ return new LocalProxy(configV1, { localApps, proxyPort });
2700
+ }
2701
+ getDefaultHost(config) {
2702
+ let defaultApp;
2703
+ if (isV2Config(config)) {
2704
+ defaultApp = config.getDefaultApplication();
2705
+ } else {
2706
+ defaultApp = config.getDefaultZone();
2707
+ }
2708
+ return this.getApplicationTarget(defaultApp);
2709
+ }
2710
+ getApplicationTarget(application) {
2711
+ var _a, _b;
2712
+ const useDev = this.localApps.includes(application.name);
2713
+ let host = useDev ? application.development.local : application.production;
2714
+ if (!host) {
2715
+ throw new Error(
2716
+ `${application.name} does not have a production host configured`
2717
+ );
2718
+ }
2719
+ if ((_b = (_a = application.overrides) == null ? void 0 : _a.environment) == null ? void 0 : _b.host) {
2720
+ host = application.overrides.environment;
2721
+ }
2722
+ const protocol = host.protocol;
2723
+ const hostname = host.host;
2724
+ const port = host.port;
2725
+ return {
2726
+ url: host.toUrl(),
2727
+ protocol,
2728
+ hostname,
2729
+ port,
2730
+ application: application.name
2731
+ };
2732
+ }
2733
+ /**
2734
+ * To enable preview deployments in localhost, we need to intercept some auth requests
2735
+ * and make sure they proxy to the correct domain. The toolbar will initiate the `vercel-auth-redirect`
2736
+ * with a `_host_override` param so that we can properly trigger the redirect flow for the
2737
+ * protected host.
2738
+ */
2739
+ getAuthTarget(request2, config) {
2740
+ var _a, _b;
2741
+ const url = new URL(request2.url ?? "", `http://${request2.headers.host}`);
2742
+ const isAuthRedirect = (_a = request2.url) == null ? void 0 : _a.startsWith(
2743
+ "/.well-known/vercel-auth-redirect"
2744
+ );
2745
+ const isSsoRedirect = (_b = request2.url) == null ? void 0 : _b.startsWith("/sso-api");
2746
+ const isJWTRedirect = url.searchParams.has("_vercel_jwt");
2747
+ const defaultHost = this.getDefaultHost(config);
2748
+ let hostname = null;
2749
+ let path4 = request2.url;
2750
+ if (isAuthRedirect) {
2751
+ hostname = url.searchParams.get("_host_override");
2752
+ }
2753
+ if (isSsoRedirect) {
2754
+ hostname = "vercel.com";
2755
+ }
2756
+ if (isJWTRedirect) {
2757
+ hostname = url.searchParams.get("_host_override");
2758
+ url.searchParams.delete("_host_override");
2759
+ path4 = `${url.pathname}${url.search}`;
2760
+ }
2761
+ if (!hostname) {
2762
+ return void 0;
2763
+ }
2764
+ return { ...defaultHost, path: path4, hostname, protocol: "https", port: 443 };
2765
+ }
2766
+ getConfigWithOverrides(cookies) {
2767
+ if (isV2Config(this.config)) {
2768
+ const cookieOverrides2 = parseOverrides(
2769
+ Object.entries(cookies).map(([name, value]) => ({ name, value }))
2770
+ );
2771
+ const hasOverrides2 = Object.keys(cookieOverrides2.applications).length > 0;
2772
+ const fromApp = this.config.getDefaultApplication().name;
2773
+ const serialized = this.config.serialize().config;
2774
+ if (!isMainConfig(serialized)) {
2775
+ throw new Error("unreachable");
2776
+ }
2777
+ return hasOverrides2 ? new MicrofrontendMainConfig({
2778
+ config: serialized,
2779
+ meta: { fromApp },
2780
+ overrides: cookieOverrides2
2781
+ }) : this.config;
2782
+ }
2783
+ const cookieOverrides = Overrides.parseOverrides(
2784
+ Object.entries(cookies).map(([name, value]) => ({ name, value }))
2785
+ );
2786
+ const hasOverrides = Object.keys(cookieOverrides.applications).length > 0;
2787
+ return hasOverrides ? new MicrofrontendConfig({
2788
+ config: this.config.serialize().config,
2789
+ overrides: cookieOverrides
2790
+ }) : this.config;
2791
+ }
2792
+ getTarget(request2) {
2793
+ const cookies = (0, import_cookie.parse)(request2.headers.cookie || "");
2794
+ const config = this.getConfigWithOverrides(cookies);
2795
+ const path4 = request2.url;
2796
+ if (!path4) {
2797
+ return this.getDefaultHost(config);
2798
+ }
2799
+ const authTarget = this.getAuthTarget(request2, config);
2800
+ if (authTarget) {
2801
+ return authTarget;
2802
+ }
2803
+ const url = new URL(`http://example.com${path4}`);
2804
+ const pathname = url.pathname;
2805
+ if (isV2Config(config)) {
2806
+ const target = this.findMatchingApplicationV2(
2807
+ path4,
2808
+ pathname,
2809
+ config.getChildApplications()
2810
+ );
2811
+ if (target)
2812
+ return target;
2813
+ } else {
2814
+ const target = this.findMatchingApplicationV1(
2815
+ path4,
2816
+ pathname,
2817
+ config.getAllApplications()
2818
+ );
2819
+ if (target)
2820
+ return target;
2821
+ }
2822
+ const defaultHost = this.getDefaultHost(config);
2823
+ mfeDebug(
2824
+ `no matching routes, routing ${path4} to default application: ${JSON.stringify(defaultHost)}`
2825
+ );
2826
+ return { path: path4, ...defaultHost };
2827
+ }
2828
+ findMatchingApplicationV1(path4, pathname, applications) {
2829
+ for (const application of Object.values(applications)) {
2830
+ if (application.routing) {
2831
+ for (const group of application.routing.matches) {
2832
+ for (const childPath of group.paths) {
2833
+ const regexp = (0, import_path_to_regexp4.pathToRegexp)(childPath);
2834
+ if (regexp.test(pathname)) {
2835
+ const target = this.getApplicationTarget(application);
2836
+ mfeDebug(
2837
+ `routing ${path4} to '${target.application}' at ${target.hostname}`
2838
+ );
2839
+ return { path: path4, ...target };
2840
+ }
2841
+ }
2842
+ if (application.routing.assetPrefix) {
2843
+ const pattern = (0, import_path_to_regexp4.pathToRegexp)(
2844
+ `/${application.routing.assetPrefix}/:path+`
2845
+ );
2846
+ if (pattern.test(pathname)) {
2847
+ const target = this.getApplicationTarget(application);
2848
+ mfeDebug(
2849
+ `routing ${path4} to '${target.application}' at ${target.hostname}`
2850
+ );
2851
+ return { path: path4, ...target };
2852
+ }
2853
+ }
2854
+ }
2855
+ }
2856
+ }
2857
+ return null;
2858
+ }
2859
+ findMatchingApplicationV2(path4, pathname, applications) {
2860
+ for (const application of Object.values(applications)) {
2861
+ for (const group of application.routing) {
2862
+ for (const childPath of group.paths) {
2863
+ const regexp = (0, import_path_to_regexp4.pathToRegexp)(childPath);
2864
+ if (regexp.test(pathname)) {
2865
+ const target = this.getApplicationTarget(application);
2866
+ mfeDebug(
2867
+ `routing ${path4} to '${target.application}' at ${target.hostname}`
2868
+ );
2869
+ return { path: path4, ...target };
2870
+ }
2871
+ }
2872
+ }
2873
+ }
2874
+ return null;
1492
2875
  }
1493
2876
  // Handles requests that return data from the local proxy itself.
1494
2877
  // Returns true if the request was handled, false otherwise.
1495
- handleProxyInfoRequest(path3, res) {
1496
- if (!path3) {
2878
+ handleProxyInfoRequest(path4, res) {
2879
+ if (!path4) {
1497
2880
  return false;
1498
2881
  }
1499
- const url = new URL(`http://example.comf${path3}`);
2882
+ const url = new URL(`http://example.comf${path4}`);
1500
2883
  const pathname = url.pathname;
1501
2884
  switch (pathname) {
1502
2885
  case "/.well-known/vercel/microfrontend-routing": {
@@ -1524,10 +2907,10 @@ var LocalProxy = class {
1524
2907
  }
1525
2908
  const target = this.getTarget(req);
1526
2909
  if (target.protocol === "https") {
1527
- const { hostname, port, path: path3 } = target;
2910
+ const { hostname, port, path: path4 } = target;
1528
2911
  const requestOptions = {
1529
2912
  hostname,
1530
- path: path3,
2913
+ path: path4,
1531
2914
  method: req.method,
1532
2915
  headers: {
1533
2916
  ...req.headers,
@@ -1555,7 +2938,7 @@ var LocalProxy = class {
1555
2938
  console.error("Proxy request error: ", err);
1556
2939
  res.writeHead(500, { "Content-Type": "text/plain" });
1557
2940
  res.end(
1558
- `Error proxying request for ${target.application} to ${hostname}:${port}${path3}`
2941
+ `Error proxying request for ${target.application} to ${hostname}:${port}${path4}`
1559
2942
  );
1560
2943
  });
1561
2944
  } else {