@elliemae/ssf-host 2.0.0-next.29

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.
Files changed (103) hide show
  1. package/dist/cjs/app.config.json +20 -0
  2. package/dist/cjs/guest.js +196 -0
  3. package/dist/cjs/host.js +930 -0
  4. package/dist/cjs/ihost.js +16 -0
  5. package/dist/cjs/index.html +183 -0
  6. package/dist/cjs/index.js +33 -0
  7. package/dist/cjs/package.json +4 -0
  8. package/dist/cjs/tests/guest.html +14 -0
  9. package/dist/cjs/tests/logger.js +31 -0
  10. package/dist/cjs/tests/scriptingObjects/appEvents.js +16 -0
  11. package/dist/cjs/tests/scriptingObjects/appObjects.js +16 -0
  12. package/dist/cjs/tests/scriptingObjects/appraisalServiceModule.js +127 -0
  13. package/dist/cjs/tests/scriptingObjects/constant.js +38 -0
  14. package/dist/cjs/tests/scriptingObjects/floodServiceModule.js +49 -0
  15. package/dist/cjs/tests/server.js +29 -0
  16. package/dist/cjs/tests/serverHandlers.js +50 -0
  17. package/dist/cjs/tests/utils.js +76 -0
  18. package/dist/cjs/types.js +46 -0
  19. package/dist/cjs/utils.js +57 -0
  20. package/dist/esm/app.config.json +20 -0
  21. package/dist/esm/guest.js +177 -0
  22. package/dist/esm/host.js +919 -0
  23. package/dist/esm/ihost.js +0 -0
  24. package/dist/esm/index.html +183 -0
  25. package/dist/esm/index.js +13 -0
  26. package/dist/esm/package.json +4 -0
  27. package/dist/esm/tests/guest.html +14 -0
  28. package/dist/esm/tests/logger.js +15 -0
  29. package/dist/esm/tests/scriptingObjects/appEvents.js +0 -0
  30. package/dist/esm/tests/scriptingObjects/appObjects.js +0 -0
  31. package/dist/esm/tests/scriptingObjects/appraisalServiceModule.js +112 -0
  32. package/dist/esm/tests/scriptingObjects/constant.js +18 -0
  33. package/dist/esm/tests/scriptingObjects/floodServiceModule.js +29 -0
  34. package/dist/esm/tests/server.js +9 -0
  35. package/dist/esm/tests/serverHandlers.js +20 -0
  36. package/dist/esm/tests/utils.js +56 -0
  37. package/dist/esm/types.js +26 -0
  38. package/dist/esm/utils.js +37 -0
  39. package/dist/public/app.config.json +20 -0
  40. package/dist/public/autoFill.js +3 -0
  41. package/dist/public/autoFill.js.br +0 -0
  42. package/dist/public/autoFill.js.gz +0 -0
  43. package/dist/public/autoFill.js.map +1 -0
  44. package/dist/public/index.html +1 -0
  45. package/dist/public/init.js +3 -0
  46. package/dist/public/init.js.br +0 -0
  47. package/dist/public/init.js.gz +0 -0
  48. package/dist/public/init.js.map +1 -0
  49. package/dist/public/js/emuiSsfHost.c8f735724b6fe44f4dd6.js +3 -0
  50. package/dist/public/js/emuiSsfHost.c8f735724b6fe44f4dd6.js.br +0 -0
  51. package/dist/public/js/emuiSsfHost.c8f735724b6fe44f4dd6.js.gz +0 -0
  52. package/dist/public/js/emuiSsfHost.c8f735724b6fe44f4dd6.js.map +1 -0
  53. package/dist/public/loan-object.js +3 -0
  54. package/dist/public/loan-object.js.br +1 -0
  55. package/dist/public/loan-object.js.gz +0 -0
  56. package/dist/public/loan-object.js.map +1 -0
  57. package/dist/public/utils.js +3 -0
  58. package/dist/public/utils.js.br +0 -0
  59. package/dist/public/utils.js.gz +0 -0
  60. package/dist/public/utils.js.map +1 -0
  61. package/dist/types/guest.d.ts +140 -0
  62. package/dist/types/host.d.ts +107 -0
  63. package/dist/types/ihost.d.ts +138 -0
  64. package/dist/types/index.d.ts +8 -0
  65. package/dist/types/tests/event.test.d.ts +1 -0
  66. package/dist/types/tests/guest.test.d.ts +1 -0
  67. package/dist/types/tests/guestAsHost.test.d.ts +1 -0
  68. package/dist/types/tests/host.test.d.ts +1 -0
  69. package/dist/types/tests/logger.d.ts +3 -0
  70. package/dist/types/tests/scriptingObject.test.d.ts +1 -0
  71. package/dist/types/tests/scriptingObjects/appEvents.d.ts +3 -0
  72. package/dist/types/tests/scriptingObjects/appObjects.d.ts +7 -0
  73. package/dist/types/tests/scriptingObjects/appraisalServiceModule.d.ts +46 -0
  74. package/dist/types/tests/scriptingObjects/constant.d.ts +8 -0
  75. package/dist/types/tests/scriptingObjects/floodServiceModule.d.ts +17 -0
  76. package/dist/types/tests/server.d.ts +1 -0
  77. package/dist/types/tests/serverHandlers.d.ts +1 -0
  78. package/dist/types/tests/utils.d.ts +28 -0
  79. package/dist/types/types.d.ts +145 -0
  80. package/dist/types/utils.d.ts +8 -0
  81. package/dist/umd/app.config.json +20 -0
  82. package/dist/umd/autoFill.js +3 -0
  83. package/dist/umd/autoFill.js.br +0 -0
  84. package/dist/umd/autoFill.js.gz +0 -0
  85. package/dist/umd/autoFill.js.map +1 -0
  86. package/dist/umd/index.html +1 -0
  87. package/dist/umd/index.js +3 -0
  88. package/dist/umd/index.js.br +0 -0
  89. package/dist/umd/index.js.gz +0 -0
  90. package/dist/umd/index.js.map +1 -0
  91. package/dist/umd/init.js +3 -0
  92. package/dist/umd/init.js.br +0 -0
  93. package/dist/umd/init.js.gz +0 -0
  94. package/dist/umd/init.js.map +1 -0
  95. package/dist/umd/loan-object.js +3 -0
  96. package/dist/umd/loan-object.js.br +1 -0
  97. package/dist/umd/loan-object.js.gz +0 -0
  98. package/dist/umd/loan-object.js.map +1 -0
  99. package/dist/umd/utils.js +3 -0
  100. package/dist/umd/utils.js.br +0 -0
  101. package/dist/umd/utils.js.gz +0 -0
  102. package/dist/umd/utils.js.map +1 -0
  103. package/package.json +69 -0
@@ -0,0 +1,919 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
+ var __publicField = (obj, key, value) => {
4
+ __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
5
+ return value;
6
+ };
7
+ var __accessCheck = (obj, member, msg) => {
8
+ if (!member.has(obj))
9
+ throw TypeError("Cannot " + msg);
10
+ };
11
+ var __privateGet = (obj, member, getter) => {
12
+ __accessCheck(obj, member, "read from private field");
13
+ return getter ? getter.call(obj) : member.get(obj);
14
+ };
15
+ var __privateAdd = (obj, member, value) => {
16
+ if (member.has(obj))
17
+ throw TypeError("Cannot add the same private member more than once");
18
+ member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
19
+ };
20
+ var __privateSet = (obj, member, value, setter) => {
21
+ __accessCheck(obj, member, "write to private field");
22
+ setter ? setter.call(obj, value) : member.set(obj, value);
23
+ return value;
24
+ };
25
+ var _remoting, _correlationId, _logger, _nextGuestId, _guests, _publishedObjects, _readyStateCallback, _popupGuestMonitor, _closeAllPopupGuests, _getGuestForWindow, _getGuestForUrl, _isScriptingObject, _encodeResponse, _encodeException, _dispatchConfigEvent, _invoke, _handleGuestReadyComplete, _handleGuestReady, _handleGuestClose, _handleObjectGet, _handleGuestResize, _handleObjectInvoke, _subscribeToGuestResizeEvent, _connect, _isProxyEvent, _attachGuest, _monitorPopupGuests, _openPopupGuest, _openEmbedGuest, _getGuestUrl;
26
+ import { v4 as uuidv4 } from "uuid";
27
+ import {
28
+ Remoting,
29
+ ScriptingObject,
30
+ MessageType,
31
+ Event
32
+ } from "@elliemae/ssf-common";
33
+ import {
34
+ IFrameSandboxValues,
35
+ OpenMode
36
+ } from "./types.js";
37
+ import { Guest } from "./guest.js";
38
+ import { flatten, isFunction, isProxy } from "./utils.js";
39
+ const SANDBOX_DEFAULT = [
40
+ IFrameSandboxValues.AllowScripts,
41
+ IFrameSandboxValues.AllowPopups,
42
+ IFrameSandboxValues.AllowModals,
43
+ IFrameSandboxValues.AllowForms,
44
+ IFrameSandboxValues.AllowDownloads,
45
+ IFrameSandboxValues.AllowSameOrigin
46
+ ].join(" ");
47
+ class SSFHost {
48
+ /**
49
+ * Create a new host
50
+ *
51
+ * @param hostId unique identifier for the host
52
+ * @param {HostOption} option - options for the host
53
+ */
54
+ constructor(hostId, option) {
55
+ /* eslint-enable indent */
56
+ /**
57
+ * unique identifier for the host
58
+ */
59
+ __publicField(this, "hostId");
60
+ /**
61
+ * reference to the remoting object
62
+ */
63
+ __privateAdd(this, _remoting, void 0);
64
+ __privateAdd(this, _correlationId, void 0);
65
+ /**
66
+ * reference to the logger
67
+ */
68
+ __privateAdd(this, _logger, void 0);
69
+ /**
70
+ * next guest id
71
+ */
72
+ __privateAdd(this, _nextGuestId, 1);
73
+ /**
74
+ * list of guests
75
+ */
76
+ __privateAdd(this, _guests, /* @__PURE__ */ new Map());
77
+ /**
78
+ * list of published scripting objects
79
+ */
80
+ __privateAdd(this, _publishedObjects, /* @__PURE__ */ new Map());
81
+ /**
82
+ * callback for ready state
83
+ */
84
+ __privateAdd(this, _readyStateCallback, null);
85
+ /**
86
+ *
87
+ */
88
+ __privateAdd(this, _popupGuestMonitor, null);
89
+ __privateAdd(this, _closeAllPopupGuests, () => {
90
+ for (const guest of __privateGet(this, _guests).values()) {
91
+ if (guest.openMode === OpenMode.Popup) {
92
+ this.unloadGuest(guest.id);
93
+ }
94
+ }
95
+ });
96
+ /**
97
+ * get the reference to the guest application by its window
98
+ *
99
+ * @param guestWindow reference to the guest window
100
+ * @returns reference to the guest
101
+ */
102
+ __privateAdd(this, _getGuestForWindow, (guestWindow) => {
103
+ for (const guest of __privateGet(this, _guests).values()) {
104
+ if (guest.window === guestWindow)
105
+ return guest;
106
+ }
107
+ return null;
108
+ });
109
+ /**
110
+ * get the reference to the guest application by its window
111
+ *
112
+ * @param url url of the guest application
113
+ * @returns reference to the guest
114
+ */
115
+ __privateAdd(this, _getGuestForUrl, (url) => {
116
+ for (const guest of __privateGet(this, _guests).values()) {
117
+ if (guest.url === url)
118
+ return guest;
119
+ }
120
+ return null;
121
+ });
122
+ /**
123
+ * check if a object is a scripting object
124
+ *
125
+ * @param value javascript object
126
+ * @returns true if the object is a scripting object
127
+ */
128
+ __privateAdd(this, _isScriptingObject, (value) => (
129
+ // eslint-disable-next-line no-underscore-dangle, @typescript-eslint/no-unsafe-member-access
130
+ typeof value?._toJSON === "function"
131
+ ));
132
+ __privateAdd(this, _encodeResponse, (val) => {
133
+ if (__privateGet(this, _isScriptingObject).call(this, val)) {
134
+ this.addScriptingObject(val);
135
+ return { type: "object", object: val._toJSON() };
136
+ }
137
+ return { type: "value", value: val };
138
+ });
139
+ __privateAdd(this, _encodeException, (ex) => {
140
+ if (typeof ex === "string") {
141
+ return ex;
142
+ }
143
+ if (ex instanceof Error) {
144
+ return ex.message;
145
+ }
146
+ return "An unexpected error occurred in the host application";
147
+ });
148
+ __privateAdd(this, _dispatchConfigEvent, (guest) => {
149
+ if (guest.ready) {
150
+ __privateGet(this, _remoting).send({
151
+ targetWin: guest.window,
152
+ targetOrigin: guest.origin,
153
+ messageType: MessageType.HostConfig,
154
+ messageBody: {
155
+ logLevel: __privateGet(this, _logger).getLogLevel(),
156
+ ...guest.getInfo()
157
+ }
158
+ });
159
+ }
160
+ });
161
+ __privateAdd(this, _invoke, ({
162
+ guest,
163
+ obj,
164
+ functionName,
165
+ functionParams
166
+ }) => {
167
+ const func = obj[functionName];
168
+ if (!isFunction(func)) {
169
+ __privateGet(this, _logger).warn(
170
+ `Attempt to call invalid function on object type ${obj.objectType}: ${String(functionName)}`
171
+ );
172
+ return Promise.reject(
173
+ new Error(
174
+ `Method '${functionName}' not found in Scripting Object '${obj.id}'`
175
+ )
176
+ );
177
+ }
178
+ __privateGet(this, _logger).debug(
179
+ `Invoking host implementation of ${obj.id}.${String(functionName)}()`
180
+ );
181
+ return new Promise((resolve) => {
182
+ if (!Object.prototype.hasOwnProperty.call(func, "callContext")) {
183
+ Object.defineProperty(func, "callContext", {
184
+ value: { guest },
185
+ enumerable: true
186
+ });
187
+ }
188
+ resolve(func(...functionParams));
189
+ });
190
+ });
191
+ __privateAdd(this, _handleGuestReadyComplete, ({
192
+ sourceWin,
193
+ sourceOrigin,
194
+ requestId
195
+ }) => {
196
+ var _a;
197
+ const guest = __privateGet(this, _getGuestForWindow).call(this, sourceWin);
198
+ if (!guest) {
199
+ __privateGet(this, _logger).warn(
200
+ `Received ready event for unknown guest. requestId: ${requestId}`
201
+ );
202
+ return;
203
+ }
204
+ if (!guest.initialized) {
205
+ __privateGet(this, _logger).warn(
206
+ "Guest must be initialized before it is marked as ready"
207
+ );
208
+ __privateGet(this, _remoting).raiseException({
209
+ targetWin: sourceWin,
210
+ targetOrigin: sourceOrigin,
211
+ requestId,
212
+ ex: "Guest must be initialized before it is marked as ready"
213
+ });
214
+ return;
215
+ }
216
+ if (!guest.ready) {
217
+ guest.ready = true;
218
+ __privateGet(this, _dispatchConfigEvent).call(this, guest);
219
+ (_a = __privateGet(this, _readyStateCallback)) == null ? void 0 : _a.call(this, guest);
220
+ __privateGet(this, _logger).audit({
221
+ message: `Guest is ready`,
222
+ ...guest.getInfo()
223
+ });
224
+ }
225
+ });
226
+ // Initializes a guest when the guest is full loaded
227
+ __privateAdd(this, _handleGuestReady, ({
228
+ sourceWin,
229
+ sourceOrigin,
230
+ requestId,
231
+ body
232
+ }) => {
233
+ const guest = __privateGet(this, _getGuestForWindow).call(this, sourceWin);
234
+ if (!guest) {
235
+ __privateGet(this, _logger).warn(
236
+ `Received ready event for unknown guest. requestid = ${requestId}`
237
+ );
238
+ return;
239
+ }
240
+ if (!guest.initialized) {
241
+ guest.initialized = true;
242
+ guest.capabilities = body || {};
243
+ __privateGet(this, _logger).audit({
244
+ message: `Guest is initialized`,
245
+ ...guest.getInfo()
246
+ });
247
+ }
248
+ if (!body || !body.onReady) {
249
+ __privateGet(this, _handleGuestReadyComplete).call(this, {
250
+ sourceWin,
251
+ sourceOrigin,
252
+ requestId,
253
+ type: "",
254
+ body: null
255
+ });
256
+ }
257
+ });
258
+ __privateAdd(this, _handleGuestClose, ({ sourceWin }) => {
259
+ if (sourceWin?.window)
260
+ this.unloadGuest(sourceWin);
261
+ });
262
+ // Handles object get requests from the remote automation framework
263
+ __privateAdd(this, _handleObjectGet, ({
264
+ sourceWin,
265
+ sourceOrigin,
266
+ requestId,
267
+ body
268
+ }) => {
269
+ const { objectId } = body;
270
+ __privateGet(this, _logger).debug(
271
+ `Processing getObject request for object ${objectId}. requestId = ${requestId}`
272
+ );
273
+ const guest = __privateGet(this, _getGuestForWindow).call(this, sourceWin);
274
+ if (!guest) {
275
+ __privateGet(this, _logger).warn("Rejected object request from unknown guest window");
276
+ __privateGet(this, _remoting).raiseException({
277
+ targetWin: sourceWin,
278
+ targetOrigin: sourceOrigin,
279
+ requestId,
280
+ ex: "Specified window is not a known guest"
281
+ });
282
+ return false;
283
+ }
284
+ const obj = this.getScriptingObject(objectId);
285
+ if (!obj) {
286
+ __privateGet(this, _logger).warn(
287
+ `unknown or unauthorized object ${objectId} from guest ${guest.id}`
288
+ );
289
+ __privateGet(this, _remoting).raiseException({
290
+ targetWin: sourceWin,
291
+ targetOrigin: sourceOrigin,
292
+ requestId,
293
+ ex: `The requested object (${objectId}) is not available`
294
+ });
295
+ return false;
296
+ }
297
+ __privateGet(this, _remoting).respond({
298
+ targetWin: sourceWin,
299
+ targetOrigin: sourceOrigin,
300
+ requestId,
301
+ response: __privateGet(this, _encodeResponse).call(this, obj)
302
+ });
303
+ __privateGet(this, _logger).audit({
304
+ message: `Scripting Object returned`,
305
+ requestId,
306
+ scriptingObject: objectId,
307
+ ...guest.getInfo()
308
+ });
309
+ return true;
310
+ });
311
+ // handles guest resize event
312
+ __privateAdd(this, _handleGuestResize, ({
313
+ sourceWin,
314
+ requestId,
315
+ body
316
+ }) => {
317
+ const guest = __privateGet(this, _getGuestForWindow).call(this, sourceWin);
318
+ if (!guest) {
319
+ __privateGet(this, _logger).warn(
320
+ `Received resize event from unknown guest. requestid = ${requestId}`
321
+ );
322
+ return;
323
+ }
324
+ if (guest.domElement) {
325
+ guest.domElement.style.height = `${body.height}px`;
326
+ }
327
+ __privateGet(this, _logger).debug(
328
+ `Guest ${guest.id} resized to ${body.width}x${body.height}`
329
+ );
330
+ });
331
+ // Handles object invoke requests from the remote automation framework
332
+ __privateAdd(this, _handleObjectInvoke, ({
333
+ sourceWin,
334
+ sourceOrigin,
335
+ requestId,
336
+ body
337
+ }) => {
338
+ const { objectId } = body;
339
+ const guest = __privateGet(this, _getGuestForWindow).call(this, sourceWin);
340
+ if (!guest) {
341
+ __privateGet(this, _logger).warn(
342
+ "Rejected method invocation request from unknown guest window"
343
+ );
344
+ __privateGet(this, _remoting).raiseException({
345
+ targetWin: sourceWin,
346
+ targetOrigin: sourceOrigin,
347
+ requestId,
348
+ ex: "Specified window is not a known guest"
349
+ });
350
+ return false;
351
+ }
352
+ __privateGet(this, _logger).debug(
353
+ `Function ${objectId}.${String(body.functionName)}() called from guest "${guest.id}" (requestId = ${requestId})`
354
+ );
355
+ const obj = this.getScriptingObject(objectId);
356
+ if (!obj) {
357
+ __privateGet(this, _logger).warn(
358
+ `Invocation of unknown or unauthorized object ${objectId} from guest ${guest.id}`
359
+ );
360
+ __privateGet(this, _remoting).raiseException({
361
+ targetWin: sourceWin,
362
+ targetOrigin: sourceOrigin,
363
+ requestId,
364
+ ex: `The requested object (${objectId}) is not available`
365
+ });
366
+ return false;
367
+ }
368
+ __privateGet(this, _invoke).call(this, {
369
+ guest,
370
+ obj,
371
+ functionName: body.functionName,
372
+ functionParams: body.functionParams
373
+ }).then((val) => {
374
+ __privateGet(this, _remoting).respond({
375
+ targetWin: sourceWin,
376
+ targetOrigin: sourceOrigin,
377
+ requestId,
378
+ response: __privateGet(this, _encodeResponse).call(this, val)
379
+ });
380
+ __privateGet(this, _logger).audit({
381
+ message: `Value returned for Scripting Object method call`,
382
+ requestId,
383
+ scriptingObject: objectId,
384
+ scriptingMethod: body.functionName,
385
+ ...guest.getInfo()
386
+ });
387
+ }).catch((ex) => {
388
+ __privateGet(this, _remoting).raiseException({
389
+ targetWin: sourceWin,
390
+ targetOrigin: guest.origin,
391
+ requestId,
392
+ ex: __privateGet(this, _encodeException).call(this, ex)
393
+ });
394
+ __privateGet(this, _logger).audit({
395
+ message: `Exception thrown for Scripting Object method call`,
396
+ requestId,
397
+ scriptingObject: objectId,
398
+ scriptingMethod: body.functionName,
399
+ ...guest.getInfo()
400
+ });
401
+ });
402
+ return true;
403
+ });
404
+ __privateAdd(this, _subscribeToGuestResizeEvent, () => {
405
+ __privateGet(this, _remoting).listen({
406
+ messageType: MessageType.GuestResize,
407
+ callback: __privateGet(this, _handleGuestResize)
408
+ });
409
+ });
410
+ __privateAdd(this, _connect, () => {
411
+ __privateGet(this, _remoting).listen({
412
+ messageType: MessageType.GuestReady,
413
+ callback: __privateGet(this, _handleGuestReady)
414
+ });
415
+ __privateGet(this, _remoting).listen({
416
+ messageType: MessageType.GuestReadyComplete,
417
+ callback: __privateGet(this, _handleGuestReadyComplete)
418
+ });
419
+ __privateGet(this, _remoting).listen({
420
+ messageType: MessageType.GuestClose,
421
+ callback: __privateGet(this, _handleGuestClose)
422
+ });
423
+ __privateGet(this, _remoting).listen({
424
+ messageType: MessageType.ObjectGet,
425
+ callback: __privateGet(this, _handleObjectGet)
426
+ });
427
+ __privateGet(this, _remoting).listen({
428
+ messageType: MessageType.ObjectInvoke,
429
+ callback: __privateGet(this, _handleObjectInvoke)
430
+ });
431
+ window.addEventListener("visibilitychange", __privateGet(this, _closeAllPopupGuests));
432
+ });
433
+ __privateAdd(this, _isProxyEvent, (value) => (
434
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
435
+ value?.constructor?.name === "ProxyEvent"
436
+ ));
437
+ /**
438
+ * Register pre-rendered guest application to host
439
+ *
440
+ * @param {AttachParam} param - parameters for attaching the guest
441
+ * @returns reference to the guest object
442
+ */
443
+ __privateAdd(this, _attachGuest, (param) => {
444
+ const guest = new Guest({ ...param, remoting: __privateGet(this, _remoting) });
445
+ guest.init();
446
+ __privateGet(this, _guests).set(param.guestId, guest);
447
+ return guest;
448
+ });
449
+ __privateAdd(this, _monitorPopupGuests, () => {
450
+ __privateSet(this, _popupGuestMonitor, setInterval(() => {
451
+ const guestsToRemove = [];
452
+ __privateGet(this, _guests).forEach((guest) => {
453
+ if (guest.openMode === OpenMode.Popup && guest.window.closed) {
454
+ guestsToRemove.push(guest);
455
+ }
456
+ });
457
+ guestsToRemove.forEach((guest) => {
458
+ this.unloadGuest(guest.id);
459
+ });
460
+ }, 1e3));
461
+ });
462
+ __privateAdd(this, _openPopupGuest, (param) => {
463
+ const { url, title, windowFeatures = {}, params, guestId } = param;
464
+ const { width = 800, height = 600, top = 100, left = 100 } = windowFeatures;
465
+ let guest = __privateGet(this, _getGuestForUrl).call(this, url);
466
+ if (guest) {
467
+ if (!guest.window.closed) {
468
+ guest.send({
469
+ messageType: MessageType.GuestFocus,
470
+ messageBody: {}
471
+ });
472
+ }
473
+ } else {
474
+ const popupWindowFeatures = [
475
+ { key: "width", value: width },
476
+ { key: "height", value: height },
477
+ { key: "top", value: top },
478
+ { key: "left", value: left }
479
+ ].reduce((acc, cur, curIndex) => {
480
+ if (curIndex > 0 && cur.value)
481
+ acc += ",";
482
+ return cur.value ? `${acc}${cur.key}=${cur.value}` : acc;
483
+ }, "");
484
+ const guestWindow = window.open(
485
+ url,
486
+ title,
487
+ `popup, ${popupWindowFeatures}`
488
+ );
489
+ if (!guestWindow)
490
+ throw new Error("Failed to open guest application in popup window");
491
+ guestWindow.opener = null;
492
+ guest = __privateGet(this, _attachGuest).call(this, {
493
+ guestId,
494
+ window: guestWindow,
495
+ title,
496
+ url,
497
+ params,
498
+ openMode: OpenMode.Popup
499
+ });
500
+ }
501
+ return guest;
502
+ });
503
+ __privateAdd(this, _openEmbedGuest, (param) => {
504
+ const {
505
+ url,
506
+ title,
507
+ targetElement,
508
+ params,
509
+ guestId,
510
+ options = {}
511
+ } = param;
512
+ const targetElementDocument = targetElement.ownerDocument ?? document;
513
+ const {
514
+ fitToContent = false,
515
+ disableSandbox = false,
516
+ sandboxValues = []
517
+ } = options;
518
+ if (!title)
519
+ throw new Error("title is required");
520
+ if (fitToContent)
521
+ __privateGet(this, _subscribeToGuestResizeEvent).call(this);
522
+ const frame = targetElementDocument.createElement("iframe");
523
+ frame.setAttribute("id", guestId);
524
+ frame.addEventListener("load", () => {
525
+ __privateGet(this, _logger).debug(`frame loaded for guest with id '${guestId}'`);
526
+ });
527
+ frame.setAttribute("style", "min-width: 100%; height: 100%; border: 0px;");
528
+ if (!disableSandbox) {
529
+ frame.setAttribute(
530
+ "sandbox",
531
+ `${SANDBOX_DEFAULT} ${sandboxValues.join(" ")}`
532
+ );
533
+ }
534
+ frame.setAttribute("title", title);
535
+ frame.setAttribute("src", url);
536
+ targetElement.appendChild(frame);
537
+ const guestFrameEle = targetElementDocument.getElementById(
538
+ guestId
539
+ );
540
+ return __privateGet(this, _attachGuest).call(this, {
541
+ guestId,
542
+ domElement: guestFrameEle,
543
+ window: guestFrameEle.contentWindow,
544
+ title,
545
+ url,
546
+ params,
547
+ openMode: OpenMode.Embed
548
+ });
549
+ });
550
+ __privateAdd(this, _getGuestUrl, (url, params) => {
551
+ let querystring = "";
552
+ Object.keys(params).forEach((queryParam) => {
553
+ querystring += `${(querystring.length ? "&" : "") + encodeURIComponent(queryParam)}=${encodeURIComponent(params[queryParam])}`;
554
+ });
555
+ return url + (!querystring ? "" : (url.indexOf("?") >= 0 ? "&" : "?") + querystring);
556
+ });
557
+ /**
558
+ * adds scripting object to host
559
+ *
560
+ * @param so scripting object
561
+ * @throws Error if the scripting object is invalid
562
+ */
563
+ __publicField(this, "addScriptingObject", (so) => {
564
+ if (!so?.id || !so?._toJSON) {
565
+ throw new Error("Object is not derived from ScriptingObject");
566
+ }
567
+ if (so.id.toLowerCase() === "module")
568
+ throw new Error(
569
+ "Do not publish the module object. Create a concrete object derived from it."
570
+ );
571
+ __privateGet(this, _publishedObjects).set(so.id, so);
572
+ });
573
+ /**
574
+ * Clone parent host's scripting object for exposing to grand children
575
+ *
576
+ * @param proxy - reference to the scripting object obtained through getObject method
577
+ * @param guest - reference to the ssf guest
578
+ * @returns cloned version of the scripting object
579
+ */
580
+ __publicField(this, "cloneScriptingObject", (proxy, guest) => {
581
+ if (!proxy)
582
+ throw new Error("proxy is required");
583
+ if (!guest)
584
+ throw new Error("guest is required");
585
+ const so = new ScriptingObject(proxy.id, proxy.objectType);
586
+ let unsubscribers = [];
587
+ Object.keys(proxy).forEach((propName) => {
588
+ const propValue = proxy[propName];
589
+ if (__privateGet(this, _isProxyEvent).call(this, propValue)) {
590
+ const event = new Event({
591
+ name: propValue.name,
592
+ requiresFeedback: false,
593
+ so
594
+ });
595
+ Object.defineProperty(so, propName, {
596
+ value: event,
597
+ enumerable: true
598
+ });
599
+ const listener = ({
600
+ eventParams,
601
+ eventOptions
602
+ }) => this.dispatchEvent({
603
+ event,
604
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
605
+ eventParams,
606
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
607
+ eventOptions
608
+ });
609
+ const token = guest.subscribe({
610
+ eventId: propValue.id,
611
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
612
+ callback: listener
613
+ });
614
+ unsubscribers.push(() => {
615
+ guest.unsubscribe({ eventId: propValue.id, token });
616
+ });
617
+ } else if (isFunction(propValue)) {
618
+ Object.defineProperty(so, propName, {
619
+ value: async (...args) => {
620
+ const retVal = await propValue(...args);
621
+ return isProxy(retVal) ? this.cloneScriptingObject(retVal, guest) : retVal;
622
+ },
623
+ enumerable: true
624
+ });
625
+ if (propName === "dispose") {
626
+ const defaultImpl = so.dispose;
627
+ Object.defineProperty(so, propName, {
628
+ value: () => {
629
+ so._dispose();
630
+ return defaultImpl.apply(so);
631
+ },
632
+ enumerable: true
633
+ });
634
+ }
635
+ }
636
+ });
637
+ so._dispose = () => {
638
+ unsubscribers.forEach((unsub) => {
639
+ unsub?.();
640
+ });
641
+ unsubscribers = [];
642
+ };
643
+ return so;
644
+ });
645
+ /**
646
+ * dispose the resources used by the host application
647
+ */
648
+ __publicField(this, "close", () => {
649
+ clearInterval(__privateGet(this, _popupGuestMonitor));
650
+ __privateGet(this, _remoting).close();
651
+ window.removeEventListener("visibilitychange", __privateGet(this, _closeAllPopupGuests));
652
+ __privateGet(this, _logger).debug(
653
+ `host is closed. hostId: ${this.hostId}, correlationId: ${__privateGet(this, _correlationId)}`
654
+ );
655
+ });
656
+ /**
657
+ * dispatch event to guest application(s)
658
+ *
659
+ * @param {EventDetail} details details of the event to be dispatched
660
+ * @returns promise that resolves to an array with result from each guest application
661
+ */
662
+ __publicField(this, "dispatchEvent", async (details) => {
663
+ const {
664
+ event: { id, name, scriptingObject },
665
+ eventParams,
666
+ eventOptions = {}
667
+ } = details;
668
+ const {
669
+ eventHandler = null,
670
+ timeout = null,
671
+ window: targetWindow = null
672
+ } = eventOptions;
673
+ const eventObj = {
674
+ // eslint-disable-next-line no-underscore-dangle
675
+ object: scriptingObject._toJSON(),
676
+ eventName: name,
677
+ eventParams,
678
+ eventHandler,
679
+ eventOptions: {
680
+ allowsFeedback: false
681
+ }
682
+ };
683
+ if (timeout && !Number.isNaN(timeout)) {
684
+ eventObj.eventOptions = {
685
+ allowsFeedback: true,
686
+ timeout: Number(timeout)
687
+ };
688
+ }
689
+ const guestPromises = [];
690
+ __privateGet(this, _guests).forEach((guest) => {
691
+ if (!targetWindow || targetWindow === guest.window) {
692
+ if (timeout && guest?.capabilities?.eventFeedback) {
693
+ guestPromises.push(guest.dispatchEvent(eventObj, timeout));
694
+ __privateGet(this, _logger).audit({
695
+ message: "Event dispatched and awaiting feedback",
696
+ scriptingEventId: id,
697
+ ...guest.getInfo()
698
+ });
699
+ } else {
700
+ guest.send({
701
+ messageType: MessageType.ObjectEvent,
702
+ messageBody: eventObj
703
+ });
704
+ __privateGet(this, _logger).audit({
705
+ message: "Event dispatched",
706
+ scriptingEventId: id,
707
+ ...guest.getInfo()
708
+ });
709
+ }
710
+ }
711
+ });
712
+ const retValue = await Promise.all(guestPromises).then((values) => {
713
+ __privateGet(this, _logger).audit({
714
+ message: "Event feedback received",
715
+ scriptingEventId: id
716
+ });
717
+ return flatten(values);
718
+ }).catch((ex) => {
719
+ __privateGet(this, _logger).error({
720
+ message: "Error processing event",
721
+ eventId: id,
722
+ exception: ex
723
+ });
724
+ throw ex;
725
+ });
726
+ return retValue;
727
+ });
728
+ /**
729
+ * get reference to all guest applications
730
+ *
731
+ * @returns list of guest application references
732
+ */
733
+ __publicField(this, "getGuests", () => {
734
+ const guestList = [];
735
+ __privateGet(this, _guests).forEach((guest) => {
736
+ guestList.push(guest);
737
+ });
738
+ return guestList;
739
+ });
740
+ /**
741
+ * get the scripting object by id
742
+ *
743
+ * @param objectId - id of the scripting object
744
+ * @returns scripting object
745
+ */
746
+ __publicField(this, "getScriptingObject", (objectId) => {
747
+ if (!__privateGet(this, _publishedObjects).has(objectId))
748
+ return null;
749
+ return __privateGet(this, _publishedObjects).get(objectId);
750
+ });
751
+ /**
752
+ * loads guest application inside sandboxed iframe
753
+ *
754
+ * @param {LoadGuestParam} param - parameters for loading the guest application
755
+ * @returns reference to the guest object
756
+ */
757
+ __publicField(this, "loadGuest", (param) => {
758
+ const {
759
+ url,
760
+ targetElement,
761
+ title,
762
+ params = {},
763
+ options = {}
764
+ } = param;
765
+ const { openMode = OpenMode.Embed, windowFeatures = {} } = options;
766
+ const guestId = `guest-${this.hostId}-sandbox-${__privateGet(this, _nextGuestId)}`;
767
+ __privateSet(this, _nextGuestId, __privateGet(this, _nextGuestId) + 1);
768
+ const srcUrl = __privateGet(this, _getGuestUrl).call(this, url, params);
769
+ let guest = null;
770
+ if (openMode === OpenMode.Popup) {
771
+ guest = __privateGet(this, _openPopupGuest).call(this, {
772
+ guestId,
773
+ url: srcUrl,
774
+ title,
775
+ params,
776
+ windowFeatures
777
+ });
778
+ } else if (openMode === OpenMode.Embed) {
779
+ guest = __privateGet(this, _openEmbedGuest).call(this, {
780
+ guestId,
781
+ url: srcUrl,
782
+ title,
783
+ targetElement,
784
+ params,
785
+ options
786
+ });
787
+ } else {
788
+ throw new Error(`Invalid openMode: ${openMode}`);
789
+ }
790
+ __privateGet(this, _logger).audit({
791
+ message: "Guest loaded",
792
+ ...guest.getInfo()
793
+ });
794
+ return guest;
795
+ });
796
+ /**
797
+ * loads guest application inside sandboxed iframe with different params
798
+ *
799
+ * @param {LoadGuestsParam} param - parameters for loading the guest application
800
+ */
801
+ __publicField(this, "loadGuests", (param) => {
802
+ const {
803
+ url,
804
+ targetElement,
805
+ title,
806
+ paramsList = [],
807
+ options = {}
808
+ } = param;
809
+ paramsList.forEach((params) => {
810
+ this.loadGuest({ url, title, targetElement, params, options });
811
+ }, this);
812
+ });
813
+ /**
814
+ * removes all scripting objects from host
815
+ *
816
+ */
817
+ __publicField(this, "removeAllScriptingObjects", () => {
818
+ const objectIds = Array.from(__privateGet(this, _publishedObjects).keys());
819
+ objectIds.forEach((objectId) => {
820
+ this.removeScriptingObject(objectId);
821
+ });
822
+ });
823
+ /**
824
+ * removes scripting object from host
825
+ *
826
+ * @param objectId unique id of the scripting object
827
+ */
828
+ __publicField(this, "removeScriptingObject", (objectId) => {
829
+ const obj = this.getScriptingObject(objectId);
830
+ if (obj) {
831
+ if (obj._dispose && typeof obj._dispose === "function") {
832
+ obj._dispose();
833
+ }
834
+ __privateGet(this, _publishedObjects).delete(objectId);
835
+ }
836
+ });
837
+ /**
838
+ * set the log level for the host application
839
+ *
840
+ * @param level - log level
841
+ */
842
+ __publicField(this, "setLogLevel", (level) => {
843
+ __privateGet(this, _logger).setLogLevel(level);
844
+ __privateGet(this, _guests).forEach(__privateGet(this, _dispatchConfigEvent));
845
+ __privateGet(this, _logger).debug("Dispatched config events to all guests");
846
+ });
847
+ /**
848
+ * unloads guest application from host
849
+ *
850
+ * @param guestIdOrWindowOrEle unique id of the guest application or window object or dom element of the guest application
851
+ * @throws Error if guestId or Window reference is invalid
852
+ */
853
+ __publicField(this, "unloadGuest", (guestIdOrWindowOrEle) => {
854
+ let guest = typeof guestIdOrWindowOrEle === "string" ? __privateGet(this, _guests).get(guestIdOrWindowOrEle) : null;
855
+ if (!guest) {
856
+ guest = Array.from(__privateGet(this, _guests).values()).find(
857
+ (value) => value.window === guestIdOrWindowOrEle || value.domElement === guestIdOrWindowOrEle
858
+ );
859
+ if (!guest) {
860
+ throw new Error("Invalid guestId or guestWindow reference");
861
+ }
862
+ }
863
+ guest.dispose();
864
+ __privateGet(this, _guests).delete(guest.id);
865
+ __privateGet(this, _logger).audit({
866
+ message: `Guest is removed from host`,
867
+ ...guest.getInfo()
868
+ });
869
+ });
870
+ this.hostId = hostId;
871
+ if (!option?.logger)
872
+ throw new Error("Logger is required");
873
+ __privateSet(this, _logger, option.logger);
874
+ __privateSet(this, _correlationId, uuidv4());
875
+ __privateSet(this, _remoting, new Remoting(__privateGet(this, _logger), __privateGet(this, _correlationId)));
876
+ if (option?.readyStateCallback && typeof option?.readyStateCallback !== "function")
877
+ throw new Error("readyStateCallback must be a function");
878
+ __privateSet(this, _readyStateCallback, option?.readyStateCallback || null);
879
+ __privateGet(this, _remoting).initialize(window);
880
+ __privateGet(this, _connect).call(this);
881
+ __privateGet(this, _monitorPopupGuests).call(this);
882
+ __privateGet(this, _logger).debug(
883
+ `host is initialized. hostId: ${this.hostId}, correlationId: ${__privateGet(this, _correlationId)}`
884
+ );
885
+ }
886
+ }
887
+ _remoting = new WeakMap();
888
+ _correlationId = new WeakMap();
889
+ _logger = new WeakMap();
890
+ _nextGuestId = new WeakMap();
891
+ _guests = new WeakMap();
892
+ _publishedObjects = new WeakMap();
893
+ _readyStateCallback = new WeakMap();
894
+ _popupGuestMonitor = new WeakMap();
895
+ _closeAllPopupGuests = new WeakMap();
896
+ _getGuestForWindow = new WeakMap();
897
+ _getGuestForUrl = new WeakMap();
898
+ _isScriptingObject = new WeakMap();
899
+ _encodeResponse = new WeakMap();
900
+ _encodeException = new WeakMap();
901
+ _dispatchConfigEvent = new WeakMap();
902
+ _invoke = new WeakMap();
903
+ _handleGuestReadyComplete = new WeakMap();
904
+ _handleGuestReady = new WeakMap();
905
+ _handleGuestClose = new WeakMap();
906
+ _handleObjectGet = new WeakMap();
907
+ _handleGuestResize = new WeakMap();
908
+ _handleObjectInvoke = new WeakMap();
909
+ _subscribeToGuestResizeEvent = new WeakMap();
910
+ _connect = new WeakMap();
911
+ _isProxyEvent = new WeakMap();
912
+ _attachGuest = new WeakMap();
913
+ _monitorPopupGuests = new WeakMap();
914
+ _openPopupGuest = new WeakMap();
915
+ _openEmbedGuest = new WeakMap();
916
+ _getGuestUrl = new WeakMap();
917
+ export {
918
+ SSFHost
919
+ };