@vercel/microfrontends 2.0.0-canary.1 → 2.0.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/CHANGELOG.md +11 -9
- package/README.md +21 -4
- package/dist/bin/cli.cjs +142 -13
- package/dist/config.cjs +123 -3
- package/dist/config.cjs.map +1 -1
- package/dist/config.d.ts +33 -2
- package/dist/config.js +122 -2
- package/dist/config.js.map +1 -1
- package/dist/experimental/sveltekit.cjs +128 -4
- package/dist/experimental/sveltekit.cjs.map +1 -1
- package/dist/experimental/sveltekit.js +127 -3
- package/dist/experimental/sveltekit.js.map +1 -1
- package/dist/experimental/vite.cjs +128 -4
- package/dist/experimental/vite.cjs.map +1 -1
- package/dist/experimental/vite.js +127 -3
- package/dist/experimental/vite.js.map +1 -1
- package/dist/microfrontends/server.cjs +128 -4
- package/dist/microfrontends/server.cjs.map +1 -1
- package/dist/microfrontends/server.d.ts +4 -3
- package/dist/microfrontends/server.js +127 -3
- package/dist/microfrontends/server.js.map +1 -1
- package/dist/next/config.cjs +131 -131
- package/dist/next/config.cjs.map +1 -1
- package/dist/next/config.d.ts +5 -0
- package/dist/next/config.js +130 -130
- package/dist/next/config.js.map +1 -1
- package/dist/next/middleware.cjs +125 -105
- package/dist/next/middleware.cjs.map +1 -1
- package/dist/next/middleware.js +125 -105
- package/dist/next/middleware.js.map +1 -1
- package/dist/next/testing.cjs +126 -6
- package/dist/next/testing.cjs.map +1 -1
- package/dist/next/testing.d.ts +2 -2
- package/dist/next/testing.js +124 -4
- package/dist/next/testing.js.map +1 -1
- package/dist/overrides.d.ts +3 -3
- package/dist/schema.d.ts +2 -2
- package/dist/{types-4299bff1.d.ts → types-88602303.d.ts} +1 -1
- package/dist/{types-0deb756b.d.ts → types-e7523e61.d.ts} +1 -1
- package/dist/utils/mfe-port.cjs +128 -4
- package/dist/utils/mfe-port.cjs.map +1 -1
- package/dist/utils/mfe-port.js +127 -3
- package/dist/utils/mfe-port.js.map +1 -1
- package/dist/validation.d.ts +1 -1
- package/package.json +7 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,22 +1,24 @@
|
|
|
1
1
|
# @vercel/microfrontends
|
|
2
2
|
|
|
3
|
-
## 2.0.0
|
|
3
|
+
## 2.0.0
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
- Support old and new asset prefixes in local development proxy.
|
|
8
|
-
|
|
9
|
-
## 2.0.0-canary.0
|
|
10
|
-
|
|
11
|
-
> **Check out our [Public Beta](https://vercel.com/changelog/microfrontends-are-now-in-public-beta) changelog to learn more about this release.**
|
|
5
|
+
> **Check out our [Public Beta](https://vercel.com/changelog/microfrontends-support-is-now-in-public-beta) changelog to learn more about this release.**
|
|
12
6
|
|
|
13
7
|
### Major Changes
|
|
14
8
|
|
|
15
9
|
- This release removes the project name and flag names from being visible to client side code.
|
|
16
10
|
- Modify the auto-generated asset prefix to use a hash of the project name instead of the project name itself.
|
|
17
|
-
- Allow users to specify a custom asset prefix in
|
|
11
|
+
- Allow users to specify a custom asset prefix in `microfrontends.json`.
|
|
18
12
|
- Remove project names and flag names from the Microfrontends client configuration.
|
|
19
13
|
|
|
14
|
+
### Minor Changes
|
|
15
|
+
|
|
16
|
+
- Use user-provided appName when inferring the location of microfrontends.json.
|
|
17
|
+
|
|
18
|
+
### Patch Changes
|
|
19
|
+
|
|
20
|
+
- Improve error messages when the name in `package.json` does not match the Vercel project name.
|
|
21
|
+
|
|
20
22
|
## 1.5.0
|
|
21
23
|
|
|
22
24
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -1,9 +1,26 @@
|
|
|
1
1
|
<picture>
|
|
2
|
-
<source srcset="https://assets.vercel.com/image/upload/v1689795055/docs-assets/static/docs/microfrontends/mfe-banner-dark.png" media="(prefers-color-scheme: dark)">
|
|
3
|
-
<source srcset="https://assets.vercel.com/image/upload/v1689795055/docs-assets/static/docs/microfrontends/mfe-banner-light.png" media="(prefers-color-scheme: light)">
|
|
4
|
-
<img src="https://assets.vercel.com/image/upload/v1689795055/docs-assets/static/docs/microfrontends/mfe-banner-
|
|
2
|
+
<source srcset="https://assets.vercel.com/image/upload/v1689795055/docs-assets/static/docs/microfrontends/mfe-package-banner-dark.png" media="(prefers-color-scheme: dark)">
|
|
3
|
+
<source srcset="https://assets.vercel.com/image/upload/v1689795055/docs-assets/static/docs/microfrontends/mfe-package-banner-light.png" media="(prefers-color-scheme: light)">
|
|
4
|
+
<img src="https://assets.vercel.com/image/upload/v1689795055/docs-assets/static/docs/microfrontends/mfe-package-banner-dark.png" alt="hero banner">
|
|
5
5
|
</picture>
|
|
6
6
|
|
|
7
7
|
# @vercel/microfrontends
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Split apart large applications and develop faster with microfrontends. This package contains library code to be used with Vercel's [microfrontends support](https://vercel.com/docs/microfrontends).
|
|
10
|
+
|
|
11
|
+
- **Improved developer velocity**: Build and test just the application that you are developing. Independent applications allow each team to choose their own technology stack.
|
|
12
|
+
- **Incremental migrations**: Gradually migrate systems to modern frameworks without rewriting everything at once.
|
|
13
|
+
|
|
14
|
+
See the [full documentation](https://vercel.com/docs/microfrontends) and [examples](https://vercel.com/templates/microfrontends) to learn more.
|
|
15
|
+
|
|
16
|
+
## Getting Started
|
|
17
|
+
|
|
18
|
+
Follow the [quickstart](https://vercel.com/docs/microfrontends/quickstart) documentation to get started.
|
|
19
|
+
|
|
20
|
+
## Frameworks support
|
|
21
|
+
|
|
22
|
+
You can use the frameworks and microfrontends frameworks of your choice. `@vercel/microfrontends` supports Next.js, SvelteKit, React Router, Vite, and React.
|
|
23
|
+
|
|
24
|
+
## Need help?
|
|
25
|
+
|
|
26
|
+
Reach out for help in the [Vercel Community](https://community.vercel.com).
|
package/dist/bin/cli.cjs
CHANGED
|
@@ -30,12 +30,17 @@ var import_env = require("@next/env");
|
|
|
30
30
|
// package.json
|
|
31
31
|
var package_default = {
|
|
32
32
|
name: "@vercel/microfrontends",
|
|
33
|
-
version: "2.0.0
|
|
33
|
+
version: "2.0.0",
|
|
34
34
|
private: false,
|
|
35
35
|
description: "Defines configuration and utilities for microfrontends development",
|
|
36
36
|
keywords: [
|
|
37
37
|
"microfrontends",
|
|
38
|
-
"
|
|
38
|
+
"micro-frontends",
|
|
39
|
+
"micro frontends",
|
|
40
|
+
"microservices",
|
|
41
|
+
"Vercel",
|
|
42
|
+
"Next.js",
|
|
43
|
+
"React"
|
|
39
44
|
],
|
|
40
45
|
homepage: "https://vercel.com/docs/microfrontends",
|
|
41
46
|
repository: {
|
|
@@ -244,7 +249,7 @@ var http = __toESM(require("http"), 1);
|
|
|
244
249
|
var https = __toESM(require("https"), 1);
|
|
245
250
|
var import_node_url = require("url");
|
|
246
251
|
var import_cookie = require("cookie");
|
|
247
|
-
var
|
|
252
|
+
var import_path_to_regexp3 = require("path-to-regexp");
|
|
248
253
|
var import_http_proxy = __toESM(require("http-proxy"), 1);
|
|
249
254
|
|
|
250
255
|
// src/config/microfrontends-config/isomorphic/index.ts
|
|
@@ -392,8 +397,106 @@ function parseOverrides(cookies) {
|
|
|
392
397
|
return overridesConfig;
|
|
393
398
|
}
|
|
394
399
|
|
|
395
|
-
// src/config/microfrontends-config/
|
|
400
|
+
// src/config/microfrontends-config/client/index.ts
|
|
396
401
|
var import_path_to_regexp = require("path-to-regexp");
|
|
402
|
+
var regexpCache = /* @__PURE__ */ new Map();
|
|
403
|
+
var getRegexp = (path7) => {
|
|
404
|
+
const existing = regexpCache.get(path7);
|
|
405
|
+
if (existing) {
|
|
406
|
+
return existing;
|
|
407
|
+
}
|
|
408
|
+
const regexp = (0, import_path_to_regexp.pathToRegexp)(path7);
|
|
409
|
+
regexpCache.set(path7, regexp);
|
|
410
|
+
return regexp;
|
|
411
|
+
};
|
|
412
|
+
var MicrofrontendConfigClient = class {
|
|
413
|
+
constructor(config, opts) {
|
|
414
|
+
this.pathCache = {};
|
|
415
|
+
this.hasFlaggedPaths = config.hasFlaggedPaths ?? false;
|
|
416
|
+
for (const app of Object.values(config.applications)) {
|
|
417
|
+
if (app.routing) {
|
|
418
|
+
if (app.routing.some((match) => match.flag)) {
|
|
419
|
+
this.hasFlaggedPaths = true;
|
|
420
|
+
}
|
|
421
|
+
const newRouting = [];
|
|
422
|
+
const pathsWithoutFlags = [];
|
|
423
|
+
for (const group of app.routing) {
|
|
424
|
+
if (group.flag) {
|
|
425
|
+
if (opts?.removeFlaggedPaths) {
|
|
426
|
+
continue;
|
|
427
|
+
}
|
|
428
|
+
if (group.group) {
|
|
429
|
+
delete group.group;
|
|
430
|
+
}
|
|
431
|
+
newRouting.push(group);
|
|
432
|
+
} else {
|
|
433
|
+
pathsWithoutFlags.push(...group.paths);
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
if (pathsWithoutFlags.length > 0) {
|
|
437
|
+
newRouting.push({ paths: pathsWithoutFlags });
|
|
438
|
+
}
|
|
439
|
+
app.routing = newRouting;
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
this.serialized = config;
|
|
443
|
+
if (this.hasFlaggedPaths) {
|
|
444
|
+
this.serialized.hasFlaggedPaths = this.hasFlaggedPaths;
|
|
445
|
+
}
|
|
446
|
+
this.applications = config.applications;
|
|
447
|
+
}
|
|
448
|
+
/**
|
|
449
|
+
* Create a new `MicrofrontendConfigClient` from a JSON string.
|
|
450
|
+
* Config must be passed in to remain framework agnostic
|
|
451
|
+
*/
|
|
452
|
+
static fromEnv(config) {
|
|
453
|
+
if (!config) {
|
|
454
|
+
throw new Error(
|
|
455
|
+
"Could not construct MicrofrontendConfigClient: configuration is empty or undefined. Did you set up your application with `withMicrofrontends`?"
|
|
456
|
+
);
|
|
457
|
+
}
|
|
458
|
+
return new MicrofrontendConfigClient(JSON.parse(config));
|
|
459
|
+
}
|
|
460
|
+
isEqual(other) {
|
|
461
|
+
return this === other || JSON.stringify(this.applications) === JSON.stringify(other.applications);
|
|
462
|
+
}
|
|
463
|
+
getApplicationNameForPath(path7) {
|
|
464
|
+
if (!path7.startsWith("/")) {
|
|
465
|
+
throw new Error(`Path must start with a /`);
|
|
466
|
+
}
|
|
467
|
+
if (this.pathCache[path7]) {
|
|
468
|
+
return this.pathCache[path7];
|
|
469
|
+
}
|
|
470
|
+
const pathname = new URL(path7, "https://example.com").pathname;
|
|
471
|
+
for (const [name, application] of Object.entries(this.applications)) {
|
|
472
|
+
if (application.routing) {
|
|
473
|
+
for (const group of application.routing) {
|
|
474
|
+
for (const childPath of group.paths) {
|
|
475
|
+
const regexp = getRegexp(childPath);
|
|
476
|
+
if (regexp.test(pathname)) {
|
|
477
|
+
this.pathCache[path7] = name;
|
|
478
|
+
return name;
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
const defaultApplication = Object.entries(this.applications).find(
|
|
485
|
+
([, application]) => application.default
|
|
486
|
+
);
|
|
487
|
+
if (!defaultApplication) {
|
|
488
|
+
return null;
|
|
489
|
+
}
|
|
490
|
+
this.pathCache[path7] = defaultApplication[0];
|
|
491
|
+
return defaultApplication[0];
|
|
492
|
+
}
|
|
493
|
+
serialize() {
|
|
494
|
+
return this.serialized;
|
|
495
|
+
}
|
|
496
|
+
};
|
|
497
|
+
|
|
498
|
+
// src/config/microfrontends-config/isomorphic/validation.ts
|
|
499
|
+
var import_path_to_regexp2 = require("path-to-regexp");
|
|
397
500
|
var LIST_FORMATTER = new Intl.ListFormat("en", {
|
|
398
501
|
style: "long",
|
|
399
502
|
type: "conjunction"
|
|
@@ -421,7 +524,7 @@ var validateConfigPaths = (applicationConfigsById) => {
|
|
|
421
524
|
} else {
|
|
422
525
|
pathsByApplicationId.set(path7, {
|
|
423
526
|
applications: [id],
|
|
424
|
-
matcher: (0,
|
|
527
|
+
matcher: (0, import_path_to_regexp2.pathToRegexp)(path7),
|
|
425
528
|
applicationId: id
|
|
426
529
|
});
|
|
427
530
|
}
|
|
@@ -468,7 +571,7 @@ var validateConfigPaths = (applicationConfigsById) => {
|
|
|
468
571
|
var PATH_DEFAULT_PATTERN = "[^\\/#\\?]+?";
|
|
469
572
|
function validatePathExpression(path7) {
|
|
470
573
|
try {
|
|
471
|
-
const tokens = (0,
|
|
574
|
+
const tokens = (0, import_path_to_regexp2.parse)(path7);
|
|
472
575
|
if (/(?<!\\)\{/.test(path7)) {
|
|
473
576
|
return `Optional paths are not supported: ${path7}`;
|
|
474
577
|
}
|
|
@@ -926,6 +1029,28 @@ var MicrofrontendConfigIsomorphic = class {
|
|
|
926
1029
|
getLocalProxyPort() {
|
|
927
1030
|
return this.config.options?.localProxyPort ?? DEFAULT_LOCAL_PROXY_PORT;
|
|
928
1031
|
}
|
|
1032
|
+
toClientConfig(options) {
|
|
1033
|
+
const applications = Object.fromEntries(
|
|
1034
|
+
Object.entries(this.childApplications).map(([name, application]) => [
|
|
1035
|
+
hashApplicationName(name),
|
|
1036
|
+
{
|
|
1037
|
+
default: false,
|
|
1038
|
+
routing: application.routing
|
|
1039
|
+
}
|
|
1040
|
+
])
|
|
1041
|
+
);
|
|
1042
|
+
applications[hashApplicationName(this.defaultApplication.name)] = {
|
|
1043
|
+
default: true
|
|
1044
|
+
};
|
|
1045
|
+
return new MicrofrontendConfigClient(
|
|
1046
|
+
{
|
|
1047
|
+
applications
|
|
1048
|
+
},
|
|
1049
|
+
{
|
|
1050
|
+
removeFlaggedPaths: options?.removeFlaggedPaths
|
|
1051
|
+
}
|
|
1052
|
+
);
|
|
1053
|
+
}
|
|
929
1054
|
/**
|
|
930
1055
|
* Serializes the class back to the Schema type.
|
|
931
1056
|
*
|
|
@@ -1553,6 +1678,7 @@ var MicrofrontendsServer = class {
|
|
|
1553
1678
|
* This can return either a Child or Main configuration.
|
|
1554
1679
|
*/
|
|
1555
1680
|
static infer({
|
|
1681
|
+
appName,
|
|
1556
1682
|
directory,
|
|
1557
1683
|
filePath,
|
|
1558
1684
|
cookies
|
|
@@ -1565,7 +1691,10 @@ var MicrofrontendsServer = class {
|
|
|
1565
1691
|
}
|
|
1566
1692
|
try {
|
|
1567
1693
|
const packageRoot = findPackageRoot(directory);
|
|
1568
|
-
const applicationContext = getApplicationContext({
|
|
1694
|
+
const applicationContext = getApplicationContext({
|
|
1695
|
+
appName,
|
|
1696
|
+
packageRoot
|
|
1697
|
+
});
|
|
1569
1698
|
const maybeConfig = findConfig({ dir: packageRoot });
|
|
1570
1699
|
if (maybeConfig) {
|
|
1571
1700
|
return MicrofrontendsServer.fromFile({
|
|
@@ -2131,7 +2260,7 @@ var ProxyRequestRouter = class {
|
|
|
2131
2260
|
}
|
|
2132
2261
|
for (const group of application.routing) {
|
|
2133
2262
|
for (const childPath of group.paths) {
|
|
2134
|
-
const regexp = (0,
|
|
2263
|
+
const regexp = (0, import_path_to_regexp3.pathToRegexp)(childPath);
|
|
2135
2264
|
if (regexp.test(url.pathname)) {
|
|
2136
2265
|
mfeDebug(
|
|
2137
2266
|
`routing ${path7} to '${target.application}' at ${target.hostname}`
|
|
@@ -2180,7 +2309,7 @@ var ProxyRequestRouter = class {
|
|
|
2180
2309
|
]);
|
|
2181
2310
|
for (const rewrite of rewrites) {
|
|
2182
2311
|
for (const assetPrefix of assetPrefixes) {
|
|
2183
|
-
if ((0,
|
|
2312
|
+
if ((0, import_path_to_regexp3.pathToRegexp)(`/${assetPrefix}${rewrite}`).test(pathname)) {
|
|
2184
2313
|
mfeDebug(
|
|
2185
2314
|
`routing ${pathname} to '${target.application}' at ${target.hostname}`
|
|
2186
2315
|
);
|
|
@@ -2198,8 +2327,8 @@ var ProxyRequestRouter = class {
|
|
|
2198
2327
|
referer = void 0,
|
|
2199
2328
|
applications
|
|
2200
2329
|
}) {
|
|
2201
|
-
const isStackFrame = (0,
|
|
2202
|
-
(0,
|
|
2330
|
+
const isStackFrame = (0, import_path_to_regexp3.pathToRegexp)("/__nextjs_original-stack-frame").test(url.pathname) || // Plural form was introduced in https://github.com/vercel/next.js/pull/75557
|
|
2331
|
+
(0, import_path_to_regexp3.pathToRegexp)("/__nextjs_original-stack-frames").test(url.pathname);
|
|
2203
2332
|
if (!referer || !isStackFrame) {
|
|
2204
2333
|
return null;
|
|
2205
2334
|
}
|
|
@@ -2219,7 +2348,7 @@ var ProxyRequestRouter = class {
|
|
|
2219
2348
|
} : null;
|
|
2220
2349
|
}
|
|
2221
2350
|
checkNextSourceMap({ url }) {
|
|
2222
|
-
const isSourceMap = (0,
|
|
2351
|
+
const isSourceMap = (0, import_path_to_regexp3.pathToRegexp)("/__nextjs_source-map").test(url.pathname);
|
|
2223
2352
|
if (!isSourceMap) {
|
|
2224
2353
|
return null;
|
|
2225
2354
|
}
|
|
@@ -2239,7 +2368,7 @@ var ProxyRequestRouter = class {
|
|
|
2239
2368
|
url,
|
|
2240
2369
|
applications
|
|
2241
2370
|
}) {
|
|
2242
|
-
const isNextImage = (0,
|
|
2371
|
+
const isNextImage = (0, import_path_to_regexp3.pathToRegexp)("/_next/image").test(url.pathname);
|
|
2243
2372
|
if (!isNextImage) {
|
|
2244
2373
|
return null;
|
|
2245
2374
|
}
|
package/dist/config.cjs
CHANGED
|
@@ -177,8 +177,106 @@ function parseOverrides(cookies) {
|
|
|
177
177
|
return overridesConfig;
|
|
178
178
|
}
|
|
179
179
|
|
|
180
|
-
// src/config/microfrontends-config/
|
|
180
|
+
// src/config/microfrontends-config/client/index.ts
|
|
181
181
|
var import_path_to_regexp = require("path-to-regexp");
|
|
182
|
+
var regexpCache = /* @__PURE__ */ new Map();
|
|
183
|
+
var getRegexp = (path) => {
|
|
184
|
+
const existing = regexpCache.get(path);
|
|
185
|
+
if (existing) {
|
|
186
|
+
return existing;
|
|
187
|
+
}
|
|
188
|
+
const regexp = (0, import_path_to_regexp.pathToRegexp)(path);
|
|
189
|
+
regexpCache.set(path, regexp);
|
|
190
|
+
return regexp;
|
|
191
|
+
};
|
|
192
|
+
var MicrofrontendConfigClient = class {
|
|
193
|
+
constructor(config, opts) {
|
|
194
|
+
this.pathCache = {};
|
|
195
|
+
this.hasFlaggedPaths = config.hasFlaggedPaths ?? false;
|
|
196
|
+
for (const app of Object.values(config.applications)) {
|
|
197
|
+
if (app.routing) {
|
|
198
|
+
if (app.routing.some((match) => match.flag)) {
|
|
199
|
+
this.hasFlaggedPaths = true;
|
|
200
|
+
}
|
|
201
|
+
const newRouting = [];
|
|
202
|
+
const pathsWithoutFlags = [];
|
|
203
|
+
for (const group of app.routing) {
|
|
204
|
+
if (group.flag) {
|
|
205
|
+
if (opts?.removeFlaggedPaths) {
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
if (group.group) {
|
|
209
|
+
delete group.group;
|
|
210
|
+
}
|
|
211
|
+
newRouting.push(group);
|
|
212
|
+
} else {
|
|
213
|
+
pathsWithoutFlags.push(...group.paths);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
if (pathsWithoutFlags.length > 0) {
|
|
217
|
+
newRouting.push({ paths: pathsWithoutFlags });
|
|
218
|
+
}
|
|
219
|
+
app.routing = newRouting;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
this.serialized = config;
|
|
223
|
+
if (this.hasFlaggedPaths) {
|
|
224
|
+
this.serialized.hasFlaggedPaths = this.hasFlaggedPaths;
|
|
225
|
+
}
|
|
226
|
+
this.applications = config.applications;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Create a new `MicrofrontendConfigClient` from a JSON string.
|
|
230
|
+
* Config must be passed in to remain framework agnostic
|
|
231
|
+
*/
|
|
232
|
+
static fromEnv(config) {
|
|
233
|
+
if (!config) {
|
|
234
|
+
throw new Error(
|
|
235
|
+
"Could not construct MicrofrontendConfigClient: configuration is empty or undefined. Did you set up your application with `withMicrofrontends`?"
|
|
236
|
+
);
|
|
237
|
+
}
|
|
238
|
+
return new MicrofrontendConfigClient(JSON.parse(config));
|
|
239
|
+
}
|
|
240
|
+
isEqual(other) {
|
|
241
|
+
return this === other || JSON.stringify(this.applications) === JSON.stringify(other.applications);
|
|
242
|
+
}
|
|
243
|
+
getApplicationNameForPath(path) {
|
|
244
|
+
if (!path.startsWith("/")) {
|
|
245
|
+
throw new Error(`Path must start with a /`);
|
|
246
|
+
}
|
|
247
|
+
if (this.pathCache[path]) {
|
|
248
|
+
return this.pathCache[path];
|
|
249
|
+
}
|
|
250
|
+
const pathname = new URL(path, "https://example.com").pathname;
|
|
251
|
+
for (const [name, application] of Object.entries(this.applications)) {
|
|
252
|
+
if (application.routing) {
|
|
253
|
+
for (const group of application.routing) {
|
|
254
|
+
for (const childPath of group.paths) {
|
|
255
|
+
const regexp = getRegexp(childPath);
|
|
256
|
+
if (regexp.test(pathname)) {
|
|
257
|
+
this.pathCache[path] = name;
|
|
258
|
+
return name;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
const defaultApplication = Object.entries(this.applications).find(
|
|
265
|
+
([, application]) => application.default
|
|
266
|
+
);
|
|
267
|
+
if (!defaultApplication) {
|
|
268
|
+
return null;
|
|
269
|
+
}
|
|
270
|
+
this.pathCache[path] = defaultApplication[0];
|
|
271
|
+
return defaultApplication[0];
|
|
272
|
+
}
|
|
273
|
+
serialize() {
|
|
274
|
+
return this.serialized;
|
|
275
|
+
}
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
// src/config/microfrontends-config/isomorphic/validation.ts
|
|
279
|
+
var import_path_to_regexp2 = require("path-to-regexp");
|
|
182
280
|
var LIST_FORMATTER = new Intl.ListFormat("en", {
|
|
183
281
|
style: "long",
|
|
184
282
|
type: "conjunction"
|
|
@@ -206,7 +304,7 @@ var validateConfigPaths = (applicationConfigsById) => {
|
|
|
206
304
|
} else {
|
|
207
305
|
pathsByApplicationId.set(path, {
|
|
208
306
|
applications: [id],
|
|
209
|
-
matcher: (0,
|
|
307
|
+
matcher: (0, import_path_to_regexp2.pathToRegexp)(path),
|
|
210
308
|
applicationId: id
|
|
211
309
|
});
|
|
212
310
|
}
|
|
@@ -253,7 +351,7 @@ var validateConfigPaths = (applicationConfigsById) => {
|
|
|
253
351
|
var PATH_DEFAULT_PATTERN = "[^\\/#\\?]+?";
|
|
254
352
|
function validatePathExpression(path) {
|
|
255
353
|
try {
|
|
256
|
-
const tokens = (0,
|
|
354
|
+
const tokens = (0, import_path_to_regexp2.parse)(path);
|
|
257
355
|
if (/(?<!\\)\{/.test(path)) {
|
|
258
356
|
return `Optional paths are not supported: ${path}`;
|
|
259
357
|
}
|
|
@@ -711,6 +809,28 @@ var MicrofrontendConfigIsomorphic = class {
|
|
|
711
809
|
getLocalProxyPort() {
|
|
712
810
|
return this.config.options?.localProxyPort ?? DEFAULT_LOCAL_PROXY_PORT;
|
|
713
811
|
}
|
|
812
|
+
toClientConfig(options) {
|
|
813
|
+
const applications = Object.fromEntries(
|
|
814
|
+
Object.entries(this.childApplications).map(([name, application]) => [
|
|
815
|
+
hashApplicationName(name),
|
|
816
|
+
{
|
|
817
|
+
default: false,
|
|
818
|
+
routing: application.routing
|
|
819
|
+
}
|
|
820
|
+
])
|
|
821
|
+
);
|
|
822
|
+
applications[hashApplicationName(this.defaultApplication.name)] = {
|
|
823
|
+
default: true
|
|
824
|
+
};
|
|
825
|
+
return new MicrofrontendConfigClient(
|
|
826
|
+
{
|
|
827
|
+
applications
|
|
828
|
+
},
|
|
829
|
+
{
|
|
830
|
+
removeFlaggedPaths: options?.removeFlaggedPaths
|
|
831
|
+
}
|
|
832
|
+
);
|
|
833
|
+
}
|
|
714
834
|
/**
|
|
715
835
|
* Serializes the class back to the Schema type.
|
|
716
836
|
*
|