@vercel/microfrontends 2.2.1 → 2.2.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 (59) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/cli/index.cjs +0 -1
  3. package/dist/bin/cli.cjs +483 -394
  4. package/dist/config.cjs +191 -169
  5. package/dist/config.cjs.map +1 -1
  6. package/dist/config.d.ts +3 -2
  7. package/dist/config.js +192 -170
  8. package/dist/config.js.map +1 -1
  9. package/dist/experimental/sveltekit.cjs +583 -511
  10. package/dist/experimental/sveltekit.cjs.map +1 -1
  11. package/dist/experimental/sveltekit.js +589 -517
  12. package/dist/experimental/sveltekit.js.map +1 -1
  13. package/dist/experimental/vite.cjs +605 -533
  14. package/dist/experimental/vite.cjs.map +1 -1
  15. package/dist/experimental/vite.js +614 -542
  16. package/dist/experimental/vite.js.map +1 -1
  17. package/dist/microfrontends/server.cjs +601 -529
  18. package/dist/microfrontends/server.cjs.map +1 -1
  19. package/dist/microfrontends/server.d.ts +2 -2
  20. package/dist/microfrontends/server.js +607 -535
  21. package/dist/microfrontends/server.js.map +1 -1
  22. package/dist/microfrontends/utils.cjs +101 -50
  23. package/dist/microfrontends/utils.cjs.map +1 -1
  24. package/dist/microfrontends/utils.d.ts +4 -4
  25. package/dist/microfrontends/utils.js +102 -51
  26. package/dist/microfrontends/utils.js.map +1 -1
  27. package/dist/next/client.cjs +1 -1
  28. package/dist/next/client.cjs.map +1 -1
  29. package/dist/next/client.d.ts +8 -8
  30. package/dist/next/client.js +1 -1
  31. package/dist/next/client.js.map +1 -1
  32. package/dist/next/config.cjs +723 -647
  33. package/dist/next/config.cjs.map +1 -1
  34. package/dist/next/config.js +720 -644
  35. package/dist/next/config.js.map +1 -1
  36. package/dist/next/middleware.cjs +244 -222
  37. package/dist/next/middleware.cjs.map +1 -1
  38. package/dist/next/middleware.js +245 -223
  39. package/dist/next/middleware.js.map +1 -1
  40. package/dist/next/testing.cjs +192 -170
  41. package/dist/next/testing.cjs.map +1 -1
  42. package/dist/next/testing.d.ts +1 -1
  43. package/dist/next/testing.js +193 -171
  44. package/dist/next/testing.js.map +1 -1
  45. package/dist/overrides.cjs +5 -5
  46. package/dist/overrides.cjs.map +1 -1
  47. package/dist/overrides.d.ts +9 -9
  48. package/dist/overrides.js +5 -5
  49. package/dist/overrides.js.map +1 -1
  50. package/dist/utils/mfe-port.cjs +620 -533
  51. package/dist/utils/mfe-port.cjs.map +1 -1
  52. package/dist/utils/mfe-port.d.ts +9 -1
  53. package/dist/utils/mfe-port.js +632 -546
  54. package/dist/utils/mfe-port.js.map +1 -1
  55. package/dist/validation.cjs +8 -24
  56. package/dist/validation.cjs.map +1 -1
  57. package/dist/validation.js +8 -24
  58. package/dist/validation.js.map +1 -1
  59. package/package.json +4 -6
@@ -39,45 +39,33 @@ module.exports = __toCommonJS(middleware_exports);
39
39
  var import_server = require("next/server");
40
40
  var import_path_to_regexp3 = require("path-to-regexp");
41
41
 
42
- // src/config/well-known/endpoints.ts
43
- async function getWellKnownClientData(config, flagValues = {}) {
44
- const clientConfig = config.toClientConfig();
45
- for (const [applicationName, application] of Object.entries(
46
- clientConfig.applications
47
- )) {
48
- if (!application.routing) {
49
- continue;
50
- }
51
- const allPaths = [];
52
- for (const pathGroup of application.routing) {
53
- if (pathGroup.flag) {
54
- const flagName = pathGroup.flag;
55
- const flagFn = flagValues[flagName];
56
- if (!flagFn) {
57
- throw new Error(
58
- `Flag "${flagName}" was specified to control routing for path group "${pathGroup.group}" in application ${applicationName} but not found in provided flag values.`
59
- );
60
- }
61
- const flagEnabled = await flagFn();
62
- if (flagEnabled) {
63
- allPaths.push(...pathGroup.paths);
64
- }
65
- } else {
66
- allPaths.push(...pathGroup.paths);
67
- }
68
- }
69
- application.routing = allPaths.length > 0 ? [{ paths: allPaths }] : [];
70
- }
71
- return {
72
- config: clientConfig.serialize()
73
- };
74
- }
75
-
76
42
  // src/bin/local-proxy-is-running.ts
77
43
  function localProxyIsRunning() {
78
44
  return process.env.TURBO_TASK_HAS_MFE_PROXY === "true";
79
45
  }
80
46
 
47
+ // src/bin/logger.ts
48
+ function debug(...args) {
49
+ if (process.env.MFE_DEBUG) {
50
+ console.log(...args);
51
+ }
52
+ }
53
+ function info(...args) {
54
+ console.log(...args);
55
+ }
56
+ function warn(...args) {
57
+ console.warn(...args);
58
+ }
59
+ function error(...args) {
60
+ console.error(...args);
61
+ }
62
+ var logger = {
63
+ debug,
64
+ info,
65
+ warn,
66
+ error
67
+ };
68
+
81
69
  // src/config/microfrontends-config/isomorphic/index.ts
82
70
  var import_jsonc_parser = require("jsonc-parser");
83
71
 
@@ -173,23 +161,6 @@ var MicrofrontendError = class extends Error {
173
161
  }
174
162
  };
175
163
 
176
- // src/config/microfrontends-config/utils/get-config-from-env.ts
177
- function getConfigStringFromEnv() {
178
- const config = process.env.MFE_CONFIG;
179
- if (!config) {
180
- throw new MicrofrontendError(`Missing "MFE_CONFIG" in environment.`, {
181
- type: "config",
182
- subtype: "not_found_in_env"
183
- });
184
- }
185
- return config;
186
- }
187
-
188
- // src/config/schema/utils/is-default-app.ts
189
- function isDefaultApp(a) {
190
- return !("routing" in a);
191
- }
192
-
193
164
  // src/config/overrides/constants.ts
194
165
  var OVERRIDES_COOKIE_PREFIX = "vercel-micro-frontends-override";
195
166
  var OVERRIDES_ENV_COOKIE_PREFIX = `${OVERRIDES_COOKIE_PREFIX}:env:`;
@@ -223,6 +194,11 @@ function parseOverrides(cookies) {
223
194
  return overridesConfig;
224
195
  }
225
196
 
197
+ // src/config/schema/utils/is-default-app.ts
198
+ function isDefaultApp(a) {
199
+ return !("routing" in a);
200
+ }
201
+
226
202
  // src/config/microfrontends-config/client/index.ts
227
203
  var import_path_to_regexp = require("path-to-regexp");
228
204
  var regexpCache = /* @__PURE__ */ new Map();
@@ -321,6 +297,183 @@ var MicrofrontendConfigClient = class {
321
297
  }
322
298
  };
323
299
 
300
+ // src/config/microfrontends-config/utils/get-config-from-env.ts
301
+ function getConfigStringFromEnv() {
302
+ const config = process.env.MFE_CONFIG;
303
+ if (!config) {
304
+ throw new MicrofrontendError(`Missing "MFE_CONFIG" in environment.`, {
305
+ type: "config",
306
+ subtype: "not_found_in_env"
307
+ });
308
+ }
309
+ return config;
310
+ }
311
+
312
+ // src/config/microfrontends-config/isomorphic/constants.ts
313
+ var DEFAULT_LOCAL_PROXY_PORT = 3024;
314
+ var MFE_APP_PORT_ENV = "MFE_APP_PORT";
315
+ var MFE_LOCAL_PROXY_PORT_ENV = "MFE_LOCAL_PROXY_PORT";
316
+
317
+ // src/config/microfrontends-config/isomorphic/utils/generate-port.ts
318
+ function generatePortFromName({
319
+ name,
320
+ minPort = 3e3,
321
+ maxPort = 8e3
322
+ }) {
323
+ if (!name) {
324
+ throw new Error("Name is required to generate a port");
325
+ }
326
+ let hash = 0;
327
+ for (let i = 0; i < name.length; i++) {
328
+ hash = (hash << 5) - hash + name.charCodeAt(i);
329
+ hash |= 0;
330
+ }
331
+ hash = Math.abs(hash);
332
+ const range = maxPort - minPort;
333
+ const port = minPort + hash % range;
334
+ return port;
335
+ }
336
+
337
+ // src/config/microfrontends-config/isomorphic/host.ts
338
+ var Host = class {
339
+ constructor(hostConfig, options) {
340
+ if (typeof hostConfig === "string") {
341
+ ({
342
+ protocol: this.protocol,
343
+ host: this.host,
344
+ port: this.port
345
+ } = Host.parseUrl(hostConfig));
346
+ } else {
347
+ const { protocol = "https", host, port } = hostConfig;
348
+ this.protocol = protocol;
349
+ this.host = host;
350
+ this.port = port;
351
+ }
352
+ this.local = options?.isLocal;
353
+ }
354
+ static parseUrl(url, defaultProtocol = "https") {
355
+ let hostToParse = url;
356
+ if (!/^https?:\/\//.exec(hostToParse)) {
357
+ hostToParse = `${defaultProtocol}://${hostToParse}`;
358
+ }
359
+ const parsed = new URL(hostToParse);
360
+ if (!parsed.hostname) {
361
+ throw new Error(Host.getMicrofrontendsError(url, "requires a host"));
362
+ }
363
+ if (parsed.hash) {
364
+ throw new Error(
365
+ Host.getMicrofrontendsError(url, "cannot have a fragment")
366
+ );
367
+ }
368
+ if (parsed.username || parsed.password) {
369
+ throw new Error(
370
+ Host.getMicrofrontendsError(
371
+ url,
372
+ "cannot have authentication credentials (username and/or password)"
373
+ )
374
+ );
375
+ }
376
+ if (parsed.pathname !== "/") {
377
+ throw new Error(Host.getMicrofrontendsError(url, "cannot have a path"));
378
+ }
379
+ if (parsed.search) {
380
+ throw new Error(
381
+ Host.getMicrofrontendsError(url, "cannot have query parameters")
382
+ );
383
+ }
384
+ const protocol = parsed.protocol.slice(0, -1);
385
+ return {
386
+ protocol,
387
+ host: parsed.hostname,
388
+ port: parsed.port ? Number.parseInt(parsed.port, 10) : void 0
389
+ };
390
+ }
391
+ static getMicrofrontendsError(url, message) {
392
+ return `Microfrontends configuration error: the URL ${url} in your microfrontends.json ${message}.`;
393
+ }
394
+ isLocal() {
395
+ return this.local || this.host === "localhost" || this.host === "127.0.0.1";
396
+ }
397
+ toString() {
398
+ const url = this.toUrl();
399
+ return url.toString().replace(/\/$/, "");
400
+ }
401
+ toUrl() {
402
+ const url = `${this.protocol}://${this.host}${this.port ? `:${this.port}` : ""}`;
403
+ return new URL(url);
404
+ }
405
+ };
406
+ var LocalHost = class extends Host {
407
+ constructor({
408
+ appName,
409
+ local
410
+ }) {
411
+ const portOverride = process.env[MFE_APP_PORT_ENV];
412
+ if (portOverride) {
413
+ const overridePort = Number.parseInt(portOverride, 10);
414
+ if (!Number.isNaN(overridePort) && overridePort > 0 && overridePort < 65536) {
415
+ super({
416
+ protocol: "http",
417
+ host: "localhost",
418
+ port: overridePort
419
+ });
420
+ return;
421
+ }
422
+ }
423
+ let protocol;
424
+ let host;
425
+ let port;
426
+ if (typeof local === "number") {
427
+ port = local;
428
+ } else if (typeof local === "string") {
429
+ if (/^\d+$/.test(local)) {
430
+ port = Number.parseInt(local, 10);
431
+ } else {
432
+ const parsed = Host.parseUrl(local, "http");
433
+ protocol = parsed.protocol;
434
+ host = parsed.host;
435
+ port = parsed.port;
436
+ }
437
+ } else if (local) {
438
+ protocol = local.protocol;
439
+ host = local.host;
440
+ port = local.port;
441
+ }
442
+ super({
443
+ protocol: protocol ?? "http",
444
+ host: host ?? "localhost",
445
+ port: port ?? generatePortFromName({ name: appName })
446
+ });
447
+ }
448
+ };
449
+
450
+ // src/config/microfrontends-config/isomorphic/utils/hash-application-name.ts
451
+ var import_md5 = __toESM(require("md5"), 1);
452
+ function hashApplicationName(name) {
453
+ if (!name) {
454
+ throw new Error("Application name is required to generate hash");
455
+ }
456
+ return (0, import_md5.default)(name).substring(0, 6).padStart(6, "0");
457
+ }
458
+
459
+ // src/config/microfrontends-config/isomorphic/utils/generate-asset-prefix.ts
460
+ var PREFIX = "vc-ap";
461
+ function generateAssetPrefixFromName({
462
+ name
463
+ }) {
464
+ if (!name) {
465
+ throw new Error("Name is required to generate an asset prefix");
466
+ }
467
+ return `${PREFIX}-${hashApplicationName(name)}`;
468
+ }
469
+
470
+ // src/config/microfrontends-config/isomorphic/utils/generate-automation-bypass-env-var-name.ts
471
+ function generateAutomationBypassEnvVarName({
472
+ name
473
+ }) {
474
+ return `AUTOMATION_BYPASS_${name.toUpperCase().replace(/[^a-zA-Z0-9]/g, "_")}`;
475
+ }
476
+
324
477
  // src/config/microfrontends-config/isomorphic/validation.ts
325
478
  var import_path_to_regexp2 = require("path-to-regexp");
326
479
  var LIST_FORMATTER = new Intl.ListFormat("en", {
@@ -502,154 +655,6 @@ var validateConfigDefaultApplication = (applicationConfigsById) => {
502
655
  }
503
656
  };
504
657
 
505
- // src/config/microfrontends-config/isomorphic/utils/hash-application-name.ts
506
- var import_md5 = __toESM(require("md5"), 1);
507
- function hashApplicationName(name) {
508
- if (!name) {
509
- throw new Error("Application name is required to generate hash");
510
- }
511
- return (0, import_md5.default)(name).substring(0, 6).padStart(6, "0");
512
- }
513
-
514
- // src/config/microfrontends-config/isomorphic/utils/generate-asset-prefix.ts
515
- var PREFIX = "vc-ap";
516
- function generateAssetPrefixFromName({
517
- name
518
- }) {
519
- if (!name) {
520
- throw new Error("Name is required to generate an asset prefix");
521
- }
522
- return `${PREFIX}-${hashApplicationName(name)}`;
523
- }
524
-
525
- // src/config/microfrontends-config/isomorphic/utils/generate-port.ts
526
- function generatePortFromName({
527
- name,
528
- minPort = 3e3,
529
- maxPort = 8e3
530
- }) {
531
- if (!name) {
532
- throw new Error("Name is required to generate a port");
533
- }
534
- let hash = 0;
535
- for (let i = 0; i < name.length; i++) {
536
- hash = (hash << 5) - hash + name.charCodeAt(i);
537
- hash |= 0;
538
- }
539
- hash = Math.abs(hash);
540
- const range = maxPort - minPort;
541
- const port = minPort + hash % range;
542
- return port;
543
- }
544
-
545
- // src/config/microfrontends-config/isomorphic/host.ts
546
- var Host = class {
547
- constructor(hostConfig, options) {
548
- if (typeof hostConfig === "string") {
549
- ({
550
- protocol: this.protocol,
551
- host: this.host,
552
- port: this.port
553
- } = Host.parseUrl(hostConfig));
554
- } else {
555
- const { protocol = "https", host, port } = hostConfig;
556
- this.protocol = protocol;
557
- this.host = host;
558
- this.port = port;
559
- }
560
- this.local = options?.isLocal;
561
- }
562
- static parseUrl(url, defaultProtocol = "https") {
563
- let hostToParse = url;
564
- if (!/^https?:\/\//.exec(hostToParse)) {
565
- hostToParse = `${defaultProtocol}://${hostToParse}`;
566
- }
567
- const parsed = new URL(hostToParse);
568
- if (!parsed.hostname) {
569
- throw new Error(Host.getMicrofrontendsError(url, "requires a host"));
570
- }
571
- if (parsed.hash) {
572
- throw new Error(
573
- Host.getMicrofrontendsError(url, "cannot have a fragment")
574
- );
575
- }
576
- if (parsed.username || parsed.password) {
577
- throw new Error(
578
- Host.getMicrofrontendsError(
579
- url,
580
- "cannot have authentication credentials (username and/or password)"
581
- )
582
- );
583
- }
584
- if (parsed.pathname !== "/") {
585
- throw new Error(Host.getMicrofrontendsError(url, "cannot have a path"));
586
- }
587
- if (parsed.search) {
588
- throw new Error(
589
- Host.getMicrofrontendsError(url, "cannot have query parameters")
590
- );
591
- }
592
- const protocol = parsed.protocol.slice(0, -1);
593
- return {
594
- protocol,
595
- host: parsed.hostname,
596
- port: parsed.port ? Number.parseInt(parsed.port) : void 0
597
- };
598
- }
599
- static getMicrofrontendsError(url, message) {
600
- return `Microfrontends configuration error: the URL ${url} in your microfrontends.json ${message}.`;
601
- }
602
- isLocal() {
603
- return this.local || this.host === "localhost" || this.host === "127.0.0.1";
604
- }
605
- toString() {
606
- const url = this.toUrl();
607
- return url.toString().replace(/\/$/, "");
608
- }
609
- toUrl() {
610
- const url = `${this.protocol}://${this.host}${this.port ? `:${this.port}` : ""}`;
611
- return new URL(url);
612
- }
613
- };
614
- var LocalHost = class extends Host {
615
- constructor({
616
- appName,
617
- local
618
- }) {
619
- let protocol;
620
- let host;
621
- let port;
622
- if (typeof local === "number") {
623
- port = local;
624
- } else if (typeof local === "string") {
625
- if (/^\d+$/.test(local)) {
626
- port = Number.parseInt(local);
627
- } else {
628
- const parsed = Host.parseUrl(local, "http");
629
- protocol = parsed.protocol;
630
- host = parsed.host;
631
- port = parsed.port;
632
- }
633
- } else if (local) {
634
- protocol = local.protocol;
635
- host = local.host;
636
- port = local.port;
637
- }
638
- super({
639
- protocol: protocol ?? "http",
640
- host: host ?? "localhost",
641
- port: port ?? generatePortFromName({ name: appName })
642
- });
643
- }
644
- };
645
-
646
- // src/config/microfrontends-config/isomorphic/utils/generate-automation-bypass-env-var-name.ts
647
- function generateAutomationBypassEnvVarName({
648
- name
649
- }) {
650
- return `AUTOMATION_BYPASS_${name.toUpperCase().replace(/[^a-zA-Z0-9]/g, "_")}`;
651
- }
652
-
653
658
  // src/config/microfrontends-config/isomorphic/application.ts
654
659
  var Application = class {
655
660
  constructor(name, {
@@ -730,9 +735,6 @@ var ChildApplication = class extends Application {
730
735
  }
731
736
  };
732
737
 
733
- // src/config/microfrontends-config/isomorphic/constants.ts
734
- var DEFAULT_LOCAL_PROXY_PORT = 3024;
735
-
736
738
  // src/config/microfrontends-config/isomorphic/index.ts
737
739
  var MicrofrontendConfigIsomorphic = class {
738
740
  constructor({
@@ -851,9 +853,17 @@ var MicrofrontendConfigIsomorphic = class {
851
853
  return this.defaultApplication;
852
854
  }
853
855
  /**
854
- * Returns the configured port for the local proxy
856
+ * Returns the configured port for the local proxy.
857
+ * Can be overridden via MFE_LOCAL_PROXY_PORT environment variable.
855
858
  */
856
859
  getLocalProxyPort() {
860
+ const portOverride = process.env[MFE_LOCAL_PROXY_PORT_ENV];
861
+ if (portOverride) {
862
+ const port = Number.parseInt(portOverride, 10);
863
+ if (!Number.isNaN(port) && port > 0 && port < 65536) {
864
+ return port;
865
+ }
866
+ }
857
867
  return this.config.options?.localProxyPort ?? DEFAULT_LOCAL_PROXY_PORT;
858
868
  }
859
869
  toClientConfig(options) {
@@ -891,27 +901,39 @@ var MicrofrontendConfigIsomorphic = class {
891
901
  }
892
902
  };
893
903
 
894
- // src/bin/logger.ts
895
- function debug(...args) {
896
- if (process.env.MFE_DEBUG) {
897
- console.log(...args);
904
+ // src/config/well-known/endpoints.ts
905
+ async function getWellKnownClientData(config, flagValues = {}) {
906
+ const clientConfig = config.toClientConfig();
907
+ for (const [applicationName, application] of Object.entries(
908
+ clientConfig.applications
909
+ )) {
910
+ if (!application.routing) {
911
+ continue;
912
+ }
913
+ const allPaths = [];
914
+ for (const pathGroup of application.routing) {
915
+ if (pathGroup.flag) {
916
+ const flagName = pathGroup.flag;
917
+ const flagFn = flagValues[flagName];
918
+ if (!flagFn) {
919
+ throw new Error(
920
+ `Flag "${flagName}" was specified to control routing for path group "${pathGroup.group}" in application ${applicationName} but not found in provided flag values.`
921
+ );
922
+ }
923
+ const flagEnabled = await flagFn();
924
+ if (flagEnabled) {
925
+ allPaths.push(...pathGroup.paths);
926
+ }
927
+ } else {
928
+ allPaths.push(...pathGroup.paths);
929
+ }
930
+ }
931
+ application.routing = allPaths.length > 0 ? [{ paths: allPaths }] : [];
898
932
  }
933
+ return {
934
+ config: clientConfig.serialize()
935
+ };
899
936
  }
900
- function info(...args) {
901
- console.log(...args);
902
- }
903
- function warn(...args) {
904
- console.warn(...args);
905
- }
906
- function error(...args) {
907
- console.error(...args);
908
- }
909
- var logger = {
910
- debug,
911
- info,
912
- warn,
913
- error
914
- };
915
937
 
916
938
  // src/next/middleware/middleware.ts
917
939
  function getMfeFlagHeader(req) {