@vercel/microfrontends 0.9.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 (90) hide show
  1. package/README.md +7 -7
  2. package/dist/bin/cli.cjs +1604 -221
  3. package/dist/config/client.d.ts +1 -1
  4. package/dist/config/edge.cjs +47 -47
  5. package/dist/config/edge.cjs.map +1 -1
  6. package/dist/config/edge.d.ts +6 -6
  7. package/dist/config/edge.js +46 -46
  8. package/dist/config/edge.js.map +1 -1
  9. package/dist/config.cjs +67 -66
  10. package/dist/config.cjs.map +1 -1
  11. package/dist/config.d.ts +4 -4
  12. package/dist/config.js +66 -65
  13. package/dist/config.js.map +1 -1
  14. package/dist/{index-eff254d8.d.ts → index-acb44057.d.ts} +12 -23
  15. package/dist/{micro-frontend-config-42886104.d.ts → microfrontend-config-983a5139.d.ts} +13 -13
  16. package/dist/next/client.cjs +1 -1
  17. package/dist/next/client.cjs.map +1 -1
  18. package/dist/next/client.js +1 -1
  19. package/dist/next/client.js.map +1 -1
  20. package/dist/next/config.cjs +86 -87
  21. package/dist/next/config.cjs.map +1 -1
  22. package/dist/next/config.d.ts +3 -3
  23. package/dist/next/config.js +85 -86
  24. package/dist/next/config.js.map +1 -1
  25. package/dist/next/middleware.cjs +60 -62
  26. package/dist/next/middleware.cjs.map +1 -1
  27. package/dist/next/middleware.d.ts +11 -11
  28. package/dist/next/middleware.js +58 -60
  29. package/dist/next/middleware.js.map +1 -1
  30. package/dist/next/testing.cjs +80 -79
  31. package/dist/next/testing.cjs.map +1 -1
  32. package/dist/next/testing.d.ts +10 -10
  33. package/dist/next/testing.js +80 -79
  34. package/dist/next/testing.js.map +1 -1
  35. package/dist/overrides.cjs +9 -9
  36. package/dist/overrides.cjs.map +1 -1
  37. package/dist/overrides.d.ts +2 -2
  38. package/dist/overrides.js +9 -9
  39. package/dist/overrides.js.map +1 -1
  40. package/dist/{schema-83a75e61.d.ts → schema-2922d49e.d.ts} +1 -7
  41. package/dist/{types-4fd1c7c6.d.ts → types-7b1cd9f7.d.ts} +1 -7
  42. package/dist/types-c3d15d04.d.ts +15 -0
  43. package/dist/v2/config.cjs +39 -39
  44. package/dist/v2/config.cjs.map +1 -1
  45. package/dist/v2/config.d.ts +3 -2
  46. package/dist/v2/config.js +38 -38
  47. package/dist/v2/config.js.map +1 -1
  48. package/dist/v2/microfrontends/server.cjs +223 -96
  49. package/dist/v2/microfrontends/server.cjs.map +1 -1
  50. package/dist/v2/microfrontends/server.d.ts +11 -3
  51. package/dist/v2/microfrontends/server.js +223 -96
  52. package/dist/v2/microfrontends/server.js.map +1 -1
  53. package/dist/v2/microfrontends.cjs +44 -44
  54. package/dist/v2/microfrontends.cjs.map +1 -1
  55. package/dist/v2/microfrontends.d.ts +6 -5
  56. package/dist/v2/microfrontends.js +44 -44
  57. package/dist/v2/microfrontends.js.map +1 -1
  58. package/dist/v2/next/client.cjs +1 -1
  59. package/dist/v2/next/client.cjs.map +1 -1
  60. package/dist/v2/next/client.js +1 -1
  61. package/dist/v2/next/client.js.map +1 -1
  62. package/dist/v2/next/config.cjs +247 -122
  63. package/dist/v2/next/config.cjs.map +1 -1
  64. package/dist/v2/next/config.d.ts +4 -4
  65. package/dist/v2/next/config.js +246 -121
  66. package/dist/v2/next/config.js.map +1 -1
  67. package/dist/v2/next/endpoints.cjs +5 -5
  68. package/dist/v2/next/endpoints.cjs.map +1 -1
  69. package/dist/v2/next/endpoints.js +5 -5
  70. package/dist/v2/next/endpoints.js.map +1 -1
  71. package/dist/v2/next/middleware.cjs +55 -55
  72. package/dist/v2/next/middleware.cjs.map +1 -1
  73. package/dist/v2/next/middleware.d.ts +8 -8
  74. package/dist/v2/next/middleware.js +53 -53
  75. package/dist/v2/next/middleware.js.map +1 -1
  76. package/dist/v2/overrides.cjs +75 -0
  77. package/dist/v2/overrides.cjs.map +1 -0
  78. package/dist/v2/overrides.d.ts +24 -0
  79. package/dist/v2/overrides.js +45 -0
  80. package/dist/v2/overrides.js.map +1 -0
  81. package/dist/v2/schema.cjs.map +1 -1
  82. package/dist/v2/schema.d.ts +1 -1
  83. package/dist/validation.cjs +20 -28
  84. package/dist/validation.cjs.map +1 -1
  85. package/dist/validation.d.ts +2 -8
  86. package/dist/validation.js +20 -28
  87. package/dist/validation.js.map +1 -1
  88. package/package.json +15 -7
  89. package/schema/schema-v2.json +0 -4
  90. 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";
@@ -40,14 +40,14 @@ function parseOverrides(cookies) {
40
40
  }
41
41
 
42
42
  // src/config-v2/errors.ts
43
- var MicroFrontendError = class extends Error {
43
+ var MicrofrontendError = class extends Error {
44
44
  constructor(message, opts) {
45
45
  super(message);
46
- this.name = "MicroFrontendsError";
47
- this.source = (opts == null ? void 0 : opts.source) ?? "@vercel/micro-frontends";
46
+ this.name = "MicrofrontendsError";
47
+ this.source = (opts == null ? void 0 : opts.source) ?? "@vercel/microfrontends";
48
48
  this.type = (opts == null ? void 0 : opts.type) ?? "unknown";
49
49
  this.subtype = opts == null ? void 0 : opts.subtype;
50
- Error.captureStackTrace(this, MicroFrontendError);
50
+ Error.captureStackTrace(this, MicrofrontendError);
51
51
  }
52
52
  isKnown() {
53
53
  return this.type !== "unknown";
@@ -56,13 +56,13 @@ var MicroFrontendError = class extends Error {
56
56
  return !this.isKnown();
57
57
  }
58
58
  /**
59
- * Converts an error to a MicroFrontendsError.
59
+ * Converts an error to a MicrofrontendsError.
60
60
  * @param original - The original error to convert.
61
- * @returns The converted MicroFrontendsError.
61
+ * @returns The converted MicrofrontendsError.
62
62
  */
63
63
  static convert(original, opts) {
64
64
  if (opts == null ? void 0 : opts.fileName) {
65
- const err = MicroFrontendError.convertFSError(original, opts.fileName);
65
+ const err = MicrofrontendError.convertFSError(original, opts.fileName);
66
66
  if (err) {
67
67
  return err;
68
68
  }
@@ -70,25 +70,25 @@ var MicroFrontendError = class extends Error {
70
70
  if (original.message.includes(
71
71
  "Code generation from strings disallowed for this context"
72
72
  )) {
73
- return new MicroFrontendError(original.message, {
73
+ return new MicrofrontendError(original.message, {
74
74
  type: "config",
75
75
  subtype: "unsupported_validation_env",
76
76
  source: "ajv"
77
77
  });
78
78
  }
79
- return new MicroFrontendError(original.message);
79
+ return new MicrofrontendError(original.message);
80
80
  }
81
81
  static convertFSError(original, fileName) {
82
82
  if (original instanceof Error && "code" in original) {
83
83
  if (original.code === "ENOENT") {
84
- return new MicroFrontendError(`Could not find "${fileName}"`, {
84
+ return new MicrofrontendError(`Could not find "${fileName}"`, {
85
85
  type: "config",
86
86
  subtype: "unable_to_read_file",
87
87
  source: "fs"
88
88
  });
89
89
  }
90
90
  if (original.code === "EACCES") {
91
- return new MicroFrontendError(
91
+ return new MicrofrontendError(
92
92
  `Permission denied while accessing "${fileName}"`,
93
93
  {
94
94
  type: "config",
@@ -99,7 +99,7 @@ var MicroFrontendError = class extends Error {
99
99
  }
100
100
  }
101
101
  if (original instanceof SyntaxError) {
102
- return new MicroFrontendError(
102
+ return new MicrofrontendError(
103
103
  `Failed to parse "${fileName}": Invalid JSON format.`,
104
104
  {
105
105
  type: "config",
@@ -111,23 +111,23 @@ var MicroFrontendError = class extends Error {
111
111
  return null;
112
112
  }
113
113
  /**
114
- * Handles an unknown error and returns a MicroFrontendsError instance.
114
+ * Handles an unknown error and returns a MicrofrontendsError instance.
115
115
  * @param err - The error to handle.
116
- * @returns A MicroFrontendsError instance.
116
+ * @returns A MicrofrontendsError instance.
117
117
  */
118
118
  static handle(err, opts) {
119
- if (err instanceof MicroFrontendError) {
119
+ if (err instanceof MicrofrontendError) {
120
120
  return err;
121
121
  }
122
122
  if (err instanceof Error) {
123
- return MicroFrontendError.convert(err, opts);
123
+ return MicrofrontendError.convert(err, opts);
124
124
  }
125
125
  if (typeof err === "object" && err !== null) {
126
126
  if ("message" in err && typeof err.message === "string") {
127
- return MicroFrontendError.convert(new Error(err.message), opts);
127
+ return MicrofrontendError.convert(new Error(err.message), opts);
128
128
  }
129
129
  }
130
- return new MicroFrontendError("An unknown error occurred");
130
+ return new MicrofrontendError("An unknown error occurred");
131
131
  }
132
132
  };
133
133
 
@@ -135,7 +135,7 @@ var MicroFrontendError = class extends Error {
135
135
  function getConfigStringFromEnv() {
136
136
  const config = process.env.MFE_CONFIG;
137
137
  if (!config) {
138
- throw new MicroFrontendError(`Missing "MFE_CONFIG" in environment.`, {
138
+ throw new MicrofrontendError(`Missing "MFE_CONFIG" in environment.`, {
139
139
  type: "config",
140
140
  subtype: "not_found_in_env"
141
141
  });
@@ -158,7 +158,7 @@ function isDefaultApp(a) {
158
158
 
159
159
  // src/config-v2/microfrontends-config/client/index.ts
160
160
  import { pathToRegexp } from "path-to-regexp";
161
- var MicroFrontendConfigClient = class {
161
+ var MicrofrontendConfigClient = class {
162
162
  constructor(config, opts) {
163
163
  this.pathCache = {};
164
164
  this.serialized = config;
@@ -172,14 +172,14 @@ var MicroFrontendConfigClient = class {
172
172
  this.applications = config.applications;
173
173
  }
174
174
  /**
175
- * Create a new `MicroFrontendConfigClient` from a JSON string.
175
+ * Create a new `MicrofrontendConfigClient` from a JSON string.
176
176
  * Config must be passed in to remain framework agnostic
177
177
  */
178
178
  static fromEnv(config, opts) {
179
179
  if (!config) {
180
- throw new Error("No micro-frontends configuration found");
180
+ throw new Error("No microfrontends configuration found");
181
181
  }
182
- return new MicroFrontendConfigClient(
182
+ return new MicrofrontendConfigClient(
183
183
  JSON.parse(config),
184
184
  opts
185
185
  );
@@ -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() {
@@ -227,7 +227,7 @@ import { pathToRegexp as pathToRegexp2, parse as parsePathRegexp } from "path-to
227
227
  var SUPPORTED_VERSIONS = ["2"];
228
228
  var validateConfigVersion = (version) => {
229
229
  if (!SUPPORTED_VERSIONS.includes(version)) {
230
- throw new MicroFrontendError(
230
+ throw new MicrofrontendError(
231
231
  `Unsupported version: ${version}. Supported versions are: ${SUPPORTED_VERSIONS.join(
232
232
  ", "
233
233
  )}`,
@@ -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}`
@@ -297,7 +297,7 @@ var validateConfigPaths = (applicationConfigsById) => {
297
297
  );
298
298
  });
299
299
  if (errors.length) {
300
- throw new MicroFrontendError(`Invalid paths: ${errors.join(", ")}`, {
300
+ throw new MicrofrontendError(`Invalid paths: ${errors.join(", ")}`, {
301
301
  type: "config",
302
302
  subtype: "conflicting_paths"
303
303
  });
@@ -310,13 +310,13 @@ var validateAppPaths = (name, app) => {
310
310
  continue;
311
311
  }
312
312
  if (p.endsWith("/")) {
313
- throw new MicroFrontendError(
313
+ throw new MicrofrontendError(
314
314
  `Invalid path for application "${name}". ${p} must not end with a slash.`,
315
315
  { type: "application", subtype: "invalid_path" }
316
316
  );
317
317
  }
318
318
  if (!p.startsWith("/")) {
319
- throw new MicroFrontendError(
319
+ throw new MicrofrontendError(
320
320
  `Invalid path for application "${name}". ${p} must start with a slash.`,
321
321
  { type: "application", subtype: "invalid_path" }
322
322
  );
@@ -338,13 +338,13 @@ var validateConfigDefaultApplication = (applicationConfigsById) => {
338
338
  const numApplicationsWithRouting = applicationsWithRoutingNames.length;
339
339
  const numApplicationsWithoutRouting = numApplications - numApplicationsWithRouting;
340
340
  if (numApplicationsWithoutRouting === 0) {
341
- throw new MicroFrontendError(
341
+ throw new MicrofrontendError(
342
342
  `No default application found. At least one application needs to be the default by omitting routing.`,
343
343
  { type: "config", subtype: "no_default_application" }
344
344
  );
345
345
  }
346
346
  if (numApplicationsWithoutRouting > 1) {
347
- throw new MicroFrontendError(
347
+ throw new MicrofrontendError(
348
348
  `Only one application can omit "routing". Found ${applicationsWithRoutingNames.length - Object.keys(applicationConfigsById).length > 1}.`,
349
349
  { type: "config", subtype: "multiple_default_applications" }
350
350
  );
@@ -356,7 +356,7 @@ var validateConfigOptions = (options) => {
356
356
  if (!/^[a-zA-Z]{2,}\.[a-zA-Z]{2,}$/.test(
357
357
  options.vercel.previewDeploymentSuffix
358
358
  )) {
359
- throw new MicroFrontendError(
359
+ throw new MicrofrontendError(
360
360
  `Invalid preview deployment suffix: ${options.vercel.previewDeploymentSuffix}. Should have be formatted like "vercel.app".`,
361
361
  { type: "config", subtype: "invalid_preview_deployment_suffix" }
362
362
  );
@@ -515,7 +515,7 @@ var ChildApplication = class extends Application {
515
515
  var DEFAULT_LOCAL_PROXY_PORT = 3024;
516
516
 
517
517
  // src/config-v2/microfrontends-config/isomorphic/index.ts
518
- var MicroFrontendConfigIsomorphic = class {
518
+ var MicrofrontendConfigIsomorphic = class {
519
519
  constructor({
520
520
  config,
521
521
  overrides,
@@ -523,7 +523,7 @@ var MicroFrontendConfigIsomorphic = class {
523
523
  }) {
524
524
  this.childApplications = {};
525
525
  var _a, _b, _c, _d;
526
- MicroFrontendConfigIsomorphic.validate(config);
526
+ MicrofrontendConfigIsomorphic.validate(config);
527
527
  const disableOverrides = ((_b = (_a = config.options) == null ? void 0 : _a.vercel) == null ? void 0 : _b.disableOverrides) ?? false;
528
528
  this.overrides = overrides && !disableOverrides ? overrides : void 0;
529
529
  this.isMainConfig = isMainConfig(config);
@@ -555,7 +555,7 @@ var MicroFrontendConfigIsomorphic = class {
555
555
  );
556
556
  }
557
557
  if (isMainConfig(config) && !this.defaultApplication) {
558
- throw new MicroFrontendError(
558
+ throw new MicrofrontendError(
559
559
  `Could not find default application in microfrontends configuration`,
560
560
  {
561
561
  type: "application",
@@ -585,7 +585,7 @@ var MicroFrontendConfigIsomorphic = class {
585
585
  meta,
586
586
  cookies
587
587
  }) {
588
- return new MicroFrontendConfigIsomorphic({
588
+ return new MicrofrontendConfigIsomorphic({
589
589
  config: parse(getConfigStringFromEnv()),
590
590
  overrides: parseOverrides(cookies ?? []),
591
591
  meta
@@ -620,7 +620,7 @@ var MicroFrontendConfigIsomorphic = class {
620
620
  }
621
621
  const app = this.childApplications[name];
622
622
  if (!app) {
623
- throw new MicroFrontendError(
623
+ throw new MicrofrontendError(
624
624
  `Could not find microfrontends configuration for application "${name}"`,
625
625
  {
626
626
  type: "application",
@@ -648,7 +648,7 @@ var MicroFrontendConfigIsomorphic = class {
648
648
  */
649
649
  getDefaultApplication() {
650
650
  if (!this.defaultApplication) {
651
- throw new MicroFrontendError(
651
+ throw new MicrofrontendError(
652
652
  `Could not find default application in microfrontends configuration`,
653
653
  {
654
654
  type: "application",
@@ -688,7 +688,7 @@ var MicroFrontendConfigIsomorphic = class {
688
688
  default: true
689
689
  };
690
690
  }
691
- return new MicroFrontendConfigClient({
691
+ return new MicrofrontendConfigClient({
692
692
  applications
693
693
  });
694
694
  }
@@ -698,7 +698,7 @@ var MicroFrontendConfigIsomorphic = class {
698
698
  };
699
699
 
700
700
  // src/config-v2/microfrontends-config/isomorphic/child.ts
701
- var MicroFrontendChildConfig = class extends MicroFrontendConfigIsomorphic {
701
+ var MicrofrontendChildConfig = class extends MicrofrontendConfigIsomorphic {
702
702
  constructor({
703
703
  config,
704
704
  overrides,
@@ -711,7 +711,7 @@ var MicroFrontendChildConfig = class extends MicroFrontendConfigIsomorphic {
711
711
  };
712
712
 
713
713
  // src/config-v2/microfrontends-config/isomorphic/main.ts
714
- var MicroFrontendMainConfig = class extends MicroFrontendConfigIsomorphic {
714
+ var MicrofrontendMainConfig = class extends MicrofrontendConfigIsomorphic {
715
715
  constructor({
716
716
  config,
717
717
  overrides,
@@ -738,7 +738,7 @@ var MicroFrontendMainConfig = class extends MicroFrontendConfigIsomorphic {
738
738
  }
739
739
  }
740
740
  if (!defaultApplication) {
741
- throw new MicroFrontendError(
741
+ throw new MicrofrontendError(
742
742
  `Could not find default application in microfrontends configuration`,
743
743
  {
744
744
  type: "application",
@@ -758,19 +758,19 @@ var Microfrontends = class {
758
758
  meta
759
759
  }) {
760
760
  if (isMainConfig(config)) {
761
- this.config = new MicroFrontendMainConfig({ config, overrides, meta });
761
+ this.config = new MicrofrontendMainConfig({ config, overrides, meta });
762
762
  } else {
763
- this.config = new MicroFrontendChildConfig({ config, overrides, meta });
763
+ this.config = new MicrofrontendChildConfig({ config, overrides, meta });
764
764
  }
765
765
  }
766
766
  isChildConfig() {
767
- return this.config instanceof MicroFrontendChildConfig;
767
+ return this.config instanceof MicrofrontendChildConfig;
768
768
  }
769
769
  static fromEnv({
770
770
  cookies,
771
771
  meta
772
772
  }) {
773
- const config = MicroFrontendConfigIsomorphic.fromEnv({
773
+ const config = MicrofrontendConfigIsomorphic.fromEnv({
774
774
  cookies,
775
775
  meta
776
776
  });
@@ -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
@@ -807,14 +881,14 @@ import { parse as parse2 } from "jsonc-parser";
807
881
  import { Ajv } from "ajv";
808
882
 
809
883
  // src/config/errors.ts
810
- var MicroFrontendError2 = class extends Error {
884
+ var MicrofrontendError2 = class extends Error {
811
885
  constructor(message, opts) {
812
886
  super(message);
813
- this.name = "MicroFrontendsError";
814
- this.source = (opts == null ? void 0 : opts.source) ?? "@vercel/micro-frontends";
887
+ this.name = "MicrofrontendsError";
888
+ this.source = (opts == null ? void 0 : opts.source) ?? "@vercel/microfrontends";
815
889
  this.type = (opts == null ? void 0 : opts.type) ?? "unknown";
816
890
  this.subtype = opts == null ? void 0 : opts.subtype;
817
- Error.captureStackTrace(this, MicroFrontendError2);
891
+ Error.captureStackTrace(this, MicrofrontendError2);
818
892
  }
819
893
  isKnown() {
820
894
  return this.type !== "unknown";
@@ -823,13 +897,13 @@ var MicroFrontendError2 = class extends Error {
823
897
  return !this.isKnown();
824
898
  }
825
899
  /**
826
- * Converts an error to a MicroFrontendsError.
900
+ * Converts an error to a MicrofrontendsError.
827
901
  * @param original - The original error to convert.
828
- * @returns The converted MicroFrontendsError.
902
+ * @returns The converted MicrofrontendsError.
829
903
  */
830
904
  static convert(original, opts) {
831
905
  if (opts == null ? void 0 : opts.fileName) {
832
- const err = MicroFrontendError2.convertFSError(original, opts.fileName);
906
+ const err = MicrofrontendError2.convertFSError(original, opts.fileName);
833
907
  if (err) {
834
908
  return err;
835
909
  }
@@ -837,25 +911,25 @@ var MicroFrontendError2 = class extends Error {
837
911
  if (original.message.includes(
838
912
  "Code generation from strings disallowed for this context"
839
913
  )) {
840
- return new MicroFrontendError2(original.message, {
914
+ return new MicrofrontendError2(original.message, {
841
915
  type: "config",
842
916
  subtype: "unsupported_validation_env",
843
917
  source: "ajv"
844
918
  });
845
919
  }
846
- return new MicroFrontendError2(original.message);
920
+ return new MicrofrontendError2(original.message);
847
921
  }
848
922
  static convertFSError(original, fileName) {
849
923
  if (original instanceof Error && "code" in original) {
850
924
  if (original.code === "ENOENT") {
851
- return new MicroFrontendError2(`Could not find "${fileName}"`, {
925
+ return new MicrofrontendError2(`Could not find "${fileName}"`, {
852
926
  type: "config",
853
927
  subtype: "unable_to_read_file",
854
928
  source: "fs"
855
929
  });
856
930
  }
857
931
  if (original.code === "EACCES") {
858
- return new MicroFrontendError2(
932
+ return new MicrofrontendError2(
859
933
  `Permission denied while accessing "${fileName}"`,
860
934
  {
861
935
  type: "config",
@@ -866,7 +940,7 @@ var MicroFrontendError2 = class extends Error {
866
940
  }
867
941
  }
868
942
  if (original instanceof SyntaxError) {
869
- return new MicroFrontendError2(
943
+ return new MicrofrontendError2(
870
944
  `Failed to parse "${fileName}": Invalid JSON format.`,
871
945
  {
872
946
  type: "config",
@@ -878,23 +952,23 @@ var MicroFrontendError2 = class extends Error {
878
952
  return null;
879
953
  }
880
954
  /**
881
- * Handles an unknown error and returns a MicroFrontendsError instance.
955
+ * Handles an unknown error and returns a MicrofrontendsError instance.
882
956
  * @param err - The error to handle.
883
- * @returns A MicroFrontendsError instance.
957
+ * @returns A MicrofrontendsError instance.
884
958
  */
885
959
  static handle(err, opts) {
886
- if (err instanceof MicroFrontendError2) {
960
+ if (err instanceof MicrofrontendError2) {
887
961
  return err;
888
962
  }
889
963
  if (err instanceof Error) {
890
- return MicroFrontendError2.convert(err, opts);
964
+ return MicrofrontendError2.convert(err, opts);
891
965
  }
892
966
  if (typeof err === "object" && err !== null) {
893
967
  if ("message" in err && typeof err.message === "string") {
894
- return MicroFrontendError2.convert(new Error(err.message), opts);
968
+ return MicrofrontendError2.convert(new Error(err.message), opts);
895
969
  }
896
970
  }
897
- return new MicroFrontendError2("An unknown error occurred");
971
+ return new MicrofrontendError2("An unknown error occurred");
898
972
  }
899
973
  };
900
974
 
@@ -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: {
@@ -1172,7 +1242,7 @@ function validateSchema(configString) {
1172
1242
  const validate = ajv.compile(SCHEMA);
1173
1243
  const isValid = validate(parsedConfig);
1174
1244
  if (!isValid) {
1175
- throw new MicroFrontendError2(
1245
+ throw new MicrofrontendError2(
1176
1246
  `Invalid config: ${ajv.errorsText(validate.errors)}`,
1177
1247
  { type: "config", subtype: "does_not_match_schema" }
1178
1248
  );
@@ -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(),
@@ -1223,7 +1293,7 @@ var MicrofrontendsServer = class extends Microfrontends {
1223
1293
  meta
1224
1294
  });
1225
1295
  }
1226
- throw new MicroFrontendError(
1296
+ throw new MicrofrontendError(
1227
1297
  "Invalid config: must be a string or an object",
1228
1298
  { type: "config", subtype: "does_not_match_schema" }
1229
1299
  );
@@ -1258,17 +1328,74 @@ 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
  });
1270
1360
  } catch (e) {
1271
- throw MicroFrontendError.handle(e, {
1361
+ throw MicrofrontendError.handle(e, {
1362
+ fileName: filePath
1363
+ });
1364
+ }
1365
+ }
1366
+ /*
1367
+ * Generates a MicrofrontendMainConfig instance from a file.
1368
+ */
1369
+ static fromMainConfigFile({
1370
+ filePath,
1371
+ overrides
1372
+ }) {
1373
+ try {
1374
+ const config = fs2.readFileSync(filePath, "utf-8");
1375
+ const validatedConfig = MicrofrontendsServer.validate(config);
1376
+ if (!isMainConfig(validatedConfig)) {
1377
+ throw new MicrofrontendError(
1378
+ `${filePath} is not a main microfrontend config`,
1379
+ {
1380
+ type: "config",
1381
+ subtype: "invalid_main_path"
1382
+ }
1383
+ );
1384
+ }
1385
+ const [defaultApplication] = Object.entries(validatedConfig.applications).filter(([, app]) => isDefaultApp(app)).map(([name]) => name);
1386
+ if (!defaultApplication) {
1387
+ throw new MicrofrontendError(
1388
+ `No default application found. At least one application needs to be the default by omitting routing.`,
1389
+ { type: "config", subtype: "no_default_application" }
1390
+ );
1391
+ }
1392
+ return new MicrofrontendsServer({
1393
+ config: validatedConfig,
1394
+ overrides,
1395
+ meta: { fromApp: defaultApplication }
1396
+ });
1397
+ } catch (e) {
1398
+ throw MicrofrontendError.handle(e, {
1272
1399
  fileName: filePath
1273
1400
  });
1274
1401
  }
@@ -1475,11 +1602,11 @@ ${table}
1475
1602
  `);
1476
1603
  }
1477
1604
  }
1478
- function pathToRewrites(path2) {
1605
+ function pathToRewrites(path3) {
1479
1606
  var _a;
1480
1607
  const regex = /(?<base>^.+)\/:.+\*$/;
1481
- const match = regex.exec(path2);
1482
- const paths = [path2];
1608
+ const match = regex.exec(path3);
1609
+ const paths = [path3];
1483
1610
  if ((_a = match == null ? void 0 : match.groups) == null ? void 0 : _a.base) {
1484
1611
  paths.unshift(match.groups.base);
1485
1612
  }
@@ -1499,7 +1626,7 @@ function rewritesMapToArr(rewrites) {
1499
1626
  });
1500
1627
  }
1501
1628
  function transform4(args) {
1502
- const { next, microFrontend, app } = args;
1629
+ const { next, microfrontend, app } = args;
1503
1630
  const buildBeforeFiles = () => {
1504
1631
  var _a;
1505
1632
  const rewrites = /* @__PURE__ */ new Map();
@@ -1514,12 +1641,12 @@ function transform4(args) {
1514
1641
  destination: { pathname: "/_vercel/:path*" }
1515
1642
  });
1516
1643
  }
1517
- } else if (microFrontend instanceof MicroFrontendMainConfig) {
1644
+ } else if (microfrontend instanceof MicrofrontendMainConfig) {
1518
1645
  for (const [_, a] of Object.entries(
1519
- microFrontend.getChildApplications()
1646
+ microfrontend.getChildApplications()
1520
1647
  )) {
1521
1648
  const { routing } = a;
1522
- const domain = getDomainForCurrentEnvironment(microFrontend, a.name);
1649
+ const domain = getDomainForCurrentEnvironment(microfrontend, a.name);
1523
1650
  rewrites.set(`/${a.getAssetPrefix()}/:path+`, {
1524
1651
  destination: {
1525
1652
  domain,
@@ -1527,9 +1654,7 @@ function transform4(args) {
1527
1654
  }
1528
1655
  });
1529
1656
  for (const group of routing) {
1530
- if (group.routeToDefaultApplication) {
1531
- continue;
1532
- } else if (group.flag) {
1657
+ if (group.flag) {
1533
1658
  continue;
1534
1659
  } else {
1535
1660
  for (const source of group.paths) {
@@ -1582,8 +1707,8 @@ function transform4(args) {
1582
1707
  var formatDomainForServerAction = (domain) => domain.replace(/https?:\/\//, "");
1583
1708
  function transform5(args) {
1584
1709
  var _a;
1585
- const { next, app, microFrontend } = args;
1586
- if (microFrontend instanceof MicroFrontendChildConfig) {
1710
+ const { next, app, microfrontend } = args;
1711
+ if (microfrontend instanceof MicrofrontendChildConfig) {
1587
1712
  console.warn(
1588
1713
  "server actions transform requires the full config - skipping"
1589
1714
  );
@@ -1591,12 +1716,12 @@ function transform5(args) {
1591
1716
  next
1592
1717
  };
1593
1718
  }
1594
- const defaultApplication = microFrontend.getDefaultApplication();
1719
+ const defaultApplication = microfrontend.getDefaultApplication();
1595
1720
  const appsToAllow = [
1596
1721
  // this zone - this is included by default unless allowedOrigins is overridden (which we are)
1597
1722
  // so we re-add it here.
1598
1723
  app,
1599
- // this is the default zone for the micro-frontend. Allow child zones to call server actions
1724
+ // this is the default zone for the microfrontend. Allow child zones to call server actions
1600
1725
  // that are in the default zone.
1601
1726
  defaultApplication
1602
1727
  ];
@@ -1613,7 +1738,7 @@ function transform5(args) {
1613
1738
  defaultApplication.production.toString()
1614
1739
  ),
1615
1740
  formatDomainForServerAction(
1616
- getDomainForCurrentEnvironment(microFrontend, a.name)
1741
+ getDomainForCurrentEnvironment(microfrontend, a.name)
1617
1742
  )
1618
1743
  ])
1619
1744
  ])
@@ -1627,7 +1752,7 @@ function transform5(args) {
1627
1752
 
1628
1753
  // src/next-v2/config/transforms/webpack.ts
1629
1754
  function transform6(args) {
1630
- const { next, microFrontend } = args;
1755
+ const { next, microfrontend } = args;
1631
1756
  const configWithWebpack = {
1632
1757
  ...next,
1633
1758
  webpack(cfg, context) {
@@ -1636,7 +1761,7 @@ function transform6(args) {
1636
1761
  if (isServer || nextRuntime === "edge") {
1637
1762
  config.plugins.push(
1638
1763
  new wpFromNext.EnvironmentPlugin({
1639
- MFE_CONFIG: JSON.stringify(microFrontend.serialize())
1764
+ MFE_CONFIG: JSON.stringify(microfrontend.serialize())
1640
1765
  })
1641
1766
  );
1642
1767
  }
@@ -1729,26 +1854,26 @@ function getApplicationContext(opts) {
1729
1854
  return { name: opts.appName };
1730
1855
  }
1731
1856
  try {
1732
- const packageJsonString = fs2.readFileSync("./package.json", "utf-8");
1857
+ const packageJsonString = fs3.readFileSync("./package.json", "utf-8");
1733
1858
  const packageJson = JSON.parse(packageJsonString);
1734
1859
  if (!packageJson.name) {
1735
- throw new MicroFrontendError(
1860
+ throw new MicrofrontendError(
1736
1861
  `package.json file missing required field "name"`,
1737
1862
  {
1738
1863
  type: "packageJson",
1739
1864
  subtype: "missing_field_name",
1740
- source: "@vercel/micro-frontends/next"
1865
+ source: "@vercel/microfrontends/next"
1741
1866
  }
1742
1867
  );
1743
1868
  }
1744
1869
  return { name: packageJson.name };
1745
1870
  } catch (err) {
1746
- throw MicroFrontendError.handle(err, {
1871
+ throw MicrofrontendError.handle(err, {
1747
1872
  fileName: "package.json"
1748
1873
  });
1749
1874
  }
1750
1875
  }
1751
- function withMicroFrontends(nextConfig, opts) {
1876
+ function withMicrofrontends(nextConfig, opts) {
1752
1877
  var _a;
1753
1878
  if (opts == null ? void 0 : opts.debug) {
1754
1879
  process.env.MFE_DEBUG = "true";
@@ -1772,7 +1897,7 @@ function withMicroFrontends(nextConfig, opts) {
1772
1897
  const transformedConfig = transform7({
1773
1898
  app,
1774
1899
  next,
1775
- microFrontend: microfrontends.config,
1900
+ microfrontend: microfrontends.config,
1776
1901
  opts: {
1777
1902
  isProduction: isProduction(opts)
1778
1903
  }
@@ -1789,6 +1914,6 @@ function withMicroFrontends(nextConfig, opts) {
1789
1914
  return next;
1790
1915
  }
1791
1916
  export {
1792
- withMicroFrontends
1917
+ withMicrofrontends
1793
1918
  };
1794
1919
  //# sourceMappingURL=config.js.map