@elliemae/ssf-host 2.9.9 → 2.17.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.
Files changed (92) hide show
  1. package/dist/cjs/host.js +74 -42
  2. package/dist/cjs/index.html +1 -1
  3. package/dist/cjs/tests/scriptingObjects/appObjects.js +13 -1
  4. package/dist/cjs/tests/scriptingObjects/appraisalServiceModule.js +8 -8
  5. package/dist/cjs/tests/scriptingObjects/floodServiceModule.js +6 -4
  6. package/dist/cjs/utils.js +0 -5
  7. package/dist/cjs/v1-guest-v2-host.html +1 -1
  8. package/dist/cjs/v2-host-v1-guest.html +1 -1
  9. package/dist/esm/host.js +77 -44
  10. package/dist/esm/index.html +1 -1
  11. package/dist/esm/tests/scriptingObjects/appObjects.js +13 -1
  12. package/dist/esm/tests/scriptingObjects/appraisalServiceModule.js +8 -8
  13. package/dist/esm/tests/scriptingObjects/floodServiceModule.js +6 -4
  14. package/dist/esm/utils.js +0 -5
  15. package/dist/esm/v1-guest-v2-host.html +1 -1
  16. package/dist/esm/v2-host-v1-guest.html +1 -1
  17. package/dist/public/analytics-object-v1.js +1 -1
  18. package/dist/public/analytics-object-v1.js.br +0 -0
  19. package/dist/public/analytics-object-v1.js.gz +0 -0
  20. package/dist/public/analytics-object-v1.js.map +1 -1
  21. package/dist/public/analytics-object-v2.js +1 -1
  22. package/dist/public/analytics-object-v2.js.br +0 -0
  23. package/dist/public/analytics-object-v2.js.gz +0 -0
  24. package/dist/public/analytics-object-v2.js.map +1 -1
  25. package/dist/public/application-object-v1.js +1 -1
  26. package/dist/public/application-object-v1.js.br +0 -0
  27. package/dist/public/application-object-v1.js.gz +0 -0
  28. package/dist/public/application-object-v1.js.map +1 -1
  29. package/dist/public/application-object-v2.js +1 -1
  30. package/dist/public/application-object-v2.js.br +0 -0
  31. package/dist/public/application-object-v2.js.gz +0 -0
  32. package/dist/public/application-object-v2.js.map +1 -1
  33. package/dist/public/autoFill.js.gz +0 -0
  34. package/dist/public/index.html +1 -1
  35. package/dist/public/init.js.gz +0 -0
  36. package/dist/public/js/emuiSsfHost.e483a5246e5088d4be69.js +3 -0
  37. package/dist/public/js/emuiSsfHost.e483a5246e5088d4be69.js.br +0 -0
  38. package/dist/public/js/emuiSsfHost.e483a5246e5088d4be69.js.gz +0 -0
  39. package/dist/public/js/emuiSsfHost.e483a5246e5088d4be69.js.map +1 -0
  40. package/dist/public/loan-object-v1.js.gz +0 -0
  41. package/dist/public/loan-object.js +1 -1
  42. package/dist/public/loan-object.js.br +0 -0
  43. package/dist/public/loan-object.js.gz +0 -0
  44. package/dist/public/loan-object.js.map +1 -1
  45. package/dist/public/utils.js.gz +0 -0
  46. package/dist/public/v1-guest-v2-host.html +1 -1
  47. package/dist/public/v2-host-v1-guest.html +1 -1
  48. package/dist/types/lib/host.d.ts +5 -5
  49. package/dist/types/lib/ihost.d.ts +7 -5
  50. package/dist/types/lib/index.d.ts +1 -1
  51. package/dist/types/lib/tests/scriptingObjects/appObjects.d.ts +10 -0
  52. package/dist/types/lib/tests/scriptingObjects/appraisalServiceModule.d.ts +2 -1
  53. package/dist/types/lib/tests/scriptingObjects/floodServiceModule.d.ts +2 -1
  54. package/dist/types/lib/types.d.ts +4 -24
  55. package/dist/types/lib/utils.d.ts +1 -2
  56. package/dist/types/tsconfig.tsbuildinfo +1 -1
  57. package/dist/umd/analytics-object-v1.js +1 -1
  58. package/dist/umd/analytics-object-v1.js.br +0 -0
  59. package/dist/umd/analytics-object-v1.js.gz +0 -0
  60. package/dist/umd/analytics-object-v1.js.map +1 -1
  61. package/dist/umd/analytics-object-v2.js +1 -1
  62. package/dist/umd/analytics-object-v2.js.br +0 -0
  63. package/dist/umd/analytics-object-v2.js.gz +0 -0
  64. package/dist/umd/analytics-object-v2.js.map +1 -1
  65. package/dist/umd/application-object-v1.js +1 -1
  66. package/dist/umd/application-object-v1.js.br +0 -0
  67. package/dist/umd/application-object-v1.js.gz +0 -0
  68. package/dist/umd/application-object-v1.js.map +1 -1
  69. package/dist/umd/application-object-v2.js +1 -1
  70. package/dist/umd/application-object-v2.js.br +0 -0
  71. package/dist/umd/application-object-v2.js.gz +0 -0
  72. package/dist/umd/application-object-v2.js.map +1 -1
  73. package/dist/umd/autoFill.js.gz +0 -0
  74. package/dist/umd/index.html +1 -1
  75. package/dist/umd/index.js +1 -1
  76. package/dist/umd/index.js.br +0 -0
  77. package/dist/umd/index.js.gz +0 -0
  78. package/dist/umd/index.js.map +1 -1
  79. package/dist/umd/init.js.gz +0 -0
  80. package/dist/umd/loan-object-v1.js.gz +0 -0
  81. package/dist/umd/loan-object.js +1 -1
  82. package/dist/umd/loan-object.js.br +0 -0
  83. package/dist/umd/loan-object.js.gz +0 -0
  84. package/dist/umd/loan-object.js.map +1 -1
  85. package/dist/umd/utils.js.gz +0 -0
  86. package/dist/umd/v1-guest-v2-host.html +1 -1
  87. package/dist/umd/v2-host-v1-guest.html +1 -1
  88. package/package.json +7 -7
  89. package/dist/public/js/emuiSsfHost.d69dde08f6e0048b5ae8.js +0 -3
  90. package/dist/public/js/emuiSsfHost.d69dde08f6e0048b5ae8.js.br +0 -0
  91. package/dist/public/js/emuiSsfHost.d69dde08f6e0048b5ae8.js.gz +0 -0
  92. package/dist/public/js/emuiSsfHost.d69dde08f6e0048b5ae8.js.map +0 -1
package/dist/cjs/host.js CHANGED
@@ -201,7 +201,9 @@ class SSFHost {
201
201
  if (!Object.prototype.hasOwnProperty.call(func, "callContext")) {
202
202
  Object.defineProperty(func, "callContext", {
203
203
  value: { guest },
204
- enumerable: true
204
+ configurable: true,
205
+ enumerable: true,
206
+ writable: true
205
207
  });
206
208
  }
207
209
  resolve(func(...functionParams));
@@ -291,6 +293,35 @@ class SSFHost {
291
293
  }
292
294
  }
293
295
  };
296
+ // Handles list objects requests from the remote automation framework
297
+ #handleListObjects = ({
298
+ sourceWin,
299
+ sourceOrigin,
300
+ requestId
301
+ }) => {
302
+ this.#logger.debug(
303
+ `Processing listObjects request. requestId = ${requestId}`
304
+ );
305
+ const guest = this.#getGuestForWindow(sourceWin);
306
+ if (!guest) {
307
+ this.#logger.warn("Rejected object request from unknown guest window");
308
+ return false;
309
+ }
310
+ const objects = this.#soManager.listScriptingObjects(guest.id);
311
+ this.#remoting.respond({
312
+ targetWin: sourceWin,
313
+ targetOrigin: sourceOrigin,
314
+ requestId,
315
+ response: objects
316
+ });
317
+ this.#logger.audit({
318
+ message: `name of scripting objects returned`,
319
+ requestId,
320
+ objects,
321
+ ...guest.getInfo()
322
+ });
323
+ return true;
324
+ };
294
325
  // Handles object get requests from the remote automation framework
295
326
  #handleObjectGet = ({
296
327
  sourceWin,
@@ -305,12 +336,6 @@ class SSFHost {
305
336
  const guest = this.#getGuestForWindow(sourceWin);
306
337
  if (!guest) {
307
338
  this.#logger.warn("Rejected object request from unknown guest window");
308
- this.#remoting.raiseException({
309
- targetWin: sourceWin,
310
- targetOrigin: sourceOrigin,
311
- requestId,
312
- ex: "Specified window is not a known guest"
313
- });
314
339
  return false;
315
340
  }
316
341
  const obj = this.getScriptingObject(objectId, { guest });
@@ -373,18 +398,12 @@ class SSFHost {
373
398
  this.#logger.warn(
374
399
  "Rejected method invocation request from unknown guest window"
375
400
  );
376
- this.#remoting.raiseException({
377
- targetWin: sourceWin,
378
- targetOrigin: sourceOrigin,
379
- requestId,
380
- ex: "Specified window is not a known guest"
381
- });
382
401
  return false;
383
402
  }
384
403
  this.#logger.debug(
385
404
  `Function ${objectId}.${String(body.functionName)}() called from guest "${guest.id}" (requestId = ${requestId})`
386
405
  );
387
- const obj = this.getScriptingObject(objectId);
406
+ const obj = this.getScriptingObject(objectId, { guest });
388
407
  if (!obj) {
389
408
  this.#logger.warn(
390
409
  `Invocation of unknown or unauthorized object ${objectId} from guest ${guest.id}`
@@ -472,6 +491,10 @@ class SSFHost {
472
491
  // eslint-disable-next-line @typescript-eslint/no-misused-promises
473
492
  callback: this.#handleGuestClose
474
493
  });
494
+ this.#remoting.listen({
495
+ messageType: import_microfe_common.MessageType.ListObjects,
496
+ callback: this.#handleListObjects
497
+ });
475
498
  this.#remoting.listen({
476
499
  messageType: import_microfe_common.MessageType.ObjectGet,
477
500
  callback: this.#handleObjectGet
@@ -534,7 +557,7 @@ class SSFHost {
534
557
  this.unloadGuest(id);
535
558
  const callbacks = this.#guestCloseCallbackList.get(id);
536
559
  callbacks?.forEach((callback) => {
537
- callback().catch(() => {
560
+ callback({ id }).catch(() => {
538
561
  });
539
562
  });
540
563
  });
@@ -601,7 +624,8 @@ class SSFHost {
601
624
  fitToContent = false,
602
625
  disableSandbox = false,
603
626
  sandboxValues = [],
604
- style = ""
627
+ style = "",
628
+ permissionPolicy = ""
605
629
  } = options;
606
630
  if (!title) throw new Error("title is required");
607
631
  if (fitToContent) this.#subscribeToGuestResizeEvent();
@@ -624,6 +648,7 @@ class SSFHost {
624
648
  }
625
649
  frame.setAttribute("title", title);
626
650
  frame.setAttribute("src", url);
651
+ if (permissionPolicy) frame.setAttribute("allow", permissionPolicy);
627
652
  targetElement.appendChild(frame);
628
653
  const guestFrameEle = targetElementDocument.getElementById(
629
654
  guestId
@@ -651,7 +676,12 @@ class SSFHost {
651
676
  * @param {AddScriptingObjectParams} params params to add scripting object
652
677
  */
653
678
  addScriptingObject = (so, params) => {
654
- this.#soManager.addScriptingObject(so, params);
679
+ if ((0, import_microfe_common.isScriptingObjectProxy)(so)) {
680
+ const clonedSo = this.cloneScriptingObject(so);
681
+ this.#soManager.addScriptingObject(clonedSo, params);
682
+ } else {
683
+ this.#soManager.addScriptingObject(so, params);
684
+ }
655
685
  };
656
686
  /**
657
687
  * Clone parent host's scripting object for exposing to grand children
@@ -659,29 +689,22 @@ class SSFHost {
659
689
  * @param guest - reference to the ssf guest
660
690
  * @returns cloned version of the scripting object
661
691
  */
662
- cloneScriptingObject = (proxy, guest) => {
692
+ cloneScriptingObject = (proxy) => {
663
693
  if (!proxy) throw new Error("proxy is required");
664
- if (!guest) throw new Error("guest is required");
665
694
  const so = new import_microfe_common.ScriptingObject(proxy.id, proxy.objectType);
666
695
  let unsubscribers = [];
667
696
  Object.keys(proxy).forEach((propName) => {
668
697
  const propValue = proxy[propName];
669
698
  if (this.#isProxyEvent(propValue)) {
670
- let event;
671
- if (propValue?.subscribe !== "function") {
672
- event = new import_microfe_common.Event({
673
- name: propValue.name || propName,
674
- requiresFeedback: false,
675
- so
676
- });
677
- } else {
678
- event = new automation.Event();
679
- }
699
+ const event = new import_microfe_common.Event({
700
+ name: propValue.name || propName,
701
+ objectId: so.id
702
+ });
680
703
  Object.defineProperty(so, propName, {
681
704
  value: event,
682
705
  enumerable: true
683
706
  });
684
- if (guest.subscribe) {
707
+ if (propValue instanceof import_microfe_common.ProxyEvent) {
685
708
  const listener = ({
686
709
  eventParams,
687
710
  eventOptions
@@ -692,13 +715,11 @@ class SSFHost {
692
715
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
693
716
  eventOptions
694
717
  });
695
- const token = guest.subscribe({
696
- eventId: propValue.id,
697
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
698
- callback: listener
699
- });
718
+ const token = propValue.subscribe(
719
+ listener
720
+ );
700
721
  unsubscribers.push(() => {
701
- guest.unsubscribe({ eventId: propValue.id, token });
722
+ propValue.unsubscribe(token);
702
723
  });
703
724
  } else {
704
725
  const token = propValue.subscribe?.(
@@ -718,7 +739,7 @@ class SSFHost {
718
739
  Object.defineProperty(so, propName, {
719
740
  value: async (...args) => {
720
741
  const retVal = await propValue(...args);
721
- return (0, import_utils.isProxy)(retVal) ? this.cloneScriptingObject(retVal, guest) : retVal;
742
+ return (0, import_microfe_common.isScriptingObjectProxy)(retVal) ? this.cloneScriptingObject(retVal) : retVal;
722
743
  },
723
744
  enumerable: true
724
745
  });
@@ -756,20 +777,31 @@ class SSFHost {
756
777
  };
757
778
  /**
758
779
  * dispatch event to guest application(s)
759
- * @param {EventDetail} details details of the event to be dispatched
780
+ * @param {EventDetail} params details of the event to be dispatched
760
781
  * @returns promise that resolves to an array with result from each guest application
761
782
  */
762
- dispatchEvent = async (details) => {
783
+ dispatchEvent = async (params) => {
763
784
  const {
764
- event: { id, name, scriptingObject },
785
+ event: { id, name },
765
786
  eventParams,
766
787
  eventOptions = {}
767
- } = details;
788
+ } = params;
768
789
  const {
769
790
  eventHandler = null,
770
791
  timeout = null,
771
- window: targetWindow = null
792
+ window: targetWindow = null,
793
+ guestId
772
794
  } = eventOptions;
795
+ const objectId = id.split(".")[0];
796
+ const guestIdorWnd = guestId || targetWindow;
797
+ const targetGuest = guestIdorWnd ? this.#findGuest(guestIdorWnd) : null;
798
+ const scriptingObject = targetGuest ? this.getScriptingObject(objectId, { guest: targetGuest }) : this.getScriptingObject(objectId);
799
+ if (!scriptingObject) {
800
+ this.#logger.warn(
801
+ `Attempt to dispatch event ${name} on unknown object ${objectId}`
802
+ );
803
+ return Promise.resolve([]);
804
+ }
773
805
  const eventObj = {
774
806
  // eslint-disable-next-line no-underscore-dangle
775
807
  object: scriptingObject._toJSON(),
@@ -7,7 +7,7 @@
7
7
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
8
8
  <title>Host</title>
9
9
  <script src="https://cdn.tailwindcss.com?plugins=forms"></script>
10
- <script src="https://qa.assets.rd.elliemae.io/pui-diagnostics@3"></script>
10
+ <script src="https://cdn.qa1.ice.com/pui-diagnostics@3"></script>
11
11
  </head>
12
12
 
13
13
  <body>
@@ -19,8 +19,10 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
19
19
  var appObjects_exports = {};
20
20
  __export(appObjects_exports, {
21
21
  APPLICATION_SERVICE_OBJECT: () => APPLICATION_SERVICE_OBJECT,
22
+ MODULE_OBJECT: () => MODULE_OBJECT,
22
23
  applicationScriptingObject: () => applicationScriptingObject,
23
- authScriptingObject: () => authScriptingObject
24
+ authScriptingObject: () => authScriptingObject,
25
+ moduleScriptingObject: () => moduleScriptingObject
24
26
  });
25
27
  module.exports = __toCommonJS(appObjects_exports);
26
28
  const applicationScriptingObject = {
@@ -55,6 +57,7 @@ const applicationScriptingObject = {
55
57
  type: "object"
56
58
  };
57
59
  const APPLICATION_SERVICE_OBJECT = "application";
60
+ const MODULE_OBJECT = "module";
58
61
  const authScriptingObject = {
59
62
  object: {
60
63
  events: [],
@@ -64,3 +67,12 @@ const authScriptingObject = {
64
67
  },
65
68
  type: "object"
66
69
  };
70
+ const moduleScriptingObject = {
71
+ object: {
72
+ events: [],
73
+ functions: ["getParameters", "getCapabilities", "log", "unload"],
74
+ objectId: "module",
75
+ objectType: "Object"
76
+ },
77
+ type: "object"
78
+ };
@@ -31,23 +31,19 @@ class AppraisalService extends import_microfe_common.ScriptingObject {
31
31
  #creditScore;
32
32
  Close = new import_microfe_common.Event({
33
33
  name: "Close",
34
- requiresFeedback: false,
35
- so: this
34
+ objectId: this.constructor.name
36
35
  });
37
36
  Unloading = new import_microfe_common.Event({
38
37
  name: "Unloading",
39
- requiresFeedback: false,
40
- so: this
38
+ objectId: this.constructor.name
41
39
  });
42
40
  onPreCommit = new import_microfe_common.Event({
43
41
  name: "onPreCommit",
44
- requiresFeedback: true,
45
- so: this
42
+ objectId: this.constructor.name
46
43
  });
47
44
  onSaved = new import_microfe_common.Event({
48
45
  name: "onSaved",
49
- requiresFeedback: false,
50
- so: this
46
+ objectId: this.constructor.name
51
47
  });
52
48
  constructor({
53
49
  loanId,
@@ -83,6 +79,10 @@ class AppraisalService extends import_microfe_common.ScriptingObject {
83
79
  delete = () => {
84
80
  throw new Error("Not implemented");
85
81
  };
82
+ log = async (message, level) => {
83
+ console.log(message, level);
84
+ return Promise.resolve();
85
+ };
86
86
  unload = async () => {
87
87
  };
88
88
  }
@@ -29,13 +29,11 @@ class FloodService extends import_microfe_common.ScriptingObject {
29
29
  lastName;
30
30
  Close = new import_microfe_common.Event({
31
31
  name: "Close",
32
- requiresFeedback: false,
33
- so: this
32
+ objectId: this.constructor.name
34
33
  });
35
34
  Unloading = new import_microfe_common.Event({
36
35
  name: "Unloading",
37
- requiresFeedback: true,
38
- so: this
36
+ objectId: this.constructor.name
39
37
  });
40
38
  constructor() {
41
39
  super("FloodService");
@@ -50,6 +48,10 @@ class FloodService extends import_microfe_common.ScriptingObject {
50
48
  getParameters = () => Promise.resolve({
51
49
  moduleId: "floodService"
52
50
  });
51
+ log = async (message, level) => {
52
+ console.log(message, level);
53
+ return Promise.resolve();
54
+ };
53
55
  unload = () => Promise.resolve();
54
56
  _dispose = () => {
55
57
  };
package/dist/cjs/utils.js CHANGED
@@ -22,7 +22,6 @@ __export(utils_exports, {
22
22
  getObjectId: () => getObjectId,
23
23
  getOrigin: () => getOrigin,
24
24
  isFunction: () => isFunction,
25
- isProxy: () => isProxy,
26
25
  isScriptingObject: () => isScriptingObject
27
26
  });
28
27
  module.exports = __toCommonJS(utils_exports);
@@ -54,8 +53,4 @@ const isScriptingObject = (value) => (
54
53
  function isFunction(value) {
55
54
  return typeof value === "function";
56
55
  }
57
- const isProxy = (value) => (
58
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
59
- value?.constructor?.name === "Proxy"
60
- );
61
56
  const getObjectId = (elementOrId) => elementOrId?.id ?? elementOrId;
@@ -21,7 +21,7 @@
21
21
  height: 100%;
22
22
  }
23
23
  </style>
24
- <script src="https://qa.assets.rd.elliemae.io/pui-diagnostics@3"></script>
24
+ <script src="https://cdn.qa1.ice.com/pui-diagnostics@3"></script>
25
25
  <script src="https://cdn.elliemae.io/elliemae/core/ssf/1.0/elli.ssf.guest.js"></script>
26
26
  </head>
27
27
  <body>
@@ -21,7 +21,7 @@
21
21
  height: 100%;
22
22
  }
23
23
  </style>
24
- <script src="https://qa.assets.rd.elliemae.io/pui-diagnostics@3"></script>
24
+ <script src="https://cdn.qa1.ice.com/pui-diagnostics@3"></script>
25
25
  </head>
26
26
  <body>
27
27
  <main>
package/dist/esm/host.js CHANGED
@@ -5,14 +5,15 @@ import {
5
5
  MessageType,
6
6
  Event,
7
7
  ScriptingObjectManager,
8
- ProxyEvent
8
+ ProxyEvent,
9
+ isScriptingObjectProxy
9
10
  } from "@elliemae/microfe-common";
10
11
  import {
11
12
  IFrameSandboxValues,
12
13
  OpenMode
13
14
  } from "./types.js";
14
15
  import { Guest } from "./guest.js";
15
- import { flatten, isFunction, isProxy } from "./utils.js";
16
+ import { flatten, isFunction } from "./utils.js";
16
17
  const SANDBOX_DEFAULT = [
17
18
  IFrameSandboxValues.AllowScripts,
18
19
  IFrameSandboxValues.AllowPopups,
@@ -188,7 +189,9 @@ class SSFHost {
188
189
  if (!Object.prototype.hasOwnProperty.call(func, "callContext")) {
189
190
  Object.defineProperty(func, "callContext", {
190
191
  value: { guest },
191
- enumerable: true
192
+ configurable: true,
193
+ enumerable: true,
194
+ writable: true
192
195
  });
193
196
  }
194
197
  resolve(func(...functionParams));
@@ -278,6 +281,35 @@ class SSFHost {
278
281
  }
279
282
  }
280
283
  };
284
+ // Handles list objects requests from the remote automation framework
285
+ #handleListObjects = ({
286
+ sourceWin,
287
+ sourceOrigin,
288
+ requestId
289
+ }) => {
290
+ this.#logger.debug(
291
+ `Processing listObjects request. requestId = ${requestId}`
292
+ );
293
+ const guest = this.#getGuestForWindow(sourceWin);
294
+ if (!guest) {
295
+ this.#logger.warn("Rejected object request from unknown guest window");
296
+ return false;
297
+ }
298
+ const objects = this.#soManager.listScriptingObjects(guest.id);
299
+ this.#remoting.respond({
300
+ targetWin: sourceWin,
301
+ targetOrigin: sourceOrigin,
302
+ requestId,
303
+ response: objects
304
+ });
305
+ this.#logger.audit({
306
+ message: `name of scripting objects returned`,
307
+ requestId,
308
+ objects,
309
+ ...guest.getInfo()
310
+ });
311
+ return true;
312
+ };
281
313
  // Handles object get requests from the remote automation framework
282
314
  #handleObjectGet = ({
283
315
  sourceWin,
@@ -292,12 +324,6 @@ class SSFHost {
292
324
  const guest = this.#getGuestForWindow(sourceWin);
293
325
  if (!guest) {
294
326
  this.#logger.warn("Rejected object request from unknown guest window");
295
- this.#remoting.raiseException({
296
- targetWin: sourceWin,
297
- targetOrigin: sourceOrigin,
298
- requestId,
299
- ex: "Specified window is not a known guest"
300
- });
301
327
  return false;
302
328
  }
303
329
  const obj = this.getScriptingObject(objectId, { guest });
@@ -360,18 +386,12 @@ class SSFHost {
360
386
  this.#logger.warn(
361
387
  "Rejected method invocation request from unknown guest window"
362
388
  );
363
- this.#remoting.raiseException({
364
- targetWin: sourceWin,
365
- targetOrigin: sourceOrigin,
366
- requestId,
367
- ex: "Specified window is not a known guest"
368
- });
369
389
  return false;
370
390
  }
371
391
  this.#logger.debug(
372
392
  `Function ${objectId}.${String(body.functionName)}() called from guest "${guest.id}" (requestId = ${requestId})`
373
393
  );
374
- const obj = this.getScriptingObject(objectId);
394
+ const obj = this.getScriptingObject(objectId, { guest });
375
395
  if (!obj) {
376
396
  this.#logger.warn(
377
397
  `Invocation of unknown or unauthorized object ${objectId} from guest ${guest.id}`
@@ -459,6 +479,10 @@ class SSFHost {
459
479
  // eslint-disable-next-line @typescript-eslint/no-misused-promises
460
480
  callback: this.#handleGuestClose
461
481
  });
482
+ this.#remoting.listen({
483
+ messageType: MessageType.ListObjects,
484
+ callback: this.#handleListObjects
485
+ });
462
486
  this.#remoting.listen({
463
487
  messageType: MessageType.ObjectGet,
464
488
  callback: this.#handleObjectGet
@@ -521,7 +545,7 @@ class SSFHost {
521
545
  this.unloadGuest(id);
522
546
  const callbacks = this.#guestCloseCallbackList.get(id);
523
547
  callbacks?.forEach((callback) => {
524
- callback().catch(() => {
548
+ callback({ id }).catch(() => {
525
549
  });
526
550
  });
527
551
  });
@@ -588,7 +612,8 @@ class SSFHost {
588
612
  fitToContent = false,
589
613
  disableSandbox = false,
590
614
  sandboxValues = [],
591
- style = ""
615
+ style = "",
616
+ permissionPolicy = ""
592
617
  } = options;
593
618
  if (!title) throw new Error("title is required");
594
619
  if (fitToContent) this.#subscribeToGuestResizeEvent();
@@ -611,6 +636,7 @@ class SSFHost {
611
636
  }
612
637
  frame.setAttribute("title", title);
613
638
  frame.setAttribute("src", url);
639
+ if (permissionPolicy) frame.setAttribute("allow", permissionPolicy);
614
640
  targetElement.appendChild(frame);
615
641
  const guestFrameEle = targetElementDocument.getElementById(
616
642
  guestId
@@ -638,7 +664,12 @@ class SSFHost {
638
664
  * @param {AddScriptingObjectParams} params params to add scripting object
639
665
  */
640
666
  addScriptingObject = (so, params) => {
641
- this.#soManager.addScriptingObject(so, params);
667
+ if (isScriptingObjectProxy(so)) {
668
+ const clonedSo = this.cloneScriptingObject(so);
669
+ this.#soManager.addScriptingObject(clonedSo, params);
670
+ } else {
671
+ this.#soManager.addScriptingObject(so, params);
672
+ }
642
673
  };
643
674
  /**
644
675
  * Clone parent host's scripting object for exposing to grand children
@@ -646,29 +677,22 @@ class SSFHost {
646
677
  * @param guest - reference to the ssf guest
647
678
  * @returns cloned version of the scripting object
648
679
  */
649
- cloneScriptingObject = (proxy, guest) => {
680
+ cloneScriptingObject = (proxy) => {
650
681
  if (!proxy) throw new Error("proxy is required");
651
- if (!guest) throw new Error("guest is required");
652
682
  const so = new ScriptingObject(proxy.id, proxy.objectType);
653
683
  let unsubscribers = [];
654
684
  Object.keys(proxy).forEach((propName) => {
655
685
  const propValue = proxy[propName];
656
686
  if (this.#isProxyEvent(propValue)) {
657
- let event;
658
- if (propValue?.subscribe !== "function") {
659
- event = new Event({
660
- name: propValue.name || propName,
661
- requiresFeedback: false,
662
- so
663
- });
664
- } else {
665
- event = new automation.Event();
666
- }
687
+ const event = new Event({
688
+ name: propValue.name || propName,
689
+ objectId: so.id
690
+ });
667
691
  Object.defineProperty(so, propName, {
668
692
  value: event,
669
693
  enumerable: true
670
694
  });
671
- if (guest.subscribe) {
695
+ if (propValue instanceof ProxyEvent) {
672
696
  const listener = ({
673
697
  eventParams,
674
698
  eventOptions
@@ -679,13 +703,11 @@ class SSFHost {
679
703
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
680
704
  eventOptions
681
705
  });
682
- const token = guest.subscribe({
683
- eventId: propValue.id,
684
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
685
- callback: listener
686
- });
706
+ const token = propValue.subscribe(
707
+ listener
708
+ );
687
709
  unsubscribers.push(() => {
688
- guest.unsubscribe({ eventId: propValue.id, token });
710
+ propValue.unsubscribe(token);
689
711
  });
690
712
  } else {
691
713
  const token = propValue.subscribe?.(
@@ -705,7 +727,7 @@ class SSFHost {
705
727
  Object.defineProperty(so, propName, {
706
728
  value: async (...args) => {
707
729
  const retVal = await propValue(...args);
708
- return isProxy(retVal) ? this.cloneScriptingObject(retVal, guest) : retVal;
730
+ return isScriptingObjectProxy(retVal) ? this.cloneScriptingObject(retVal) : retVal;
709
731
  },
710
732
  enumerable: true
711
733
  });
@@ -743,20 +765,31 @@ class SSFHost {
743
765
  };
744
766
  /**
745
767
  * dispatch event to guest application(s)
746
- * @param {EventDetail} details details of the event to be dispatched
768
+ * @param {EventDetail} params details of the event to be dispatched
747
769
  * @returns promise that resolves to an array with result from each guest application
748
770
  */
749
- dispatchEvent = async (details) => {
771
+ dispatchEvent = async (params) => {
750
772
  const {
751
- event: { id, name, scriptingObject },
773
+ event: { id, name },
752
774
  eventParams,
753
775
  eventOptions = {}
754
- } = details;
776
+ } = params;
755
777
  const {
756
778
  eventHandler = null,
757
779
  timeout = null,
758
- window: targetWindow = null
780
+ window: targetWindow = null,
781
+ guestId
759
782
  } = eventOptions;
783
+ const objectId = id.split(".")[0];
784
+ const guestIdorWnd = guestId || targetWindow;
785
+ const targetGuest = guestIdorWnd ? this.#findGuest(guestIdorWnd) : null;
786
+ const scriptingObject = targetGuest ? this.getScriptingObject(objectId, { guest: targetGuest }) : this.getScriptingObject(objectId);
787
+ if (!scriptingObject) {
788
+ this.#logger.warn(
789
+ `Attempt to dispatch event ${name} on unknown object ${objectId}`
790
+ );
791
+ return Promise.resolve([]);
792
+ }
760
793
  const eventObj = {
761
794
  // eslint-disable-next-line no-underscore-dangle
762
795
  object: scriptingObject._toJSON(),
@@ -7,7 +7,7 @@
7
7
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
8
8
  <title>Host</title>
9
9
  <script src="https://cdn.tailwindcss.com?plugins=forms"></script>
10
- <script src="https://qa.assets.rd.elliemae.io/pui-diagnostics@3"></script>
10
+ <script src="https://cdn.qa1.ice.com/pui-diagnostics@3"></script>
11
11
  </head>
12
12
 
13
13
  <body>
@@ -30,6 +30,7 @@ const applicationScriptingObject = {
30
30
  type: "object"
31
31
  };
32
32
  const APPLICATION_SERVICE_OBJECT = "application";
33
+ const MODULE_OBJECT = "module";
33
34
  const authScriptingObject = {
34
35
  object: {
35
36
  events: [],
@@ -39,8 +40,19 @@ const authScriptingObject = {
39
40
  },
40
41
  type: "object"
41
42
  };
43
+ const moduleScriptingObject = {
44
+ object: {
45
+ events: [],
46
+ functions: ["getParameters", "getCapabilities", "log", "unload"],
47
+ objectId: "module",
48
+ objectType: "Object"
49
+ },
50
+ type: "object"
51
+ };
42
52
  export {
43
53
  APPLICATION_SERVICE_OBJECT,
54
+ MODULE_OBJECT,
44
55
  applicationScriptingObject,
45
- authScriptingObject
56
+ authScriptingObject,
57
+ moduleScriptingObject
46
58
  };