@vercel/microfrontends 0.10.0 → 0.10.1

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 (62) hide show
  1. package/README.md +5 -5
  2. package/dist/bin/cli.cjs +172 -86
  3. package/dist/config/client.d.ts +1 -1
  4. package/dist/config/edge.d.ts +2 -2
  5. package/dist/config.cjs +1 -6
  6. package/dist/config.cjs.map +1 -1
  7. package/dist/config.d.ts +3 -3
  8. package/dist/config.js +1 -6
  9. package/dist/config.js.map +1 -1
  10. package/dist/{index-05742bef.d.ts → index-acb44057.d.ts} +2 -2
  11. package/dist/{microfrontend-config-2425db74.d.ts → microfrontend-config-983a5139.d.ts} +1 -1
  12. package/dist/next/client.cjs +1 -1
  13. package/dist/next/client.cjs.map +1 -1
  14. package/dist/next/client.js +1 -1
  15. package/dist/next/client.js.map +1 -1
  16. package/dist/next/config.cjs +3 -10
  17. package/dist/next/config.cjs.map +1 -1
  18. package/dist/next/config.js +3 -10
  19. package/dist/next/config.js.map +1 -1
  20. package/dist/next/middleware.cjs +5 -7
  21. package/dist/next/middleware.cjs.map +1 -1
  22. package/dist/next/middleware.js +5 -7
  23. package/dist/next/middleware.js.map +1 -1
  24. package/dist/next/testing.cjs +1 -6
  25. package/dist/next/testing.cjs.map +1 -1
  26. package/dist/next/testing.d.ts +2 -2
  27. package/dist/next/testing.js +1 -6
  28. package/dist/next/testing.js.map +1 -1
  29. package/dist/overrides.d.ts +2 -2
  30. package/dist/{schema-83a75e61.d.ts → schema-2922d49e.d.ts} +1 -7
  31. package/dist/{types-4fd1c7c6.d.ts → types-7b1cd9f7.d.ts} +1 -7
  32. package/dist/{types-13f3e535.d.ts → types-c3d15d04.d.ts} +1 -1
  33. package/dist/v2/config.d.ts +3 -3
  34. package/dist/v2/microfrontends/server.cjs +122 -32
  35. package/dist/v2/microfrontends/server.cjs.map +1 -1
  36. package/dist/v2/microfrontends/server.d.ts +7 -4
  37. package/dist/v2/microfrontends/server.js +122 -32
  38. package/dist/v2/microfrontends/server.js.map +1 -1
  39. package/dist/v2/microfrontends.d.ts +3 -3
  40. package/dist/v2/next/client.cjs +1 -1
  41. package/dist/v2/next/client.cjs.map +1 -1
  42. package/dist/v2/next/client.js +1 -1
  43. package/dist/v2/next/client.js.map +1 -1
  44. package/dist/v2/next/config.cjs +128 -40
  45. package/dist/v2/next/config.cjs.map +1 -1
  46. package/dist/v2/next/config.js +128 -40
  47. package/dist/v2/next/config.js.map +1 -1
  48. package/dist/v2/next/middleware.cjs +1 -1
  49. package/dist/v2/next/middleware.cjs.map +1 -1
  50. package/dist/v2/next/middleware.js +1 -1
  51. package/dist/v2/next/middleware.js.map +1 -1
  52. package/dist/v2/overrides.d.ts +3 -3
  53. package/dist/v2/schema.cjs.map +1 -1
  54. package/dist/v2/schema.d.ts +1 -1
  55. package/dist/validation.cjs +0 -8
  56. package/dist/validation.cjs.map +1 -1
  57. package/dist/validation.d.ts +2 -8
  58. package/dist/validation.js +0 -8
  59. package/dist/validation.js.map +1 -1
  60. package/package.json +8 -7
  61. package/schema/schema-v2.json +0 -4
  62. package/schema/schema.json +0 -4
@@ -33,8 +33,8 @@ __export(server_exports, {
33
33
  MicrofrontendsServer: () => MicrofrontendsServer
34
34
  });
35
35
  module.exports = __toCommonJS(server_exports);
36
- var import_node_fs = __toESM(require("fs"), 1);
37
- var import_node_path2 = require("path");
36
+ var import_node_fs3 = __toESM(require("fs"), 1);
37
+ var import_node_path4 = require("path");
38
38
 
39
39
  // src/config-v2/overrides/constants.ts
40
40
  var OVERRIDES_COOKIE_PREFIX = "vercel-microfrontends-override";
@@ -218,21 +218,21 @@ var MicrofrontendConfigClient = class {
218
218
  isEqual(other) {
219
219
  return JSON.stringify(this.applications) === JSON.stringify(other.applications);
220
220
  }
221
- getApplicationNameForPath(path2) {
222
- if (!path2.startsWith("/")) {
221
+ getApplicationNameForPath(path3) {
222
+ if (!path3.startsWith("/")) {
223
223
  throw new Error(`Path must start with a /`);
224
224
  }
225
- if (this.pathCache[path2]) {
226
- return this.pathCache[path2];
225
+ if (this.pathCache[path3]) {
226
+ return this.pathCache[path3];
227
227
  }
228
- const pathname = new URL(path2, "https://example.com").pathname;
228
+ const pathname = new URL(path3, "https://example.com").pathname;
229
229
  for (const [name, application] of Object.entries(this.applications)) {
230
230
  if (application.routing) {
231
231
  for (const group of application.routing) {
232
232
  for (const childPath of group.paths) {
233
233
  const regexp = (0, import_path_to_regexp.pathToRegexp)(childPath);
234
234
  if (regexp.test(pathname)) {
235
- this.pathCache[path2] = name;
235
+ this.pathCache[path3] = name;
236
236
  return name;
237
237
  }
238
238
  }
@@ -245,7 +245,7 @@ var MicrofrontendConfigClient = class {
245
245
  if (!defaultApplication) {
246
246
  return null;
247
247
  }
248
- this.pathCache[path2] = defaultApplication[0];
248
+ this.pathCache[path3] = defaultApplication[0];
249
249
  return defaultApplication[0];
250
250
  }
251
251
  serialize() {
@@ -277,22 +277,22 @@ var validateConfigPaths = (applicationConfigsById) => {
277
277
  continue;
278
278
  }
279
279
  for (const pathMatch of app.routing) {
280
- for (const path2 of pathMatch.paths) {
281
- const tokens = (0, import_path_to_regexp2.parse)(path2);
280
+ for (const path3 of pathMatch.paths) {
281
+ const tokens = (0, import_path_to_regexp2.parse)(path3);
282
282
  for (const token of tokens.slice(0, -1)) {
283
283
  if (typeof token !== "string") {
284
284
  errors.push(
285
- `Path ${path2} may only have a :wildcard in the last path component`
285
+ `Path ${path3} may only have a :wildcard in the last path component`
286
286
  );
287
287
  }
288
288
  }
289
- const existing = pathsByApplicationId.get(path2);
289
+ const existing = pathsByApplicationId.get(path3);
290
290
  if (existing) {
291
291
  existing.applications.push(id);
292
292
  } else {
293
- pathsByApplicationId.set(path2, {
293
+ pathsByApplicationId.set(path3, {
294
294
  applications: [id],
295
- matcher: (0, import_path_to_regexp2.pathToRegexp)(path2),
295
+ matcher: (0, import_path_to_regexp2.pathToRegexp)(path3),
296
296
  applicationId: id
297
297
  });
298
298
  }
@@ -300,10 +300,10 @@ var validateConfigPaths = (applicationConfigsById) => {
300
300
  }
301
301
  }
302
302
  const entries = Array.from(pathsByApplicationId.entries());
303
- entries.forEach(([path2, { applications: ids, matcher, applicationId }]) => {
303
+ entries.forEach(([path3, { applications: ids, matcher, applicationId }]) => {
304
304
  if (ids.length > 1) {
305
305
  errors.push(
306
- `Duplicate path "${path2}" for applications "${ids.join(", ")}"`
306
+ `Duplicate path "${path3}" for applications "${ids.join(", ")}"`
307
307
  );
308
308
  }
309
309
  entries.forEach(
@@ -311,14 +311,14 @@ var validateConfigPaths = (applicationConfigsById) => {
311
311
  matchPath,
312
312
  { applications: matchIds, applicationId: matchApplicationId }
313
313
  ]) => {
314
- if (path2 === matchPath) {
314
+ if (path3 === matchPath) {
315
315
  return;
316
316
  }
317
317
  if (applicationId === matchApplicationId) {
318
318
  return;
319
319
  }
320
320
  if (matcher.test(matchPath)) {
321
- const source = `"${path2}" of application${ids.length > 0 ? "s" : ""} ${ids.join(", ")}`;
321
+ const source = `"${path3}" of application${ids.length > 0 ? "s" : ""} ${ids.join(", ")}`;
322
322
  const destination = `"${matchPath}" of application${matchIds.length > 0 ? "s" : ""} ${matchIds.join(", ")}`;
323
323
  errors.push(
324
324
  `Overlapping path detected between ${source} and ${destination}`
@@ -809,8 +809,82 @@ var Microfrontends = class {
809
809
  }
810
810
  };
811
811
 
812
- // src/config-v2/microfrontends/server/utils/get-output-file-path.ts
812
+ // src/config-v2/microfrontends/utils/find-repository-root.ts
813
+ var import_node_fs = __toESM(require("fs"), 1);
813
814
  var import_node_path = __toESM(require("path"), 1);
815
+ var GIT_DIRECTORY = ".git";
816
+ function findRepositoryRoot(startDir) {
817
+ let currentDir = startDir || process.cwd();
818
+ while (currentDir !== import_node_path.default.parse(currentDir).root) {
819
+ const gitPath = import_node_path.default.join(currentDir, GIT_DIRECTORY);
820
+ if (import_node_fs.default.existsSync(gitPath) && import_node_fs.default.statSync(gitPath).isDirectory()) {
821
+ return currentDir;
822
+ }
823
+ currentDir = import_node_path.default.dirname(currentDir);
824
+ }
825
+ throw new Error(
826
+ "Repository root not found. Specify the root of the repository with the `repository.root` option."
827
+ );
828
+ }
829
+
830
+ // src/config-v2/microfrontends/utils/find-package-path.ts
831
+ var import_node_path2 = require("path");
832
+ var import_node_fs2 = require("fs");
833
+ var import_fast_glob = __toESM(require("fast-glob"), 1);
834
+ var configCache = {};
835
+ function findPackagePathWithGlob({
836
+ repositoryRoot,
837
+ name
838
+ }) {
839
+ try {
840
+ const packageJsonPaths = import_fast_glob.default.globSync("**/package.json", {
841
+ cwd: repositoryRoot,
842
+ absolute: true,
843
+ onlyFiles: true,
844
+ followSymbolicLinks: false,
845
+ ignore: ["**/node_modules/**", "**/.git/**"]
846
+ });
847
+ const matchingPaths = [];
848
+ for (const packageJsonPath2 of packageJsonPaths) {
849
+ const packageJsonContent = (0, import_node_fs2.readFileSync)(packageJsonPath2, "utf-8");
850
+ const packageJson = JSON.parse(packageJsonContent);
851
+ if (packageJson.name === name) {
852
+ matchingPaths.push(packageJsonPath2);
853
+ }
854
+ }
855
+ if (matchingPaths.length > 1) {
856
+ throw new Error(
857
+ `Found multiple packages with the name "${name}" in the repository: ${matchingPaths.join(", ")}`
858
+ );
859
+ }
860
+ if (matchingPaths.length === 0) {
861
+ throw new Error(
862
+ `Could not find package with the name "${name}" in the repository`
863
+ );
864
+ }
865
+ const [packageJsonPath] = matchingPaths;
866
+ return (0, import_node_path2.dirname)(packageJsonPath);
867
+ } catch (error) {
868
+ return null;
869
+ }
870
+ }
871
+ function findPackagePath(opts) {
872
+ const cacheKey = `${opts.repositoryRoot}-${opts.name}`;
873
+ if (configCache[cacheKey]) {
874
+ return configCache[cacheKey];
875
+ }
876
+ const result = findPackagePathWithGlob(opts);
877
+ if (!result) {
878
+ throw new Error(
879
+ `Could not find package with the name "${opts.name}" in the repository`
880
+ );
881
+ }
882
+ configCache[cacheKey] = result;
883
+ return result;
884
+ }
885
+
886
+ // src/config-v2/microfrontends/server/utils/get-output-file-path.ts
887
+ var import_node_path3 = __toESM(require("path"), 1);
814
888
 
815
889
  // src/config-v2/microfrontends/server/constants.ts
816
890
  var MFE_CONFIG_DEFAULT_FILE_PATH = "microfrontends";
@@ -824,13 +898,13 @@ function isVercel() {
824
898
  // src/config-v2/microfrontends/server/utils/get-output-file-path.ts
825
899
  function getOutputFilePath() {
826
900
  if (isVercel()) {
827
- return import_node_path.default.join(
901
+ return import_node_path3.default.join(
828
902
  ".vercel",
829
903
  MFE_CONFIG_DEFAULT_FILE_PATH,
830
904
  MFE_CONFIG_DEFAULT_FILE_NAME
831
905
  );
832
906
  }
833
- return import_node_path.default.join(MFE_CONFIG_DEFAULT_FILE_PATH, MFE_CONFIG_DEFAULT_FILE_NAME);
907
+ return import_node_path3.default.join(MFE_CONFIG_DEFAULT_FILE_PATH, MFE_CONFIG_DEFAULT_FILE_NAME);
834
908
  }
835
909
 
836
910
  // src/config-v2/microfrontends/server/validation.ts
@@ -1140,10 +1214,6 @@ var schema_v2_default = {
1140
1214
  type: "string",
1141
1215
  description: "flag name that can be used to enable/disable all paths in the group"
1142
1216
  },
1143
- routeToDefaultApplication: {
1144
- type: "boolean",
1145
- description: "True to route the request to the default application for this micro-frontends set-up. This must be `true` when using `flag` or when you want to use custom logic to make the routing decision for this group of paths."
1146
- },
1147
1217
  paths: {
1148
1218
  type: "array",
1149
1219
  items: {
@@ -1220,8 +1290,8 @@ var MicrofrontendsServer = class extends Microfrontends {
1220
1290
  pretty: true
1221
1291
  }) {
1222
1292
  const outputPath = getOutputFilePath();
1223
- import_node_fs.default.mkdirSync((0, import_node_path2.dirname)(outputPath), { recursive: true });
1224
- import_node_fs.default.writeFileSync(
1293
+ import_node_fs3.default.mkdirSync((0, import_node_path4.dirname)(outputPath), { recursive: true });
1294
+ import_node_fs3.default.writeFileSync(
1225
1295
  outputPath,
1226
1296
  JSON.stringify(
1227
1297
  this.config.toSchemaJson(),
@@ -1289,12 +1359,32 @@ var MicrofrontendsServer = class extends Microfrontends {
1289
1359
  static fromFile({
1290
1360
  filePath,
1291
1361
  cookies,
1292
- meta
1362
+ meta,
1363
+ options
1293
1364
  }) {
1294
1365
  try {
1295
- const config = import_node_fs.default.readFileSync(filePath, "utf-8");
1366
+ const configJson = import_node_fs3.default.readFileSync(filePath, "utf-8");
1367
+ const config = MicrofrontendsServer.validate(configJson);
1368
+ if (!isMainConfig(config) && (options == null ? void 0 : options.resolveMainConfig)) {
1369
+ const repositoryRoot = findRepositoryRoot();
1370
+ const packagePath = findPackagePath({
1371
+ repositoryRoot,
1372
+ name: config.partOf
1373
+ });
1374
+ if (!packagePath) {
1375
+ throw new MicrofrontendError(
1376
+ `Could not find default application "${config.partOf}" in the repository`,
1377
+ { type: "config", subtype: "not_found" }
1378
+ );
1379
+ }
1380
+ const mainConfigPath = (0, import_node_path4.join)(packagePath, "microfrontends.json");
1381
+ return MicrofrontendsServer.fromMainConfigFile({
1382
+ filePath: mainConfigPath,
1383
+ overrides: cookies ? parseOverrides(cookies) : void 0
1384
+ });
1385
+ }
1296
1386
  return new MicrofrontendsServer({
1297
- config: MicrofrontendsServer.validate(config),
1387
+ config,
1298
1388
  overrides: cookies ? parseOverrides(cookies) : void 0,
1299
1389
  meta
1300
1390
  });
@@ -1312,7 +1402,7 @@ var MicrofrontendsServer = class extends Microfrontends {
1312
1402
  overrides
1313
1403
  }) {
1314
1404
  try {
1315
- const config = import_node_fs.default.readFileSync(filePath, "utf-8");
1405
+ const config = import_node_fs3.default.readFileSync(filePath, "utf-8");
1316
1406
  const validatedConfig = MicrofrontendsServer.validate(config);
1317
1407
  if (!isMainConfig(validatedConfig)) {
1318
1408
  throw new MicrofrontendError(