@elliemae/pui-app-bridge 2.9.4 → 2.16.6
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/cjs/appBridge.js +380 -93
- package/dist/cjs/appRegistry.js +136 -0
- package/dist/cjs/config/app.js +15 -2
- package/dist/cjs/config/microFE.js +3 -3
- package/dist/cjs/eventManager.js +16 -16
- package/dist/cjs/frame.html +2 -2
- package/dist/cjs/frame.js +39 -14
- package/dist/cjs/index.html +1 -1
- package/dist/cjs/index.js +3 -3
- package/dist/cjs/loaders/script.js +5 -5
- package/dist/cjs/loaders/style.js +1 -0
- package/dist/cjs/microfeHost.js +51 -31
- package/dist/cjs/tests/flights/23.1/app.checksum1.js +25 -24
- package/dist/cjs/tests/flights/latest/app.checksum.js +25 -24
- package/dist/cjs/tests/hotels/23.1/app.checksum.js +27 -24
- package/dist/cjs/tests/hotels/latest/app.checksum.js +27 -24
- package/dist/cjs/tests/loan/latest/index.js +49 -57
- package/dist/cjs/tests/scriptingObjects/analytics.js +7 -7
- package/dist/cjs/tests/scriptingObjects/appraisalServiceModule.js +8 -8
- package/dist/cjs/tests/scriptingObjects/global.js +1 -2
- package/dist/cjs/tests/task/latest/index.dev.js +29 -28
- package/dist/cjs/tests/task/latest/index.js +29 -28
- package/dist/cjs/tests/travelhub/23.1/app.checksum.js +24 -26
- package/dist/cjs/tests/travelhub/23.1/landing.checksum1.js +5 -7
- package/dist/cjs/utils.js +31 -1
- package/dist/esm/appBridge.js +390 -95
- package/dist/esm/appRegistry.js +116 -0
- package/dist/esm/config/app.js +15 -2
- package/dist/esm/config/microFE.js +3 -3
- package/dist/esm/eventManager.js +16 -16
- package/dist/esm/frame.html +2 -2
- package/dist/esm/frame.js +29 -14
- package/dist/esm/index.html +1 -1
- package/dist/esm/loaders/script.js +5 -5
- package/dist/esm/loaders/style.js +1 -0
- package/dist/esm/microfeHost.js +55 -31
- package/dist/esm/tests/flights/23.1/app.checksum1.js +25 -24
- package/dist/esm/tests/flights/latest/app.checksum.js +25 -24
- package/dist/esm/tests/hotels/23.1/app.checksum.js +27 -24
- package/dist/esm/tests/hotels/latest/app.checksum.js +27 -24
- package/dist/esm/tests/loan/latest/index.js +49 -57
- package/dist/esm/tests/scriptingObjects/analytics.js +7 -7
- package/dist/esm/tests/scriptingObjects/appraisalServiceModule.js +8 -8
- package/dist/esm/tests/scriptingObjects/global.js +1 -2
- package/dist/esm/tests/task/latest/index.dev.js +29 -28
- package/dist/esm/tests/task/latest/index.js +29 -28
- package/dist/esm/tests/travelhub/23.1/app.checksum.js +24 -26
- package/dist/esm/tests/travelhub/23.1/landing.checksum1.js +5 -7
- package/dist/esm/utils.js +31 -1
- package/dist/public/assets/frame.671d9de68be598da64ca.html +47 -0
- package/dist/public/frame.html +1 -1
- package/dist/public/index.html +1 -1
- package/dist/public/js/emuiAppBridge.40c8880c94dbc97b49fd.js +51 -0
- package/dist/public/js/emuiAppBridge.40c8880c94dbc97b49fd.js.br +0 -0
- package/dist/public/js/emuiAppBridge.40c8880c94dbc97b49fd.js.gz +0 -0
- package/dist/public/js/emuiAppBridge.40c8880c94dbc97b49fd.js.map +1 -0
- package/dist/public/loan-object.js +1 -1
- package/dist/public/loan-object.js.br +0 -0
- package/dist/public/loan-object.js.gz +0 -0
- package/dist/public/loan-object.js.map +1 -1
- package/dist/types/lib/appBridge.d.ts +38 -28
- package/dist/types/lib/appRegistry.d.ts +41 -0
- package/dist/types/lib/eventManager.d.ts +4 -4
- package/dist/types/lib/frame.d.ts +45 -4
- package/dist/types/lib/index.d.ts +3 -3
- package/dist/types/lib/loaders/script.d.ts +2 -1
- package/dist/types/lib/microfeHost.d.ts +15 -25
- package/dist/types/lib/tests/flights/23.1/app.checksum1.d.ts +7 -0
- package/dist/types/lib/tests/flights/latest/app.checksum.d.ts +7 -0
- package/dist/types/lib/tests/hotels/23.1/app.checksum.d.ts +7 -0
- package/dist/types/lib/tests/hotels/latest/app.checksum.d.ts +7 -0
- package/dist/types/lib/tests/loan/latest/index.d.ts +11 -0
- package/dist/types/lib/tests/scriptingObjects/analytics.d.ts +3 -3
- package/dist/types/lib/tests/scriptingObjects/appraisalServiceModule.d.ts +2 -1
- package/dist/types/lib/tests/task/latest/index.d.ts +10 -0
- package/dist/types/lib/tests/task/latest/index.dev.d.ts +10 -0
- package/dist/types/lib/tests/travelhub/23.1/app.checksum.d.ts +7 -0
- package/dist/types/lib/tests/travelhub/23.1/landing.checksum1.d.ts +2 -0
- package/dist/types/lib/typings/appInfo.d.ts +1 -0
- package/dist/types/lib/typings/common.d.ts +0 -66
- package/dist/types/lib/typings/guest.d.ts +10 -3
- package/dist/types/lib/typings/host.d.ts +32 -32
- package/dist/types/lib/typings/window.d.ts +6 -1
- package/dist/types/lib/utils.d.ts +7 -0
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/dist/umd/671d9de68be598da64ca.html +47 -0
- package/dist/umd/frame.html +1 -1
- package/dist/umd/index.html +1 -1
- package/dist/umd/index.js +35 -9
- package/dist/umd/index.js.br +0 -0
- package/dist/umd/index.js.gz +0 -0
- package/dist/umd/index.js.map +1 -1
- package/dist/umd/loan-object.js +1 -1
- package/dist/umd/loan-object.js.br +0 -0
- package/dist/umd/loan-object.js.gz +0 -0
- package/dist/umd/loan-object.js.map +1 -1
- package/package.json +12 -12
- package/dist/public/js/emuiAppBridge.34df989fae2296115611.js +0 -25
- package/dist/public/js/emuiAppBridge.34df989fae2296115611.js.br +0 -0
- package/dist/public/js/emuiAppBridge.34df989fae2296115611.js.gz +0 -0
- package/dist/public/js/emuiAppBridge.34df989fae2296115611.js.map +0 -1
- package/dist/types/lib/tests/pubsubAPI.test.d.ts +0 -1
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
class CAppRegistry {
|
|
2
|
+
constructor() {
|
|
3
|
+
if (!window.emui) {
|
|
4
|
+
window.emui = {};
|
|
5
|
+
}
|
|
6
|
+
window.emui.registerApp = this.#registerApp;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* global method for guest apps to register themselves with parent
|
|
10
|
+
* @param param0
|
|
11
|
+
* @param param0.appId
|
|
12
|
+
* @param param0.app
|
|
13
|
+
*/
|
|
14
|
+
#registerApp = ({ appId, app }) => {
|
|
15
|
+
if (!app?.uuid) throw new Error("application uuid is required");
|
|
16
|
+
window.emui[appId] = window.emui[appId] || [];
|
|
17
|
+
if (Array.isArray(window.emui[appId])) {
|
|
18
|
+
const appIndex = window.emui[appId].findIndex(
|
|
19
|
+
(eApp) => eApp.uuid === app.uuid
|
|
20
|
+
);
|
|
21
|
+
if (appIndex > -1) {
|
|
22
|
+
window.emui[appId][appIndex] = app;
|
|
23
|
+
} else {
|
|
24
|
+
window.emui[appId].push(app);
|
|
25
|
+
}
|
|
26
|
+
} else {
|
|
27
|
+
let existingApp = window.emui[appId];
|
|
28
|
+
if (existingApp?.uuid === app.uuid) {
|
|
29
|
+
existingApp = { ...existingApp, ...app };
|
|
30
|
+
window.emui[appId] = [existingApp];
|
|
31
|
+
} else if (typeof existingApp.init === void 0) {
|
|
32
|
+
window.emui[appId] = [{ ...existingApp, ...app }];
|
|
33
|
+
} else {
|
|
34
|
+
window.emui[appId] = [window.emui[appId], app];
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* get micro app guest from window object
|
|
40
|
+
* @param param0 id and uuid
|
|
41
|
+
* @param param0.id app id
|
|
42
|
+
* @param param0.uuid unique instance id
|
|
43
|
+
* @param param0.instanceId
|
|
44
|
+
* @returns micro app guest
|
|
45
|
+
*/
|
|
46
|
+
get = ({ id, instanceId }) => {
|
|
47
|
+
const apps = window.emui?.[id];
|
|
48
|
+
if (Array.isArray(apps)) {
|
|
49
|
+
const app = apps.find((eApp) => eApp.uuid === instanceId);
|
|
50
|
+
return app ?? null;
|
|
51
|
+
}
|
|
52
|
+
if (apps?.uuid === instanceId) {
|
|
53
|
+
return apps;
|
|
54
|
+
}
|
|
55
|
+
return null;
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* add app to global emui window variable
|
|
59
|
+
* @param id.id
|
|
60
|
+
* @param id app id
|
|
61
|
+
* @param instanceId unique instance id
|
|
62
|
+
* @param id.instanceId
|
|
63
|
+
* @param id.documentEle
|
|
64
|
+
*/
|
|
65
|
+
add = ({
|
|
66
|
+
id,
|
|
67
|
+
instanceId,
|
|
68
|
+
documentEle
|
|
69
|
+
}) => {
|
|
70
|
+
const newAppInstance = {
|
|
71
|
+
uuid: instanceId,
|
|
72
|
+
init: null,
|
|
73
|
+
mount: null,
|
|
74
|
+
unmount: null
|
|
75
|
+
};
|
|
76
|
+
const appInstances = window.emui[id];
|
|
77
|
+
if (appInstances) {
|
|
78
|
+
if (!instanceId) {
|
|
79
|
+
throw new Error(
|
|
80
|
+
`Application ${id} is already loaded. uuid is required to load multiple instances of the same app`
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
if (Array.isArray(appInstances)) {
|
|
84
|
+
appInstances.push(newAppInstance);
|
|
85
|
+
} else {
|
|
86
|
+
window.emui[id] = [appInstances, newAppInstance];
|
|
87
|
+
}
|
|
88
|
+
} else {
|
|
89
|
+
window.emui[id] = [newAppInstance];
|
|
90
|
+
}
|
|
91
|
+
if (documentEle.defaultView) {
|
|
92
|
+
documentEle.defaultView.emui = documentEle.defaultView.emui ?? {};
|
|
93
|
+
documentEle.defaultView.emui.uuid = instanceId;
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
/**
|
|
97
|
+
* delete app from global emui window variable
|
|
98
|
+
* @param id.id app id
|
|
99
|
+
* @param id.instanceId unique instance id
|
|
100
|
+
* @param id.id.id
|
|
101
|
+
* @param id.id.instanceId
|
|
102
|
+
*/
|
|
103
|
+
delete = ({ id, instanceId }) => {
|
|
104
|
+
if (Array.isArray(window.emui[id])) {
|
|
105
|
+
const index = window.emui[id].findIndex(
|
|
106
|
+
(app) => app.uuid === instanceId
|
|
107
|
+
);
|
|
108
|
+
if (index > -1) window.emui[id].splice(index, 1);
|
|
109
|
+
} else {
|
|
110
|
+
delete window.emui[id];
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
export {
|
|
115
|
+
CAppRegistry
|
|
116
|
+
};
|
package/dist/esm/config/app.js
CHANGED
|
@@ -40,14 +40,27 @@ class CAppConfig {
|
|
|
40
40
|
* @returns true if key exists
|
|
41
41
|
*/
|
|
42
42
|
has = (key = "") => lodashHas(this.#gAppConfig, key);
|
|
43
|
+
/**
|
|
44
|
+
* add version to the base url
|
|
45
|
+
* @returns versioned base url
|
|
46
|
+
*/
|
|
47
|
+
#getVersionedBaseUrl = () => {
|
|
48
|
+
const regex = /(?:\/)(\d+\.\d+|latest)(?:\/?)?$/;
|
|
49
|
+
if (!regex.test(this.#baseUrl)) {
|
|
50
|
+
const majorMinorVersion = this.#version.match(/^(?:\d+\.\d+)*/g);
|
|
51
|
+
return appendTrailingSlash(
|
|
52
|
+
`${this.#baseUrl}${majorMinorVersion?.[0] || LATEST_VERSION}`
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
return this.#baseUrl;
|
|
56
|
+
};
|
|
43
57
|
/**
|
|
44
58
|
* load application configuration from the given asset path
|
|
45
59
|
* @param assetPath url path to load app config from
|
|
46
60
|
* @param configUrl
|
|
47
61
|
*/
|
|
48
62
|
load = async (configUrl) => {
|
|
49
|
-
const
|
|
50
|
-
const appConfigUrl = configUrl ?? `${this.#baseUrl}${majorMinorVersion && majorMinorVersion[0] || LATEST_VERSION}/app.config.json`;
|
|
63
|
+
const appConfigUrl = configUrl ?? `${this.#getVersionedBaseUrl()}app.config.json`;
|
|
51
64
|
const response = await fetch(appConfigUrl);
|
|
52
65
|
if (response.ok) {
|
|
53
66
|
try {
|
|
@@ -69,7 +69,8 @@ const getConfig = ({
|
|
|
69
69
|
name: id,
|
|
70
70
|
mode: "production",
|
|
71
71
|
manifestPath: "./{SYSTEM_VERSION}/",
|
|
72
|
-
securityContext: SecurityContext.USER
|
|
72
|
+
securityContext: SecurityContext.USER,
|
|
73
|
+
isJsModule: true
|
|
73
74
|
},
|
|
74
75
|
config,
|
|
75
76
|
envConfig
|
|
@@ -90,8 +91,7 @@ class CMicroFEConfig {
|
|
|
90
91
|
appConfig
|
|
91
92
|
}) => {
|
|
92
93
|
const mfeAppsFromConfig = appConfig.get(CONFIG_KEY);
|
|
93
|
-
if (!mfeAppsFromConfig)
|
|
94
|
-
throw new Error("app.config.json is missing microFrontendApps section");
|
|
94
|
+
if (!mfeAppsFromConfig) return;
|
|
95
95
|
this.#microFrontendApps = Object.keys(mfeAppsFromConfig).map(
|
|
96
96
|
(appId) => {
|
|
97
97
|
validate(appId, mfeAppsFromConfig[appId]);
|
package/dist/esm/eventManager.js
CHANGED
|
@@ -70,17 +70,19 @@ class EventManager {
|
|
|
70
70
|
};
|
|
71
71
|
/**
|
|
72
72
|
* dispatch an event
|
|
73
|
+
* @param scriptingObject
|
|
73
74
|
* @param {DispatchEventParam<EventId, Params>} param - parameters for dispatching an event
|
|
74
75
|
*/
|
|
75
|
-
dispatchEvent = async (param) => {
|
|
76
|
+
dispatchEvent = async (scriptingObject, param) => {
|
|
76
77
|
const {
|
|
77
|
-
event: { id, name
|
|
78
|
+
event: { id, name },
|
|
78
79
|
eventParams,
|
|
79
|
-
|
|
80
|
+
eventOptions
|
|
80
81
|
} = param;
|
|
82
|
+
const { timeout } = eventOptions ?? {};
|
|
81
83
|
if (!id) throw new Error("Event Id is required");
|
|
82
84
|
const listeners = this.#listeners.get(id) || [];
|
|
83
|
-
if (!
|
|
85
|
+
if (!timeout || timeout <= 0) {
|
|
84
86
|
this.#emitEvent({
|
|
85
87
|
eventName: name,
|
|
86
88
|
scriptingObject,
|
|
@@ -94,7 +96,7 @@ class EventManager {
|
|
|
94
96
|
eventName: name,
|
|
95
97
|
scriptingObject,
|
|
96
98
|
eventParams,
|
|
97
|
-
feedbackWaitTime
|
|
99
|
+
feedbackWaitTime: timeout
|
|
98
100
|
});
|
|
99
101
|
};
|
|
100
102
|
/**
|
|
@@ -102,30 +104,28 @@ class EventManager {
|
|
|
102
104
|
* @param {SubscribeParam<EventId, AppEvents[EventId]>} param - parameters for subscribing to an event
|
|
103
105
|
*/
|
|
104
106
|
subscribe = (param) => {
|
|
105
|
-
const { eventId,
|
|
107
|
+
const { eventId, callback } = param;
|
|
106
108
|
if (!eventId) throw new Error("eventId is required");
|
|
107
|
-
if (!
|
|
109
|
+
if (!callback) throw new Error("Callback is required");
|
|
108
110
|
const listeners = this.#listeners.get(eventId) || [];
|
|
109
|
-
const
|
|
111
|
+
const token = uuidv4();
|
|
110
112
|
listeners.push({
|
|
111
|
-
|
|
112
|
-
callback
|
|
113
|
+
token,
|
|
114
|
+
callback
|
|
113
115
|
});
|
|
114
116
|
this.#listeners.set(eventId, listeners);
|
|
115
|
-
return
|
|
117
|
+
return token;
|
|
116
118
|
};
|
|
117
119
|
/**
|
|
118
120
|
* Unsubscribe from an event
|
|
119
121
|
* @param {UnsubscribeParam<EventId>} param - parameters for unsubscribing from an event
|
|
120
122
|
*/
|
|
121
123
|
unsubscribe = (param) => {
|
|
122
|
-
const { eventId,
|
|
124
|
+
const { eventId, token } = param;
|
|
123
125
|
if (!eventId) throw new Error("eventId id is required");
|
|
124
|
-
if (
|
|
126
|
+
if (token) {
|
|
125
127
|
const listeners = this.#listeners.get(eventId) || [];
|
|
126
|
-
const index = listeners.findIndex(
|
|
127
|
-
(listener) => listener.subscriptionId === subscriptionId
|
|
128
|
-
);
|
|
128
|
+
const index = listeners.findIndex((listener) => listener.token === token);
|
|
129
129
|
if (index > -1) {
|
|
130
130
|
listeners.splice(index, 1);
|
|
131
131
|
this.#listeners.set(eventId, listeners);
|
package/dist/esm/frame.html
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<meta name="mobile-web-app-capable" content="yes" />
|
|
7
7
|
<link rel="icon" href="/favicon.ico" />
|
|
8
8
|
<title>Application</title>
|
|
9
|
-
<script>
|
|
9
|
+
<script nonce="__CSP_NONCE__">
|
|
10
10
|
(function (i, s, o, g, r, a, m) {
|
|
11
11
|
i['GoogleAnalyticsObject'] = r;
|
|
12
12
|
(i[r] =
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
'ga',
|
|
28
28
|
);
|
|
29
29
|
</script>
|
|
30
|
-
<style>
|
|
30
|
+
<style nonce="__CSP_NONCE__">
|
|
31
31
|
.full-width {
|
|
32
32
|
width: 100%;
|
|
33
33
|
}
|
package/dist/esm/frame.js
CHANGED
|
@@ -1,23 +1,35 @@
|
|
|
1
|
-
|
|
1
|
+
import frameHtml from "./frame.html?resource";
|
|
2
2
|
const FRAME_APP_CONTAINER_ID_PREFIX = "pui-app-container-";
|
|
3
|
-
const create = (
|
|
3
|
+
const create = ({
|
|
4
|
+
id,
|
|
5
|
+
instanceId,
|
|
6
|
+
manifestPath,
|
|
7
|
+
hostUrl,
|
|
8
|
+
options
|
|
9
|
+
}) => new Promise((resolve, reject) => {
|
|
4
10
|
const iframeContainer = document.createElement("div");
|
|
5
11
|
iframeContainer.setAttribute(
|
|
6
12
|
"style",
|
|
7
13
|
"display: flex;width: 100%;height: 100%;flex-direction: column;overflow: hidden;"
|
|
8
14
|
);
|
|
9
15
|
const frame = document.createElement("iframe");
|
|
10
|
-
frame.setAttribute("id",
|
|
16
|
+
frame.setAttribute("id", instanceId);
|
|
17
|
+
frame.setAttribute("data-testid", id);
|
|
11
18
|
frame.setAttribute("title", options.title);
|
|
12
19
|
frame.setAttribute("allowfullscreen", "true");
|
|
13
20
|
frame.setAttribute("allowtransparency", "true");
|
|
14
|
-
|
|
21
|
+
if (options.permissionPolicy)
|
|
22
|
+
frame.setAttribute("allow", options.permissionPolicy);
|
|
15
23
|
if (options.sandbox) frame.setAttribute("sandbox", options.sandbox);
|
|
16
24
|
frame.setAttribute(
|
|
17
25
|
"style",
|
|
18
26
|
options.style ?? "flex-grow: 1;border: none;margin: 0;padding: 0;display: block;min-width: 100%;height: 100%;"
|
|
19
27
|
);
|
|
20
|
-
frame.setAttribute(
|
|
28
|
+
frame.setAttribute(
|
|
29
|
+
"src",
|
|
30
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
31
|
+
options.src ?? (frameHtml.default ?? frameHtml)
|
|
32
|
+
);
|
|
21
33
|
frame.addEventListener("load", () => {
|
|
22
34
|
if (!frame.contentDocument) {
|
|
23
35
|
reject(new Error("Frame content window is null"));
|
|
@@ -26,7 +38,15 @@ const create = (appId, options) => new Promise((resolve, reject) => {
|
|
|
26
38
|
const documentEle = frame.contentDocument;
|
|
27
39
|
const ele = documentEle.getElementById(FRAME_APP_CONTAINER_ID_PREFIX);
|
|
28
40
|
if (ele) {
|
|
29
|
-
ele.id = `${ele.id}${
|
|
41
|
+
ele.id = `${ele.id}${id}`;
|
|
42
|
+
}
|
|
43
|
+
let baseTag = documentEle.getElementsByTagName("base")?.[0];
|
|
44
|
+
if (baseTag) {
|
|
45
|
+
baseTag.href = new URL(manifestPath, hostUrl).href;
|
|
46
|
+
} else {
|
|
47
|
+
baseTag = documentEle.createElement("base");
|
|
48
|
+
baseTag.href = new URL(manifestPath, hostUrl).href;
|
|
49
|
+
documentEle.getElementsByTagName("head")[0].appendChild(baseTag);
|
|
30
50
|
}
|
|
31
51
|
resolve(frame);
|
|
32
52
|
});
|
|
@@ -35,13 +55,9 @@ const create = (appId, options) => new Promise((resolve, reject) => {
|
|
|
35
55
|
const parentElement = document.getElementById(containerId ?? "") ?? document.body;
|
|
36
56
|
parentElement.appendChild(iframeContainer);
|
|
37
57
|
});
|
|
38
|
-
const get = (
|
|
39
|
-
|
|
40
|
-
);
|
|
41
|
-
const remove = (appId) => {
|
|
42
|
-
const frameEle = document.getElementById(
|
|
43
|
-
`${FRAME_CONTAINER_ID_PREFIX}${appId}`
|
|
44
|
-
);
|
|
58
|
+
const get = (instanceId) => document.getElementById(instanceId);
|
|
59
|
+
const remove = (instanceId) => {
|
|
60
|
+
const frameEle = get(instanceId);
|
|
45
61
|
if (frameEle) {
|
|
46
62
|
frameEle.remove();
|
|
47
63
|
}
|
|
@@ -53,6 +69,5 @@ const Frame = {
|
|
|
53
69
|
};
|
|
54
70
|
export {
|
|
55
71
|
FRAME_APP_CONTAINER_ID_PREFIX,
|
|
56
|
-
FRAME_CONTAINER_ID_PREFIX,
|
|
57
72
|
Frame
|
|
58
73
|
};
|
package/dist/esm/index.html
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
7
|
<title>Host</title>
|
|
8
8
|
<script src="https://cdn.tailwindcss.com?plugins=forms"></script>
|
|
9
|
-
<script src="https://
|
|
9
|
+
<script src="https://cdn.qa1.ice.com/pui-diagnostics@3" ></script>
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
|
12
12
|
<header class="bg-indigo-300 h-10 flex place-items-center">
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { removeDoubleSlash, isJSDOM } from "../utils.js";
|
|
2
2
|
const APP_SCRIPT_ID_PREFIX = "ice-script-";
|
|
3
|
-
const HEAD_SCRIPTS = /(?:emuiDiagnostics|global|global-prod|emuiUserMonitoring)(?:..*)?.js/;
|
|
4
|
-
const isDeferEligible = (scriptSrc) => !HEAD_SCRIPTS.test(scriptSrc);
|
|
5
3
|
class ScriptLoader {
|
|
6
4
|
#logger;
|
|
7
5
|
constructor(logger) {
|
|
@@ -12,12 +10,16 @@ class ScriptLoader {
|
|
|
12
10
|
hostUrl,
|
|
13
11
|
documentEle,
|
|
14
12
|
fileName,
|
|
15
|
-
index
|
|
13
|
+
index,
|
|
14
|
+
isJsModule = true
|
|
16
15
|
}) => new Promise((resolve, reject) => {
|
|
17
16
|
const url = new URL(fileName, hostUrl);
|
|
18
17
|
const ele = documentEle.createElement("script");
|
|
19
18
|
ele.id = `${APP_SCRIPT_ID_PREFIX}${name.toLowerCase()}-${index}`;
|
|
20
19
|
ele.src = removeDoubleSlash(url.href);
|
|
20
|
+
ele.nonce = "__CSP_NONCE__";
|
|
21
|
+
if (!isJSDOM() && isJsModule) ele.type = "module";
|
|
22
|
+
else ele.async = false;
|
|
21
23
|
ele.onload = resolve.bind(null, ele.id);
|
|
22
24
|
ele.onerror = (err) => {
|
|
23
25
|
reject(
|
|
@@ -26,8 +28,6 @@ class ScriptLoader {
|
|
|
26
28
|
})
|
|
27
29
|
);
|
|
28
30
|
};
|
|
29
|
-
ele.async = false;
|
|
30
|
-
if (!isJSDOM() && isDeferEligible(ele.src)) ele.defer = true;
|
|
31
31
|
documentEle.head.appendChild(ele);
|
|
32
32
|
});
|
|
33
33
|
remove = (elementId = "", documentEle = document) => new Promise((resolve) => {
|
|
@@ -14,6 +14,7 @@ class StyleLoader {
|
|
|
14
14
|
}) => new Promise((resolve, reject) => {
|
|
15
15
|
const ele = documentEle.createElement("link");
|
|
16
16
|
ele.id = `${APP_STYLE_ID_PREFIX}${name.toLowerCase()}-${index}`;
|
|
17
|
+
ele.nonce = "__CSP_NONCE__";
|
|
17
18
|
ele.rel = "stylesheet";
|
|
18
19
|
const url = new URL(fileName, hostUrl);
|
|
19
20
|
ele.href = removeDoubleSlash(url.href);
|
package/dist/esm/microfeHost.js
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
Event,
|
|
3
|
+
isPublicFunction,
|
|
4
|
+
ScriptingObjectProxy
|
|
5
|
+
} from "@elliemae/microfe-common";
|
|
3
6
|
import { LATEST_VERSION } from "./constant.js";
|
|
4
7
|
class CMicroFEHost {
|
|
5
8
|
#logger;
|
|
9
|
+
/**
|
|
10
|
+
* unique id of the iframe container
|
|
11
|
+
*/
|
|
12
|
+
#containerId;
|
|
6
13
|
#guest;
|
|
7
14
|
#version;
|
|
8
15
|
#soManager;
|
|
@@ -14,16 +21,11 @@ class CMicroFEHost {
|
|
|
14
21
|
constructor(params) {
|
|
15
22
|
this.#guest = params.guest;
|
|
16
23
|
this.#logger = params.logger;
|
|
24
|
+
this.#containerId = params.containerId;
|
|
17
25
|
this.#version = params?.version || LATEST_VERSION;
|
|
18
26
|
this.#soManager = params.soManager;
|
|
19
27
|
this.#eventManager = params.eventManager;
|
|
20
28
|
}
|
|
21
|
-
/**
|
|
22
|
-
* add listener to the scripting object event
|
|
23
|
-
* @param {SubscribeParam<EventId, EventListener>} params - parameters to add event listener
|
|
24
|
-
* @returns subscription id
|
|
25
|
-
*/
|
|
26
|
-
addEventListener = (params) => this.#eventManager.subscribe(params);
|
|
27
29
|
/**
|
|
28
30
|
* application release version
|
|
29
31
|
* @returns release version
|
|
@@ -37,43 +39,65 @@ class CMicroFEHost {
|
|
|
37
39
|
* @param objectId
|
|
38
40
|
* @returns scripting object reference
|
|
39
41
|
*/
|
|
40
|
-
getObject = (objectId) =>
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
42
|
+
getObject = (objectId) => {
|
|
43
|
+
const so = this.#soManager.getObject(objectId, this.#guest);
|
|
44
|
+
if (so) {
|
|
45
|
+
const proxy = new ScriptingObjectProxy(so.id, so.objectType);
|
|
46
|
+
Object.keys(so).forEach((propName) => {
|
|
47
|
+
const propValue = so[propName];
|
|
48
|
+
if (propValue instanceof Event) {
|
|
49
|
+
Object.defineProperty(proxy, propName, {
|
|
50
|
+
value: new Event({
|
|
51
|
+
name: propName,
|
|
52
|
+
objectId: so.id
|
|
53
|
+
}),
|
|
54
|
+
enumerable: true
|
|
55
|
+
});
|
|
56
|
+
} else if (isPublicFunction(propValue, propName)) {
|
|
57
|
+
Object.defineProperty(proxy, propName, {
|
|
58
|
+
value: (...args) => {
|
|
59
|
+
Object.defineProperty(propValue, "callContext", {
|
|
60
|
+
value: { guest: this.#guest },
|
|
61
|
+
configurable: true,
|
|
62
|
+
enumerable: true,
|
|
63
|
+
writable: true
|
|
64
|
+
});
|
|
65
|
+
return so[propName](
|
|
66
|
+
...args
|
|
67
|
+
);
|
|
68
|
+
},
|
|
69
|
+
enumerable: true
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
return Promise.resolve(proxy);
|
|
74
|
+
}
|
|
75
|
+
return Promise.resolve(null);
|
|
47
76
|
};
|
|
48
77
|
/**
|
|
49
78
|
* set the size of the guest application iframe window
|
|
50
79
|
* @param {AppWindowSize} appSize window size of the application
|
|
51
80
|
*/
|
|
52
81
|
setAppWindowSize = (appSize) => {
|
|
53
|
-
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
);
|
|
82
|
+
if (!this.#containerId) return;
|
|
83
|
+
const { size } = appSize;
|
|
84
|
+
const frameEle = document.getElementById(this.#containerId);
|
|
57
85
|
if (frameEle) {
|
|
58
86
|
frameEle.style.height = `${size.height}px`;
|
|
59
87
|
}
|
|
60
88
|
};
|
|
61
|
-
// deprecated legacy eventing methods (to be removed)
|
|
62
89
|
/**
|
|
63
|
-
*
|
|
64
|
-
* @param
|
|
65
|
-
* @
|
|
66
|
-
* @returns token to be used to unsubscribe
|
|
90
|
+
* add listener to the scripting object event
|
|
91
|
+
* @param {SubscribeParam<EventId, EventListener>} params - parameters to add event listener
|
|
92
|
+
* @returns subscription id
|
|
67
93
|
*/
|
|
68
|
-
|
|
69
|
-
subscribe = (eventId, listener) => subscribe(eventId, listener);
|
|
94
|
+
subscribe = (params) => this.#eventManager.subscribe(params);
|
|
70
95
|
/**
|
|
71
|
-
*
|
|
72
|
-
* @param
|
|
73
|
-
* @param eventId unique id of the event. The format is [scripting object name].[event name]
|
|
96
|
+
* removes listener from the scripting object event
|
|
97
|
+
* @param {UnsubscribeParam<EventId>} params - parameters to remove event listener
|
|
74
98
|
*/
|
|
75
|
-
unsubscribe = (
|
|
76
|
-
unsubscribe(
|
|
99
|
+
unsubscribe = (params) => {
|
|
100
|
+
this.#eventManager.unsubscribe(params);
|
|
77
101
|
};
|
|
78
102
|
}
|
|
79
103
|
export {
|
|
@@ -1,27 +1,26 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
browserWindow.emui[appId].init = async (options) => {
|
|
1
|
+
const appId = "flights";
|
|
2
|
+
const appName = "Flights App";
|
|
3
|
+
const getWindow = () => {
|
|
4
|
+
try {
|
|
5
|
+
window.parent.document;
|
|
6
|
+
return window.parent;
|
|
7
|
+
} catch (err) {
|
|
8
|
+
return window;
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
let host = null;
|
|
12
|
+
let parentHistory = null;
|
|
13
|
+
let logger = null;
|
|
14
|
+
window.emui = window.emui || { uuid: crypto.randomUUID() };
|
|
15
|
+
window.emui.app = {
|
|
16
|
+
uuid: window.emui.uuid,
|
|
17
|
+
init: async (options) => {
|
|
19
18
|
host = options.host;
|
|
20
19
|
parentHistory = options.history;
|
|
21
20
|
logger = options.logger;
|
|
22
21
|
return Promise.resolve();
|
|
23
|
-
}
|
|
24
|
-
|
|
22
|
+
},
|
|
23
|
+
mount: async () => {
|
|
25
24
|
const mainElement = document.createElement("main");
|
|
26
25
|
const pageHeaderEle = document.createElement("h1");
|
|
27
26
|
pageHeaderEle.textContent = appName;
|
|
@@ -33,10 +32,12 @@
|
|
|
33
32
|
mainElement.appendChild(versionEle);
|
|
34
33
|
document.body.appendChild(mainElement);
|
|
35
34
|
return Promise.resolve();
|
|
36
|
-
}
|
|
37
|
-
|
|
35
|
+
},
|
|
36
|
+
unmount: () => {
|
|
38
37
|
const mainEle = document.getElementsByTagName("main")[0];
|
|
39
38
|
if (mainEle) mainEle.remove();
|
|
40
39
|
return Promise.resolve();
|
|
41
|
-
}
|
|
42
|
-
}
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
const browserWindow = getWindow();
|
|
43
|
+
browserWindow.emui?.registerApp?.({ appId, app: window.emui.app });
|
|
@@ -1,27 +1,26 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
browserWindow.emui[appId].init = async (options) => {
|
|
1
|
+
const appId = "flights";
|
|
2
|
+
const appName = "Flights App";
|
|
3
|
+
const getWindow = () => {
|
|
4
|
+
try {
|
|
5
|
+
window.parent.document;
|
|
6
|
+
return window.parent;
|
|
7
|
+
} catch (err) {
|
|
8
|
+
return window;
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
let host = null;
|
|
12
|
+
let parentHistory = null;
|
|
13
|
+
let logger = null;
|
|
14
|
+
window.emui = window.emui || { uuid: crypto.randomUUID() };
|
|
15
|
+
window.emui.app = {
|
|
16
|
+
uuid: window.emui.uuid,
|
|
17
|
+
init: async (options) => {
|
|
19
18
|
host = options.host;
|
|
20
19
|
parentHistory = options.history;
|
|
21
20
|
logger = options.logger;
|
|
22
21
|
return Promise.resolve();
|
|
23
|
-
}
|
|
24
|
-
|
|
22
|
+
},
|
|
23
|
+
mount: async () => {
|
|
25
24
|
const mainElement = document.createElement("main");
|
|
26
25
|
const pageHeaderEle = document.createElement("h1");
|
|
27
26
|
pageHeaderEle.textContent = appName;
|
|
@@ -33,10 +32,12 @@
|
|
|
33
32
|
mainElement.appendChild(versionEle);
|
|
34
33
|
document.body.appendChild(mainElement);
|
|
35
34
|
return Promise.resolve();
|
|
36
|
-
}
|
|
37
|
-
|
|
35
|
+
},
|
|
36
|
+
unmount: () => {
|
|
38
37
|
const mainEle = document.getElementsByTagName("main")[0];
|
|
39
38
|
if (mainEle) mainEle.remove();
|
|
40
39
|
return Promise.resolve();
|
|
41
|
-
}
|
|
42
|
-
}
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
const browserWindow = getWindow();
|
|
43
|
+
browserWindow.emui?.registerApp?.({ appId, app: window.emui.app });
|