@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
@@ -33,12 +33,12 @@ __export(mfe_port_exports, {
33
33
  mfePort: () => mfePort
34
34
  });
35
35
  module.exports = __toCommonJS(mfe_port_exports);
36
- var import_node_path9 = __toESM(require("path"), 1);
37
- var import_node_fs8 = __toESM(require("fs"), 1);
36
+ var import_node_path10 = __toESM(require("path"), 1);
37
+ var import_node_fs9 = __toESM(require("fs"), 1);
38
38
 
39
39
  // src/config/microfrontends/server/index.ts
40
- var import_node_fs7 = __toESM(require("fs"), 1);
41
- var import_node_path8 = require("path");
40
+ var import_node_fs8 = __toESM(require("fs"), 1);
41
+ var import_node_path9 = require("path");
42
42
 
43
43
  // src/config/overrides/constants.ts
44
44
  var OVERRIDES_COOKIE_PREFIX = "vercel-micro-frontends-override";
@@ -221,21 +221,21 @@ var MicrofrontendConfigClient = class {
221
221
  isEqual(other) {
222
222
  return JSON.stringify(this.applications) === JSON.stringify(other.applications);
223
223
  }
224
- getApplicationNameForPath(path6) {
225
- if (!path6.startsWith("/")) {
224
+ getApplicationNameForPath(path7) {
225
+ if (!path7.startsWith("/")) {
226
226
  throw new Error(`Path must start with a /`);
227
227
  }
228
- if (this.pathCache[path6]) {
229
- return this.pathCache[path6];
228
+ if (this.pathCache[path7]) {
229
+ return this.pathCache[path7];
230
230
  }
231
- const pathname = new URL(path6, "https://example.com").pathname;
231
+ const pathname = new URL(path7, "https://example.com").pathname;
232
232
  for (const [name, application] of Object.entries(this.applications)) {
233
233
  if (application.routing) {
234
234
  for (const group of application.routing) {
235
235
  for (const childPath of group.paths) {
236
236
  const regexp = (0, import_path_to_regexp.pathToRegexp)(childPath);
237
237
  if (regexp.test(pathname)) {
238
- this.pathCache[path6] = name;
238
+ this.pathCache[path7] = name;
239
239
  return name;
240
240
  }
241
241
  }
@@ -248,7 +248,7 @@ var MicrofrontendConfigClient = class {
248
248
  if (!defaultApplication) {
249
249
  return null;
250
250
  }
251
- this.pathCache[path6] = defaultApplication[0];
251
+ this.pathCache[path7] = defaultApplication[0];
252
252
  return defaultApplication[0];
253
253
  }
254
254
  serialize() {
@@ -270,18 +270,18 @@ var validateConfigPaths = (applicationConfigsById) => {
270
270
  }
271
271
  const childApp = app;
272
272
  for (const pathMatch of childApp.routing) {
273
- for (const path6 of pathMatch.paths) {
274
- const maybeError = validatePathExpression(path6);
273
+ for (const path7 of pathMatch.paths) {
274
+ const maybeError = validatePathExpression(path7);
275
275
  if (maybeError) {
276
276
  errors.push(maybeError);
277
277
  } else {
278
- const existing = pathsByApplicationId.get(path6);
278
+ const existing = pathsByApplicationId.get(path7);
279
279
  if (existing) {
280
280
  existing.applications.push(id);
281
281
  } else {
282
- pathsByApplicationId.set(path6, {
282
+ pathsByApplicationId.set(path7, {
283
283
  applications: [id],
284
- matcher: (0, import_path_to_regexp2.pathToRegexp)(path6),
284
+ matcher: (0, import_path_to_regexp2.pathToRegexp)(path7),
285
285
  applicationId: id
286
286
  });
287
287
  }
@@ -290,24 +290,24 @@ var validateConfigPaths = (applicationConfigsById) => {
290
290
  }
291
291
  }
292
292
  const entries = Array.from(pathsByApplicationId.entries());
293
- for (const [path6, { applications: ids, matcher, applicationId }] of entries) {
293
+ for (const [path7, { applications: ids, matcher, applicationId }] of entries) {
294
294
  if (ids.length > 1) {
295
295
  errors.push(
296
- `Duplicate path "${path6}" for applications "${ids.join(", ")}"`
296
+ `Duplicate path "${path7}" for applications "${ids.join(", ")}"`
297
297
  );
298
298
  }
299
299
  for (const [
300
300
  matchPath,
301
301
  { applications: matchIds, applicationId: matchApplicationId }
302
302
  ] of entries) {
303
- if (path6 === matchPath) {
303
+ if (path7 === matchPath) {
304
304
  continue;
305
305
  }
306
306
  if (applicationId === matchApplicationId) {
307
307
  continue;
308
308
  }
309
309
  if (matcher.test(matchPath)) {
310
- const source = `"${path6}" of application${ids.length > 0 ? "s" : ""} ${ids.join(", ")}`;
310
+ const source = `"${path7}" of application${ids.length > 0 ? "s" : ""} ${ids.join(", ")}`;
311
311
  const destination = `"${matchPath}" of application${matchIds.length > 0 ? "s" : ""} ${matchIds.join(", ")}`;
312
312
  errors.push(
313
313
  `Overlapping path detected between ${source} and ${destination}`
@@ -323,39 +323,42 @@ var validateConfigPaths = (applicationConfigsById) => {
323
323
  }
324
324
  };
325
325
  var PATH_DEFAULT_PATTERN = "[^\\/#\\?]+?";
326
- function validatePathExpression(path6) {
326
+ function validatePathExpression(path7) {
327
327
  try {
328
- const tokens = (0, import_path_to_regexp2.parse)(path6);
329
- if (/(?<!\\)\{/.test(path6)) {
330
- return `Optional paths are not supported: ${path6}`;
328
+ const tokens = (0, import_path_to_regexp2.parse)(path7);
329
+ if (/(?<!\\)\{/.test(path7)) {
330
+ return `Optional paths are not supported: ${path7}`;
331
331
  }
332
- if (/(?<!\\|\()\?/.test(path6)) {
333
- return `Optional paths are not supported: ${path6}`;
332
+ if (/(?<!\\|\()\?/.test(path7)) {
333
+ return `Optional paths are not supported: ${path7}`;
334
334
  }
335
- if (/\/[^/]*(?<!\\):[^/]*(?<!\\):[^/]*/.test(path6)) {
336
- return `Only one wildcard is allowed per path segment: ${path6}`;
335
+ if (/\/[^/]*(?<!\\):[^/]*(?<!\\):[^/]*/.test(path7)) {
336
+ return `Only one wildcard is allowed per path segment: ${path7}`;
337
337
  }
338
338
  for (let i = 0; i < tokens.length; i++) {
339
339
  const token = tokens[i];
340
340
  if (token === void 0) {
341
- return `token ${i} in ${path6} is undefined, this shouldn't happen`;
341
+ return `token ${i} in ${path7} is undefined, this shouldn't happen`;
342
342
  }
343
343
  if (typeof token !== "string") {
344
+ if (!token.name) {
345
+ return `Only named wildcards are allowed: ${path7} (hint: add ":path" to the wildcard)`;
346
+ }
344
347
  if (token.pattern !== PATH_DEFAULT_PATTERN && // Allows (a|b|c) and ((?!a|b|c).*) regex
345
348
  // Only limited regex is supported for now, due to performance considerations
346
349
  !/^(?<allowed>[\w]+(?:\|[^|()]+)+)$|^\(\?!(?<disallowed>[\w]+(?:\|[^|()]+)+)\)\.\*$/.test(
347
350
  token.pattern
348
351
  )) {
349
- return `Path ${path6} cannot use unsupported regular expression wildcard`;
352
+ return `Path ${path7} cannot use unsupported regular expression wildcard`;
350
353
  }
351
354
  if (token.modifier && i !== tokens.length - 1) {
352
- return `Modifier ${token.modifier} is not allowed on wildcard :${token.name} in ${path6}. Modifiers are only allowed in the last path component`;
355
+ return `Modifier ${token.modifier} is not allowed on wildcard :${token.name} in ${path7}. Modifiers are only allowed in the last path component`;
353
356
  }
354
357
  }
355
358
  }
356
359
  } catch (e) {
357
360
  const message = e instanceof Error ? e.message : String(e);
358
- return `Path ${path6} could not be parsed into regexp: ${message}`;
361
+ return `Path ${path7} could not be parsed into regexp: ${message}`;
359
362
  }
360
363
  return void 0;
361
364
  }
@@ -910,6 +913,9 @@ var import_node_fs = __toESM(require("fs"), 1);
910
913
  var import_node_path = __toESM(require("path"), 1);
911
914
  var GIT_DIRECTORY = ".git";
912
915
  function findRepositoryRoot(startDir) {
916
+ if (process.env.NX_WORKSPACE_ROOT) {
917
+ return process.env.NX_WORKSPACE_ROOT;
918
+ }
913
919
  let currentDir = startDir || process.cwd();
914
920
  while (currentDir !== import_node_path.default.parse(currentDir).root) {
915
921
  const gitPath = import_node_path.default.join(currentDir, GIT_DIRECTORY);
@@ -1067,6 +1073,9 @@ function isMonorepo({
1067
1073
  if (import_node_fs4.default.existsSync(import_node_path4.default.join(repositoryRoot, "vlt-workspaces.json"))) {
1068
1074
  return true;
1069
1075
  }
1076
+ if (process.env.NX_WORKSPACE_ROOT === import_node_path4.default.resolve(repositoryRoot)) {
1077
+ return true;
1078
+ }
1070
1079
  const packageJsonPath = import_node_path4.default.join(repositoryRoot, "package.json");
1071
1080
  if (!import_node_fs4.default.existsSync(packageJsonPath)) {
1072
1081
  return false;
@@ -1112,8 +1121,42 @@ function findConfig({ dir }) {
1112
1121
  return null;
1113
1122
  }
1114
1123
 
1115
- // src/config/microfrontends/server/utils/get-output-file-path.ts
1124
+ // src/config/microfrontends/utils/get-application-context.ts
1125
+ var import_node_fs7 = __toESM(require("fs"), 1);
1116
1126
  var import_node_path7 = __toESM(require("path"), 1);
1127
+ function getApplicationContext(opts) {
1128
+ if (opts?.appName) {
1129
+ return { name: opts.appName };
1130
+ }
1131
+ if (process.env.NX_TASK_TARGET_PROJECT) {
1132
+ return { name: process.env.NX_TASK_TARGET_PROJECT };
1133
+ }
1134
+ try {
1135
+ const packageJsonString = import_node_fs7.default.readFileSync(
1136
+ import_node_path7.default.join(opts?.packageRoot || ".", "package.json"),
1137
+ "utf-8"
1138
+ );
1139
+ const packageJson = JSON.parse(packageJsonString);
1140
+ if (!packageJson.name) {
1141
+ throw new MicrofrontendError(
1142
+ `package.json file missing required field "name"`,
1143
+ {
1144
+ type: "packageJson",
1145
+ subtype: "missing_field_name",
1146
+ source: "@vercel/microfrontends/next"
1147
+ }
1148
+ );
1149
+ }
1150
+ return { name: packageJson.name };
1151
+ } catch (err) {
1152
+ throw MicrofrontendError.handle(err, {
1153
+ fileName: "package.json"
1154
+ });
1155
+ }
1156
+ }
1157
+
1158
+ // src/config/microfrontends/server/utils/get-output-file-path.ts
1159
+ var import_node_path8 = __toESM(require("path"), 1);
1117
1160
 
1118
1161
  // src/config/microfrontends/server/constants.ts
1119
1162
  var MFE_CONFIG_DEFAULT_FILE_PATH = "microfrontends";
@@ -1121,7 +1164,7 @@ var MFE_CONFIG_DEFAULT_FILE_NAME = "microfrontends.json";
1121
1164
 
1122
1165
  // src/config/microfrontends/server/utils/get-output-file-path.ts
1123
1166
  function getOutputFilePath() {
1124
- return import_node_path7.default.join(MFE_CONFIG_DEFAULT_FILE_PATH, MFE_CONFIG_DEFAULT_FILE_NAME);
1167
+ return import_node_path8.default.join(MFE_CONFIG_DEFAULT_FILE_PATH, MFE_CONFIG_DEFAULT_FILE_NAME);
1125
1168
  }
1126
1169
 
1127
1170
  // src/config/microfrontends/server/validation.ts
@@ -1460,8 +1503,8 @@ var MicrofrontendsServer = class extends Microfrontends {
1460
1503
  pretty: true
1461
1504
  }) {
1462
1505
  const outputPath = getOutputFilePath();
1463
- import_node_fs7.default.mkdirSync((0, import_node_path8.dirname)(outputPath), { recursive: true });
1464
- import_node_fs7.default.writeFileSync(
1506
+ import_node_fs8.default.mkdirSync((0, import_node_path9.dirname)(outputPath), { recursive: true });
1507
+ import_node_fs8.default.writeFileSync(
1465
1508
  outputPath,
1466
1509
  JSON.stringify(
1467
1510
  this.config.toSchemaJson(),
@@ -1547,14 +1590,8 @@ var MicrofrontendsServer = class extends Microfrontends {
1547
1590
  }
1548
1591
  try {
1549
1592
  const packageRoot = findPackageRoot(directory);
1550
- const packageJsonPath = (0, import_node_path8.join)(packageRoot, "package.json");
1551
- const packageJson = JSON.parse(
1552
- import_node_fs7.default.readFileSync(packageJsonPath, "utf-8")
1553
- );
1554
- if (!packageJson.name) {
1555
- throw new Error(`No name found in package.json at ${packageJsonPath}`);
1556
- }
1557
- const configMeta = meta ?? { fromApp: packageJson.name };
1593
+ const { name: appName } = getApplicationContext({ packageRoot });
1594
+ const configMeta = meta ?? { fromApp: appName };
1558
1595
  const maybeConfig = findConfig({ dir: packageRoot });
1559
1596
  if (maybeConfig) {
1560
1597
  return MicrofrontendsServer.fromFile({
@@ -1569,7 +1606,7 @@ var MicrofrontendsServer = class extends Microfrontends {
1569
1606
  if (isMonorepo2) {
1570
1607
  const defaultPackage = findDefaultMicrofrontendsPackage({
1571
1608
  repositoryRoot,
1572
- applicationName: packageJson.name
1609
+ applicationName: appName
1573
1610
  });
1574
1611
  const maybeConfigFromDefault = findConfig({ dir: defaultPackage });
1575
1612
  if (maybeConfigFromDefault) {
@@ -1599,7 +1636,7 @@ var MicrofrontendsServer = class extends Microfrontends {
1599
1636
  options
1600
1637
  }) {
1601
1638
  try {
1602
- const configJson = import_node_fs7.default.readFileSync(filePath, "utf-8");
1639
+ const configJson = import_node_fs8.default.readFileSync(filePath, "utf-8");
1603
1640
  const config = MicrofrontendsServer.validate(configJson);
1604
1641
  if (!isMainConfig(config) && options?.resolveMainConfig) {
1605
1642
  const repositoryRoot = findRepositoryRoot();
@@ -1647,7 +1684,7 @@ var MicrofrontendsServer = class extends Microfrontends {
1647
1684
  overrides
1648
1685
  }) {
1649
1686
  try {
1650
- const config = import_node_fs7.default.readFileSync(filePath, "utf-8");
1687
+ const config = import_node_fs8.default.readFileSync(filePath, "utf-8");
1651
1688
  const validatedConfig = MicrofrontendsServer.validate(config);
1652
1689
  if (!isMainConfig(validatedConfig)) {
1653
1690
  throw new MicrofrontendError(
@@ -1696,8 +1733,8 @@ function mfePort(packageDir) {
1696
1733
  };
1697
1734
  }
1698
1735
  function getPackageJson(packageDir) {
1699
- const filePath = import_node_path9.default.join(packageDir, "package.json");
1700
- return JSON.parse(import_node_fs8.default.readFileSync(filePath, "utf-8"));
1736
+ const filePath = import_node_path10.default.join(packageDir, "package.json");
1737
+ return JSON.parse(import_node_fs9.default.readFileSync(filePath, "utf-8"));
1701
1738
  }
1702
1739
  function loadConfig({
1703
1740
  packageDir,