UNPKG

@trycourier/courier-js

Version:

A browser-safe API wrapper

3 lines (2 loc) 27.8 kB
!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).CourierJS={})}(this,(function(e){"use strict";var t=Object.defineProperty,n=(e,n,s)=>((e,n,s)=>n in e?t(e,n,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[n]=s)(e,"symbol"!=typeof n?n+"":n,s);const s=e=>Object.freeze({courier:Object.freeze({...e.courier}),inbox:Object.freeze({...e.inbox})}),i={us:s({courier:{rest:"https://api.courier.com",graphql:"https://api.courier.com/client/q"},inbox:{graphql:"https://inbox.courier.com/q",webSocket:"wss://realtime.courier.io"}}),eu:s({courier:{rest:"https://api.eu.courier.com",graphql:"https://api.eu.courier.com/client/q"},inbox:{graphql:"https://inbox.eu.courier.io/q",webSocket:"wss://realtime.eu.courier.io"}})},o=i.us,r=i.eu,a=(e="us")=>{return{courier:{...(t=i[e]).courier},inbox:{...t.inbox}};var t},c=e=>{const t=o;return{courier:{rest:(null==e?void 0:e.courier.rest)||t.courier.rest,graphql:(null==e?void 0:e.courier.graphql)||t.courier.graphql},inbox:{graphql:(null==e?void 0:e.inbox.graphql)||t.inbox.graphql,webSocket:(null==e?void 0:e.inbox.webSocket)||t.inbox.webSocket}}};var u=(e=>(e.Subscribe="subscribe",e.Unsubscribe="unsubscribe",e.Pong="pong",e.Ping="ping",e.GetConfig="get-config",e))(u||{}),h=(e=>(e.Ping="ping",e))(h||{}),d=(e=>(e.NewMessage="message",e.Archive="archive",e.ArchiveAll="archive-all",e.ArchiveRead="archive-read",e.Clicked="clicked",e.MarkAllRead="mark-all-read",e.Opened="opened",e.Read="read",e.Unarchive="unarchive",e.Unopened="unopened",e.Unread="unread",e))(d||{});class l{constructor(e){n(this,"PREFIX","[COURIER]"),this.showLogs=e}warn(e,...t){this.showLogs&&console.warn(`${this.PREFIX} ${e}`,...t)}log(e,...t){this.showLogs&&console.log(`${this.PREFIX} ${e}`,...t)}error(e,...t){this.showLogs&&console.error(`${this.PREFIX} ${e}`,...t)}debug(e,...t){this.showLogs&&console.debug(`${this.PREFIX} ${e}`,...t)}info(e,...t){this.showLogs&&console.info(`${this.PREFIX} ${e}`,...t)}}const p=class e{static nanoid(t=21){let n="",s=crypto.getRandomValues(new Uint8Array(t|=0));for(;t--;)n+=e.ALPHABET[63&s[t]];return n}};n(p,"ALPHABET","useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict");let g=p;const m="x-courier-ua",I="sdk",y="sdkv",v="cid";class f extends Error{constructor(e,t,n){super(t),this.code=e,this.type=n,this.name="CourierRequestError"}}function b(e,t,n,s){e.log(`\n📡 New Courier ${n} Request: ${t}\nURL: ${s.url}\n${s.method?`Method: ${s.method}`:""}\n${s.query?`Query: ${s.query}`:""}\n${s.variables?`Variables: ${JSON.stringify(s.variables,null,2)}`:""}\nHeaders: ${JSON.stringify(s.headers,null,2)}\nBody: ${s.body?JSON.stringify(s.body,null,2):"Empty"}\n `)}function T(e,t,n,s){e.log(`\n📡 New Courier ${n} Response: ${t}\nStatus Code: ${s.status}\nResponse JSON: ${JSON.stringify(s.response,null,2)}\n `)}async function w(e){const t=e.validCodes??[200],n=e.options.showLogs?g.nanoid():void 0,s=e.options.courierUserAgent.toHttpHeaderValue(),i=new Request(e.url,{method:e.method,headers:{"Content-Type":"application/json",[m]:s,...e.headers},body:e.body?JSON.stringify(e.body):void 0});n&&b(e.options.logger,n,"HTTP",{url:i.url,method:i.method,headers:Object.fromEntries(i.headers.entries()),body:e.body});const o=await fetch(i);if(204===o.status)return;let r;try{r=await o.json()}catch(a){if(200===o.status)return;throw new f(o.status,"Failed to parse response as JSON","PARSE_ERROR")}if(n&&T(e.options.logger,n,"HTTP",{status:o.status,response:r}),!t.includes(o.status))throw new f(o.status,(null==r?void 0:r.message)||"Unknown Error",null==r?void 0:r.type);return r}async function $(e){const t=e.options.showLogs?g.nanoid():void 0,n=e.options.courierUserAgent.toHttpHeaderValue();t&&b(e.options.logger,t,"GraphQL",{url:e.url,headers:e.headers,query:e.query,variables:e.variables});const s=await fetch(e.url,{method:"POST",headers:{"Content-Type":"application/json",[m]:n,...e.headers},body:JSON.stringify({query:e.query,variables:e.variables})});let i;try{i=await s.json()}catch(o){throw new f(s.status,"Failed to parse response as JSON","PARSE_ERROR")}if(t&&T(e.options.logger,t,"GraphQL",{status:s.status,response:i}),!s.ok)throw new f(s.status,(null==i?void 0:i.message)||"Unknown Error",null==i?void 0:i.type);return i}class A{constructor(e){this.options=e}}class R extends A{async getBrand(e){const t=`\n query GetBrand {\n brand(brandId: "${e.brandId}") {\n settings {\n colors {\n primary\n secondary\n tertiary\n }\n inapp {\n borderRadius\n disableCourierFooter\n }\n }\n }\n }\n `;return(await $({options:this.options,url:this.options.apiUrls.courier.graphql,headers:{"x-courier-user-id":this.options.userId,"x-courier-client-key":"empty",Authorization:`Bearer ${this.options.accessToken}`},query:t,variables:{brandId:e.brandId}})).data.brand}}const k=1e3,C=class e{constructor(e){n(this,"webSocket",null),n(this,"retryAttempt",0),n(this,"retryTimeoutId",null),n(this,"closeRequested",!1),n(this,"url"),n(this,"options"),this.url=e.apiUrls.inbox.webSocket,this.options=e}async connect(){var t,n;return this.isConnecting||this.isOpen?(null==(n=this.options.logger)||n.info(`Attempted to open a WebSocket connection, but one already exists in state '${null==(t=this.webSocket)?void 0:t.readyState}'.`),Promise.resolve()):(this.clearRetryTimeout(),this.closeRequested=!1,new Promise(((t,n)=>{this.webSocket=new WebSocket(this.getWebSocketUrl()),this.webSocket.addEventListener("open",(e=>{this.retryAttempt=0,this.onOpen(e),t()})),this.webSocket.addEventListener("message",(async e=>{var t;try{const t=JSON.parse(e.data);if("event"in t&&"reconnect"===t.event)return this.close(k),void(await this.retryConnection(1e3*t.retryAfter));this.onMessageReceived(t)}catch(n){null==(t=this.options.logger)||t.error("Error parsing socket message",n)}})),this.webSocket.addEventListener("close",(t=>{if(t.code!==k&&!this.closeRequested){const n=e.parseCloseEvent(t);n.retryAfterSeconds?this.retryConnection(1e3*n.retryAfterSeconds):this.retryConnection()}this.onClose(t)})),this.webSocket.addEventListener("error",(e=>{this.closeRequested||this.retryConnection(),this.onError(e),n(e)}))})))}close(e=1e3,t){null!==this.webSocket&&(this.closeRequested=!0,this.clearRetryTimeout(),this.retryAttempt=0,this.webSocket.close(e,t))}send(e){var t;if(null===this.webSocket||this.isConnecting)return void(null==(t=this.options.logger)||t.info("Attempted to send a message, but the WebSocket is not yet open."));const n=JSON.stringify(e);this.webSocket.send(n)}get userId(){return this.options.userId}get subTenantId(){return this.options.tenantId}get logger(){return this.options.logger}get courierUserAgent(){return this.options.courierUserAgent}get isConnecting(){return null!==this.webSocket&&this.webSocket.readyState===WebSocket.CONNECTING}get isOpen(){return null!==this.webSocket&&this.webSocket.readyState===WebSocket.OPEN}getWebSocketUrl(){const e=this.options.accessToken,t=this.options.connectionId,n=this.userId,s=this.courierUserAgent.getUserAgentInfo()[I],i=this.courierUserAgent.getUserAgentInfo()[y];return`${this.url}?auth=${e}&cid=${t}&iwpv=v1&userId=${n}&${I}=${s}&${y}=${i}`}static parseCloseEvent(t){if(null===t.reason||""===t.reason)return t;try{const n=JSON.parse(t.reason);if(!n[e.RETRY_AFTER_KEY])return t;const s=parseInt(n[e.RETRY_AFTER_KEY]);return Number.isNaN(s)||s<0?t:{...t,retryAfterSeconds:s}}catch(n){return t}}getBackoffTimeInMillis(){const t=e.BACKOFF_INTERVALS_IN_MILLIS[this.retryAttempt],n=t-t*e.BACKOFF_JITTER_FACTOR,s=t+t*e.BACKOFF_JITTER_FACTOR;return Math.floor(Math.random()*(s-n)+n)}async retryConnection(t){var n,s,i;if(null!==this.retryTimeoutId)return void(null==(n=this.logger)||n.debug("Skipping retry attempt because a previous retry is already scheduled."));if(this.retryAttempt>=e.MAX_RETRY_ATTEMPTS)return void(null==(s=this.logger)||s.error(`Max retry attempts (${e.MAX_RETRY_ATTEMPTS}) reached.`));const o=t??this.getBackoffTimeInMillis();this.retryTimeoutId=window.setTimeout((async()=>{try{await this.connect()}catch(e){}}),o),null==(i=this.logger)||i.debug(`Retrying connection in ${Math.floor(o/1e3)}s. Retry attempt ${this.retryAttempt+1} of ${e.MAX_RETRY_ATTEMPTS}.`),this.retryAttempt++}clearRetryTimeout(){null!==this.retryTimeoutId&&(window.clearTimeout(this.retryTimeoutId),this.retryTimeoutId=null)}};n(C,"BACKOFF_JITTER_FACTOR",.5),n(C,"MAX_RETRY_ATTEMPTS",5),n(C,"BACKOFF_INTERVALS_IN_MILLIS",[3e4,6e4,12e4,24e4,48e4]),n(C,"RETRY_AFTER_KEY","Retry-After");let E=C;class S{constructor(e=10){n(this,"outstandingRequestsMap",new Map),n(this,"completedTransactionsQueue",[]),n(this,"completedTransactionsToKeep"),this.completedTransactionsToKeep=e}addOutstandingRequest(e,t){if(this.outstandingRequestsMap.has(e))throw new Error(`Transaction [${e}] already has an outstanding request`);const n={transactionId:e,request:t,response:null,start:new Date,end:null};this.outstandingRequestsMap.set(e,n)}addResponse(e,t){const n=this.outstandingRequestsMap.get(e);if(void 0===n)throw new Error(`Transaction [${e}] does not have an outstanding request`);n.response=t,n.end=new Date,this.outstandingRequestsMap.delete(e),this.addCompletedTransaction(n)}get outstandingRequests(){return Array.from(this.outstandingRequestsMap.values())}get completedTransactions(){return this.completedTransactionsQueue}clearOutstandingRequests(){this.outstandingRequestsMap.clear()}addCompletedTransaction(e){this.completedTransactionsQueue.push(e),this.completedTransactionsQueue.length>this.completedTransactionsToKeep&&this.completedTransactionsQueue.shift()}}function U(e){return function(e){if(e.event===d.NewMessage){const t=e.data;return t.created||(t.created=(new Date).toISOString()),{...e,data:t}}return e}(e)}const P=class e extends E{constructor(e){super(e),n(this,"pingIntervalId",null),n(this,"messageEventListeners",[]),n(this,"config",null),n(this,"pingTransactionManager",new S)}onOpen(e){return this.pingTransactionManager.clearOutstandingRequests(),this.restartPingInterval(),this.sendGetConfig(),this.sendSubscribe(),Promise.resolve()}onMessageReceived(t){if("action"in t&&t.action===h.Ping){const e=t;this.sendPong(e)}if("response"in t&&"pong"===t.response){const e=t;this.pingTransactionManager.addResponse(e.tid,e),this.pingTransactionManager.clearOutstandingRequests()}if("response"in t&&"config"===t.response){const e=t;this.setConfig(e.data)}if("event"in t&&e.isInboxMessageEvent(t.event)){const e=U(t);for(const t of this.messageEventListeners)t(e)}return this.restartPingInterval(),Promise.resolve()}onClose(e){return this.clearPingInterval(),this.clearMessageEventListeners(),this.pingTransactionManager.clearOutstandingRequests(),Promise.resolve()}onError(e){return Promise.resolve()}sendSubscribe(){const e={channel:this.userId,event:"*"};this.subTenantId&&(e.accountId=this.subTenantId);const t={tid:g.nanoid(),action:u.Subscribe,data:e};this.send(t)}sendUnsubscribe(){const e={tid:g.nanoid(),action:u.Unsubscribe,data:{channel:this.userId}};this.send(e)}addMessageEventListener(e){return this.messageEventListeners.push(e),()=>{this.removeMessageEventListener(e)}}sendPing(){var e;if(this.pingTransactionManager.outstandingRequests.length>=this.maxOutstandingPings)return null==(e=this.logger)||e.debug("Max outstanding pings reached, retrying connection."),this.close(k,"Max outstanding pings reached, retrying connection."),void this.retryConnection();const t={tid:g.nanoid(),action:u.Ping};this.send(t),this.pingTransactionManager.addOutstandingRequest(t.tid,t)}sendPong(e){const t={tid:e.tid,action:u.Pong};this.send(t)}sendGetConfig(){const e={tid:g.nanoid(),action:u.GetConfig};this.send(e)}restartPingInterval(){this.clearPingInterval(),this.pingIntervalId=window.setInterval((()=>{this.sendPing()}),this.pingInterval)}clearPingInterval(){this.pingIntervalId&&window.clearInterval(this.pingIntervalId)}get pingInterval(){return this.config?1e3*this.config.pingInterval:e.DEFAULT_PING_INTERVAL_MILLIS}get maxOutstandingPings(){return this.config?this.config.maxOutstandingPings:e.DEFAULT_MAX_OUTSTANDING_PINGS}setConfig(e){this.config=e}clearMessageEventListeners(){for(;this.messageEventListeners.length>0;)this.messageEventListeners.pop()}removeMessageEventListener(e){const t=this.messageEventListeners.indexOf(e);t>-1&&this.messageEventListeners.splice(t,1)}static isInboxMessageEvent(e){return Object.values(d).includes(e)}};n(P,"DEFAULT_PING_INTERVAL_MILLIS",6e4),n(P,"DEFAULT_MAX_OUTSTANDING_PINGS",3);let x=P;class q extends A{constructor(e){super(e),n(this,"socket"),this.socket=new x(e)}async getMessages(e){const t=(null==e?void 0:e.filter)||{},n=`\n query GetInboxMessages(\n $params: FilterParamsInput = ${this.createFilterParams(t)}\n $unreadCountParams: FilterParamsInput = ${this.createUnreadCountFilterParams(t)}\n $limit: Int = ${(null==e?void 0:e.paginationLimit)??24}\n $after: String ${(null==e?void 0:e.startCursor)?`= "${e.startCursor}"`:""}\n ) {\n count: count(params: $params)\n unreadCount: count(params: $unreadCountParams)\n messages(params: $params, limit: $limit, after: $after) {\n totalCount\n pageInfo {\n startCursor\n hasNextPage\n }\n nodes {\n messageId\n read\n archived\n created\n opened\n title\n preview\n data\n tags\n trackingIds {\n clickTrackingId\n }\n actions {\n content\n data\n href\n }\n }\n }\n }\n `;return await $({options:this.options,query:n,headers:{"x-courier-user-id":this.options.userId,Authorization:`Bearer ${this.options.accessToken}`},url:this.options.apiUrls.inbox.graphql})}async getUnreadCounts(e){const t={},n={};for(const[c,u]of Object.entries(e))"read"===u.status?t[c]=0:n[c]=u;if(0===Object.keys(n).length)return t;const s=[],i=[],o={};for(const[c,u]of Object.entries(n)){const e=q.sanitizeGraphQLIdentifier(c);o[e]=c;const t=this.createUnreadCountFilterParams(u);s.push(`$${e}: FilterParamsInput = ${t}`),i.push(`${e}: count(params: $${e})`)}const r=`\n query GetUnreadCounts(\n ${s.join("\n")}\n ) {\n ${i.join("\n")}\n }\n `,a=await $({options:this.options,query:r,headers:{"x-courier-user-id":this.options.userId,Authorization:`Bearer ${this.options.accessToken}`},url:this.options.apiUrls.inbox.graphql});if(a.data)for(const[c,u]of Object.entries(o))t[u]=a.data[c]??0;return t}async getArchivedMessages(e){return this.getMessages({paginationLimit:null==e?void 0:e.paginationLimit,startCursor:null==e?void 0:e.startCursor,filter:{archived:!0}})}async getUnreadMessageCount(){var e;const t=`\n query GetMessages {\n count(params: { status: "unread" ${this.options.tenantId?`, accountId: "${this.options.tenantId}"`:""} })\n }\n `;return(null==(e=(await $({options:this.options,query:t,headers:{"x-courier-user-id":this.options.userId,Authorization:`Bearer ${this.options.accessToken}`},url:this.options.apiUrls.inbox.graphql})).data)?void 0:e.count)??0}async click(e){const t=`\n mutation TrackEvent {\n clicked(messageId: "${e.messageId}", trackingId: "${e.trackingId}")\n }\n `,n={"x-courier-user-id":this.options.userId,Authorization:`Bearer ${this.options.accessToken}`};this.options.connectionId&&(n["x-courier-client-source-id"]=this.options.connectionId),await $({options:this.options,query:t,headers:n,url:this.options.apiUrls.inbox.graphql})}async read(e){const t=`\n mutation TrackEvent {\n read(messageId: "${e.messageId}")\n }\n `,n={"x-courier-user-id":this.options.userId,Authorization:`Bearer ${this.options.accessToken}`};this.options.connectionId&&(n["x-courier-client-source-id"]=this.options.connectionId),await $({options:this.options,query:t,headers:n,url:this.options.apiUrls.inbox.graphql})}async unread(e){const t=`\n mutation TrackEvent {\n unread(messageId: "${e.messageId}")\n }\n `,n={"x-courier-user-id":this.options.userId,Authorization:`Bearer ${this.options.accessToken}`};this.options.connectionId&&(n["x-courier-client-source-id"]=this.options.connectionId),await $({options:this.options,query:t,headers:n,url:this.options.apiUrls.inbox.graphql})}async open(e){const t=`\n mutation TrackEvent {\n opened(messageId: "${e.messageId}")\n }\n `,n={"x-courier-user-id":this.options.userId,Authorization:`Bearer ${this.options.accessToken}`};this.options.connectionId&&(n["x-courier-client-source-id"]=this.options.connectionId),await $({options:this.options,query:t,headers:n,url:this.options.apiUrls.inbox.graphql})}async archive(e){const t=`\n mutation TrackEvent {\n archive(messageId: "${e.messageId}")\n }\n `,n={"x-courier-user-id":this.options.userId,Authorization:`Bearer ${this.options.accessToken}`};this.options.connectionId&&(n["x-courier-client-source-id"]=this.options.connectionId),await $({options:this.options,query:t,headers:n,url:this.options.apiUrls.inbox.graphql})}async unarchive(e){const t=`\n mutation TrackEvent {\n unarchive(messageId: "${e.messageId}")\n }\n `,n={"x-courier-user-id":this.options.userId,Authorization:`Bearer ${this.options.accessToken}`};this.options.connectionId&&(n["x-courier-client-source-id"]=this.options.connectionId),await $({options:this.options,query:t,headers:n,url:this.options.apiUrls.inbox.graphql})}async readAll(){const e={"x-courier-user-id":this.options.userId,Authorization:`Bearer ${this.options.accessToken}`};this.options.connectionId&&(e["x-courier-client-source-id"]=this.options.connectionId),await $({options:this.options,query:"\n mutation TrackEvent {\n markAllRead\n }\n ",headers:e,url:this.options.apiUrls.inbox.graphql})}async archiveRead(){const e={"x-courier-user-id":this.options.userId,Authorization:`Bearer ${this.options.accessToken}`};this.options.connectionId&&(e["x-courier-client-source-id"]=this.options.connectionId),await $({options:this.options,query:"\n mutation TrackEvent {\n archiveRead\n }\n ",headers:e,url:this.options.apiUrls.inbox.graphql})}async archiveAll(){const e={"x-courier-user-id":this.options.userId,Authorization:`Bearer ${this.options.accessToken}`};this.options.connectionId&&(e["x-courier-client-source-id"]=this.options.connectionId),await $({options:this.options,query:"\n mutation TrackEvent {\n archiveAll\n }\n ",headers:e,url:this.options.apiUrls.inbox.graphql})}createFilterParams(e){const t=[];return this.options.tenantId&&t.push(`accountId: "${this.options.tenantId}"`),e.tags&&t.push(`tags: [${e.tags.map((e=>`"${e}"`)).join(",")}]`),e.status&&t.push(`status: "${e.status}"`),e.archived&&t.push(`archived: ${e.archived}`),e.from&&t.push(`from: "${e.from}"`),`{ ${t.join(",")} }`}createUnreadCountFilterParams(e){return e.status?this.createFilterParams(e):this.createFilterParams({...e,status:"unread"})}static sanitizeGraphQLIdentifier(e){return`id_${e.replace(/_/g,"__").replace(/-/g,"_")}`}}class L extends A{async getUserPreferences(e){var t,n;const s=`\n query GetRecipientPreferences {\n recipientPreferences${this.options.tenantId?`(accountId: "${this.options.tenantId}")`:""} {\n nodes {\n templateId\n templateName\n sectionId\n sectionName\n defaultStatus\n status\n hasCustomRouting\n routingPreferences\n digestSchedule\n }\n }\n }\n `;return{items:((null==(n=null==(t=(await $({options:this.options,url:this.options.apiUrls.courier.graphql,query:s,headers:{"x-courier-user-id":this.options.userId,"x-courier-client-key":"empty",Authorization:`Bearer ${this.options.accessToken}`}})).data)?void 0:t.recipientPreferences)?void 0:n.nodes)||[]).map((e=>this.transformToTopic(e))),paging:{cursor:null==e?void 0:e.paginationCursor,more:!1}}}async getUserPreferenceTopic(e){var t;const n=`\n query GetRecipientPreferenceTopic {\n recipientPreference(templateId: "${e.topicId}"${this.options.tenantId?`, accountId: "${this.options.tenantId}"`:""}) {\n templateId\n templateName\n status\n hasCustomRouting\n routingPreferences\n digestSchedule\n sectionId\n sectionName\n defaultStatus\n }\n }\n `,s=null==(t=(await $({options:this.options,url:this.options.apiUrls.courier.graphql,query:n,headers:{"x-courier-user-id":this.options.userId,"x-courier-client-key":"empty",Authorization:`Bearer ${this.options.accessToken}`}})).data)?void 0:t.recipientPreference;if(!s)throw new Error(`Preference topic not found: ${e.topicId}`);return this.transformToTopic(s)}async putUserPreferenceTopic(e){const t=e.customRouting.length>0?`[${e.customRouting.join(", ")}]`:"[]",n=`\n mutation UpdateRecipientPreferences {\n updatePreferences(\n templateId: "${e.topicId}",\n preferences: {\n status: ${e.status},\n hasCustomRouting: ${e.hasCustomRouting},\n routingPreferences: ${t}\n }${this.options.tenantId?`, accountId: "${this.options.tenantId}"`:""}\n )\n }\n `;await $({options:this.options,url:this.options.apiUrls.courier.graphql,query:n,headers:{"x-courier-user-id":this.options.userId,"x-courier-client-key":"empty",Authorization:`Bearer ${this.options.accessToken}`}})}getNotificationCenterUrl(e){return`https://view.notificationcenter.app/p/${function(e){const t=new Uint8Array(e.length);for(let n=0;n<e.length;n++)t[n]=e.charCodeAt(n);return btoa(String.fromCharCode(...t))}(`${function(e){const t=atob(e),n=new Uint8Array(t.length);for(let s=0;s<t.length;s++)n[s]=t.charCodeAt(s);return String.fromCharCode(...n)}(e.clientKey)}#${this.options.userId}${this.options.tenantId?`#${this.options.tenantId}`:""}#false`)}`}transformToTopic(e){return{topicId:e.templateId,topicName:e.templateName||"",sectionId:e.sectionId||"",sectionName:e.sectionName||"",status:e.status||"UNKNOWN",defaultStatus:e.defaultStatus||"UNKNOWN",hasCustomRouting:e.hasCustomRouting||!1,customRouting:e.routingPreferences||[]}}}class O extends A{async putUserToken(e){const t={provider_key:e.provider,...e.device&&{device:{app_id:e.device.appId,ad_id:e.device.adId,device_id:e.device.deviceId,platform:e.device.platform,manufacturer:e.device.manufacturer,model:e.device.model}}};await w({options:this.options,url:`${this.options.apiUrls.courier.rest}/users/${this.options.userId}/tokens/${e.token}`,method:"PUT",headers:{Authorization:`Bearer ${this.options.accessToken}`},body:t,validCodes:[200,204]})}async deleteUserToken(e){await w({options:this.options,url:`${this.options.apiUrls.courier.rest}/users/${this.options.userId}/tokens/${e.token}`,method:"DELETE",headers:{Authorization:`Bearer ${this.options.accessToken}`},validCodes:[200,204]})}}class _ extends A{async putSubscription(e){return await w({url:`${this.options.apiUrls.courier.rest}/lists/${e.listId}/subscriptions/${this.options.userId}`,options:this.options,method:"PUT",headers:{Authorization:`Bearer ${this.options.accessToken}`}})}async deleteSubscription(e){return await w({url:`${this.options.apiUrls.courier.rest}/lists/${e.listId}/subscriptions/${this.options.userId}`,options:this.options,method:"DELETE",headers:{Authorization:`Bearer ${this.options.accessToken}`}})}}class N extends A{async postInboundCourier(e){const{clientKey:t,...n}=e;return await w({url:`${this.options.apiUrls.courier.rest}/inbound/courier`,options:this.options,method:"POST",headers:{"x-courier-client-key":t},body:{...n,userId:this.options.userId},validCodes:[200,202]})}async postTrackingUrl(e){return await w({url:e.url,options:this.options,method:"POST",body:{event:e.event}})}}class M{constructor(e,t,n){this.clientId=e,this.sdkName=t,this.sdkVersion=n}getUserAgentInfo(){return{[I]:this.sdkName,[y]:this.sdkVersion,[v]:this.clientId}}toHttpHeaderValue(){return Object.entries(this.getUserAgentInfo()).map((([e,t])=>`${e}=${t}`)).join(",")}}const F=class e extends A{constructor(t){var s,i;const o=void 0!==t.showLogs&&t.showLogs,r=g.nanoid(),u={...t,showLogs:o,connectionId:r,apiUrls:t.apiUrls||a("us"),accessToken:t.jwt??t.publicApiKey},h=new M(r,t.courierUserAgentName||e.COURIER_JS_NAME,t.courierUserAgentVersion||e.COURIER_JS_VERSION);super({...u,logger:new l(u.showLogs),courierUserAgent:h,apiUrls:c(u.apiUrls)}),n(this,"tokens"),n(this,"brands"),n(this,"preferences"),n(this,"inbox"),n(this,"lists"),n(this,"tracking"),this.tokens=new O(this.options),this.brands=new R(this.options),this.preferences=new L(this.options),this.inbox=new q(this.options),this.lists=new _(this.options),this.tracking=new N(this.options),this.options.jwt||this.options.publicApiKey||this.options.logger.warn("Courier Client initialized with no authentication method. Please provide a JWT or public API key."),this.options.publicApiKey&&(null==(s=this.options.logger)||s.warn("Courier Warning: Public API Keys are for testing only. Please use JWTs for production.\nYou can generate a JWT with this endpoint: https://www.courier.com/docs/api-reference/authentication/create-jwt\nThis endpoint should be called from your backend server, not the SDK.")),this.options.jwt&&this.options.publicApiKey&&(null==(i=this.options.logger)||i.warn("Courier Warning: Both a JWT and a Public API Key were provided. The Public API Key will be ignored."))}};n(F,"COURIER_JS_NAME","courier-js"),n(F,"COURIER_JS_VERSION","3.1.1");let B=F;class j{constructor(e){n(this,"callback"),this.callback=e}remove(){J.shared.removeAuthenticationListener(this)}}const z=class e{constructor(){n(this,"id",g.nanoid()),n(this,"instanceClient"),n(this,"courierUserAgentName"),n(this,"courierUserAgentVersion"),n(this,"_paginationLimit",24),n(this,"authenticationListeners",[])}get paginationLimit(){return this._paginationLimit}set paginationLimit(e){this._paginationLimit=Math.min(Math.max(e,1),100)}get client(){return this.instanceClient}static get shared(){return e.instance||(e.instance=new e),e.instance}signIn(e){this.instanceClient&&(this.instanceClient.options.logger.warn("Sign in called but there is already a user signed in. Signing out the current user."),this.signOut()),this.instanceClient=new B({...e,courierUserAgentName:this.courierUserAgentName,courierUserAgentVersion:this.courierUserAgentVersion}),this.notifyAuthenticationListeners({userId:e.userId})}signOut(){var e,t;null==(t=null==(e=this.instanceClient)?void 0:e.inbox.socket)||t.close(),this.instanceClient=void 0,this.notifyAuthenticationListeners({userId:void 0})}addAuthenticationListener(e){var t;null==(t=this.instanceClient)||t.options.logger.info("Adding authentication listener");const n=new j(e);return this.authenticationListeners.push(n),n}removeAuthenticationListener(e){var t;null==(t=this.instanceClient)||t.options.logger.info("Removing authentication listener"),this.authenticationListeners=this.authenticationListeners.filter((t=>t!==e))}notifyAuthenticationListeners(e){this.authenticationListeners.forEach((t=>t.callback(e)))}};n(z,"instance");let J=z;e.BrandClient=R,e.Courier=J,e.CourierClient=B,e.DEFAULT_COURIER_API_URLS=o,e.EU_COURIER_API_URLS=r,e.InboxClient=q,e.InboxMessageEvent=d,e.ListClient=_,e.PreferenceClient=L,e.TokenClient=O,e.TrackingClient=N,e.getCourierApiUrls=c,e.getCourierApiUrlsForRegion=a,Object.defineProperty(e,Symbol.toStringTag,{value:"Module"})})); //# sourceMappingURL=index.js.map