@vercel/microfrontends 0.10.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 +5 -5
- package/dist/bin/cli.cjs +172 -86
- package/dist/config/client.d.ts +1 -1
- package/dist/config/edge.d.ts +2 -2
- package/dist/config.cjs +1 -6
- package/dist/config.cjs.map +1 -1
- package/dist/config.d.ts +3 -3
- package/dist/config.js +1 -6
- package/dist/config.js.map +1 -1
- package/dist/{index-05742bef.d.ts → index-acb44057.d.ts} +2 -2
- package/dist/{microfrontend-config-2425db74.d.ts → microfrontend-config-983a5139.d.ts} +1 -1
- 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 +3 -10
- package/dist/next/config.cjs.map +1 -1
- package/dist/next/config.js +3 -10
- package/dist/next/config.js.map +1 -1
- package/dist/next/middleware.cjs +5 -7
- package/dist/next/middleware.cjs.map +1 -1
- package/dist/next/middleware.js +5 -7
- package/dist/next/middleware.js.map +1 -1
- package/dist/next/testing.cjs +1 -6
- package/dist/next/testing.cjs.map +1 -1
- package/dist/next/testing.d.ts +2 -2
- package/dist/next/testing.js +1 -6
- package/dist/next/testing.js.map +1 -1
- package/dist/overrides.d.ts +2 -2
- 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-13f3e535.d.ts → types-c3d15d04.d.ts} +1 -1
- package/dist/v2/config.d.ts +3 -3
- package/dist/v2/microfrontends/server.cjs +122 -32
- package/dist/v2/microfrontends/server.cjs.map +1 -1
- package/dist/v2/microfrontends/server.d.ts +7 -4
- package/dist/v2/microfrontends/server.js +122 -32
- package/dist/v2/microfrontends/server.js.map +1 -1
- package/dist/v2/microfrontends.d.ts +3 -3
- 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 +128 -40
- package/dist/v2/next/config.cjs.map +1 -1
- package/dist/v2/next/config.js +128 -40
- package/dist/v2/next/config.js.map +1 -1
- package/dist/v2/next/middleware.cjs +1 -1
- package/dist/v2/next/middleware.cjs.map +1 -1
- package/dist/v2/next/middleware.js +1 -1
- package/dist/v2/next/middleware.js.map +1 -1
- package/dist/v2/overrides.d.ts +3 -3
- package/dist/v2/schema.cjs.map +1 -1
- package/dist/v2/schema.d.ts +1 -1
- package/dist/validation.cjs +0 -8
- package/dist/validation.cjs.map +1 -1
- package/dist/validation.d.ts +2 -8
- package/dist/validation.js +0 -8
- package/dist/validation.js.map +1 -1
- package/package.json +8 -7
- package/schema/schema-v2.json +0 -4
- package/schema/schema.json +0 -4
package/README.md
CHANGED
|
@@ -89,17 +89,17 @@ the `files` attribute.
|
|
|
89
89
|
#### `next.config.js`
|
|
90
90
|
|
|
91
91
|
In the `next.config.js` configuration for your application, wrap your config
|
|
92
|
-
with the `
|
|
92
|
+
with the `withMicrofrontends` function specifying the `micro-frontends.json`
|
|
93
93
|
config that you created above.
|
|
94
94
|
|
|
95
95
|
```js filename="next.config.js"
|
|
96
|
-
const {
|
|
96
|
+
const { withMicrofrontends } = require('@vercel/microfrontends/next/config');
|
|
97
97
|
|
|
98
98
|
const nextConfig = {
|
|
99
99
|
// ...
|
|
100
100
|
};
|
|
101
101
|
|
|
102
|
-
module.exports =
|
|
102
|
+
module.exports = withMicrofrontends(
|
|
103
103
|
nextConfig,
|
|
104
104
|
path.join(
|
|
105
105
|
__dirname,
|
|
@@ -117,13 +117,13 @@ Next you have to include the micro-frontends middleware. You can run this code
|
|
|
117
117
|
in your middleware to apply the micro-frontends routing logic.
|
|
118
118
|
|
|
119
119
|
```typescript filename="middleware.ts"
|
|
120
|
-
import {
|
|
120
|
+
import { runMicrofrontendsMiddleware } from '@vercel/microfrontends/next/middleware';
|
|
121
121
|
|
|
122
122
|
export async function middleware(
|
|
123
123
|
request: NextRequest,
|
|
124
124
|
event: NextFetchEvent,
|
|
125
125
|
): Promise<Response> {
|
|
126
|
-
let response = await
|
|
126
|
+
let response = await runMicrofrontendsMiddleware(request);
|
|
127
127
|
if (response) {
|
|
128
128
|
return response;
|
|
129
129
|
}
|
package/dist/bin/cli.cjs
CHANGED
|
@@ -29,7 +29,7 @@ var import_commander = require("commander");
|
|
|
29
29
|
// package.json
|
|
30
30
|
var package_default = {
|
|
31
31
|
name: "@vercel/microfrontends",
|
|
32
|
-
version: "0.10.
|
|
32
|
+
version: "0.10.1",
|
|
33
33
|
private: false,
|
|
34
34
|
description: "Defines configuration and utilities for micro-frontend development",
|
|
35
35
|
repository: {
|
|
@@ -161,6 +161,7 @@ var package_default = {
|
|
|
161
161
|
ajv: "^8.17.1",
|
|
162
162
|
commander: "^12.1.0",
|
|
163
163
|
cookie: "0.4.0",
|
|
164
|
+
"fast-glob": "^3.3.2",
|
|
164
165
|
"http-proxy": "^1.18.1",
|
|
165
166
|
"jsonc-parser": "^3.3.1",
|
|
166
167
|
"path-to-regexp": "6.2.1"
|
|
@@ -180,9 +181,9 @@ var package_default = {
|
|
|
180
181
|
"@vercel-private/conformance": "^1.12.2-canary.0",
|
|
181
182
|
jest: "^29.7.0",
|
|
182
183
|
"jest-environment-jsdom": "29.2.2",
|
|
183
|
-
next: "15.0.4-canary.
|
|
184
|
-
react: "19.0.0-rc-
|
|
185
|
-
"react-dom": "19.0.0-rc-
|
|
184
|
+
next: "15.0.4-canary.41",
|
|
185
|
+
react: "19.0.0-rc-de68d2f4-20241204",
|
|
186
|
+
"react-dom": "19.0.0-rc-de68d2f4-20241204",
|
|
186
187
|
"ts-json-schema-generator": "^1.1.2",
|
|
187
188
|
tsup: "^6.6.2",
|
|
188
189
|
tsx: "^4.6.2",
|
|
@@ -190,9 +191,9 @@ var package_default = {
|
|
|
190
191
|
webpack: "5"
|
|
191
192
|
},
|
|
192
193
|
peerDependencies: {
|
|
193
|
-
next: "15.0.4-canary.
|
|
194
|
-
react: "19.0.0-rc-
|
|
195
|
-
"react-dom": "19.0.0-rc-
|
|
194
|
+
next: "15.0.4-canary.41",
|
|
195
|
+
react: "19.0.0-rc-de68d2f4-20241204",
|
|
196
|
+
"react-dom": "19.0.0-rc-de68d2f4-20241204"
|
|
196
197
|
},
|
|
197
198
|
publishConfig: {
|
|
198
199
|
access: "restricted"
|
|
@@ -873,10 +874,6 @@ var schema_default = {
|
|
|
873
874
|
flag: {
|
|
874
875
|
type: "string",
|
|
875
876
|
description: "flag name that can be used to enable/disable all paths in the group"
|
|
876
|
-
},
|
|
877
|
-
routeToDefaultApplication: {
|
|
878
|
-
type: "boolean",
|
|
879
|
-
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."
|
|
880
877
|
}
|
|
881
878
|
}
|
|
882
879
|
},
|
|
@@ -1093,8 +1090,8 @@ function validateMainPath(applicationConfigsById) {
|
|
|
1093
1090
|
});
|
|
1094
1091
|
}
|
|
1095
1092
|
for (const { id: otherId, paths } of pathsWithApp) {
|
|
1096
|
-
const isValid = paths.every((
|
|
1097
|
-
const matcher = (0, import_path_to_regexp.pathToRegexp)(
|
|
1093
|
+
const isValid = paths.every((path4) => {
|
|
1094
|
+
const matcher = (0, import_path_to_regexp.pathToRegexp)(path4);
|
|
1098
1095
|
return !matcher.test(defaultRoute);
|
|
1099
1096
|
});
|
|
1100
1097
|
if (!isValid) {
|
|
@@ -1106,8 +1103,8 @@ function validateMainPath(applicationConfigsById) {
|
|
|
1106
1103
|
}
|
|
1107
1104
|
} else {
|
|
1108
1105
|
const allPaths = app.routing.matches.flatMap((match) => match.paths);
|
|
1109
|
-
const isValid = allPaths.some((
|
|
1110
|
-
const matcher = (0, import_path_to_regexp.pathToRegexp)(
|
|
1106
|
+
const isValid = allPaths.some((path4) => {
|
|
1107
|
+
const matcher = (0, import_path_to_regexp.pathToRegexp)(path4);
|
|
1111
1108
|
return matcher.test(defaultRoute);
|
|
1112
1109
|
});
|
|
1113
1110
|
if (!isValid) {
|
|
@@ -1127,18 +1124,18 @@ var validatePaths = (applicationConfigsById) => {
|
|
|
1127
1124
|
continue;
|
|
1128
1125
|
}
|
|
1129
1126
|
for (const pathMatch of app.routing.matches) {
|
|
1130
|
-
for (const
|
|
1131
|
-
const maybeError = validatePathExpression(
|
|
1127
|
+
for (const path4 of pathMatch.paths) {
|
|
1128
|
+
const maybeError = validatePathExpression(path4);
|
|
1132
1129
|
if (maybeError) {
|
|
1133
1130
|
errors.push(maybeError);
|
|
1134
1131
|
}
|
|
1135
|
-
const existing = pathsByApplicationId.get(
|
|
1132
|
+
const existing = pathsByApplicationId.get(path4);
|
|
1136
1133
|
if (existing) {
|
|
1137
1134
|
existing.applications.push(id);
|
|
1138
1135
|
} else {
|
|
1139
|
-
pathsByApplicationId.set(
|
|
1136
|
+
pathsByApplicationId.set(path4, {
|
|
1140
1137
|
applications: [id],
|
|
1141
|
-
matcher: (0, import_path_to_regexp.pathToRegexp)(
|
|
1138
|
+
matcher: (0, import_path_to_regexp.pathToRegexp)(path4),
|
|
1142
1139
|
applicationId: id
|
|
1143
1140
|
});
|
|
1144
1141
|
}
|
|
@@ -1146,10 +1143,10 @@ var validatePaths = (applicationConfigsById) => {
|
|
|
1146
1143
|
}
|
|
1147
1144
|
}
|
|
1148
1145
|
const entries = Array.from(pathsByApplicationId.entries());
|
|
1149
|
-
entries.forEach(([
|
|
1146
|
+
entries.forEach(([path4, { applications: ids, matcher, applicationId }]) => {
|
|
1150
1147
|
if (ids.length > 1) {
|
|
1151
1148
|
errors.push(
|
|
1152
|
-
`Duplicate path "${
|
|
1149
|
+
`Duplicate path "${path4}" for applications "${ids.join(", ")}"`
|
|
1153
1150
|
);
|
|
1154
1151
|
}
|
|
1155
1152
|
entries.forEach(
|
|
@@ -1157,14 +1154,14 @@ var validatePaths = (applicationConfigsById) => {
|
|
|
1157
1154
|
matchPath,
|
|
1158
1155
|
{ applications: matchIds, applicationId: matchApplicationId }
|
|
1159
1156
|
]) => {
|
|
1160
|
-
if (
|
|
1157
|
+
if (path4 === matchPath) {
|
|
1161
1158
|
return;
|
|
1162
1159
|
}
|
|
1163
1160
|
if (applicationId === matchApplicationId) {
|
|
1164
1161
|
return;
|
|
1165
1162
|
}
|
|
1166
1163
|
if (matcher.test(matchPath)) {
|
|
1167
|
-
const source = `"${
|
|
1164
|
+
const source = `"${path4}" of application${ids.length > 0 ? "s" : ""} ${ids.join(", ")}`;
|
|
1168
1165
|
const destination = `"${matchPath}" of application${matchIds.length > 0 ? "s" : ""} ${matchIds.join(", ")}`;
|
|
1169
1166
|
errors.push(
|
|
1170
1167
|
`Overlapping path detected between ${source} and ${destination}`
|
|
@@ -1181,25 +1178,25 @@ var validatePaths = (applicationConfigsById) => {
|
|
|
1181
1178
|
}
|
|
1182
1179
|
};
|
|
1183
1180
|
var PATH_DEFAULT_PATTERN = "[^\\/#\\?]+?";
|
|
1184
|
-
function validatePathExpression(
|
|
1185
|
-
const tokens = (0, import_path_to_regexp.parse)(
|
|
1181
|
+
function validatePathExpression(path4) {
|
|
1182
|
+
const tokens = (0, import_path_to_regexp.parse)(path4);
|
|
1186
1183
|
for (let i = 0; i < tokens.length; i++) {
|
|
1187
1184
|
const token = tokens[i];
|
|
1188
1185
|
if (token === void 0) {
|
|
1189
|
-
return `token ${i} in ${
|
|
1186
|
+
return `token ${i} in ${path4} is undefined, this shouldn't happen`;
|
|
1190
1187
|
}
|
|
1191
1188
|
if (typeof token !== "string") {
|
|
1192
1189
|
if (token.pattern !== PATH_DEFAULT_PATTERN) {
|
|
1193
|
-
return `Path ${
|
|
1190
|
+
return `Path ${path4} cannot use a regular expression wildcard`;
|
|
1194
1191
|
}
|
|
1195
1192
|
if (token.prefix !== "/") {
|
|
1196
|
-
return `Wildcard :${token.name} must be immediately after a / in ${
|
|
1193
|
+
return `Wildcard :${token.name} must be immediately after a / in ${path4}`;
|
|
1197
1194
|
}
|
|
1198
1195
|
if (token.suffix) {
|
|
1199
1196
|
return `Wildcard suffix on :${token.name} is not allowed. Suffixes are not supported`;
|
|
1200
1197
|
}
|
|
1201
1198
|
if (token.modifier && i !== tokens.length - 1) {
|
|
1202
|
-
return `Modifier ${token.modifier} is not allowed on wildcard :${token.name} in ${
|
|
1199
|
+
return `Modifier ${token.modifier} is not allowed on wildcard :${token.name} in ${path4}. Modifiers are only allowed in the last path component`;
|
|
1203
1200
|
}
|
|
1204
1201
|
}
|
|
1205
1202
|
}
|
|
@@ -1237,11 +1234,10 @@ var validateOptions = (options) => {
|
|
|
1237
1234
|
// src/config/utils/convert.ts
|
|
1238
1235
|
function convertV1RoutingToV2Routing(routing) {
|
|
1239
1236
|
return routing.matches.map((group) => {
|
|
1240
|
-
var _a
|
|
1237
|
+
var _a;
|
|
1241
1238
|
return {
|
|
1242
1239
|
group: group.group,
|
|
1243
1240
|
flag: (_a = group.options) == null ? void 0 : _a.flag,
|
|
1244
|
-
routeToDefaultApplication: (_b = group.options) == null ? void 0 : _b.routeToDefaultApplication,
|
|
1245
1241
|
paths: group.paths
|
|
1246
1242
|
};
|
|
1247
1243
|
});
|
|
@@ -1478,22 +1474,22 @@ var validateConfigPaths = (applicationConfigsById) => {
|
|
|
1478
1474
|
continue;
|
|
1479
1475
|
}
|
|
1480
1476
|
for (const pathMatch of app.routing) {
|
|
1481
|
-
for (const
|
|
1482
|
-
const tokens = (0, import_path_to_regexp2.parse)(
|
|
1477
|
+
for (const path4 of pathMatch.paths) {
|
|
1478
|
+
const tokens = (0, import_path_to_regexp2.parse)(path4);
|
|
1483
1479
|
for (const token of tokens.slice(0, -1)) {
|
|
1484
1480
|
if (typeof token !== "string") {
|
|
1485
1481
|
errors.push(
|
|
1486
|
-
`Path ${
|
|
1482
|
+
`Path ${path4} may only have a :wildcard in the last path component`
|
|
1487
1483
|
);
|
|
1488
1484
|
}
|
|
1489
1485
|
}
|
|
1490
|
-
const existing = pathsByApplicationId.get(
|
|
1486
|
+
const existing = pathsByApplicationId.get(path4);
|
|
1491
1487
|
if (existing) {
|
|
1492
1488
|
existing.applications.push(id);
|
|
1493
1489
|
} else {
|
|
1494
|
-
pathsByApplicationId.set(
|
|
1490
|
+
pathsByApplicationId.set(path4, {
|
|
1495
1491
|
applications: [id],
|
|
1496
|
-
matcher: (0, import_path_to_regexp2.pathToRegexp)(
|
|
1492
|
+
matcher: (0, import_path_to_regexp2.pathToRegexp)(path4),
|
|
1497
1493
|
applicationId: id
|
|
1498
1494
|
});
|
|
1499
1495
|
}
|
|
@@ -1501,10 +1497,10 @@ var validateConfigPaths = (applicationConfigsById) => {
|
|
|
1501
1497
|
}
|
|
1502
1498
|
}
|
|
1503
1499
|
const entries = Array.from(pathsByApplicationId.entries());
|
|
1504
|
-
entries.forEach(([
|
|
1500
|
+
entries.forEach(([path4, { applications: ids, matcher, applicationId }]) => {
|
|
1505
1501
|
if (ids.length > 1) {
|
|
1506
1502
|
errors.push(
|
|
1507
|
-
`Duplicate path "${
|
|
1503
|
+
`Duplicate path "${path4}" for applications "${ids.join(", ")}"`
|
|
1508
1504
|
);
|
|
1509
1505
|
}
|
|
1510
1506
|
entries.forEach(
|
|
@@ -1512,14 +1508,14 @@ var validateConfigPaths = (applicationConfigsById) => {
|
|
|
1512
1508
|
matchPath,
|
|
1513
1509
|
{ applications: matchIds, applicationId: matchApplicationId }
|
|
1514
1510
|
]) => {
|
|
1515
|
-
if (
|
|
1511
|
+
if (path4 === matchPath) {
|
|
1516
1512
|
return;
|
|
1517
1513
|
}
|
|
1518
1514
|
if (applicationId === matchApplicationId) {
|
|
1519
1515
|
return;
|
|
1520
1516
|
}
|
|
1521
1517
|
if (matcher.test(matchPath)) {
|
|
1522
|
-
const source = `"${
|
|
1518
|
+
const source = `"${path4}" of application${ids.length > 0 ? "s" : ""} ${ids.join(", ")}`;
|
|
1523
1519
|
const destination = `"${matchPath}" of application${matchIds.length > 0 ? "s" : ""} ${matchIds.join(", ")}`;
|
|
1524
1520
|
errors.push(
|
|
1525
1521
|
`Overlapping path detected between ${source} and ${destination}`
|
|
@@ -1794,21 +1790,21 @@ var MicrofrontendConfigClient = class {
|
|
|
1794
1790
|
isEqual(other) {
|
|
1795
1791
|
return JSON.stringify(this.applications) === JSON.stringify(other.applications);
|
|
1796
1792
|
}
|
|
1797
|
-
getApplicationNameForPath(
|
|
1798
|
-
if (!
|
|
1793
|
+
getApplicationNameForPath(path4) {
|
|
1794
|
+
if (!path4.startsWith("/")) {
|
|
1799
1795
|
throw new Error(`Path must start with a /`);
|
|
1800
1796
|
}
|
|
1801
|
-
if (this.pathCache[
|
|
1802
|
-
return this.pathCache[
|
|
1797
|
+
if (this.pathCache[path4]) {
|
|
1798
|
+
return this.pathCache[path4];
|
|
1803
1799
|
}
|
|
1804
|
-
const pathname = new URL(
|
|
1800
|
+
const pathname = new URL(path4, "https://example.com").pathname;
|
|
1805
1801
|
for (const [name, application] of Object.entries(this.applications)) {
|
|
1806
1802
|
if (application.routing) {
|
|
1807
1803
|
for (const group of application.routing) {
|
|
1808
1804
|
for (const childPath of group.paths) {
|
|
1809
1805
|
const regexp = (0, import_path_to_regexp3.pathToRegexp)(childPath);
|
|
1810
1806
|
if (regexp.test(pathname)) {
|
|
1811
|
-
this.pathCache[
|
|
1807
|
+
this.pathCache[path4] = name;
|
|
1812
1808
|
return name;
|
|
1813
1809
|
}
|
|
1814
1810
|
}
|
|
@@ -1821,7 +1817,7 @@ var MicrofrontendConfigClient = class {
|
|
|
1821
1817
|
if (!defaultApplication) {
|
|
1822
1818
|
return null;
|
|
1823
1819
|
}
|
|
1824
|
-
this.pathCache[
|
|
1820
|
+
this.pathCache[path4] = defaultApplication[0];
|
|
1825
1821
|
return defaultApplication[0];
|
|
1826
1822
|
}
|
|
1827
1823
|
serialize() {
|
|
@@ -2089,14 +2085,14 @@ var MicrofrontendMainConfig = class extends MicrofrontendConfigIsomorphic {
|
|
|
2089
2085
|
}
|
|
2090
2086
|
};
|
|
2091
2087
|
|
|
2092
|
-
// src/config-v2/microfrontends/
|
|
2088
|
+
// src/config-v2/microfrontends/utils/is-main-config.ts
|
|
2093
2089
|
function isMainConfig2(c) {
|
|
2094
2090
|
return !("partOf" in c);
|
|
2095
2091
|
}
|
|
2096
2092
|
|
|
2097
2093
|
// src/config-v2/microfrontends/server/index.ts
|
|
2098
|
-
var
|
|
2099
|
-
var
|
|
2094
|
+
var import_node_fs5 = __toESM(require("fs"), 1);
|
|
2095
|
+
var import_node_path6 = require("path");
|
|
2100
2096
|
|
|
2101
2097
|
// src/config-v2/microfrontends-config/isomorphic/child.ts
|
|
2102
2098
|
var MicrofrontendChildConfig = class extends MicrofrontendConfigIsomorphic {
|
|
@@ -2139,6 +2135,80 @@ var Microfrontends = class {
|
|
|
2139
2135
|
}
|
|
2140
2136
|
};
|
|
2141
2137
|
|
|
2138
|
+
// src/config-v2/microfrontends/utils/find-repository-root.ts
|
|
2139
|
+
var import_node_fs3 = __toESM(require("fs"), 1);
|
|
2140
|
+
var import_node_path4 = __toESM(require("path"), 1);
|
|
2141
|
+
var GIT_DIRECTORY = ".git";
|
|
2142
|
+
function findRepositoryRoot(startDir) {
|
|
2143
|
+
let currentDir = startDir || process.cwd();
|
|
2144
|
+
while (currentDir !== import_node_path4.default.parse(currentDir).root) {
|
|
2145
|
+
const gitPath = import_node_path4.default.join(currentDir, GIT_DIRECTORY);
|
|
2146
|
+
if (import_node_fs3.default.existsSync(gitPath) && import_node_fs3.default.statSync(gitPath).isDirectory()) {
|
|
2147
|
+
return currentDir;
|
|
2148
|
+
}
|
|
2149
|
+
currentDir = import_node_path4.default.dirname(currentDir);
|
|
2150
|
+
}
|
|
2151
|
+
throw new Error(
|
|
2152
|
+
"Repository root not found. Specify the root of the repository with the `repository.root` option."
|
|
2153
|
+
);
|
|
2154
|
+
}
|
|
2155
|
+
|
|
2156
|
+
// src/config-v2/microfrontends/utils/find-package-path.ts
|
|
2157
|
+
var import_node_path5 = require("path");
|
|
2158
|
+
var import_node_fs4 = require("fs");
|
|
2159
|
+
var import_fast_glob = __toESM(require("fast-glob"), 1);
|
|
2160
|
+
var configCache = {};
|
|
2161
|
+
function findPackagePathWithGlob({
|
|
2162
|
+
repositoryRoot,
|
|
2163
|
+
name
|
|
2164
|
+
}) {
|
|
2165
|
+
try {
|
|
2166
|
+
const packageJsonPaths = import_fast_glob.default.globSync("**/package.json", {
|
|
2167
|
+
cwd: repositoryRoot,
|
|
2168
|
+
absolute: true,
|
|
2169
|
+
onlyFiles: true,
|
|
2170
|
+
followSymbolicLinks: false,
|
|
2171
|
+
ignore: ["**/node_modules/**", "**/.git/**"]
|
|
2172
|
+
});
|
|
2173
|
+
const matchingPaths = [];
|
|
2174
|
+
for (const packageJsonPath2 of packageJsonPaths) {
|
|
2175
|
+
const packageJsonContent = (0, import_node_fs4.readFileSync)(packageJsonPath2, "utf-8");
|
|
2176
|
+
const packageJson = JSON.parse(packageJsonContent);
|
|
2177
|
+
if (packageJson.name === name) {
|
|
2178
|
+
matchingPaths.push(packageJsonPath2);
|
|
2179
|
+
}
|
|
2180
|
+
}
|
|
2181
|
+
if (matchingPaths.length > 1) {
|
|
2182
|
+
throw new Error(
|
|
2183
|
+
`Found multiple packages with the name "${name}" in the repository: ${matchingPaths.join(", ")}`
|
|
2184
|
+
);
|
|
2185
|
+
}
|
|
2186
|
+
if (matchingPaths.length === 0) {
|
|
2187
|
+
throw new Error(
|
|
2188
|
+
`Could not find package with the name "${name}" in the repository`
|
|
2189
|
+
);
|
|
2190
|
+
}
|
|
2191
|
+
const [packageJsonPath] = matchingPaths;
|
|
2192
|
+
return (0, import_node_path5.dirname)(packageJsonPath);
|
|
2193
|
+
} catch (error) {
|
|
2194
|
+
return null;
|
|
2195
|
+
}
|
|
2196
|
+
}
|
|
2197
|
+
function findPackagePath(opts) {
|
|
2198
|
+
const cacheKey = `${opts.repositoryRoot}-${opts.name}`;
|
|
2199
|
+
if (configCache[cacheKey]) {
|
|
2200
|
+
return configCache[cacheKey];
|
|
2201
|
+
}
|
|
2202
|
+
const result = findPackagePathWithGlob(opts);
|
|
2203
|
+
if (!result) {
|
|
2204
|
+
throw new Error(
|
|
2205
|
+
`Could not find package with the name "${opts.name}" in the repository`
|
|
2206
|
+
);
|
|
2207
|
+
}
|
|
2208
|
+
configCache[cacheKey] = result;
|
|
2209
|
+
return result;
|
|
2210
|
+
}
|
|
2211
|
+
|
|
2142
2212
|
// src/config-v2/microfrontends/server/validation.ts
|
|
2143
2213
|
var import_jsonc_parser3 = require("jsonc-parser");
|
|
2144
2214
|
var import_ajv2 = require("ajv");
|
|
@@ -2354,10 +2424,6 @@ var schema_v2_default = {
|
|
|
2354
2424
|
type: "string",
|
|
2355
2425
|
description: "flag name that can be used to enable/disable all paths in the group"
|
|
2356
2426
|
},
|
|
2357
|
-
routeToDefaultApplication: {
|
|
2358
|
-
type: "boolean",
|
|
2359
|
-
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."
|
|
2360
|
-
},
|
|
2361
2427
|
paths: {
|
|
2362
2428
|
type: "array",
|
|
2363
2429
|
items: {
|
|
@@ -2434,8 +2500,8 @@ var MicrofrontendsServer = class extends Microfrontends {
|
|
|
2434
2500
|
pretty: true
|
|
2435
2501
|
}) {
|
|
2436
2502
|
const outputPath = getOutputFilePath();
|
|
2437
|
-
|
|
2438
|
-
|
|
2503
|
+
import_node_fs5.default.mkdirSync((0, import_node_path6.dirname)(outputPath), { recursive: true });
|
|
2504
|
+
import_node_fs5.default.writeFileSync(
|
|
2439
2505
|
outputPath,
|
|
2440
2506
|
JSON.stringify(
|
|
2441
2507
|
this.config.toSchemaJson(),
|
|
@@ -2503,12 +2569,32 @@ var MicrofrontendsServer = class extends Microfrontends {
|
|
|
2503
2569
|
static fromFile({
|
|
2504
2570
|
filePath,
|
|
2505
2571
|
cookies,
|
|
2506
|
-
meta
|
|
2572
|
+
meta,
|
|
2573
|
+
options
|
|
2507
2574
|
}) {
|
|
2508
2575
|
try {
|
|
2509
|
-
const
|
|
2576
|
+
const configJson = import_node_fs5.default.readFileSync(filePath, "utf-8");
|
|
2577
|
+
const config = MicrofrontendsServer.validate(configJson);
|
|
2578
|
+
if (!isMainConfig(config) && (options == null ? void 0 : options.resolveMainConfig)) {
|
|
2579
|
+
const repositoryRoot = findRepositoryRoot();
|
|
2580
|
+
const packagePath = findPackagePath({
|
|
2581
|
+
repositoryRoot,
|
|
2582
|
+
name: config.partOf
|
|
2583
|
+
});
|
|
2584
|
+
if (!packagePath) {
|
|
2585
|
+
throw new MicrofrontendError2(
|
|
2586
|
+
`Could not find default application "${config.partOf}" in the repository`,
|
|
2587
|
+
{ type: "config", subtype: "not_found" }
|
|
2588
|
+
);
|
|
2589
|
+
}
|
|
2590
|
+
const mainConfigPath = (0, import_node_path6.join)(packagePath, "microfrontends.json");
|
|
2591
|
+
return MicrofrontendsServer.fromMainConfigFile({
|
|
2592
|
+
filePath: mainConfigPath,
|
|
2593
|
+
overrides: cookies ? parseOverrides(cookies) : void 0
|
|
2594
|
+
});
|
|
2595
|
+
}
|
|
2510
2596
|
return new MicrofrontendsServer({
|
|
2511
|
-
config
|
|
2597
|
+
config,
|
|
2512
2598
|
overrides: cookies ? parseOverrides(cookies) : void 0,
|
|
2513
2599
|
meta
|
|
2514
2600
|
});
|
|
@@ -2526,7 +2612,7 @@ var MicrofrontendsServer = class extends Microfrontends {
|
|
|
2526
2612
|
overrides
|
|
2527
2613
|
}) {
|
|
2528
2614
|
try {
|
|
2529
|
-
const config =
|
|
2615
|
+
const config = import_node_fs5.default.readFileSync(filePath, "utf-8");
|
|
2530
2616
|
const validatedConfig = MicrofrontendsServer.validate(config);
|
|
2531
2617
|
if (!isMainConfig(validatedConfig)) {
|
|
2532
2618
|
throw new MicrofrontendError2(
|
|
@@ -2660,7 +2746,7 @@ var LocalProxy = class {
|
|
|
2660
2746
|
const isJWTRedirect = url.searchParams.has("_vercel_jwt");
|
|
2661
2747
|
const defaultHost = this.getDefaultHost(config);
|
|
2662
2748
|
let hostname = null;
|
|
2663
|
-
let
|
|
2749
|
+
let path4 = request2.url;
|
|
2664
2750
|
if (isAuthRedirect) {
|
|
2665
2751
|
hostname = url.searchParams.get("_host_override");
|
|
2666
2752
|
}
|
|
@@ -2670,12 +2756,12 @@ var LocalProxy = class {
|
|
|
2670
2756
|
if (isJWTRedirect) {
|
|
2671
2757
|
hostname = url.searchParams.get("_host_override");
|
|
2672
2758
|
url.searchParams.delete("_host_override");
|
|
2673
|
-
|
|
2759
|
+
path4 = `${url.pathname}${url.search}`;
|
|
2674
2760
|
}
|
|
2675
2761
|
if (!hostname) {
|
|
2676
2762
|
return void 0;
|
|
2677
2763
|
}
|
|
2678
|
-
return { ...defaultHost, path:
|
|
2764
|
+
return { ...defaultHost, path: path4, hostname, protocol: "https", port: 443 };
|
|
2679
2765
|
}
|
|
2680
2766
|
getConfigWithOverrides(cookies) {
|
|
2681
2767
|
if (isV2Config(this.config)) {
|
|
@@ -2706,19 +2792,19 @@ var LocalProxy = class {
|
|
|
2706
2792
|
getTarget(request2) {
|
|
2707
2793
|
const cookies = (0, import_cookie.parse)(request2.headers.cookie || "");
|
|
2708
2794
|
const config = this.getConfigWithOverrides(cookies);
|
|
2709
|
-
const
|
|
2710
|
-
if (!
|
|
2795
|
+
const path4 = request2.url;
|
|
2796
|
+
if (!path4) {
|
|
2711
2797
|
return this.getDefaultHost(config);
|
|
2712
2798
|
}
|
|
2713
2799
|
const authTarget = this.getAuthTarget(request2, config);
|
|
2714
2800
|
if (authTarget) {
|
|
2715
2801
|
return authTarget;
|
|
2716
2802
|
}
|
|
2717
|
-
const url = new URL(`http://example.com${
|
|
2803
|
+
const url = new URL(`http://example.com${path4}`);
|
|
2718
2804
|
const pathname = url.pathname;
|
|
2719
2805
|
if (isV2Config(config)) {
|
|
2720
2806
|
const target = this.findMatchingApplicationV2(
|
|
2721
|
-
|
|
2807
|
+
path4,
|
|
2722
2808
|
pathname,
|
|
2723
2809
|
config.getChildApplications()
|
|
2724
2810
|
);
|
|
@@ -2726,7 +2812,7 @@ var LocalProxy = class {
|
|
|
2726
2812
|
return target;
|
|
2727
2813
|
} else {
|
|
2728
2814
|
const target = this.findMatchingApplicationV1(
|
|
2729
|
-
|
|
2815
|
+
path4,
|
|
2730
2816
|
pathname,
|
|
2731
2817
|
config.getAllApplications()
|
|
2732
2818
|
);
|
|
@@ -2735,11 +2821,11 @@ var LocalProxy = class {
|
|
|
2735
2821
|
}
|
|
2736
2822
|
const defaultHost = this.getDefaultHost(config);
|
|
2737
2823
|
mfeDebug(
|
|
2738
|
-
`no matching routes, routing ${
|
|
2824
|
+
`no matching routes, routing ${path4} to default application: ${JSON.stringify(defaultHost)}`
|
|
2739
2825
|
);
|
|
2740
|
-
return { path:
|
|
2826
|
+
return { path: path4, ...defaultHost };
|
|
2741
2827
|
}
|
|
2742
|
-
findMatchingApplicationV1(
|
|
2828
|
+
findMatchingApplicationV1(path4, pathname, applications) {
|
|
2743
2829
|
for (const application of Object.values(applications)) {
|
|
2744
2830
|
if (application.routing) {
|
|
2745
2831
|
for (const group of application.routing.matches) {
|
|
@@ -2748,9 +2834,9 @@ var LocalProxy = class {
|
|
|
2748
2834
|
if (regexp.test(pathname)) {
|
|
2749
2835
|
const target = this.getApplicationTarget(application);
|
|
2750
2836
|
mfeDebug(
|
|
2751
|
-
`routing ${
|
|
2837
|
+
`routing ${path4} to '${target.application}' at ${target.hostname}`
|
|
2752
2838
|
);
|
|
2753
|
-
return { path:
|
|
2839
|
+
return { path: path4, ...target };
|
|
2754
2840
|
}
|
|
2755
2841
|
}
|
|
2756
2842
|
if (application.routing.assetPrefix) {
|
|
@@ -2760,9 +2846,9 @@ var LocalProxy = class {
|
|
|
2760
2846
|
if (pattern.test(pathname)) {
|
|
2761
2847
|
const target = this.getApplicationTarget(application);
|
|
2762
2848
|
mfeDebug(
|
|
2763
|
-
`routing ${
|
|
2849
|
+
`routing ${path4} to '${target.application}' at ${target.hostname}`
|
|
2764
2850
|
);
|
|
2765
|
-
return { path:
|
|
2851
|
+
return { path: path4, ...target };
|
|
2766
2852
|
}
|
|
2767
2853
|
}
|
|
2768
2854
|
}
|
|
@@ -2770,7 +2856,7 @@ var LocalProxy = class {
|
|
|
2770
2856
|
}
|
|
2771
2857
|
return null;
|
|
2772
2858
|
}
|
|
2773
|
-
findMatchingApplicationV2(
|
|
2859
|
+
findMatchingApplicationV2(path4, pathname, applications) {
|
|
2774
2860
|
for (const application of Object.values(applications)) {
|
|
2775
2861
|
for (const group of application.routing) {
|
|
2776
2862
|
for (const childPath of group.paths) {
|
|
@@ -2778,9 +2864,9 @@ var LocalProxy = class {
|
|
|
2778
2864
|
if (regexp.test(pathname)) {
|
|
2779
2865
|
const target = this.getApplicationTarget(application);
|
|
2780
2866
|
mfeDebug(
|
|
2781
|
-
`routing ${
|
|
2867
|
+
`routing ${path4} to '${target.application}' at ${target.hostname}`
|
|
2782
2868
|
);
|
|
2783
|
-
return { path:
|
|
2869
|
+
return { path: path4, ...target };
|
|
2784
2870
|
}
|
|
2785
2871
|
}
|
|
2786
2872
|
}
|
|
@@ -2789,11 +2875,11 @@ var LocalProxy = class {
|
|
|
2789
2875
|
}
|
|
2790
2876
|
// Handles requests that return data from the local proxy itself.
|
|
2791
2877
|
// Returns true if the request was handled, false otherwise.
|
|
2792
|
-
handleProxyInfoRequest(
|
|
2793
|
-
if (!
|
|
2878
|
+
handleProxyInfoRequest(path4, res) {
|
|
2879
|
+
if (!path4) {
|
|
2794
2880
|
return false;
|
|
2795
2881
|
}
|
|
2796
|
-
const url = new URL(`http://example.comf${
|
|
2882
|
+
const url = new URL(`http://example.comf${path4}`);
|
|
2797
2883
|
const pathname = url.pathname;
|
|
2798
2884
|
switch (pathname) {
|
|
2799
2885
|
case "/.well-known/vercel/microfrontend-routing": {
|
|
@@ -2821,10 +2907,10 @@ var LocalProxy = class {
|
|
|
2821
2907
|
}
|
|
2822
2908
|
const target = this.getTarget(req);
|
|
2823
2909
|
if (target.protocol === "https") {
|
|
2824
|
-
const { hostname, port, path:
|
|
2910
|
+
const { hostname, port, path: path4 } = target;
|
|
2825
2911
|
const requestOptions = {
|
|
2826
2912
|
hostname,
|
|
2827
|
-
path:
|
|
2913
|
+
path: path4,
|
|
2828
2914
|
method: req.method,
|
|
2829
2915
|
headers: {
|
|
2830
2916
|
...req.headers,
|
|
@@ -2852,7 +2938,7 @@ var LocalProxy = class {
|
|
|
2852
2938
|
console.error("Proxy request error: ", err);
|
|
2853
2939
|
res.writeHead(500, { "Content-Type": "text/plain" });
|
|
2854
2940
|
res.end(
|
|
2855
|
-
`Error proxying request for ${target.application} to ${hostname}:${port}${
|
|
2941
|
+
`Error proxying request for ${target.application} to ${hostname}:${port}${path4}`
|
|
2856
2942
|
);
|
|
2857
2943
|
});
|
|
2858
2944
|
} else {
|
package/dist/config/client.d.ts
CHANGED
package/dist/config/edge.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { C as MicrofrontendSchema } from '../schema-
|
|
2
|
-
import { a as MicrofrontendConfigCommon } from '../microfrontend-config-
|
|
1
|
+
export { C as MicrofrontendSchema } from '../schema-2922d49e.js';
|
|
2
|
+
import { a as MicrofrontendConfigCommon } from '../microfrontend-config-983a5139.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Edge Runtime does not support ajv validation, or fs access.
|
package/dist/config.cjs
CHANGED
|
@@ -765,10 +765,6 @@ var schema_default = {
|
|
|
765
765
|
flag: {
|
|
766
766
|
type: "string",
|
|
767
767
|
description: "flag name that can be used to enable/disable all paths in the group"
|
|
768
|
-
},
|
|
769
|
-
routeToDefaultApplication: {
|
|
770
|
-
type: "boolean",
|
|
771
|
-
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."
|
|
772
768
|
}
|
|
773
769
|
}
|
|
774
770
|
},
|
|
@@ -1129,11 +1125,10 @@ var validateOptions = (options) => {
|
|
|
1129
1125
|
// src/config/utils/convert.ts
|
|
1130
1126
|
function convertV1RoutingToV2Routing(routing) {
|
|
1131
1127
|
return routing.matches.map((group) => {
|
|
1132
|
-
var _a
|
|
1128
|
+
var _a;
|
|
1133
1129
|
return {
|
|
1134
1130
|
group: group.group,
|
|
1135
1131
|
flag: (_a = group.options) == null ? void 0 : _a.flag,
|
|
1136
|
-
routeToDefaultApplication: (_b = group.options) == null ? void 0 : _b.routeToDefaultApplication,
|
|
1137
1132
|
paths: group.paths
|
|
1138
1133
|
};
|
|
1139
1134
|
});
|