@vercel/microfrontends 1.0.1-canary.2 → 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 (44) hide show
  1. package/dist/bin/cli.cjs +115 -85
  2. package/dist/config.cjs +5 -6
  3. package/dist/config.cjs.map +1 -1
  4. package/dist/config.d.ts +1 -1
  5. package/dist/config.js +5 -6
  6. package/dist/config.js.map +1 -1
  7. package/dist/experimental/sveltekit.cjs +81 -78
  8. package/dist/experimental/sveltekit.cjs.map +1 -1
  9. package/dist/experimental/sveltekit.js +81 -78
  10. package/dist/experimental/sveltekit.js.map +1 -1
  11. package/dist/experimental/vite.cjs +124 -88
  12. package/dist/experimental/vite.cjs.map +1 -1
  13. package/dist/experimental/vite.d.ts +1 -1
  14. package/dist/experimental/vite.js +124 -90
  15. package/dist/experimental/vite.js.map +1 -1
  16. package/dist/{index-d5994ac5.d.ts → index-2b59c627.d.ts} +1 -1
  17. package/dist/microfrontends/server.cjs +81 -51
  18. package/dist/microfrontends/server.cjs.map +1 -1
  19. package/dist/microfrontends/server.d.ts +1 -1
  20. package/dist/microfrontends/server.js +81 -51
  21. package/dist/microfrontends/server.js.map +1 -1
  22. package/dist/microfrontends.cjs +5 -6
  23. package/dist/microfrontends.cjs.map +1 -1
  24. package/dist/microfrontends.d.ts +1 -1
  25. package/dist/microfrontends.js +5 -6
  26. package/dist/microfrontends.js.map +1 -1
  27. package/dist/next/config.cjs +81 -78
  28. package/dist/next/config.cjs.map +1 -1
  29. package/dist/next/config.js +81 -78
  30. package/dist/next/config.js.map +1 -1
  31. package/dist/next/middleware.cjs +5 -6
  32. package/dist/next/middleware.cjs.map +1 -1
  33. package/dist/next/middleware.js +5 -6
  34. package/dist/next/middleware.js.map +1 -1
  35. package/dist/next/testing.cjs +5 -6
  36. package/dist/next/testing.cjs.map +1 -1
  37. package/dist/next/testing.d.ts +1 -1
  38. package/dist/next/testing.js +5 -6
  39. package/dist/next/testing.js.map +1 -1
  40. package/dist/utils/mfe-port.cjs +85 -55
  41. package/dist/utils/mfe-port.cjs.map +1 -1
  42. package/dist/utils/mfe-port.js +85 -55
  43. package/dist/utils/mfe-port.js.map +1 -1
  44. 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.2",
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() {
@@ -930,12 +933,8 @@ var MicrofrontendConfigIsomorphic = class {
930
933
  const skipValidation = opts?.skipValidation ?? [];
931
934
  const c = typeof config === "string" ? (0, import_jsonc_parser.parse)(config) : config;
932
935
  if (isMainConfig(c)) {
933
- if (!skipValidation.includes("paths")) {
934
- validateConfigPaths(c.applications);
935
- }
936
- if (!skipValidation.includes("defaultApplication")) {
937
- validateConfigDefaultApplication(c.applications);
938
- }
936
+ validateConfigPaths(c.applications);
937
+ validateConfigDefaultApplication(c.applications);
939
938
  if (!skipValidation.includes("deprecatedFields")) {
940
939
  validateDeprecatedFields(c);
941
940
  }
@@ -1095,8 +1094,8 @@ function isMainConfig2(c) {
1095
1094
  }
1096
1095
 
1097
1096
  // src/config/microfrontends/server/index.ts
1098
- var import_node_fs7 = __toESM(require("fs"), 1);
1099
- var import_node_path8 = require("path");
1097
+ var import_node_fs8 = __toESM(require("fs"), 1);
1098
+ var import_node_path9 = require("path");
1100
1099
 
1101
1100
  // src/config/microfrontends-config/isomorphic/child.ts
1102
1101
  var MicrofrontendChildConfig = class extends MicrofrontendConfigIsomorphic {
@@ -1301,6 +1300,9 @@ function isMonorepo({
1301
1300
  if (import_node_fs4.default.existsSync(import_node_path4.default.join(repositoryRoot, "vlt-workspaces.json"))) {
1302
1301
  return true;
1303
1302
  }
1303
+ if (process.env.NX_WORKSPACE_ROOT === import_node_path4.default.resolve(repositoryRoot)) {
1304
+ return true;
1305
+ }
1304
1306
  const packageJsonPath = import_node_path4.default.join(repositoryRoot, "package.json");
1305
1307
  if (!import_node_fs4.default.existsSync(packageJsonPath)) {
1306
1308
  return false;
@@ -1346,8 +1348,42 @@ function findConfig({ dir }) {
1346
1348
  return null;
1347
1349
  }
1348
1350
 
1349
- // 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);
1350
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);
1351
1387
 
1352
1388
  // src/config/microfrontends/server/constants.ts
1353
1389
  var MFE_CONFIG_DEFAULT_FILE_PATH = "microfrontends";
@@ -1355,7 +1391,7 @@ var MFE_CONFIG_DEFAULT_FILE_NAME = "microfrontends.json";
1355
1391
 
1356
1392
  // src/config/microfrontends/server/utils/get-output-file-path.ts
1357
1393
  function getOutputFilePath() {
1358
- 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);
1359
1395
  }
1360
1396
 
1361
1397
  // src/config/microfrontends/server/validation.ts
@@ -1694,8 +1730,8 @@ var MicrofrontendsServer = class extends Microfrontends {
1694
1730
  pretty: true
1695
1731
  }) {
1696
1732
  const outputPath = getOutputFilePath();
1697
- import_node_fs7.default.mkdirSync((0, import_node_path8.dirname)(outputPath), { recursive: true });
1698
- 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(
1699
1735
  outputPath,
1700
1736
  JSON.stringify(
1701
1737
  this.config.toSchemaJson(),
@@ -1781,14 +1817,8 @@ var MicrofrontendsServer = class extends Microfrontends {
1781
1817
  }
1782
1818
  try {
1783
1819
  const packageRoot = findPackageRoot(directory);
1784
- const packageJsonPath = (0, import_node_path8.join)(packageRoot, "package.json");
1785
- const packageJson = JSON.parse(
1786
- import_node_fs7.default.readFileSync(packageJsonPath, "utf-8")
1787
- );
1788
- if (!packageJson.name) {
1789
- throw new Error(`No name found in package.json at ${packageJsonPath}`);
1790
- }
1791
- const configMeta = meta ?? { fromApp: packageJson.name };
1820
+ const { name: appName } = getApplicationContext({ packageRoot });
1821
+ const configMeta = meta ?? { fromApp: appName };
1792
1822
  const maybeConfig = findConfig({ dir: packageRoot });
1793
1823
  if (maybeConfig) {
1794
1824
  return MicrofrontendsServer.fromFile({
@@ -1803,7 +1833,7 @@ var MicrofrontendsServer = class extends Microfrontends {
1803
1833
  if (isMonorepo2) {
1804
1834
  const defaultPackage = findDefaultMicrofrontendsPackage({
1805
1835
  repositoryRoot,
1806
- applicationName: packageJson.name
1836
+ applicationName: appName
1807
1837
  });
1808
1838
  const maybeConfigFromDefault = findConfig({ dir: defaultPackage });
1809
1839
  if (maybeConfigFromDefault) {
@@ -1833,7 +1863,7 @@ var MicrofrontendsServer = class extends Microfrontends {
1833
1863
  options
1834
1864
  }) {
1835
1865
  try {
1836
- const configJson = import_node_fs7.default.readFileSync(filePath, "utf-8");
1866
+ const configJson = import_node_fs8.default.readFileSync(filePath, "utf-8");
1837
1867
  const config = MicrofrontendsServer.validate(configJson);
1838
1868
  if (!isMainConfig(config) && options?.resolveMainConfig) {
1839
1869
  const repositoryRoot = findRepositoryRoot();
@@ -1881,7 +1911,7 @@ var MicrofrontendsServer = class extends Microfrontends {
1881
1911
  overrides
1882
1912
  }) {
1883
1913
  try {
1884
- const config = import_node_fs7.default.readFileSync(filePath, "utf-8");
1914
+ const config = import_node_fs8.default.readFileSync(filePath, "utf-8");
1885
1915
  const validatedConfig = MicrofrontendsServer.validate(config);
1886
1916
  if (!isMainConfig(validatedConfig)) {
1887
1917
  throw new MicrofrontendError(
@@ -1971,7 +2001,7 @@ var ProxyRequestRouter = class {
1971
2001
  const isJWTRedirect = url.searchParams.has("_vercel_jwt");
1972
2002
  const defaultHost = this.getDefaultHost(config);
1973
2003
  let hostname = null;
1974
- let path6 = request2.url;
2004
+ let path7 = request2.url;
1975
2005
  if (isAuthRedirect) {
1976
2006
  hostname = url.searchParams.get("_host_override");
1977
2007
  }
@@ -1981,12 +2011,12 @@ var ProxyRequestRouter = class {
1981
2011
  if (isJWTRedirect) {
1982
2012
  hostname = url.searchParams.get("_host_override");
1983
2013
  url.searchParams.delete("_host_override");
1984
- path6 = `${url.pathname}${url.search}`;
2014
+ path7 = `${url.pathname}${url.search}`;
1985
2015
  }
1986
2016
  if (!hostname) {
1987
2017
  return void 0;
1988
2018
  }
1989
- return { ...defaultHost, path: path6, hostname, protocol: "https", port: 443 };
2019
+ return { ...defaultHost, path: path7, hostname, protocol: "https", port: 443 };
1990
2020
  }
1991
2021
  getConfigWithOverrides(cookies) {
1992
2022
  const cookieOverrides = parseOverrides(
@@ -2010,14 +2040,14 @@ var ProxyRequestRouter = class {
2010
2040
  if (!request2.url) {
2011
2041
  return this.getDefaultHost(config);
2012
2042
  }
2013
- const { path: path6, mfeFlagValue } = extractMfeFlagValue(request2.url);
2043
+ const { path: path7, mfeFlagValue } = extractMfeFlagValue(request2.url);
2014
2044
  const authTarget = this.getAuthTarget(request2, config);
2015
2045
  if (authTarget) {
2016
2046
  return authTarget;
2017
2047
  }
2018
- const url = new import_node_url.URL(`http://example.com${path6}`);
2048
+ const url = new import_node_url.URL(`http://example.com${path7}`);
2019
2049
  const target = this.findMatchingApplication({
2020
- path: path6,
2050
+ path: path7,
2021
2051
  url,
2022
2052
  applications: config.getChildApplications(),
2023
2053
  referer: request2.headers.referer,
@@ -2033,12 +2063,12 @@ var ProxyRequestRouter = class {
2033
2063
  return target;
2034
2064
  const defaultHost = this.getDefaultHost(config);
2035
2065
  mfeDebug(
2036
- `no matching routes, routing ${path6} to default application: ${JSON.stringify(defaultHost)}`
2066
+ `no matching routes, routing ${path7} to default application: ${JSON.stringify(defaultHost)}`
2037
2067
  );
2038
- return { path: path6, ...defaultHost };
2068
+ return { path: path7, ...defaultHost };
2039
2069
  }
2040
2070
  findMatchingApplication({
2041
- path: path6,
2071
+ path: path7,
2042
2072
  url,
2043
2073
  applications,
2044
2074
  referer = void 0,
@@ -2050,15 +2080,15 @@ var ProxyRequestRouter = class {
2050
2080
  if (middlewareMfeZone) {
2051
2081
  if (middlewareMfeZone === application.name) {
2052
2082
  mfeDebug(
2053
- `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`
2054
2084
  );
2055
- return { path: path6, ...target };
2085
+ return { path: path7, ...target };
2056
2086
  }
2057
2087
  continue;
2058
2088
  }
2059
2089
  const builtInRewrite = this.checkBuiltinAssetPrefix({
2060
2090
  rewrites: ["/:path*"],
2061
- path: path6,
2091
+ path: path7,
2062
2092
  url,
2063
2093
  app: application
2064
2094
  }) || this.checkNextOriginalFrame({ url, referer, applications });
@@ -2070,7 +2100,7 @@ var ProxyRequestRouter = class {
2070
2100
  const regexp = (0, import_path_to_regexp3.pathToRegexp)(childPath);
2071
2101
  if (regexp.test(url.pathname)) {
2072
2102
  mfeDebug(
2073
- `routing ${path6} to '${target.application}' at ${target.hostname}`
2103
+ `routing ${path7} to '${target.application}' at ${target.hostname}`
2074
2104
  );
2075
2105
  if (group.flag) {
2076
2106
  if (mfeFlagValue === true) {
@@ -2083,13 +2113,13 @@ var ProxyRequestRouter = class {
2083
2113
  if (!this.isDefaultAppLocal()) {
2084
2114
  const defaultApp = this.getDefaultHost(this.config);
2085
2115
  console.error(
2086
- `'${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.`
2087
2117
  );
2088
2118
  }
2089
2119
  return null;
2090
2120
  }
2091
2121
  }
2092
- return { path: path6, ...target };
2122
+ return { path: path7, ...target };
2093
2123
  }
2094
2124
  }
2095
2125
  }
@@ -2103,7 +2133,7 @@ var ProxyRequestRouter = class {
2103
2133
  }
2104
2134
  checkBuiltinAssetPrefix({
2105
2135
  rewrites,
2106
- path: path6,
2136
+ path: path7,
2107
2137
  url,
2108
2138
  app
2109
2139
  }) {
@@ -2115,7 +2145,7 @@ var ProxyRequestRouter = class {
2115
2145
  `routing ${pathname} to '${target.application}' at ${target.hostname}`
2116
2146
  );
2117
2147
  return {
2118
- path: path6,
2148
+ path: path7,
2119
2149
  ...target
2120
2150
  };
2121
2151
  }
@@ -2214,10 +2244,10 @@ var LocalProxy = class {
2214
2244
  const target = this.router.getTarget(req);
2215
2245
  const { req: strippedReq, mfeFlagValue } = removeMfeFlagQuery(req);
2216
2246
  if (target.protocol === "https") {
2217
- const { hostname, port, path: path6 } = target;
2247
+ const { hostname, port, path: path7 } = target;
2218
2248
  const requestOptions = {
2219
2249
  hostname,
2220
- path: path6,
2250
+ path: path7,
2221
2251
  method: req.method,
2222
2252
  headers: { ...req.headers, host: hostname },
2223
2253
  port
@@ -2242,7 +2272,7 @@ var LocalProxy = class {
2242
2272
  console.error("Proxy request error: ", err);
2243
2273
  res.writeHead(500, { "Content-Type": "text/plain" });
2244
2274
  res.end(
2245
- `Error proxying request for ${target.application} to ${hostname}:${port}${path6}`
2275
+ `Error proxying request for ${target.application} to ${hostname}:${port}${path7}`
2246
2276
  );
2247
2277
  });
2248
2278
  } else {
@@ -2259,11 +2289,11 @@ var LocalProxy = class {
2259
2289
  }
2260
2290
  // Handles requests that return data from the local proxy itself.
2261
2291
  // Returns true if the request was handled, false otherwise.
2262
- handleProxyInfoRequest(path6, res) {
2263
- if (!path6) {
2292
+ handleProxyInfoRequest(path7, res) {
2293
+ if (!path7) {
2264
2294
  return false;
2265
2295
  }
2266
- const url = new import_node_url.URL(`http://example.comf${path6}`);
2296
+ const url = new import_node_url.URL(`http://example.comf${path7}`);
2267
2297
  const pathname = url.pathname;
2268
2298
  switch (pathname) {
2269
2299
  case "/.well-known/vercel/microfrontends/routing": {
@@ -2286,12 +2316,12 @@ var LocalProxy = class {
2286
2316
  return false;
2287
2317
  }
2288
2318
  };
2289
- function extractMfeFlagValue(path6) {
2319
+ function extractMfeFlagValue(path7) {
2290
2320
  const host = "http://example.com";
2291
- const url = new import_node_url.URL(`${host}${path6}`);
2321
+ const url = new import_node_url.URL(`${host}${path7}`);
2292
2322
  const mfeFlagValue = stringAsBoolean(url.searchParams.get(MFE_FLAG_VALUE));
2293
2323
  url.searchParams.delete(MFE_FLAG_VALUE);
2294
- const pathWithoutMfe = mfeFlagValue === void 0 ? path6 : url.toString().substring(host.length);
2324
+ const pathWithoutMfe = mfeFlagValue === void 0 ? path7 : url.toString().substring(host.length);
2295
2325
  return { path: pathWithoutMfe, mfeFlagValue };
2296
2326
  }
2297
2327
  function stringAsBoolean(value) {
@@ -2306,11 +2336,11 @@ function removeMfeFlagQuery(req) {
2306
2336
  if (!req.url) {
2307
2337
  return { req };
2308
2338
  }
2309
- const { path: path6, mfeFlagValue } = extractMfeFlagValue(req.url);
2339
+ const { path: path7, mfeFlagValue } = extractMfeFlagValue(req.url);
2310
2340
  if (mfeFlagValue === void 0) {
2311
2341
  return { req };
2312
2342
  }
2313
- req.url = path6;
2343
+ req.url = path7;
2314
2344
  return { req, mfeFlagValue };
2315
2345
  }
2316
2346
 
@@ -2318,8 +2348,8 @@ function removeMfeFlagQuery(req) {
2318
2348
  var import_node_process = require("process");
2319
2349
 
2320
2350
  // src/utils/mfe-port.ts
2321
- var import_node_path9 = __toESM(require("path"), 1);
2322
- 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);
2323
2353
  function mfePort(packageDir) {
2324
2354
  const { name: appName, version } = getPackageJson(packageDir);
2325
2355
  const result = loadConfig({ packageDir, appName });
@@ -2337,8 +2367,8 @@ function mfePort(packageDir) {
2337
2367
  };
2338
2368
  }
2339
2369
  function getPackageJson(packageDir) {
2340
- const filePath = import_node_path9.default.join(packageDir, "package.json");
2341
- 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"));
2342
2372
  }
2343
2373
  function loadConfig({
2344
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(
@@ -691,12 +694,8 @@ var MicrofrontendConfigIsomorphic = class {
691
694
  const skipValidation = opts?.skipValidation ?? [];
692
695
  const c = typeof config === "string" ? (0, import_jsonc_parser.parse)(config) : config;
693
696
  if (isMainConfig(c)) {
694
- if (!skipValidation.includes("paths")) {
695
- validateConfigPaths(c.applications);
696
- }
697
- if (!skipValidation.includes("defaultApplication")) {
698
- validateConfigDefaultApplication(c.applications);
699
- }
697
+ validateConfigPaths(c.applications);
698
+ validateConfigDefaultApplication(c.applications);
700
699
  if (!skipValidation.includes("deprecatedFields")) {
701
700
  validateDeprecatedFields(c);
702
701
  }