@vercel/microfrontends 1.0.1-canary.3 → 1.0.1-canary.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/dist/bin/cli.cjs +113 -79
  2. package/dist/config.cjs +3 -0
  3. package/dist/config.cjs.map +1 -1
  4. package/dist/config.js +3 -0
  5. package/dist/config.js.map +1 -1
  6. package/dist/experimental/sveltekit.cjs +79 -72
  7. package/dist/experimental/sveltekit.cjs.map +1 -1
  8. package/dist/experimental/sveltekit.js +79 -72
  9. package/dist/experimental/sveltekit.js.map +1 -1
  10. package/dist/experimental/vite.cjs +82 -75
  11. package/dist/experimental/vite.cjs.map +1 -1
  12. package/dist/experimental/vite.js +82 -75
  13. package/dist/experimental/vite.js.map +1 -1
  14. package/dist/microfrontends/server.cjs +79 -45
  15. package/dist/microfrontends/server.cjs.map +1 -1
  16. package/dist/microfrontends/server.js +79 -45
  17. package/dist/microfrontends/server.js.map +1 -1
  18. package/dist/microfrontends.cjs +3 -0
  19. package/dist/microfrontends.cjs.map +1 -1
  20. package/dist/microfrontends.js +3 -0
  21. package/dist/microfrontends.js.map +1 -1
  22. package/dist/next/config.cjs +79 -72
  23. package/dist/next/config.cjs.map +1 -1
  24. package/dist/next/config.js +79 -72
  25. package/dist/next/config.js.map +1 -1
  26. package/dist/next/middleware.cjs +3 -0
  27. package/dist/next/middleware.cjs.map +1 -1
  28. package/dist/next/middleware.js +3 -0
  29. package/dist/next/middleware.js.map +1 -1
  30. package/dist/next/testing.cjs +3 -0
  31. package/dist/next/testing.cjs.map +1 -1
  32. package/dist/next/testing.js +3 -0
  33. package/dist/next/testing.js.map +1 -1
  34. package/dist/utils/mfe-port.cjs +83 -49
  35. package/dist/utils/mfe-port.cjs.map +1 -1
  36. package/dist/utils/mfe-port.js +83 -49
  37. package/dist/utils/mfe-port.js.map +1 -1
  38. package/package.json +2 -2
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: "1.0.1-canary.3",
32
+ version: "1.0.1-canary.4",
33
33
  private: false,
34
34
  description: "Defines configuration and utilities for microfrontends development",
35
35
  keywords: [
@@ -189,7 +189,7 @@ var package_default = {
189
189
  "fast-glob": "^3.3.2",
190
190
  "http-proxy": "^1.18.1",
191
191
  "jsonc-parser": "^3.3.1",
192
- nanoid: "^5.1.2",
192
+ nanoid: "^3.3.9",
193
193
  "path-to-regexp": "6.2.1"
194
194
  },
195
195
  devDependencies: {
@@ -372,18 +372,18 @@ var validateConfigPaths = (applicationConfigsById) => {
372
372
  }
373
373
  const childApp = app;
374
374
  for (const pathMatch of childApp.routing) {
375
- for (const path6 of pathMatch.paths) {
376
- const maybeError = validatePathExpression(path6);
375
+ for (const path7 of pathMatch.paths) {
376
+ const maybeError = validatePathExpression(path7);
377
377
  if (maybeError) {
378
378
  errors.push(maybeError);
379
379
  } else {
380
- const existing = pathsByApplicationId.get(path6);
380
+ const existing = pathsByApplicationId.get(path7);
381
381
  if (existing) {
382
382
  existing.applications.push(id);
383
383
  } else {
384
- pathsByApplicationId.set(path6, {
384
+ pathsByApplicationId.set(path7, {
385
385
  applications: [id],
386
- matcher: (0, import_path_to_regexp.pathToRegexp)(path6),
386
+ matcher: (0, import_path_to_regexp.pathToRegexp)(path7),
387
387
  applicationId: id
388
388
  });
389
389
  }
@@ -392,24 +392,24 @@ var validateConfigPaths = (applicationConfigsById) => {
392
392
  }
393
393
  }
394
394
  const entries = Array.from(pathsByApplicationId.entries());
395
- for (const [path6, { applications: ids, matcher, applicationId }] of entries) {
395
+ for (const [path7, { applications: ids, matcher, applicationId }] of entries) {
396
396
  if (ids.length > 1) {
397
397
  errors.push(
398
- `Duplicate path "${path6}" for applications "${ids.join(", ")}"`
398
+ `Duplicate path "${path7}" for applications "${ids.join(", ")}"`
399
399
  );
400
400
  }
401
401
  for (const [
402
402
  matchPath,
403
403
  { applications: matchIds, applicationId: matchApplicationId }
404
404
  ] of entries) {
405
- if (path6 === matchPath) {
405
+ if (path7 === matchPath) {
406
406
  continue;
407
407
  }
408
408
  if (applicationId === matchApplicationId) {
409
409
  continue;
410
410
  }
411
411
  if (matcher.test(matchPath)) {
412
- const source = `"${path6}" of application${ids.length > 0 ? "s" : ""} ${ids.join(", ")}`;
412
+ const source = `"${path7}" of application${ids.length > 0 ? "s" : ""} ${ids.join(", ")}`;
413
413
  const destination = `"${matchPath}" of application${matchIds.length > 0 ? "s" : ""} ${matchIds.join(", ")}`;
414
414
  errors.push(
415
415
  `Overlapping path detected between ${source} and ${destination}`
@@ -425,39 +425,42 @@ var validateConfigPaths = (applicationConfigsById) => {
425
425
  }
426
426
  };
427
427
  var PATH_DEFAULT_PATTERN = "[^\\/#\\?]+?";
428
- function validatePathExpression(path6) {
428
+ function validatePathExpression(path7) {
429
429
  try {
430
- const tokens = (0, import_path_to_regexp.parse)(path6);
431
- if (/(?<!\\)\{/.test(path6)) {
432
- return `Optional paths are not supported: ${path6}`;
430
+ const tokens = (0, import_path_to_regexp.parse)(path7);
431
+ if (/(?<!\\)\{/.test(path7)) {
432
+ return `Optional paths are not supported: ${path7}`;
433
433
  }
434
- if (/(?<!\\|\()\?/.test(path6)) {
435
- return `Optional paths are not supported: ${path6}`;
434
+ if (/(?<!\\|\()\?/.test(path7)) {
435
+ return `Optional paths are not supported: ${path7}`;
436
436
  }
437
- if (/\/[^/]*(?<!\\):[^/]*(?<!\\):[^/]*/.test(path6)) {
438
- return `Only one wildcard is allowed per path segment: ${path6}`;
437
+ if (/\/[^/]*(?<!\\):[^/]*(?<!\\):[^/]*/.test(path7)) {
438
+ return `Only one wildcard is allowed per path segment: ${path7}`;
439
439
  }
440
440
  for (let i = 0; i < tokens.length; i++) {
441
441
  const token = tokens[i];
442
442
  if (token === void 0) {
443
- return `token ${i} in ${path6} is undefined, this shouldn't happen`;
443
+ return `token ${i} in ${path7} is undefined, this shouldn't happen`;
444
444
  }
445
445
  if (typeof token !== "string") {
446
+ if (!token.name) {
447
+ return `Only named wildcards are allowed: ${path7} (hint: add ":path" to the wildcard)`;
448
+ }
446
449
  if (token.pattern !== PATH_DEFAULT_PATTERN && // Allows (a|b|c) and ((?!a|b|c).*) regex
447
450
  // Only limited regex is supported for now, due to performance considerations
448
451
  !/^(?<allowed>[\w]+(?:\|[^|()]+)+)$|^\(\?!(?<disallowed>[\w]+(?:\|[^|()]+)+)\)\.\*$/.test(
449
452
  token.pattern
450
453
  )) {
451
- return `Path ${path6} cannot use unsupported regular expression wildcard`;
454
+ return `Path ${path7} cannot use unsupported regular expression wildcard`;
452
455
  }
453
456
  if (token.modifier && i !== tokens.length - 1) {
454
- return `Modifier ${token.modifier} is not allowed on wildcard :${token.name} in ${path6}. Modifiers are only allowed in the last path component`;
457
+ return `Modifier ${token.modifier} is not allowed on wildcard :${token.name} in ${path7}. Modifiers are only allowed in the last path component`;
455
458
  }
456
459
  }
457
460
  }
458
461
  } catch (e) {
459
462
  const message = e instanceof Error ? e.message : String(e);
460
- return `Path ${path6} could not be parsed into regexp: ${message}`;
463
+ return `Path ${path7} could not be parsed into regexp: ${message}`;
461
464
  }
462
465
  return void 0;
463
466
  }
@@ -798,21 +801,21 @@ var MicrofrontendConfigClient = class {
798
801
  isEqual(other) {
799
802
  return JSON.stringify(this.applications) === JSON.stringify(other.applications);
800
803
  }
801
- getApplicationNameForPath(path6) {
802
- if (!path6.startsWith("/")) {
804
+ getApplicationNameForPath(path7) {
805
+ if (!path7.startsWith("/")) {
803
806
  throw new Error(`Path must start with a /`);
804
807
  }
805
- if (this.pathCache[path6]) {
806
- return this.pathCache[path6];
808
+ if (this.pathCache[path7]) {
809
+ return this.pathCache[path7];
807
810
  }
808
- const pathname = new URL(path6, "https://example.com").pathname;
811
+ const pathname = new URL(path7, "https://example.com").pathname;
809
812
  for (const [name, application] of Object.entries(this.applications)) {
810
813
  if (application.routing) {
811
814
  for (const group of application.routing) {
812
815
  for (const childPath of group.paths) {
813
816
  const regexp = (0, import_path_to_regexp2.pathToRegexp)(childPath);
814
817
  if (regexp.test(pathname)) {
815
- this.pathCache[path6] = name;
818
+ this.pathCache[path7] = name;
816
819
  return name;
817
820
  }
818
821
  }
@@ -825,7 +828,7 @@ var MicrofrontendConfigClient = class {
825
828
  if (!defaultApplication) {
826
829
  return null;
827
830
  }
828
- this.pathCache[path6] = defaultApplication[0];
831
+ this.pathCache[path7] = defaultApplication[0];
829
832
  return defaultApplication[0];
830
833
  }
831
834
  serialize() {
@@ -1091,8 +1094,8 @@ function isMainConfig2(c) {
1091
1094
  }
1092
1095
 
1093
1096
  // src/config/microfrontends/server/index.ts
1094
- var import_node_fs7 = __toESM(require("fs"), 1);
1095
- var import_node_path8 = require("path");
1097
+ var import_node_fs8 = __toESM(require("fs"), 1);
1098
+ var import_node_path9 = require("path");
1096
1099
 
1097
1100
  // src/config/microfrontends-config/isomorphic/child.ts
1098
1101
  var MicrofrontendChildConfig = class extends MicrofrontendConfigIsomorphic {
@@ -1297,6 +1300,9 @@ function isMonorepo({
1297
1300
  if (import_node_fs4.default.existsSync(import_node_path4.default.join(repositoryRoot, "vlt-workspaces.json"))) {
1298
1301
  return true;
1299
1302
  }
1303
+ if (process.env.NX_WORKSPACE_ROOT === import_node_path4.default.resolve(repositoryRoot)) {
1304
+ return true;
1305
+ }
1300
1306
  const packageJsonPath = import_node_path4.default.join(repositoryRoot, "package.json");
1301
1307
  if (!import_node_fs4.default.existsSync(packageJsonPath)) {
1302
1308
  return false;
@@ -1342,8 +1348,42 @@ function findConfig({ dir }) {
1342
1348
  return null;
1343
1349
  }
1344
1350
 
1345
- // src/config/microfrontends/server/utils/get-output-file-path.ts
1351
+ // src/config/microfrontends/utils/get-application-context.ts
1352
+ var import_node_fs7 = __toESM(require("fs"), 1);
1346
1353
  var import_node_path7 = __toESM(require("path"), 1);
1354
+ function getApplicationContext(opts) {
1355
+ if (opts?.appName) {
1356
+ return { name: opts.appName };
1357
+ }
1358
+ if (process.env.NX_TASK_TARGET_PROJECT) {
1359
+ return { name: process.env.NX_TASK_TARGET_PROJECT };
1360
+ }
1361
+ try {
1362
+ const packageJsonString = import_node_fs7.default.readFileSync(
1363
+ import_node_path7.default.join(opts?.packageRoot || ".", "package.json"),
1364
+ "utf-8"
1365
+ );
1366
+ const packageJson = JSON.parse(packageJsonString);
1367
+ if (!packageJson.name) {
1368
+ throw new MicrofrontendError(
1369
+ `package.json file missing required field "name"`,
1370
+ {
1371
+ type: "packageJson",
1372
+ subtype: "missing_field_name",
1373
+ source: "@vercel/microfrontends/next"
1374
+ }
1375
+ );
1376
+ }
1377
+ return { name: packageJson.name };
1378
+ } catch (err) {
1379
+ throw MicrofrontendError.handle(err, {
1380
+ fileName: "package.json"
1381
+ });
1382
+ }
1383
+ }
1384
+
1385
+ // src/config/microfrontends/server/utils/get-output-file-path.ts
1386
+ var import_node_path8 = __toESM(require("path"), 1);
1347
1387
 
1348
1388
  // src/config/microfrontends/server/constants.ts
1349
1389
  var MFE_CONFIG_DEFAULT_FILE_PATH = "microfrontends";
@@ -1351,7 +1391,7 @@ var MFE_CONFIG_DEFAULT_FILE_NAME = "microfrontends.json";
1351
1391
 
1352
1392
  // src/config/microfrontends/server/utils/get-output-file-path.ts
1353
1393
  function getOutputFilePath() {
1354
- return import_node_path7.default.join(MFE_CONFIG_DEFAULT_FILE_PATH, MFE_CONFIG_DEFAULT_FILE_NAME);
1394
+ return import_node_path8.default.join(MFE_CONFIG_DEFAULT_FILE_PATH, MFE_CONFIG_DEFAULT_FILE_NAME);
1355
1395
  }
1356
1396
 
1357
1397
  // src/config/microfrontends/server/validation.ts
@@ -1690,8 +1730,8 @@ var MicrofrontendsServer = class extends Microfrontends {
1690
1730
  pretty: true
1691
1731
  }) {
1692
1732
  const outputPath = getOutputFilePath();
1693
- import_node_fs7.default.mkdirSync((0, import_node_path8.dirname)(outputPath), { recursive: true });
1694
- import_node_fs7.default.writeFileSync(
1733
+ import_node_fs8.default.mkdirSync((0, import_node_path9.dirname)(outputPath), { recursive: true });
1734
+ import_node_fs8.default.writeFileSync(
1695
1735
  outputPath,
1696
1736
  JSON.stringify(
1697
1737
  this.config.toSchemaJson(),
@@ -1777,14 +1817,8 @@ var MicrofrontendsServer = class extends Microfrontends {
1777
1817
  }
1778
1818
  try {
1779
1819
  const packageRoot = findPackageRoot(directory);
1780
- const packageJsonPath = (0, import_node_path8.join)(packageRoot, "package.json");
1781
- const packageJson = JSON.parse(
1782
- import_node_fs7.default.readFileSync(packageJsonPath, "utf-8")
1783
- );
1784
- if (!packageJson.name) {
1785
- throw new Error(`No name found in package.json at ${packageJsonPath}`);
1786
- }
1787
- const configMeta = meta ?? { fromApp: packageJson.name };
1820
+ const { name: appName } = getApplicationContext({ packageRoot });
1821
+ const configMeta = meta ?? { fromApp: appName };
1788
1822
  const maybeConfig = findConfig({ dir: packageRoot });
1789
1823
  if (maybeConfig) {
1790
1824
  return MicrofrontendsServer.fromFile({
@@ -1799,7 +1833,7 @@ var MicrofrontendsServer = class extends Microfrontends {
1799
1833
  if (isMonorepo2) {
1800
1834
  const defaultPackage = findDefaultMicrofrontendsPackage({
1801
1835
  repositoryRoot,
1802
- applicationName: packageJson.name
1836
+ applicationName: appName
1803
1837
  });
1804
1838
  const maybeConfigFromDefault = findConfig({ dir: defaultPackage });
1805
1839
  if (maybeConfigFromDefault) {
@@ -1829,7 +1863,7 @@ var MicrofrontendsServer = class extends Microfrontends {
1829
1863
  options
1830
1864
  }) {
1831
1865
  try {
1832
- const configJson = import_node_fs7.default.readFileSync(filePath, "utf-8");
1866
+ const configJson = import_node_fs8.default.readFileSync(filePath, "utf-8");
1833
1867
  const config = MicrofrontendsServer.validate(configJson);
1834
1868
  if (!isMainConfig(config) && options?.resolveMainConfig) {
1835
1869
  const repositoryRoot = findRepositoryRoot();
@@ -1877,7 +1911,7 @@ var MicrofrontendsServer = class extends Microfrontends {
1877
1911
  overrides
1878
1912
  }) {
1879
1913
  try {
1880
- const config = import_node_fs7.default.readFileSync(filePath, "utf-8");
1914
+ const config = import_node_fs8.default.readFileSync(filePath, "utf-8");
1881
1915
  const validatedConfig = MicrofrontendsServer.validate(config);
1882
1916
  if (!isMainConfig(validatedConfig)) {
1883
1917
  throw new MicrofrontendError(
@@ -1967,7 +2001,7 @@ var ProxyRequestRouter = class {
1967
2001
  const isJWTRedirect = url.searchParams.has("_vercel_jwt");
1968
2002
  const defaultHost = this.getDefaultHost(config);
1969
2003
  let hostname = null;
1970
- let path6 = request2.url;
2004
+ let path7 = request2.url;
1971
2005
  if (isAuthRedirect) {
1972
2006
  hostname = url.searchParams.get("_host_override");
1973
2007
  }
@@ -1977,12 +2011,12 @@ var ProxyRequestRouter = class {
1977
2011
  if (isJWTRedirect) {
1978
2012
  hostname = url.searchParams.get("_host_override");
1979
2013
  url.searchParams.delete("_host_override");
1980
- path6 = `${url.pathname}${url.search}`;
2014
+ path7 = `${url.pathname}${url.search}`;
1981
2015
  }
1982
2016
  if (!hostname) {
1983
2017
  return void 0;
1984
2018
  }
1985
- return { ...defaultHost, path: path6, hostname, protocol: "https", port: 443 };
2019
+ return { ...defaultHost, path: path7, hostname, protocol: "https", port: 443 };
1986
2020
  }
1987
2021
  getConfigWithOverrides(cookies) {
1988
2022
  const cookieOverrides = parseOverrides(
@@ -2006,14 +2040,14 @@ var ProxyRequestRouter = class {
2006
2040
  if (!request2.url) {
2007
2041
  return this.getDefaultHost(config);
2008
2042
  }
2009
- const { path: path6, mfeFlagValue } = extractMfeFlagValue(request2.url);
2043
+ const { path: path7, mfeFlagValue } = extractMfeFlagValue(request2.url);
2010
2044
  const authTarget = this.getAuthTarget(request2, config);
2011
2045
  if (authTarget) {
2012
2046
  return authTarget;
2013
2047
  }
2014
- const url = new import_node_url.URL(`http://example.com${path6}`);
2048
+ const url = new import_node_url.URL(`http://example.com${path7}`);
2015
2049
  const target = this.findMatchingApplication({
2016
- path: path6,
2050
+ path: path7,
2017
2051
  url,
2018
2052
  applications: config.getChildApplications(),
2019
2053
  referer: request2.headers.referer,
@@ -2029,12 +2063,12 @@ var ProxyRequestRouter = class {
2029
2063
  return target;
2030
2064
  const defaultHost = this.getDefaultHost(config);
2031
2065
  mfeDebug(
2032
- `no matching routes, routing ${path6} to default application: ${JSON.stringify(defaultHost)}`
2066
+ `no matching routes, routing ${path7} to default application: ${JSON.stringify(defaultHost)}`
2033
2067
  );
2034
- return { path: path6, ...defaultHost };
2068
+ return { path: path7, ...defaultHost };
2035
2069
  }
2036
2070
  findMatchingApplication({
2037
- path: path6,
2071
+ path: path7,
2038
2072
  url,
2039
2073
  applications,
2040
2074
  referer = void 0,
@@ -2046,15 +2080,15 @@ var ProxyRequestRouter = class {
2046
2080
  if (middlewareMfeZone) {
2047
2081
  if (middlewareMfeZone === application.name) {
2048
2082
  mfeDebug(
2049
- `routing ${path6} to '${target.application}' at ${target.hostname} according to 'x-vercel-mfe-zone' header`
2083
+ `routing ${path7} to '${target.application}' at ${target.hostname} according to 'x-vercel-mfe-zone' header`
2050
2084
  );
2051
- return { path: path6, ...target };
2085
+ return { path: path7, ...target };
2052
2086
  }
2053
2087
  continue;
2054
2088
  }
2055
2089
  const builtInRewrite = this.checkBuiltinAssetPrefix({
2056
2090
  rewrites: ["/:path*"],
2057
- path: path6,
2091
+ path: path7,
2058
2092
  url,
2059
2093
  app: application
2060
2094
  }) || this.checkNextOriginalFrame({ url, referer, applications });
@@ -2066,7 +2100,7 @@ var ProxyRequestRouter = class {
2066
2100
  const regexp = (0, import_path_to_regexp3.pathToRegexp)(childPath);
2067
2101
  if (regexp.test(url.pathname)) {
2068
2102
  mfeDebug(
2069
- `routing ${path6} to '${target.application}' at ${target.hostname}`
2103
+ `routing ${path7} to '${target.application}' at ${target.hostname}`
2070
2104
  );
2071
2105
  if (group.flag) {
2072
2106
  if (mfeFlagValue === true) {
@@ -2079,13 +2113,13 @@ var ProxyRequestRouter = class {
2079
2113
  if (!this.isDefaultAppLocal()) {
2080
2114
  const defaultApp = this.getDefaultHost(this.config);
2081
2115
  console.error(
2082
- `'${path6}' is a flagged path, but the default application is not running locally. Using '${defaultApp.hostname}' to handle this request.`
2116
+ `'${path7}' is a flagged path, but the default application is not running locally. Using '${defaultApp.hostname}' to handle this request.`
2083
2117
  );
2084
2118
  }
2085
2119
  return null;
2086
2120
  }
2087
2121
  }
2088
- return { path: path6, ...target };
2122
+ return { path: path7, ...target };
2089
2123
  }
2090
2124
  }
2091
2125
  }
@@ -2099,7 +2133,7 @@ var ProxyRequestRouter = class {
2099
2133
  }
2100
2134
  checkBuiltinAssetPrefix({
2101
2135
  rewrites,
2102
- path: path6,
2136
+ path: path7,
2103
2137
  url,
2104
2138
  app
2105
2139
  }) {
@@ -2111,7 +2145,7 @@ var ProxyRequestRouter = class {
2111
2145
  `routing ${pathname} to '${target.application}' at ${target.hostname}`
2112
2146
  );
2113
2147
  return {
2114
- path: path6,
2148
+ path: path7,
2115
2149
  ...target
2116
2150
  };
2117
2151
  }
@@ -2210,10 +2244,10 @@ var LocalProxy = class {
2210
2244
  const target = this.router.getTarget(req);
2211
2245
  const { req: strippedReq, mfeFlagValue } = removeMfeFlagQuery(req);
2212
2246
  if (target.protocol === "https") {
2213
- const { hostname, port, path: path6 } = target;
2247
+ const { hostname, port, path: path7 } = target;
2214
2248
  const requestOptions = {
2215
2249
  hostname,
2216
- path: path6,
2250
+ path: path7,
2217
2251
  method: req.method,
2218
2252
  headers: { ...req.headers, host: hostname },
2219
2253
  port
@@ -2238,7 +2272,7 @@ var LocalProxy = class {
2238
2272
  console.error("Proxy request error: ", err);
2239
2273
  res.writeHead(500, { "Content-Type": "text/plain" });
2240
2274
  res.end(
2241
- `Error proxying request for ${target.application} to ${hostname}:${port}${path6}`
2275
+ `Error proxying request for ${target.application} to ${hostname}:${port}${path7}`
2242
2276
  );
2243
2277
  });
2244
2278
  } else {
@@ -2255,11 +2289,11 @@ var LocalProxy = class {
2255
2289
  }
2256
2290
  // Handles requests that return data from the local proxy itself.
2257
2291
  // Returns true if the request was handled, false otherwise.
2258
- handleProxyInfoRequest(path6, res) {
2259
- if (!path6) {
2292
+ handleProxyInfoRequest(path7, res) {
2293
+ if (!path7) {
2260
2294
  return false;
2261
2295
  }
2262
- const url = new import_node_url.URL(`http://example.comf${path6}`);
2296
+ const url = new import_node_url.URL(`http://example.comf${path7}`);
2263
2297
  const pathname = url.pathname;
2264
2298
  switch (pathname) {
2265
2299
  case "/.well-known/vercel/microfrontends/routing": {
@@ -2282,12 +2316,12 @@ var LocalProxy = class {
2282
2316
  return false;
2283
2317
  }
2284
2318
  };
2285
- function extractMfeFlagValue(path6) {
2319
+ function extractMfeFlagValue(path7) {
2286
2320
  const host = "http://example.com";
2287
- const url = new import_node_url.URL(`${host}${path6}`);
2321
+ const url = new import_node_url.URL(`${host}${path7}`);
2288
2322
  const mfeFlagValue = stringAsBoolean(url.searchParams.get(MFE_FLAG_VALUE));
2289
2323
  url.searchParams.delete(MFE_FLAG_VALUE);
2290
- const pathWithoutMfe = mfeFlagValue === void 0 ? path6 : url.toString().substring(host.length);
2324
+ const pathWithoutMfe = mfeFlagValue === void 0 ? path7 : url.toString().substring(host.length);
2291
2325
  return { path: pathWithoutMfe, mfeFlagValue };
2292
2326
  }
2293
2327
  function stringAsBoolean(value) {
@@ -2302,11 +2336,11 @@ function removeMfeFlagQuery(req) {
2302
2336
  if (!req.url) {
2303
2337
  return { req };
2304
2338
  }
2305
- const { path: path6, mfeFlagValue } = extractMfeFlagValue(req.url);
2339
+ const { path: path7, mfeFlagValue } = extractMfeFlagValue(req.url);
2306
2340
  if (mfeFlagValue === void 0) {
2307
2341
  return { req };
2308
2342
  }
2309
- req.url = path6;
2343
+ req.url = path7;
2310
2344
  return { req, mfeFlagValue };
2311
2345
  }
2312
2346
 
@@ -2314,8 +2348,8 @@ function removeMfeFlagQuery(req) {
2314
2348
  var import_node_process = require("process");
2315
2349
 
2316
2350
  // src/utils/mfe-port.ts
2317
- var import_node_path9 = __toESM(require("path"), 1);
2318
- var import_node_fs8 = __toESM(require("fs"), 1);
2351
+ var import_node_path10 = __toESM(require("path"), 1);
2352
+ var import_node_fs9 = __toESM(require("fs"), 1);
2319
2353
  function mfePort(packageDir) {
2320
2354
  const { name: appName, version } = getPackageJson(packageDir);
2321
2355
  const result = loadConfig({ packageDir, appName });
@@ -2333,8 +2367,8 @@ function mfePort(packageDir) {
2333
2367
  };
2334
2368
  }
2335
2369
  function getPackageJson(packageDir) {
2336
- const filePath = import_node_path9.default.join(packageDir, "package.json");
2337
- return JSON.parse(import_node_fs8.default.readFileSync(filePath, "utf-8"));
2370
+ const filePath = import_node_path10.default.join(packageDir, "package.json");
2371
+ return JSON.parse(import_node_fs9.default.readFileSync(filePath, "utf-8"));
2338
2372
  }
2339
2373
  function loadConfig({
2340
2374
  packageDir,
package/dist/config.cjs CHANGED
@@ -323,6 +323,9 @@ function validatePathExpression(path) {
323
323
  return `token ${i} in ${path} is undefined, this shouldn't happen`;
324
324
  }
325
325
  if (typeof token !== "string") {
326
+ if (!token.name) {
327
+ return `Only named wildcards are allowed: ${path} (hint: add ":path" to the wildcard)`;
328
+ }
326
329
  if (token.pattern !== PATH_DEFAULT_PATTERN && // Allows (a|b|c) and ((?!a|b|c).*) regex
327
330
  // Only limited regex is supported for now, due to performance considerations
328
331
  !/^(?<allowed>[\w]+(?:\|[^|()]+)+)$|^\(\?!(?<disallowed>[\w]+(?:\|[^|()]+)+)\)\.\*$/.test(