@vercel/microfrontends 2.0.0-canary.0 → 2.0.0-canary.2

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 (45) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +21 -4
  3. package/dist/bin/cli.cjs +156 -20
  4. package/dist/config.cjs +123 -3
  5. package/dist/config.cjs.map +1 -1
  6. package/dist/config.d.ts +33 -2
  7. package/dist/config.js +122 -2
  8. package/dist/config.js.map +1 -1
  9. package/dist/experimental/sveltekit.cjs +128 -4
  10. package/dist/experimental/sveltekit.cjs.map +1 -1
  11. package/dist/experimental/sveltekit.js +127 -3
  12. package/dist/experimental/sveltekit.js.map +1 -1
  13. package/dist/experimental/vite.cjs +128 -4
  14. package/dist/experimental/vite.cjs.map +1 -1
  15. package/dist/experimental/vite.js +127 -3
  16. package/dist/experimental/vite.js.map +1 -1
  17. package/dist/microfrontends/server.cjs +128 -4
  18. package/dist/microfrontends/server.cjs.map +1 -1
  19. package/dist/microfrontends/server.d.ts +4 -3
  20. package/dist/microfrontends/server.js +127 -3
  21. package/dist/microfrontends/server.js.map +1 -1
  22. package/dist/next/config.cjs +131 -131
  23. package/dist/next/config.cjs.map +1 -1
  24. package/dist/next/config.d.ts +5 -0
  25. package/dist/next/config.js +130 -130
  26. package/dist/next/config.js.map +1 -1
  27. package/dist/next/middleware.cjs +125 -105
  28. package/dist/next/middleware.cjs.map +1 -1
  29. package/dist/next/middleware.js +125 -105
  30. package/dist/next/middleware.js.map +1 -1
  31. package/dist/next/testing.cjs +126 -6
  32. package/dist/next/testing.cjs.map +1 -1
  33. package/dist/next/testing.d.ts +2 -2
  34. package/dist/next/testing.js +124 -4
  35. package/dist/next/testing.js.map +1 -1
  36. package/dist/overrides.d.ts +3 -3
  37. package/dist/schema.d.ts +2 -2
  38. package/dist/{types-4299bff1.d.ts → types-88602303.d.ts} +1 -1
  39. package/dist/{types-0deb756b.d.ts → types-e7523e61.d.ts} +1 -1
  40. package/dist/utils/mfe-port.cjs +128 -4
  41. package/dist/utils/mfe-port.cjs.map +1 -1
  42. package/dist/utils/mfe-port.js +127 -3
  43. package/dist/utils/mfe-port.js.map +1 -1
  44. package/dist/validation.d.ts +1 -1
  45. package/package.json +7 -2
@@ -387,8 +387,106 @@ function findConfig({ dir }) {
387
387
  // src/config/microfrontends-config/isomorphic/index.ts
388
388
  var import_jsonc_parser2 = require("jsonc-parser");
389
389
 
390
- // src/config/microfrontends-config/isomorphic/validation.ts
390
+ // src/config/microfrontends-config/client/index.ts
391
391
  var import_path_to_regexp = require("path-to-regexp");
392
+ var regexpCache = /* @__PURE__ */ new Map();
393
+ var getRegexp = (path6) => {
394
+ const existing = regexpCache.get(path6);
395
+ if (existing) {
396
+ return existing;
397
+ }
398
+ const regexp = (0, import_path_to_regexp.pathToRegexp)(path6);
399
+ regexpCache.set(path6, regexp);
400
+ return regexp;
401
+ };
402
+ var MicrofrontendConfigClient = class {
403
+ constructor(config, opts) {
404
+ this.pathCache = {};
405
+ this.hasFlaggedPaths = config.hasFlaggedPaths ?? false;
406
+ for (const app of Object.values(config.applications)) {
407
+ if (app.routing) {
408
+ if (app.routing.some((match) => match.flag)) {
409
+ this.hasFlaggedPaths = true;
410
+ }
411
+ const newRouting = [];
412
+ const pathsWithoutFlags = [];
413
+ for (const group of app.routing) {
414
+ if (group.flag) {
415
+ if (opts?.removeFlaggedPaths) {
416
+ continue;
417
+ }
418
+ if (group.group) {
419
+ delete group.group;
420
+ }
421
+ newRouting.push(group);
422
+ } else {
423
+ pathsWithoutFlags.push(...group.paths);
424
+ }
425
+ }
426
+ if (pathsWithoutFlags.length > 0) {
427
+ newRouting.push({ paths: pathsWithoutFlags });
428
+ }
429
+ app.routing = newRouting;
430
+ }
431
+ }
432
+ this.serialized = config;
433
+ if (this.hasFlaggedPaths) {
434
+ this.serialized.hasFlaggedPaths = this.hasFlaggedPaths;
435
+ }
436
+ this.applications = config.applications;
437
+ }
438
+ /**
439
+ * Create a new `MicrofrontendConfigClient` from a JSON string.
440
+ * Config must be passed in to remain framework agnostic
441
+ */
442
+ static fromEnv(config) {
443
+ if (!config) {
444
+ throw new Error(
445
+ "Could not construct MicrofrontendConfigClient: configuration is empty or undefined. Did you set up your application with `withMicrofrontends`?"
446
+ );
447
+ }
448
+ return new MicrofrontendConfigClient(JSON.parse(config));
449
+ }
450
+ isEqual(other) {
451
+ return this === other || JSON.stringify(this.applications) === JSON.stringify(other.applications);
452
+ }
453
+ getApplicationNameForPath(path6) {
454
+ if (!path6.startsWith("/")) {
455
+ throw new Error(`Path must start with a /`);
456
+ }
457
+ if (this.pathCache[path6]) {
458
+ return this.pathCache[path6];
459
+ }
460
+ const pathname = new URL(path6, "https://example.com").pathname;
461
+ for (const [name, application] of Object.entries(this.applications)) {
462
+ if (application.routing) {
463
+ for (const group of application.routing) {
464
+ for (const childPath of group.paths) {
465
+ const regexp = getRegexp(childPath);
466
+ if (regexp.test(pathname)) {
467
+ this.pathCache[path6] = name;
468
+ return name;
469
+ }
470
+ }
471
+ }
472
+ }
473
+ }
474
+ const defaultApplication = Object.entries(this.applications).find(
475
+ ([, application]) => application.default
476
+ );
477
+ if (!defaultApplication) {
478
+ return null;
479
+ }
480
+ this.pathCache[path6] = defaultApplication[0];
481
+ return defaultApplication[0];
482
+ }
483
+ serialize() {
484
+ return this.serialized;
485
+ }
486
+ };
487
+
488
+ // src/config/microfrontends-config/isomorphic/validation.ts
489
+ var import_path_to_regexp2 = require("path-to-regexp");
392
490
  var LIST_FORMATTER = new Intl.ListFormat("en", {
393
491
  style: "long",
394
492
  type: "conjunction"
@@ -416,7 +514,7 @@ var validateConfigPaths = (applicationConfigsById) => {
416
514
  } else {
417
515
  pathsByApplicationId.set(path6, {
418
516
  applications: [id],
419
- matcher: (0, import_path_to_regexp.pathToRegexp)(path6),
517
+ matcher: (0, import_path_to_regexp2.pathToRegexp)(path6),
420
518
  applicationId: id
421
519
  });
422
520
  }
@@ -463,7 +561,7 @@ var validateConfigPaths = (applicationConfigsById) => {
463
561
  var PATH_DEFAULT_PATTERN = "[^\\/#\\?]+?";
464
562
  function validatePathExpression(path6) {
465
563
  try {
466
- const tokens = (0, import_path_to_regexp.parse)(path6);
564
+ const tokens = (0, import_path_to_regexp2.parse)(path6);
467
565
  if (/(?<!\\)\{/.test(path6)) {
468
566
  return `Optional paths are not supported: ${path6}`;
469
567
  }
@@ -921,6 +1019,28 @@ var MicrofrontendConfigIsomorphic = class {
921
1019
  getLocalProxyPort() {
922
1020
  return this.config.options?.localProxyPort ?? DEFAULT_LOCAL_PROXY_PORT;
923
1021
  }
1022
+ toClientConfig(options) {
1023
+ const applications = Object.fromEntries(
1024
+ Object.entries(this.childApplications).map(([name, application]) => [
1025
+ hashApplicationName(name),
1026
+ {
1027
+ default: false,
1028
+ routing: application.routing
1029
+ }
1030
+ ])
1031
+ );
1032
+ applications[hashApplicationName(this.defaultApplication.name)] = {
1033
+ default: true
1034
+ };
1035
+ return new MicrofrontendConfigClient(
1036
+ {
1037
+ applications
1038
+ },
1039
+ {
1040
+ removeFlaggedPaths: options?.removeFlaggedPaths
1041
+ }
1042
+ );
1043
+ }
924
1044
  /**
925
1045
  * Serializes the class back to the Schema type.
926
1046
  *
@@ -1340,6 +1460,7 @@ var MicrofrontendsServer = class {
1340
1460
  * This can return either a Child or Main configuration.
1341
1461
  */
1342
1462
  static infer({
1463
+ appName,
1343
1464
  directory,
1344
1465
  filePath,
1345
1466
  cookies
@@ -1352,7 +1473,10 @@ var MicrofrontendsServer = class {
1352
1473
  }
1353
1474
  try {
1354
1475
  const packageRoot = findPackageRoot(directory);
1355
- const applicationContext = getApplicationContext({ packageRoot });
1476
+ const applicationContext = getApplicationContext({
1477
+ appName,
1478
+ packageRoot
1479
+ });
1356
1480
  const maybeConfig = findConfig({ dir: packageRoot });
1357
1481
  if (maybeConfig) {
1358
1482
  return MicrofrontendsServer.fromFile({