@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
@@ -1,9 +1,9 @@
1
1
  // src/next-v2/config/index.ts
2
- import fs5 from "node:fs";
2
+ import fs6 from "node:fs";
3
3
 
4
4
  // src/config-v2/microfrontends/server/index.ts
5
- import fs4 from "node:fs";
6
- import { dirname as dirname3, join } from "node:path";
5
+ import fs5 from "node:fs";
6
+ import { dirname as dirname3, join as join2 } from "node:path";
7
7
 
8
8
  // src/config-v2/overrides/constants.ts
9
9
  var OVERRIDES_COOKIE_PREFIX = "vercel-micro-frontends-override";
@@ -350,19 +350,6 @@ var validateConfigDefaultApplication = (applicationConfigsById) => {
350
350
  );
351
351
  }
352
352
  };
353
- var validateConfigOptions = (options) => {
354
- var _a;
355
- if ((_a = options == null ? void 0 : options.vercel) == null ? void 0 : _a.previewDeploymentSuffix) {
356
- if (!/^[a-zA-Z]{2,}\.[a-zA-Z]{2,}$/.test(
357
- options.vercel.previewDeploymentSuffix
358
- )) {
359
- throw new MicrofrontendError(
360
- `Invalid preview deployment suffix: ${options.vercel.previewDeploymentSuffix}. Should have be formatted like "vercel.app".`,
361
- { type: "config", subtype: "invalid_preview_deployment_suffix" }
362
- );
363
- }
364
- }
365
- };
366
353
 
367
354
  // src/config-v2/microfrontends-config/isomorphic/utils/generate-asset-prefix.ts
368
355
  var PREFIX = "vc-ap";
@@ -581,7 +568,6 @@ var MicrofrontendConfigIsomorphic = class {
581
568
  validateConfigPaths(c.applications);
582
569
  validateConfigDefaultApplication(c.applications);
583
570
  }
584
- validateConfigOptions(c.options);
585
571
  return c;
586
572
  }
587
573
  static fromEnv({
@@ -857,29 +843,39 @@ function findPackagePath(opts) {
857
843
  // src/config-v2/microfrontends/utils/find-default-package.ts
858
844
  import { dirname as dirname2 } from "node:path";
859
845
  import { readFileSync as readFileSync2 } from "node:fs";
846
+ import { parse as parse2 } from "jsonc-parser";
860
847
  import fg2 from "fast-glob";
848
+
849
+ // src/config-v2/constants.ts
850
+ var CONFIGURATION_FILENAMES = [
851
+ "microfrontends.jsonc",
852
+ "microfrontends.json"
853
+ ];
854
+
855
+ // src/config-v2/microfrontends/utils/find-default-package.ts
861
856
  var configCache2 = {};
862
857
  function findDefaultMicrofrontendsPackages({
863
858
  repositoryRoot,
864
859
  applicationName
865
860
  }) {
866
861
  try {
867
- const microfrontendsJsonPaths = fg2.globSync("**/microfrontends.json", {
868
- cwd: repositoryRoot,
869
- absolute: true,
870
- onlyFiles: true,
871
- followSymbolicLinks: false,
872
- ignore: ["**/node_modules/**", "**/.git/**"]
873
- });
862
+ const microfrontendsJsonPaths = fg2.globSync(
863
+ `**/{${CONFIGURATION_FILENAMES.join(",")}}`,
864
+ {
865
+ cwd: repositoryRoot,
866
+ absolute: true,
867
+ onlyFiles: true,
868
+ followSymbolicLinks: false,
869
+ ignore: ["**/node_modules/**", "**/.git/**"]
870
+ }
871
+ );
874
872
  const matchingPaths = [];
875
873
  for (const microfrontendsJsonPath of microfrontendsJsonPaths) {
876
874
  const microfrontendsJsonContent = readFileSync2(
877
875
  microfrontendsJsonPath,
878
876
  "utf-8"
879
877
  );
880
- const microfrontendsJson = JSON.parse(
881
- microfrontendsJsonContent
882
- );
878
+ const microfrontendsJson = parse2(microfrontendsJsonContent);
883
879
  if (isMainConfig(microfrontendsJson) && microfrontendsJson.applications[applicationName]) {
884
880
  matchingPaths.push(microfrontendsJsonPath);
885
881
  }
@@ -909,7 +905,7 @@ function findDefaultMicrofrontendsPackage(opts) {
909
905
  const result = findDefaultMicrofrontendsPackages(opts);
910
906
  if (!result) {
911
907
  throw new Error(
912
- `Error trying to resolve the main microfrontends.json configuration`
908
+ `Error trying to resolve the main microfrontends configuration`
913
909
  );
914
910
  }
915
911
  configCache2[cacheKey] = result;
@@ -961,6 +957,19 @@ function findPackageRoot(startDir) {
961
957
  );
962
958
  }
963
959
 
960
+ // src/config-v2/microfrontends/utils/find-config.ts
961
+ import fs4 from "node:fs";
962
+ import { join } from "node:path";
963
+ function findConfig({ dir }) {
964
+ for (const filename of CONFIGURATION_FILENAMES) {
965
+ const maybeConfig = join(dir, filename);
966
+ if (fs4.existsSync(maybeConfig)) {
967
+ return maybeConfig;
968
+ }
969
+ }
970
+ return null;
971
+ }
972
+
964
973
  // src/config-v2/microfrontends/server/utils/get-output-file-path.ts
965
974
  import path4 from "node:path";
966
975
 
@@ -986,7 +995,7 @@ function getOutputFilePath() {
986
995
  }
987
996
 
988
997
  // src/config-v2/microfrontends/server/validation.ts
989
- import { parse as parse2 } from "jsonc-parser";
998
+ import { parse as parse3 } from "jsonc-parser";
990
999
  import { Ajv } from "ajv";
991
1000
 
992
1001
  // src/config/errors.ts
@@ -1139,10 +1148,6 @@ var schema_v2_default = {
1139
1148
  VercelOptions: {
1140
1149
  type: "object",
1141
1150
  properties: {
1142
- previewDeploymentSuffix: {
1143
- type: "string",
1144
- 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`."
1145
- },
1146
1151
  teamSlug: {
1147
1152
  type: "string",
1148
1153
  description: "Team slug for the Vercel team"
@@ -1336,7 +1341,7 @@ var SCHEMA = schema_v2_default;
1336
1341
 
1337
1342
  // src/config-v2/microfrontends/server/validation.ts
1338
1343
  function validateSchema(configString) {
1339
- const parsedConfig = parse2(configString);
1344
+ const parsedConfig = parse3(configString);
1340
1345
  const ajv = new Ajv();
1341
1346
  const validate = ajv.compile(SCHEMA);
1342
1347
  const isValid = validate(parsedConfig);
@@ -1358,8 +1363,8 @@ var MicrofrontendsServer = class extends Microfrontends {
1358
1363
  pretty: true
1359
1364
  }) {
1360
1365
  const outputPath = getOutputFilePath();
1361
- fs4.mkdirSync(dirname3(outputPath), { recursive: true });
1362
- fs4.writeFileSync(
1366
+ fs5.mkdirSync(dirname3(outputPath), { recursive: true });
1367
+ fs5.writeFileSync(
1363
1368
  outputPath,
1364
1369
  JSON.stringify(
1365
1370
  this.config.toSchemaJson(),
@@ -1422,8 +1427,8 @@ var MicrofrontendsServer = class extends Microfrontends {
1422
1427
  return config;
1423
1428
  }
1424
1429
  /**
1425
- * Looks up the configuration by inferring the package root and looking for a microfrontends.json file. If a file is not found,
1426
- * it will look for a package in the repository with a microfrontends.json file that contains the current application
1430
+ * Looks up the configuration by inferring the package root and looking for a microfrontends config file. If a file is not found,
1431
+ * it will look for a package in the repository with a microfrontends file that contains the current application
1427
1432
  * and use that configuration.
1428
1433
  *
1429
1434
  * This can return either a Child or Main configuration.
@@ -1445,16 +1450,16 @@ var MicrofrontendsServer = class extends Microfrontends {
1445
1450
  }
1446
1451
  try {
1447
1452
  const packageRoot = findPackageRoot(directory);
1448
- const packageJsonPath = join(packageRoot, "package.json");
1453
+ const packageJsonPath = join2(packageRoot, "package.json");
1449
1454
  const packageJson = JSON.parse(
1450
- fs4.readFileSync(packageJsonPath, "utf-8")
1455
+ fs5.readFileSync(packageJsonPath, "utf-8")
1451
1456
  );
1452
1457
  if (!packageJson.name) {
1453
1458
  throw new Error(`No name found in package.json at ${packageJsonPath}`);
1454
1459
  }
1455
1460
  const configMeta = meta ?? { fromApp: packageJson.name };
1456
- const maybeConfig = join(packageRoot, "microfrontends.json");
1457
- if (fs4.existsSync(maybeConfig)) {
1461
+ const maybeConfig = findConfig({ dir: packageRoot });
1462
+ if (maybeConfig) {
1458
1463
  return MicrofrontendsServer.fromFile({
1459
1464
  filePath: maybeConfig,
1460
1465
  cookies,
@@ -1469,12 +1474,15 @@ var MicrofrontendsServer = class extends Microfrontends {
1469
1474
  repositoryRoot,
1470
1475
  applicationName: packageJson.name
1471
1476
  });
1472
- return MicrofrontendsServer.fromFile({
1473
- filePath: join(defaultPackage, "microfrontends.json"),
1474
- cookies,
1475
- meta: configMeta,
1476
- options
1477
- });
1477
+ const maybeConfigFromDefault = findConfig({ dir: defaultPackage });
1478
+ if (maybeConfigFromDefault) {
1479
+ return MicrofrontendsServer.fromFile({
1480
+ filePath: maybeConfigFromDefault,
1481
+ cookies,
1482
+ meta: configMeta,
1483
+ options
1484
+ });
1485
+ }
1478
1486
  }
1479
1487
  throw new Error("Unable to infer");
1480
1488
  } catch (e) {
@@ -1494,7 +1502,7 @@ var MicrofrontendsServer = class extends Microfrontends {
1494
1502
  options
1495
1503
  }) {
1496
1504
  try {
1497
- const configJson = fs4.readFileSync(filePath, "utf-8");
1505
+ const configJson = fs5.readFileSync(filePath, "utf-8");
1498
1506
  const config = MicrofrontendsServer.validate(configJson);
1499
1507
  if (!isMainConfig(config) && (options == null ? void 0 : options.resolveMainConfig)) {
1500
1508
  const repositoryRoot = findRepositoryRoot();
@@ -1510,9 +1518,15 @@ var MicrofrontendsServer = class extends Microfrontends {
1510
1518
  { type: "config", subtype: "not_found" }
1511
1519
  );
1512
1520
  }
1513
- const mainConfigPath = join(packagePath, "microfrontends.json");
1521
+ const maybeConfig = findConfig({ dir: packagePath });
1522
+ if (!maybeConfig) {
1523
+ throw new MicrofrontendError(
1524
+ `Could not find microfrontends configuration in ${packagePath}`,
1525
+ { type: "config", subtype: "not_found" }
1526
+ );
1527
+ }
1514
1528
  return MicrofrontendsServer.fromMainConfigFile({
1515
- filePath: mainConfigPath,
1529
+ filePath: maybeConfig,
1516
1530
  overrides: cookies ? parseOverrides(cookies) : void 0
1517
1531
  });
1518
1532
  }
@@ -1536,7 +1550,7 @@ var MicrofrontendsServer = class extends Microfrontends {
1536
1550
  overrides
1537
1551
  }) {
1538
1552
  try {
1539
- const config = fs4.readFileSync(filePath, "utf-8");
1553
+ const config = fs5.readFileSync(filePath, "utf-8");
1540
1554
  const validatedConfig = MicrofrontendsServer.validate(config);
1541
1555
  if (!isMainConfig(validatedConfig)) {
1542
1556
  throw new MicrofrontendError(
@@ -1674,23 +1688,28 @@ function getDomainFromEnvironment({
1674
1688
  app,
1675
1689
  target
1676
1690
  }) {
1677
- var _a, _b;
1691
+ var _a;
1678
1692
  const mfeProjects = JSON.parse(
1679
- process.env.VERCEL_MICROFRONTENDS_PROJECTS ?? "{}"
1693
+ process.env.VERCEL_MICROFRONTENDS_PROJECTS ?? "[]"
1680
1694
  );
1681
- if (Object.keys(mfeProjects).length === 0) {
1695
+ if (mfeProjects.length === 0) {
1682
1696
  throw new Error("Missing related microfrontends project information");
1683
1697
  }
1684
1698
  if (!((_a = app.vercel) == null ? void 0 : _a.projectId)) {
1685
1699
  throw new Error(`Missing applications[${app.name}].vercel.projectId`);
1686
1700
  }
1687
- const vercelProject = (_b = mfeProjects.applications) == null ? void 0 : _b[app.vercel.projectId];
1701
+ const vercelProject = mfeProjects.find(
1702
+ (p) => {
1703
+ var _a2;
1704
+ return p.project.id === ((_a2 = app.vercel) == null ? void 0 : _a2.projectId);
1705
+ }
1706
+ );
1688
1707
  if (!vercelProject) {
1689
1708
  throw new Error(
1690
1709
  `Missing related microfrontends project information for application "${app.name}"`
1691
1710
  );
1692
1711
  }
1693
- const domain = target === "preview" && vercelProject.deploymentAlias ? vercelProject.deploymentAlias : vercelProject.productionHost;
1712
+ const domain = target === "preview" && vercelProject.preview.branch ? vercelProject.preview.branch : vercelProject.production.alias ?? vercelProject.production.url;
1694
1713
  if (!domain) {
1695
1714
  throw new Error(
1696
1715
  `Missing domain for target "${target}" in application "${app.name}"`
@@ -1809,6 +1828,16 @@ function transform4(args) {
1809
1828
  const buildBeforeFiles = () => {
1810
1829
  const rewrites = /* @__PURE__ */ new Map();
1811
1830
  if (!app.isDefault()) {
1831
+ rewrites.set(`/${app.getAssetPrefix()}/_next/:path+`, {
1832
+ destination: {
1833
+ pathname: `/_next/:path+`
1834
+ }
1835
+ });
1836
+ rewrites.set(`/${app.getAssetPrefix()}/.well-known/vercel/flags`, {
1837
+ destination: {
1838
+ pathname: `/.well-known/vercel/flags`
1839
+ }
1840
+ });
1812
1841
  if (process.env.VERCEL_MICROFRONTENDS_CONSOLIDATE_SPEED_INSIGHTS === "1") {
1813
1842
  rewrites.set(`/${app.getAssetPrefix()}/_vercel/:path*`, {
1814
1843
  destination: { pathname: "/_vercel/:path*" }
@@ -1877,9 +1906,27 @@ function transform4(args) {
1877
1906
  }
1878
1907
 
1879
1908
  // src/next-v2/config/transforms/server-actions.ts
1909
+ function debugRewrites2(allowedOrigins) {
1910
+ if (process.env.MFE_DEBUG === "true" && allowedOrigins) {
1911
+ const indent = " ".repeat(4);
1912
+ const header = "server actions allowed origins";
1913
+ const separator = "\u23AF".repeat(header.length);
1914
+ const maxSourceLength = Math.max(
1915
+ ...allowedOrigins.map((key) => key.length)
1916
+ );
1917
+ const table = allowedOrigins.map((origin, idx) => {
1918
+ const paddedSource = origin.padEnd(maxSourceLength);
1919
+ return `${indent} ${idx + 1}. ${paddedSource}`;
1920
+ }).join("\n");
1921
+ console.log(`${indent}${header}
1922
+ ${indent}${separator}
1923
+ ${table}
1924
+ `);
1925
+ }
1926
+ }
1880
1927
  var formatDomainForServerAction = (domain) => domain.replace(/https?:\/\//, "");
1881
1928
  function transform5(args) {
1882
- var _a;
1929
+ var _a, _b;
1883
1930
  const { next, app, microfrontend } = args;
1884
1931
  if (microfrontend instanceof MicrofrontendChildConfig) {
1885
1932
  console.warn(
@@ -1905,11 +1952,14 @@ function transform5(args) {
1905
1952
  ...existingServerActionConfig,
1906
1953
  allowedOrigins: Array.from(
1907
1954
  /* @__PURE__ */ new Set([
1955
+ // existing
1908
1956
  ...(existingServerActionConfig == null ? void 0 : existingServerActionConfig.allowedOrigins) ?? [],
1957
+ // this deployments host
1958
+ ...process.env.VERCEL_URL ? [formatDomainForServerAction(process.env.VERCEL_URL)] : [],
1959
+ // default application host
1960
+ formatDomainForServerAction(defaultApplication.production.toString()),
1961
+ // environment specific microfrontend hosts
1909
1962
  ...appsToAllow.flatMap((a) => [
1910
- formatDomainForServerAction(
1911
- defaultApplication.production.toString()
1912
- ),
1913
1963
  formatDomainForServerAction(
1914
1964
  getDomainForCurrentEnvironment(microfrontend, a.name)
1915
1965
  )
@@ -1918,6 +1968,7 @@ function transform5(args) {
1918
1968
  )
1919
1969
  }
1920
1970
  };
1971
+ debugRewrites2((_b = next.experimental.serverActions) == null ? void 0 : _b.allowedOrigins);
1921
1972
  return {
1922
1973
  next
1923
1974
  };
@@ -2027,7 +2078,7 @@ function getApplicationContext(opts) {
2027
2078
  return { name: opts.appName };
2028
2079
  }
2029
2080
  try {
2030
- const packageJsonString = fs5.readFileSync("./package.json", "utf-8");
2081
+ const packageJsonString = fs6.readFileSync("./package.json", "utf-8");
2031
2082
  const packageJson = JSON.parse(packageJsonString);
2032
2083
  if (!packageJson.name) {
2033
2084
  throw new MicrofrontendError(