@microsoft/teams-js
Version:
Microsoft Client SDK for building app for Microsoft hosts
2 lines (1 loc) • 11.1 kB
JavaScript
import{__awaiter as e}from"../../../../node_modules/.pnpm/@rollup_plugin-typescript@11.1.6_rollup@4.24.4_tslib@2.6.3_typescript@4.9.5/node_modules/tslib/tslib.es6.js";import{isSdkError as n,ErrorCode as t}from"../public/interfaces.js";import{latestRuntimeApiVersion as o}from"../public/runtime.js";import{isSerializable as r}from"../public/serializable.interface.js";import{UUID as i}from"../public/uuidObject.js";import{version as s}from"../public/version.js";import{uninitializeChildCommunication as a,shouldProcessChildMessage as c,handleIncomingMessageFromChild as d}from"./childCommunication.js";import{getMessageIdsAsLogString as u,flushMessageQueue as l}from"./communicationUtils.js";import{GlobalVars as g}from"./globalVars.js";import{callHandler as p}from"./handlers.js";import f from"./hostToAppTelemetry.js";import{serializeMessageRequest as m,deserializeMessageResponse as w}from"./messageObjects.js";import{tryPolyfillWithNestedAppAuthBridge as h}from"./nestedAppAuthUtils.js";import{getLogger as v,isFollowingApiVersionTagFormat as b}from"./telemetry.js";import{getCurrentTimestamp as W,ssrSafeWindow as M}from"./utils.js";import{validateOrigin as y}from"./validOrigins.js";const k=v("communication");class I{}class T{}function E(n,t){if(T.messageListener=n=>function(n){return e(this,void 0,void 0,(function*(){if(!n||!n.data||"object"!=typeof n.data)return void J("Unrecognized message format received by app, message being ignored. Message: %o",n);const e=n.source||n.originalEvent&&n.originalEvent.source,t=n.origin||n.originalEvent&&n.originalEvent.origin;return B(e,t).then((o=>{o?(!function(e,n){g.isFramelessWindow||I.parentWindow&&!I.parentWindow.closed&&e!==I.parentWindow||(I.parentWindow=e,I.parentOrigin=n);I.parentWindow&&I.parentWindow.closed&&(I.parentWindow=null,I.parentOrigin=null);l(I.parentWindow,I.parentOrigin,T.parentMessageQueue,"parent")}(e,t),e!==I.parentWindow?c(e,t)&&d(n,e,V,((e,n)=>T.callbacks.set(e,n))):Y(n)):J("Message being ignored by app because it is either coming from the current window or a different window with an invalid origin, message: %o, source: %o, origin: %o",n,e,t)}))}))}(n),I.currentWindow=I.currentWindow||M(),I.parentWindow=I.currentWindow.parent!==I.currentWindow.self?I.currentWindow.parent:I.currentWindow.opener,I.topWindow=I.currentWindow.top,(I.parentWindow||n)&&I.currentWindow.addEventListener("message",T.messageListener,!1),!I.parentWindow){const e=I.currentWindow;if(!e.nativeInterface)return Promise.reject(new Error("Initialization Failed. No Parent window found."));g.isFramelessWindow=!0,e.onNativeMessage=Y}try{return I.parentOrigin="*",S(t,"initialize",[s,o,n]).then((([e,n,t,o])=>(h(o,I.currentWindow,{onMessage:D,sendPostMessage:L}),{context:e,clientType:n,runtimeConfig:t,clientSupportedSDKVersion:o})))}finally{I.parentOrigin=null}}function j(){I.currentWindow&&I.currentWindow.removeEventListener("message",T.messageListener,!1),I.currentWindow=null,I.parentWindow=null,I.parentOrigin=null,T.parentMessageQueue=[],T.nextMessageId=0,T.callbacks.clear(),T.promiseCallbacks.clear(),T.portCallbacks.clear(),T.legacyMessageIdsToUuidMap={},f.clearMessages(),a()}function O(e,n,...t){return S(e,n,t).then((([e])=>e))}function R(e,n,...t){return S(e,n,t).then((([e,n])=>{if(!e)throw new Error(n)}))}function C(e,n,t,...o){return S(e,n,o).then((([e,n])=>{if(!e)throw new Error(n||t)}))}function P(e,n,...t){return S(e,n,t).then((([e,n])=>{if(e)throw e;return n}))}function S(e,n,t=void 0){if(!b(e))throw Error(`apiVersionTag: ${e} passed in doesn't follow the pattern starting with 'v' followed by digits, then underscore with words, please check.`);return new Promise((o=>{const r=V(e,n,t);var i;o((i=r.uuid,new Promise((e=>{T.promiseCallbacks.set(i,e)}))))}))}function x(e){return e.map((e=>r(e)?e.serialize():e))}function N(o,r,i,s,a){var c;return e(this,void 0,void 0,(function*(){const e=x(r),[d]=yield S(s,o,e);if(a&&a(d)||!a&&n(d))throw new Error(`${d.errorCode}, message: ${null!==(c=d.message)&&void 0!==c?c:"None"}`);if(i.validate(d))return i.deserialize(d);throw new Error(`${t.INTERNAL_ERROR}, message: Invalid response from host - ${JSON.stringify(d)}`)}))}function A(o,r,i,s){var a;return e(this,void 0,void 0,(function*(){const e=x(r),[c]=yield S(i,o,e);if(s&&s(c)||!s&&n(c))throw new Error(`${c.errorCode}, message: ${null!==(a=c.message)&&void 0!==a?a:"None"}`);if(void 0!==c)throw new Error(`${t.INTERNAL_ERROR}, message: Invalid response from host`)}))}function U(e,n,t=void 0){if(!b(e))throw Error(`apiVersionTag: ${e} passed in doesn't follow the pattern starting with 'v' followed by digits, then underscore with words, please check.`);const o=V(e,n,t);return r=o.uuid,new Promise(((e,n)=>{T.portCallbacks.set(r,((t,o)=>{t instanceof MessagePort?e(t):n(o&&o.length>0?o[0]:new Error("Host responded without port or error details."))}))}));var r}function $(e,n,t,o){let r;if(t instanceof Function?o=t:t instanceof Array&&(r=t),!b(e))throw Error(`apiVersionTag: ${e} passed in doesn't follow the pattern starting with 'v' followed by digits, then underscore with words, please check.`);const i=V(e,n,r);o&&T.callbacks.set(i.uuid,o)}T.parentMessageQueue=[],T.topMessageQueue=[],T.nextMessageId=0,T.callbacks=new Map,T.promiseCallbacks=new Map,T.portCallbacks=new Map,T.legacyMessageIdsToUuidMap={};const z=k.extend("sendNestedAuthRequestToTopWindow");function L(e,n){const t=z,o=I.topWindow,r=function(e,n){const t=T.nextMessageId++,o=new i;return T.legacyMessageIdsToUuidMap[t]=o,{id:t,uuid:o,func:"nestedAppAuth.execute",timestamp:Date.now(),monotonicTimestamp:W(),apiVersionTag:n,args:[],data:e}}(e,n);return t("Message %s information: %o",u(r),{actionName:r.func}),F(o,r)}const _=k.extend("sendRequestToTargetWindowHelper");function F(e,n){const t=_,o=function(e){return e===I.topWindow&&Z()?"top":e===I.parentWindow?"parent":null}(e),r=m(n);if(g.isFramelessWindow)I.currentWindow&&I.currentWindow.nativeInterface&&(t("Sending message %s to %s via framelessPostMessage interface",u(r),o),I.currentWindow.nativeInterface.framelessPostMessage(JSON.stringify(r)));else{const i=function(e){return e===I.topWindow&&Z()?I.topOrigin:e===I.parentWindow?I.parentOrigin:null}(e);e&&i?(t("Sending message %s to %s via postMessage",u(r),o),e.postMessage(r,i)):(t("Adding message %s to %s message queue",u(r),o),ee(e).push(n))}return n}const Q=k.extend("sendMessageToParentHelper");function V(e,n,t,o,r){const s=Q,a=I.parentWindow,c=function(e,n,t,o,r){const s=T.nextMessageId++,a=new i;T.legacyMessageIdsToUuidMap[s]=a;const c=!0===o?r:g.teamsJsInstanceId;return{id:s,uuid:a,func:n,timestamp:Date.now(),monotonicTimestamp:W(),args:t||[],apiVersionTag:e,isProxiedFromChild:null!=o&&o,teamsJsInstanceId:c}}(e,n,t,o,r);return f.storeCallbackInformation(c.uuid,{name:n,calledAt:c.timestamp}),s("Message %s information: %o",u(c),{actionName:n,args:t}),F(a,c)}const J=k.extend("processIncomingMessage");const q=k.extend("processAuthBridgeMessage");function D(e,n){var t,o;const r=q;if(!e||!e.data||"object"!=typeof e.data)return void r("Unrecognized message format received by app, message being ignored. Message: %o",e);const{args:i}=e.data,[,s]=null!=i?i:[],a=(()=>{try{return JSON.parse(s)}catch(e){return null}})();if(!a||"object"!=typeof a||"NestedAppAuthResponse"!==a.messageType)return void r("Unrecognized data format received by app, message being ignored. Message: %o",e);const c=e.source||(null===(t=null==e?void 0:e.originalEvent)||void 0===t?void 0:t.source),d=e.origin||(null===(o=null==e?void 0:e.originalEvent)||void 0===o?void 0:o.origin);c?B(c,d)?(I.topWindow&&!I.topWindow.closed&&c!==I.topWindow||(I.topWindow=c,I.topOrigin=d),I.topWindow&&I.topWindow.closed&&(I.topWindow=null,I.topOrigin=null),l(I.topWindow,I.topOrigin,T.topMessageQueue,"top"),n(s)):r("Message being ignored by app because it is either coming from the current window or a different window with an invalid origin"):r("Message being ignored by app because it is coming for a target that is null")}const H=k.extend("shouldProcessIncomingMessage");function B(n,t){return e(this,void 0,void 0,(function*(){if(I.currentWindow&&n===I.currentWindow)return H("Should not process message because it is coming from the current window"),!1;if(I.currentWindow&&I.currentWindow.location&&t&&t===I.currentWindow.location.origin)return!0;{let e;try{e=new URL(t)}catch(e){return H("Message has an invalid origin of %s",t),!1}const n=yield y(e);return n||H("Message has an invalid origin of %s",t),n}}))}const K=k.extend("handleIncomingMessageFromParent");function G(e,n){if(n){const t=[...e].find((([e,t])=>e.toString()===n.toString()));if(t)return t[0]}}function X(e,n){const t=G(n,e.uuid);t&&n.delete(t),e.uuid?T.legacyMessageIdsToUuidMap={}:delete T.legacyMessageIdsToUuidMap[e.id]}function Y(e){const n=K,t=W();if("id"in e.data&&"number"==typeof e.data.id){const o=e.data,r=w(o),i=function(e){const n=K;if(!e.uuid)return T.legacyMessageIdsToUuidMap[e.id];{const n=e.uuid,t=G(T.callbacks,n);if(t)return t;const o=G(T.promiseCallbacks,n);if(o)return o;const r=G(T.portCallbacks,n);if(r)return r}n("Received message %s that failed to produce a callbackId",u(e))}(r);if(i){const o=T.callbacks.get(i);n("Received a response from parent for message %s",i.toString()),f.handlePerformanceMetrics(i,r,n,t),o&&(n("Invoking the registered callback for message %s with arguments %o",i.toString(),r.args),o.apply(null,[...r.args,r.isPartialResponse]),function(e){return!0===e.data.isPartialResponse}(e)||(n("Removing registered callback for message %s",i.toString()),X(r,T.callbacks)));const s=T.promiseCallbacks.get(i);s&&(n("Invoking the registered promise callback for message %s with arguments %o",i.toString(),r.args),s(r.args),n("Removing registered promise callback for message %s",i.toString()),X(r,T.promiseCallbacks));const a=T.portCallbacks.get(i);if(a){let t;n("Invoking the registered port callback for message %s with arguments %o",i.toString(),r.args),e.ports&&e.ports[0]instanceof MessagePort&&(t=e.ports[0]),a(t,r.args),n("Removing registered port callback for message %s",i.toString()),X(r,T.portCallbacks)}r.uuid&&(T.legacyMessageIdsToUuidMap={})}}else if("func"in e.data&&"string"==typeof e.data.func){const o=e.data;f.handleOneWayPerformanceMetrics(o,n,t),n('Received a message from parent %s, action: "%s"',u(o),o.func),p(o.func,o.args)}else n("Received an unknown message: %O",e)}function Z(){return I.topWindow!==I.parentWindow}function ee(e){return e===I.topWindow&&Z()?T.topMessageQueue:e===I.parentWindow?T.parentMessageQueue:[]}function ne(e,n){let t;t=I.currentWindow.setInterval((()=>{0===ee(e).length&&(clearInterval(t),n())}),100)}export{I as Communication,A as callFunctionInHost,N as callFunctionInHostAndHandleResponse,E as initializeCommunication,U as requestPortFromParentWithVersion,P as sendAndHandleSdkError,R as sendAndHandleStatusAndReason,C as sendAndHandleStatusAndReasonWithDefaultError,O as sendAndUnwrap,$ as sendMessageToParent,S as sendMessageToParentAsync,L as sendNestedAuthRequestToTopWindow,j as uninitializeCommunication,ne as waitForMessageQueue};