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