@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
@@ -1,6 +1,6 @@
1
1
  // src/config/microfrontends/server/index.ts
2
- import fs5 from "node:fs";
3
- import { dirname as dirname3, join as join2 } from "node:path";
2
+ import fs6 from "node:fs";
3
+ import { dirname as dirname3 } from "node:path";
4
4
 
5
5
  // src/config/overrides/constants.ts
6
6
  var OVERRIDES_COOKIE_PREFIX = "vercel-micro-frontends-override";
@@ -183,21 +183,21 @@ var MicrofrontendConfigClient = class {
183
183
  isEqual(other) {
184
184
  return JSON.stringify(this.applications) === JSON.stringify(other.applications);
185
185
  }
186
- getApplicationNameForPath(path5) {
187
- if (!path5.startsWith("/")) {
186
+ getApplicationNameForPath(path6) {
187
+ if (!path6.startsWith("/")) {
188
188
  throw new Error(`Path must start with a /`);
189
189
  }
190
- if (this.pathCache[path5]) {
191
- return this.pathCache[path5];
190
+ if (this.pathCache[path6]) {
191
+ return this.pathCache[path6];
192
192
  }
193
- const pathname = new URL(path5, "https://example.com").pathname;
193
+ const pathname = new URL(path6, "https://example.com").pathname;
194
194
  for (const [name, application] of Object.entries(this.applications)) {
195
195
  if (application.routing) {
196
196
  for (const group of application.routing) {
197
197
  for (const childPath of group.paths) {
198
198
  const regexp = pathToRegexp(childPath);
199
199
  if (regexp.test(pathname)) {
200
- this.pathCache[path5] = name;
200
+ this.pathCache[path6] = name;
201
201
  return name;
202
202
  }
203
203
  }
@@ -210,7 +210,7 @@ var MicrofrontendConfigClient = class {
210
210
  if (!defaultApplication) {
211
211
  return null;
212
212
  }
213
- this.pathCache[path5] = defaultApplication[0];
213
+ this.pathCache[path6] = defaultApplication[0];
214
214
  return defaultApplication[0];
215
215
  }
216
216
  serialize() {
@@ -232,18 +232,18 @@ var validateConfigPaths = (applicationConfigsById) => {
232
232
  }
233
233
  const childApp = app;
234
234
  for (const pathMatch of childApp.routing) {
235
- for (const path5 of pathMatch.paths) {
236
- const maybeError = validatePathExpression(path5);
235
+ for (const path6 of pathMatch.paths) {
236
+ const maybeError = validatePathExpression(path6);
237
237
  if (maybeError) {
238
238
  errors.push(maybeError);
239
239
  } else {
240
- const existing = pathsByApplicationId.get(path5);
240
+ const existing = pathsByApplicationId.get(path6);
241
241
  if (existing) {
242
242
  existing.applications.push(id);
243
243
  } else {
244
- pathsByApplicationId.set(path5, {
244
+ pathsByApplicationId.set(path6, {
245
245
  applications: [id],
246
- matcher: pathToRegexp2(path5),
246
+ matcher: pathToRegexp2(path6),
247
247
  applicationId: id
248
248
  });
249
249
  }
@@ -252,24 +252,24 @@ var validateConfigPaths = (applicationConfigsById) => {
252
252
  }
253
253
  }
254
254
  const entries = Array.from(pathsByApplicationId.entries());
255
- for (const [path5, { applications: ids, matcher, applicationId }] of entries) {
255
+ for (const [path6, { applications: ids, matcher, applicationId }] of entries) {
256
256
  if (ids.length > 1) {
257
257
  errors.push(
258
- `Duplicate path "${path5}" for applications "${ids.join(", ")}"`
258
+ `Duplicate path "${path6}" for applications "${ids.join(", ")}"`
259
259
  );
260
260
  }
261
261
  for (const [
262
262
  matchPath,
263
263
  { applications: matchIds, applicationId: matchApplicationId }
264
264
  ] of entries) {
265
- if (path5 === matchPath) {
265
+ if (path6 === matchPath) {
266
266
  continue;
267
267
  }
268
268
  if (applicationId === matchApplicationId) {
269
269
  continue;
270
270
  }
271
271
  if (matcher.test(matchPath)) {
272
- const source = `"${path5}" of application${ids.length > 0 ? "s" : ""} ${ids.join(", ")}`;
272
+ const source = `"${path6}" of application${ids.length > 0 ? "s" : ""} ${ids.join(", ")}`;
273
273
  const destination = `"${matchPath}" of application${matchIds.length > 0 ? "s" : ""} ${matchIds.join(", ")}`;
274
274
  errors.push(
275
275
  `Overlapping path detected between ${source} and ${destination}`
@@ -285,39 +285,42 @@ var validateConfigPaths = (applicationConfigsById) => {
285
285
  }
286
286
  };
287
287
  var PATH_DEFAULT_PATTERN = "[^\\/#\\?]+?";
288
- function validatePathExpression(path5) {
288
+ function validatePathExpression(path6) {
289
289
  try {
290
- const tokens = parsePathRegexp(path5);
291
- if (/(?<!\\)\{/.test(path5)) {
292
- return `Optional paths are not supported: ${path5}`;
290
+ const tokens = parsePathRegexp(path6);
291
+ if (/(?<!\\)\{/.test(path6)) {
292
+ return `Optional paths are not supported: ${path6}`;
293
293
  }
294
- if (/(?<!\\|\()\?/.test(path5)) {
295
- return `Optional paths are not supported: ${path5}`;
294
+ if (/(?<!\\|\()\?/.test(path6)) {
295
+ return `Optional paths are not supported: ${path6}`;
296
296
  }
297
- if (/\/[^/]*(?<!\\):[^/]*(?<!\\):[^/]*/.test(path5)) {
298
- return `Only one wildcard is allowed per path segment: ${path5}`;
297
+ if (/\/[^/]*(?<!\\):[^/]*(?<!\\):[^/]*/.test(path6)) {
298
+ return `Only one wildcard is allowed per path segment: ${path6}`;
299
299
  }
300
300
  for (let i = 0; i < tokens.length; i++) {
301
301
  const token = tokens[i];
302
302
  if (token === void 0) {
303
- return `token ${i} in ${path5} is undefined, this shouldn't happen`;
303
+ return `token ${i} in ${path6} is undefined, this shouldn't happen`;
304
304
  }
305
305
  if (typeof token !== "string") {
306
+ if (!token.name) {
307
+ return `Only named wildcards are allowed: ${path6} (hint: add ":path" to the wildcard)`;
308
+ }
306
309
  if (token.pattern !== PATH_DEFAULT_PATTERN && // Allows (a|b|c) and ((?!a|b|c).*) regex
307
310
  // Only limited regex is supported for now, due to performance considerations
308
311
  !/^(?<allowed>[\w]+(?:\|[^|()]+)+)$|^\(\?!(?<disallowed>[\w]+(?:\|[^|()]+)+)\)\.\*$/.test(
309
312
  token.pattern
310
313
  )) {
311
- return `Path ${path5} cannot use unsupported regular expression wildcard`;
314
+ return `Path ${path6} cannot use unsupported regular expression wildcard`;
312
315
  }
313
316
  if (token.modifier && i !== tokens.length - 1) {
314
- return `Modifier ${token.modifier} is not allowed on wildcard :${token.name} in ${path5}. Modifiers are only allowed in the last path component`;
317
+ return `Modifier ${token.modifier} is not allowed on wildcard :${token.name} in ${path6}. Modifiers are only allowed in the last path component`;
315
318
  }
316
319
  }
317
320
  }
318
321
  } catch (e) {
319
322
  const message = e instanceof Error ? e.message : String(e);
320
- return `Path ${path5} could not be parsed into regexp: ${message}`;
323
+ return `Path ${path6} could not be parsed into regexp: ${message}`;
321
324
  }
322
325
  return void 0;
323
326
  }
@@ -1029,6 +1032,9 @@ function isMonorepo({
1029
1032
  if (fs2.existsSync(path2.join(repositoryRoot, "vlt-workspaces.json"))) {
1030
1033
  return true;
1031
1034
  }
1035
+ if (process.env.NX_WORKSPACE_ROOT === path2.resolve(repositoryRoot)) {
1036
+ return true;
1037
+ }
1032
1038
  const packageJsonPath = path2.join(repositoryRoot, "package.json");
1033
1039
  if (!fs2.existsSync(packageJsonPath)) {
1034
1040
  return false;
@@ -1074,8 +1080,42 @@ function findConfig({ dir }) {
1074
1080
  return null;
1075
1081
  }
1076
1082
 
1077
- // src/config/microfrontends/server/utils/get-output-file-path.ts
1083
+ // src/config/microfrontends/utils/get-application-context.ts
1084
+ import fs5 from "node:fs";
1078
1085
  import path4 from "node:path";
1086
+ function getApplicationContext(opts) {
1087
+ if (opts?.appName) {
1088
+ return { name: opts.appName };
1089
+ }
1090
+ if (process.env.NX_TASK_TARGET_PROJECT) {
1091
+ return { name: process.env.NX_TASK_TARGET_PROJECT };
1092
+ }
1093
+ try {
1094
+ const packageJsonString = fs5.readFileSync(
1095
+ path4.join(opts?.packageRoot || ".", "package.json"),
1096
+ "utf-8"
1097
+ );
1098
+ const packageJson = JSON.parse(packageJsonString);
1099
+ if (!packageJson.name) {
1100
+ throw new MicrofrontendError(
1101
+ `package.json file missing required field "name"`,
1102
+ {
1103
+ type: "packageJson",
1104
+ subtype: "missing_field_name",
1105
+ source: "@vercel/microfrontends/next"
1106
+ }
1107
+ );
1108
+ }
1109
+ return { name: packageJson.name };
1110
+ } catch (err) {
1111
+ throw MicrofrontendError.handle(err, {
1112
+ fileName: "package.json"
1113
+ });
1114
+ }
1115
+ }
1116
+
1117
+ // src/config/microfrontends/server/utils/get-output-file-path.ts
1118
+ import path5 from "node:path";
1079
1119
 
1080
1120
  // src/config/microfrontends/server/constants.ts
1081
1121
  var MFE_CONFIG_DEFAULT_FILE_PATH = "microfrontends";
@@ -1083,7 +1123,7 @@ var MFE_CONFIG_DEFAULT_FILE_NAME = "microfrontends.json";
1083
1123
 
1084
1124
  // src/config/microfrontends/server/utils/get-output-file-path.ts
1085
1125
  function getOutputFilePath() {
1086
- return path4.join(MFE_CONFIG_DEFAULT_FILE_PATH, MFE_CONFIG_DEFAULT_FILE_NAME);
1126
+ return path5.join(MFE_CONFIG_DEFAULT_FILE_PATH, MFE_CONFIG_DEFAULT_FILE_NAME);
1087
1127
  }
1088
1128
 
1089
1129
  // src/config/microfrontends/server/validation.ts
@@ -1422,8 +1462,8 @@ var MicrofrontendsServer = class extends Microfrontends {
1422
1462
  pretty: true
1423
1463
  }) {
1424
1464
  const outputPath = getOutputFilePath();
1425
- fs5.mkdirSync(dirname3(outputPath), { recursive: true });
1426
- fs5.writeFileSync(
1465
+ fs6.mkdirSync(dirname3(outputPath), { recursive: true });
1466
+ fs6.writeFileSync(
1427
1467
  outputPath,
1428
1468
  JSON.stringify(
1429
1469
  this.config.toSchemaJson(),
@@ -1509,14 +1549,8 @@ var MicrofrontendsServer = class extends Microfrontends {
1509
1549
  }
1510
1550
  try {
1511
1551
  const packageRoot = findPackageRoot(directory);
1512
- const packageJsonPath = join2(packageRoot, "package.json");
1513
- const packageJson = JSON.parse(
1514
- fs5.readFileSync(packageJsonPath, "utf-8")
1515
- );
1516
- if (!packageJson.name) {
1517
- throw new Error(`No name found in package.json at ${packageJsonPath}`);
1518
- }
1519
- const configMeta = meta ?? { fromApp: packageJson.name };
1552
+ const { name: appName } = getApplicationContext({ packageRoot });
1553
+ const configMeta = meta ?? { fromApp: appName };
1520
1554
  const maybeConfig = findConfig({ dir: packageRoot });
1521
1555
  if (maybeConfig) {
1522
1556
  return MicrofrontendsServer.fromFile({
@@ -1531,7 +1565,7 @@ var MicrofrontendsServer = class extends Microfrontends {
1531
1565
  if (isMonorepo2) {
1532
1566
  const defaultPackage = findDefaultMicrofrontendsPackage({
1533
1567
  repositoryRoot,
1534
- applicationName: packageJson.name
1568
+ applicationName: appName
1535
1569
  });
1536
1570
  const maybeConfigFromDefault = findConfig({ dir: defaultPackage });
1537
1571
  if (maybeConfigFromDefault) {
@@ -1561,7 +1595,7 @@ var MicrofrontendsServer = class extends Microfrontends {
1561
1595
  options
1562
1596
  }) {
1563
1597
  try {
1564
- const configJson = fs5.readFileSync(filePath, "utf-8");
1598
+ const configJson = fs6.readFileSync(filePath, "utf-8");
1565
1599
  const config = MicrofrontendsServer.validate(configJson);
1566
1600
  if (!isMainConfig(config) && options?.resolveMainConfig) {
1567
1601
  const repositoryRoot = findRepositoryRoot();
@@ -1609,7 +1643,7 @@ var MicrofrontendsServer = class extends Microfrontends {
1609
1643
  overrides
1610
1644
  }) {
1611
1645
  try {
1612
- const config = fs5.readFileSync(filePath, "utf-8");
1646
+ const config = fs6.readFileSync(filePath, "utf-8");
1613
1647
  const validatedConfig = MicrofrontendsServer.validate(config);
1614
1648
  if (!isMainConfig(validatedConfig)) {
1615
1649
  throw new MicrofrontendError(
@@ -1640,42 +1674,15 @@ var MicrofrontendsServer = class extends Microfrontends {
1640
1674
  }
1641
1675
  };
1642
1676
 
1643
- // src/config/microfrontends/utils/get-application-context.ts
1644
- import fs6 from "node:fs";
1645
- function getApplicationContext(opts) {
1646
- if (opts?.appName) {
1647
- return { name: opts.appName };
1648
- }
1649
- try {
1650
- const packageJsonString = fs6.readFileSync("./package.json", "utf-8");
1651
- const packageJson = JSON.parse(packageJsonString);
1652
- if (!packageJson.name) {
1653
- throw new MicrofrontendError(
1654
- `package.json file missing required field "name"`,
1655
- {
1656
- type: "packageJson",
1657
- subtype: "missing_field_name",
1658
- source: "@vercel/microfrontends/next"
1659
- }
1660
- );
1661
- }
1662
- return { name: packageJson.name };
1663
- } catch (err) {
1664
- throw MicrofrontendError.handle(err, {
1665
- fileName: "package.json"
1666
- });
1667
- }
1668
- }
1669
-
1670
1677
  // src/vite/detect-framework.ts
1671
1678
  import { existsSync } from "node:fs";
1672
- import { join as join3 } from "node:path";
1679
+ import { join as join2 } from "node:path";
1673
1680
  import { cwd } from "node:process";
1674
1681
  function detectFramework() {
1675
- if (existsSync(join3(cwd(), "svelte.config.js"))) {
1682
+ if (existsSync(join2(cwd(), "svelte.config.js"))) {
1676
1683
  return "sveltekit";
1677
1684
  }
1678
- if (existsSync(join3(cwd(), "react-router.config.js")) || existsSync(join3(cwd(), "react-router.config.ts"))) {
1685
+ if (existsSync(join2(cwd(), "react-router.config.js")) || existsSync(join2(cwd(), "react-router.config.ts"))) {
1679
1686
  return "react-router";
1680
1687
  }
1681
1688
  return "unknown";