@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.
- package/README.md +7 -7
- package/dist/bin/cli.cjs +1604 -221
- package/dist/config/client.d.ts +1 -1
- package/dist/config/edge.cjs +47 -47
- package/dist/config/edge.cjs.map +1 -1
- package/dist/config/edge.d.ts +6 -6
- package/dist/config/edge.js +46 -46
- package/dist/config/edge.js.map +1 -1
- package/dist/config.cjs +67 -66
- package/dist/config.cjs.map +1 -1
- package/dist/config.d.ts +4 -4
- package/dist/config.js +66 -65
- package/dist/config.js.map +1 -1
- package/dist/{index-eff254d8.d.ts → index-acb44057.d.ts} +12 -23
- package/dist/{micro-frontend-config-42886104.d.ts → microfrontend-config-983a5139.d.ts} +13 -13
- package/dist/next/client.cjs +1 -1
- package/dist/next/client.cjs.map +1 -1
- package/dist/next/client.js +1 -1
- package/dist/next/client.js.map +1 -1
- package/dist/next/config.cjs +86 -87
- package/dist/next/config.cjs.map +1 -1
- package/dist/next/config.d.ts +3 -3
- package/dist/next/config.js +85 -86
- package/dist/next/config.js.map +1 -1
- package/dist/next/middleware.cjs +60 -62
- package/dist/next/middleware.cjs.map +1 -1
- package/dist/next/middleware.d.ts +11 -11
- package/dist/next/middleware.js +58 -60
- package/dist/next/middleware.js.map +1 -1
- package/dist/next/testing.cjs +80 -79
- package/dist/next/testing.cjs.map +1 -1
- package/dist/next/testing.d.ts +10 -10
- package/dist/next/testing.js +80 -79
- package/dist/next/testing.js.map +1 -1
- package/dist/overrides.cjs +9 -9
- package/dist/overrides.cjs.map +1 -1
- package/dist/overrides.d.ts +2 -2
- package/dist/overrides.js +9 -9
- package/dist/overrides.js.map +1 -1
- package/dist/{schema-83a75e61.d.ts → schema-2922d49e.d.ts} +1 -7
- package/dist/{types-4fd1c7c6.d.ts → types-7b1cd9f7.d.ts} +1 -7
- package/dist/types-c3d15d04.d.ts +15 -0
- package/dist/v2/config.cjs +39 -39
- package/dist/v2/config.cjs.map +1 -1
- package/dist/v2/config.d.ts +3 -2
- package/dist/v2/config.js +38 -38
- package/dist/v2/config.js.map +1 -1
- package/dist/v2/microfrontends/server.cjs +223 -96
- package/dist/v2/microfrontends/server.cjs.map +1 -1
- package/dist/v2/microfrontends/server.d.ts +11 -3
- package/dist/v2/microfrontends/server.js +223 -96
- package/dist/v2/microfrontends/server.js.map +1 -1
- package/dist/v2/microfrontends.cjs +44 -44
- package/dist/v2/microfrontends.cjs.map +1 -1
- package/dist/v2/microfrontends.d.ts +6 -5
- package/dist/v2/microfrontends.js +44 -44
- package/dist/v2/microfrontends.js.map +1 -1
- package/dist/v2/next/client.cjs +1 -1
- package/dist/v2/next/client.cjs.map +1 -1
- package/dist/v2/next/client.js +1 -1
- package/dist/v2/next/client.js.map +1 -1
- package/dist/v2/next/config.cjs +247 -122
- package/dist/v2/next/config.cjs.map +1 -1
- package/dist/v2/next/config.d.ts +4 -4
- package/dist/v2/next/config.js +246 -121
- package/dist/v2/next/config.js.map +1 -1
- package/dist/v2/next/endpoints.cjs +5 -5
- package/dist/v2/next/endpoints.cjs.map +1 -1
- package/dist/v2/next/endpoints.js +5 -5
- package/dist/v2/next/endpoints.js.map +1 -1
- package/dist/v2/next/middleware.cjs +55 -55
- package/dist/v2/next/middleware.cjs.map +1 -1
- package/dist/v2/next/middleware.d.ts +8 -8
- package/dist/v2/next/middleware.js +53 -53
- package/dist/v2/next/middleware.js.map +1 -1
- package/dist/v2/overrides.cjs +75 -0
- package/dist/v2/overrides.cjs.map +1 -0
- package/dist/v2/overrides.d.ts +24 -0
- package/dist/v2/overrides.js +45 -0
- package/dist/v2/overrides.js.map +1 -0
- package/dist/v2/schema.cjs.map +1 -1
- package/dist/v2/schema.d.ts +1 -1
- package/dist/validation.cjs +20 -28
- package/dist/validation.cjs.map +1 -1
- package/dist/validation.d.ts +2 -8
- package/dist/validation.js +20 -28
- package/dist/validation.js.map +1 -1
- package/package.json +15 -7
- package/schema/schema-v2.json +0 -4
- package/schema/schema.json +0 -4
|
@@ -33,8 +33,8 @@ __export(server_exports, {
|
|
|
33
33
|
MicrofrontendsServer: () => MicrofrontendsServer
|
|
34
34
|
});
|
|
35
35
|
module.exports = __toCommonJS(server_exports);
|
|
36
|
-
var
|
|
37
|
-
var
|
|
36
|
+
var import_node_fs3 = __toESM(require("fs"), 1);
|
|
37
|
+
var import_node_path4 = require("path");
|
|
38
38
|
|
|
39
39
|
// src/config-v2/overrides/constants.ts
|
|
40
40
|
var OVERRIDES_COOKIE_PREFIX = "vercel-microfrontends-override";
|
|
@@ -71,14 +71,14 @@ function parseOverrides(cookies) {
|
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
// src/config-v2/errors.ts
|
|
74
|
-
var
|
|
74
|
+
var MicrofrontendError = class extends Error {
|
|
75
75
|
constructor(message, opts) {
|
|
76
76
|
super(message);
|
|
77
|
-
this.name = "
|
|
78
|
-
this.source = (opts == null ? void 0 : opts.source) ?? "@vercel/
|
|
77
|
+
this.name = "MicrofrontendsError";
|
|
78
|
+
this.source = (opts == null ? void 0 : opts.source) ?? "@vercel/microfrontends";
|
|
79
79
|
this.type = (opts == null ? void 0 : opts.type) ?? "unknown";
|
|
80
80
|
this.subtype = opts == null ? void 0 : opts.subtype;
|
|
81
|
-
Error.captureStackTrace(this,
|
|
81
|
+
Error.captureStackTrace(this, MicrofrontendError);
|
|
82
82
|
}
|
|
83
83
|
isKnown() {
|
|
84
84
|
return this.type !== "unknown";
|
|
@@ -87,13 +87,13 @@ var MicroFrontendError = class extends Error {
|
|
|
87
87
|
return !this.isKnown();
|
|
88
88
|
}
|
|
89
89
|
/**
|
|
90
|
-
* Converts an error to a
|
|
90
|
+
* Converts an error to a MicrofrontendsError.
|
|
91
91
|
* @param original - The original error to convert.
|
|
92
|
-
* @returns The converted
|
|
92
|
+
* @returns The converted MicrofrontendsError.
|
|
93
93
|
*/
|
|
94
94
|
static convert(original, opts) {
|
|
95
95
|
if (opts == null ? void 0 : opts.fileName) {
|
|
96
|
-
const err =
|
|
96
|
+
const err = MicrofrontendError.convertFSError(original, opts.fileName);
|
|
97
97
|
if (err) {
|
|
98
98
|
return err;
|
|
99
99
|
}
|
|
@@ -101,25 +101,25 @@ var MicroFrontendError = class extends Error {
|
|
|
101
101
|
if (original.message.includes(
|
|
102
102
|
"Code generation from strings disallowed for this context"
|
|
103
103
|
)) {
|
|
104
|
-
return new
|
|
104
|
+
return new MicrofrontendError(original.message, {
|
|
105
105
|
type: "config",
|
|
106
106
|
subtype: "unsupported_validation_env",
|
|
107
107
|
source: "ajv"
|
|
108
108
|
});
|
|
109
109
|
}
|
|
110
|
-
return new
|
|
110
|
+
return new MicrofrontendError(original.message);
|
|
111
111
|
}
|
|
112
112
|
static convertFSError(original, fileName) {
|
|
113
113
|
if (original instanceof Error && "code" in original) {
|
|
114
114
|
if (original.code === "ENOENT") {
|
|
115
|
-
return new
|
|
115
|
+
return new MicrofrontendError(`Could not find "${fileName}"`, {
|
|
116
116
|
type: "config",
|
|
117
117
|
subtype: "unable_to_read_file",
|
|
118
118
|
source: "fs"
|
|
119
119
|
});
|
|
120
120
|
}
|
|
121
121
|
if (original.code === "EACCES") {
|
|
122
|
-
return new
|
|
122
|
+
return new MicrofrontendError(
|
|
123
123
|
`Permission denied while accessing "${fileName}"`,
|
|
124
124
|
{
|
|
125
125
|
type: "config",
|
|
@@ -130,7 +130,7 @@ var MicroFrontendError = class extends Error {
|
|
|
130
130
|
}
|
|
131
131
|
}
|
|
132
132
|
if (original instanceof SyntaxError) {
|
|
133
|
-
return new
|
|
133
|
+
return new MicrofrontendError(
|
|
134
134
|
`Failed to parse "${fileName}": Invalid JSON format.`,
|
|
135
135
|
{
|
|
136
136
|
type: "config",
|
|
@@ -142,23 +142,23 @@ var MicroFrontendError = class extends Error {
|
|
|
142
142
|
return null;
|
|
143
143
|
}
|
|
144
144
|
/**
|
|
145
|
-
* Handles an unknown error and returns a
|
|
145
|
+
* Handles an unknown error and returns a MicrofrontendsError instance.
|
|
146
146
|
* @param err - The error to handle.
|
|
147
|
-
* @returns A
|
|
147
|
+
* @returns A MicrofrontendsError instance.
|
|
148
148
|
*/
|
|
149
149
|
static handle(err, opts) {
|
|
150
|
-
if (err instanceof
|
|
150
|
+
if (err instanceof MicrofrontendError) {
|
|
151
151
|
return err;
|
|
152
152
|
}
|
|
153
153
|
if (err instanceof Error) {
|
|
154
|
-
return
|
|
154
|
+
return MicrofrontendError.convert(err, opts);
|
|
155
155
|
}
|
|
156
156
|
if (typeof err === "object" && err !== null) {
|
|
157
157
|
if ("message" in err && typeof err.message === "string") {
|
|
158
|
-
return
|
|
158
|
+
return MicrofrontendError.convert(new Error(err.message), opts);
|
|
159
159
|
}
|
|
160
160
|
}
|
|
161
|
-
return new
|
|
161
|
+
return new MicrofrontendError("An unknown error occurred");
|
|
162
162
|
}
|
|
163
163
|
};
|
|
164
164
|
|
|
@@ -166,7 +166,7 @@ var MicroFrontendError = class extends Error {
|
|
|
166
166
|
function getConfigStringFromEnv() {
|
|
167
167
|
const config = process.env.MFE_CONFIG;
|
|
168
168
|
if (!config) {
|
|
169
|
-
throw new
|
|
169
|
+
throw new MicrofrontendError(`Missing "MFE_CONFIG" in environment.`, {
|
|
170
170
|
type: "config",
|
|
171
171
|
subtype: "not_found_in_env"
|
|
172
172
|
});
|
|
@@ -189,7 +189,7 @@ function isDefaultApp(a) {
|
|
|
189
189
|
|
|
190
190
|
// src/config-v2/microfrontends-config/client/index.ts
|
|
191
191
|
var import_path_to_regexp = require("path-to-regexp");
|
|
192
|
-
var
|
|
192
|
+
var MicrofrontendConfigClient = class {
|
|
193
193
|
constructor(config, opts) {
|
|
194
194
|
this.pathCache = {};
|
|
195
195
|
this.serialized = config;
|
|
@@ -203,14 +203,14 @@ var MicroFrontendConfigClient = class {
|
|
|
203
203
|
this.applications = config.applications;
|
|
204
204
|
}
|
|
205
205
|
/**
|
|
206
|
-
* Create a new `
|
|
206
|
+
* Create a new `MicrofrontendConfigClient` from a JSON string.
|
|
207
207
|
* Config must be passed in to remain framework agnostic
|
|
208
208
|
*/
|
|
209
209
|
static fromEnv(config, opts) {
|
|
210
210
|
if (!config) {
|
|
211
|
-
throw new Error("No
|
|
211
|
+
throw new Error("No microfrontends configuration found");
|
|
212
212
|
}
|
|
213
|
-
return new
|
|
213
|
+
return new MicrofrontendConfigClient(
|
|
214
214
|
JSON.parse(config),
|
|
215
215
|
opts
|
|
216
216
|
);
|
|
@@ -218,21 +218,21 @@ var MicroFrontendConfigClient = class {
|
|
|
218
218
|
isEqual(other) {
|
|
219
219
|
return JSON.stringify(this.applications) === JSON.stringify(other.applications);
|
|
220
220
|
}
|
|
221
|
-
getApplicationNameForPath(
|
|
222
|
-
if (!
|
|
221
|
+
getApplicationNameForPath(path3) {
|
|
222
|
+
if (!path3.startsWith("/")) {
|
|
223
223
|
throw new Error(`Path must start with a /`);
|
|
224
224
|
}
|
|
225
|
-
if (this.pathCache[
|
|
226
|
-
return this.pathCache[
|
|
225
|
+
if (this.pathCache[path3]) {
|
|
226
|
+
return this.pathCache[path3];
|
|
227
227
|
}
|
|
228
|
-
const pathname = new URL(
|
|
228
|
+
const pathname = new URL(path3, "https://example.com").pathname;
|
|
229
229
|
for (const [name, application] of Object.entries(this.applications)) {
|
|
230
230
|
if (application.routing) {
|
|
231
231
|
for (const group of application.routing) {
|
|
232
232
|
for (const childPath of group.paths) {
|
|
233
233
|
const regexp = (0, import_path_to_regexp.pathToRegexp)(childPath);
|
|
234
234
|
if (regexp.test(pathname)) {
|
|
235
|
-
this.pathCache[
|
|
235
|
+
this.pathCache[path3] = name;
|
|
236
236
|
return name;
|
|
237
237
|
}
|
|
238
238
|
}
|
|
@@ -245,7 +245,7 @@ var MicroFrontendConfigClient = class {
|
|
|
245
245
|
if (!defaultApplication) {
|
|
246
246
|
return null;
|
|
247
247
|
}
|
|
248
|
-
this.pathCache[
|
|
248
|
+
this.pathCache[path3] = defaultApplication[0];
|
|
249
249
|
return defaultApplication[0];
|
|
250
250
|
}
|
|
251
251
|
serialize() {
|
|
@@ -258,7 +258,7 @@ var import_path_to_regexp2 = require("path-to-regexp");
|
|
|
258
258
|
var SUPPORTED_VERSIONS = ["2"];
|
|
259
259
|
var validateConfigVersion = (version) => {
|
|
260
260
|
if (!SUPPORTED_VERSIONS.includes(version)) {
|
|
261
|
-
throw new
|
|
261
|
+
throw new MicrofrontendError(
|
|
262
262
|
`Unsupported version: ${version}. Supported versions are: ${SUPPORTED_VERSIONS.join(
|
|
263
263
|
", "
|
|
264
264
|
)}`,
|
|
@@ -277,22 +277,22 @@ var validateConfigPaths = (applicationConfigsById) => {
|
|
|
277
277
|
continue;
|
|
278
278
|
}
|
|
279
279
|
for (const pathMatch of app.routing) {
|
|
280
|
-
for (const
|
|
281
|
-
const tokens = (0, import_path_to_regexp2.parse)(
|
|
280
|
+
for (const path3 of pathMatch.paths) {
|
|
281
|
+
const tokens = (0, import_path_to_regexp2.parse)(path3);
|
|
282
282
|
for (const token of tokens.slice(0, -1)) {
|
|
283
283
|
if (typeof token !== "string") {
|
|
284
284
|
errors.push(
|
|
285
|
-
`Path ${
|
|
285
|
+
`Path ${path3} may only have a :wildcard in the last path component`
|
|
286
286
|
);
|
|
287
287
|
}
|
|
288
288
|
}
|
|
289
|
-
const existing = pathsByApplicationId.get(
|
|
289
|
+
const existing = pathsByApplicationId.get(path3);
|
|
290
290
|
if (existing) {
|
|
291
291
|
existing.applications.push(id);
|
|
292
292
|
} else {
|
|
293
|
-
pathsByApplicationId.set(
|
|
293
|
+
pathsByApplicationId.set(path3, {
|
|
294
294
|
applications: [id],
|
|
295
|
-
matcher: (0, import_path_to_regexp2.pathToRegexp)(
|
|
295
|
+
matcher: (0, import_path_to_regexp2.pathToRegexp)(path3),
|
|
296
296
|
applicationId: id
|
|
297
297
|
});
|
|
298
298
|
}
|
|
@@ -300,10 +300,10 @@ var validateConfigPaths = (applicationConfigsById) => {
|
|
|
300
300
|
}
|
|
301
301
|
}
|
|
302
302
|
const entries = Array.from(pathsByApplicationId.entries());
|
|
303
|
-
entries.forEach(([
|
|
303
|
+
entries.forEach(([path3, { applications: ids, matcher, applicationId }]) => {
|
|
304
304
|
if (ids.length > 1) {
|
|
305
305
|
errors.push(
|
|
306
|
-
`Duplicate path "${
|
|
306
|
+
`Duplicate path "${path3}" for applications "${ids.join(", ")}"`
|
|
307
307
|
);
|
|
308
308
|
}
|
|
309
309
|
entries.forEach(
|
|
@@ -311,14 +311,14 @@ var validateConfigPaths = (applicationConfigsById) => {
|
|
|
311
311
|
matchPath,
|
|
312
312
|
{ applications: matchIds, applicationId: matchApplicationId }
|
|
313
313
|
]) => {
|
|
314
|
-
if (
|
|
314
|
+
if (path3 === matchPath) {
|
|
315
315
|
return;
|
|
316
316
|
}
|
|
317
317
|
if (applicationId === matchApplicationId) {
|
|
318
318
|
return;
|
|
319
319
|
}
|
|
320
320
|
if (matcher.test(matchPath)) {
|
|
321
|
-
const source = `"${
|
|
321
|
+
const source = `"${path3}" of application${ids.length > 0 ? "s" : ""} ${ids.join(", ")}`;
|
|
322
322
|
const destination = `"${matchPath}" of application${matchIds.length > 0 ? "s" : ""} ${matchIds.join(", ")}`;
|
|
323
323
|
errors.push(
|
|
324
324
|
`Overlapping path detected between ${source} and ${destination}`
|
|
@@ -328,7 +328,7 @@ var validateConfigPaths = (applicationConfigsById) => {
|
|
|
328
328
|
);
|
|
329
329
|
});
|
|
330
330
|
if (errors.length) {
|
|
331
|
-
throw new
|
|
331
|
+
throw new MicrofrontendError(`Invalid paths: ${errors.join(", ")}`, {
|
|
332
332
|
type: "config",
|
|
333
333
|
subtype: "conflicting_paths"
|
|
334
334
|
});
|
|
@@ -341,13 +341,13 @@ var validateAppPaths = (name, app) => {
|
|
|
341
341
|
continue;
|
|
342
342
|
}
|
|
343
343
|
if (p.endsWith("/")) {
|
|
344
|
-
throw new
|
|
344
|
+
throw new MicrofrontendError(
|
|
345
345
|
`Invalid path for application "${name}". ${p} must not end with a slash.`,
|
|
346
346
|
{ type: "application", subtype: "invalid_path" }
|
|
347
347
|
);
|
|
348
348
|
}
|
|
349
349
|
if (!p.startsWith("/")) {
|
|
350
|
-
throw new
|
|
350
|
+
throw new MicrofrontendError(
|
|
351
351
|
`Invalid path for application "${name}". ${p} must start with a slash.`,
|
|
352
352
|
{ type: "application", subtype: "invalid_path" }
|
|
353
353
|
);
|
|
@@ -369,13 +369,13 @@ var validateConfigDefaultApplication = (applicationConfigsById) => {
|
|
|
369
369
|
const numApplicationsWithRouting = applicationsWithRoutingNames.length;
|
|
370
370
|
const numApplicationsWithoutRouting = numApplications - numApplicationsWithRouting;
|
|
371
371
|
if (numApplicationsWithoutRouting === 0) {
|
|
372
|
-
throw new
|
|
372
|
+
throw new MicrofrontendError(
|
|
373
373
|
`No default application found. At least one application needs to be the default by omitting routing.`,
|
|
374
374
|
{ type: "config", subtype: "no_default_application" }
|
|
375
375
|
);
|
|
376
376
|
}
|
|
377
377
|
if (numApplicationsWithoutRouting > 1) {
|
|
378
|
-
throw new
|
|
378
|
+
throw new MicrofrontendError(
|
|
379
379
|
`Only one application can omit "routing". Found ${applicationsWithRoutingNames.length - Object.keys(applicationConfigsById).length > 1}.`,
|
|
380
380
|
{ type: "config", subtype: "multiple_default_applications" }
|
|
381
381
|
);
|
|
@@ -387,7 +387,7 @@ var validateConfigOptions = (options) => {
|
|
|
387
387
|
if (!/^[a-zA-Z]{2,}\.[a-zA-Z]{2,}$/.test(
|
|
388
388
|
options.vercel.previewDeploymentSuffix
|
|
389
389
|
)) {
|
|
390
|
-
throw new
|
|
390
|
+
throw new MicrofrontendError(
|
|
391
391
|
`Invalid preview deployment suffix: ${options.vercel.previewDeploymentSuffix}. Should have be formatted like "vercel.app".`,
|
|
392
392
|
{ type: "config", subtype: "invalid_preview_deployment_suffix" }
|
|
393
393
|
);
|
|
@@ -546,7 +546,7 @@ var ChildApplication = class extends Application {
|
|
|
546
546
|
var DEFAULT_LOCAL_PROXY_PORT = 3024;
|
|
547
547
|
|
|
548
548
|
// src/config-v2/microfrontends-config/isomorphic/index.ts
|
|
549
|
-
var
|
|
549
|
+
var MicrofrontendConfigIsomorphic = class {
|
|
550
550
|
constructor({
|
|
551
551
|
config,
|
|
552
552
|
overrides,
|
|
@@ -554,7 +554,7 @@ var MicroFrontendConfigIsomorphic = class {
|
|
|
554
554
|
}) {
|
|
555
555
|
this.childApplications = {};
|
|
556
556
|
var _a, _b, _c, _d;
|
|
557
|
-
|
|
557
|
+
MicrofrontendConfigIsomorphic.validate(config);
|
|
558
558
|
const disableOverrides = ((_b = (_a = config.options) == null ? void 0 : _a.vercel) == null ? void 0 : _b.disableOverrides) ?? false;
|
|
559
559
|
this.overrides = overrides && !disableOverrides ? overrides : void 0;
|
|
560
560
|
this.isMainConfig = isMainConfig(config);
|
|
@@ -586,7 +586,7 @@ var MicroFrontendConfigIsomorphic = class {
|
|
|
586
586
|
);
|
|
587
587
|
}
|
|
588
588
|
if (isMainConfig(config) && !this.defaultApplication) {
|
|
589
|
-
throw new
|
|
589
|
+
throw new MicrofrontendError(
|
|
590
590
|
`Could not find default application in microfrontends configuration`,
|
|
591
591
|
{
|
|
592
592
|
type: "application",
|
|
@@ -616,7 +616,7 @@ var MicroFrontendConfigIsomorphic = class {
|
|
|
616
616
|
meta,
|
|
617
617
|
cookies
|
|
618
618
|
}) {
|
|
619
|
-
return new
|
|
619
|
+
return new MicrofrontendConfigIsomorphic({
|
|
620
620
|
config: (0, import_jsonc_parser.parse)(getConfigStringFromEnv()),
|
|
621
621
|
overrides: parseOverrides(cookies ?? []),
|
|
622
622
|
meta
|
|
@@ -651,7 +651,7 @@ var MicroFrontendConfigIsomorphic = class {
|
|
|
651
651
|
}
|
|
652
652
|
const app = this.childApplications[name];
|
|
653
653
|
if (!app) {
|
|
654
|
-
throw new
|
|
654
|
+
throw new MicrofrontendError(
|
|
655
655
|
`Could not find microfrontends configuration for application "${name}"`,
|
|
656
656
|
{
|
|
657
657
|
type: "application",
|
|
@@ -679,7 +679,7 @@ var MicroFrontendConfigIsomorphic = class {
|
|
|
679
679
|
*/
|
|
680
680
|
getDefaultApplication() {
|
|
681
681
|
if (!this.defaultApplication) {
|
|
682
|
-
throw new
|
|
682
|
+
throw new MicrofrontendError(
|
|
683
683
|
`Could not find default application in microfrontends configuration`,
|
|
684
684
|
{
|
|
685
685
|
type: "application",
|
|
@@ -719,7 +719,7 @@ var MicroFrontendConfigIsomorphic = class {
|
|
|
719
719
|
default: true
|
|
720
720
|
};
|
|
721
721
|
}
|
|
722
|
-
return new
|
|
722
|
+
return new MicrofrontendConfigClient({
|
|
723
723
|
applications
|
|
724
724
|
});
|
|
725
725
|
}
|
|
@@ -729,7 +729,7 @@ var MicroFrontendConfigIsomorphic = class {
|
|
|
729
729
|
};
|
|
730
730
|
|
|
731
731
|
// src/config-v2/microfrontends-config/isomorphic/child.ts
|
|
732
|
-
var
|
|
732
|
+
var MicrofrontendChildConfig = class extends MicrofrontendConfigIsomorphic {
|
|
733
733
|
constructor({
|
|
734
734
|
config,
|
|
735
735
|
overrides,
|
|
@@ -742,7 +742,7 @@ var MicroFrontendChildConfig = class extends MicroFrontendConfigIsomorphic {
|
|
|
742
742
|
};
|
|
743
743
|
|
|
744
744
|
// src/config-v2/microfrontends-config/isomorphic/main.ts
|
|
745
|
-
var
|
|
745
|
+
var MicrofrontendMainConfig = class extends MicrofrontendConfigIsomorphic {
|
|
746
746
|
constructor({
|
|
747
747
|
config,
|
|
748
748
|
overrides,
|
|
@@ -769,7 +769,7 @@ var MicroFrontendMainConfig = class extends MicroFrontendConfigIsomorphic {
|
|
|
769
769
|
}
|
|
770
770
|
}
|
|
771
771
|
if (!defaultApplication) {
|
|
772
|
-
throw new
|
|
772
|
+
throw new MicrofrontendError(
|
|
773
773
|
`Could not find default application in microfrontends configuration`,
|
|
774
774
|
{
|
|
775
775
|
type: "application",
|
|
@@ -789,19 +789,19 @@ var Microfrontends = class {
|
|
|
789
789
|
meta
|
|
790
790
|
}) {
|
|
791
791
|
if (isMainConfig(config)) {
|
|
792
|
-
this.config = new
|
|
792
|
+
this.config = new MicrofrontendMainConfig({ config, overrides, meta });
|
|
793
793
|
} else {
|
|
794
|
-
this.config = new
|
|
794
|
+
this.config = new MicrofrontendChildConfig({ config, overrides, meta });
|
|
795
795
|
}
|
|
796
796
|
}
|
|
797
797
|
isChildConfig() {
|
|
798
|
-
return this.config instanceof
|
|
798
|
+
return this.config instanceof MicrofrontendChildConfig;
|
|
799
799
|
}
|
|
800
800
|
static fromEnv({
|
|
801
801
|
cookies,
|
|
802
802
|
meta
|
|
803
803
|
}) {
|
|
804
|
-
const config =
|
|
804
|
+
const config = MicrofrontendConfigIsomorphic.fromEnv({
|
|
805
805
|
cookies,
|
|
806
806
|
meta
|
|
807
807
|
});
|
|
@@ -809,8 +809,82 @@ var Microfrontends = class {
|
|
|
809
809
|
}
|
|
810
810
|
};
|
|
811
811
|
|
|
812
|
-
// src/config-v2/microfrontends/
|
|
812
|
+
// src/config-v2/microfrontends/utils/find-repository-root.ts
|
|
813
|
+
var import_node_fs = __toESM(require("fs"), 1);
|
|
813
814
|
var import_node_path = __toESM(require("path"), 1);
|
|
815
|
+
var GIT_DIRECTORY = ".git";
|
|
816
|
+
function findRepositoryRoot(startDir) {
|
|
817
|
+
let currentDir = startDir || process.cwd();
|
|
818
|
+
while (currentDir !== import_node_path.default.parse(currentDir).root) {
|
|
819
|
+
const gitPath = import_node_path.default.join(currentDir, GIT_DIRECTORY);
|
|
820
|
+
if (import_node_fs.default.existsSync(gitPath) && import_node_fs.default.statSync(gitPath).isDirectory()) {
|
|
821
|
+
return currentDir;
|
|
822
|
+
}
|
|
823
|
+
currentDir = import_node_path.default.dirname(currentDir);
|
|
824
|
+
}
|
|
825
|
+
throw new Error(
|
|
826
|
+
"Repository root not found. Specify the root of the repository with the `repository.root` option."
|
|
827
|
+
);
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
// src/config-v2/microfrontends/utils/find-package-path.ts
|
|
831
|
+
var import_node_path2 = require("path");
|
|
832
|
+
var import_node_fs2 = require("fs");
|
|
833
|
+
var import_fast_glob = __toESM(require("fast-glob"), 1);
|
|
834
|
+
var configCache = {};
|
|
835
|
+
function findPackagePathWithGlob({
|
|
836
|
+
repositoryRoot,
|
|
837
|
+
name
|
|
838
|
+
}) {
|
|
839
|
+
try {
|
|
840
|
+
const packageJsonPaths = import_fast_glob.default.globSync("**/package.json", {
|
|
841
|
+
cwd: repositoryRoot,
|
|
842
|
+
absolute: true,
|
|
843
|
+
onlyFiles: true,
|
|
844
|
+
followSymbolicLinks: false,
|
|
845
|
+
ignore: ["**/node_modules/**", "**/.git/**"]
|
|
846
|
+
});
|
|
847
|
+
const matchingPaths = [];
|
|
848
|
+
for (const packageJsonPath2 of packageJsonPaths) {
|
|
849
|
+
const packageJsonContent = (0, import_node_fs2.readFileSync)(packageJsonPath2, "utf-8");
|
|
850
|
+
const packageJson = JSON.parse(packageJsonContent);
|
|
851
|
+
if (packageJson.name === name) {
|
|
852
|
+
matchingPaths.push(packageJsonPath2);
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
if (matchingPaths.length > 1) {
|
|
856
|
+
throw new Error(
|
|
857
|
+
`Found multiple packages with the name "${name}" in the repository: ${matchingPaths.join(", ")}`
|
|
858
|
+
);
|
|
859
|
+
}
|
|
860
|
+
if (matchingPaths.length === 0) {
|
|
861
|
+
throw new Error(
|
|
862
|
+
`Could not find package with the name "${name}" in the repository`
|
|
863
|
+
);
|
|
864
|
+
}
|
|
865
|
+
const [packageJsonPath] = matchingPaths;
|
|
866
|
+
return (0, import_node_path2.dirname)(packageJsonPath);
|
|
867
|
+
} catch (error) {
|
|
868
|
+
return null;
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
function findPackagePath(opts) {
|
|
872
|
+
const cacheKey = `${opts.repositoryRoot}-${opts.name}`;
|
|
873
|
+
if (configCache[cacheKey]) {
|
|
874
|
+
return configCache[cacheKey];
|
|
875
|
+
}
|
|
876
|
+
const result = findPackagePathWithGlob(opts);
|
|
877
|
+
if (!result) {
|
|
878
|
+
throw new Error(
|
|
879
|
+
`Could not find package with the name "${opts.name}" in the repository`
|
|
880
|
+
);
|
|
881
|
+
}
|
|
882
|
+
configCache[cacheKey] = result;
|
|
883
|
+
return result;
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
// src/config-v2/microfrontends/server/utils/get-output-file-path.ts
|
|
887
|
+
var import_node_path3 = __toESM(require("path"), 1);
|
|
814
888
|
|
|
815
889
|
// src/config-v2/microfrontends/server/constants.ts
|
|
816
890
|
var MFE_CONFIG_DEFAULT_FILE_PATH = "microfrontends";
|
|
@@ -824,13 +898,13 @@ function isVercel() {
|
|
|
824
898
|
// src/config-v2/microfrontends/server/utils/get-output-file-path.ts
|
|
825
899
|
function getOutputFilePath() {
|
|
826
900
|
if (isVercel()) {
|
|
827
|
-
return
|
|
901
|
+
return import_node_path3.default.join(
|
|
828
902
|
".vercel",
|
|
829
903
|
MFE_CONFIG_DEFAULT_FILE_PATH,
|
|
830
904
|
MFE_CONFIG_DEFAULT_FILE_NAME
|
|
831
905
|
);
|
|
832
906
|
}
|
|
833
|
-
return
|
|
907
|
+
return import_node_path3.default.join(MFE_CONFIG_DEFAULT_FILE_PATH, MFE_CONFIG_DEFAULT_FILE_NAME);
|
|
834
908
|
}
|
|
835
909
|
|
|
836
910
|
// src/config-v2/microfrontends/server/validation.ts
|
|
@@ -838,14 +912,14 @@ var import_jsonc_parser2 = require("jsonc-parser");
|
|
|
838
912
|
var import_ajv = require("ajv");
|
|
839
913
|
|
|
840
914
|
// src/config/errors.ts
|
|
841
|
-
var
|
|
915
|
+
var MicrofrontendError2 = class extends Error {
|
|
842
916
|
constructor(message, opts) {
|
|
843
917
|
super(message);
|
|
844
|
-
this.name = "
|
|
845
|
-
this.source = (opts == null ? void 0 : opts.source) ?? "@vercel/
|
|
918
|
+
this.name = "MicrofrontendsError";
|
|
919
|
+
this.source = (opts == null ? void 0 : opts.source) ?? "@vercel/microfrontends";
|
|
846
920
|
this.type = (opts == null ? void 0 : opts.type) ?? "unknown";
|
|
847
921
|
this.subtype = opts == null ? void 0 : opts.subtype;
|
|
848
|
-
Error.captureStackTrace(this,
|
|
922
|
+
Error.captureStackTrace(this, MicrofrontendError2);
|
|
849
923
|
}
|
|
850
924
|
isKnown() {
|
|
851
925
|
return this.type !== "unknown";
|
|
@@ -854,13 +928,13 @@ var MicroFrontendError2 = class extends Error {
|
|
|
854
928
|
return !this.isKnown();
|
|
855
929
|
}
|
|
856
930
|
/**
|
|
857
|
-
* Converts an error to a
|
|
931
|
+
* Converts an error to a MicrofrontendsError.
|
|
858
932
|
* @param original - The original error to convert.
|
|
859
|
-
* @returns The converted
|
|
933
|
+
* @returns The converted MicrofrontendsError.
|
|
860
934
|
*/
|
|
861
935
|
static convert(original, opts) {
|
|
862
936
|
if (opts == null ? void 0 : opts.fileName) {
|
|
863
|
-
const err =
|
|
937
|
+
const err = MicrofrontendError2.convertFSError(original, opts.fileName);
|
|
864
938
|
if (err) {
|
|
865
939
|
return err;
|
|
866
940
|
}
|
|
@@ -868,25 +942,25 @@ var MicroFrontendError2 = class extends Error {
|
|
|
868
942
|
if (original.message.includes(
|
|
869
943
|
"Code generation from strings disallowed for this context"
|
|
870
944
|
)) {
|
|
871
|
-
return new
|
|
945
|
+
return new MicrofrontendError2(original.message, {
|
|
872
946
|
type: "config",
|
|
873
947
|
subtype: "unsupported_validation_env",
|
|
874
948
|
source: "ajv"
|
|
875
949
|
});
|
|
876
950
|
}
|
|
877
|
-
return new
|
|
951
|
+
return new MicrofrontendError2(original.message);
|
|
878
952
|
}
|
|
879
953
|
static convertFSError(original, fileName) {
|
|
880
954
|
if (original instanceof Error && "code" in original) {
|
|
881
955
|
if (original.code === "ENOENT") {
|
|
882
|
-
return new
|
|
956
|
+
return new MicrofrontendError2(`Could not find "${fileName}"`, {
|
|
883
957
|
type: "config",
|
|
884
958
|
subtype: "unable_to_read_file",
|
|
885
959
|
source: "fs"
|
|
886
960
|
});
|
|
887
961
|
}
|
|
888
962
|
if (original.code === "EACCES") {
|
|
889
|
-
return new
|
|
963
|
+
return new MicrofrontendError2(
|
|
890
964
|
`Permission denied while accessing "${fileName}"`,
|
|
891
965
|
{
|
|
892
966
|
type: "config",
|
|
@@ -897,7 +971,7 @@ var MicroFrontendError2 = class extends Error {
|
|
|
897
971
|
}
|
|
898
972
|
}
|
|
899
973
|
if (original instanceof SyntaxError) {
|
|
900
|
-
return new
|
|
974
|
+
return new MicrofrontendError2(
|
|
901
975
|
`Failed to parse "${fileName}": Invalid JSON format.`,
|
|
902
976
|
{
|
|
903
977
|
type: "config",
|
|
@@ -909,23 +983,23 @@ var MicroFrontendError2 = class extends Error {
|
|
|
909
983
|
return null;
|
|
910
984
|
}
|
|
911
985
|
/**
|
|
912
|
-
* Handles an unknown error and returns a
|
|
986
|
+
* Handles an unknown error and returns a MicrofrontendsError instance.
|
|
913
987
|
* @param err - The error to handle.
|
|
914
|
-
* @returns A
|
|
988
|
+
* @returns A MicrofrontendsError instance.
|
|
915
989
|
*/
|
|
916
990
|
static handle(err, opts) {
|
|
917
|
-
if (err instanceof
|
|
991
|
+
if (err instanceof MicrofrontendError2) {
|
|
918
992
|
return err;
|
|
919
993
|
}
|
|
920
994
|
if (err instanceof Error) {
|
|
921
|
-
return
|
|
995
|
+
return MicrofrontendError2.convert(err, opts);
|
|
922
996
|
}
|
|
923
997
|
if (typeof err === "object" && err !== null) {
|
|
924
998
|
if ("message" in err && typeof err.message === "string") {
|
|
925
|
-
return
|
|
999
|
+
return MicrofrontendError2.convert(new Error(err.message), opts);
|
|
926
1000
|
}
|
|
927
1001
|
}
|
|
928
|
-
return new
|
|
1002
|
+
return new MicrofrontendError2("An unknown error occurred");
|
|
929
1003
|
}
|
|
930
1004
|
};
|
|
931
1005
|
|
|
@@ -1140,10 +1214,6 @@ var schema_v2_default = {
|
|
|
1140
1214
|
type: "string",
|
|
1141
1215
|
description: "flag name that can be used to enable/disable all paths in the group"
|
|
1142
1216
|
},
|
|
1143
|
-
routeToDefaultApplication: {
|
|
1144
|
-
type: "boolean",
|
|
1145
|
-
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."
|
|
1146
|
-
},
|
|
1147
1217
|
paths: {
|
|
1148
1218
|
type: "array",
|
|
1149
1219
|
items: {
|
|
@@ -1203,7 +1273,7 @@ function validateSchema(configString) {
|
|
|
1203
1273
|
const validate = ajv.compile(SCHEMA);
|
|
1204
1274
|
const isValid = validate(parsedConfig);
|
|
1205
1275
|
if (!isValid) {
|
|
1206
|
-
throw new
|
|
1276
|
+
throw new MicrofrontendError2(
|
|
1207
1277
|
`Invalid config: ${ajv.errorsText(validate.errors)}`,
|
|
1208
1278
|
{ type: "config", subtype: "does_not_match_schema" }
|
|
1209
1279
|
);
|
|
@@ -1220,8 +1290,8 @@ var MicrofrontendsServer = class extends Microfrontends {
|
|
|
1220
1290
|
pretty: true
|
|
1221
1291
|
}) {
|
|
1222
1292
|
const outputPath = getOutputFilePath();
|
|
1223
|
-
|
|
1224
|
-
|
|
1293
|
+
import_node_fs3.default.mkdirSync((0, import_node_path4.dirname)(outputPath), { recursive: true });
|
|
1294
|
+
import_node_fs3.default.writeFileSync(
|
|
1225
1295
|
outputPath,
|
|
1226
1296
|
JSON.stringify(
|
|
1227
1297
|
this.config.toSchemaJson(),
|
|
@@ -1254,7 +1324,7 @@ var MicrofrontendsServer = class extends Microfrontends {
|
|
|
1254
1324
|
meta
|
|
1255
1325
|
});
|
|
1256
1326
|
}
|
|
1257
|
-
throw new
|
|
1327
|
+
throw new MicrofrontendError(
|
|
1258
1328
|
"Invalid config: must be a string or an object",
|
|
1259
1329
|
{ type: "config", subtype: "does_not_match_schema" }
|
|
1260
1330
|
);
|
|
@@ -1289,17 +1359,74 @@ var MicrofrontendsServer = class extends Microfrontends {
|
|
|
1289
1359
|
static fromFile({
|
|
1290
1360
|
filePath,
|
|
1291
1361
|
cookies,
|
|
1292
|
-
meta
|
|
1362
|
+
meta,
|
|
1363
|
+
options
|
|
1293
1364
|
}) {
|
|
1294
1365
|
try {
|
|
1295
|
-
const
|
|
1366
|
+
const configJson = import_node_fs3.default.readFileSync(filePath, "utf-8");
|
|
1367
|
+
const config = MicrofrontendsServer.validate(configJson);
|
|
1368
|
+
if (!isMainConfig(config) && (options == null ? void 0 : options.resolveMainConfig)) {
|
|
1369
|
+
const repositoryRoot = findRepositoryRoot();
|
|
1370
|
+
const packagePath = findPackagePath({
|
|
1371
|
+
repositoryRoot,
|
|
1372
|
+
name: config.partOf
|
|
1373
|
+
});
|
|
1374
|
+
if (!packagePath) {
|
|
1375
|
+
throw new MicrofrontendError(
|
|
1376
|
+
`Could not find default application "${config.partOf}" in the repository`,
|
|
1377
|
+
{ type: "config", subtype: "not_found" }
|
|
1378
|
+
);
|
|
1379
|
+
}
|
|
1380
|
+
const mainConfigPath = (0, import_node_path4.join)(packagePath, "microfrontends.json");
|
|
1381
|
+
return MicrofrontendsServer.fromMainConfigFile({
|
|
1382
|
+
filePath: mainConfigPath,
|
|
1383
|
+
overrides: cookies ? parseOverrides(cookies) : void 0
|
|
1384
|
+
});
|
|
1385
|
+
}
|
|
1296
1386
|
return new MicrofrontendsServer({
|
|
1297
|
-
config
|
|
1387
|
+
config,
|
|
1298
1388
|
overrides: cookies ? parseOverrides(cookies) : void 0,
|
|
1299
1389
|
meta
|
|
1300
1390
|
});
|
|
1301
1391
|
} catch (e) {
|
|
1302
|
-
throw
|
|
1392
|
+
throw MicrofrontendError.handle(e, {
|
|
1393
|
+
fileName: filePath
|
|
1394
|
+
});
|
|
1395
|
+
}
|
|
1396
|
+
}
|
|
1397
|
+
/*
|
|
1398
|
+
* Generates a MicrofrontendMainConfig instance from a file.
|
|
1399
|
+
*/
|
|
1400
|
+
static fromMainConfigFile({
|
|
1401
|
+
filePath,
|
|
1402
|
+
overrides
|
|
1403
|
+
}) {
|
|
1404
|
+
try {
|
|
1405
|
+
const config = import_node_fs3.default.readFileSync(filePath, "utf-8");
|
|
1406
|
+
const validatedConfig = MicrofrontendsServer.validate(config);
|
|
1407
|
+
if (!isMainConfig(validatedConfig)) {
|
|
1408
|
+
throw new MicrofrontendError(
|
|
1409
|
+
`${filePath} is not a main microfrontend config`,
|
|
1410
|
+
{
|
|
1411
|
+
type: "config",
|
|
1412
|
+
subtype: "invalid_main_path"
|
|
1413
|
+
}
|
|
1414
|
+
);
|
|
1415
|
+
}
|
|
1416
|
+
const [defaultApplication] = Object.entries(validatedConfig.applications).filter(([, app]) => isDefaultApp(app)).map(([name]) => name);
|
|
1417
|
+
if (!defaultApplication) {
|
|
1418
|
+
throw new MicrofrontendError(
|
|
1419
|
+
`No default application found. At least one application needs to be the default by omitting routing.`,
|
|
1420
|
+
{ type: "config", subtype: "no_default_application" }
|
|
1421
|
+
);
|
|
1422
|
+
}
|
|
1423
|
+
return new MicrofrontendsServer({
|
|
1424
|
+
config: validatedConfig,
|
|
1425
|
+
overrides,
|
|
1426
|
+
meta: { fromApp: defaultApplication }
|
|
1427
|
+
});
|
|
1428
|
+
} catch (e) {
|
|
1429
|
+
throw MicrofrontendError.handle(e, {
|
|
1303
1430
|
fileName: filePath
|
|
1304
1431
|
});
|
|
1305
1432
|
}
|