@mashroom/mashroom-portal-open-microfrontends-support 3.0.0-alpha.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/LICENSE +21 -0
- package/README.md +42 -0
- package/dist/app-enhancement/MashroomOpenMicrofrontendsMashroomPortalAppEnhancementPlugin.js +30 -0
- package/dist/app-enhancement/mapPortalAppSetupToOpenMicrofrontendsContext.js +33 -0
- package/dist/app-enhancement/mashroom-bootstrap-portal-app-enhancement.js +15 -0
- package/dist/def-builder/MashroomOpenMicrofrontendsPluginPackageDefinitionBuilder.js +51 -0
- package/dist/def-builder/constants.js +11 -0
- package/dist/def-builder/fetchRemoteJSONorYAML.js +39 -0
- package/dist/def-builder/mapOpenMicrofrontendsToPortalApp2.js +164 -0
- package/dist/def-builder/mashroom-bootstrap-package-definition-builder.js +15 -0
- package/dist/public/openMicrofrontendsClientBootstrapAdapter.js +2 -0
- package/dist/public/openMicrofrontendsClientBootstrapAdapter.js.map +1 -0
- package/mashroom.json +32 -0
- package/package.json +43 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) nonblocking.at gmbh
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
|
|
2
|
+
# Mashroom Portal Open Microfrontends Support
|
|
3
|
+
|
|
4
|
+
Plugin for [Mashroom Server](https://www.mashroom-server.com), a **Microfrontend Integration Platform**.
|
|
5
|
+
|
|
6
|
+
This plugins loads support for registering and loading [OpenMicrofrontends](https://open-microfrontends.org) compatible Microfrontends
|
|
7
|
+
in the [Mashroom Portal](../mashroom-portal).
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
If *node_modules/@mashroom* is configured as a plugin path, add **mashroom-portal-open-microfrontends-support** as *dependency*.
|
|
12
|
+
|
|
13
|
+
After that you can register [OpenMicrofrontends](https://open-microfrontends.org) compatible Microfrontends like any other *remote plugin*, e.g.,
|
|
14
|
+
by opening */mashroom/admin/ext/remote-plugin-packages* and pasting the Microfrontend URL into the form.
|
|
15
|
+
|
|
16
|
+
### Custom Extensions
|
|
17
|
+
|
|
18
|
+
This plugin supports some custom annotations for features OpenMicrofrontends doesn't support out of the box:
|
|
19
|
+
|
|
20
|
+
* MASHROOM_ROLE_PERMISSIONS: Sames as *rolePermissions* in native Mashroom Portal Apps.
|
|
21
|
+
* MASHROOM_DEFAULT_RESTRICT_VIEW_TO_ROLES: Same as *defaultRestrictViewToRoles* in native Mashroom Portal Apps.
|
|
22
|
+
* MASHROOM_PROXIES_RESTRICT_TO_ROLES: Define *restrictToRoles* for specific proxies.
|
|
23
|
+
* MASHROOM_META_INFO: Will be merged into *metaInfo*.
|
|
24
|
+
|
|
25
|
+
Example:
|
|
26
|
+
|
|
27
|
+
```yaml
|
|
28
|
+
annotations:
|
|
29
|
+
# Mashroom extensions
|
|
30
|
+
MASHROOM_ROLE_PERMISSIONS:
|
|
31
|
+
deleteCustomer:
|
|
32
|
+
- role1
|
|
33
|
+
- role2
|
|
34
|
+
MASHROOM_DEFAULT_RESTRICT_VIEW_TO_ROLES:
|
|
35
|
+
- role3
|
|
36
|
+
MASHROOM_PROXIES_RESTRICT_TO_ROLES:
|
|
37
|
+
proxy1:
|
|
38
|
+
- role4
|
|
39
|
+
- role5
|
|
40
|
+
MASHROOM_META_INFO:
|
|
41
|
+
myCustomProperty: myCustomValue
|
|
42
|
+
```
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _mapPortalAppSetupToOpenMicrofrontendsContext = _interopRequireDefault(require("./mapPortalAppSetupToOpenMicrofrontendsContext"));
|
|
8
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
9
|
+
class MashroomOpenMicrofrontendsMashroomPortalAppEnhancementPlugin {
|
|
10
|
+
#logger;
|
|
11
|
+
constructor(loggerFactory) {
|
|
12
|
+
this.#logger = loggerFactory('mashroom.portal.open-microfrontends');
|
|
13
|
+
}
|
|
14
|
+
async enhancePortalAppSetup(portalAppSetup, portalApp, request) {
|
|
15
|
+
if (portalApp.metaInfo?.openMicrofrontends) {
|
|
16
|
+
this.#logger.debug(`Mapping setup to OpenMicrofrontends context for App ${portalApp.name}`);
|
|
17
|
+
const context = (0, _mapPortalAppSetupToOpenMicrofrontendsContext.default)(portalAppSetup);
|
|
18
|
+
return {
|
|
19
|
+
...portalAppSetup,
|
|
20
|
+
...context,
|
|
21
|
+
user: {
|
|
22
|
+
...portalAppSetup.user,
|
|
23
|
+
...context.user
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
return portalAppSetup;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
exports.default = MashroomOpenMicrofrontendsMashroomPortalAppEnhancementPlugin;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _default = portalAppSetup => {
|
|
8
|
+
const {
|
|
9
|
+
appId,
|
|
10
|
+
lang,
|
|
11
|
+
proxyPaths,
|
|
12
|
+
user,
|
|
13
|
+
appConfig,
|
|
14
|
+
serverSideRendered
|
|
15
|
+
} = portalAppSetup;
|
|
16
|
+
return {
|
|
17
|
+
id: appId,
|
|
18
|
+
lang,
|
|
19
|
+
user: !user.guest ? {
|
|
20
|
+
username: user.username,
|
|
21
|
+
displayName: user.displayName
|
|
22
|
+
} : undefined,
|
|
23
|
+
permissions: user.permissions,
|
|
24
|
+
apiProxyPaths: proxyPaths,
|
|
25
|
+
config: appConfig,
|
|
26
|
+
serverSideRendered,
|
|
27
|
+
hostContext: {
|
|
28
|
+
hostApplicationName: 'Mashroom Portal',
|
|
29
|
+
openMicrofrontends: true
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
exports.default = _default;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _MashroomOpenMicrofrontendsMashroomPortalAppEnhancementPlugin = _interopRequireDefault(require("./MashroomOpenMicrofrontendsMashroomPortalAppEnhancementPlugin"));
|
|
8
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
9
|
+
const bootstrap = (pluginName, pluginConfig, pluginContextHolder) => {
|
|
10
|
+
const {
|
|
11
|
+
loggerFactory
|
|
12
|
+
} = pluginContextHolder.getPluginContext();
|
|
13
|
+
return new _MashroomOpenMicrofrontendsMashroomPortalAppEnhancementPlugin.default(loggerFactory);
|
|
14
|
+
};
|
|
15
|
+
var _default = exports.default = bootstrap;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _url = require("url");
|
|
8
|
+
var _fetchRemoteJSONorYAML = _interopRequireDefault(require("./fetchRemoteJSONorYAML"));
|
|
9
|
+
var _mapOpenMicrofrontendsToPortalApp = _interopRequireDefault(require("./mapOpenMicrofrontendsToPortalApp2"));
|
|
10
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
11
|
+
const KNOWN_OPEN_MICROFRONTENDS_DESCRIPTOR_PATHS = ['/microfrontends.yaml', '/microfrontends.json'];
|
|
12
|
+
class MashroomOpenMicrofrontendsPluginPackageDefinitionBuilder {
|
|
13
|
+
#logger;
|
|
14
|
+
constructor(loggerFactory) {
|
|
15
|
+
this.#logger = loggerFactory('mashroom.portal.open-microfrontends');
|
|
16
|
+
}
|
|
17
|
+
get name() {
|
|
18
|
+
return 'Mashroom Open Microfrontends Plugin Package Definition Builder';
|
|
19
|
+
}
|
|
20
|
+
async buildDefinition(packageUrl, scannerHints) {
|
|
21
|
+
if (packageUrl.protocol === 'file:') {
|
|
22
|
+
// Ignore local packages
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
this.#logger.debug(`Checking for an OpenMicrofrontends: ${packageUrl}`);
|
|
26
|
+
|
|
27
|
+
// If there is a scanner hint that suggest that this is a native Mashroom remote package, skip it
|
|
28
|
+
if (Object.keys(scannerHints).find(hint => hint.startsWith('mashroom-server.com/'))) {
|
|
29
|
+
this.#logger.debug(`Ignoring package because ${scannerHints.pluginDefinitionPath} doesn't look like a OpenMicrofrontends compatible service`);
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
let descriptor;
|
|
33
|
+
for (const path of KNOWN_OPEN_MICROFRONTENDS_DESCRIPTOR_PATHS) {
|
|
34
|
+
const descriptorURL = new _url.URL(path, packageUrl);
|
|
35
|
+
try {
|
|
36
|
+
descriptor = await (0, _fetchRemoteJSONorYAML.default)(descriptorURL, this.#logger);
|
|
37
|
+
if (descriptor) {
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
} catch (e) {
|
|
41
|
+
this.#logger.error(`Fetching OpenMicrofrontends descriptor from ${descriptorURL} failed!`, e);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
if (!descriptor || !('openMicrofrontends' in descriptor)) {
|
|
45
|
+
this.#logger.debug(`No OpenMicrofrontends descriptor found for ${packageUrl}`);
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
return [await (0, _mapOpenMicrofrontendsToPortalApp.default)(packageUrl, scannerHints, descriptor, this.#logger)];
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
exports.default = MashroomOpenMicrofrontendsPluginPackageDefinitionBuilder;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.META_INFO_FLAG_OPEN_MICROFRONTENDS = exports.ANNOTATION_ROLE_PERMISSIONS = exports.ANNOTATION_PROXIES_RESTRICT_TO_ROLES = exports.ANNOTATION_META_INFO = exports.ANNOTATION_DEFAULT_RESTRICT_VIEW_TO_ROLES = void 0;
|
|
7
|
+
const META_INFO_FLAG_OPEN_MICROFRONTENDS = exports.META_INFO_FLAG_OPEN_MICROFRONTENDS = 'openMicrofrontends';
|
|
8
|
+
const ANNOTATION_ROLE_PERMISSIONS = exports.ANNOTATION_ROLE_PERMISSIONS = 'MASHROOM_ROLE_PERMISSIONS';
|
|
9
|
+
const ANNOTATION_DEFAULT_RESTRICT_VIEW_TO_ROLES = exports.ANNOTATION_DEFAULT_RESTRICT_VIEW_TO_ROLES = 'MASHROOM_DEFAULT_RESTRICT_VIEW_TO_ROLES';
|
|
10
|
+
const ANNOTATION_PROXIES_RESTRICT_TO_ROLES = exports.ANNOTATION_PROXIES_RESTRICT_TO_ROLES = 'MASHROOM_PROXIES_RESTRICT_TO_ROLES';
|
|
11
|
+
const ANNOTATION_META_INFO = exports.ANNOTATION_META_INFO = 'MASHROOM_META_INFO'; // Test
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _mashroomUtils = require("@mashroom/mashroom-utils");
|
|
8
|
+
const REMOTE_DEFAULT_SOCKET_TIMEOUT_MS = 5 * 1000;
|
|
9
|
+
var _default = async (url, logger) => {
|
|
10
|
+
const controller = new AbortController();
|
|
11
|
+
const timeout = setTimeout(() => controller.abort(), REMOTE_DEFAULT_SOCKET_TIMEOUT_MS);
|
|
12
|
+
try {
|
|
13
|
+
const result = await fetch(url.toString(), {
|
|
14
|
+
signal: controller.signal
|
|
15
|
+
});
|
|
16
|
+
if (result.ok) {
|
|
17
|
+
const text = await result.text();
|
|
18
|
+
if (url.pathname.endsWith('.json')) {
|
|
19
|
+
return JSON.parse(text);
|
|
20
|
+
}
|
|
21
|
+
return _mashroomUtils.configFileUtils.fromYaml(text);
|
|
22
|
+
} else if (result.status === 404) {
|
|
23
|
+
logger.debug(`Not found: ${url}`);
|
|
24
|
+
return null;
|
|
25
|
+
} else {
|
|
26
|
+
throw new Error(`Status code ${result.status}`);
|
|
27
|
+
}
|
|
28
|
+
} catch (e) {
|
|
29
|
+
if (e.message.includes('aborted')) {
|
|
30
|
+
logger.error(`Fetching from ${url} failed! Timed out after ${REMOTE_DEFAULT_SOCKET_TIMEOUT_MS}sec`);
|
|
31
|
+
} else {
|
|
32
|
+
logger.error(`Fetching from ${url} failed!`, e);
|
|
33
|
+
}
|
|
34
|
+
} finally {
|
|
35
|
+
clearTimeout(timeout);
|
|
36
|
+
}
|
|
37
|
+
return null;
|
|
38
|
+
};
|
|
39
|
+
exports.default = _default;
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _url = require("url");
|
|
8
|
+
var _constants = require("./constants");
|
|
9
|
+
var _fetchRemoteJSONorYAML = _interopRequireDefault(require("./fetchRemoteJSONorYAML"));
|
|
10
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
11
|
+
const OPEN_MICROFRONTEND_VERSION_REGEX = /^(1\.\d+\.\d+)$/;
|
|
12
|
+
var _default = async (packageUrl, scannerHints, description, logger) => {
|
|
13
|
+
const {
|
|
14
|
+
openMicrofrontends,
|
|
15
|
+
info,
|
|
16
|
+
microfrontends
|
|
17
|
+
} = description;
|
|
18
|
+
if (!openMicrofrontends || !OPEN_MICROFRONTEND_VERSION_REGEX.test(openMicrofrontends)) {
|
|
19
|
+
throw new Error(`Unsupported OpenMicrofrontends version: ${openMicrofrontends}`);
|
|
20
|
+
}
|
|
21
|
+
const unsupportedFeatureMessages = [];
|
|
22
|
+
let buildManifestPath;
|
|
23
|
+
microfrontends.forEach(omf => {
|
|
24
|
+
if (omf.assets.buildManifestPath) {
|
|
25
|
+
if (!buildManifestPath) {
|
|
26
|
+
buildManifestPath = omf.assets.buildManifestPath;
|
|
27
|
+
} else if (omf.assets.buildManifestPath !== buildManifestPath) {
|
|
28
|
+
logger.warn(`The build manifests found in OpenMicrofrontends descriptor ${packageUrl} . Choosing: ${buildManifestPath}`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// Check the build manifest for version info (only if no scannerHints.packageVersion is set, which probably the docker image version and has precedence)
|
|
34
|
+
let buildManifestVersion;
|
|
35
|
+
if (!scannerHints.packageVersion && buildManifestPath) {
|
|
36
|
+
try {
|
|
37
|
+
const buildManifest = await (0, _fetchRemoteJSONorYAML.default)(new _url.URL(buildManifestPath, packageUrl), logger);
|
|
38
|
+
if (buildManifest) {
|
|
39
|
+
buildManifestVersion = buildManifest.version || buildManifest.timestamp;
|
|
40
|
+
if (!buildManifestVersion) {
|
|
41
|
+
logger.warn(`The build manifest at ${buildManifestPath} in ${packageUrl} does not contain a version or timestamp!`);
|
|
42
|
+
}
|
|
43
|
+
} else {
|
|
44
|
+
logger.warn(`Couldn't load build manifest ${buildManifestPath} from ${packageUrl}.`);
|
|
45
|
+
}
|
|
46
|
+
} catch (e) {
|
|
47
|
+
logger.warn(`Couldn't load build manifest ${buildManifestPath} from ${packageUrl}: ${e}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
const meta = {
|
|
51
|
+
name: scannerHints.packageName ?? packageUrl.hostname,
|
|
52
|
+
version: scannerHints.packageVersion ?? buildManifestVersion ?? String(Date.now()),
|
|
53
|
+
description: info?.description ?? null,
|
|
54
|
+
homepage: null,
|
|
55
|
+
author: info?.contact?.author ?? null,
|
|
56
|
+
license: null
|
|
57
|
+
};
|
|
58
|
+
const definition = {
|
|
59
|
+
buildManifestPath,
|
|
60
|
+
plugins: []
|
|
61
|
+
};
|
|
62
|
+
microfrontends.forEach(omf => {
|
|
63
|
+
const {
|
|
64
|
+
name,
|
|
65
|
+
rendererFunctionName,
|
|
66
|
+
assets,
|
|
67
|
+
ssr,
|
|
68
|
+
userPermissions,
|
|
69
|
+
apiProxies,
|
|
70
|
+
config,
|
|
71
|
+
annotations
|
|
72
|
+
} = omf;
|
|
73
|
+
let rolePermissions = annotations?.[_constants.ANNOTATION_ROLE_PERMISSIONS];
|
|
74
|
+
let defaultRestrictViewToRoles = annotations?.[_constants.ANNOTATION_DEFAULT_RESTRICT_VIEW_TO_ROLES];
|
|
75
|
+
let proxiesRestrictToRoles = annotations?.[_constants.ANNOTATION_PROXIES_RESTRICT_TO_ROLES];
|
|
76
|
+
let extraMetaInfo = annotations?.[_constants.ANNOTATION_META_INFO];
|
|
77
|
+
if (rolePermissions && typeof rolePermissions !== 'object') {
|
|
78
|
+
logger.warn(`Invalid rolePermissions annotation for OpenMicrofrontend ${name}: ${rolePermissions}`);
|
|
79
|
+
rolePermissions = undefined;
|
|
80
|
+
}
|
|
81
|
+
if (defaultRestrictViewToRoles && !Array.isArray(defaultRestrictViewToRoles)) {
|
|
82
|
+
logger.warn(`Invalid defaultRestrictViewToRoles annotation for OpenMicrofrontend ${name}: ${defaultRestrictViewToRoles}`);
|
|
83
|
+
defaultRestrictViewToRoles = undefined;
|
|
84
|
+
}
|
|
85
|
+
if (proxiesRestrictToRoles && typeof proxiesRestrictToRoles !== 'object') {
|
|
86
|
+
logger.warn(`Invalid proxiesRestrictToRoles annotation for OpenMicrofrontend ${name}: ${proxiesRestrictToRoles}`);
|
|
87
|
+
proxiesRestrictToRoles = undefined;
|
|
88
|
+
}
|
|
89
|
+
if (extraMetaInfo && typeof extraMetaInfo !== 'object') {
|
|
90
|
+
logger.warn(`Invalid extraMetaInfo annotation for OpenMicrofrontend ${name}: ${extraMetaInfo}`);
|
|
91
|
+
extraMetaInfo = undefined;
|
|
92
|
+
}
|
|
93
|
+
let proxies;
|
|
94
|
+
if (typeof apiProxies === 'object') {
|
|
95
|
+
proxies = {};
|
|
96
|
+
Object.keys(apiProxies).forEach(proxyName => {
|
|
97
|
+
const apiProxy = apiProxies[proxyName];
|
|
98
|
+
if (apiProxy.security) {
|
|
99
|
+
unsupportedFeatureMessages.push(`Microfrontend "${name}": apiProxy "${proxyName}" requires security: You have to define an additional "portal-app-config" plugin.`);
|
|
100
|
+
}
|
|
101
|
+
if ('path' in apiProxy) {
|
|
102
|
+
proxies[proxyName] = {
|
|
103
|
+
targetPath: apiProxy.path,
|
|
104
|
+
restrictToRoles: proxiesRestrictToRoles?.[proxyName]
|
|
105
|
+
};
|
|
106
|
+
} else {
|
|
107
|
+
const targets = apiProxy.targets;
|
|
108
|
+
if (targets && Array.isArray(targets)) {
|
|
109
|
+
unsupportedFeatureMessages.push(`Microfrontend "${name}": apiProxy "${proxyName}" has multiple possible targets, choosing: ${targets[0].url}. Define an additional "portal-app-config" plugin to select the correct one.`);
|
|
110
|
+
proxies[proxyName] = {
|
|
111
|
+
targetUri: targets[0].url,
|
|
112
|
+
restrictToRoles: proxiesRestrictToRoles?.[proxyName]
|
|
113
|
+
};
|
|
114
|
+
} else {
|
|
115
|
+
logger.warn(`No targets defined for apiProxy ${proxyName} of OpenMicrofrontend ${name}. Ignoring it.`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
if (ssr?.security) {
|
|
121
|
+
unsupportedFeatureMessages.push(`Microfrontend "${name}": Requires security for the SSR route. This requires an additional "portal-app-config" plugin.`);
|
|
122
|
+
}
|
|
123
|
+
if (userPermissions?.provided) {
|
|
124
|
+
unsupportedFeatureMessages.push(`Microfrontend "${name}": Found a userPermissions provider. This requires an additional "portal-app-config" plugin.`);
|
|
125
|
+
}
|
|
126
|
+
const portalApp2 = {
|
|
127
|
+
name,
|
|
128
|
+
type: 'portal-app2',
|
|
129
|
+
clientBootstrap: rendererFunctionName,
|
|
130
|
+
resources: {
|
|
131
|
+
moduleSystem: assets.js.moduleSystem,
|
|
132
|
+
importMap: assets.js.importMap,
|
|
133
|
+
js: assets.js.initial,
|
|
134
|
+
css: assets.css
|
|
135
|
+
},
|
|
136
|
+
remote: {
|
|
137
|
+
resourcesRoot: assets.basePath ?? '/',
|
|
138
|
+
ssrInitialHtmlPath: ssr?.path
|
|
139
|
+
},
|
|
140
|
+
defaultConfig: {
|
|
141
|
+
title: omf.title,
|
|
142
|
+
description: omf.description,
|
|
143
|
+
proxies,
|
|
144
|
+
rolePermissions,
|
|
145
|
+
defaultRestrictViewToRoles,
|
|
146
|
+
metaInfo: {
|
|
147
|
+
[_constants.META_INFO_FLAG_OPEN_MICROFRONTENDS]: true,
|
|
148
|
+
...(extraMetaInfo || {})
|
|
149
|
+
},
|
|
150
|
+
appConfig: config?.default
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
definition.plugins.push(portalApp2);
|
|
154
|
+
});
|
|
155
|
+
if (unsupportedFeatureMessages.length > 0) {
|
|
156
|
+
logger.warn(`Unsupported features in OpenMicrofrontend descriptor ${packageUrl}:\n\t${unsupportedFeatureMessages.join('\n\t')}`);
|
|
157
|
+
}
|
|
158
|
+
return {
|
|
159
|
+
packageUrl,
|
|
160
|
+
meta,
|
|
161
|
+
definition
|
|
162
|
+
};
|
|
163
|
+
};
|
|
164
|
+
exports.default = _default;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _MashroomOpenMicrofrontendsPluginPackageDefinitionBuilder = _interopRequireDefault(require("./MashroomOpenMicrofrontendsPluginPackageDefinitionBuilder"));
|
|
8
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
9
|
+
const bootstrap = async (pluginName, pluginConfig, pluginContextHolder) => {
|
|
10
|
+
const {
|
|
11
|
+
loggerFactory
|
|
12
|
+
} = pluginContextHolder.getPluginContext();
|
|
13
|
+
return new _MashroomOpenMicrofrontendsPluginPackageDefinitionBuilder.default(loggerFactory);
|
|
14
|
+
};
|
|
15
|
+
var _default = exports.default = bootstrap;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
(()=>{"use strict";const e={get name(){return"OpenMicrofrontends Client Bootstrap Adapter"},shouldAdapt:e=>"hostContext"in e&&e.hostContext.openMicrofrontends,adapt:e=>async(o,t,r)=>{const n=e,s={...t,messageBus:r.messageBus},a=await n(o,s);if(a?.onRemove)return{willBeRemoved:a.onRemove}}},o=window.MashroomPortalServices.portalAppService;o?o.registerClientBootstrapAdapter(e):console.error("Cannot install OpenMicrofrontends Client Bootstrap Adapter: No Mashroom Portal Services found!")})();
|
|
2
|
+
//# sourceMappingURL=openMicrofrontendsClientBootstrapAdapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openMicrofrontendsClientBootstrapAdapter.js","mappings":"mBAQA,MAAMA,EAAmD,CACrD,QAAIC,GACA,MAAM,6CACV,EACAC,YAAYC,GACD,gBAAiBA,GAAmBA,EAAuBC,YAAYC,mBAElFC,MAAMC,GACKC,MAAOC,EAAsBN,EAAgBO,KAChD,MAAMC,EAAWJ,EACXK,EAAe,IACdT,EACHU,WAAYH,EAAeG,YAGzBC,QAAeH,EAASF,EAAsBG,GACpD,GAAIE,GAAQC,SACR,MAAO,CACHC,cAAeF,EAAOC,YAQpCE,EAA8CC,OAAeC,uBAAuBF,iBACtFA,EACAA,EAAiBG,+BAA+BpB,GAEhDqB,QAAQC,MAAM","sources":["webpack://@mashroom/mashroom-portal-open-microfrontends-support/./src/page-enhancement/openMicrofrontendsClientBootstrapAdapter.ts"],"sourcesContent":["import type {\n MashroomPortalAppClientBootstrapAdapter,\n MashroomPortalAppPluginBootstrapFunction,\n MashroomPortalAppService,\n MashroomPortalAppSetup\n} from '@mashroom/mashroom-portal/type-definitions';\nimport type {OpenMicrofrontendsRenderer} from '@open-microfrontends/types/OpenMicrofrontendsRenderer';\n\nconst adapter: MashroomPortalAppClientBootstrapAdapter = {\n get name() {\n return'OpenMicrofrontends Client Bootstrap Adapter';\n },\n shouldAdapt(portalAppSetup: MashroomPortalAppSetup) {\n return 'hostContext' in portalAppSetup && (portalAppSetup as any).hostContext.openMicrofrontends;\n },\n adapt(orginalBootstrap): MashroomPortalAppPluginBootstrapFunction {\n return async (portalAppHostElement, portalAppSetup, clientServices) => {\n const renderer = orginalBootstrap as unknown as OpenMicrofrontendsRenderer<any>;\n const context: any = {\n ...portalAppSetup,\n messageBus: clientServices.messageBus,\n };\n\n const result = await renderer(portalAppHostElement, context);\n if (result?.onRemove) {\n return {\n willBeRemoved: result.onRemove,\n };\n }\n return undefined;\n };\n },\n};\n\nconst portalAppService: MashroomPortalAppService = (window as any).MashroomPortalServices.portalAppService;\nif (portalAppService) {\n portalAppService.registerClientBootstrapAdapter(adapter);\n} else {\n console.error('Cannot install OpenMicrofrontends Client Bootstrap Adapter: No Mashroom Portal Services found!');\n}\n\n"],"names":["adapter","name","shouldAdapt","portalAppSetup","hostContext","openMicrofrontends","adapt","orginalBootstrap","async","portalAppHostElement","clientServices","renderer","context","messageBus","result","onRemove","willBeRemoved","portalAppService","window","MashroomPortalServices","registerClientBootstrapAdapter","console","error"],"sourceRoot":""}
|
package/mashroom.json
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "../../../node_modules/@mashroom/mashroom-json-schemas/schemas/mashroom-plugins.json",
|
|
3
|
+
"devModeBuildScript": "build",
|
|
4
|
+
"plugins": [
|
|
5
|
+
{
|
|
6
|
+
"name": "Mashroom OpenMicrofrontends Support Definition Builder Plugin",
|
|
7
|
+
"type": "plugin-package-definition-builder",
|
|
8
|
+
"bootstrap": "./dist/def-builder/mashroom-bootstrap-package-definition-builder.js",
|
|
9
|
+
"defaultConfig": {
|
|
10
|
+
"order": 10
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"name": "Mashroom OpenMicrofrontends Support App Enhancement Plugin",
|
|
15
|
+
"type": "portal-app-enhancement",
|
|
16
|
+
"bootstrap": "./dist/app-enhancement/mashroom-bootstrap-portal-app-enhancement.js"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"name": "Mashroom OpenMicrofrontends Support Page Enhancement Plugin",
|
|
20
|
+
"type": "portal-page-enhancement",
|
|
21
|
+
"resourcesRoot": "./dist/public",
|
|
22
|
+
"pageResources": {
|
|
23
|
+
"js": [{
|
|
24
|
+
"path": "openMicrofrontendsClientBootstrapAdapter.js",
|
|
25
|
+
"location": "footer"
|
|
26
|
+
}]
|
|
27
|
+
},
|
|
28
|
+
"defaultConfig": {
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
]
|
|
32
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mashroom/mashroom-portal-open-microfrontends-support",
|
|
3
|
+
"description": "Mashroom Portal Open Microfrontends Support",
|
|
4
|
+
"homepage": "https://www.mashroom-server.com",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/nonblocking/mashroom.git"
|
|
8
|
+
},
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"version": "3.0.0-alpha.0",
|
|
11
|
+
"files": [
|
|
12
|
+
"dist/**",
|
|
13
|
+
"mashroom.json"
|
|
14
|
+
],
|
|
15
|
+
"devDependencies": {
|
|
16
|
+
"@mashroom/mashroom": "3.0.0-alpha.0",
|
|
17
|
+
"@mashroom/mashroom-utils": "3.0.0-alpha.0",
|
|
18
|
+
"@open-microfrontends/types": "^1.0.0"
|
|
19
|
+
},
|
|
20
|
+
"jest": {
|
|
21
|
+
"testEnvironment": "node",
|
|
22
|
+
"roots": [
|
|
23
|
+
"<rootDir>/test"
|
|
24
|
+
],
|
|
25
|
+
"testRegex": "(\\.(test|spec))\\.ts",
|
|
26
|
+
"transform": {
|
|
27
|
+
"^.+\\.ts$": "ts-jest"
|
|
28
|
+
},
|
|
29
|
+
"reporters": [
|
|
30
|
+
"default",
|
|
31
|
+
"jest-junit"
|
|
32
|
+
]
|
|
33
|
+
},
|
|
34
|
+
"jest-junit": {
|
|
35
|
+
"outputDirectory": "./test-reports"
|
|
36
|
+
},
|
|
37
|
+
"scripts": {
|
|
38
|
+
"lint": "eslint --fix",
|
|
39
|
+
"type-check": "tsc --noEmit",
|
|
40
|
+
"test": "jest",
|
|
41
|
+
"build": "babel src/def-builder -d dist/def-builder --extensions \".ts\" && babel src/app-enhancement -d dist/app-enhancement --extensions \".ts\" && webpack --mode production"
|
|
42
|
+
}
|
|
43
|
+
}
|