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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/dist/bin/cli.cjs +116 -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 +82 -72
  7. package/dist/experimental/sveltekit.cjs.map +1 -1
  8. package/dist/experimental/sveltekit.js +82 -72
  9. package/dist/experimental/sveltekit.js.map +1 -1
  10. package/dist/experimental/vite.cjs +85 -75
  11. package/dist/experimental/vite.cjs.map +1 -1
  12. package/dist/experimental/vite.js +85 -75
  13. package/dist/experimental/vite.js.map +1 -1
  14. package/dist/microfrontends/server.cjs +82 -45
  15. package/dist/microfrontends/server.cjs.map +1 -1
  16. package/dist/microfrontends/server.js +82 -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 +82 -72
  23. package/dist/next/config.cjs.map +1 -1
  24. package/dist/next/config.js +82 -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 +86 -49
  35. package/dist/utils/mfe-port.cjs.map +1 -1
  36. package/dist/utils/mfe-port.js +86 -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.5",
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 {
@@ -1140,6 +1143,9 @@ var import_node_fs = __toESM(require("fs"), 1);
1140
1143
  var import_node_path = __toESM(require("path"), 1);
1141
1144
  var GIT_DIRECTORY = ".git";
1142
1145
  function findRepositoryRoot(startDir) {
1146
+ if (process.env.NX_WORKSPACE_ROOT) {
1147
+ return process.env.NX_WORKSPACE_ROOT;
1148
+ }
1143
1149
  let currentDir = startDir || process.cwd();
1144
1150
  while (currentDir !== import_node_path.default.parse(currentDir).root) {
1145
1151
  const gitPath = import_node_path.default.join(currentDir, GIT_DIRECTORY);
@@ -1297,6 +1303,9 @@ function isMonorepo({
1297
1303
  if (import_node_fs4.default.existsSync(import_node_path4.default.join(repositoryRoot, "vlt-workspaces.json"))) {
1298
1304
  return true;
1299
1305
  }
1306
+ if (process.env.NX_WORKSPACE_ROOT === import_node_path4.default.resolve(repositoryRoot)) {
1307
+ return true;
1308
+ }
1300
1309
  const packageJsonPath = import_node_path4.default.join(repositoryRoot, "package.json");
1301
1310
  if (!import_node_fs4.default.existsSync(packageJsonPath)) {
1302
1311
  return false;
@@ -1342,8 +1351,42 @@ function findConfig({ dir }) {
1342
1351
  return null;
1343
1352
  }
1344
1353
 
1345
- // src/config/microfrontends/server/utils/get-output-file-path.ts
1354
+ // src/config/microfrontends/utils/get-application-context.ts
1355
+ var import_node_fs7 = __toESM(require("fs"), 1);
1346
1356
  var import_node_path7 = __toESM(require("path"), 1);
1357
+ function getApplicationContext(opts) {
1358
+ if (opts?.appName) {
1359
+ return { name: opts.appName };
1360
+ }
1361
+ if (process.env.NX_TASK_TARGET_PROJECT) {
1362
+ return { name: process.env.NX_TASK_TARGET_PROJECT };
1363
+ }
1364
+ try {
1365
+ const packageJsonString = import_node_fs7.default.readFileSync(
1366
+ import_node_path7.default.join(opts?.packageRoot || ".", "package.json"),
1367
+ "utf-8"
1368
+ );
1369
+ const packageJson = JSON.parse(packageJsonString);
1370
+ if (!packageJson.name) {
1371
+ throw new MicrofrontendError(
1372
+ `package.json file missing required field "name"`,
1373
+ {
1374
+ type: "packageJson",
1375
+ subtype: "missing_field_name",
1376
+ source: "@vercel/microfrontends/next"
1377
+ }
1378
+ );
1379
+ }
1380
+ return { name: packageJson.name };
1381
+ } catch (err) {
1382
+ throw MicrofrontendError.handle(err, {
1383
+ fileName: "package.json"
1384
+ });
1385
+ }
1386
+ }
1387
+
1388
+ // src/config/microfrontends/server/utils/get-output-file-path.ts
1389
+ var import_node_path8 = __toESM(require("path"), 1);
1347
1390
 
1348
1391
  // src/config/microfrontends/server/constants.ts
1349
1392
  var MFE_CONFIG_DEFAULT_FILE_PATH = "microfrontends";
@@ -1351,7 +1394,7 @@ var MFE_CONFIG_DEFAULT_FILE_NAME = "microfrontends.json";
1351
1394
 
1352
1395
  // src/config/microfrontends/server/utils/get-output-file-path.ts
1353
1396
  function getOutputFilePath() {
1354
- return import_node_path7.default.join(MFE_CONFIG_DEFAULT_FILE_PATH, MFE_CONFIG_DEFAULT_FILE_NAME);
1397
+ return import_node_path8.default.join(MFE_CONFIG_DEFAULT_FILE_PATH, MFE_CONFIG_DEFAULT_FILE_NAME);
1355
1398
  }
1356
1399
 
1357
1400
  // src/config/microfrontends/server/validation.ts
@@ -1690,8 +1733,8 @@ var MicrofrontendsServer = class extends Microfrontends {
1690
1733
  pretty: true
1691
1734
  }) {
1692
1735
  const outputPath = getOutputFilePath();
1693
- import_node_fs7.default.mkdirSync((0, import_node_path8.dirname)(outputPath), { recursive: true });
1694
- import_node_fs7.default.writeFileSync(
1736
+ import_node_fs8.default.mkdirSync((0, import_node_path9.dirname)(outputPath), { recursive: true });
1737
+ import_node_fs8.default.writeFileSync(
1695
1738
  outputPath,
1696
1739
  JSON.stringify(
1697
1740
  this.config.toSchemaJson(),
@@ -1777,14 +1820,8 @@ var MicrofrontendsServer = class extends Microfrontends {
1777
1820
  }
1778
1821
  try {
1779
1822
  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 };
1823
+ const { name: appName } = getApplicationContext({ packageRoot });
1824
+ const configMeta = meta ?? { fromApp: appName };
1788
1825
  const maybeConfig = findConfig({ dir: packageRoot });
1789
1826
  if (maybeConfig) {
1790
1827
  return MicrofrontendsServer.fromFile({
@@ -1799,7 +1836,7 @@ var MicrofrontendsServer = class extends Microfrontends {
1799
1836
  if (isMonorepo2) {
1800
1837
  const defaultPackage = findDefaultMicrofrontendsPackage({
1801
1838
  repositoryRoot,
1802
- applicationName: packageJson.name
1839
+ applicationName: appName
1803
1840
  });
1804
1841
  const maybeConfigFromDefault = findConfig({ dir: defaultPackage });
1805
1842
  if (maybeConfigFromDefault) {
@@ -1829,7 +1866,7 @@ var MicrofrontendsServer = class extends Microfrontends {
1829
1866
  options
1830
1867
  }) {
1831
1868
  try {
1832
- const configJson = import_node_fs7.default.readFileSync(filePath, "utf-8");
1869
+ const configJson = import_node_fs8.default.readFileSync(filePath, "utf-8");
1833
1870
  const config = MicrofrontendsServer.validate(configJson);
1834
1871
  if (!isMainConfig(config) && options?.resolveMainConfig) {
1835
1872
  const repositoryRoot = findRepositoryRoot();
@@ -1877,7 +1914,7 @@ var MicrofrontendsServer = class extends Microfrontends {
1877
1914
  overrides
1878
1915
  }) {
1879
1916
  try {
1880
- const config = import_node_fs7.default.readFileSync(filePath, "utf-8");
1917
+ const config = import_node_fs8.default.readFileSync(filePath, "utf-8");
1881
1918
  const validatedConfig = MicrofrontendsServer.validate(config);
1882
1919
  if (!isMainConfig(validatedConfig)) {
1883
1920
  throw new MicrofrontendError(
@@ -1967,7 +2004,7 @@ var ProxyRequestRouter = class {
1967
2004
  const isJWTRedirect = url.searchParams.has("_vercel_jwt");
1968
2005
  const defaultHost = this.getDefaultHost(config);
1969
2006
  let hostname = null;
1970
- let path6 = request2.url;
2007
+ let path7 = request2.url;
1971
2008
  if (isAuthRedirect) {
1972
2009
  hostname = url.searchParams.get("_host_override");
1973
2010
  }
@@ -1977,12 +2014,12 @@ var ProxyRequestRouter = class {
1977
2014
  if (isJWTRedirect) {
1978
2015
  hostname = url.searchParams.get("_host_override");
1979
2016
  url.searchParams.delete("_host_override");
1980
- path6 = `${url.pathname}${url.search}`;
2017
+ path7 = `${url.pathname}${url.search}`;
1981
2018
  }
1982
2019
  if (!hostname) {
1983
2020
  return void 0;
1984
2021
  }
1985
- return { ...defaultHost, path: path6, hostname, protocol: "https", port: 443 };
2022
+ return { ...defaultHost, path: path7, hostname, protocol: "https", port: 443 };
1986
2023
  }
1987
2024
  getConfigWithOverrides(cookies) {
1988
2025
  const cookieOverrides = parseOverrides(
@@ -2006,14 +2043,14 @@ var ProxyRequestRouter = class {
2006
2043
  if (!request2.url) {
2007
2044
  return this.getDefaultHost(config);
2008
2045
  }
2009
- const { path: path6, mfeFlagValue } = extractMfeFlagValue(request2.url);
2046
+ const { path: path7, mfeFlagValue } = extractMfeFlagValue(request2.url);
2010
2047
  const authTarget = this.getAuthTarget(request2, config);
2011
2048
  if (authTarget) {
2012
2049
  return authTarget;
2013
2050
  }
2014
- const url = new import_node_url.URL(`http://example.com${path6}`);
2051
+ const url = new import_node_url.URL(`http://example.com${path7}`);
2015
2052
  const target = this.findMatchingApplication({
2016
- path: path6,
2053
+ path: path7,
2017
2054
  url,
2018
2055
  applications: config.getChildApplications(),
2019
2056
  referer: request2.headers.referer,
@@ -2029,12 +2066,12 @@ var ProxyRequestRouter = class {
2029
2066
  return target;
2030
2067
  const defaultHost = this.getDefaultHost(config);
2031
2068
  mfeDebug(
2032
- `no matching routes, routing ${path6} to default application: ${JSON.stringify(defaultHost)}`
2069
+ `no matching routes, routing ${path7} to default application: ${JSON.stringify(defaultHost)}`
2033
2070
  );
2034
- return { path: path6, ...defaultHost };
2071
+ return { path: path7, ...defaultHost };
2035
2072
  }
2036
2073
  findMatchingApplication({
2037
- path: path6,
2074
+ path: path7,
2038
2075
  url,
2039
2076
  applications,
2040
2077
  referer = void 0,
@@ -2046,15 +2083,15 @@ var ProxyRequestRouter = class {
2046
2083
  if (middlewareMfeZone) {
2047
2084
  if (middlewareMfeZone === application.name) {
2048
2085
  mfeDebug(
2049
- `routing ${path6} to '${target.application}' at ${target.hostname} according to 'x-vercel-mfe-zone' header`
2086
+ `routing ${path7} to '${target.application}' at ${target.hostname} according to 'x-vercel-mfe-zone' header`
2050
2087
  );
2051
- return { path: path6, ...target };
2088
+ return { path: path7, ...target };
2052
2089
  }
2053
2090
  continue;
2054
2091
  }
2055
2092
  const builtInRewrite = this.checkBuiltinAssetPrefix({
2056
2093
  rewrites: ["/:path*"],
2057
- path: path6,
2094
+ path: path7,
2058
2095
  url,
2059
2096
  app: application
2060
2097
  }) || this.checkNextOriginalFrame({ url, referer, applications });
@@ -2066,7 +2103,7 @@ var ProxyRequestRouter = class {
2066
2103
  const regexp = (0, import_path_to_regexp3.pathToRegexp)(childPath);
2067
2104
  if (regexp.test(url.pathname)) {
2068
2105
  mfeDebug(
2069
- `routing ${path6} to '${target.application}' at ${target.hostname}`
2106
+ `routing ${path7} to '${target.application}' at ${target.hostname}`
2070
2107
  );
2071
2108
  if (group.flag) {
2072
2109
  if (mfeFlagValue === true) {
@@ -2079,13 +2116,13 @@ var ProxyRequestRouter = class {
2079
2116
  if (!this.isDefaultAppLocal()) {
2080
2117
  const defaultApp = this.getDefaultHost(this.config);
2081
2118
  console.error(
2082
- `'${path6}' is a flagged path, but the default application is not running locally. Using '${defaultApp.hostname}' to handle this request.`
2119
+ `'${path7}' is a flagged path, but the default application is not running locally. Using '${defaultApp.hostname}' to handle this request.`
2083
2120
  );
2084
2121
  }
2085
2122
  return null;
2086
2123
  }
2087
2124
  }
2088
- return { path: path6, ...target };
2125
+ return { path: path7, ...target };
2089
2126
  }
2090
2127
  }
2091
2128
  }
@@ -2099,7 +2136,7 @@ var ProxyRequestRouter = class {
2099
2136
  }
2100
2137
  checkBuiltinAssetPrefix({
2101
2138
  rewrites,
2102
- path: path6,
2139
+ path: path7,
2103
2140
  url,
2104
2141
  app
2105
2142
  }) {
@@ -2111,7 +2148,7 @@ var ProxyRequestRouter = class {
2111
2148
  `routing ${pathname} to '${target.application}' at ${target.hostname}`
2112
2149
  );
2113
2150
  return {
2114
- path: path6,
2151
+ path: path7,
2115
2152
  ...target
2116
2153
  };
2117
2154
  }
@@ -2210,10 +2247,10 @@ var LocalProxy = class {
2210
2247
  const target = this.router.getTarget(req);
2211
2248
  const { req: strippedReq, mfeFlagValue } = removeMfeFlagQuery(req);
2212
2249
  if (target.protocol === "https") {
2213
- const { hostname, port, path: path6 } = target;
2250
+ const { hostname, port, path: path7 } = target;
2214
2251
  const requestOptions = {
2215
2252
  hostname,
2216
- path: path6,
2253
+ path: path7,
2217
2254
  method: req.method,
2218
2255
  headers: { ...req.headers, host: hostname },
2219
2256
  port
@@ -2238,7 +2275,7 @@ var LocalProxy = class {
2238
2275
  console.error("Proxy request error: ", err);
2239
2276
  res.writeHead(500, { "Content-Type": "text/plain" });
2240
2277
  res.end(
2241
- `Error proxying request for ${target.application} to ${hostname}:${port}${path6}`
2278
+ `Error proxying request for ${target.application} to ${hostname}:${port}${path7}`
2242
2279
  );
2243
2280
  });
2244
2281
  } else {
@@ -2255,11 +2292,11 @@ var LocalProxy = class {
2255
2292
  }
2256
2293
  // Handles requests that return data from the local proxy itself.
2257
2294
  // Returns true if the request was handled, false otherwise.
2258
- handleProxyInfoRequest(path6, res) {
2259
- if (!path6) {
2295
+ handleProxyInfoRequest(path7, res) {
2296
+ if (!path7) {
2260
2297
  return false;
2261
2298
  }
2262
- const url = new import_node_url.URL(`http://example.comf${path6}`);
2299
+ const url = new import_node_url.URL(`http://example.comf${path7}`);
2263
2300
  const pathname = url.pathname;
2264
2301
  switch (pathname) {
2265
2302
  case "/.well-known/vercel/microfrontends/routing": {
@@ -2282,12 +2319,12 @@ var LocalProxy = class {
2282
2319
  return false;
2283
2320
  }
2284
2321
  };
2285
- function extractMfeFlagValue(path6) {
2322
+ function extractMfeFlagValue(path7) {
2286
2323
  const host = "http://example.com";
2287
- const url = new import_node_url.URL(`${host}${path6}`);
2324
+ const url = new import_node_url.URL(`${host}${path7}`);
2288
2325
  const mfeFlagValue = stringAsBoolean(url.searchParams.get(MFE_FLAG_VALUE));
2289
2326
  url.searchParams.delete(MFE_FLAG_VALUE);
2290
- const pathWithoutMfe = mfeFlagValue === void 0 ? path6 : url.toString().substring(host.length);
2327
+ const pathWithoutMfe = mfeFlagValue === void 0 ? path7 : url.toString().substring(host.length);
2291
2328
  return { path: pathWithoutMfe, mfeFlagValue };
2292
2329
  }
2293
2330
  function stringAsBoolean(value) {
@@ -2302,11 +2339,11 @@ function removeMfeFlagQuery(req) {
2302
2339
  if (!req.url) {
2303
2340
  return { req };
2304
2341
  }
2305
- const { path: path6, mfeFlagValue } = extractMfeFlagValue(req.url);
2342
+ const { path: path7, mfeFlagValue } = extractMfeFlagValue(req.url);
2306
2343
  if (mfeFlagValue === void 0) {
2307
2344
  return { req };
2308
2345
  }
2309
- req.url = path6;
2346
+ req.url = path7;
2310
2347
  return { req, mfeFlagValue };
2311
2348
  }
2312
2349
 
@@ -2314,8 +2351,8 @@ function removeMfeFlagQuery(req) {
2314
2351
  var import_node_process = require("process");
2315
2352
 
2316
2353
  // src/utils/mfe-port.ts
2317
- var import_node_path9 = __toESM(require("path"), 1);
2318
- var import_node_fs8 = __toESM(require("fs"), 1);
2354
+ var import_node_path10 = __toESM(require("path"), 1);
2355
+ var import_node_fs9 = __toESM(require("fs"), 1);
2319
2356
  function mfePort(packageDir) {
2320
2357
  const { name: appName, version } = getPackageJson(packageDir);
2321
2358
  const result = loadConfig({ packageDir, appName });
@@ -2333,8 +2370,8 @@ function mfePort(packageDir) {
2333
2370
  };
2334
2371
  }
2335
2372
  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"));
2373
+ const filePath = import_node_path10.default.join(packageDir, "package.json");
2374
+ return JSON.parse(import_node_fs9.default.readFileSync(filePath, "utf-8"));
2338
2375
  }
2339
2376
  function loadConfig({
2340
2377
  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(