@vercel/microfrontends 0.12.1 → 0.14.0

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 (77) hide show
  1. package/README.md +3 -3
  2. package/dist/bin/cli.cjs +241 -176
  3. package/dist/config/client.d.ts +1 -1
  4. package/dist/config.cjs.map +1 -1
  5. package/dist/config.d.ts +1 -1
  6. package/dist/config.js.map +1 -1
  7. package/dist/{index-83133f2d.d.ts → index-bf67a461.d.ts} +3 -10
  8. package/dist/next/client.cjs +1 -1
  9. package/dist/next/client.cjs.map +1 -1
  10. package/dist/next/client.js +1 -1
  11. package/dist/next/client.js.map +1 -1
  12. package/dist/next/endpoints.cjs.map +1 -1
  13. package/dist/next/endpoints.d.ts +1 -1
  14. package/dist/next/endpoints.js.map +1 -1
  15. package/dist/next/middleware.cjs +0 -29
  16. package/dist/next/middleware.cjs.map +1 -1
  17. package/dist/next/middleware.js +0 -29
  18. package/dist/next/middleware.js.map +1 -1
  19. package/dist/{types-a995174e.d.ts → types-a29d224a.d.ts} +1 -7
  20. package/dist/{types-15b7f215.d.ts → types-cfe3308b.d.ts} +1 -1
  21. package/dist/types-fc30696d.d.ts +11 -0
  22. package/dist/utils/mfe-port.cjs +2704 -0
  23. package/dist/utils/mfe-port.cjs.map +1 -0
  24. package/dist/utils/mfe-port.d.ts +8 -0
  25. package/dist/utils/mfe-port.js +2669 -0
  26. package/dist/utils/mfe-port.js.map +1 -0
  27. package/dist/v2/config.cjs +0 -14
  28. package/dist/v2/config.cjs.map +1 -1
  29. package/dist/v2/config.d.ts +4 -3
  30. package/dist/v2/config.js +0 -14
  31. package/dist/v2/config.js.map +1 -1
  32. package/dist/v2/microfrontends/server.cjs +68 -54
  33. package/dist/v2/microfrontends/server.cjs.map +1 -1
  34. package/dist/v2/microfrontends/server.d.ts +6 -5
  35. package/dist/v2/microfrontends/server.js +65 -51
  36. package/dist/v2/microfrontends/server.js.map +1 -1
  37. package/dist/v2/microfrontends.cjs +0 -14
  38. package/dist/v2/microfrontends.cjs.map +1 -1
  39. package/dist/v2/microfrontends.d.ts +4 -3
  40. package/dist/v2/microfrontends.js +0 -14
  41. package/dist/v2/microfrontends.js.map +1 -1
  42. package/dist/v2/next/client.cjs +1 -1
  43. package/dist/v2/next/client.cjs.map +1 -1
  44. package/dist/v2/next/client.js +1 -1
  45. package/dist/v2/next/client.js.map +1 -1
  46. package/dist/v2/next/config.cjs +116 -65
  47. package/dist/v2/next/config.cjs.map +1 -1
  48. package/dist/v2/next/config.js +113 -62
  49. package/dist/v2/next/config.js.map +1 -1
  50. package/dist/v2/next/endpoints.cjs.map +1 -1
  51. package/dist/v2/next/endpoints.d.ts +13 -2
  52. package/dist/v2/next/endpoints.js.map +1 -1
  53. package/dist/v2/next/middleware.cjs +20 -59
  54. package/dist/v2/next/middleware.cjs.map +1 -1
  55. package/dist/v2/next/middleware.d.ts +7 -2
  56. package/dist/v2/next/middleware.js +20 -59
  57. package/dist/v2/next/middleware.js.map +1 -1
  58. package/dist/v2/next/testing.cjs +992 -0
  59. package/dist/v2/next/testing.cjs.map +1 -0
  60. package/dist/v2/next/testing.d.ts +55 -0
  61. package/dist/v2/next/testing.js +961 -0
  62. package/dist/v2/next/testing.js.map +1 -0
  63. package/dist/v2/overrides.d.ts +3 -3
  64. package/dist/v2/routing.cjs +19 -0
  65. package/dist/v2/routing.cjs.map +1 -0
  66. package/dist/v2/routing.d.ts +26 -0
  67. package/dist/v2/routing.js +1 -0
  68. package/dist/v2/routing.js.map +1 -0
  69. package/dist/v2/schema.cjs.map +1 -1
  70. package/dist/v2/schema.d.ts +1 -1
  71. package/dist/validation.cjs +0 -4
  72. package/dist/validation.cjs.map +1 -1
  73. package/dist/validation.d.ts +0 -6
  74. package/dist/validation.js +0 -4
  75. package/dist/validation.js.map +1 -1
  76. package/package.json +25 -3
  77. package/schema/schema-v2.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.12.1",
32
+ version: "0.14.0",
33
33
  private: false,
34
34
  description: "Defines configuration and utilities for micro-frontend development",
35
35
  repository: {
@@ -40,6 +40,7 @@ var package_default = {
40
40
  sideEffects: false,
41
41
  type: "module",
42
42
  bin: {
43
+ microfrontends: "./cli/index.cjs",
43
44
  "micro-frontends": "./cli/index.cjs"
44
45
  },
45
46
  exports: {
@@ -92,6 +93,10 @@ var package_default = {
92
93
  import: "./dist/v2/overrides.js",
93
94
  require: "./dist/v2/overrides.cjs"
94
95
  },
96
+ "./v2/routing": {
97
+ import: "./dist/v2/routing.js",
98
+ require: "./dist/v2/routing.cjs"
99
+ },
95
100
  "./v2/microfrontends/server": {
96
101
  import: "./dist/v2/microfrontends/server.js",
97
102
  require: "./dist/v2/microfrontends/server.cjs"
@@ -112,6 +117,10 @@ var package_default = {
112
117
  import: "./dist/v2/next/endpoints.js",
113
118
  require: "./dist/v2/next/endpoints.cjs"
114
119
  },
120
+ "./v2/next/testing": {
121
+ import: "./dist/v2/next/testing.js",
122
+ require: "./dist/v2/next/testing.cjs"
123
+ },
115
124
  "./next/client": {
116
125
  import: "./dist/next/client.js",
117
126
  require: "./dist/next/client.cjs"
@@ -119,73 +128,39 @@ var package_default = {
119
128
  "./v2/next/client": {
120
129
  import: "./dist/v2/next/client.js",
121
130
  require: "./dist/v2/next/client.cjs"
131
+ },
132
+ "./utils/mfe-port": {
133
+ import: "./dist/utils/mfe-port.js",
134
+ require: "./dist/utils/mfe-port.cjs"
122
135
  }
123
136
  },
124
137
  typesVersions: {
125
138
  "*": {
126
- validation: [
127
- "./dist/validation.d.ts"
128
- ],
129
- config: [
130
- "./dist/config.d.ts"
131
- ],
132
- "config/client": [
133
- "./dist/config/client.d.ts"
134
- ],
135
- "config/edge": [
136
- "./dist/config/edge.d.ts"
137
- ],
138
- overrides: [
139
- "./dist/overrides.d.ts"
140
- ],
141
- "next/config": [
142
- "./dist/next/config.d.ts"
143
- ],
144
- "next/middleware": [
145
- "./dist/next/middleware.d.ts"
146
- ],
147
- "next/endpoints": [
148
- "./dist/next/endpoints.d.ts"
149
- ],
150
- "next/testing": [
151
- "./dist/next/testing.d.ts"
152
- ],
153
- "v2/config": [
154
- "./dist/v2/config.d.ts"
155
- ],
156
- "v2/microfrontends": [
157
- "./dist/v2/microfrontends.d.ts"
158
- ],
159
- "v2/overrides": [
160
- "./dist/v2/overrides.d.ts"
161
- ],
162
- "v2/microfrontends/server": [
163
- "./dist/v2/microfrontends/server.d.ts"
164
- ],
165
- "v2/schema": [
166
- "./dist/v2/schema.d.ts"
167
- ],
168
- "v2/next/config": [
169
- "./dist/v2/next/config.d.ts"
170
- ],
171
- "v2/next/middleware": [
172
- "./dist/v2/next/middleware.d.ts"
173
- ],
174
- "v2/next/endpoints": [
175
- "./dist/v2/next/endpoints.d.ts"
176
- ],
177
- "next/client": [
178
- "./dist/next/client.d.ts"
179
- ],
180
- "v2/next/client": [
181
- "./dist/v2/next/client.d.ts"
182
- ]
139
+ validation: ["./dist/validation.d.ts"],
140
+ config: ["./dist/config.d.ts"],
141
+ "config/client": ["./dist/config/client.d.ts"],
142
+ "config/edge": ["./dist/config/edge.d.ts"],
143
+ overrides: ["./dist/overrides.d.ts"],
144
+ "next/config": ["./dist/next/config.d.ts"],
145
+ "next/middleware": ["./dist/next/middleware.d.ts"],
146
+ "next/endpoints": ["./dist/next/endpoints.d.ts"],
147
+ "next/testing": ["./dist/next/testing.d.ts"],
148
+ "v2/config": ["./dist/v2/config.d.ts"],
149
+ "v2/microfrontends": ["./dist/v2/microfrontends.d.ts"],
150
+ "v2/overrides": ["./dist/v2/overrides.d.ts"],
151
+ "v2/routing": ["./dist/v2/routing.d.ts"],
152
+ "v2/microfrontends/server": ["./dist/v2/microfrontends/server.d.ts"],
153
+ "v2/schema": ["./dist/v2/schema.d.ts"],
154
+ "v2/next/config": ["./dist/v2/next/config.d.ts"],
155
+ "v2/next/middleware": ["./dist/v2/next/middleware.d.ts"],
156
+ "v2/next/endpoints": ["./dist/v2/next/endpoints.d.ts"],
157
+ "v2/next/testing": ["./dist/v2/next/testing.d.ts"],
158
+ "next/client": ["./dist/next/client.d.ts"],
159
+ "v2/next/client": ["./dist/v2/next/client.d.ts"],
160
+ "utils/mfe-port": ["./dist/utils/mfe-port.d.ts"]
183
161
  }
184
162
  },
185
- files: [
186
- "dist",
187
- "schema"
188
- ],
163
+ files: ["dist", "schema"],
189
164
  scripts: {
190
165
  build: "tsup",
191
166
  postbuild: "pnpm generate:exports",
@@ -223,7 +198,7 @@ var package_default = {
223
198
  "@vercel-private/conformance": "^1.12.2-canary.0",
224
199
  jest: "^29.7.0",
225
200
  "jest-environment-jsdom": "29.2.2",
226
- next: "15.1.1-canary.0",
201
+ next: "15.2.0-canary.14",
227
202
  react: "19.0.0",
228
203
  "react-dom": "19.0.0",
229
204
  "ts-json-schema-generator": "^1.1.2",
@@ -233,7 +208,7 @@ var package_default = {
233
208
  webpack: "5"
234
209
  },
235
210
  peerDependencies: {
236
- next: "15.1.1-canary.0",
211
+ next: "15.2.0-canary.14",
237
212
  react: "19.0.0",
238
213
  "react-dom": "19.0.0"
239
214
  },
@@ -1132,8 +1107,8 @@ function validateMainPath(applicationConfigsById) {
1132
1107
  });
1133
1108
  }
1134
1109
  for (const { id: otherId, paths } of pathsWithApp) {
1135
- const isValid = paths.every((path6) => {
1136
- const matcher = (0, import_path_to_regexp.pathToRegexp)(path6);
1110
+ const isValid = paths.every((path7) => {
1111
+ const matcher = (0, import_path_to_regexp.pathToRegexp)(path7);
1137
1112
  return !matcher.test(defaultRoute);
1138
1113
  });
1139
1114
  if (!isValid) {
@@ -1145,8 +1120,8 @@ function validateMainPath(applicationConfigsById) {
1145
1120
  }
1146
1121
  } else {
1147
1122
  const allPaths = app.routing.matches.flatMap((match) => match.paths);
1148
- const isValid = allPaths.some((path6) => {
1149
- const matcher = (0, import_path_to_regexp.pathToRegexp)(path6);
1123
+ const isValid = allPaths.some((path7) => {
1124
+ const matcher = (0, import_path_to_regexp.pathToRegexp)(path7);
1150
1125
  return matcher.test(defaultRoute);
1151
1126
  });
1152
1127
  if (!isValid) {
@@ -1166,18 +1141,18 @@ var validatePaths = (applicationConfigsById) => {
1166
1141
  continue;
1167
1142
  }
1168
1143
  for (const pathMatch of app.routing.matches) {
1169
- for (const path6 of pathMatch.paths) {
1170
- const maybeError = validatePathExpression(path6);
1144
+ for (const path7 of pathMatch.paths) {
1145
+ const maybeError = validatePathExpression(path7);
1171
1146
  if (maybeError) {
1172
1147
  errors.push(maybeError);
1173
1148
  }
1174
- const existing = pathsByApplicationId.get(path6);
1149
+ const existing = pathsByApplicationId.get(path7);
1175
1150
  if (existing) {
1176
1151
  existing.applications.push(id);
1177
1152
  } else {
1178
- pathsByApplicationId.set(path6, {
1153
+ pathsByApplicationId.set(path7, {
1179
1154
  applications: [id],
1180
- matcher: (0, import_path_to_regexp.pathToRegexp)(path6),
1155
+ matcher: (0, import_path_to_regexp.pathToRegexp)(path7),
1181
1156
  applicationId: id
1182
1157
  });
1183
1158
  }
@@ -1185,10 +1160,10 @@ var validatePaths = (applicationConfigsById) => {
1185
1160
  }
1186
1161
  }
1187
1162
  const entries = Array.from(pathsByApplicationId.entries());
1188
- entries.forEach(([path6, { applications: ids, matcher, applicationId }]) => {
1163
+ entries.forEach(([path7, { applications: ids, matcher, applicationId }]) => {
1189
1164
  if (ids.length > 1) {
1190
1165
  errors.push(
1191
- `Duplicate path "${path6}" for applications "${ids.join(", ")}"`
1166
+ `Duplicate path "${path7}" for applications "${ids.join(", ")}"`
1192
1167
  );
1193
1168
  }
1194
1169
  entries.forEach(
@@ -1196,14 +1171,14 @@ var validatePaths = (applicationConfigsById) => {
1196
1171
  matchPath,
1197
1172
  { applications: matchIds, applicationId: matchApplicationId }
1198
1173
  ]) => {
1199
- if (path6 === matchPath) {
1174
+ if (path7 === matchPath) {
1200
1175
  return;
1201
1176
  }
1202
1177
  if (applicationId === matchApplicationId) {
1203
1178
  return;
1204
1179
  }
1205
1180
  if (matcher.test(matchPath)) {
1206
- const source = `"${path6}" of application${ids.length > 0 ? "s" : ""} ${ids.join(", ")}`;
1181
+ const source = `"${path7}" of application${ids.length > 0 ? "s" : ""} ${ids.join(", ")}`;
1207
1182
  const destination = `"${matchPath}" of application${matchIds.length > 0 ? "s" : ""} ${matchIds.join(", ")}`;
1208
1183
  errors.push(
1209
1184
  `Overlapping path detected between ${source} and ${destination}`
@@ -1220,25 +1195,25 @@ var validatePaths = (applicationConfigsById) => {
1220
1195
  }
1221
1196
  };
1222
1197
  var PATH_DEFAULT_PATTERN = "[^\\/#\\?]+?";
1223
- function validatePathExpression(path6) {
1224
- const tokens = (0, import_path_to_regexp.parse)(path6);
1198
+ function validatePathExpression(path7) {
1199
+ const tokens = (0, import_path_to_regexp.parse)(path7);
1225
1200
  for (let i = 0; i < tokens.length; i++) {
1226
1201
  const token = tokens[i];
1227
1202
  if (token === void 0) {
1228
- return `token ${i} in ${path6} is undefined, this shouldn't happen`;
1203
+ return `token ${i} in ${path7} is undefined, this shouldn't happen`;
1229
1204
  }
1230
1205
  if (typeof token !== "string") {
1231
1206
  if (token.pattern !== PATH_DEFAULT_PATTERN) {
1232
- return `Path ${path6} cannot use a regular expression wildcard`;
1207
+ return `Path ${path7} cannot use a regular expression wildcard`;
1233
1208
  }
1234
1209
  if (token.prefix !== "/") {
1235
- return `Wildcard :${token.name} must be immediately after a / in ${path6}`;
1210
+ return `Wildcard :${token.name} must be immediately after a / in ${path7}`;
1236
1211
  }
1237
1212
  if (token.suffix) {
1238
1213
  return `Wildcard suffix on :${token.name} is not allowed. Suffixes are not supported`;
1239
1214
  }
1240
1215
  if (token.modifier && i !== tokens.length - 1) {
1241
- return `Modifier ${token.modifier} is not allowed on wildcard :${token.name} in ${path6}. Modifiers are only allowed in the last path component`;
1216
+ return `Modifier ${token.modifier} is not allowed on wildcard :${token.name} in ${path7}. Modifiers are only allowed in the last path component`;
1242
1217
  }
1243
1218
  }
1244
1219
  }
@@ -1514,22 +1489,22 @@ var validateConfigPaths = (applicationConfigsById) => {
1514
1489
  continue;
1515
1490
  }
1516
1491
  for (const pathMatch of app.routing) {
1517
- for (const path6 of pathMatch.paths) {
1518
- const tokens = (0, import_path_to_regexp2.parse)(path6);
1492
+ for (const path7 of pathMatch.paths) {
1493
+ const tokens = (0, import_path_to_regexp2.parse)(path7);
1519
1494
  for (const token of tokens.slice(0, -1)) {
1520
1495
  if (typeof token !== "string") {
1521
1496
  errors.push(
1522
- `Path ${path6} may only have a :wildcard in the last path component`
1497
+ `Path ${path7} may only have a :wildcard in the last path component`
1523
1498
  );
1524
1499
  }
1525
1500
  }
1526
- const existing = pathsByApplicationId.get(path6);
1501
+ const existing = pathsByApplicationId.get(path7);
1527
1502
  if (existing) {
1528
1503
  existing.applications.push(id);
1529
1504
  } else {
1530
- pathsByApplicationId.set(path6, {
1505
+ pathsByApplicationId.set(path7, {
1531
1506
  applications: [id],
1532
- matcher: (0, import_path_to_regexp2.pathToRegexp)(path6),
1507
+ matcher: (0, import_path_to_regexp2.pathToRegexp)(path7),
1533
1508
  applicationId: id
1534
1509
  });
1535
1510
  }
@@ -1537,10 +1512,10 @@ var validateConfigPaths = (applicationConfigsById) => {
1537
1512
  }
1538
1513
  }
1539
1514
  const entries = Array.from(pathsByApplicationId.entries());
1540
- entries.forEach(([path6, { applications: ids, matcher, applicationId }]) => {
1515
+ entries.forEach(([path7, { applications: ids, matcher, applicationId }]) => {
1541
1516
  if (ids.length > 1) {
1542
1517
  errors.push(
1543
- `Duplicate path "${path6}" for applications "${ids.join(", ")}"`
1518
+ `Duplicate path "${path7}" for applications "${ids.join(", ")}"`
1544
1519
  );
1545
1520
  }
1546
1521
  entries.forEach(
@@ -1548,14 +1523,14 @@ var validateConfigPaths = (applicationConfigsById) => {
1548
1523
  matchPath,
1549
1524
  { applications: matchIds, applicationId: matchApplicationId }
1550
1525
  ]) => {
1551
- if (path6 === matchPath) {
1526
+ if (path7 === matchPath) {
1552
1527
  return;
1553
1528
  }
1554
1529
  if (applicationId === matchApplicationId) {
1555
1530
  return;
1556
1531
  }
1557
1532
  if (matcher.test(matchPath)) {
1558
- const source = `"${path6}" of application${ids.length > 0 ? "s" : ""} ${ids.join(", ")}`;
1533
+ const source = `"${path7}" of application${ids.length > 0 ? "s" : ""} ${ids.join(", ")}`;
1559
1534
  const destination = `"${matchPath}" of application${matchIds.length > 0 ? "s" : ""} ${matchIds.join(", ")}`;
1560
1535
  errors.push(
1561
1536
  `Overlapping path detected between ${source} and ${destination}`
@@ -1618,19 +1593,6 @@ var validateConfigDefaultApplication = (applicationConfigsById) => {
1618
1593
  );
1619
1594
  }
1620
1595
  };
1621
- var validateConfigOptions = (options) => {
1622
- var _a;
1623
- if ((_a = options == null ? void 0 : options.vercel) == null ? void 0 : _a.previewDeploymentSuffix) {
1624
- if (!/^[a-zA-Z]{2,}\.[a-zA-Z]{2,}$/.test(
1625
- options.vercel.previewDeploymentSuffix
1626
- )) {
1627
- throw new MicrofrontendError2(
1628
- `Invalid preview deployment suffix: ${options.vercel.previewDeploymentSuffix}. Should have be formatted like "vercel.app".`,
1629
- { type: "config", subtype: "invalid_preview_deployment_suffix" }
1630
- );
1631
- }
1632
- }
1633
- };
1634
1596
 
1635
1597
  // src/config-v2/microfrontends-config/isomorphic/utils/generate-asset-prefix.ts
1636
1598
  var PREFIX = "vc-ap";
@@ -1833,21 +1795,21 @@ var MicrofrontendConfigClient = class {
1833
1795
  isEqual(other) {
1834
1796
  return JSON.stringify(this.applications) === JSON.stringify(other.applications);
1835
1797
  }
1836
- getApplicationNameForPath(path6) {
1837
- if (!path6.startsWith("/")) {
1798
+ getApplicationNameForPath(path7) {
1799
+ if (!path7.startsWith("/")) {
1838
1800
  throw new Error(`Path must start with a /`);
1839
1801
  }
1840
- if (this.pathCache[path6]) {
1841
- return this.pathCache[path6];
1802
+ if (this.pathCache[path7]) {
1803
+ return this.pathCache[path7];
1842
1804
  }
1843
- const pathname = new URL(path6, "https://example.com").pathname;
1805
+ const pathname = new URL(path7, "https://example.com").pathname;
1844
1806
  for (const [name, application] of Object.entries(this.applications)) {
1845
1807
  if (application.routing) {
1846
1808
  for (const group of application.routing) {
1847
1809
  for (const childPath of group.paths) {
1848
1810
  const regexp = (0, import_path_to_regexp3.pathToRegexp)(childPath);
1849
1811
  if (regexp.test(pathname)) {
1850
- this.pathCache[path6] = name;
1812
+ this.pathCache[path7] = name;
1851
1813
  return name;
1852
1814
  }
1853
1815
  }
@@ -1860,7 +1822,7 @@ var MicrofrontendConfigClient = class {
1860
1822
  if (!defaultApplication) {
1861
1823
  return null;
1862
1824
  }
1863
- this.pathCache[path6] = defaultApplication[0];
1825
+ this.pathCache[path7] = defaultApplication[0];
1864
1826
  return defaultApplication[0];
1865
1827
  }
1866
1828
  serialize() {
@@ -1969,7 +1931,6 @@ var MicrofrontendConfigIsomorphic = class {
1969
1931
  validateConfigPaths(c.applications);
1970
1932
  validateConfigDefaultApplication(c.applications);
1971
1933
  }
1972
- validateConfigOptions(c.options);
1973
1934
  return c;
1974
1935
  }
1975
1936
  static fromEnv({
@@ -2133,8 +2094,8 @@ function isMainConfig2(c) {
2133
2094
  }
2134
2095
 
2135
2096
  // src/config-v2/microfrontends/server/index.ts
2136
- var import_node_fs8 = __toESM(require("fs"), 1);
2137
- var import_node_path9 = require("path");
2097
+ var import_node_fs9 = __toESM(require("fs"), 1);
2098
+ var import_node_path10 = require("path");
2138
2099
 
2139
2100
  // src/config-v2/microfrontends-config/isomorphic/child.ts
2140
2101
  var MicrofrontendChildConfig = class extends MicrofrontendConfigIsomorphic {
@@ -2254,29 +2215,39 @@ function findPackagePath(opts) {
2254
2215
  // src/config-v2/microfrontends/utils/find-default-package.ts
2255
2216
  var import_node_path6 = require("path");
2256
2217
  var import_node_fs5 = require("fs");
2218
+ var import_jsonc_parser3 = require("jsonc-parser");
2257
2219
  var import_fast_glob2 = __toESM(require("fast-glob"), 1);
2220
+
2221
+ // src/config-v2/constants.ts
2222
+ var CONFIGURATION_FILENAMES = [
2223
+ "microfrontends.jsonc",
2224
+ "microfrontends.json"
2225
+ ];
2226
+
2227
+ // src/config-v2/microfrontends/utils/find-default-package.ts
2258
2228
  var configCache2 = {};
2259
2229
  function findDefaultMicrofrontendsPackages({
2260
2230
  repositoryRoot,
2261
2231
  applicationName
2262
2232
  }) {
2263
2233
  try {
2264
- const microfrontendsJsonPaths = import_fast_glob2.default.globSync("**/microfrontends.json", {
2265
- cwd: repositoryRoot,
2266
- absolute: true,
2267
- onlyFiles: true,
2268
- followSymbolicLinks: false,
2269
- ignore: ["**/node_modules/**", "**/.git/**"]
2270
- });
2234
+ const microfrontendsJsonPaths = import_fast_glob2.default.globSync(
2235
+ `**/{${CONFIGURATION_FILENAMES.join(",")}}`,
2236
+ {
2237
+ cwd: repositoryRoot,
2238
+ absolute: true,
2239
+ onlyFiles: true,
2240
+ followSymbolicLinks: false,
2241
+ ignore: ["**/node_modules/**", "**/.git/**"]
2242
+ }
2243
+ );
2271
2244
  const matchingPaths = [];
2272
2245
  for (const microfrontendsJsonPath of microfrontendsJsonPaths) {
2273
2246
  const microfrontendsJsonContent = (0, import_node_fs5.readFileSync)(
2274
2247
  microfrontendsJsonPath,
2275
2248
  "utf-8"
2276
2249
  );
2277
- const microfrontendsJson = JSON.parse(
2278
- microfrontendsJsonContent
2279
- );
2250
+ const microfrontendsJson = (0, import_jsonc_parser3.parse)(microfrontendsJsonContent);
2280
2251
  if (isMainConfig(microfrontendsJson) && microfrontendsJson.applications[applicationName]) {
2281
2252
  matchingPaths.push(microfrontendsJsonPath);
2282
2253
  }
@@ -2306,7 +2277,7 @@ function findDefaultMicrofrontendsPackage(opts) {
2306
2277
  const result = findDefaultMicrofrontendsPackages(opts);
2307
2278
  if (!result) {
2308
2279
  throw new Error(
2309
- `Error trying to resolve the main microfrontends.json configuration`
2280
+ `Error trying to resolve the main microfrontends configuration`
2310
2281
  );
2311
2282
  }
2312
2283
  configCache2[cacheKey] = result;
@@ -2358,8 +2329,21 @@ function findPackageRoot(startDir) {
2358
2329
  );
2359
2330
  }
2360
2331
 
2332
+ // src/config-v2/microfrontends/utils/find-config.ts
2333
+ var import_node_fs8 = __toESM(require("fs"), 1);
2334
+ var import_node_path9 = require("path");
2335
+ function findConfig({ dir }) {
2336
+ for (const filename of CONFIGURATION_FILENAMES) {
2337
+ const maybeConfig = (0, import_node_path9.join)(dir, filename);
2338
+ if (import_node_fs8.default.existsSync(maybeConfig)) {
2339
+ return maybeConfig;
2340
+ }
2341
+ }
2342
+ return null;
2343
+ }
2344
+
2361
2345
  // src/config-v2/microfrontends/server/validation.ts
2362
- var import_jsonc_parser3 = require("jsonc-parser");
2346
+ var import_jsonc_parser4 = require("jsonc-parser");
2363
2347
  var import_ajv2 = require("ajv");
2364
2348
 
2365
2349
  // schema/schema-v2.json
@@ -2420,10 +2404,6 @@ var schema_v2_default = {
2420
2404
  VercelOptions: {
2421
2405
  type: "object",
2422
2406
  properties: {
2423
- previewDeploymentSuffix: {
2424
- type: "string",
2425
- 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`."
2426
- },
2427
2407
  teamSlug: {
2428
2408
  type: "string",
2429
2409
  description: "Team slug for the Vercel team"
@@ -2617,7 +2597,7 @@ var SCHEMA2 = schema_v2_default;
2617
2597
 
2618
2598
  // src/config-v2/microfrontends/server/validation.ts
2619
2599
  function validateSchema2(configString) {
2620
- const parsedConfig = (0, import_jsonc_parser3.parse)(configString);
2600
+ const parsedConfig = (0, import_jsonc_parser4.parse)(configString);
2621
2601
  const ajv = new import_ajv2.Ajv();
2622
2602
  const validate = ajv.compile(SCHEMA2);
2623
2603
  const isValid = validate(parsedConfig);
@@ -2639,8 +2619,8 @@ var MicrofrontendsServer = class extends Microfrontends {
2639
2619
  pretty: true
2640
2620
  }) {
2641
2621
  const outputPath = getOutputFilePath();
2642
- import_node_fs8.default.mkdirSync((0, import_node_path9.dirname)(outputPath), { recursive: true });
2643
- import_node_fs8.default.writeFileSync(
2622
+ import_node_fs9.default.mkdirSync((0, import_node_path10.dirname)(outputPath), { recursive: true });
2623
+ import_node_fs9.default.writeFileSync(
2644
2624
  outputPath,
2645
2625
  JSON.stringify(
2646
2626
  this.config.toSchemaJson(),
@@ -2703,8 +2683,8 @@ var MicrofrontendsServer = class extends Microfrontends {
2703
2683
  return config;
2704
2684
  }
2705
2685
  /**
2706
- * Looks up the configuration by inferring the package root and looking for a microfrontends.json file. If a file is not found,
2707
- * it will look for a package in the repository with a microfrontends.json file that contains the current application
2686
+ * Looks up the configuration by inferring the package root and looking for a microfrontends config file. If a file is not found,
2687
+ * it will look for a package in the repository with a microfrontends file that contains the current application
2708
2688
  * and use that configuration.
2709
2689
  *
2710
2690
  * This can return either a Child or Main configuration.
@@ -2726,16 +2706,16 @@ var MicrofrontendsServer = class extends Microfrontends {
2726
2706
  }
2727
2707
  try {
2728
2708
  const packageRoot = findPackageRoot(directory);
2729
- const packageJsonPath = (0, import_node_path9.join)(packageRoot, "package.json");
2709
+ const packageJsonPath = (0, import_node_path10.join)(packageRoot, "package.json");
2730
2710
  const packageJson = JSON.parse(
2731
- import_node_fs8.default.readFileSync(packageJsonPath, "utf-8")
2711
+ import_node_fs9.default.readFileSync(packageJsonPath, "utf-8")
2732
2712
  );
2733
2713
  if (!packageJson.name) {
2734
2714
  throw new Error(`No name found in package.json at ${packageJsonPath}`);
2735
2715
  }
2736
2716
  const configMeta = meta ?? { fromApp: packageJson.name };
2737
- const maybeConfig = (0, import_node_path9.join)(packageRoot, "microfrontends.json");
2738
- if (import_node_fs8.default.existsSync(maybeConfig)) {
2717
+ const maybeConfig = findConfig({ dir: packageRoot });
2718
+ if (maybeConfig) {
2739
2719
  return MicrofrontendsServer.fromFile({
2740
2720
  filePath: maybeConfig,
2741
2721
  cookies,
@@ -2750,12 +2730,15 @@ var MicrofrontendsServer = class extends Microfrontends {
2750
2730
  repositoryRoot,
2751
2731
  applicationName: packageJson.name
2752
2732
  });
2753
- return MicrofrontendsServer.fromFile({
2754
- filePath: (0, import_node_path9.join)(defaultPackage, "microfrontends.json"),
2755
- cookies,
2756
- meta: configMeta,
2757
- options
2758
- });
2733
+ const maybeConfigFromDefault = findConfig({ dir: defaultPackage });
2734
+ if (maybeConfigFromDefault) {
2735
+ return MicrofrontendsServer.fromFile({
2736
+ filePath: maybeConfigFromDefault,
2737
+ cookies,
2738
+ meta: configMeta,
2739
+ options
2740
+ });
2741
+ }
2759
2742
  }
2760
2743
  throw new Error("Unable to infer");
2761
2744
  } catch (e) {
@@ -2775,7 +2758,7 @@ var MicrofrontendsServer = class extends Microfrontends {
2775
2758
  options
2776
2759
  }) {
2777
2760
  try {
2778
- const configJson = import_node_fs8.default.readFileSync(filePath, "utf-8");
2761
+ const configJson = import_node_fs9.default.readFileSync(filePath, "utf-8");
2779
2762
  const config = MicrofrontendsServer.validate(configJson);
2780
2763
  if (!isMainConfig(config) && (options == null ? void 0 : options.resolveMainConfig)) {
2781
2764
  const repositoryRoot = findRepositoryRoot();
@@ -2791,9 +2774,15 @@ var MicrofrontendsServer = class extends Microfrontends {
2791
2774
  { type: "config", subtype: "not_found" }
2792
2775
  );
2793
2776
  }
2794
- const mainConfigPath = (0, import_node_path9.join)(packagePath, "microfrontends.json");
2777
+ const maybeConfig = findConfig({ dir: packagePath });
2778
+ if (!maybeConfig) {
2779
+ throw new MicrofrontendError2(
2780
+ `Could not find microfrontends configuration in ${packagePath}`,
2781
+ { type: "config", subtype: "not_found" }
2782
+ );
2783
+ }
2795
2784
  return MicrofrontendsServer.fromMainConfigFile({
2796
- filePath: mainConfigPath,
2785
+ filePath: maybeConfig,
2797
2786
  overrides: cookies ? parseOverrides(cookies) : void 0
2798
2787
  });
2799
2788
  }
@@ -2817,7 +2806,7 @@ var MicrofrontendsServer = class extends Microfrontends {
2817
2806
  overrides
2818
2807
  }) {
2819
2808
  try {
2820
- const config = import_node_fs8.default.readFileSync(filePath, "utf-8");
2809
+ const config = import_node_fs9.default.readFileSync(filePath, "utf-8");
2821
2810
  const validatedConfig = MicrofrontendsServer.validate(config);
2822
2811
  if (!isMainConfig(validatedConfig)) {
2823
2812
  throw new MicrofrontendError2(
@@ -2959,7 +2948,7 @@ var LocalProxy = class {
2959
2948
  const isJWTRedirect = url.searchParams.has("_vercel_jwt");
2960
2949
  const defaultHost = this.getDefaultHost(config);
2961
2950
  let hostname = null;
2962
- let path6 = request2.url;
2951
+ let path7 = request2.url;
2963
2952
  if (isAuthRedirect) {
2964
2953
  hostname = url.searchParams.get("_host_override");
2965
2954
  }
@@ -2969,12 +2958,12 @@ var LocalProxy = class {
2969
2958
  if (isJWTRedirect) {
2970
2959
  hostname = url.searchParams.get("_host_override");
2971
2960
  url.searchParams.delete("_host_override");
2972
- path6 = `${url.pathname}${url.search}`;
2961
+ path7 = `${url.pathname}${url.search}`;
2973
2962
  }
2974
2963
  if (!hostname) {
2975
2964
  return void 0;
2976
2965
  }
2977
- return { ...defaultHost, path: path6, hostname, protocol: "https", port: 443 };
2966
+ return { ...defaultHost, path: path7, hostname, protocol: "https", port: 443 };
2978
2967
  }
2979
2968
  getConfigWithOverrides(cookies) {
2980
2969
  if (isV2Config(this.config)) {
@@ -3005,19 +2994,19 @@ var LocalProxy = class {
3005
2994
  getTarget(request2) {
3006
2995
  const cookies = (0, import_cookie.parse)(request2.headers.cookie || "");
3007
2996
  const config = this.getConfigWithOverrides(cookies);
3008
- const path6 = request2.url;
3009
- if (!path6) {
2997
+ const path7 = request2.url;
2998
+ if (!path7) {
3010
2999
  return this.getDefaultHost(config);
3011
3000
  }
3012
3001
  const authTarget = this.getAuthTarget(request2, config);
3013
3002
  if (authTarget) {
3014
3003
  return authTarget;
3015
3004
  }
3016
- const url = new URL(`http://example.com${path6}`);
3005
+ const url = new URL(`http://example.com${path7}`);
3017
3006
  const pathname = url.pathname;
3018
3007
  if (isV2Config(config)) {
3019
3008
  const target = this.findMatchingApplicationV2(
3020
- path6,
3009
+ path7,
3021
3010
  pathname,
3022
3011
  config.getChildApplications()
3023
3012
  );
@@ -3025,7 +3014,7 @@ var LocalProxy = class {
3025
3014
  return target;
3026
3015
  } else {
3027
3016
  const target = this.findMatchingApplicationV1(
3028
- path6,
3017
+ path7,
3029
3018
  pathname,
3030
3019
  config.getAllApplications()
3031
3020
  );
@@ -3034,11 +3023,11 @@ var LocalProxy = class {
3034
3023
  }
3035
3024
  const defaultHost = this.getDefaultHost(config);
3036
3025
  mfeDebug(
3037
- `no matching routes, routing ${path6} to default application: ${JSON.stringify(defaultHost)}`
3026
+ `no matching routes, routing ${path7} to default application: ${JSON.stringify(defaultHost)}`
3038
3027
  );
3039
- return { path: path6, ...defaultHost };
3028
+ return { path: path7, ...defaultHost };
3040
3029
  }
3041
- findMatchingApplicationV1(path6, pathname, applications) {
3030
+ findMatchingApplicationV1(path7, pathname, applications) {
3042
3031
  for (const application of Object.values(applications)) {
3043
3032
  if (application.routing) {
3044
3033
  for (const group of application.routing.matches) {
@@ -3047,9 +3036,9 @@ var LocalProxy = class {
3047
3036
  if (regexp.test(pathname)) {
3048
3037
  const target = this.getApplicationTarget(application);
3049
3038
  mfeDebug(
3050
- `routing ${path6} to '${target.application}' at ${target.hostname}`
3039
+ `routing ${path7} to '${target.application}' at ${target.hostname}`
3051
3040
  );
3052
- return { path: path6, ...target };
3041
+ return { path: path7, ...target };
3053
3042
  }
3054
3043
  }
3055
3044
  if (application.routing.assetPrefix) {
@@ -3059,9 +3048,9 @@ var LocalProxy = class {
3059
3048
  if (pattern.test(pathname)) {
3060
3049
  const target = this.getApplicationTarget(application);
3061
3050
  mfeDebug(
3062
- `routing ${path6} to '${target.application}' at ${target.hostname}`
3051
+ `routing ${path7} to '${target.application}' at ${target.hostname}`
3063
3052
  );
3064
- return { path: path6, ...target };
3053
+ return { path: path7, ...target };
3065
3054
  }
3066
3055
  }
3067
3056
  }
@@ -3069,7 +3058,7 @@ var LocalProxy = class {
3069
3058
  }
3070
3059
  return null;
3071
3060
  }
3072
- findMatchingApplicationV2(path6, pathname, applications) {
3061
+ findMatchingApplicationV2(path7, pathname, applications) {
3073
3062
  for (const application of Object.values(applications)) {
3074
3063
  for (const group of application.routing) {
3075
3064
  for (const childPath of group.paths) {
@@ -3077,9 +3066,9 @@ var LocalProxy = class {
3077
3066
  if (regexp.test(pathname)) {
3078
3067
  const target = this.getApplicationTarget(application);
3079
3068
  mfeDebug(
3080
- `routing ${path6} to '${target.application}' at ${target.hostname}`
3069
+ `routing ${path7} to '${target.application}' at ${target.hostname}`
3081
3070
  );
3082
- return { path: path6, ...target };
3071
+ return { path: path7, ...target };
3083
3072
  }
3084
3073
  }
3085
3074
  }
@@ -3088,14 +3077,14 @@ var LocalProxy = class {
3088
3077
  }
3089
3078
  // Handles requests that return data from the local proxy itself.
3090
3079
  // Returns true if the request was handled, false otherwise.
3091
- handleProxyInfoRequest(path6, res) {
3092
- if (!path6) {
3080
+ handleProxyInfoRequest(path7, res) {
3081
+ if (!path7) {
3093
3082
  return false;
3094
3083
  }
3095
- const url = new URL(`http://example.comf${path6}`);
3084
+ const url = new URL(`http://example.comf${path7}`);
3096
3085
  const pathname = url.pathname;
3097
3086
  switch (pathname) {
3098
- case "/.well-known/vercel/microfrontend-routing": {
3087
+ case "/.well-known/vercel/microfrontends/routing": {
3099
3088
  res.writeHead(200, {
3100
3089
  "Content-Type": "application/json"
3101
3090
  });
@@ -3120,10 +3109,10 @@ var LocalProxy = class {
3120
3109
  }
3121
3110
  const target = this.getTarget(req);
3122
3111
  if (target.protocol === "https") {
3123
- const { hostname, port, path: path6 } = target;
3112
+ const { hostname, port, path: path7 } = target;
3124
3113
  const requestOptions = {
3125
3114
  hostname,
3126
- path: path6,
3115
+ path: path7,
3127
3116
  method: req.method,
3128
3117
  headers: {
3129
3118
  ...req.headers,
@@ -3151,7 +3140,7 @@ var LocalProxy = class {
3151
3140
  console.error("Proxy request error: ", err);
3152
3141
  res.writeHead(500, { "Content-Type": "text/plain" });
3153
3142
  res.end(
3154
- `Error proxying request for ${target.application} to ${hostname}:${port}${path6}`
3143
+ `Error proxying request for ${target.application} to ${hostname}:${port}${path7}`
3155
3144
  );
3156
3145
  });
3157
3146
  } else {
@@ -3178,6 +3167,79 @@ var LocalProxy = class {
3178
3167
  }
3179
3168
  };
3180
3169
 
3170
+ // src/bin/port.ts
3171
+ var import_node_process = require("process");
3172
+
3173
+ // src/utils/mfe-port.ts
3174
+ var import_node_path11 = __toESM(require("path"), 1);
3175
+ var import_node_fs10 = __toESM(require("fs"), 1);
3176
+ function mfePort(packageDir) {
3177
+ const { name: appName, version } = getPackageJson(packageDir);
3178
+ const result = loadV2({ packageDir, appName }) || loadV1({ packageDir, appName });
3179
+ if (!result) {
3180
+ throw new MicrofrontendError2(
3181
+ `Unable to determine configured port for ${appName}`,
3182
+ { type: "config", subtype: "not_found" }
3183
+ );
3184
+ }
3185
+ const { port } = result;
3186
+ return {
3187
+ name: appName,
3188
+ version,
3189
+ port
3190
+ };
3191
+ }
3192
+ function getPackageJson(packageDir) {
3193
+ const filePath = import_node_path11.default.join(packageDir, "package.json");
3194
+ return JSON.parse(import_node_fs10.default.readFileSync(filePath, "utf-8"));
3195
+ }
3196
+ function loadV2({
3197
+ packageDir,
3198
+ appName
3199
+ }) {
3200
+ let config;
3201
+ try {
3202
+ config = MicrofrontendsServer.infer({
3203
+ directory: packageDir,
3204
+ meta: { fromApp: appName },
3205
+ options: { resolveMainConfig: true }
3206
+ });
3207
+ } catch (e) {
3208
+ return void 0;
3209
+ }
3210
+ const app = config.config.getApplication(appName);
3211
+ const port = app.development.local.port;
3212
+ return { port };
3213
+ }
3214
+ function loadV1({
3215
+ packageDir,
3216
+ appName
3217
+ }) {
3218
+ const filePath = import_node_path11.default.join(packageDir, "micro-frontends.jsonc");
3219
+ let config;
3220
+ try {
3221
+ config = MicrofrontendConfig.fromFile({ filePath });
3222
+ } catch (e) {
3223
+ return void 0;
3224
+ }
3225
+ const zone = config.getZone(appName);
3226
+ const port = zone.development.local.port;
3227
+ return { port };
3228
+ }
3229
+
3230
+ // src/bin/port.ts
3231
+ function displayPort() {
3232
+ const portInfo = mfePort((0, import_node_process.cwd)());
3233
+ header(portInfo);
3234
+ console.log(portInfo.port);
3235
+ }
3236
+ function header({ name, version, port }) {
3237
+ console.error(`
3238
+ \u25B2 ${name}@${version}
3239
+ \xB7 setting port to ${port}
3240
+ `);
3241
+ }
3242
+
3181
3243
  // src/bin/index.ts
3182
3244
  function main() {
3183
3245
  const program = new import_commander.Command();
@@ -3195,6 +3257,9 @@ function main() {
3195
3257
  });
3196
3258
  localProxy.startServer();
3197
3259
  });
3260
+ program.command("port").description("Prints development port").action(() => {
3261
+ displayPort();
3262
+ });
3198
3263
  program.parse(process.argv);
3199
3264
  }
3200
3265
  main();