@juspay-tech/hyperswitch-control-center-embed-core 1.1.1 → 1.2.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.
package/dist/index.min.js CHANGED
@@ -1,2 +1,2 @@
1
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).Hyperswitch={})}(this,function(e){"use strict";const t="undefined"!=typeof window;class n{constructor(e,n){this.instance=e,this.options=n||{},this._internalId=`hyper-el-${Math.random().toString(36).substring(7)}`,this.boundMessageHandler=null,t&&(this.element=document.createElement("div"),this.iframe=document.createElement("iframe"),this.boundMessageHandler=this.handleMessage.bind(this),this.setupElement(),this.setupIframe(),window.addEventListener("message",this.boundMessageHandler))}setupElement(){t&&(this.element.className=`hyperswitch-element ${this.options.className||""}`.trim(),this.element.dataset.hyperswitchElement=this.getElementType(),Object.assign(this.element.style,Object.assign({width:this.options.width||"100%",height:this.options.height||"500px",overflow:"hidden"},this.options.style||{})))}setupIframe(){t&&(this.iframe.src=this.getIframeSrc(),this.iframe.style.border="none",this.iframe.style.width="100%",this.iframe.style.height="100%",this.iframe.title=`Hyperswitch ${this.getElementType()}`,this.iframe.setAttribute("allow","clipboard-read; clipboard-write; clipboard-sanitized-write"),this.iframe.setAttribute("sandbox","allow-scripts allow-same-origin allow-popups allow-forms allow-modals allow-presentation allow-downloads"),this.element.appendChild(this.iframe))}handleMessage(e){var n;if(t&&(this.options.onMessage&&this.options.onMessage(e.data),"EMBEDDED_COMPONENT_RESIZE"===(null===(n=e.data)||void 0===n?void 0:n.type))){const t=e.data.height;(e.data.component||"")===this.getElementType()&&"number"==typeof t&&t>0&&(this.element.style.height=`${t}px`,this.options.onResize&&this.options.onResize({width:this.element.clientWidth,height:t}))}}mount(e){if(!t)throw new Error("HyperswitchElement.mount can only be called in a browser environment");const n="string"==typeof e?document.querySelector(e):e;if(!n)throw new Error(`Invalid mount point: ${e}`);return n.appendChild(this.element),this}destroy(){t&&(this.boundMessageHandler&&window.removeEventListener("message",this.boundMessageHandler),this.element&&this.element.parentNode&&this.element.parentNode.removeChild(this.element))}getIframe(){return this.iframe}}class o extends n{constructor(e,t){super(e,t)}getElementType(){return"connectors"}getIframeSrc(){return`${this.options.url||"http://localhost:9000"}/embedded/connectors`}}const i="undefined"!=typeof window;class s{constructor(e){if(this.token=null,this.initConfig=null,this.activeElements=new Map,this.isRefetchingToken=!1,this.tokenError=null,!e||"function"!=typeof e.fetchToken)throw new Error("loadHyperswitch requires a fetchToken callback function");this.fetchToken=e.fetchToken,this.initConfig=e.initConfig?function(e){var t,n,o,i,s,r,l,a,d,h,c,u,m,f,p,g,v,E,y,w;const k=e||{};return{settings:{colors:{primary:null!==(t=k.primaryColor)&&void 0!==t?t:null,secondary:null,background:null!==(n=k.backgroundColor)&&void 0!==n?n:null},sidebar:null,typography:null,buttons:{primary:{backgroundColor:null!==(s=null===(i=null===(o=k.buttons)||void 0===o?void 0:o.primary)||void 0===i?void 0:i.backgroundColor)&&void 0!==s?s:null,textColor:null!==(a=null===(l=null===(r=k.buttons)||void 0===r?void 0:r.primary)||void 0===l?void 0:l.textColor)&&void 0!==a?a:null,hoverBackgroundColor:null!==(c=null===(h=null===(d=k.buttons)||void 0===d?void 0:d.primary)||void 0===h?void 0:h.hoverBackgroundColor)&&void 0!==c?c:null},secondary:{backgroundColor:null!==(f=null===(m=null===(u=k.buttons)||void 0===u?void 0:u.secondary)||void 0===m?void 0:m.backgroundColor)&&void 0!==f?f:null,textColor:null!==(v=null===(g=null===(p=k.buttons)||void 0===p?void 0:p.secondary)||void 0===g?void 0:g.textColor)&&void 0!==v?v:null,hoverBackgroundColor:null!==(w=null===(y=null===(E=k.buttons)||void 0===E?void 0:E.secondary)||void 0===y?void 0:y.hoverBackgroundColor)&&void 0!==w?w:null}},borders:null,spacing:null},urls:{faviconUrl:null,logoUrl:null}}}(e.initConfig):null,this.initPromise=this.fetchInitialToken(),this.listenForMessages()}fetchInitialToken(){return(()=>{try{return this.fetchToken()}catch(e){return Promise.reject(e)}})().then(e=>{e?this.token=e:this.tokenError="Failed to fetch token: Token returned empty or undefined"}).catch(e=>{this.tokenError=`Failed to fetch token: ${e instanceof Error?e.message:String(e)}`})}listenForMessages(){i&&window.addEventListener("message",async e=>{var t,n,o;"TOKEN_EXPIRED"===(null===(t=e.data)||void 0===t?void 0:t.type)&&!0===(null===(n=e.data)||void 0===n?void 0:n.value)?await this.refetchAndBroadcastToken():"EMBEDDED_IFRAME_READY"===(null===(o=e.data)||void 0===o?void 0:o.type)&&this.activeElements.forEach(t=>{const n=t.getIframe();(null==n?void 0:n.contentWindow)===e.source&&this.onElementIframeLoaded(t)})})}async refetchAndBroadcastToken(){if(!this.isRefetchingToken){this.isRefetchingToken=!0;try{const e=await this.fetchToken();e?(this.token=e,this.tokenError=null,this.activeElements.forEach((e,t)=>{const n=e.getIframe();(null==n?void 0:n.contentWindow)&&n.contentWindow.postMessage({type:"AUTH_TOKEN",token:this.token},"*")})):(this.tokenError="Failed to refetch token: Token returned empty or undefined",this.sendErrorToActiveElements(this.tokenError))}catch(e){this.tokenError=`Failed to refetch token: ${e instanceof Error?e.message:String(e)}`,this.sendErrorToActiveElements(this.tokenError)}finally{this.isRefetchingToken=!1}}}sendErrorToActiveElements(e){this.activeElements.forEach(t=>{const n=t.getIframe();(null==n?void 0:n.contentWindow)&&n.contentWindow.postMessage({type:"AUTH_ERROR",error:e},"*")})}create(e,t){let n;if("connectors"!==e)throw new Error(`Unknown element type: ${e}`);return n=new o(this,t),this.activeElements.set(n._internalId,n),n}onElementIframeLoaded(e){this.initPromise.then(()=>{const t=e.getIframe();(null==t?void 0:t.contentWindow)&&setTimeout(()=>{try{const e=t.contentWindow;if(!e)return;this.tokenError?e.postMessage({type:"AUTH_ERROR",error:this.tokenError},"*"):this.token?e.postMessage({type:"AUTH_TOKEN",token:this.token},"*"):e.postMessage({type:"AUTH_ERROR",error:"No token available"},"*"),this.initConfig&&e.postMessage({type:"INIT_CONFIG",init_config:this.initConfig},"*")}catch(e){}},100)}).catch(t=>{const n=e.getIframe(),o=null==n?void 0:n.contentWindow;o&&setTimeout(()=>{try{o.postMessage({type:"AUTH_ERROR",error:`Token initialization failed: ${t instanceof Error?t.message:String(t)}`},"*")}catch(e){}},100)})}}e.ConnectorConfigurationComponent=o,e.Hyperswitch=s,e.HyperswitchElement=n,e.VERSION="1.0.0",e.loadHyperswitch=function(e){return new s(e)},Object.defineProperty(e,"__esModule",{value:!0})});
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).Hyperswitch={})}(this,function(e){"use strict";const t="undefined"!=typeof window;class i{constructor(e,i){this.isFullPage=!1,this.previousBodyOverflow="",this.showIframeTimer=null,this.iframeOrigin=null,this.instance=e,this.options=i||{},this._internalId=`hyper-el-${Math.random().toString(36).substring(7)}`,this.boundMessageHandler=null,t&&(this.element=document.createElement("div"),this.iframe=document.createElement("iframe"),this.boundMessageHandler=this.handleMessage.bind(this),this.setupElement(),this.setupIframe(),window.addEventListener("message",this.boundMessageHandler))}setupElement(){t&&(this.element.className=`hyperswitch-element ${this.options.className||""}`.trim(),this.element.dataset.hyperswitchElement=this.getElementType(),Object.assign(this.element.style,Object.assign({width:this.options.width||"100%",height:this.options.height||"500px",overflow:"hidden"},this.options.style||{})))}setupIframe(){t&&(this.iframe.src=this.getIframeSrc(),this.iframe.style.border="none",this.iframe.style.width="100%",this.iframe.style.height="100%",this.iframe.title=`Hyperswitch ${this.getElementType()}`,this.iframe.setAttribute("allow","clipboard-read; clipboard-write; clipboard-sanitized-write"),this.iframe.setAttribute("sandbox","allow-scripts allow-same-origin allow-popups allow-forms allow-modals allow-presentation allow-downloads"),this.element.appendChild(this.iframe))}handleMessage(e){var i,o,n,s;if(t&&(this.options.onMessage&&this.options.onMessage(e.data),this.acceptMessage(e)&&(this.isFullPageModalEnabled()&&("EMBEDDED_MODAL_OPEN"===(null===(i=e.data)||void 0===i?void 0:i.type)?this.setFullPage(!0):"EMBEDDED_MODAL_CLOSE"===(null===(o=e.data)||void 0===o?void 0:o.type)?this.setFullPage(!1):"EMBEDDED_MODAL_VISIBLE"===(null===(n=e.data)||void 0===n?void 0:n.type)&&this.showIframe()),"EMBEDDED_COMPONENT_RESIZE"===(null===(s=e.data)||void 0===s?void 0:s.type)))){const t=e.data.height,i=e.data.component||"";!this.isFullPage&&i===this.getElementType()&&"number"==typeof t&&t>0&&(this.element.style.height=`${t}px`,this.options.onResize&&this.options.onResize({width:this.element.clientWidth,height:t}))}}setFullPage(e){e!==this.isFullPage&&(this.isFullPage=e,this.iframe.style.visibility="hidden",e?(this.previousBodyOverflow=document.body.style.overflow,document.body.style.overflow="hidden",Object.assign(this.iframe.style,{position:"fixed",top:"0",left:"0",width:"100vw",height:"100vh",zIndex:"2147483647"})):(document.body.style.overflow=this.previousBodyOverflow,Object.assign(this.iframe.style,{position:"",top:"",left:"",width:"100%",height:"100%",zIndex:""})),this.showIframeTimer&&clearTimeout(this.showIframeTimer),this.showIframeTimer=setTimeout(()=>this.showIframe(),300)),this.postMessageToIframe({type:e?"EMBEDDED_MODAL_OPENED":"EMBEDDED_MODAL_CLOSED"})}showIframe(){this.showIframeTimer&&(clearTimeout(this.showIframeTimer),this.showIframeTimer=null),this.iframe.style.visibility=""}mount(e){if(!t)throw new Error("HyperswitchElement.mount can only be called in a browser environment");const i="string"==typeof e?document.querySelector(e):e;if(!i)throw new Error(`Invalid mount point: ${e}`);return i.appendChild(this.element),this}destroy(){t&&(this.isFullPage&&(this.isFullPage=!1,document.body.style.overflow=this.previousBodyOverflow),this.showIframeTimer&&(clearTimeout(this.showIframeTimer),this.showIframeTimer=null),this.boundMessageHandler&&window.removeEventListener("message",this.boundMessageHandler),this.element&&this.element.parentNode&&this.element.parentNode.removeChild(this.element))}getIframe(){return this.iframe}acceptMessage(e){var t;return e.source===(null===(t=this.iframe)||void 0===t?void 0:t.contentWindow)&&(null===this.iframeOrigin&&e.origin&&"null"!==e.origin&&(this.iframeOrigin=e.origin),null===this.iframeOrigin||e.origin===this.iframeOrigin)}postMessageToIframe(e){var t,i;null!==this.iframeOrigin&&(null===(i=null===(t=this.iframe)||void 0===t?void 0:t.contentWindow)||void 0===i||i.postMessage(e,this.iframeOrigin))}isFullPageModalEnabled(){return!1!==this.options.fullPageModals}}class o extends i{constructor(e,t){super(e,t)}getElementType(){return"connectors"}getIframeSrc(){return`${this.options.url||"http://localhost:9000"}/embedded/connectors`}}class n extends i{constructor(e,t){super(e,t)}getElementType(){return"payments"}getIframeSrc(){return`${this.options.url||"http://localhost:9000"}/embedded/payments`}}class s extends i{constructor(e,t){super(e,t)}getElementType(){return"refunds"}getIframeSrc(){return`${this.options.url||"http://localhost:9000"}/embedded/refunds`}}const r="undefined"!=typeof window;class l{constructor(e){if(this.token=null,this.initConfig=null,this.activeElements=new Map,this.isRefetchingToken=!1,this.tokenError=null,!e||"function"!=typeof e.fetchToken)throw new Error("loadHyperswitch requires a fetchToken callback function");this.fetchToken=e.fetchToken,this.initConfig=e.initConfig?function(e){var t,i,o,n,s,r,l,a,h,d,u,c,m,f,p,g,v,y,E,w;const T=e||{};return{settings:{colors:{primary:null!==(t=T.primaryColor)&&void 0!==t?t:null,secondary:null,background:null!==(i=T.backgroundColor)&&void 0!==i?i:null},sidebar:null,typography:null,buttons:{primary:{backgroundColor:null!==(s=null===(n=null===(o=T.buttons)||void 0===o?void 0:o.primary)||void 0===n?void 0:n.backgroundColor)&&void 0!==s?s:null,textColor:null!==(a=null===(l=null===(r=T.buttons)||void 0===r?void 0:r.primary)||void 0===l?void 0:l.textColor)&&void 0!==a?a:null,hoverBackgroundColor:null!==(u=null===(d=null===(h=T.buttons)||void 0===h?void 0:h.primary)||void 0===d?void 0:d.hoverBackgroundColor)&&void 0!==u?u:null},secondary:{backgroundColor:null!==(f=null===(m=null===(c=T.buttons)||void 0===c?void 0:c.secondary)||void 0===m?void 0:m.backgroundColor)&&void 0!==f?f:null,textColor:null!==(v=null===(g=null===(p=T.buttons)||void 0===p?void 0:p.secondary)||void 0===g?void 0:g.textColor)&&void 0!==v?v:null,hoverBackgroundColor:null!==(w=null===(E=null===(y=T.buttons)||void 0===y?void 0:y.secondary)||void 0===E?void 0:E.hoverBackgroundColor)&&void 0!==w?w:null}},borders:null,spacing:null},urls:{faviconUrl:null,logoUrl:null}}}(e.initConfig):null,this.initPromise=this.fetchInitialToken(),this.listenForMessages()}fetchInitialToken(){return(()=>{try{return this.fetchToken()}catch(e){return Promise.reject(e)}})().then(e=>{e?this.token=e:this.tokenError="Failed to fetch token: Token returned empty or undefined"}).catch(e=>{this.tokenError=`Failed to fetch token: ${e instanceof Error?e.message:String(e)}`})}listenForMessages(){r&&window.addEventListener("message",async e=>{var t,i,o;const n=Array.from(this.activeElements.values()).find(t=>t.acceptMessage(e));n&&("TOKEN_EXPIRED"===(null===(t=e.data)||void 0===t?void 0:t.type)&&!0===(null===(i=e.data)||void 0===i?void 0:i.value)?await this.refetchAndBroadcastToken():"EMBEDDED_IFRAME_READY"===(null===(o=e.data)||void 0===o?void 0:o.type)&&this.onElementIframeLoaded(n))})}async refetchAndBroadcastToken(){if(!this.isRefetchingToken){this.isRefetchingToken=!0;try{const e=await this.fetchToken();e?(this.token=e,this.tokenError=null,this.activeElements.forEach(e=>{e.postMessageToIframe({type:"AUTH_TOKEN",token:this.token})})):(this.tokenError="Failed to refetch token: Token returned empty or undefined",this.sendErrorToActiveElements(this.tokenError))}catch(e){this.tokenError=`Failed to refetch token: ${e instanceof Error?e.message:String(e)}`,this.sendErrorToActiveElements(this.tokenError)}finally{this.isRefetchingToken=!1}}}sendErrorToActiveElements(e){this.activeElements.forEach(t=>{t.postMessageToIframe({type:"AUTH_ERROR",error:e})})}create(e,t){let i;switch(e){case"connectors":i=new o(this,t);break;case"payments":i=new n(this,t);break;case"refunds":i=new s(this,t);break;default:throw new Error(`Unknown element type: ${e}`)}return this.activeElements.set(i._internalId,i),i}onElementIframeLoaded(e){this.initPromise.then(()=>{const t=e.getIframe();(null==t?void 0:t.contentWindow)&&setTimeout(()=>{var t;try{this.tokenError?e.postMessageToIframe({type:"AUTH_ERROR",error:this.tokenError}):this.token?e.postMessageToIframe({type:"AUTH_TOKEN",token:this.token}):e.postMessageToIframe({type:"AUTH_ERROR",error:"No token available"}),e.postMessageToIframe({type:"INIT_CONFIG",init_config:null!==(t=this.initConfig)&&void 0!==t?t:{},sdk_capabilities:{full_page_modal:e.isFullPageModalEnabled()}})}catch(e){}},100)}).catch(t=>{setTimeout(()=>{try{e.postMessageToIframe({type:"AUTH_ERROR",error:`Token initialization failed: ${t instanceof Error?t.message:String(t)}`})}catch(e){}},100)})}}e.ConnectorConfigurationComponent=o,e.Hyperswitch=l,e.HyperswitchElement=i,e.PaymentsComponent=n,e.RefundsComponent=s,e.VERSION="1.0.0",e.loadHyperswitch=function(e){return new l(e)},Object.defineProperty(e,"__esModule",{value:!0})});
2
2
  //# sourceMappingURL=index.min.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.min.js","sources":["../src/element.ts","../src/connector-configuration.ts","../src/hyperswitch.ts","../src/init-config.ts","../src/index.ts"],"sourcesContent":["import { Hyperswitch } from './hyperswitch';\nimport { ElementOptions } from './types';\n\nconst isBrowser = typeof window !== 'undefined';\n\nabstract class HyperswitchElement {\n protected instance: Hyperswitch;\n protected options: ElementOptions;\n public element!: HTMLElement;\n protected iframe!: HTMLIFrameElement;\n private boundMessageHandler: ((event: MessageEvent) => void) | null;\n public readonly _internalId: string;\n \n constructor(instance: Hyperswitch, options?: ElementOptions) {\n this.instance = instance;\n this.options = options || {};\n this._internalId = `hyper-el-${Math.random().toString(36).substring(7)}`;\n this.boundMessageHandler = null;\n // In SSR / non-browser environments, avoid touching DOM APIs.\n // The React wrapper only creates and mounts elements on the client,\n // so it's safe for server-side usage as long as we no-op here.\n if (!isBrowser) {\n return;\n }\n \n this.element = document.createElement('div');\n this.iframe = document.createElement('iframe');\n this.boundMessageHandler = this.handleMessage.bind(this);\n \n this.setupElement();\n this.setupIframe();\n window.addEventListener('message', this.boundMessageHandler);\n }\n\n private setupElement(): void {\n if (!isBrowser) {\n return;\n }\n\n this.element.className = `hyperswitch-element ${this.options.className || ''}`.trim();\n this.element.dataset.hyperswitchElement = this.getElementType();\n \n Object.assign(this.element.style, {\n width: this.options.width || '100%',\n height: this.options.height || '500px',\n overflow: 'hidden',\n ...(this.options.style || {})\n });\n }\n \n private setupIframe(): void {\n if (!isBrowser) {\n return;\n }\n\n this.iframe.src = this.getIframeSrc();\n this.iframe.style.border = 'none';\n this.iframe.style.width = '100%';\n this.iframe.style.height = '100%';\n this.iframe.title = `Hyperswitch ${this.getElementType()}`;\n this.iframe.setAttribute('allow', 'clipboard-read; clipboard-write; clipboard-sanitized-write');\n this.iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin allow-popups allow-forms allow-modals allow-presentation allow-downloads');\n \n this.element.appendChild(this.iframe);\n }\n \n private handleMessage(event: MessageEvent): void {\n if (!isBrowser) {\n return;\n }\n\n if (this.options.onMessage) {\n this.options.onMessage(event.data);\n }\n \n if (event.data?.type === 'EMBEDDED_COMPONENT_RESIZE') {\n const newHeight = event.data.height;\n const messageComponent = event.data.component || '';\n \n if (messageComponent === this.getElementType() && typeof newHeight === 'number' && newHeight > 0) {\n this.element.style.height = `${newHeight}px`;\n \n if (this.options.onResize) {\n this.options.onResize({\n width: this.element.clientWidth,\n height: newHeight\n });\n }\n }\n }\n }\n \n mount(domNode: string | HTMLElement): HyperswitchElement {\n if (!isBrowser) {\n throw new Error('HyperswitchElement.mount can only be called in a browser environment');\n }\n\n const parent = typeof domNode === 'string' \n ? document.querySelector(domNode) \n : domNode;\n \n if (!parent) {\n throw new Error(`Invalid mount point: ${domNode}`);\n }\n \n parent.appendChild(this.element);\n return this;\n }\n \n destroy(): void {\n if (!isBrowser) {\n return;\n }\n if (this.boundMessageHandler) {\n window.removeEventListener('message', this.boundMessageHandler);\n }\n \n if (this.element && this.element.parentNode) {\n this.element.parentNode.removeChild(this.element);\n }\n }\n \n protected abstract getElementType(): string;\n protected abstract getIframeSrc(): string;\n\n public getIframe(): HTMLIFrameElement {\n return this.iframe;\n }\n}\n\nexport { HyperswitchElement };\n","import { Hyperswitch } from './hyperswitch';\nimport { HyperswitchElement } from './element';\nimport { ElementOptions } from './types';\n\nexport class ConnectorConfigurationComponent extends HyperswitchElement {\n constructor(instance: Hyperswitch, options?: ElementOptions) {\n super(instance, options);\n }\n \n protected getElementType(): string {\n return 'connectors';\n }\n \n protected getIframeSrc(): string {\n const baseUrl = this.options.url || 'http://localhost:9000';\n return `${baseUrl}/embedded/connectors`;\n }\n}\n","import { HyperswitchElement } from './element';\nimport { ConnectorConfigurationComponent } from './connector-configuration';\nimport { HyperswitchInitOptions } from './types';\nimport { buildInitConfig,InitConfig } from './init-config';\n\nconst isBrowser = typeof window !== 'undefined';\n\nclass Hyperswitch {\n private token: string | null = null;\n private fetchToken: () => Promise<string | undefined>;\n private initConfig: InitConfig | null = null;\n private activeElements: Map<string, HyperswitchElement> = new Map();\n private isRefetchingToken: boolean = false;\n private initPromise: Promise<void>;\n private tokenError: string | null = null;\n\n constructor(options: HyperswitchInitOptions) {\n if (!options || typeof options.fetchToken !== 'function') {\n throw new Error('loadHyperswitch requires a fetchToken callback function');\n }\n\n this.fetchToken = options.fetchToken;\n this.initConfig = options.initConfig ? buildInitConfig(options.initConfig) : null;\n this.initPromise = this.fetchInitialToken();\n this.listenForMessages();\n }\n\n private fetchInitialToken(): Promise<void> {\n const eagerTokenPromise = (() => {\n try {\n return this.fetchToken();\n } catch (error) {\n return Promise.reject(error);\n }\n })();\n\n return eagerTokenPromise.then((token) => {\n if (token) {\n this.token = token;\n } else {\n this.tokenError = 'Failed to fetch token: Token returned empty or undefined';\n }\n }).catch((error) => {\n this.tokenError = `Failed to fetch token: ${error instanceof Error ? error.message : String(error)}`;\n });\n } \n\n private listenForMessages(): void {\n if (!isBrowser) {\n // In SSR / non-browser environments we can't listen for postMessage events,\n // but it's still safe to create a Hyperswitch instance (it will become\n // useful on the client where another instance will typically be created).\n return;\n }\n\n window.addEventListener(\"message\", async (event) => {\n if (event.data?.type === \"TOKEN_EXPIRED\" && event.data?.value === true) {\n await this.refetchAndBroadcastToken();\n } else if (event.data?.type === \"EMBEDDED_IFRAME_READY\") {\n // Find the element whose iframe matches the event source\n this.activeElements.forEach((element) => {\n const iframe = element.getIframe();\n if (iframe?.contentWindow === event.source) {\n this.onElementIframeLoaded(element);\n }\n });\n }\n });\n }\n\n private async refetchAndBroadcastToken(): Promise<void> {\n if (this.isRefetchingToken) {\n return;\n }\n \n this.isRefetchingToken = true;\n \n try {\n const newToken = await this.fetchToken();\n \n if (newToken) {\n this.token = newToken;\n this.tokenError = null;\n this.activeElements.forEach((element, elementId) => {\n const iframe = element.getIframe();\n if (iframe?.contentWindow) {\n iframe.contentWindow.postMessage({\n type: 'AUTH_TOKEN',\n token: this.token\n }, '*');\n }\n });\n } else {\n this.tokenError = 'Failed to refetch token: Token returned empty or undefined';\n this.sendErrorToActiveElements(this.tokenError);\n }\n } catch (error) {\n this.tokenError = `Failed to refetch token: ${error instanceof Error ? error.message : String(error)}`;\n this.sendErrorToActiveElements(this.tokenError);\n } finally {\n this.isRefetchingToken = false;\n }\n }\n\n private sendErrorToActiveElements(errorMessage: string): void {\n this.activeElements.forEach((element) => {\n const iframe = element.getIframe();\n if (iframe?.contentWindow) {\n iframe.contentWindow.postMessage({\n type: 'AUTH_ERROR',\n error: errorMessage\n }, '*');\n }\n });\n }\n\n public create(type: string, options?: any): HyperswitchElement {\n let element: HyperswitchElement;\n \n switch (type) {\n case 'connectors':\n element = new ConnectorConfigurationComponent(this, options);\n break;\n default:\n throw new Error(`Unknown element type: ${type}`);\n }\n \n this.activeElements.set(element._internalId, element);\n \n return element;\n }\n\n public onElementIframeLoaded(element: HyperswitchElement): void {\n this.initPromise.then(() => {\n const iframe = element.getIframe();\n if (!iframe?.contentWindow) {\n return;\n }\n \n setTimeout(() => {\n try {\n const contentWindow = iframe.contentWindow;\n if (!contentWindow) {\n return;\n }\n\n if (this.tokenError) {\n contentWindow.postMessage({\n type: 'AUTH_ERROR',\n error: this.tokenError\n }, '*');\n } else if (this.token) {\n contentWindow.postMessage({\n type: 'AUTH_TOKEN',\n token: this.token\n }, '*');\n } else {\n contentWindow.postMessage({\n type: 'AUTH_ERROR',\n error: 'No token available'\n }, '*');\n }\n\n // Send init_config (if available) as a separate message\n if (this.initConfig) {\n contentWindow.postMessage({\n type: 'INIT_CONFIG',\n init_config: this.initConfig\n }, '*');\n }\n } catch (error) {\n }\n }, 100);\n }).catch((error) => {\n const iframe = element.getIframe();\n const contentWindow = iframe?.contentWindow;\n if (contentWindow) {\n setTimeout(() => {\n try {\n contentWindow.postMessage({\n type: 'AUTH_ERROR',\n error: `Token initialization failed: ${error instanceof Error ? error.message : String(error)}`\n }, '*');\n } catch {\n }\n }, 100);\n }\n });\n }\n}\n\nexport function loadHyperswitch(options: HyperswitchInitOptions): Hyperswitch {\n return new Hyperswitch(options);\n}\n\nexport { Hyperswitch };\n","/**\n * Theme configuration received from the merchant.\n * This is the ONLY contract we expect merchants to follow.\n */\nexport type MerchantTheme = {\n /** Primary color */\n primaryColor?: string;\n /** Page background color */\n backgroundColor?: string;\n /** Button configurations */\n buttons?: {\n /** Primary button configuration */\n primary?: {\n /** Primary button background color */\n backgroundColor?: string;\n /** Primary button text color */\n textColor?: string;\n /** Primary button hover background color */\n hoverBackgroundColor?: string;\n };\n /** Secondary button configuration */\n secondary?: {\n /** Secondary button background color */\n backgroundColor?: string;\n /** Secondary button text color */\n textColor?: string;\n /** Secondary button hover background color */\n hoverBackgroundColor?: string;\n };\n };\n};\n\n/**\n * Full init_config payload shape sent to the Control Center.\n * Most fields are null for now; Control Center applies defaults.\n */\nexport type InitConfig = {\n settings: {\n colors: {\n primary: string | null;\n secondary: string | null;\n background: string | null;\n };\n sidebar: null;\n typography: null;\n buttons: {\n primary: {\n backgroundColor: string | null;\n textColor: string | null;\n hoverBackgroundColor: string | null;\n };\n secondary: {\n backgroundColor: string | null;\n textColor: string | null;\n hoverBackgroundColor: string | null;\n };\n };\n borders: null;\n spacing: null;\n };\n urls: {\n faviconUrl: null;\n logoUrl: null;\n };\n};\n\n/**\n * Build the init_config object that Control Center expects\n * from the simple MerchantTheme contract.\n *\n * Any missing value is set to null.\n */\nexport function buildInitConfig(merchantTheme: MerchantTheme | undefined | null): InitConfig {\n const safeTheme = merchantTheme || {};\n\n return {\n settings: {\n colors: {\n primary: safeTheme.primaryColor ?? null,\n secondary: null,\n background: safeTheme.backgroundColor ?? null\n },\n sidebar: null,\n typography: null,\n buttons: {\n primary: {\n backgroundColor: safeTheme.buttons?.primary?.backgroundColor ?? null,\n textColor: safeTheme.buttons?.primary?.textColor ?? null,\n hoverBackgroundColor: safeTheme.buttons?.primary?.hoverBackgroundColor ?? null\n },\n secondary: {\n backgroundColor: safeTheme.buttons?.secondary?.backgroundColor ?? null,\n textColor: safeTheme.buttons?.secondary?.textColor ?? null,\n hoverBackgroundColor: safeTheme.buttons?.secondary?.hoverBackgroundColor ?? null\n }\n },\n borders: null,\n spacing: null\n },\n urls: {\n faviconUrl: null,\n logoUrl: null\n }\n };\n}\n\n\n","export { loadHyperswitch, Hyperswitch } from './hyperswitch';\nexport { HyperswitchElement } from './element';\nexport { ConnectorConfigurationComponent } from './connector-configuration';\nexport type { HyperswitchInitOptions, ElementOptions } from './types';\nexport type { MerchantTheme } from './init-config';\n\nexport const VERSION = '1.0.0';\n"],"names":["isBrowser","window","HyperswitchElement","constructor","instance","options","this","_internalId","Math","random","toString","substring","boundMessageHandler","element","document","createElement","iframe","handleMessage","bind","setupElement","setupIframe","addEventListener","className","trim","dataset","hyperswitchElement","getElementType","Object","assign","style","width","height","overflow","src","getIframeSrc","border","title","setAttribute","appendChild","event","onMessage","data","_a","type","newHeight","component","onResize","clientWidth","mount","domNode","Error","parent","querySelector","destroy","removeEventListener","parentNode","removeChild","getIframe","ConnectorConfigurationComponent","super","url","Hyperswitch","token","initConfig","activeElements","Map","isRefetchingToken","tokenError","fetchToken","merchantTheme","safeTheme","settings","colors","primary","primaryColor","secondary","background","_b","backgroundColor","sidebar","typography","buttons","_e","_d","_c","textColor","_h","_g","_f","hoverBackgroundColor","_l","_k","_j","_p","_o","_m","_s","_r","_q","_v","_u","_t","borders","spacing","urls","faviconUrl","logoUrl","buildInitConfig","initPromise","fetchInitialToken","listenForMessages","error","Promise","reject","then","catch","message","String","async","value","refetchAndBroadcastToken","forEach","contentWindow","source","onElementIframeLoaded","newToken","elementId","postMessage","sendErrorToActiveElements","errorMessage","create","set","setTimeout","init_config"],"mappings":"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"}
1
+ {"version":3,"file":"index.min.js","sources":["../src/element.ts","../src/connector-configuration.ts","../src/payments.ts","../src/refunds.ts","../src/hyperswitch.ts","../src/init-config.ts","../src/index.ts"],"sourcesContent":["import { Hyperswitch } from './hyperswitch';\nimport { ElementOptions } from './types';\n\nconst isBrowser = typeof window !== 'undefined';\n\nabstract class HyperswitchElement {\n protected instance: Hyperswitch;\n protected options: ElementOptions;\n public element!: HTMLElement;\n protected iframe!: HTMLIFrameElement;\n private boundMessageHandler: ((event: MessageEvent) => void) | null;\n public readonly _internalId: string;\n private isFullPage: boolean = false;\n private previousBodyOverflow: string = '';\n private showIframeTimer: ReturnType<typeof setTimeout> | null = null;\n private iframeOrigin: string | null = null;\n \n constructor(instance: Hyperswitch, options?: ElementOptions) {\n this.instance = instance;\n this.options = options || {};\n this._internalId = `hyper-el-${Math.random().toString(36).substring(7)}`;\n this.boundMessageHandler = null;\n // In SSR / non-browser environments, avoid touching DOM APIs.\n // The React wrapper only creates and mounts elements on the client,\n // so it's safe for server-side usage as long as we no-op here.\n if (!isBrowser) {\n return;\n }\n \n this.element = document.createElement('div');\n this.iframe = document.createElement('iframe');\n this.boundMessageHandler = this.handleMessage.bind(this);\n \n this.setupElement();\n this.setupIframe();\n window.addEventListener('message', this.boundMessageHandler);\n }\n\n private setupElement(): void {\n if (!isBrowser) {\n return;\n }\n\n this.element.className = `hyperswitch-element ${this.options.className || ''}`.trim();\n this.element.dataset.hyperswitchElement = this.getElementType();\n \n Object.assign(this.element.style, {\n width: this.options.width || '100%',\n height: this.options.height || '500px',\n overflow: 'hidden',\n ...(this.options.style || {})\n });\n }\n \n private setupIframe(): void {\n if (!isBrowser) {\n return;\n }\n\n this.iframe.src = this.getIframeSrc();\n this.iframe.style.border = 'none';\n this.iframe.style.width = '100%';\n this.iframe.style.height = '100%';\n this.iframe.title = `Hyperswitch ${this.getElementType()}`;\n this.iframe.setAttribute('allow', 'clipboard-read; clipboard-write; clipboard-sanitized-write');\n this.iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin allow-popups allow-forms allow-modals allow-presentation allow-downloads');\n \n this.element.appendChild(this.iframe);\n }\n \n private handleMessage(event: MessageEvent): void {\n if (!isBrowser) {\n return;\n }\n\n if (this.options.onMessage) {\n this.options.onMessage(event.data);\n }\n \n if (!this.acceptMessage(event)) {\n return;\n }\n \n if (this.isFullPageModalEnabled()) {\n if (event.data?.type === 'EMBEDDED_MODAL_OPEN') {\n this.setFullPage(true);\n } else if (event.data?.type === 'EMBEDDED_MODAL_CLOSE') {\n this.setFullPage(false);\n } else if (event.data?.type === 'EMBEDDED_MODAL_VISIBLE') {\n this.showIframe();\n }\n }\n \n if (event.data?.type === 'EMBEDDED_COMPONENT_RESIZE') {\n const newHeight = event.data.height;\n const messageComponent = event.data.component || '';\n \n if (!this.isFullPage && messageComponent === this.getElementType() && typeof newHeight === 'number' && newHeight > 0) {\n this.element.style.height = `${newHeight}px`;\n \n if (this.options.onResize) {\n this.options.onResize({\n width: this.element.clientWidth,\n height: newHeight\n });\n }\n }\n }\n }\n \n private setFullPage(isFullPage: boolean): void {\n if (isFullPage !== this.isFullPage) {\n this.isFullPage = isFullPage;\n this.iframe.style.visibility = 'hidden';\n \n if (isFullPage) {\n this.previousBodyOverflow = document.body.style.overflow;\n document.body.style.overflow = 'hidden';\n Object.assign(this.iframe.style, {\n position: 'fixed',\n top: '0',\n left: '0',\n width: '100vw',\n height: '100vh',\n zIndex: '2147483647'\n });\n } else {\n document.body.style.overflow = this.previousBodyOverflow;\n Object.assign(this.iframe.style, {\n position: '',\n top: '',\n left: '',\n width: '100%',\n height: '100%',\n zIndex: ''\n });\n }\n \n if (this.showIframeTimer) {\n clearTimeout(this.showIframeTimer);\n }\n this.showIframeTimer = setTimeout(() => this.showIframe(), 300);\n }\n \n this.postMessageToIframe({\n type: isFullPage ? 'EMBEDDED_MODAL_OPENED' : 'EMBEDDED_MODAL_CLOSED'\n });\n }\n \n private showIframe(): void {\n if (this.showIframeTimer) {\n clearTimeout(this.showIframeTimer);\n this.showIframeTimer = null;\n }\n this.iframe.style.visibility = '';\n }\n \n mount(domNode: string | HTMLElement): HyperswitchElement {\n if (!isBrowser) {\n throw new Error('HyperswitchElement.mount can only be called in a browser environment');\n }\n\n const parent = typeof domNode === 'string' \n ? document.querySelector(domNode) \n : domNode;\n \n if (!parent) {\n throw new Error(`Invalid mount point: ${domNode}`);\n }\n \n parent.appendChild(this.element);\n return this;\n }\n \n destroy(): void {\n if (!isBrowser) {\n return;\n }\n if (this.isFullPage) {\n this.isFullPage = false;\n document.body.style.overflow = this.previousBodyOverflow;\n }\n if (this.showIframeTimer) {\n clearTimeout(this.showIframeTimer);\n this.showIframeTimer = null;\n }\n if (this.boundMessageHandler) {\n window.removeEventListener('message', this.boundMessageHandler);\n }\n \n if (this.element && this.element.parentNode) {\n this.element.parentNode.removeChild(this.element);\n }\n }\n \n protected abstract getElementType(): string;\n protected abstract getIframeSrc(): string;\n\n public getIframe(): HTMLIFrameElement {\n return this.iframe;\n }\n\n public acceptMessage(event: MessageEvent): boolean {\n if (event.source !== this.iframe?.contentWindow) {\n return false;\n }\n if (this.iframeOrigin === null && event.origin && event.origin !== 'null') {\n this.iframeOrigin = event.origin;\n }\n return this.iframeOrigin === null || event.origin === this.iframeOrigin;\n }\n\n public postMessageToIframe(message: Record<string, unknown>): void {\n if (this.iframeOrigin === null) {\n return;\n }\n this.iframe?.contentWindow?.postMessage(message, this.iframeOrigin);\n }\n\n public isFullPageModalEnabled(): boolean {\n return this.options.fullPageModals !== false;\n }\n}\n\nexport { HyperswitchElement };\n","import { Hyperswitch } from './hyperswitch';\nimport { HyperswitchElement } from './element';\nimport { ElementOptions } from './types';\n\nexport class ConnectorConfigurationComponent extends HyperswitchElement {\n constructor(instance: Hyperswitch, options?: ElementOptions) {\n super(instance, options);\n }\n \n protected getElementType(): string {\n return 'connectors';\n }\n \n protected getIframeSrc(): string {\n const baseUrl = this.options.url || 'http://localhost:9000';\n return `${baseUrl}/embedded/connectors`;\n }\n}\n","import { Hyperswitch } from './hyperswitch';\nimport { HyperswitchElement } from './element';\nimport { ElementOptions } from './types';\n\nexport class PaymentsComponent extends HyperswitchElement {\n constructor(instance: Hyperswitch, options?: ElementOptions) {\n super(instance, options);\n }\n \n protected getElementType(): string {\n return 'payments';\n }\n \n protected getIframeSrc(): string {\n const baseUrl = this.options.url || 'http://localhost:9000';\n return `${baseUrl}/embedded/payments`;\n }\n}\n","import { Hyperswitch } from './hyperswitch';\nimport { HyperswitchElement } from './element';\nimport { ElementOptions } from './types';\n\nexport class RefundsComponent extends HyperswitchElement {\n constructor(instance: Hyperswitch, options?: ElementOptions) {\n super(instance, options);\n }\n \n protected getElementType(): string {\n return 'refunds';\n }\n \n protected getIframeSrc(): string {\n const baseUrl = this.options.url || 'http://localhost:9000';\n return `${baseUrl}/embedded/refunds`;\n }\n}\n","import { HyperswitchElement } from './element';\nimport { ConnectorConfigurationComponent } from './connector-configuration';\nimport { PaymentsComponent } from './payments';\nimport { RefundsComponent } from './refunds';\nimport { HyperswitchInitOptions } from './types';\nimport { buildInitConfig,InitConfig } from './init-config';\n\nconst isBrowser = typeof window !== 'undefined';\n\nclass Hyperswitch {\n private token: string | null = null;\n private fetchToken: () => Promise<string | undefined>;\n private initConfig: InitConfig | null = null;\n private activeElements: Map<string, HyperswitchElement> = new Map();\n private isRefetchingToken: boolean = false;\n private initPromise: Promise<void>;\n private tokenError: string | null = null;\n\n constructor(options: HyperswitchInitOptions) {\n if (!options || typeof options.fetchToken !== 'function') {\n throw new Error('loadHyperswitch requires a fetchToken callback function');\n }\n\n this.fetchToken = options.fetchToken;\n this.initConfig = options.initConfig ? buildInitConfig(options.initConfig) : null;\n this.initPromise = this.fetchInitialToken();\n this.listenForMessages();\n }\n\n private fetchInitialToken(): Promise<void> {\n const eagerTokenPromise = (() => {\n try {\n return this.fetchToken();\n } catch (error) {\n return Promise.reject(error);\n }\n })();\n\n return eagerTokenPromise.then((token) => {\n if (token) {\n this.token = token;\n } else {\n this.tokenError = 'Failed to fetch token: Token returned empty or undefined';\n }\n }).catch((error) => {\n this.tokenError = `Failed to fetch token: ${error instanceof Error ? error.message : String(error)}`;\n });\n } \n\n private listenForMessages(): void {\n if (!isBrowser) {\n // In SSR / non-browser environments we can't listen for postMessage events,\n // but it's still safe to create a Hyperswitch instance (it will become\n // useful on the client where another instance will typically be created).\n return;\n }\n\n window.addEventListener(\"message\", async (event) => {\n const sourceElement = Array.from(this.activeElements.values()).find(\n (element) => element.acceptMessage(event)\n );\n if (!sourceElement) {\n return;\n }\n\n if (event.data?.type === \"TOKEN_EXPIRED\" && event.data?.value === true) {\n await this.refetchAndBroadcastToken();\n } else if (event.data?.type === \"EMBEDDED_IFRAME_READY\") {\n this.onElementIframeLoaded(sourceElement);\n }\n });\n }\n\n private async refetchAndBroadcastToken(): Promise<void> {\n if (this.isRefetchingToken) {\n return;\n }\n \n this.isRefetchingToken = true;\n \n try {\n const newToken = await this.fetchToken();\n \n if (newToken) {\n this.token = newToken;\n this.tokenError = null;\n this.activeElements.forEach((element) => {\n element.postMessageToIframe({\n type: 'AUTH_TOKEN',\n token: this.token\n });\n });\n } else {\n this.tokenError = 'Failed to refetch token: Token returned empty or undefined';\n this.sendErrorToActiveElements(this.tokenError);\n }\n } catch (error) {\n this.tokenError = `Failed to refetch token: ${error instanceof Error ? error.message : String(error)}`;\n this.sendErrorToActiveElements(this.tokenError);\n } finally {\n this.isRefetchingToken = false;\n }\n }\n\n private sendErrorToActiveElements(errorMessage: string): void {\n this.activeElements.forEach((element) => {\n element.postMessageToIframe({\n type: 'AUTH_ERROR',\n error: errorMessage\n });\n });\n }\n\n public create(type: string, options?: any): HyperswitchElement {\n let element: HyperswitchElement;\n \n switch (type) {\n case 'connectors':\n element = new ConnectorConfigurationComponent(this, options);\n break;\n case 'payments':\n element = new PaymentsComponent(this, options);\n break;\n case 'refunds':\n element = new RefundsComponent(this, options);\n break;\n default:\n throw new Error(`Unknown element type: ${type}`);\n }\n \n this.activeElements.set(element._internalId, element);\n \n return element;\n }\n\n public onElementIframeLoaded(element: HyperswitchElement): void {\n this.initPromise.then(() => {\n const iframe = element.getIframe();\n if (!iframe?.contentWindow) {\n return;\n }\n \n setTimeout(() => {\n try {\n if (this.tokenError) {\n element.postMessageToIframe({\n type: 'AUTH_ERROR',\n error: this.tokenError\n });\n } else if (this.token) {\n element.postMessageToIframe({\n type: 'AUTH_TOKEN',\n token: this.token\n });\n } else {\n element.postMessageToIframe({\n type: 'AUTH_ERROR',\n error: 'No token available'\n });\n }\n\n // Always send init_config. If merchant doesn't provide it, send an empty object.\n element.postMessageToIframe({\n type: 'INIT_CONFIG',\n init_config: this.initConfig ?? {},\n sdk_capabilities: { full_page_modal: element.isFullPageModalEnabled() }\n });\n } catch (error) {\n }\n }, 100);\n }).catch((error) => {\n setTimeout(() => {\n try {\n element.postMessageToIframe({\n type: 'AUTH_ERROR',\n error: `Token initialization failed: ${error instanceof Error ? error.message : String(error)}`\n });\n } catch {\n }\n }, 100);\n });\n }\n}\n\nexport function loadHyperswitch(options: HyperswitchInitOptions): Hyperswitch {\n return new Hyperswitch(options);\n}\n\nexport { Hyperswitch };\n","/**\n * Theme configuration received from the merchant.\n * This is the ONLY contract we expect merchants to follow.\n */\nexport type MerchantTheme = {\n /** Primary color */\n primaryColor?: string;\n /** Page background color */\n backgroundColor?: string;\n /** Button configurations */\n buttons?: {\n /** Primary button configuration */\n primary?: {\n /** Primary button background color */\n backgroundColor?: string;\n /** Primary button text color */\n textColor?: string;\n /** Primary button hover background color */\n hoverBackgroundColor?: string;\n };\n /** Secondary button configuration */\n secondary?: {\n /** Secondary button background color */\n backgroundColor?: string;\n /** Secondary button text color */\n textColor?: string;\n /** Secondary button hover background color */\n hoverBackgroundColor?: string;\n };\n };\n};\n\n/**\n * Full init_config payload shape sent to the Control Center.\n * Most fields are null for now; Control Center applies defaults.\n */\nexport type InitConfig = {\n settings: {\n colors: {\n primary: string | null;\n secondary: string | null;\n background: string | null;\n };\n sidebar: null;\n typography: null;\n buttons: {\n primary: {\n backgroundColor: string | null;\n textColor: string | null;\n hoverBackgroundColor: string | null;\n };\n secondary: {\n backgroundColor: string | null;\n textColor: string | null;\n hoverBackgroundColor: string | null;\n };\n };\n borders: null;\n spacing: null;\n };\n urls: {\n faviconUrl: null;\n logoUrl: null;\n };\n};\n\n/**\n * Build the init_config object that Control Center expects\n * from the simple MerchantTheme contract.\n *\n * Any missing value is set to null.\n */\nexport function buildInitConfig(merchantTheme: MerchantTheme | undefined | null): InitConfig {\n const safeTheme = merchantTheme || {};\n\n return {\n settings: {\n colors: {\n primary: safeTheme.primaryColor ?? null,\n secondary: null,\n background: safeTheme.backgroundColor ?? null\n },\n sidebar: null,\n typography: null,\n buttons: {\n primary: {\n backgroundColor: safeTheme.buttons?.primary?.backgroundColor ?? null,\n textColor: safeTheme.buttons?.primary?.textColor ?? null,\n hoverBackgroundColor: safeTheme.buttons?.primary?.hoverBackgroundColor ?? null\n },\n secondary: {\n backgroundColor: safeTheme.buttons?.secondary?.backgroundColor ?? null,\n textColor: safeTheme.buttons?.secondary?.textColor ?? null,\n hoverBackgroundColor: safeTheme.buttons?.secondary?.hoverBackgroundColor ?? null\n }\n },\n borders: null,\n spacing: null\n },\n urls: {\n faviconUrl: null,\n logoUrl: null\n }\n };\n}\n\n\n","export { loadHyperswitch, Hyperswitch } from './hyperswitch';\nexport { HyperswitchElement } from './element';\nexport { ConnectorConfigurationComponent } from './connector-configuration';\nexport { PaymentsComponent } from './payments';\nexport { RefundsComponent } from './refunds';\nexport type { HyperswitchInitOptions, ElementOptions } from './types';\nexport type { MerchantTheme } from './init-config';\n\nexport const VERSION = '1.0.0';\n"],"names":["isBrowser","window","HyperswitchElement","constructor","instance","options","this","isFullPage","previousBodyOverflow","showIframeTimer","iframeOrigin","_internalId","Math","random","toString","substring","boundMessageHandler","element","document","createElement","iframe","handleMessage","bind","setupElement","setupIframe","addEventListener","className","trim","dataset","hyperswitchElement","getElementType","Object","assign","style","width","height","overflow","src","getIframeSrc","border","title","setAttribute","appendChild","event","onMessage","data","acceptMessage","isFullPageModalEnabled","_a","type","setFullPage","_b","_c","showIframe","_d","newHeight","messageComponent","component","onResize","clientWidth","visibility","body","position","top","left","zIndex","clearTimeout","setTimeout","postMessageToIframe","mount","domNode","Error","parent","querySelector","destroy","removeEventListener","parentNode","removeChild","getIframe","source","contentWindow","origin","message","postMessage","fullPageModals","ConnectorConfigurationComponent","super","url","PaymentsComponent","RefundsComponent","Hyperswitch","token","initConfig","activeElements","Map","isRefetchingToken","tokenError","fetchToken","merchantTheme","safeTheme","settings","colors","primary","primaryColor","secondary","background","backgroundColor","sidebar","typography","buttons","_e","textColor","_h","_g","_f","hoverBackgroundColor","_l","_k","_j","_p","_o","_m","_s","_r","_q","_v","_u","_t","borders","spacing","urls","faviconUrl","logoUrl","buildInitConfig","initPromise","fetchInitialToken","listenForMessages","error","Promise","reject","then","catch","String","async","sourceElement","Array","from","values","find","value","refetchAndBroadcastToken","onElementIframeLoaded","newToken","forEach","sendErrorToActiveElements","errorMessage","create","set","init_config","sdk_capabilities","full_page_modal"],"mappings":"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"}
package/dist/index.umd.js CHANGED
@@ -7,6 +7,10 @@
7
7
  const isBrowser$1 = typeof window !== 'undefined';
8
8
  class HyperswitchElement {
9
9
  constructor(instance, options) {
10
+ this.isFullPage = false;
11
+ this.previousBodyOverflow = '';
12
+ this.showIframeTimer = null;
13
+ this.iframeOrigin = null;
10
14
  this.instance = instance;
11
15
  this.options = options || {};
12
16
  this._internalId = `hyper-el-${Math.random().toString(36).substring(7)}`;
@@ -46,17 +50,31 @@
46
50
  this.element.appendChild(this.iframe);
47
51
  }
48
52
  handleMessage(event) {
49
- var _a;
53
+ var _a, _b, _c, _d;
50
54
  if (!isBrowser$1) {
51
55
  return;
52
56
  }
53
57
  if (this.options.onMessage) {
54
58
  this.options.onMessage(event.data);
55
59
  }
56
- if (((_a = event.data) === null || _a === void 0 ? void 0 : _a.type) === 'EMBEDDED_COMPONENT_RESIZE') {
60
+ if (!this.acceptMessage(event)) {
61
+ return;
62
+ }
63
+ if (this.isFullPageModalEnabled()) {
64
+ if (((_a = event.data) === null || _a === void 0 ? void 0 : _a.type) === 'EMBEDDED_MODAL_OPEN') {
65
+ this.setFullPage(true);
66
+ }
67
+ else if (((_b = event.data) === null || _b === void 0 ? void 0 : _b.type) === 'EMBEDDED_MODAL_CLOSE') {
68
+ this.setFullPage(false);
69
+ }
70
+ else if (((_c = event.data) === null || _c === void 0 ? void 0 : _c.type) === 'EMBEDDED_MODAL_VISIBLE') {
71
+ this.showIframe();
72
+ }
73
+ }
74
+ if (((_d = event.data) === null || _d === void 0 ? void 0 : _d.type) === 'EMBEDDED_COMPONENT_RESIZE') {
57
75
  const newHeight = event.data.height;
58
76
  const messageComponent = event.data.component || '';
59
- if (messageComponent === this.getElementType() && typeof newHeight === 'number' && newHeight > 0) {
77
+ if (!this.isFullPage && messageComponent === this.getElementType() && typeof newHeight === 'number' && newHeight > 0) {
60
78
  this.element.style.height = `${newHeight}px`;
61
79
  if (this.options.onResize) {
62
80
  this.options.onResize({
@@ -67,6 +85,49 @@
67
85
  }
68
86
  }
69
87
  }
88
+ setFullPage(isFullPage) {
89
+ if (isFullPage !== this.isFullPage) {
90
+ this.isFullPage = isFullPage;
91
+ this.iframe.style.visibility = 'hidden';
92
+ if (isFullPage) {
93
+ this.previousBodyOverflow = document.body.style.overflow;
94
+ document.body.style.overflow = 'hidden';
95
+ Object.assign(this.iframe.style, {
96
+ position: 'fixed',
97
+ top: '0',
98
+ left: '0',
99
+ width: '100vw',
100
+ height: '100vh',
101
+ zIndex: '2147483647'
102
+ });
103
+ }
104
+ else {
105
+ document.body.style.overflow = this.previousBodyOverflow;
106
+ Object.assign(this.iframe.style, {
107
+ position: '',
108
+ top: '',
109
+ left: '',
110
+ width: '100%',
111
+ height: '100%',
112
+ zIndex: ''
113
+ });
114
+ }
115
+ if (this.showIframeTimer) {
116
+ clearTimeout(this.showIframeTimer);
117
+ }
118
+ this.showIframeTimer = setTimeout(() => this.showIframe(), 300);
119
+ }
120
+ this.postMessageToIframe({
121
+ type: isFullPage ? 'EMBEDDED_MODAL_OPENED' : 'EMBEDDED_MODAL_CLOSED'
122
+ });
123
+ }
124
+ showIframe() {
125
+ if (this.showIframeTimer) {
126
+ clearTimeout(this.showIframeTimer);
127
+ this.showIframeTimer = null;
128
+ }
129
+ this.iframe.style.visibility = '';
130
+ }
70
131
  mount(domNode) {
71
132
  if (!isBrowser$1) {
72
133
  throw new Error('HyperswitchElement.mount can only be called in a browser environment');
@@ -84,6 +145,14 @@
84
145
  if (!isBrowser$1) {
85
146
  return;
86
147
  }
148
+ if (this.isFullPage) {
149
+ this.isFullPage = false;
150
+ document.body.style.overflow = this.previousBodyOverflow;
151
+ }
152
+ if (this.showIframeTimer) {
153
+ clearTimeout(this.showIframeTimer);
154
+ this.showIframeTimer = null;
155
+ }
87
156
  if (this.boundMessageHandler) {
88
157
  window.removeEventListener('message', this.boundMessageHandler);
89
158
  }
@@ -94,6 +163,26 @@
94
163
  getIframe() {
95
164
  return this.iframe;
96
165
  }
166
+ acceptMessage(event) {
167
+ var _a;
168
+ if (event.source !== ((_a = this.iframe) === null || _a === void 0 ? void 0 : _a.contentWindow)) {
169
+ return false;
170
+ }
171
+ if (this.iframeOrigin === null && event.origin && event.origin !== 'null') {
172
+ this.iframeOrigin = event.origin;
173
+ }
174
+ return this.iframeOrigin === null || event.origin === this.iframeOrigin;
175
+ }
176
+ postMessageToIframe(message) {
177
+ var _a, _b;
178
+ if (this.iframeOrigin === null) {
179
+ return;
180
+ }
181
+ (_b = (_a = this.iframe) === null || _a === void 0 ? void 0 : _a.contentWindow) === null || _b === void 0 ? void 0 : _b.postMessage(message, this.iframeOrigin);
182
+ }
183
+ isFullPageModalEnabled() {
184
+ return this.options.fullPageModals !== false;
185
+ }
97
186
  }
98
187
 
99
188
  class ConnectorConfigurationComponent extends HyperswitchElement {
@@ -109,6 +198,32 @@
109
198
  }
110
199
  }
111
200
 
201
+ class PaymentsComponent extends HyperswitchElement {
202
+ constructor(instance, options) {
203
+ super(instance, options);
204
+ }
205
+ getElementType() {
206
+ return 'payments';
207
+ }
208
+ getIframeSrc() {
209
+ const baseUrl = this.options.url || 'http://localhost:9000';
210
+ return `${baseUrl}/embedded/payments`;
211
+ }
212
+ }
213
+
214
+ class RefundsComponent extends HyperswitchElement {
215
+ constructor(instance, options) {
216
+ super(instance, options);
217
+ }
218
+ getElementType() {
219
+ return 'refunds';
220
+ }
221
+ getIframeSrc() {
222
+ const baseUrl = this.options.url || 'http://localhost:9000';
223
+ return `${baseUrl}/embedded/refunds`;
224
+ }
225
+ }
226
+
112
227
  /**
113
228
  * Build the init_config object that Control Center expects
114
229
  * from the simple MerchantTheme contract.
@@ -194,17 +309,15 @@
194
309
  }
195
310
  window.addEventListener("message", async (event) => {
196
311
  var _a, _b, _c;
312
+ const sourceElement = Array.from(this.activeElements.values()).find((element) => element.acceptMessage(event));
313
+ if (!sourceElement) {
314
+ return;
315
+ }
197
316
  if (((_a = event.data) === null || _a === void 0 ? void 0 : _a.type) === "TOKEN_EXPIRED" && ((_b = event.data) === null || _b === void 0 ? void 0 : _b.value) === true) {
198
317
  await this.refetchAndBroadcastToken();
199
318
  }
200
319
  else if (((_c = event.data) === null || _c === void 0 ? void 0 : _c.type) === "EMBEDDED_IFRAME_READY") {
201
- // Find the element whose iframe matches the event source
202
- this.activeElements.forEach((element) => {
203
- const iframe = element.getIframe();
204
- if ((iframe === null || iframe === void 0 ? void 0 : iframe.contentWindow) === event.source) {
205
- this.onElementIframeLoaded(element);
206
- }
207
- });
320
+ this.onElementIframeLoaded(sourceElement);
208
321
  }
209
322
  });
210
323
  }
@@ -218,14 +331,11 @@
218
331
  if (newToken) {
219
332
  this.token = newToken;
220
333
  this.tokenError = null;
221
- this.activeElements.forEach((element, elementId) => {
222
- const iframe = element.getIframe();
223
- if (iframe === null || iframe === void 0 ? void 0 : iframe.contentWindow) {
224
- iframe.contentWindow.postMessage({
225
- type: 'AUTH_TOKEN',
226
- token: this.token
227
- }, '*');
228
- }
334
+ this.activeElements.forEach((element) => {
335
+ element.postMessageToIframe({
336
+ type: 'AUTH_TOKEN',
337
+ token: this.token
338
+ });
229
339
  });
230
340
  }
231
341
  else {
@@ -243,13 +353,10 @@
243
353
  }
244
354
  sendErrorToActiveElements(errorMessage) {
245
355
  this.activeElements.forEach((element) => {
246
- const iframe = element.getIframe();
247
- if (iframe === null || iframe === void 0 ? void 0 : iframe.contentWindow) {
248
- iframe.contentWindow.postMessage({
249
- type: 'AUTH_ERROR',
250
- error: errorMessage
251
- }, '*');
252
- }
356
+ element.postMessageToIframe({
357
+ type: 'AUTH_ERROR',
358
+ error: errorMessage
359
+ });
253
360
  });
254
361
  }
255
362
  create(type, options) {
@@ -258,6 +365,12 @@
258
365
  case 'connectors':
259
366
  element = new ConnectorConfigurationComponent(this, options);
260
367
  break;
368
+ case 'payments':
369
+ element = new PaymentsComponent(this, options);
370
+ break;
371
+ case 'refunds':
372
+ element = new RefundsComponent(this, options);
373
+ break;
261
374
  default:
262
375
  throw new Error(`Unknown element type: ${type}`);
263
376
  }
@@ -271,55 +384,47 @@
271
384
  return;
272
385
  }
273
386
  setTimeout(() => {
387
+ var _a;
274
388
  try {
275
- const contentWindow = iframe.contentWindow;
276
- if (!contentWindow) {
277
- return;
278
- }
279
389
  if (this.tokenError) {
280
- contentWindow.postMessage({
390
+ element.postMessageToIframe({
281
391
  type: 'AUTH_ERROR',
282
392
  error: this.tokenError
283
- }, '*');
393
+ });
284
394
  }
285
395
  else if (this.token) {
286
- contentWindow.postMessage({
396
+ element.postMessageToIframe({
287
397
  type: 'AUTH_TOKEN',
288
398
  token: this.token
289
- }, '*');
399
+ });
290
400
  }
291
401
  else {
292
- contentWindow.postMessage({
402
+ element.postMessageToIframe({
293
403
  type: 'AUTH_ERROR',
294
404
  error: 'No token available'
295
- }, '*');
296
- }
297
- // Send init_config (if available) as a separate message
298
- if (this.initConfig) {
299
- contentWindow.postMessage({
300
- type: 'INIT_CONFIG',
301
- init_config: this.initConfig
302
- }, '*');
405
+ });
303
406
  }
407
+ // Always send init_config. If merchant doesn't provide it, send an empty object.
408
+ element.postMessageToIframe({
409
+ type: 'INIT_CONFIG',
410
+ init_config: (_a = this.initConfig) !== null && _a !== void 0 ? _a : {},
411
+ sdk_capabilities: { full_page_modal: element.isFullPageModalEnabled() }
412
+ });
304
413
  }
305
414
  catch (error) {
306
415
  }
307
416
  }, 100);
308
417
  }).catch((error) => {
309
- const iframe = element.getIframe();
310
- const contentWindow = iframe === null || iframe === void 0 ? void 0 : iframe.contentWindow;
311
- if (contentWindow) {
312
- setTimeout(() => {
313
- try {
314
- contentWindow.postMessage({
315
- type: 'AUTH_ERROR',
316
- error: `Token initialization failed: ${error instanceof Error ? error.message : String(error)}`
317
- }, '*');
318
- }
319
- catch (_a) {
320
- }
321
- }, 100);
322
- }
418
+ setTimeout(() => {
419
+ try {
420
+ element.postMessageToIframe({
421
+ type: 'AUTH_ERROR',
422
+ error: `Token initialization failed: ${error instanceof Error ? error.message : String(error)}`
423
+ });
424
+ }
425
+ catch (_a) {
426
+ }
427
+ }, 100);
323
428
  });
324
429
  }
325
430
  }
@@ -332,6 +437,8 @@
332
437
  exports.ConnectorConfigurationComponent = ConnectorConfigurationComponent;
333
438
  exports.Hyperswitch = Hyperswitch;
334
439
  exports.HyperswitchElement = HyperswitchElement;
440
+ exports.PaymentsComponent = PaymentsComponent;
441
+ exports.RefundsComponent = RefundsComponent;
335
442
  exports.VERSION = VERSION;
336
443
  exports.loadHyperswitch = loadHyperswitch;
337
444