@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
@@ -1,9 +1,9 @@
1
1
  // src/next-v2/config/index.ts
2
- import fs2 from "node:fs";
2
+ import fs3 from "node:fs";
3
3
 
4
4
  // src/config-v2/microfrontends/server/index.ts
5
- import fs from "node:fs";
6
- import { dirname } from "node:path";
5
+ import fs2 from "node:fs";
6
+ import { dirname as dirname2, join } from "node:path";
7
7
 
8
8
  // src/config-v2/overrides/constants.ts
9
9
  var OVERRIDES_COOKIE_PREFIX = "vercel-microfrontends-override";
@@ -187,21 +187,21 @@ var MicrofrontendConfigClient = class {
187
187
  isEqual(other) {
188
188
  return JSON.stringify(this.applications) === JSON.stringify(other.applications);
189
189
  }
190
- getApplicationNameForPath(path2) {
191
- if (!path2.startsWith("/")) {
190
+ getApplicationNameForPath(path3) {
191
+ if (!path3.startsWith("/")) {
192
192
  throw new Error(`Path must start with a /`);
193
193
  }
194
- if (this.pathCache[path2]) {
195
- return this.pathCache[path2];
194
+ if (this.pathCache[path3]) {
195
+ return this.pathCache[path3];
196
196
  }
197
- const pathname = new URL(path2, "https://example.com").pathname;
197
+ const pathname = new URL(path3, "https://example.com").pathname;
198
198
  for (const [name, application] of Object.entries(this.applications)) {
199
199
  if (application.routing) {
200
200
  for (const group of application.routing) {
201
201
  for (const childPath of group.paths) {
202
202
  const regexp = pathToRegexp(childPath);
203
203
  if (regexp.test(pathname)) {
204
- this.pathCache[path2] = name;
204
+ this.pathCache[path3] = name;
205
205
  return name;
206
206
  }
207
207
  }
@@ -214,7 +214,7 @@ var MicrofrontendConfigClient = class {
214
214
  if (!defaultApplication) {
215
215
  return null;
216
216
  }
217
- this.pathCache[path2] = defaultApplication[0];
217
+ this.pathCache[path3] = defaultApplication[0];
218
218
  return defaultApplication[0];
219
219
  }
220
220
  serialize() {
@@ -246,22 +246,22 @@ var validateConfigPaths = (applicationConfigsById) => {
246
246
  continue;
247
247
  }
248
248
  for (const pathMatch of app.routing) {
249
- for (const path2 of pathMatch.paths) {
250
- const tokens = parsePathRegexp(path2);
249
+ for (const path3 of pathMatch.paths) {
250
+ const tokens = parsePathRegexp(path3);
251
251
  for (const token of tokens.slice(0, -1)) {
252
252
  if (typeof token !== "string") {
253
253
  errors.push(
254
- `Path ${path2} may only have a :wildcard in the last path component`
254
+ `Path ${path3} may only have a :wildcard in the last path component`
255
255
  );
256
256
  }
257
257
  }
258
- const existing = pathsByApplicationId.get(path2);
258
+ const existing = pathsByApplicationId.get(path3);
259
259
  if (existing) {
260
260
  existing.applications.push(id);
261
261
  } else {
262
- pathsByApplicationId.set(path2, {
262
+ pathsByApplicationId.set(path3, {
263
263
  applications: [id],
264
- matcher: pathToRegexp2(path2),
264
+ matcher: pathToRegexp2(path3),
265
265
  applicationId: id
266
266
  });
267
267
  }
@@ -269,10 +269,10 @@ var validateConfigPaths = (applicationConfigsById) => {
269
269
  }
270
270
  }
271
271
  const entries = Array.from(pathsByApplicationId.entries());
272
- entries.forEach(([path2, { applications: ids, matcher, applicationId }]) => {
272
+ entries.forEach(([path3, { applications: ids, matcher, applicationId }]) => {
273
273
  if (ids.length > 1) {
274
274
  errors.push(
275
- `Duplicate path "${path2}" for applications "${ids.join(", ")}"`
275
+ `Duplicate path "${path3}" for applications "${ids.join(", ")}"`
276
276
  );
277
277
  }
278
278
  entries.forEach(
@@ -280,14 +280,14 @@ var validateConfigPaths = (applicationConfigsById) => {
280
280
  matchPath,
281
281
  { applications: matchIds, applicationId: matchApplicationId }
282
282
  ]) => {
283
- if (path2 === matchPath) {
283
+ if (path3 === matchPath) {
284
284
  return;
285
285
  }
286
286
  if (applicationId === matchApplicationId) {
287
287
  return;
288
288
  }
289
289
  if (matcher.test(matchPath)) {
290
- const source = `"${path2}" of application${ids.length > 0 ? "s" : ""} ${ids.join(", ")}`;
290
+ const source = `"${path3}" of application${ids.length > 0 ? "s" : ""} ${ids.join(", ")}`;
291
291
  const destination = `"${matchPath}" of application${matchIds.length > 0 ? "s" : ""} ${matchIds.join(", ")}`;
292
292
  errors.push(
293
293
  `Overlapping path detected between ${source} and ${destination}`
@@ -778,8 +778,82 @@ var Microfrontends = class {
778
778
  }
779
779
  };
780
780
 
781
- // src/config-v2/microfrontends/server/utils/get-output-file-path.ts
781
+ // src/config-v2/microfrontends/utils/find-repository-root.ts
782
+ import fs from "node:fs";
782
783
  import path from "node:path";
784
+ var GIT_DIRECTORY = ".git";
785
+ function findRepositoryRoot(startDir) {
786
+ let currentDir = startDir || process.cwd();
787
+ while (currentDir !== path.parse(currentDir).root) {
788
+ const gitPath = path.join(currentDir, GIT_DIRECTORY);
789
+ if (fs.existsSync(gitPath) && fs.statSync(gitPath).isDirectory()) {
790
+ return currentDir;
791
+ }
792
+ currentDir = path.dirname(currentDir);
793
+ }
794
+ throw new Error(
795
+ "Repository root not found. Specify the root of the repository with the `repository.root` option."
796
+ );
797
+ }
798
+
799
+ // src/config-v2/microfrontends/utils/find-package-path.ts
800
+ import { dirname } from "node:path";
801
+ import { readFileSync } from "node:fs";
802
+ import fg from "fast-glob";
803
+ var configCache = {};
804
+ function findPackagePathWithGlob({
805
+ repositoryRoot,
806
+ name
807
+ }) {
808
+ try {
809
+ const packageJsonPaths = fg.globSync("**/package.json", {
810
+ cwd: repositoryRoot,
811
+ absolute: true,
812
+ onlyFiles: true,
813
+ followSymbolicLinks: false,
814
+ ignore: ["**/node_modules/**", "**/.git/**"]
815
+ });
816
+ const matchingPaths = [];
817
+ for (const packageJsonPath2 of packageJsonPaths) {
818
+ const packageJsonContent = readFileSync(packageJsonPath2, "utf-8");
819
+ const packageJson = JSON.parse(packageJsonContent);
820
+ if (packageJson.name === name) {
821
+ matchingPaths.push(packageJsonPath2);
822
+ }
823
+ }
824
+ if (matchingPaths.length > 1) {
825
+ throw new Error(
826
+ `Found multiple packages with the name "${name}" in the repository: ${matchingPaths.join(", ")}`
827
+ );
828
+ }
829
+ if (matchingPaths.length === 0) {
830
+ throw new Error(
831
+ `Could not find package with the name "${name}" in the repository`
832
+ );
833
+ }
834
+ const [packageJsonPath] = matchingPaths;
835
+ return dirname(packageJsonPath);
836
+ } catch (error) {
837
+ return null;
838
+ }
839
+ }
840
+ function findPackagePath(opts) {
841
+ const cacheKey = `${opts.repositoryRoot}-${opts.name}`;
842
+ if (configCache[cacheKey]) {
843
+ return configCache[cacheKey];
844
+ }
845
+ const result = findPackagePathWithGlob(opts);
846
+ if (!result) {
847
+ throw new Error(
848
+ `Could not find package with the name "${opts.name}" in the repository`
849
+ );
850
+ }
851
+ configCache[cacheKey] = result;
852
+ return result;
853
+ }
854
+
855
+ // src/config-v2/microfrontends/server/utils/get-output-file-path.ts
856
+ import path2 from "node:path";
783
857
 
784
858
  // src/config-v2/microfrontends/server/constants.ts
785
859
  var MFE_CONFIG_DEFAULT_FILE_PATH = "microfrontends";
@@ -793,13 +867,13 @@ function isVercel() {
793
867
  // src/config-v2/microfrontends/server/utils/get-output-file-path.ts
794
868
  function getOutputFilePath() {
795
869
  if (isVercel()) {
796
- return path.join(
870
+ return path2.join(
797
871
  ".vercel",
798
872
  MFE_CONFIG_DEFAULT_FILE_PATH,
799
873
  MFE_CONFIG_DEFAULT_FILE_NAME
800
874
  );
801
875
  }
802
- return path.join(MFE_CONFIG_DEFAULT_FILE_PATH, MFE_CONFIG_DEFAULT_FILE_NAME);
876
+ return path2.join(MFE_CONFIG_DEFAULT_FILE_PATH, MFE_CONFIG_DEFAULT_FILE_NAME);
803
877
  }
804
878
 
805
879
  // src/config-v2/microfrontends/server/validation.ts
@@ -1109,10 +1183,6 @@ var schema_v2_default = {
1109
1183
  type: "string",
1110
1184
  description: "flag name that can be used to enable/disable all paths in the group"
1111
1185
  },
1112
- routeToDefaultApplication: {
1113
- type: "boolean",
1114
- 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."
1115
- },
1116
1186
  paths: {
1117
1187
  type: "array",
1118
1188
  items: {
@@ -1189,8 +1259,8 @@ var MicrofrontendsServer = class extends Microfrontends {
1189
1259
  pretty: true
1190
1260
  }) {
1191
1261
  const outputPath = getOutputFilePath();
1192
- fs.mkdirSync(dirname(outputPath), { recursive: true });
1193
- fs.writeFileSync(
1262
+ fs2.mkdirSync(dirname2(outputPath), { recursive: true });
1263
+ fs2.writeFileSync(
1194
1264
  outputPath,
1195
1265
  JSON.stringify(
1196
1266
  this.config.toSchemaJson(),
@@ -1258,12 +1328,32 @@ var MicrofrontendsServer = class extends Microfrontends {
1258
1328
  static fromFile({
1259
1329
  filePath,
1260
1330
  cookies,
1261
- meta
1331
+ meta,
1332
+ options
1262
1333
  }) {
1263
1334
  try {
1264
- const config = fs.readFileSync(filePath, "utf-8");
1335
+ const configJson = fs2.readFileSync(filePath, "utf-8");
1336
+ const config = MicrofrontendsServer.validate(configJson);
1337
+ if (!isMainConfig(config) && (options == null ? void 0 : options.resolveMainConfig)) {
1338
+ const repositoryRoot = findRepositoryRoot();
1339
+ const packagePath = findPackagePath({
1340
+ repositoryRoot,
1341
+ name: config.partOf
1342
+ });
1343
+ if (!packagePath) {
1344
+ throw new MicrofrontendError(
1345
+ `Could not find default application "${config.partOf}" in the repository`,
1346
+ { type: "config", subtype: "not_found" }
1347
+ );
1348
+ }
1349
+ const mainConfigPath = join(packagePath, "microfrontends.json");
1350
+ return MicrofrontendsServer.fromMainConfigFile({
1351
+ filePath: mainConfigPath,
1352
+ overrides: cookies ? parseOverrides(cookies) : void 0
1353
+ });
1354
+ }
1265
1355
  return new MicrofrontendsServer({
1266
- config: MicrofrontendsServer.validate(config),
1356
+ config,
1267
1357
  overrides: cookies ? parseOverrides(cookies) : void 0,
1268
1358
  meta
1269
1359
  });
@@ -1281,7 +1371,7 @@ var MicrofrontendsServer = class extends Microfrontends {
1281
1371
  overrides
1282
1372
  }) {
1283
1373
  try {
1284
- const config = fs.readFileSync(filePath, "utf-8");
1374
+ const config = fs2.readFileSync(filePath, "utf-8");
1285
1375
  const validatedConfig = MicrofrontendsServer.validate(config);
1286
1376
  if (!isMainConfig(validatedConfig)) {
1287
1377
  throw new MicrofrontendError(
@@ -1512,11 +1602,11 @@ ${table}
1512
1602
  `);
1513
1603
  }
1514
1604
  }
1515
- function pathToRewrites(path2) {
1605
+ function pathToRewrites(path3) {
1516
1606
  var _a;
1517
1607
  const regex = /(?<base>^.+)\/:.+\*$/;
1518
- const match = regex.exec(path2);
1519
- const paths = [path2];
1608
+ const match = regex.exec(path3);
1609
+ const paths = [path3];
1520
1610
  if ((_a = match == null ? void 0 : match.groups) == null ? void 0 : _a.base) {
1521
1611
  paths.unshift(match.groups.base);
1522
1612
  }
@@ -1564,9 +1654,7 @@ function transform4(args) {
1564
1654
  }
1565
1655
  });
1566
1656
  for (const group of routing) {
1567
- if (group.routeToDefaultApplication) {
1568
- continue;
1569
- } else if (group.flag) {
1657
+ if (group.flag) {
1570
1658
  continue;
1571
1659
  } else {
1572
1660
  for (const source of group.paths) {
@@ -1766,7 +1854,7 @@ function getApplicationContext(opts) {
1766
1854
  return { name: opts.appName };
1767
1855
  }
1768
1856
  try {
1769
- const packageJsonString = fs2.readFileSync("./package.json", "utf-8");
1857
+ const packageJsonString = fs3.readFileSync("./package.json", "utf-8");
1770
1858
  const packageJson = JSON.parse(packageJsonString);
1771
1859
  if (!packageJson.name) {
1772
1860
  throw new MicrofrontendError(