@vercel/microfrontends 0.10.1 → 0.12.0
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/dist/bin/cli.cjs +263 -102
- package/dist/config.cjs +0 -2
- package/dist/config.cjs.map +1 -1
- package/dist/config.js +0 -2
- package/dist/config.js.map +1 -1
- package/dist/{index-acb44057.d.ts → index-35038aec.d.ts} +2 -2
- package/dist/next/config.cjs +10 -3
- package/dist/next/config.cjs.map +1 -1
- package/dist/next/config.js +10 -3
- package/dist/next/config.js.map +1 -1
- package/dist/next/middleware.cjs +17 -1
- package/dist/next/middleware.cjs.map +1 -1
- package/dist/next/middleware.js +17 -1
- package/dist/next/middleware.js.map +1 -1
- package/dist/next/testing.cjs +0 -2
- package/dist/next/testing.cjs.map +1 -1
- package/dist/next/testing.js +0 -2
- package/dist/next/testing.js.map +1 -1
- package/dist/{types-c3d15d04.d.ts → types-15b7f215.d.ts} +1 -1
- package/dist/{types-7b1cd9f7.d.ts → types-a995174e.d.ts} +1 -4
- package/dist/v2/config.cjs +1 -1
- package/dist/v2/config.cjs.map +1 -1
- package/dist/v2/config.d.ts +3 -3
- package/dist/v2/config.js +1 -1
- package/dist/v2/config.js.map +1 -1
- package/dist/v2/microfrontends/server.cjs +215 -53
- package/dist/v2/microfrontends/server.cjs.map +1 -1
- package/dist/v2/microfrontends/server.d.ts +22 -3
- package/dist/v2/microfrontends/server.js +215 -53
- package/dist/v2/microfrontends/server.js.map +1 -1
- package/dist/v2/microfrontends.cjs +1 -2
- package/dist/v2/microfrontends.cjs.map +1 -1
- package/dist/v2/microfrontends.d.ts +3 -4
- package/dist/v2/microfrontends.js +1 -2
- package/dist/v2/microfrontends.js.map +1 -1
- package/dist/v2/next/config.cjs +249 -82
- package/dist/v2/next/config.cjs.map +1 -1
- package/dist/v2/next/config.js +249 -82
- package/dist/v2/next/config.js.map +1 -1
- package/dist/v2/next/endpoints.cjs +5 -2
- package/dist/v2/next/endpoints.cjs.map +1 -1
- package/dist/v2/next/endpoints.d.ts +1 -1
- package/dist/v2/next/endpoints.js +5 -2
- package/dist/v2/next/endpoints.js.map +1 -1
- package/dist/v2/next/middleware.cjs +107 -88
- package/dist/v2/next/middleware.cjs.map +1 -1
- package/dist/v2/next/middleware.js +107 -88
- package/dist/v2/next/middleware.js.map +1 -1
- package/dist/v2/overrides.cjs +1 -1
- package/dist/v2/overrides.cjs.map +1 -1
- package/dist/v2/overrides.d.ts +3 -3
- package/dist/v2/overrides.js +1 -1
- package/dist/v2/overrides.js.map +1 -1
- package/dist/v2/schema.d.ts +1 -1
- package/dist/validation.cjs +1 -11
- package/dist/validation.cjs.map +1 -1
- package/dist/validation.d.ts +0 -3
- package/dist/validation.js +1 -11
- package/dist/validation.js.map +1 -1
- package/package.json +8 -7
- package/schema/schema-v2.json +0 -14
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.
|
|
32
|
+
version: "0.12.0",
|
|
33
33
|
private: false,
|
|
34
34
|
description: "Defines configuration and utilities for micro-frontend development",
|
|
35
35
|
repository: {
|
|
@@ -43,6 +43,7 @@ var package_default = {
|
|
|
43
43
|
"micro-frontends": "./cli/index.cjs"
|
|
44
44
|
},
|
|
45
45
|
exports: {
|
|
46
|
+
"./schema.json": "./schema/schema-v2.json",
|
|
46
47
|
"./validation": {
|
|
47
48
|
import: "./dist/validation.js",
|
|
48
49
|
require: "./dist/validation.cjs"
|
|
@@ -181,9 +182,9 @@ var package_default = {
|
|
|
181
182
|
"@vercel-private/conformance": "^1.12.2-canary.0",
|
|
182
183
|
jest: "^29.7.0",
|
|
183
184
|
"jest-environment-jsdom": "29.2.2",
|
|
184
|
-
next: "15.
|
|
185
|
-
react: "19.0.0
|
|
186
|
-
"react-dom": "19.0.0
|
|
185
|
+
next: "15.1.1-canary.0",
|
|
186
|
+
react: "19.0.0",
|
|
187
|
+
"react-dom": "19.0.0",
|
|
187
188
|
"ts-json-schema-generator": "^1.1.2",
|
|
188
189
|
tsup: "^6.6.2",
|
|
189
190
|
tsx: "^4.6.2",
|
|
@@ -191,9 +192,9 @@ var package_default = {
|
|
|
191
192
|
webpack: "5"
|
|
192
193
|
},
|
|
193
194
|
peerDependencies: {
|
|
194
|
-
next: "15.
|
|
195
|
-
react: "19.0.0
|
|
196
|
-
"react-dom": "19.0.0
|
|
195
|
+
next: "15.1.1-canary.0",
|
|
196
|
+
react: "19.0.0",
|
|
197
|
+
"react-dom": "19.0.0"
|
|
197
198
|
},
|
|
198
199
|
publishConfig: {
|
|
199
200
|
access: "restricted"
|
|
@@ -1090,8 +1091,8 @@ function validateMainPath(applicationConfigsById) {
|
|
|
1090
1091
|
});
|
|
1091
1092
|
}
|
|
1092
1093
|
for (const { id: otherId, paths } of pathsWithApp) {
|
|
1093
|
-
const isValid = paths.every((
|
|
1094
|
-
const matcher = (0, import_path_to_regexp.pathToRegexp)(
|
|
1094
|
+
const isValid = paths.every((path6) => {
|
|
1095
|
+
const matcher = (0, import_path_to_regexp.pathToRegexp)(path6);
|
|
1095
1096
|
return !matcher.test(defaultRoute);
|
|
1096
1097
|
});
|
|
1097
1098
|
if (!isValid) {
|
|
@@ -1103,8 +1104,8 @@ function validateMainPath(applicationConfigsById) {
|
|
|
1103
1104
|
}
|
|
1104
1105
|
} else {
|
|
1105
1106
|
const allPaths = app.routing.matches.flatMap((match) => match.paths);
|
|
1106
|
-
const isValid = allPaths.some((
|
|
1107
|
-
const matcher = (0, import_path_to_regexp.pathToRegexp)(
|
|
1107
|
+
const isValid = allPaths.some((path6) => {
|
|
1108
|
+
const matcher = (0, import_path_to_regexp.pathToRegexp)(path6);
|
|
1108
1109
|
return matcher.test(defaultRoute);
|
|
1109
1110
|
});
|
|
1110
1111
|
if (!isValid) {
|
|
@@ -1124,18 +1125,18 @@ var validatePaths = (applicationConfigsById) => {
|
|
|
1124
1125
|
continue;
|
|
1125
1126
|
}
|
|
1126
1127
|
for (const pathMatch of app.routing.matches) {
|
|
1127
|
-
for (const
|
|
1128
|
-
const maybeError = validatePathExpression(
|
|
1128
|
+
for (const path6 of pathMatch.paths) {
|
|
1129
|
+
const maybeError = validatePathExpression(path6);
|
|
1129
1130
|
if (maybeError) {
|
|
1130
1131
|
errors.push(maybeError);
|
|
1131
1132
|
}
|
|
1132
|
-
const existing = pathsByApplicationId.get(
|
|
1133
|
+
const existing = pathsByApplicationId.get(path6);
|
|
1133
1134
|
if (existing) {
|
|
1134
1135
|
existing.applications.push(id);
|
|
1135
1136
|
} else {
|
|
1136
|
-
pathsByApplicationId.set(
|
|
1137
|
+
pathsByApplicationId.set(path6, {
|
|
1137
1138
|
applications: [id],
|
|
1138
|
-
matcher: (0, import_path_to_regexp.pathToRegexp)(
|
|
1139
|
+
matcher: (0, import_path_to_regexp.pathToRegexp)(path6),
|
|
1139
1140
|
applicationId: id
|
|
1140
1141
|
});
|
|
1141
1142
|
}
|
|
@@ -1143,10 +1144,10 @@ var validatePaths = (applicationConfigsById) => {
|
|
|
1143
1144
|
}
|
|
1144
1145
|
}
|
|
1145
1146
|
const entries = Array.from(pathsByApplicationId.entries());
|
|
1146
|
-
entries.forEach(([
|
|
1147
|
+
entries.forEach(([path6, { applications: ids, matcher, applicationId }]) => {
|
|
1147
1148
|
if (ids.length > 1) {
|
|
1148
1149
|
errors.push(
|
|
1149
|
-
`Duplicate path "${
|
|
1150
|
+
`Duplicate path "${path6}" for applications "${ids.join(", ")}"`
|
|
1150
1151
|
);
|
|
1151
1152
|
}
|
|
1152
1153
|
entries.forEach(
|
|
@@ -1154,14 +1155,14 @@ var validatePaths = (applicationConfigsById) => {
|
|
|
1154
1155
|
matchPath,
|
|
1155
1156
|
{ applications: matchIds, applicationId: matchApplicationId }
|
|
1156
1157
|
]) => {
|
|
1157
|
-
if (
|
|
1158
|
+
if (path6 === matchPath) {
|
|
1158
1159
|
return;
|
|
1159
1160
|
}
|
|
1160
1161
|
if (applicationId === matchApplicationId) {
|
|
1161
1162
|
return;
|
|
1162
1163
|
}
|
|
1163
1164
|
if (matcher.test(matchPath)) {
|
|
1164
|
-
const source = `"${
|
|
1165
|
+
const source = `"${path6}" of application${ids.length > 0 ? "s" : ""} ${ids.join(", ")}`;
|
|
1165
1166
|
const destination = `"${matchPath}" of application${matchIds.length > 0 ? "s" : ""} ${matchIds.join(", ")}`;
|
|
1166
1167
|
errors.push(
|
|
1167
1168
|
`Overlapping path detected between ${source} and ${destination}`
|
|
@@ -1178,25 +1179,25 @@ var validatePaths = (applicationConfigsById) => {
|
|
|
1178
1179
|
}
|
|
1179
1180
|
};
|
|
1180
1181
|
var PATH_DEFAULT_PATTERN = "[^\\/#\\?]+?";
|
|
1181
|
-
function validatePathExpression(
|
|
1182
|
-
const tokens = (0, import_path_to_regexp.parse)(
|
|
1182
|
+
function validatePathExpression(path6) {
|
|
1183
|
+
const tokens = (0, import_path_to_regexp.parse)(path6);
|
|
1183
1184
|
for (let i = 0; i < tokens.length; i++) {
|
|
1184
1185
|
const token = tokens[i];
|
|
1185
1186
|
if (token === void 0) {
|
|
1186
|
-
return `token ${i} in ${
|
|
1187
|
+
return `token ${i} in ${path6} is undefined, this shouldn't happen`;
|
|
1187
1188
|
}
|
|
1188
1189
|
if (typeof token !== "string") {
|
|
1189
1190
|
if (token.pattern !== PATH_DEFAULT_PATTERN) {
|
|
1190
|
-
return `Path ${
|
|
1191
|
+
return `Path ${path6} cannot use a regular expression wildcard`;
|
|
1191
1192
|
}
|
|
1192
1193
|
if (token.prefix !== "/") {
|
|
1193
|
-
return `Wildcard :${token.name} must be immediately after a / in ${
|
|
1194
|
+
return `Wildcard :${token.name} must be immediately after a / in ${path6}`;
|
|
1194
1195
|
}
|
|
1195
1196
|
if (token.suffix) {
|
|
1196
1197
|
return `Wildcard suffix on :${token.name} is not allowed. Suffixes are not supported`;
|
|
1197
1198
|
}
|
|
1198
1199
|
if (token.modifier && i !== tokens.length - 1) {
|
|
1199
|
-
return `Modifier ${token.modifier} is not allowed on wildcard :${token.name} in ${
|
|
1200
|
+
return `Modifier ${token.modifier} is not allowed on wildcard :${token.name} in ${path6}. Modifiers are only allowed in the last path component`;
|
|
1200
1201
|
}
|
|
1201
1202
|
}
|
|
1202
1203
|
}
|
|
@@ -1267,8 +1268,6 @@ function convertV1ConfigToV2Config(config, fromApp) {
|
|
|
1267
1268
|
if (config.applications[fromApp].default) {
|
|
1268
1269
|
return {
|
|
1269
1270
|
...common,
|
|
1270
|
-
// this is assumed for now, and by the time this is released we won't need this conversion
|
|
1271
|
-
provider: "vercel",
|
|
1272
1271
|
applications: Object.fromEntries(
|
|
1273
1272
|
Object.entries(config.applications).map(([id, application]) => [
|
|
1274
1273
|
id,
|
|
@@ -1474,22 +1473,22 @@ var validateConfigPaths = (applicationConfigsById) => {
|
|
|
1474
1473
|
continue;
|
|
1475
1474
|
}
|
|
1476
1475
|
for (const pathMatch of app.routing) {
|
|
1477
|
-
for (const
|
|
1478
|
-
const tokens = (0, import_path_to_regexp2.parse)(
|
|
1476
|
+
for (const path6 of pathMatch.paths) {
|
|
1477
|
+
const tokens = (0, import_path_to_regexp2.parse)(path6);
|
|
1479
1478
|
for (const token of tokens.slice(0, -1)) {
|
|
1480
1479
|
if (typeof token !== "string") {
|
|
1481
1480
|
errors.push(
|
|
1482
|
-
`Path ${
|
|
1481
|
+
`Path ${path6} may only have a :wildcard in the last path component`
|
|
1483
1482
|
);
|
|
1484
1483
|
}
|
|
1485
1484
|
}
|
|
1486
|
-
const existing = pathsByApplicationId.get(
|
|
1485
|
+
const existing = pathsByApplicationId.get(path6);
|
|
1487
1486
|
if (existing) {
|
|
1488
1487
|
existing.applications.push(id);
|
|
1489
1488
|
} else {
|
|
1490
|
-
pathsByApplicationId.set(
|
|
1489
|
+
pathsByApplicationId.set(path6, {
|
|
1491
1490
|
applications: [id],
|
|
1492
|
-
matcher: (0, import_path_to_regexp2.pathToRegexp)(
|
|
1491
|
+
matcher: (0, import_path_to_regexp2.pathToRegexp)(path6),
|
|
1493
1492
|
applicationId: id
|
|
1494
1493
|
});
|
|
1495
1494
|
}
|
|
@@ -1497,10 +1496,10 @@ var validateConfigPaths = (applicationConfigsById) => {
|
|
|
1497
1496
|
}
|
|
1498
1497
|
}
|
|
1499
1498
|
const entries = Array.from(pathsByApplicationId.entries());
|
|
1500
|
-
entries.forEach(([
|
|
1499
|
+
entries.forEach(([path6, { applications: ids, matcher, applicationId }]) => {
|
|
1501
1500
|
if (ids.length > 1) {
|
|
1502
1501
|
errors.push(
|
|
1503
|
-
`Duplicate path "${
|
|
1502
|
+
`Duplicate path "${path6}" for applications "${ids.join(", ")}"`
|
|
1504
1503
|
);
|
|
1505
1504
|
}
|
|
1506
1505
|
entries.forEach(
|
|
@@ -1508,14 +1507,14 @@ var validateConfigPaths = (applicationConfigsById) => {
|
|
|
1508
1507
|
matchPath,
|
|
1509
1508
|
{ applications: matchIds, applicationId: matchApplicationId }
|
|
1510
1509
|
]) => {
|
|
1511
|
-
if (
|
|
1510
|
+
if (path6 === matchPath) {
|
|
1512
1511
|
return;
|
|
1513
1512
|
}
|
|
1514
1513
|
if (applicationId === matchApplicationId) {
|
|
1515
1514
|
return;
|
|
1516
1515
|
}
|
|
1517
1516
|
if (matcher.test(matchPath)) {
|
|
1518
|
-
const source = `"${
|
|
1517
|
+
const source = `"${path6}" of application${ids.length > 0 ? "s" : ""} ${ids.join(", ")}`;
|
|
1519
1518
|
const destination = `"${matchPath}" of application${matchIds.length > 0 ? "s" : ""} ${matchIds.join(", ")}`;
|
|
1520
1519
|
errors.push(
|
|
1521
1520
|
`Overlapping path detected between ${source} and ${destination}`
|
|
@@ -1790,21 +1789,21 @@ var MicrofrontendConfigClient = class {
|
|
|
1790
1789
|
isEqual(other) {
|
|
1791
1790
|
return JSON.stringify(this.applications) === JSON.stringify(other.applications);
|
|
1792
1791
|
}
|
|
1793
|
-
getApplicationNameForPath(
|
|
1794
|
-
if (!
|
|
1792
|
+
getApplicationNameForPath(path6) {
|
|
1793
|
+
if (!path6.startsWith("/")) {
|
|
1795
1794
|
throw new Error(`Path must start with a /`);
|
|
1796
1795
|
}
|
|
1797
|
-
if (this.pathCache[
|
|
1798
|
-
return this.pathCache[
|
|
1796
|
+
if (this.pathCache[path6]) {
|
|
1797
|
+
return this.pathCache[path6];
|
|
1799
1798
|
}
|
|
1800
|
-
const pathname = new URL(
|
|
1799
|
+
const pathname = new URL(path6, "https://example.com").pathname;
|
|
1801
1800
|
for (const [name, application] of Object.entries(this.applications)) {
|
|
1802
1801
|
if (application.routing) {
|
|
1803
1802
|
for (const group of application.routing) {
|
|
1804
1803
|
for (const childPath of group.paths) {
|
|
1805
1804
|
const regexp = (0, import_path_to_regexp3.pathToRegexp)(childPath);
|
|
1806
1805
|
if (regexp.test(pathname)) {
|
|
1807
|
-
this.pathCache[
|
|
1806
|
+
this.pathCache[path6] = name;
|
|
1808
1807
|
return name;
|
|
1809
1808
|
}
|
|
1810
1809
|
}
|
|
@@ -1817,7 +1816,7 @@ var MicrofrontendConfigClient = class {
|
|
|
1817
1816
|
if (!defaultApplication) {
|
|
1818
1817
|
return null;
|
|
1819
1818
|
}
|
|
1820
|
-
this.pathCache[
|
|
1819
|
+
this.pathCache[path6] = defaultApplication[0];
|
|
1821
1820
|
return defaultApplication[0];
|
|
1822
1821
|
}
|
|
1823
1822
|
serialize() {
|
|
@@ -1826,7 +1825,7 @@ var MicrofrontendConfigClient = class {
|
|
|
1826
1825
|
};
|
|
1827
1826
|
|
|
1828
1827
|
// src/config-v2/overrides/constants.ts
|
|
1829
|
-
var OVERRIDES_COOKIE_PREFIX2 = "vercel-
|
|
1828
|
+
var OVERRIDES_COOKIE_PREFIX2 = "vercel-micro-frontends-override";
|
|
1830
1829
|
var OVERRIDES_ENV_COOKIE_PREFIX = `${OVERRIDES_COOKIE_PREFIX2}:env:`;
|
|
1831
1830
|
|
|
1832
1831
|
// src/config-v2/overrides/is-override-cookie.ts
|
|
@@ -2055,7 +2054,6 @@ var MicrofrontendMainConfig = class extends MicrofrontendConfigIsomorphic {
|
|
|
2055
2054
|
var _a, _b, _c;
|
|
2056
2055
|
super({ config, overrides, meta });
|
|
2057
2056
|
this.isMainConfig = true;
|
|
2058
|
-
this.provider = config.provider;
|
|
2059
2057
|
const disableOverrides = ((_b = (_a = config.options) == null ? void 0 : _a.vercel) == null ? void 0 : _b.disableOverrides) ?? false;
|
|
2060
2058
|
let defaultApplication;
|
|
2061
2059
|
for (const [appId, appConfig] of Object.entries(config.applications)) {
|
|
@@ -2091,8 +2089,8 @@ function isMainConfig2(c) {
|
|
|
2091
2089
|
}
|
|
2092
2090
|
|
|
2093
2091
|
// src/config-v2/microfrontends/server/index.ts
|
|
2094
|
-
var
|
|
2095
|
-
var
|
|
2092
|
+
var import_node_fs8 = __toESM(require("fs"), 1);
|
|
2093
|
+
var import_node_path9 = require("path");
|
|
2096
2094
|
|
|
2097
2095
|
// src/config-v2/microfrontends-config/isomorphic/child.ts
|
|
2098
2096
|
var MicrofrontendChildConfig = class extends MicrofrontendConfigIsomorphic {
|
|
@@ -2209,6 +2207,113 @@ function findPackagePath(opts) {
|
|
|
2209
2207
|
return result;
|
|
2210
2208
|
}
|
|
2211
2209
|
|
|
2210
|
+
// src/config-v2/microfrontends/utils/find-default-package.ts
|
|
2211
|
+
var import_node_path6 = require("path");
|
|
2212
|
+
var import_node_fs5 = require("fs");
|
|
2213
|
+
var import_fast_glob2 = __toESM(require("fast-glob"), 1);
|
|
2214
|
+
var configCache2 = {};
|
|
2215
|
+
function findDefaultMicrofrontendsPackages({
|
|
2216
|
+
repositoryRoot,
|
|
2217
|
+
applicationName
|
|
2218
|
+
}) {
|
|
2219
|
+
try {
|
|
2220
|
+
const microfrontendsJsonPaths = import_fast_glob2.default.globSync("**/microfrontends.json", {
|
|
2221
|
+
cwd: repositoryRoot,
|
|
2222
|
+
absolute: true,
|
|
2223
|
+
onlyFiles: true,
|
|
2224
|
+
followSymbolicLinks: false,
|
|
2225
|
+
ignore: ["**/node_modules/**", "**/.git/**"]
|
|
2226
|
+
});
|
|
2227
|
+
const matchingPaths = [];
|
|
2228
|
+
for (const microfrontendsJsonPath of microfrontendsJsonPaths) {
|
|
2229
|
+
const microfrontendsJsonContent = (0, import_node_fs5.readFileSync)(
|
|
2230
|
+
microfrontendsJsonPath,
|
|
2231
|
+
"utf-8"
|
|
2232
|
+
);
|
|
2233
|
+
const microfrontendsJson = JSON.parse(
|
|
2234
|
+
microfrontendsJsonContent
|
|
2235
|
+
);
|
|
2236
|
+
if (isMainConfig(microfrontendsJson) && microfrontendsJson.applications[applicationName]) {
|
|
2237
|
+
matchingPaths.push(microfrontendsJsonPath);
|
|
2238
|
+
}
|
|
2239
|
+
}
|
|
2240
|
+
if (matchingPaths.length > 1) {
|
|
2241
|
+
throw new Error(
|
|
2242
|
+
`Found multiple default applications referencing "${applicationName}" in the repository, this is not yet supported.
|
|
2243
|
+
${matchingPaths.join("\n \u2022 ")}`
|
|
2244
|
+
);
|
|
2245
|
+
}
|
|
2246
|
+
if (matchingPaths.length === 0) {
|
|
2247
|
+
throw new Error(
|
|
2248
|
+
`Could not find default application with "applications.${applicationName}"`
|
|
2249
|
+
);
|
|
2250
|
+
}
|
|
2251
|
+
const [packageJsonPath] = matchingPaths;
|
|
2252
|
+
return (0, import_node_path6.dirname)(packageJsonPath);
|
|
2253
|
+
} catch (error) {
|
|
2254
|
+
return null;
|
|
2255
|
+
}
|
|
2256
|
+
}
|
|
2257
|
+
function findDefaultMicrofrontendsPackage(opts) {
|
|
2258
|
+
const cacheKey = `${opts.repositoryRoot}-${opts.applicationName}`;
|
|
2259
|
+
if (configCache2[cacheKey]) {
|
|
2260
|
+
return configCache2[cacheKey];
|
|
2261
|
+
}
|
|
2262
|
+
const result = findDefaultMicrofrontendsPackages(opts);
|
|
2263
|
+
if (!result) {
|
|
2264
|
+
throw new Error(
|
|
2265
|
+
`Error trying to resolve the main microfrontends.json configuration`
|
|
2266
|
+
);
|
|
2267
|
+
}
|
|
2268
|
+
configCache2[cacheKey] = result;
|
|
2269
|
+
return result;
|
|
2270
|
+
}
|
|
2271
|
+
|
|
2272
|
+
// src/config-v2/microfrontends/utils/is-monorepo.ts
|
|
2273
|
+
var import_node_fs6 = __toESM(require("fs"), 1);
|
|
2274
|
+
var import_node_path7 = __toESM(require("path"), 1);
|
|
2275
|
+
function isMonorepo({
|
|
2276
|
+
repositoryRoot
|
|
2277
|
+
}) {
|
|
2278
|
+
try {
|
|
2279
|
+
if (import_node_fs6.default.existsSync(import_node_path7.default.join(repositoryRoot, "pnpm-workspace.yaml"))) {
|
|
2280
|
+
return true;
|
|
2281
|
+
}
|
|
2282
|
+
if (import_node_fs6.default.existsSync(import_node_path7.default.join(repositoryRoot, "vlt-workspaces.json"))) {
|
|
2283
|
+
return true;
|
|
2284
|
+
}
|
|
2285
|
+
const packageJsonPath = import_node_path7.default.join(repositoryRoot, "package.json");
|
|
2286
|
+
if (!import_node_fs6.default.existsSync(packageJsonPath)) {
|
|
2287
|
+
return false;
|
|
2288
|
+
}
|
|
2289
|
+
const packageJson = JSON.parse(
|
|
2290
|
+
import_node_fs6.default.readFileSync(packageJsonPath, "utf-8")
|
|
2291
|
+
);
|
|
2292
|
+
return packageJson.workspaces !== void 0;
|
|
2293
|
+
} catch (error) {
|
|
2294
|
+
console.error("Error determining if repository is a monorepo", error);
|
|
2295
|
+
return false;
|
|
2296
|
+
}
|
|
2297
|
+
}
|
|
2298
|
+
|
|
2299
|
+
// src/config-v2/microfrontends/utils/find-package-root.ts
|
|
2300
|
+
var import_node_fs7 = __toESM(require("fs"), 1);
|
|
2301
|
+
var import_node_path8 = __toESM(require("path"), 1);
|
|
2302
|
+
var PACKAGE_JSON = "package.json";
|
|
2303
|
+
function findPackageRoot(startDir) {
|
|
2304
|
+
let currentDir = startDir || process.cwd();
|
|
2305
|
+
while (currentDir !== import_node_path8.default.parse(currentDir).root) {
|
|
2306
|
+
const pkgJsonPath = import_node_path8.default.join(currentDir, PACKAGE_JSON);
|
|
2307
|
+
if (import_node_fs7.default.existsSync(pkgJsonPath)) {
|
|
2308
|
+
return currentDir;
|
|
2309
|
+
}
|
|
2310
|
+
currentDir = import_node_path8.default.dirname(currentDir);
|
|
2311
|
+
}
|
|
2312
|
+
throw new Error(
|
|
2313
|
+
"Package root not found. Specify the root of the package with the `package.root` option."
|
|
2314
|
+
);
|
|
2315
|
+
}
|
|
2316
|
+
|
|
2212
2317
|
// src/config-v2/microfrontends/server/validation.ts
|
|
2213
2318
|
var import_jsonc_parser3 = require("jsonc-parser");
|
|
2214
2319
|
var import_ajv2 = require("ajv");
|
|
@@ -2248,15 +2353,12 @@ var schema_v2_default = {
|
|
|
2248
2353
|
},
|
|
2249
2354
|
description: "Applications that only serve a subset of the microfrontend routes only need to reference the name of the primary application that owns the full microfrontends configuration."
|
|
2250
2355
|
},
|
|
2251
|
-
provider: {
|
|
2252
|
-
$ref: "#/definitions/Provider"
|
|
2253
|
-
},
|
|
2254
2356
|
applications: {
|
|
2255
2357
|
$ref: "#/definitions/ApplicationRouting",
|
|
2256
2358
|
description: "Mapping of application names to the routes that they host. Only needs to be defined in the application that owns the primary microfrontend domain"
|
|
2257
2359
|
}
|
|
2258
2360
|
},
|
|
2259
|
-
required: ["applications", "
|
|
2361
|
+
required: ["applications", "version"]
|
|
2260
2362
|
},
|
|
2261
2363
|
Options: {
|
|
2262
2364
|
type: "object",
|
|
@@ -2328,9 +2430,6 @@ var schema_v2_default = {
|
|
|
2328
2430
|
projectId: {
|
|
2329
2431
|
type: "string",
|
|
2330
2432
|
description: "Vercel project ID"
|
|
2331
|
-
},
|
|
2332
|
-
routeSpeedInsightsToDefaultZone: {
|
|
2333
|
-
type: "boolean"
|
|
2334
2433
|
}
|
|
2335
2434
|
},
|
|
2336
2435
|
required: ["projectId"]
|
|
@@ -2433,10 +2532,6 @@ var schema_v2_default = {
|
|
|
2433
2532
|
},
|
|
2434
2533
|
required: ["paths"]
|
|
2435
2534
|
},
|
|
2436
|
-
Provider: {
|
|
2437
|
-
type: "string",
|
|
2438
|
-
enum: ["vercel", "other"]
|
|
2439
|
-
},
|
|
2440
2535
|
ApplicationRouting: {
|
|
2441
2536
|
type: "object",
|
|
2442
2537
|
additionalProperties: {
|
|
@@ -2500,8 +2595,8 @@ var MicrofrontendsServer = class extends Microfrontends {
|
|
|
2500
2595
|
pretty: true
|
|
2501
2596
|
}) {
|
|
2502
2597
|
const outputPath = getOutputFilePath();
|
|
2503
|
-
|
|
2504
|
-
|
|
2598
|
+
import_node_fs8.default.mkdirSync((0, import_node_path9.dirname)(outputPath), { recursive: true });
|
|
2599
|
+
import_node_fs8.default.writeFileSync(
|
|
2505
2600
|
outputPath,
|
|
2506
2601
|
JSON.stringify(
|
|
2507
2602
|
this.config.toSchemaJson(),
|
|
@@ -2563,6 +2658,69 @@ var MicrofrontendsServer = class extends Microfrontends {
|
|
|
2563
2658
|
}
|
|
2564
2659
|
return config;
|
|
2565
2660
|
}
|
|
2661
|
+
/**
|
|
2662
|
+
* Looks up the configuration by inferring the package root and looking for a microfrontends.json file. If a file is not found,
|
|
2663
|
+
* it will look for a package in the repository with a microfrontends.json file that contains the current application
|
|
2664
|
+
* and use that configuration.
|
|
2665
|
+
*
|
|
2666
|
+
* This can return either a Child or Main configuration.
|
|
2667
|
+
*/
|
|
2668
|
+
static infer({
|
|
2669
|
+
directory,
|
|
2670
|
+
filePath,
|
|
2671
|
+
meta,
|
|
2672
|
+
cookies,
|
|
2673
|
+
options
|
|
2674
|
+
} = {}) {
|
|
2675
|
+
if (filePath && meta) {
|
|
2676
|
+
return MicrofrontendsServer.fromFile({
|
|
2677
|
+
filePath,
|
|
2678
|
+
cookies,
|
|
2679
|
+
meta,
|
|
2680
|
+
options
|
|
2681
|
+
});
|
|
2682
|
+
}
|
|
2683
|
+
try {
|
|
2684
|
+
const packageRoot = findPackageRoot(directory);
|
|
2685
|
+
const packageJsonPath = (0, import_node_path9.join)(packageRoot, "package.json");
|
|
2686
|
+
const packageJson = JSON.parse(
|
|
2687
|
+
import_node_fs8.default.readFileSync(packageJsonPath, "utf-8")
|
|
2688
|
+
);
|
|
2689
|
+
if (!packageJson.name) {
|
|
2690
|
+
throw new Error(`No name found in package.json at ${packageJsonPath}`);
|
|
2691
|
+
}
|
|
2692
|
+
const configMeta = meta ?? { fromApp: packageJson.name };
|
|
2693
|
+
const maybeConfig = (0, import_node_path9.join)(packageRoot, "microfrontends.json");
|
|
2694
|
+
if (import_node_fs8.default.existsSync(maybeConfig)) {
|
|
2695
|
+
return MicrofrontendsServer.fromFile({
|
|
2696
|
+
filePath: maybeConfig,
|
|
2697
|
+
cookies,
|
|
2698
|
+
meta: configMeta,
|
|
2699
|
+
options
|
|
2700
|
+
});
|
|
2701
|
+
}
|
|
2702
|
+
const repositoryRoot = findRepositoryRoot();
|
|
2703
|
+
const isMonorepo2 = isMonorepo({ repositoryRoot });
|
|
2704
|
+
if (isMonorepo2) {
|
|
2705
|
+
const defaultPackage = findDefaultMicrofrontendsPackage({
|
|
2706
|
+
repositoryRoot,
|
|
2707
|
+
applicationName: packageJson.name
|
|
2708
|
+
});
|
|
2709
|
+
return MicrofrontendsServer.fromFile({
|
|
2710
|
+
filePath: (0, import_node_path9.join)(defaultPackage, "microfrontends.json"),
|
|
2711
|
+
cookies,
|
|
2712
|
+
meta: configMeta,
|
|
2713
|
+
options
|
|
2714
|
+
});
|
|
2715
|
+
}
|
|
2716
|
+
throw new Error("Unable to infer");
|
|
2717
|
+
} catch (e) {
|
|
2718
|
+
throw new MicrofrontendError2(
|
|
2719
|
+
"Unable to infer microfrontends configuration",
|
|
2720
|
+
{ type: "config", subtype: "inference_failed" }
|
|
2721
|
+
);
|
|
2722
|
+
}
|
|
2723
|
+
}
|
|
2566
2724
|
/*
|
|
2567
2725
|
* Generates a MicrofrontendsServer instance from a file.
|
|
2568
2726
|
*/
|
|
@@ -2573,25 +2731,28 @@ var MicrofrontendsServer = class extends Microfrontends {
|
|
|
2573
2731
|
options
|
|
2574
2732
|
}) {
|
|
2575
2733
|
try {
|
|
2576
|
-
const configJson =
|
|
2734
|
+
const configJson = import_node_fs8.default.readFileSync(filePath, "utf-8");
|
|
2577
2735
|
const config = MicrofrontendsServer.validate(configJson);
|
|
2578
2736
|
if (!isMainConfig(config) && (options == null ? void 0 : options.resolveMainConfig)) {
|
|
2579
2737
|
const repositoryRoot = findRepositoryRoot();
|
|
2580
|
-
const
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2738
|
+
const isMonorepo2 = isMonorepo({ repositoryRoot });
|
|
2739
|
+
if (isMonorepo2) {
|
|
2740
|
+
const packagePath = findPackagePath({
|
|
2741
|
+
repositoryRoot,
|
|
2742
|
+
name: config.partOf
|
|
2743
|
+
});
|
|
2744
|
+
if (!packagePath) {
|
|
2745
|
+
throw new MicrofrontendError2(
|
|
2746
|
+
`Could not find default application "${config.partOf}" in the repository`,
|
|
2747
|
+
{ type: "config", subtype: "not_found" }
|
|
2748
|
+
);
|
|
2749
|
+
}
|
|
2750
|
+
const mainConfigPath = (0, import_node_path9.join)(packagePath, "microfrontends.json");
|
|
2751
|
+
return MicrofrontendsServer.fromMainConfigFile({
|
|
2752
|
+
filePath: mainConfigPath,
|
|
2753
|
+
overrides: cookies ? parseOverrides(cookies) : void 0
|
|
2754
|
+
});
|
|
2589
2755
|
}
|
|
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
2756
|
}
|
|
2596
2757
|
return new MicrofrontendsServer({
|
|
2597
2758
|
config,
|
|
@@ -2612,7 +2773,7 @@ var MicrofrontendsServer = class extends Microfrontends {
|
|
|
2612
2773
|
overrides
|
|
2613
2774
|
}) {
|
|
2614
2775
|
try {
|
|
2615
|
-
const config =
|
|
2776
|
+
const config = import_node_fs8.default.readFileSync(filePath, "utf-8");
|
|
2616
2777
|
const validatedConfig = MicrofrontendsServer.validate(config);
|
|
2617
2778
|
if (!isMainConfig(validatedConfig)) {
|
|
2618
2779
|
throw new MicrofrontendError2(
|
|
@@ -2746,7 +2907,7 @@ var LocalProxy = class {
|
|
|
2746
2907
|
const isJWTRedirect = url.searchParams.has("_vercel_jwt");
|
|
2747
2908
|
const defaultHost = this.getDefaultHost(config);
|
|
2748
2909
|
let hostname = null;
|
|
2749
|
-
let
|
|
2910
|
+
let path6 = request2.url;
|
|
2750
2911
|
if (isAuthRedirect) {
|
|
2751
2912
|
hostname = url.searchParams.get("_host_override");
|
|
2752
2913
|
}
|
|
@@ -2756,12 +2917,12 @@ var LocalProxy = class {
|
|
|
2756
2917
|
if (isJWTRedirect) {
|
|
2757
2918
|
hostname = url.searchParams.get("_host_override");
|
|
2758
2919
|
url.searchParams.delete("_host_override");
|
|
2759
|
-
|
|
2920
|
+
path6 = `${url.pathname}${url.search}`;
|
|
2760
2921
|
}
|
|
2761
2922
|
if (!hostname) {
|
|
2762
2923
|
return void 0;
|
|
2763
2924
|
}
|
|
2764
|
-
return { ...defaultHost, path:
|
|
2925
|
+
return { ...defaultHost, path: path6, hostname, protocol: "https", port: 443 };
|
|
2765
2926
|
}
|
|
2766
2927
|
getConfigWithOverrides(cookies) {
|
|
2767
2928
|
if (isV2Config(this.config)) {
|
|
@@ -2792,19 +2953,19 @@ var LocalProxy = class {
|
|
|
2792
2953
|
getTarget(request2) {
|
|
2793
2954
|
const cookies = (0, import_cookie.parse)(request2.headers.cookie || "");
|
|
2794
2955
|
const config = this.getConfigWithOverrides(cookies);
|
|
2795
|
-
const
|
|
2796
|
-
if (!
|
|
2956
|
+
const path6 = request2.url;
|
|
2957
|
+
if (!path6) {
|
|
2797
2958
|
return this.getDefaultHost(config);
|
|
2798
2959
|
}
|
|
2799
2960
|
const authTarget = this.getAuthTarget(request2, config);
|
|
2800
2961
|
if (authTarget) {
|
|
2801
2962
|
return authTarget;
|
|
2802
2963
|
}
|
|
2803
|
-
const url = new URL(`http://example.com${
|
|
2964
|
+
const url = new URL(`http://example.com${path6}`);
|
|
2804
2965
|
const pathname = url.pathname;
|
|
2805
2966
|
if (isV2Config(config)) {
|
|
2806
2967
|
const target = this.findMatchingApplicationV2(
|
|
2807
|
-
|
|
2968
|
+
path6,
|
|
2808
2969
|
pathname,
|
|
2809
2970
|
config.getChildApplications()
|
|
2810
2971
|
);
|
|
@@ -2812,7 +2973,7 @@ var LocalProxy = class {
|
|
|
2812
2973
|
return target;
|
|
2813
2974
|
} else {
|
|
2814
2975
|
const target = this.findMatchingApplicationV1(
|
|
2815
|
-
|
|
2976
|
+
path6,
|
|
2816
2977
|
pathname,
|
|
2817
2978
|
config.getAllApplications()
|
|
2818
2979
|
);
|
|
@@ -2821,11 +2982,11 @@ var LocalProxy = class {
|
|
|
2821
2982
|
}
|
|
2822
2983
|
const defaultHost = this.getDefaultHost(config);
|
|
2823
2984
|
mfeDebug(
|
|
2824
|
-
`no matching routes, routing ${
|
|
2985
|
+
`no matching routes, routing ${path6} to default application: ${JSON.stringify(defaultHost)}`
|
|
2825
2986
|
);
|
|
2826
|
-
return { path:
|
|
2987
|
+
return { path: path6, ...defaultHost };
|
|
2827
2988
|
}
|
|
2828
|
-
findMatchingApplicationV1(
|
|
2989
|
+
findMatchingApplicationV1(path6, pathname, applications) {
|
|
2829
2990
|
for (const application of Object.values(applications)) {
|
|
2830
2991
|
if (application.routing) {
|
|
2831
2992
|
for (const group of application.routing.matches) {
|
|
@@ -2834,9 +2995,9 @@ var LocalProxy = class {
|
|
|
2834
2995
|
if (regexp.test(pathname)) {
|
|
2835
2996
|
const target = this.getApplicationTarget(application);
|
|
2836
2997
|
mfeDebug(
|
|
2837
|
-
`routing ${
|
|
2998
|
+
`routing ${path6} to '${target.application}' at ${target.hostname}`
|
|
2838
2999
|
);
|
|
2839
|
-
return { path:
|
|
3000
|
+
return { path: path6, ...target };
|
|
2840
3001
|
}
|
|
2841
3002
|
}
|
|
2842
3003
|
if (application.routing.assetPrefix) {
|
|
@@ -2846,9 +3007,9 @@ var LocalProxy = class {
|
|
|
2846
3007
|
if (pattern.test(pathname)) {
|
|
2847
3008
|
const target = this.getApplicationTarget(application);
|
|
2848
3009
|
mfeDebug(
|
|
2849
|
-
`routing ${
|
|
3010
|
+
`routing ${path6} to '${target.application}' at ${target.hostname}`
|
|
2850
3011
|
);
|
|
2851
|
-
return { path:
|
|
3012
|
+
return { path: path6, ...target };
|
|
2852
3013
|
}
|
|
2853
3014
|
}
|
|
2854
3015
|
}
|
|
@@ -2856,7 +3017,7 @@ var LocalProxy = class {
|
|
|
2856
3017
|
}
|
|
2857
3018
|
return null;
|
|
2858
3019
|
}
|
|
2859
|
-
findMatchingApplicationV2(
|
|
3020
|
+
findMatchingApplicationV2(path6, pathname, applications) {
|
|
2860
3021
|
for (const application of Object.values(applications)) {
|
|
2861
3022
|
for (const group of application.routing) {
|
|
2862
3023
|
for (const childPath of group.paths) {
|
|
@@ -2864,9 +3025,9 @@ var LocalProxy = class {
|
|
|
2864
3025
|
if (regexp.test(pathname)) {
|
|
2865
3026
|
const target = this.getApplicationTarget(application);
|
|
2866
3027
|
mfeDebug(
|
|
2867
|
-
`routing ${
|
|
3028
|
+
`routing ${path6} to '${target.application}' at ${target.hostname}`
|
|
2868
3029
|
);
|
|
2869
|
-
return { path:
|
|
3030
|
+
return { path: path6, ...target };
|
|
2870
3031
|
}
|
|
2871
3032
|
}
|
|
2872
3033
|
}
|
|
@@ -2875,11 +3036,11 @@ var LocalProxy = class {
|
|
|
2875
3036
|
}
|
|
2876
3037
|
// Handles requests that return data from the local proxy itself.
|
|
2877
3038
|
// Returns true if the request was handled, false otherwise.
|
|
2878
|
-
handleProxyInfoRequest(
|
|
2879
|
-
if (!
|
|
3039
|
+
handleProxyInfoRequest(path6, res) {
|
|
3040
|
+
if (!path6) {
|
|
2880
3041
|
return false;
|
|
2881
3042
|
}
|
|
2882
|
-
const url = new URL(`http://example.comf${
|
|
3043
|
+
const url = new URL(`http://example.comf${path6}`);
|
|
2883
3044
|
const pathname = url.pathname;
|
|
2884
3045
|
switch (pathname) {
|
|
2885
3046
|
case "/.well-known/vercel/microfrontend-routing": {
|
|
@@ -2907,10 +3068,10 @@ var LocalProxy = class {
|
|
|
2907
3068
|
}
|
|
2908
3069
|
const target = this.getTarget(req);
|
|
2909
3070
|
if (target.protocol === "https") {
|
|
2910
|
-
const { hostname, port, path:
|
|
3071
|
+
const { hostname, port, path: path6 } = target;
|
|
2911
3072
|
const requestOptions = {
|
|
2912
3073
|
hostname,
|
|
2913
|
-
path:
|
|
3074
|
+
path: path6,
|
|
2914
3075
|
method: req.method,
|
|
2915
3076
|
headers: {
|
|
2916
3077
|
...req.headers,
|
|
@@ -2938,7 +3099,7 @@ var LocalProxy = class {
|
|
|
2938
3099
|
console.error("Proxy request error: ", err);
|
|
2939
3100
|
res.writeHead(500, { "Content-Type": "text/plain" });
|
|
2940
3101
|
res.end(
|
|
2941
|
-
`Error proxying request for ${target.application} to ${hostname}:${port}${
|
|
3102
|
+
`Error proxying request for ${target.application} to ${hostname}:${port}${path6}`
|
|
2942
3103
|
);
|
|
2943
3104
|
});
|
|
2944
3105
|
} else {
|