@machinemetrics/mm-react-embeddable 1.4.0-4 → 1.4.0-5
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/mm-react-embeddable.cjs.js +10 -10
- package/dist/mm-react-embeddable.es.js +456 -336
- package/dist/mm-react-embeddable.umd.js +10 -10
- package/package.json +1 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react"),C=require("prop-types"),v=require("styled-components"),H=t.createContext(null),D=t.createContext({pending:[],authorize:()=>{},approve:()=>{},complete:()=>{},dismiss:()=>{},originEpochs:{},credentials:{},unsupported:{}}),ee="access_token",N=s=>s?s.kind?s:s.accessToken?{kind:ee,accessToken:s.accessToken,expiresAt:s.expiresAt||null}:null:null,de=new Set(["host_not_allowed","invalid_token","provider_unavailable"]),G=typeof window!="undefined"&&window.location.protocol==="https:",fe=8e3,K=s=>{try{return new URL(s).origin}catch{return null}},Q=(s,c)=>{const u=c==null?void 0:c.origin;return!u||K(s==null?void 0:s.authUrl)!==u?null:u},X=s=>{if(!s||/^\d{1,3}(?:\.\d{1,3}){3}$/.test(s)||s.includes(":"))return s;const c=s.split(".");return c.length<=2?s:c.slice(-2).join(".")},te=(s,c)=>{try{const u=new URL(s),f=new URL(c);return u.protocol!==f.protocol?!0:X(u.hostname)!==X(f.hostname)}catch{return!0}},ne=(s,{onBlocked:c,onClosed:u})=>{const f=window.open(s.authUrl,"mm-embed-auth","popup,width=600,height=700");if(!f)return c(),()=>{};const g=setInterval(()=>{f.closed&&(clearInterval(g),u())},1e3);return()=>clearInterval(g)},re=({children:s,launcher:c,broker:u})=>{const f=t.useContext(H),[g,E]=t.useState({}),[y,w]=t.useState({}),[x,T]=t.useState({}),[I,S]=t.useState({}),$=t.useRef(x);$.current=x;const p=t.useRef(null),F=t.useRef({}),O=t.useRef({}),_=t.useRef({}),U=t.useRef(u);U.current=u;const M=t.useCallback(e=>{const n=O.current[e];if(!n)return;const r=a=>!a[e]||a[e].clientId?a:{...a,[e]:{...a[e],clientId:n}};E(r),S(r)},[]),P=t.useCallback((e,n)=>{e&&(S(r=>r[e]?r:{...r,[e]:{origin:e,reason:n,clientId:O.current[e]||null}}),M(e))},[M]),o=t.useCallback((e,{v2:n=!1,origin:r=null}={})=>{r&&(n&&$.current[r]||(E(a=>a[r]?a:{...a,[r]:{origin:r,authUrl:e.authUrl,silentUrl:e.silentUrl||null,status:n&&U.current?"broker":n&&e.silentUrl&&G?"silent":"interactive",v2:n,scope:e.scope||null,acceptsCredentials:_.current[r]||null,consent:null,error:null,clientId:e.clientId||O.current[r]||null,popupBlocked:!1}}),M(r)))},[M]),l=t.useCallback(e=>{E(n=>{if(!n[e])return n;const r={...n};return delete r[e],r})},[]),i=t.useCallback(e=>{e&&(l(e),w(n=>({...n,[e]:(n[e]||0)+1})))},[l]),d=t.useCallback(e=>{E(n=>!n[e]||n[e].status==="interactive"?n:{...n,[e]:{...n[e],status:"interactive"}})},[]),m=t.useCallback(e=>{l(e.origin)},[l]),h=t.useCallback((e,n)=>{const r=Q(e,n);if(r){if(te(r,window.location.origin)){P(r,"cross-site-legacy");return}o(e,{origin:r})}},[o,P]);t.useEffect(()=>{if(!f)return;const e=[f.addListener("*","init",(n,r)=>{r!=null&&r.origin&&(n!=null&&n.clientId)&&(O.current[r.origin]=n.clientId,M(r.origin)),r!=null&&r.origin&&Array.isArray(n==null?void 0:n.acceptsCredentials)&&(_.current[r.origin]=n.acceptsCredentials)}),f.addListener("*","authorize",h),f.addListener("*","login",h),f.addListener("*","credential-request",(n,r)=>o(n,{v2:!0,origin:Q(n,r)}))];return()=>e.forEach(n=>n())},[f,h,o,M]),t.useEffect(()=>{const e=n=>{const r=n==null?void 0:n.data;if(!r||r.type!=="authorized"&&r.type!=="authorize-failed")return;const a=K(r.authUrl);if(!(!a||n.origin!==a)){if(r.type==="authorized"){r.accessToken?(T(b=>({...b,[a]:N({accessToken:r.accessToken})})),l(a)):i(a);return}d(a)}};return window.addEventListener("message",e),()=>window.removeEventListener("message",e)},[l,i,d]);const z=t.useCallback((e,n)=>{const r=e==null?void 0:e.origin,a=N(n);!r||!a||(T(b=>({...b,[r]:a})),l(r))},[l]),k=t.useCallback((e,n)=>{E(r=>r[e]?{...r,[e]:{...r[e],...n}}:r)},[]),R=t.useCallback(async(e,{approve:n}={})=>{const r=U.current,{origin:a}=e;let b;try{b=await r({origin:a,clientId:e.clientId,scope:e.scope,authUrl:e.authUrl},{approve:n})}catch{n?k(a,{error:{reason:"broker_unavailable"}}):k(a,{status:e.silentUrl&&G?"silent":"interactive"});return}if((b==null?void 0:b.status)===200&&b.credential){z(e,b.credential);return}if((b==null?void 0:b.status)===409&&b.consentRequired){k(a,{status:"interactive",consent:{client:b.client||null,stepUp:!!b.stepUp,scope:b.scope||e.scope},error:null});return}const W=(b==null?void 0:b.error)||"broker_error";if(!n&&de.has(W)){k(a,{status:e.silentUrl&&G?"silent":"interactive"});return}if(n&&W==="consent_denied"){k(a,{error:null});return}l(a),S(J=>({...J,[a]:{origin:a,reason:`broker:${W}`,detail:b||null,clientId:e.clientId||O.current[a]||null}}))},[z,k,l]),L=t.useRef({});t.useEffect(()=>{Object.values(g).forEach(e=>{e.status!=="broker"||L.current[e.origin]||(L.current[e.origin]=!0,R(e).finally(()=>{delete L.current[e.origin]}))})},[g,R]);const q=t.useCallback(e=>!U.current||!(e!=null&&e.consent)?Promise.resolve():R(e,{approve:!0}),[R]);t.useEffect(()=>{const e=F.current;Object.values(g).forEach(n=>{n.status==="silent"&&!e[n.origin]&&(e[n.origin]=setTimeout(()=>{delete e[n.origin],d(n.origin)},fe))}),Object.keys(e).forEach(n=>{(!g[n]||g[n].status!=="silent")&&(clearTimeout(e[n]),delete e[n])})},[g,d]),t.useEffect(()=>()=>{p.current&&p.current(),Object.values(F.current).forEach(clearTimeout)},[]);const A=t.useCallback(e=>{p.current&&(p.current(),p.current=null);const n=c||ne;p.current=n(e,{onBlocked:()=>{E(r=>r[e.origin]?{...r,[e.origin]:{...r[e.origin],popupBlocked:!0}}:r)},onClosed:()=>{if(e.v2){G&&E(r=>!r[e.origin]||!r[e.origin].silentUrl?r:{...r,[e.origin]:{...r[e.origin],status:"silent"}});return}i(e.origin)}})},[c,i]),j={pending:Object.values(g).filter(e=>e.status==="interactive"),authorize:A,approve:q,complete:z,dismiss:m,originEpochs:y,credentials:x,unsupported:I},Z=Object.values(g).filter(e=>e.status==="silent"&&e.silentUrl);return t.createElement(D.Provider,{value:j},s,Z.map(e=>t.createElement("iframe",{key:`mm-silent-auth-${e.origin}`,src:e.silentUrl,title:`MachineMetrics silent authorization (${e.origin})`,"aria-hidden":"true",tabIndex:-1,style:{display:"none"}})))};re.propTypes={children:C.node,launcher:C.func,broker:C.func};const se=()=>t.useContext(D),oe=s=>{const{originEpochs:c}=t.useContext(D),u=K(s);return u&&c[u]||0},ie=s=>{const{credentials:c}=t.useContext(D),u=K(s);return u&&c[u]||null},ce=s=>{const{unsupported:c}=t.useContext(D),u=K(s);return u&&c[u]||null},ue=({children:s,authorizationLauncher:c,credentialBroker:u})=>{const[f,g]=t.useState({}),[E,y]=t.useState({}),w=t.useRef({}),x=t.useRef({}),T=t.useRef({}),I=t.useCallback((o,l)=>{var i;return!!((i=T.current[o])!=null&&i.has(l))},[]),S=t.useCallback((o,l,i)=>{g(d=>({...d,[o]:{origin:l,frameRef:i}}))},[]),$=t.useCallback(o=>{g(l=>{const i={...l};return delete i[o],i}),y(l=>{const i={...l};return delete i[o],i}),delete T.current[o]},[]);t.useEffect(()=>{const o=(i=[],d,m)=>{i.forEach(h=>h(d,m))},l=i=>{var L,q,A,j,Z,e,n;if(!((L=i==null?void 0:i.data)!=null&&L.instanceId))return;const{instanceId:d,type:m}=i.data,h=f[d],z=(A=(q=h==null?void 0:h.frameRef)==null?void 0:q.current)==null?void 0:A.contentWindow;if(!z||i.source!==z||i.origin!==h.origin)return;const k={origin:i.origin},R=w.current;if(m==="response"){const{callbackId:r,response:a,error:b}=i.data,W=x.current[r];W&&(W(a,b),delete x.current[r]);return}if(m==="mark-registered"){const{requestType:r}=i.data;T.current[d]||(T.current[d]=new Set),T.current[d].add(r);return}m==="ready"&&y(r=>({...r,[d]:!0})),o((j=R[d])==null?void 0:j[m],i.data,k),o((Z=R["*"])==null?void 0:Z[m],i.data,k),o((e=R[d])==null?void 0:e["*"],i.data,k),o((n=R["*"])==null?void 0:n["*"],i.data,k)};return window.addEventListener("message",l),()=>{window.removeEventListener("message",l)}},[f]);const p=t.useCallback((o,l,i)=>{var m,h;const d=f[o];if(!d){console.warn(`Origin not set for id: ${o}. Unable to send message.`);return}(h=(m=d==null?void 0:d.frameRef)==null?void 0:m.current)!=null&&h.contentWindow&&d.frameRef.current.contentWindow.postMessage({type:l,...i,instanceId:o},d.origin)},[f]),F=t.useRef(0),O=t.useCallback(()=>`${Date.now()}-${++F.current}`,[]),_=t.useCallback(async(o,l,i={})=>new Promise((d,m)=>{const h=O(),z=(k,R)=>{delete x.current[h],R?m(R):d(k)};x.current[h]=z,p(o,"request",{callbackId:h,requestType:l,data:i})}),[p]),U=t.useCallback((o,l)=>{p(o,"load-options",l)},[p]),M=t.useCallback((o,l)=>{p(o,"validate",l)},[p]),P=t.useMemo(()=>({registerFrame:S,unregisterFrame:$,sendMessage:p,sendRequest:_,loadOptions:U,validate:M,hasHandler:I,readyFrames:E,addListener:(o,l,i)=>(w.current[o]||(w.current[o]={}),w.current[o][l]||(w.current[o][l]=[]),w.current[o][l].push(i),()=>{w.current[o][l]=w.current[o][l].filter(d=>d!==i)})}),[S,$,p,_,U,M,I,E]);return t.createElement(H.Provider,{value:P},t.createElement(re,{launcher:c,broker:u},s))},B=(s,c,u)=>{const f=t.useContext(H);if(f===null)throw new Error("useEmbeddedEffect must be used within a MMEmbeddableZoneProvider");const g=t.useRef(u);t.useEffect(()=>{g.current=u},[u]),t.useEffect(()=>{if(!(!s||!c)){if(c.startsWith("key:")){const E=c.substring(4);return f.readyFrames[s]&&f.sendMessage(s,"subscribe-key",{keyChord:E}),f.addListener(s,`key-pressed:${E}`,(...w)=>g.current(...w))}return f.addListener(s,c,(...E)=>g.current(...E))}},[f,s,c])};ue.propTypes={children:C.node.isRequired,authorizationLauncher:C.func,credentialBroker:C.func};const V=v.default||v,pe=1e4,be="credentials",Y=(s,c)=>`${s}/mm-embedded-interop?id=${c}&origin=${window.location.origin}&caps=${be}`,ge=V.iframe`
|
|
2
2
|
width: 100%;
|
|
3
3
|
height: 100%;
|
|
4
4
|
border: none;
|
|
5
|
-
visibility: ${
|
|
6
|
-
`,
|
|
5
|
+
visibility: ${s=>s.$isReady?"visible":"hidden"};
|
|
6
|
+
`,me=V.div`
|
|
7
7
|
width: 100%;
|
|
8
8
|
height: 100%;
|
|
9
9
|
display: flex;
|
|
@@ -16,13 +16,13 @@
|
|
|
16
16
|
text-align: center;
|
|
17
17
|
color: #555;
|
|
18
18
|
font-size: 14px;
|
|
19
|
-
`,
|
|
19
|
+
`,le=({entry:s})=>t.createElement(me,null,t.createElement("div",{style:{fontWeight:600}},s&&s.origin||"This app"," can’t be embedded here"),t.createElement("div",{style:{fontSize:12,color:"#888"}},"It needs an update to support embedding from a different domain."));le.propTypes={entry:C.shape({origin:C.string,name:C.string,reason:C.string})};const he=V.div`
|
|
20
20
|
height: 100%;
|
|
21
21
|
display: flex;
|
|
22
22
|
flex: 1;
|
|
23
23
|
align-items: center;
|
|
24
24
|
justify-content: center;
|
|
25
|
-
`,
|
|
25
|
+
`,Ee=()=>t.createElement(he,null,t.createElement("div",{style:{textAlign:"center"}},"This app couldn’t be loaded as an embeddable widget.")),ae=({id:s,src:c,path:u,onInit:f=()=>{},onTimeout:g,context:E={},params:y={},renderUnsupported:w,renderTimeout:x,...T})=>{if("isConfiguring"in T)return console.error("isConfiguring must be passed via the params prop to MMEmbeddableZone"),null;if("colorMode"in E)return console.error("colorMode must be passed via the params prop to MMEmbeddableZone"),null;if("isFullScreen"in E)return console.error("isFullScreen must be passed via the params prop to MMEmbeddableZone"),null;const I=t.useRef(),[S,$]=t.useState(),[p,F]=t.useState(0),[O,_]=t.useState(!1),[U,M]=t.useState(!1),P=oe(c),o=ie(c),l=ce(c);t.useEffect(()=>{P>0&&F(0)},[P]);const{registerFrame:i,unregisterFrame:d,sendMessage:m}=t.useContext(H),[h,z]=t.useState(),k=t.useRef(),R=t.useRef(g),L=t.useRef(f),q=t.useRef(!1);t.useEffect(()=>{R.current=g},[g]),t.useEffect(()=>{L.current=f},[f]),t.useEffect(()=>{p&&m(s,"set-context",{context:{...E}})},[E,s,p]),t.useEffect(()=>{p&&m(s,"set-params",{params:y})},[y,s,p]),t.useEffect(()=>{u!==void 0&&z((u==null?void 0:u.indexOf("/"))===0?u:`/${u}`)},[u]),t.useEffect(()=>{h===void 0||!p||m(s,"navigate",{path:h})},[h,p,s,m]),t.useEffect(()=>{if(!c||!s||!I)return;const n=new URL(c);return i(s,n.origin,I),L.current(),$(Y(n.origin,s)),()=>{d(s)}},[c,s,i,I]),t.useEffect(()=>{if(!(!S||q.current))return k.current=setTimeout(()=>{_(!0),R.current&&R.current()},pe),()=>clearTimeout(k.current)},[S]);const A=t.useCallback(()=>{q.current=!0,clearTimeout(k.current),_(!1)},[]),[j,Z]=t.useState(null);B(s,"init",n=>{A(),Array.isArray(n==null?void 0:n.acceptsCredentials)&&Z(n.acceptsCredentials)}),B(s,"authorize",A),B(s,"login",A),B(s,"credential-request",()=>{A(),M(!0)}),t.useEffect(()=>{if(!U||!o)return;const n=j;if(Array.isArray(n)&&!n.includes(o.kind))return;const r=o.kind==="access_token"?{accessToken:o.accessToken}:{};m(s,"credential",{...r,credential:o})},[U,o,j,s,m]),B(s,"ready",()=>{A(),F(n=>n+1)});const e=t.useRef();return B(s,"heartbeat",()=>{e.current&&clearTimeout(e.current),e.current=setTimeout(()=>{if(I.current){const n=new URL(c);I.current.src=Y(n.origin,s)}},6e3)}),t.useEffect(()=>()=>{e.current&&clearTimeout(e.current)},[]),l?w?w(l):t.createElement(le,{entry:l}):O&&!p?x?x():t.createElement(Ee,null):t.createElement(ge,{key:`auth-epoch-${P}`,$isReady:p,ref:I,src:S,...T})};ae.propTypes={id:C.string,src:C.string.isRequired,path:C.string,onInit:C.func,onTimeout:C.func,renderUnsupported:C.func,renderTimeout:C.func};const ke=v.div`
|
|
26
26
|
position: fixed;
|
|
27
27
|
inset: 0;
|
|
28
28
|
background: rgba(0, 0, 0, 0.45);
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
align-items: center;
|
|
31
31
|
justify-content: center;
|
|
32
32
|
z-index: 10000;
|
|
33
|
-
`,
|
|
33
|
+
`,Ce=v.div`
|
|
34
34
|
background: #fff;
|
|
35
35
|
border-radius: 8px;
|
|
36
36
|
box-shadow: 0 4px 24px rgba(0, 0, 0, 0.2);
|
|
@@ -39,13 +39,13 @@
|
|
|
39
39
|
max-width: calc(100vw - 32px);
|
|
40
40
|
font-family: sans-serif;
|
|
41
41
|
color: #222;
|
|
42
|
-
`,
|
|
42
|
+
`,Re=v.div`
|
|
43
43
|
display: flex;
|
|
44
44
|
align-items: center;
|
|
45
45
|
justify-content: space-between;
|
|
46
46
|
padding: 10px 0;
|
|
47
47
|
gap: 16px;
|
|
48
|
-
`,
|
|
48
|
+
`,we=v.button`
|
|
49
49
|
background: #16a500;
|
|
50
50
|
color: #fff;
|
|
51
51
|
border: none;
|
|
@@ -54,8 +54,8 @@
|
|
|
54
54
|
font-size: 14px;
|
|
55
55
|
cursor: pointer;
|
|
56
56
|
white-space: nowrap;
|
|
57
|
-
`,
|
|
57
|
+
`,xe=v.p`
|
|
58
58
|
color: #b3261e;
|
|
59
59
|
font-size: 13px;
|
|
60
60
|
margin: 4px 0 0;
|
|
61
|
-
`,
|
|
61
|
+
`,Te=()=>{const{pending:s,authorize:c}=se();return s.length===0?null:t.createElement(ke,null,t.createElement(Ce,null,t.createElement("h3",{style:{margin:"0 0 8px"}},"Authorization Required"),t.createElement("p",{style:{margin:"0 0 12px",fontSize:14,color:"#555"}},"The following apps need you to sign in and authorize them before they can load."),s.map(u=>t.createElement("div",{key:u.origin},t.createElement(Re,null,t.createElement("div",null,t.createElement("div",{style:{fontWeight:600}},u.origin)),t.createElement(we,{onClick:()=>c(u)},"Authorize")),u.popupBlocked&&t.createElement(xe,null,"The sign-in window was blocked. Allow popups for this site, then try again.")))))};exports.CREDENTIAL_KIND_ACCESS_TOKEN=ee;exports.EmbeddedAuthorizationContext=D;exports.EmbeddedAuthorizationPrompt=Te;exports.MMEmbeddableZone=ae;exports.MMEmbeddableZoneContext=H;exports.MMEmbeddableZoneProvider=ue;exports.isCrossSite=te;exports.normalizeCredential=N;exports.popupAuthorizationLauncher=ne;exports.useEmbeddedAuthorizations=se;exports.useEmbeddedCredential=ie;exports.useEmbeddedEffect=B;exports.useEmbeddedOriginEpoch=oe;exports.useEmbeddedUnsupported=ce;
|