@trycourier/courier-js 2.0.2-beta → 2.0.3-beta

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.
@@ -77,8 +77,20 @@ export declare class InboxClient extends Client {
77
77
  archive(props: {
78
78
  messageId: string;
79
79
  }): Promise<void>;
80
+ /**
81
+ * Unarchive a message
82
+ * @param messageId - ID of the message to unarchive
83
+ * @returns Promise resolving when message is unarchived
84
+ */
85
+ unarchive(props: {
86
+ messageId: string;
87
+ }): Promise<void>;
80
88
  /**
81
89
  * Archive all read messages.
82
90
  */
83
91
  archiveRead(): Promise<void>;
92
+ /**
93
+ * Archive all read messages.
94
+ */
95
+ archiveAll(): Promise<void>;
84
96
  }
package/dist/index.js CHANGED
@@ -1 +1,2 @@
1
- !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).CourierJS={})}(this,(function(t){"use strict";var e=Object.defineProperty,s=(t,s,n)=>((t,s,n)=>s in t?e(t,s,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[s]=n)(t,"symbol"!=typeof s?s+"":s,n);const n=class t{constructor(t,e){s(this,"webSocket",null),s(this,"pingInterval",null),s(this,"onOpen"),s(this,"onMessageReceived"),s(this,"onClose"),s(this,"onError"),s(this,"url"),s(this,"options"),this.url=t,this.options=e}get isConnected(){return null!==this.webSocket}async connect(){return this.disconnect(),new Promise(((t,e)=>{try{this.webSocket=new WebSocket(this.url),this.webSocket.onopen=()=>{var e;null==(e=this.onOpen)||e.call(this),t()},this.webSocket.onmessage=t=>{var e;null==(e=this.onMessageReceived)||e.call(this,t.data)},this.webSocket.onclose=t=>{var e;this.webSocket=null,null==(e=this.onClose)||e.call(this,t.code,t.reason)},this.webSocket.onerror=t=>{var s;this.webSocket=null;const n=new Error("Courier Socket connection failed");n.originalEvent=t,null==(s=this.onError)||s.call(this,n),e(n)}}catch(s){this.webSocket=null,e(s)}}))}disconnect(){this.stopPing(),this.webSocket&&(this.webSocket.close(t.NORMAL_CLOSURE_STATUS),this.webSocket=null)}async send(t){if(!this.webSocket)return!1;const e=JSON.stringify(t);return void 0!==this.webSocket.send(e)}keepAlive(t){this.stopPing(),this.pingInterval=setInterval((async()=>{var t;try{await this.send({action:"keepAlive"})}catch(e){null==(t=this.options.logger)||t.error("Error occurred on Keep Alive:",e)}}),(null==t?void 0:t.intervalInMillis)??3e5)}stopPing(){this.pingInterval&&(clearInterval(this.pingInterval),this.pingInterval=null)}};s(n,"NORMAL_CLOSURE_STATUS",1e3);let i=n;const o=t=>({courier:{rest:(null==t?void 0:t.courier.rest)||"https://api.courier.com",graphql:(null==t?void 0:t.courier.graphql)||"https://api.courier.com/client/q"},inbox:{graphql:(null==t?void 0:t.inbox.graphql)||"https://inbox.courier.com/q",webSocket:(null==t?void 0:t.inbox.webSocket)||"wss://realtime.courier.com"}});class r{constructor(t){s(this,"PREFIX","[COURIER]"),this.showLogs=t}warn(t,...e){this.showLogs&&console.warn(`${this.PREFIX} ${t}`,...e)}log(t,...e){this.showLogs&&console.log(`${this.PREFIX} ${t}`,...e)}error(t,...e){this.showLogs&&console.error(`${this.PREFIX} ${t}`,...e)}debug(t,...e){this.showLogs&&console.debug(`${this.PREFIX} ${t}`,...e)}info(t,...e){this.showLogs&&console.info(`${this.PREFIX} ${t}`,...e)}}class a{static generate(t){const e=Math.random().toString(36).substring(2,15)+Math.random().toString(36).substring(2,15);return t?t+e:e}}class c extends Error{constructor(t,e,s){super(e),this.code=t,this.type=s,this.name="CourierRequestError"}}function u(t,e,s,n){t.log(`\nšŸ“” New Courier ${s} Request: ${e}\nURL: ${n.url}\n${n.method?`Method: ${n.method}`:""}\n${n.query?`Query: ${n.query}`:""}\n${n.variables?`Variables: ${JSON.stringify(n.variables,null,2)}`:""}\nHeaders: ${JSON.stringify(n.headers,null,2)}\nBody: ${n.body?JSON.stringify(n.body,null,2):"Empty"}\n `)}function h(t,e,s,n){t.log(`\nšŸ“” New Courier ${s} Response: ${e}\nStatus Code: ${n.status}\nResponse JSON: ${JSON.stringify(n.response,null,2)}\n `)}async function l(t){const e=t.validCodes??[200],s=t.options.showLogs?a.generate():void 0,n=new Request(t.url,{method:t.method,headers:{"Content-Type":"application/json",...t.headers},body:t.body?JSON.stringify(t.body):void 0});s&&u(t.options.logger,s,"HTTP",{url:n.url,method:n.method,headers:Object.fromEntries(n.headers.entries()),body:t.body});const i=await fetch(n);if(204===i.status)return;let o;try{o=await i.json()}catch(r){if(200===i.status)return;throw new c(i.status,"Failed to parse response as JSON","PARSE_ERROR")}if(s&&h(t.options.logger,s,"HTTP",{status:i.status,response:o}),!e.includes(i.status))throw new c(i.status,(null==o?void 0:o.message)||"Unknown Error",null==o?void 0:o.type);return o}async function d(t){const e=t.options.showLogs?a.generate():void 0;e&&u(t.options.logger,e,"GraphQL",{url:t.url,headers:t.headers,query:t.query,variables:t.variables});const s=await fetch(t.url,{method:"POST",headers:{"Content-Type":"application/json",...t.headers},body:JSON.stringify({query:t.query,variables:t.variables})});let n;try{n=await s.json()}catch(i){throw new c(s.status,"Failed to parse response as JSON","PARSE_ERROR")}if(e&&h(t.options.logger,e,"GraphQL",{status:s.status,response:n}),!s.ok)throw new c(s.status,(null==n?void 0:n.message)||"Unknown Error",null==n?void 0:n.type);return n}class p{constructor(t){this.options=t}}class g extends p{async getBrand(t){const e=`\n query GetBrand {\n brand(brandId: "${t.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 d({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:e,variables:{brandId:t.brandId}})).data.brand}}class m extends i{constructor(t){super(m.buildUrl(t),t),s(this,"receivedMessage"),s(this,"receivedMessageEvent"),this.onMessageReceived=t=>this.convertToType(t)}convertToType(t){var e,s,n,i;try{switch(JSON.parse(t).type){case"event":const n=JSON.parse(t);null==(e=this.receivedMessageEvent)||e.call(this,n);break;case"message":const i=JSON.parse(t);null==(s=this.receivedMessage)||s.call(this,i)}}catch(o){null==(n=this.options.logger)||n.error("Error parsing socket message",o),o instanceof Error&&(null==(i=this.onError)||i.call(this,o))}}async sendSubscribe(t){var e;const s={action:"subscribe",data:{userAgent:"courier-js",channel:this.options.userId,event:"*",version:(null==t?void 0:t.version)??5}};this.options.connectionId&&(s.data.clientSourceId=this.options.connectionId),this.options.tenantId&&(s.data.accountId=this.options.tenantId),null==(e=this.options.logger)||e.debug("Sending subscribe request",s),await this.send(s)}static buildUrl(t){var e;let s=(null==(e=t.apiUrls)?void 0:e.inbox.webSocket)??"";return t.accessToken&&(s+=`/?auth=${t.accessToken}`),s}}class I extends p{constructor(t){super(t),s(this,"socket"),this.socket=new m(t)}async getMessages(t){const e=`\n query GetInboxMessages(\n $params: FilterParamsInput = { ${this.options.tenantId?`accountId: "${this.options.tenantId}"`:""} }\n $limit: Int = ${(null==t?void 0:t.paginationLimit)??24}\n $after: String ${(null==t?void 0:t.startCursor)?`= "${t.startCursor}"`:""}\n ) {\n count(params: $params)\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 d({options:this.options,query:e,headers:{"x-courier-user-id":this.options.userId,Authorization:`Bearer ${this.options.accessToken}`},url:this.options.apiUrls.inbox.graphql})}async getArchivedMessages(t){const e=`\n query GetInboxMessages(\n $params: FilterParamsInput = { ${this.options.tenantId?`accountId: "${this.options.tenantId}"`:""}, archived: true }\n $limit: Int = ${(null==t?void 0:t.paginationLimit)??24}\n $after: String ${(null==t?void 0:t.startCursor)?`= "${t.startCursor}"`:""}\n ) {\n count(params: $params)\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 d({options:this.options,query:e,headers:{"x-courier-user-id":this.options.userId,Authorization:`Bearer ${this.options.accessToken}`},url:this.options.apiUrls.inbox.graphql})}async getUnreadMessageCount(){var t;const e=`\n query GetMessages {\n count(params: { status: "unread" ${this.options.tenantId?`, accountId: "${this.options.tenantId}"`:""} })\n }\n `;return(null==(t=(await d({options:this.options,query:e,headers:{"x-courier-user-id":this.options.userId,Authorization:`Bearer ${this.options.accessToken}`},url:this.options.apiUrls.inbox.graphql})).data)?void 0:t.count)??0}async click(t){const e=`\n mutation TrackEvent {\n clicked(messageId: "${t.messageId}", trackingId: "${t.trackingId}")\n }\n `,s={"x-courier-user-id":this.options.userId,Authorization:`Bearer ${this.options.accessToken}`};this.options.connectionId&&(s["x-courier-client-source-id"]=this.options.connectionId),await d({options:this.options,query:e,headers:s,url:this.options.apiUrls.inbox.graphql})}async read(t){const e=`\n mutation TrackEvent {\n read(messageId: "${t.messageId}")\n }\n `,s={"x-courier-user-id":this.options.userId,Authorization:`Bearer ${this.options.accessToken}`};this.options.connectionId&&(s["x-courier-client-source-id"]=this.options.connectionId),await d({options:this.options,query:e,headers:s,url:this.options.apiUrls.inbox.graphql})}async unread(t){const e=`\n mutation TrackEvent {\n unread(messageId: "${t.messageId}")\n }\n `,s={"x-courier-user-id":this.options.userId,Authorization:`Bearer ${this.options.accessToken}`};this.options.connectionId&&(s["x-courier-client-source-id"]=this.options.connectionId),await d({options:this.options,query:e,headers:s,url:this.options.apiUrls.inbox.graphql})}async readAll(){const t={"x-courier-user-id":this.options.userId,Authorization:`Bearer ${this.options.accessToken}`};this.options.connectionId&&(t["x-courier-client-source-id"]=this.options.connectionId),await d({options:this.options,query:"\n mutation TrackEvent {\n markAllRead\n }\n ",headers:t,url:this.options.apiUrls.inbox.graphql})}async open(t){const e=`\n mutation TrackEvent {\n opened(messageId: "${t.messageId}")\n }\n `,s={"x-courier-user-id":this.options.userId,Authorization:`Bearer ${this.options.accessToken}`};this.options.connectionId&&(s["x-courier-client-source-id"]=this.options.connectionId),await d({options:this.options,query:e,headers:s,url:this.options.apiUrls.inbox.graphql})}async archive(t){const e=`\n mutation TrackEvent {\n archive(messageId: "${t.messageId}")\n }\n `,s={"x-courier-user-id":this.options.userId,Authorization:`Bearer ${this.options.accessToken}`};this.options.connectionId&&(s["x-courier-client-source-id"]=this.options.connectionId),await d({options:this.options,query:e,headers:s,url:this.options.apiUrls.inbox.graphql})}async archiveRead(){const t={"x-courier-user-id":this.options.userId,Authorization:`Bearer ${this.options.accessToken}`};this.options.connectionId&&(t["x-courier-client-source-id"]=this.options.connectionId),await d({options:this.options,query:"\n mutation TrackEvent {\n archiveRead\n }\n ",headers:t,url:this.options.apiUrls.inbox.graphql})}}class v{transformItem(t){return{topicId:t.topic_id,topicName:t.topic_name,sectionId:t.section_id,sectionName:t.section_name,status:t.status,defaultStatus:t.default_status,hasCustomRouting:t.has_custom_routing,customRouting:t.custom_routing||[]}}*transform(t){for(const e of t)yield this.transformItem(e)}}class b extends p{constructor(){super(...arguments),s(this,"transformer",new v)}async getUserPreferences(t){let e=`${this.options.apiUrls.courier.rest}/users/${this.options.userId}/preferences`;(null==t?void 0:t.paginationCursor)&&(e+=`?cursor=${t.paginationCursor}`);const s=await l({options:this.options,url:e,method:"GET",headers:{Authorization:`Bearer ${this.options.accessToken}`}});return{items:[...this.transformer.transform(s.items)],paging:s.paging}}async getUserPreferenceTopic(t){const e=await l({options:this.options,url:`${this.options.apiUrls.courier.rest}/users/${this.options.userId}/preferences/${t.topicId}`,method:"GET",headers:{Authorization:`Bearer ${this.options.accessToken}`}});return this.transformer.transformItem(e.topic)}async putUserPreferenceTopic(t){const e={topic:{status:t.status,has_custom_routing:t.hasCustomRouting,custom_routing:t.customRouting}};await l({options:this.options,url:`${this.options.apiUrls.courier.rest}/users/${this.options.userId}/preferences/${t.topicId}`,method:"PUT",headers:{Authorization:`Bearer ${this.options.accessToken}`},body:e})}getNotificationCenterUrl(t){return`https://view.notificationcenter.app/p/${function(t){const e=new Uint8Array(t.length);for(let s=0;s<t.length;s++)e[s]=t.charCodeAt(s);return btoa(String.fromCharCode(...e))}(`${function(t){const e=atob(t),s=new Uint8Array(e.length);for(let n=0;n<e.length;n++)s[n]=e.charCodeAt(n);return String.fromCharCode(...s)}(t.clientKey)}#${this.options.userId}${this.options.tenantId?`#${this.options.tenantId}`:""}#false`)}`}}class y extends p{async putUserToken(t){const e={provider_key:t.provider,...t.device&&{device:{app_id:t.device.appId,ad_id:t.device.adId,device_id:t.device.deviceId,platform:t.device.platform,manufacturer:t.device.manufacturer,model:t.device.model}}};await l({options:this.options,url:`${this.options.apiUrls.courier.rest}/users/${this.options.userId}/tokens/${t.token}`,method:"PUT",headers:{Authorization:`Bearer ${this.options.accessToken}`},body:e,validCodes:[200,204]})}async deleteUserToken(t){await l({options:this.options,url:`${this.options.apiUrls.courier.rest}/users/${this.options.userId}/tokens/${t.token}`,method:"DELETE",headers:{Authorization:`Bearer ${this.options.accessToken}`},validCodes:[200,204]})}}class w extends p{async putSubscription(t){return await l({url:`${this.options.apiUrls.courier.rest}/lists/${t.listId}/subscriptions/${this.options.userId}`,options:this.options,method:"PUT",headers:{Authorization:`Bearer ${this.options.accessToken}`}})}async deleteSubscription(t){return await l({url:`${this.options.apiUrls.courier.rest}/lists/${t.listId}/subscriptions/${this.options.userId}`,options:this.options,method:"DELETE",headers:{Authorization:`Bearer ${this.options.accessToken}`}})}}class $ extends p{async postInboundCourier(t){return await l({url:`${this.options.apiUrls.courier.rest}/inbound/courier`,options:this.options,method:"POST",headers:{Authorization:`Bearer ${this.options.accessToken}`},body:{...t,userId:this.options.userId},validCodes:[200,202]})}async postTrackingUrl(t){return await l({url:t.url,options:this.options,method:"POST",body:{event:t.event}})}}class f extends p{constructor(t){var e,n;const i=void 0!==t.showLogs?t.showLogs:"development"===process.env.NODE_ENV,a={...t,showLogs:i,apiUrls:t.apiUrls||o(),accessToken:t.jwt??t.publicApiKey};super({...a,logger:new r(a.showLogs),apiUrls:o(a.apiUrls)}),s(this,"tokens"),s(this,"brands"),s(this,"preferences"),s(this,"inbox"),s(this,"lists"),s(this,"tracking"),this.tokens=new y(this.options),this.brands=new g(this.options),this.preferences=new b(this.options),this.inbox=new I(this.options),this.lists=new w(this.options),this.tracking=new $(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==(e=this.options.logger)||e.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/reference/auth/issue-token\nThis endpoint should be called from your backend server, not the SDK.")),this.options.jwt&&this.options.publicApiKey&&(null==(n=this.options.logger)||n.warn("Courier Warning: Both a JWT and a Public API Key were provided. The Public API Key will be ignored."))}}class k{constructor(t){s(this,"callback"),this.callback=t}remove(){S.shared.removeAuthenticationListener(this)}}const T=class t{constructor(){s(this,"id",a.generate()),s(this,"instanceClient"),s(this,"_paginationLimit",24),s(this,"authenticationListeners",[])}get paginationLimit(){return this._paginationLimit}set paginationLimit(t){this._paginationLimit=Math.min(Math.max(t,1),100)}get client(){return this.instanceClient}static get shared(){return t.instance||(t.instance=new t),t.instance}signIn(t){const e=t.connectionId??a.generate();this.instanceClient=new f({...t,connectionId:e}),this.notifyAuthenticationListeners({userId:t.userId})}signOut(){this.instanceClient=void 0,this.notifyAuthenticationListeners({userId:void 0})}addAuthenticationListener(t){var e;null==(e=this.instanceClient)||e.options.logger.info("Adding authentication listener");const s=new k(t);return this.authenticationListeners.push(s),s}removeAuthenticationListener(t){var e;null==(e=this.instanceClient)||e.options.logger.info("Removing authentication listener"),this.authenticationListeners=this.authenticationListeners.filter((e=>e!==t))}notifyAuthenticationListeners(t){this.authenticationListeners.forEach((e=>e.callback(t)))}};s(T,"instance");let S=T;t.BrandClient=g,t.Courier=S,t.CourierClient=f,t.CourierSocket=i,t.InboxClient=I,t.ListClient=w,t.PreferenceClient=b,t.TokenClient=y,Object.defineProperty(t,Symbol.toStringTag,{value:"Module"})}));
1
+ !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).CourierJS={})}(this,(function(t){"use strict";var e=Object.defineProperty,s=(t,s,n)=>((t,s,n)=>s in t?e(t,s,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[s]=n)(t,"symbol"!=typeof s?s+"":s,n);const n=class t{constructor(t,e){s(this,"webSocket",null),s(this,"pingInterval",null),s(this,"onOpen"),s(this,"onMessageReceived"),s(this,"onClose"),s(this,"onError"),s(this,"url"),s(this,"options"),this.url=t,this.options=e}get isConnected(){return null!==this.webSocket}async connect(){return this.disconnect(),new Promise(((t,e)=>{try{this.webSocket=new WebSocket(this.url),this.webSocket.onopen=()=>{var e;null==(e=this.onOpen)||e.call(this),t()},this.webSocket.onmessage=t=>{var e;null==(e=this.onMessageReceived)||e.call(this,t.data)},this.webSocket.onclose=t=>{var e;this.webSocket=null,null==(e=this.onClose)||e.call(this,t.code,t.reason)},this.webSocket.onerror=t=>{var s;this.webSocket=null;const n=new Error("Courier Socket connection failed");n.originalEvent=t,null==(s=this.onError)||s.call(this,n),e(n)}}catch(s){this.webSocket=null,e(s)}}))}disconnect(){this.stopPing(),this.webSocket&&(this.webSocket.close(t.NORMAL_CLOSURE_STATUS),this.webSocket=null)}async send(t){if(!this.webSocket)return!1;const e=JSON.stringify(t);return void 0!==this.webSocket.send(e)}keepAlive(t){this.stopPing(),this.pingInterval=setInterval((async()=>{var t;try{await this.send({action:"keepAlive"})}catch(e){null==(t=this.options.logger)||t.error("Error occurred on Keep Alive:",e)}}),(null==t?void 0:t.intervalInMillis)??3e5)}stopPing(){this.pingInterval&&(clearInterval(this.pingInterval),this.pingInterval=null)}};s(n,"NORMAL_CLOSURE_STATUS",1e3);let i=n;const o=t=>({courier:{rest:(null==t?void 0:t.courier.rest)||"https://api.courier.com",graphql:(null==t?void 0:t.courier.graphql)||"https://api.courier.com/client/q"},inbox:{graphql:(null==t?void 0:t.inbox.graphql)||"https://inbox.courier.com/q",webSocket:(null==t?void 0:t.inbox.webSocket)||"wss://realtime.courier.io"}});class r{constructor(t){s(this,"PREFIX","[COURIER]"),this.showLogs=t}warn(t,...e){this.showLogs&&console.warn(`${this.PREFIX} ${t}`,...e)}log(t,...e){this.showLogs&&console.log(`${this.PREFIX} ${t}`,...e)}error(t,...e){this.showLogs&&console.error(`${this.PREFIX} ${t}`,...e)}debug(t,...e){this.showLogs&&console.debug(`${this.PREFIX} ${t}`,...e)}info(t,...e){this.showLogs&&console.info(`${this.PREFIX} ${t}`,...e)}}class a{static generate(t){const e=Math.random().toString(36).substring(2,15)+Math.random().toString(36).substring(2,15);return t?t+e:e}}class c extends Error{constructor(t,e,s){super(e),this.code=t,this.type=s,this.name="CourierRequestError"}}function u(t,e,s,n){t.log(`\nšŸ“” New Courier ${s} Request: ${e}\nURL: ${n.url}\n${n.method?`Method: ${n.method}`:""}\n${n.query?`Query: ${n.query}`:""}\n${n.variables?`Variables: ${JSON.stringify(n.variables,null,2)}`:""}\nHeaders: ${JSON.stringify(n.headers,null,2)}\nBody: ${n.body?JSON.stringify(n.body,null,2):"Empty"}\n `)}function h(t,e,s,n){t.log(`\nšŸ“” New Courier ${s} Response: ${e}\nStatus Code: ${n.status}\nResponse JSON: ${JSON.stringify(n.response,null,2)}\n `)}async function l(t){const e=t.validCodes??[200],s=t.options.showLogs?a.generate():void 0,n=new Request(t.url,{method:t.method,headers:{"Content-Type":"application/json",...t.headers},body:t.body?JSON.stringify(t.body):void 0});s&&u(t.options.logger,s,"HTTP",{url:n.url,method:n.method,headers:Object.fromEntries(n.headers.entries()),body:t.body});const i=await fetch(n);if(204===i.status)return;let o;try{o=await i.json()}catch(r){if(200===i.status)return;throw new c(i.status,"Failed to parse response as JSON","PARSE_ERROR")}if(s&&h(t.options.logger,s,"HTTP",{status:i.status,response:o}),!e.includes(i.status))throw new c(i.status,(null==o?void 0:o.message)||"Unknown Error",null==o?void 0:o.type);return o}async function d(t){const e=t.options.showLogs?a.generate():void 0;e&&u(t.options.logger,e,"GraphQL",{url:t.url,headers:t.headers,query:t.query,variables:t.variables});const s=await fetch(t.url,{method:"POST",headers:{"Content-Type":"application/json",...t.headers},body:JSON.stringify({query:t.query,variables:t.variables})});let n;try{n=await s.json()}catch(i){throw new c(s.status,"Failed to parse response as JSON","PARSE_ERROR")}if(e&&h(t.options.logger,e,"GraphQL",{status:s.status,response:n}),!s.ok)throw new c(s.status,(null==n?void 0:n.message)||"Unknown Error",null==n?void 0:n.type);return n}class p{constructor(t){this.options=t}}class g extends p{async getBrand(t){const e=`\n query GetBrand {\n brand(brandId: "${t.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 d({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:e,variables:{brandId:t.brandId}})).data.brand}}class m extends i{constructor(t){super(m.buildUrl(t),t),s(this,"receivedMessage"),s(this,"receivedMessageEvent"),this.onMessageReceived=t=>this.convertToType(t)}convertToType(t){var e,s,n,i;try{switch(JSON.parse(t).type){case"event":const n=JSON.parse(t);null==(e=this.receivedMessageEvent)||e.call(this,n);break;case"message":const i=JSON.parse(t);null==(s=this.receivedMessage)||s.call(this,i)}}catch(o){null==(n=this.options.logger)||n.error("Error parsing socket message",o),o instanceof Error&&(null==(i=this.onError)||i.call(this,o))}}async sendSubscribe(t){var e;const s={action:"subscribe",data:{userAgent:"courier-js",channel:this.options.userId,event:"*",version:(null==t?void 0:t.version)??5}};this.options.connectionId&&(s.data.clientSourceId=this.options.connectionId),this.options.tenantId&&(s.data.accountId=this.options.tenantId),null==(e=this.options.logger)||e.debug("Sending subscribe request",s),await this.send(s)}static buildUrl(t){var e;let s=(null==(e=t.apiUrls)?void 0:e.inbox.webSocket)??"";return t.accessToken&&(s+=`/?auth=${t.accessToken}`),s}}class I extends p{constructor(t){super(t),s(this,"socket"),this.socket=new m(t)}async getMessages(t){const e=`\n query GetInboxMessages(\n $params: FilterParamsInput = { ${this.options.tenantId?`accountId: "${this.options.tenantId}"`:""} }\n $limit: Int = ${(null==t?void 0:t.paginationLimit)??24}\n $after: String ${(null==t?void 0:t.startCursor)?`= "${t.startCursor}"`:""}\n ) {\n count(params: $params)\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 d({options:this.options,query:e,headers:{"x-courier-user-id":this.options.userId,Authorization:`Bearer ${this.options.accessToken}`},url:this.options.apiUrls.inbox.graphql})}async getArchivedMessages(t){const e=`\n query GetInboxMessages(\n $params: FilterParamsInput = { ${this.options.tenantId?`accountId: "${this.options.tenantId}"`:""}, archived: true }\n $limit: Int = ${(null==t?void 0:t.paginationLimit)??24}\n $after: String ${(null==t?void 0:t.startCursor)?`= "${t.startCursor}"`:""}\n ) {\n count(params: $params)\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 d({options:this.options,query:e,headers:{"x-courier-user-id":this.options.userId,Authorization:`Bearer ${this.options.accessToken}`},url:this.options.apiUrls.inbox.graphql})}async getUnreadMessageCount(){var t;const e=`\n query GetMessages {\n count(params: { status: "unread" ${this.options.tenantId?`, accountId: "${this.options.tenantId}"`:""} })\n }\n `;return(null==(t=(await d({options:this.options,query:e,headers:{"x-courier-user-id":this.options.userId,Authorization:`Bearer ${this.options.accessToken}`},url:this.options.apiUrls.inbox.graphql})).data)?void 0:t.count)??0}async click(t){const e=`\n mutation TrackEvent {\n clicked(messageId: "${t.messageId}", trackingId: "${t.trackingId}")\n }\n `,s={"x-courier-user-id":this.options.userId,Authorization:`Bearer ${this.options.accessToken}`};this.options.connectionId&&(s["x-courier-client-source-id"]=this.options.connectionId),await d({options:this.options,query:e,headers:s,url:this.options.apiUrls.inbox.graphql})}async read(t){const e=`\n mutation TrackEvent {\n read(messageId: "${t.messageId}")\n }\n `,s={"x-courier-user-id":this.options.userId,Authorization:`Bearer ${this.options.accessToken}`};this.options.connectionId&&(s["x-courier-client-source-id"]=this.options.connectionId),await d({options:this.options,query:e,headers:s,url:this.options.apiUrls.inbox.graphql})}async unread(t){const e=`\n mutation TrackEvent {\n unread(messageId: "${t.messageId}")\n }\n `,s={"x-courier-user-id":this.options.userId,Authorization:`Bearer ${this.options.accessToken}`};this.options.connectionId&&(s["x-courier-client-source-id"]=this.options.connectionId),await d({options:this.options,query:e,headers:s,url:this.options.apiUrls.inbox.graphql})}async readAll(){const t={"x-courier-user-id":this.options.userId,Authorization:`Bearer ${this.options.accessToken}`};this.options.connectionId&&(t["x-courier-client-source-id"]=this.options.connectionId),await d({options:this.options,query:"\n mutation TrackEvent {\n markAllRead\n }\n ",headers:t,url:this.options.apiUrls.inbox.graphql})}async open(t){const e=`\n mutation TrackEvent {\n opened(messageId: "${t.messageId}")\n }\n `,s={"x-courier-user-id":this.options.userId,Authorization:`Bearer ${this.options.accessToken}`};this.options.connectionId&&(s["x-courier-client-source-id"]=this.options.connectionId),await d({options:this.options,query:e,headers:s,url:this.options.apiUrls.inbox.graphql})}async archive(t){const e=`\n mutation TrackEvent {\n archive(messageId: "${t.messageId}")\n }\n `,s={"x-courier-user-id":this.options.userId,Authorization:`Bearer ${this.options.accessToken}`};this.options.connectionId&&(s["x-courier-client-source-id"]=this.options.connectionId),await d({options:this.options,query:e,headers:s,url:this.options.apiUrls.inbox.graphql})}async unarchive(t){const e=`\n mutation TrackEvent {\n unarchive(messageId: "${t.messageId}")\n }\n `,s={"x-courier-user-id":this.options.userId,Authorization:`Bearer ${this.options.accessToken}`};this.options.connectionId&&(s["x-courier-client-source-id"]=this.options.connectionId),await d({options:this.options,query:e,headers:s,url:this.options.apiUrls.inbox.graphql})}async archiveRead(){const t={"x-courier-user-id":this.options.userId,Authorization:`Bearer ${this.options.accessToken}`};this.options.connectionId&&(t["x-courier-client-source-id"]=this.options.connectionId),await d({options:this.options,query:"\n mutation TrackEvent {\n archiveRead\n }\n ",headers:t,url:this.options.apiUrls.inbox.graphql})}async archiveAll(){const t={"x-courier-user-id":this.options.userId,Authorization:`Bearer ${this.options.accessToken}`};this.options.connectionId&&(t["x-courier-client-source-id"]=this.options.connectionId),await d({options:this.options,query:"\n mutation TrackEvent {\n archiveAll\n }\n ",headers:t,url:this.options.apiUrls.inbox.graphql})}}class v{transformItem(t){return{topicId:t.topic_id,topicName:t.topic_name,sectionId:t.section_id,sectionName:t.section_name,status:t.status,defaultStatus:t.default_status,hasCustomRouting:t.has_custom_routing,customRouting:t.custom_routing||[]}}*transform(t){for(const e of t)yield this.transformItem(e)}}class b extends p{constructor(){super(...arguments),s(this,"transformer",new v)}async getUserPreferences(t){let e=`${this.options.apiUrls.courier.rest}/users/${this.options.userId}/preferences`;(null==t?void 0:t.paginationCursor)&&(e+=`?cursor=${t.paginationCursor}`);const s=await l({options:this.options,url:e,method:"GET",headers:{Authorization:`Bearer ${this.options.accessToken}`}});return{items:[...this.transformer.transform(s.items)],paging:s.paging}}async getUserPreferenceTopic(t){const e=await l({options:this.options,url:`${this.options.apiUrls.courier.rest}/users/${this.options.userId}/preferences/${t.topicId}`,method:"GET",headers:{Authorization:`Bearer ${this.options.accessToken}`}});return this.transformer.transformItem(e.topic)}async putUserPreferenceTopic(t){const e={topic:{status:t.status,has_custom_routing:t.hasCustomRouting,custom_routing:t.customRouting}};await l({options:this.options,url:`${this.options.apiUrls.courier.rest}/users/${this.options.userId}/preferences/${t.topicId}`,method:"PUT",headers:{Authorization:`Bearer ${this.options.accessToken}`},body:e})}getNotificationCenterUrl(t){return`https://view.notificationcenter.app/p/${function(t){const e=new Uint8Array(t.length);for(let s=0;s<t.length;s++)e[s]=t.charCodeAt(s);return btoa(String.fromCharCode(...e))}(`${function(t){const e=atob(t),s=new Uint8Array(e.length);for(let n=0;n<e.length;n++)s[n]=e.charCodeAt(n);return String.fromCharCode(...s)}(t.clientKey)}#${this.options.userId}${this.options.tenantId?`#${this.options.tenantId}`:""}#false`)}`}}class y extends p{async putUserToken(t){const e={provider_key:t.provider,...t.device&&{device:{app_id:t.device.appId,ad_id:t.device.adId,device_id:t.device.deviceId,platform:t.device.platform,manufacturer:t.device.manufacturer,model:t.device.model}}};await l({options:this.options,url:`${this.options.apiUrls.courier.rest}/users/${this.options.userId}/tokens/${t.token}`,method:"PUT",headers:{Authorization:`Bearer ${this.options.accessToken}`},body:e,validCodes:[200,204]})}async deleteUserToken(t){await l({options:this.options,url:`${this.options.apiUrls.courier.rest}/users/${this.options.userId}/tokens/${t.token}`,method:"DELETE",headers:{Authorization:`Bearer ${this.options.accessToken}`},validCodes:[200,204]})}}class w extends p{async putSubscription(t){return await l({url:`${this.options.apiUrls.courier.rest}/lists/${t.listId}/subscriptions/${this.options.userId}`,options:this.options,method:"PUT",headers:{Authorization:`Bearer ${this.options.accessToken}`}})}async deleteSubscription(t){return await l({url:`${this.options.apiUrls.courier.rest}/lists/${t.listId}/subscriptions/${this.options.userId}`,options:this.options,method:"DELETE",headers:{Authorization:`Bearer ${this.options.accessToken}`}})}}class $ extends p{async postInboundCourier(t){return await l({url:`${this.options.apiUrls.courier.rest}/inbound/courier`,options:this.options,method:"POST",headers:{Authorization:`Bearer ${this.options.accessToken}`},body:{...t,userId:this.options.userId},validCodes:[200,202]})}async postTrackingUrl(t){return await l({url:t.url,options:this.options,method:"POST",body:{event:t.event}})}}class f extends p{constructor(t){var e,n;const i=void 0!==t.showLogs?t.showLogs:"development"===process.env.NODE_ENV,a={...t,showLogs:i,apiUrls:t.apiUrls||o(),accessToken:t.jwt??t.publicApiKey};super({...a,logger:new r(a.showLogs),apiUrls:o(a.apiUrls)}),s(this,"tokens"),s(this,"brands"),s(this,"preferences"),s(this,"inbox"),s(this,"lists"),s(this,"tracking"),this.tokens=new y(this.options),this.brands=new g(this.options),this.preferences=new b(this.options),this.inbox=new I(this.options),this.lists=new w(this.options),this.tracking=new $(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==(e=this.options.logger)||e.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/reference/auth/issue-token\nThis endpoint should be called from your backend server, not the SDK.")),this.options.jwt&&this.options.publicApiKey&&(null==(n=this.options.logger)||n.warn("Courier Warning: Both a JWT and a Public API Key were provided. The Public API Key will be ignored."))}}class k{constructor(t){s(this,"callback"),this.callback=t}remove(){S.shared.removeAuthenticationListener(this)}}const T=class t{constructor(){s(this,"id",a.generate()),s(this,"instanceClient"),s(this,"_paginationLimit",24),s(this,"authenticationListeners",[])}get paginationLimit(){return this._paginationLimit}set paginationLimit(t){this._paginationLimit=Math.min(Math.max(t,1),100)}get client(){return this.instanceClient}static get shared(){return t.instance||(t.instance=new t),t.instance}signIn(t){const e=t.connectionId??a.generate();this.instanceClient=new f({...t,connectionId:e}),this.notifyAuthenticationListeners({userId:t.userId})}signOut(){this.instanceClient=void 0,this.notifyAuthenticationListeners({userId:void 0})}addAuthenticationListener(t){var e;null==(e=this.instanceClient)||e.options.logger.info("Adding authentication listener");const s=new k(t);return this.authenticationListeners.push(s),s}removeAuthenticationListener(t){var e;null==(e=this.instanceClient)||e.options.logger.info("Removing authentication listener"),this.authenticationListeners=this.authenticationListeners.filter((e=>e!==t))}notifyAuthenticationListeners(t){this.authenticationListeners.forEach((e=>e.callback(t)))}};s(T,"instance");let S=T;t.BrandClient=g,t.Courier=S,t.CourierClient=f,t.CourierSocket=i,t.InboxClient=I,t.ListClient=w,t.PreferenceClient=b,t.TokenClient=y,Object.defineProperty(t,Symbol.toStringTag,{value:"Module"})}));
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../src/socket/courier-socket.ts","../src/types/courier-api-urls.ts","../src/utils/logger.ts","../src/utils/uuid.ts","../src/utils/request.ts","../src/client/client.ts","../src/client/brand-client.ts","../src/socket/inbox-socket.ts","../src/client/inbox-client.ts","../src/types/preference.ts","../src/client/preference-client.ts","../src/utils/coding.ts","../src/client/token-client.ts","../src/client/list-client.ts","../src/client/tracking-client.ts","../src/client/courier-client.ts","../src/shared/authentication-listener.ts","../src/shared/courier.ts"],"sourcesContent":["import { CourierClientOptions } from \"../client/courier-client\";\n\nexport class CourierSocket {\n\n // Constants\n private static readonly NORMAL_CLOSURE_STATUS = 1000;\n\n // Properties\n private webSocket: WebSocket | null = null;\n private pingInterval: NodeJS.Timeout | null = null;\n\n // Callbacks\n public onOpen?: () => void;\n public onMessageReceived?: (message: string) => void;\n public onClose?: (code: number, reason?: string) => void;\n public onError?: (error: Error) => void;\n\n // Properties\n private readonly url: string;\n readonly options: CourierClientOptions;\n\n constructor(url: string, options: CourierClientOptions) {\n this.url = url;\n this.options = options;\n }\n\n /**\n * Dynamically checks if the WebSocket is connected\n */\n public get isConnected(): boolean {\n return this.webSocket !== null;\n }\n\n public async connect(): Promise<void> {\n // Disconnect if already connected\n this.disconnect();\n\n return new Promise((resolve, reject) => {\n try {\n this.webSocket = new WebSocket(this.url);\n\n this.webSocket.onopen = () => {\n this.onOpen?.();\n resolve();\n };\n\n this.webSocket.onmessage = (event) => {\n this.onMessageReceived?.(event.data);\n };\n\n this.webSocket.onclose = (event) => {\n this.webSocket = null;\n this.onClose?.(event.code, event.reason);\n };\n\n this.webSocket.onerror = (event) => {\n this.webSocket = null;\n const error = new Error('Courier Socket connection failed');\n (error as any).originalEvent = event;\n this.onError?.(error);\n reject(error);\n };\n\n } catch (error) {\n this.webSocket = null;\n reject(error);\n }\n });\n }\n\n public disconnect(): void {\n this.stopPing();\n if (this.webSocket) {\n this.webSocket.close(CourierSocket.NORMAL_CLOSURE_STATUS);\n this.webSocket = null;\n }\n }\n\n public async send(message: Record<string, any>): Promise<boolean> {\n if (!this.webSocket) {\n return false;\n }\n\n const json = JSON.stringify(message);\n return this.webSocket.send(json) !== undefined;\n }\n\n public keepAlive(props?: {\n intervalInMillis?: number;\n }): void {\n this.stopPing();\n this.pingInterval = setInterval(async () => {\n try {\n await this.send({ action: 'keepAlive' });\n } catch (error) {\n this.options.logger?.error('Error occurred on Keep Alive:', error);\n }\n }, props?.intervalInMillis ?? 300_000);\n }\n\n private stopPing(): void {\n if (this.pingInterval) {\n clearInterval(this.pingInterval);\n this.pingInterval = null;\n }\n }\n\n}\n","export interface CourierApiUrls {\n courier: {\n rest: string;\n graphql: string;\n },\n inbox: {\n graphql: string;\n webSocket: string;\n }\n}\n\nexport const getCourierApiUrls = (urls?: CourierApiUrls): CourierApiUrls => ({\n courier: {\n rest: urls?.courier.rest || 'https://api.courier.com',\n graphql: urls?.courier.graphql || 'https://api.courier.com/client/q',\n },\n inbox: {\n graphql: urls?.inbox.graphql || 'https://inbox.courier.com/q',\n webSocket: urls?.inbox.webSocket || 'wss://realtime.courier.io'\n }\n});","export class Logger {\n\n private readonly PREFIX = '[COURIER]';\n\n constructor(private readonly showLogs: boolean) { }\n\n public warn(message: string, ...args: any[]): void {\n if (this.showLogs) {\n console.warn(`${this.PREFIX} ${message}`, ...args);\n }\n }\n\n public log(message: string, ...args: any[]): void {\n if (this.showLogs) {\n console.log(`${this.PREFIX} ${message}`, ...args);\n }\n }\n\n public error(message: string, ...args: any[]): void {\n if (this.showLogs) {\n console.error(`${this.PREFIX} ${message}`, ...args);\n }\n }\n\n public debug(message: string, ...args: any[]): void {\n if (this.showLogs) {\n console.debug(`${this.PREFIX} ${message}`, ...args);\n }\n }\n\n public info(message: string, ...args: any[]): void {\n if (this.showLogs) {\n console.info(`${this.PREFIX} ${message}`, ...args);\n }\n }\n}\n","export class UUID {\n\n static generate(prefix?: string): string {\n const id = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);\n return prefix ? prefix + id : id;\n }\n\n}","import { CourierClientOptions } from \"../client/courier-client\";\nimport { Logger } from \"./logger\";\nimport { UUID } from \"./uuid\";\n\nexport class CourierRequestError extends Error {\n constructor(\n public code: number,\n message: string,\n public type?: string\n ) {\n super(message);\n this.name = 'CourierRequestError';\n }\n}\n\nfunction logRequest(logger: Logger, uid: string, type: 'HTTP' | 'GraphQL', data: {\n url: string;\n method?: string;\n headers: Record<string, string>;\n body?: any;\n query?: string;\n variables?: Record<string, any>;\n}) {\n logger.log(`\nšŸ“” New Courier ${type} Request: ${uid}\nURL: ${data.url}\n${data.method ? `Method: ${data.method}` : ''}\n${data.query ? `Query: ${data.query}` : ''}\n${data.variables ? `Variables: ${JSON.stringify(data.variables, null, 2)}` : ''}\nHeaders: ${JSON.stringify(data.headers, null, 2)}\nBody: ${data.body ? JSON.stringify(data.body, null, 2) : 'Empty'}\n `);\n}\n\nfunction logResponse(logger: Logger, uid: string, type: 'HTTP' | 'GraphQL', data: {\n status: number;\n response: any;\n}) {\n logger.log(`\nšŸ“” New Courier ${type} Response: ${uid}\nStatus Code: ${data.status}\nResponse JSON: ${JSON.stringify(data.response, null, 2)}\n `);\n}\n\nexport async function http(props: {\n url: string,\n options: CourierClientOptions,\n method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH',\n headers?: Record<string, string>,\n body?: any,\n validCodes?: number[]\n}): Promise<any> {\n const validCodes = props.validCodes ?? [200];\n const uid = props.options.showLogs ? UUID.generate() : undefined;\n\n // Create request\n const request = new Request(props.url, {\n method: props.method,\n headers: {\n 'Content-Type': 'application/json',\n ...props.headers\n },\n body: props.body ? JSON.stringify(props.body) : undefined\n });\n\n // Log request if enabled\n if (uid) {\n logRequest(props.options.logger, uid, 'HTTP', {\n url: request.url,\n method: request.method,\n headers: Object.fromEntries(request.headers.entries()),\n body: props.body\n });\n }\n\n // Perform request\n const response = await fetch(request);\n\n // Handle empty responses (like 204 No Content)\n if (response.status === 204) {\n return;\n }\n\n // Try to parse JSON response\n let data;\n try {\n data = await response.json();\n } catch (error) {\n\n // Weird fallback for only tracking url events :facepalm:\n if (response.status === 200) {\n return;\n }\n\n throw new CourierRequestError(\n response.status,\n 'Failed to parse response as JSON',\n 'PARSE_ERROR'\n );\n }\n\n // Log response if enabled\n if (uid) {\n logResponse(props.options.logger, uid, 'HTTP', {\n status: response.status,\n response: data\n });\n }\n\n // Handle invalid status codes\n if (!validCodes.includes(response.status)) {\n throw new CourierRequestError(\n response.status,\n data?.message || 'Unknown Error',\n data?.type\n );\n }\n\n return data;\n}\n\nexport async function graphql(props: {\n url: string,\n options: CourierClientOptions,\n headers: Record<string, string>,\n query: string,\n variables?: Record<string, any>\n}): Promise<any> {\n const uid = props.options.showLogs ? UUID.generate() : undefined;\n\n // Log request if enabled\n if (uid) {\n logRequest(props.options.logger, uid, 'GraphQL', {\n url: props.url,\n headers: props.headers,\n query: props.query,\n variables: props.variables\n });\n }\n\n const response = await fetch(props.url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...props.headers\n },\n body: JSON.stringify({\n query: props.query,\n variables: props.variables\n })\n });\n\n // Try to parse JSON response\n let data;\n try {\n data = await response.json();\n } catch (error) {\n throw new CourierRequestError(\n response.status,\n 'Failed to parse response as JSON',\n 'PARSE_ERROR'\n );\n }\n\n // Log response if enabled\n if (uid) {\n logResponse(props.options.logger, uid, 'GraphQL', {\n status: response.status,\n response: data\n });\n }\n\n if (!response.ok) {\n throw new CourierRequestError(\n response.status,\n data?.message || 'Unknown Error',\n data?.type\n );\n }\n\n return data;\n}\n","import { CourierClientOptions } from \"./courier-client\";\n\nexport class Client {\n\n constructor(public readonly options: CourierClientOptions) { }\n\n}\n","import { CourierBrand } from '../types/brands';\nimport { graphql } from '../utils/request';\nimport { Client } from './client';\n\nexport class BrandClient extends Client {\n\n /**\n * Get a brand by ID using GraphQL\n * @param brandId - The ID of the brand to retrieve\n * @returns Promise resolving to the requested brand\n */\n public async getBrand(props: { brandId: string }): Promise<CourierBrand> {\n const query = `\n query GetBrand {\n brand(brandId: \"${props.brandId}\") {\n settings {\n colors {\n primary\n secondary\n tertiary\n }\n inapp {\n borderRadius\n disableCourierFooter\n }\n }\n }\n }\n `;\n\n const json = await graphql({\n options: this.options,\n url: this.options.apiUrls.courier.graphql,\n headers: {\n 'x-courier-user-id': this.options.userId,\n 'x-courier-client-key': 'empty', // Empty for now. Will be removed in future.\n 'Authorization': `Bearer ${this.options.accessToken}`\n },\n query,\n variables: { brandId: props.brandId }\n });\n\n return json.data.brand as CourierBrand;\n }\n\n}\n","import { CourierSocket } from './courier-socket';\nimport { CourierClientOptions } from '../client/courier-client';\nimport { InboxMessage } from '../types/inbox';\n\ninterface SocketPayload {\n type: 'event' | 'message';\n}\n\nexport interface MessageEvent {\n event: EventType;\n messageId?: string;\n type: string;\n}\n\nexport type EventType =\n | 'archive-read'\n | 'archive'\n | 'click'\n | 'mark-all-read'\n | 'opened'\n | 'read'\n | 'unarchive'\n | 'unopened'\n | 'unread';\n\nexport class InboxSocket extends CourierSocket {\n\n public receivedMessage?: (message: InboxMessage) => void;\n public receivedMessageEvent?: (event: MessageEvent) => void;\n\n constructor(options: CourierClientOptions) {\n const url = InboxSocket.buildUrl(options);\n super(url, options);\n this.onMessageReceived = (data) => this.convertToType(data);\n }\n\n private convertToType(data: string): void {\n try {\n const payload = JSON.parse(data) as SocketPayload;\n\n switch (payload.type) {\n case 'event':\n const messageEvent = JSON.parse(data) as MessageEvent;\n this.receivedMessageEvent?.(messageEvent);\n break;\n\n case 'message':\n const message = JSON.parse(data) as InboxMessage;\n this.receivedMessage?.(message);\n break;\n }\n } catch (error) {\n this.options.logger?.error('Error parsing socket message', error);\n if (error instanceof Error) {\n this.onError?.(error);\n }\n }\n }\n\n public async sendSubscribe(props?: {\n version?: number;\n }): Promise<void> {\n const subscription: Record<string, any> = {\n action: 'subscribe',\n data: {\n userAgent: 'courier-js', // TODO: Equivalent to Courier.agent.value()\n channel: this.options.userId,\n event: '*',\n version: props?.version ?? 5,\n }\n };\n\n // Add optional parameters\n if (this.options.connectionId) {\n subscription.data.clientSourceId = this.options.connectionId;\n }\n if (this.options.tenantId) {\n subscription.data.accountId = this.options.tenantId;\n }\n\n this.options.logger?.debug('Sending subscribe request', subscription);\n\n await this.send(subscription);\n }\n\n private static buildUrl(options: CourierClientOptions): string {\n let url = options.apiUrls?.inbox.webSocket ?? '';\n\n if (options.accessToken) {\n url += `/?auth=${options.accessToken}`;\n }\n\n return url;\n }\n}\n","import { InboxSocket } from '../socket/inbox-socket';\nimport { CourierGetInboxMessagesResponse } from '../types/inbox';\nimport { graphql } from '../utils/request';\nimport { Client } from './client';\nimport { CourierClientOptions } from './courier-client';\n\nexport class InboxClient extends Client {\n\n readonly socket: InboxSocket;\n\n constructor(options: CourierClientOptions) {\n super(options);\n this.socket = new InboxSocket(options);\n }\n\n /**\n * Get paginated messages\n * @param paginationLimit - Number of messages to return per page (default: 24)\n * @param startCursor - Cursor for pagination\n * @returns Promise resolving to paginated messages response\n */\n public async getMessages(props?: {\n paginationLimit?: number;\n startCursor?: string;\n }): Promise<CourierGetInboxMessagesResponse> {\n const query = `\n query GetInboxMessages(\n $params: FilterParamsInput = { ${this.options.tenantId ? `accountId: \"${this.options.tenantId}\"` : ''} }\n $limit: Int = ${props?.paginationLimit ?? 24}\n $after: String ${props?.startCursor ? `= \"${props.startCursor}\"` : ''}\n ) {\n count(params: $params)\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 `;\n\n return await graphql({\n options: this.options,\n query,\n headers: {\n 'x-courier-user-id': this.options.userId,\n 'Authorization': `Bearer ${this.options.accessToken}`\n },\n url: this.options.apiUrls.inbox.graphql,\n });\n }\n\n /**\n * Get paginated archived messages\n * @param paginationLimit - Number of messages to return per page (default: 24)\n * @param startCursor - Cursor for pagination\n * @returns Promise resolving to paginated archived messages response\n */\n public async getArchivedMessages(props?: {\n paginationLimit?: number;\n startCursor?: string;\n }): Promise<CourierGetInboxMessagesResponse> {\n const query = `\n query GetInboxMessages(\n $params: FilterParamsInput = { ${this.options.tenantId ? `accountId: \"${this.options.tenantId}\"` : ''}, archived: true }\n $limit: Int = ${props?.paginationLimit ?? 24}\n $after: String ${props?.startCursor ? `= \"${props.startCursor}\"` : ''}\n ) {\n count(params: $params)\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 `;\n\n return graphql({\n options: this.options,\n query,\n headers: {\n 'x-courier-user-id': this.options.userId,\n 'Authorization': `Bearer ${this.options.accessToken}`\n },\n url: this.options.apiUrls.inbox.graphql,\n });\n }\n\n /**\n * Get unread message count\n * @returns Promise resolving to number of unread messages\n */\n public async getUnreadMessageCount(): Promise<number> {\n const query = `\n query GetMessages {\n count(params: { status: \"unread\" ${this.options.tenantId ? `, accountId: \"${this.options.tenantId}\"` : ''} })\n }\n `;\n\n const response = await graphql({\n options: this.options,\n query,\n headers: {\n 'x-courier-user-id': this.options.userId,\n 'Authorization': `Bearer ${this.options.accessToken}`\n },\n url: this.options.apiUrls.inbox.graphql,\n });\n\n return response.data?.count ?? 0;\n }\n\n /**\n * Track a click event\n * @param messageId - ID of the message\n * @param trackingId - ID for tracking the click\n * @returns Promise resolving when click is tracked\n */\n public async click(props: { messageId: string, trackingId: string }): Promise<void> {\n const query = `\n mutation TrackEvent {\n clicked(messageId: \"${props.messageId}\", trackingId: \"${props.trackingId}\")\n }\n `;\n\n const headers: Record<string, string> = {\n 'x-courier-user-id': this.options.userId,\n 'Authorization': `Bearer ${this.options.accessToken}`\n };\n\n if (this.options.connectionId) {\n headers['x-courier-client-source-id'] = this.options.connectionId;\n }\n\n await graphql({\n options: this.options,\n query,\n headers,\n url: this.options.apiUrls.inbox.graphql,\n });\n }\n\n /**\n * Mark a message as read\n * @param messageId - ID of the message to mark as read\n * @returns Promise resolving when message is marked as read\n */\n public async read(props: { messageId: string }): Promise<void> {\n const query = `\n mutation TrackEvent {\n read(messageId: \"${props.messageId}\")\n }\n `;\n\n const headers: Record<string, string> = {\n 'x-courier-user-id': this.options.userId,\n 'Authorization': `Bearer ${this.options.accessToken}`\n };\n\n if (this.options.connectionId) {\n headers['x-courier-client-source-id'] = this.options.connectionId;\n }\n\n await graphql({\n options: this.options,\n query,\n headers,\n url: this.options.apiUrls.inbox.graphql,\n });\n }\n\n /**\n * Mark a message as unread\n * @param messageId - ID of the message to mark as unread\n * @returns Promise resolving when message is marked as unread\n */\n public async unread(props: { messageId: string }): Promise<void> {\n const query = `\n mutation TrackEvent {\n unread(messageId: \"${props.messageId}\")\n }\n `;\n\n const headers: Record<string, string> = {\n 'x-courier-user-id': this.options.userId,\n 'Authorization': `Bearer ${this.options.accessToken}`\n };\n\n if (this.options.connectionId) {\n headers['x-courier-client-source-id'] = this.options.connectionId;\n }\n\n await graphql({\n options: this.options,\n query,\n headers,\n url: this.options.apiUrls.inbox.graphql,\n });\n }\n\n /**\n * Mark all messages as read\n * @returns Promise resolving when all messages are marked as read\n */\n public async readAll(): Promise<void> {\n const query = `\n mutation TrackEvent {\n markAllRead\n }\n `;\n\n const headers: Record<string, string> = {\n 'x-courier-user-id': this.options.userId,\n 'Authorization': `Bearer ${this.options.accessToken}`\n };\n\n if (this.options.connectionId) {\n headers['x-courier-client-source-id'] = this.options.connectionId;\n }\n\n await graphql({\n options: this.options,\n query,\n headers,\n url: this.options.apiUrls.inbox.graphql,\n });\n }\n\n /**\n * Mark a message as opened\n * @param messageId - ID of the message to mark as opened\n * @returns Promise resolving when message is marked as opened\n */\n public async open(props: { messageId: string }): Promise<void> {\n const query = `\n mutation TrackEvent {\n opened(messageId: \"${props.messageId}\")\n }\n `;\n\n const headers: Record<string, string> = {\n 'x-courier-user-id': this.options.userId,\n 'Authorization': `Bearer ${this.options.accessToken}`\n };\n\n if (this.options.connectionId) {\n headers['x-courier-client-source-id'] = this.options.connectionId;\n }\n\n await graphql({\n options: this.options,\n query,\n headers,\n url: this.options.apiUrls.inbox.graphql,\n });\n }\n\n /**\n * Archive a message\n * @param messageId - ID of the message to archive\n * @returns Promise resolving when message is archived\n */\n public async archive(props: { messageId: string }): Promise<void> {\n const query = `\n mutation TrackEvent {\n archive(messageId: \"${props.messageId}\")\n }\n `;\n\n const headers: Record<string, string> = {\n 'x-courier-user-id': this.options.userId,\n 'Authorization': `Bearer ${this.options.accessToken}`\n };\n\n if (this.options.connectionId) {\n headers['x-courier-client-source-id'] = this.options.connectionId;\n }\n\n await graphql({\n options: this.options,\n query,\n headers,\n url: this.options.apiUrls.inbox.graphql,\n });\n }\n\n /**\n * Unarchive a message\n * @param messageId - ID of the message to unarchive\n * @returns Promise resolving when message is unarchived\n */\n public async unarchive(props: { messageId: string }): Promise<void> {\n const query = `\n mutation TrackEvent {\n unarchive(messageId: \"${props.messageId}\")\n }\n `;\n\n const headers: Record<string, string> = {\n 'x-courier-user-id': this.options.userId,\n 'Authorization': `Bearer ${this.options.accessToken}`\n };\n\n if (this.options.connectionId) {\n headers['x-courier-client-source-id'] = this.options.connectionId;\n }\n\n await graphql({\n options: this.options,\n query,\n headers,\n url: this.options.apiUrls.inbox.graphql,\n });\n }\n\n /**\n * Archive all read messages.\n */\n public async archiveRead(): Promise<void> {\n const query = `\n mutation TrackEvent {\n archiveRead\n }\n `;\n\n const headers: Record<string, string> = {\n 'x-courier-user-id': this.options.userId,\n 'Authorization': `Bearer ${this.options.accessToken}`\n };\n\n if (this.options.connectionId) {\n headers['x-courier-client-source-id'] = this.options.connectionId;\n }\n\n await graphql({\n options: this.options,\n query,\n headers,\n url: this.options.apiUrls.inbox.graphql,\n });\n }\n\n /**\n * Archive all read messages.\n */\n public async archiveAll(): Promise<void> {\n const query = `\n mutation TrackEvent {\n archiveAll\n }\n `;\n\n const headers: Record<string, string> = {\n 'x-courier-user-id': this.options.userId,\n 'Authorization': `Bearer ${this.options.accessToken}`\n };\n\n if (this.options.connectionId) {\n headers['x-courier-client-source-id'] = this.options.connectionId;\n }\n\n await graphql({\n options: this.options,\n query,\n headers,\n url: this.options.apiUrls.inbox.graphql,\n });\n }\n\n}\n","export type CourierUserPreferencesStatus = 'OPTED_IN' | 'OPTED_OUT' | 'REQUIRED' | 'UNKNOWN';\n\nexport type CourierUserPreferencesChannel = 'direct_message' | 'email' | 'push' | 'sms' | 'webhook' | 'unknown';\n\nexport interface CourierUserPreferencesPaging {\n cursor?: string;\n more: boolean;\n}\n\nexport interface CourierUserPreferencesTopic {\n topicId: string;\n topicName: string;\n sectionId: string;\n sectionName: string;\n status: CourierUserPreferencesStatus;\n defaultStatus: CourierUserPreferencesStatus;\n hasCustomRouting: boolean;\n customRouting: CourierUserPreferencesChannel[];\n}\n\nexport interface CourierUserPreferences {\n items: CourierUserPreferencesTopic[];\n paging: CourierUserPreferencesPaging;\n}\n\nexport interface CourierUserPreferencesTopicResponse {\n topic: CourierUserPreferencesTopic;\n}\n\nexport class PreferenceTransformer {\n /**\n * Transforms a single API response item to the CourierUserPreferencesTopic type\n * @param item - The API response item\n * @returns A CourierUserPreferencesTopic object\n */\n transformItem(item: any): CourierUserPreferencesTopic {\n return {\n topicId: item.topic_id,\n topicName: item.topic_name,\n sectionId: item.section_id,\n sectionName: item.section_name,\n status: item.status,\n defaultStatus: item.default_status,\n hasCustomRouting: item.has_custom_routing,\n customRouting: item.custom_routing || []\n };\n }\n\n /**\n * Transforms an array of API response items to CourierUserPreferencesTopic objects\n * @param items - The API response items\n * @returns A generator of CourierUserPreferencesTopic objects\n */\n *transform(items: any[]): Generator<CourierUserPreferencesTopic> {\n for (const item of items) {\n yield this.transformItem(item);\n }\n }\n}","import { CourierUserPreferences, CourierUserPreferencesChannel, CourierUserPreferencesStatus, CourierUserPreferencesTopic, CourierUserPreferencesTopicResponse, PreferenceTransformer } from '../types/preference';\nimport { decode, encode } from '../utils/coding';\nimport { http } from '../utils/request';\nimport { Client } from './client';\n\nexport class PreferenceClient extends Client {\n private transformer = new PreferenceTransformer();\n\n /**\n * Get all preferences for a user\n * @param paginationCursor - Optional cursor for pagination\n * @returns Promise resolving to user preferences\n * @see https://www.courier.com/docs/reference/user-preferences/list-all-user-preferences\n */\n public async getUserPreferences(props?: {\n paginationCursor?: string;\n }): Promise<CourierUserPreferences> {\n let url = `${this.options.apiUrls.courier.rest}/users/${this.options.userId}/preferences`;\n\n if (props?.paginationCursor) {\n url += `?cursor=${props.paginationCursor}`;\n }\n\n const json = await http({\n options: this.options,\n url,\n method: 'GET',\n headers: {\n 'Authorization': `Bearer ${this.options.accessToken}`\n },\n });\n\n const data = json as CourierUserPreferences;\n\n return {\n items: [...this.transformer.transform(data.items)],\n paging: data.paging\n };\n }\n\n /**\n * Get preferences for a specific topic\n * @param topicId - The ID of the topic to get preferences for\n * @returns Promise resolving to topic preferences\n * @see https://www.courier.com/docs/reference/user-preferences/get-subscription-topic-preferences\n */\n public async getUserPreferenceTopic(props: {\n topicId: string;\n }): Promise<CourierUserPreferencesTopic> {\n\n const json = await http({\n options: this.options,\n url: `${this.options.apiUrls.courier.rest}/users/${this.options.userId}/preferences/${props.topicId}`,\n method: 'GET',\n headers: {\n 'Authorization': `Bearer ${this.options.accessToken}`\n },\n });\n\n const res = json as CourierUserPreferencesTopicResponse;\n return this.transformer.transformItem(res.topic);\n }\n\n /**\n * Update preferences for a specific topic\n * @param topicId - The ID of the topic to update preferences for\n * @param status - The new status for the topic\n * @param hasCustomRouting - Whether the topic has custom routing\n * @param customRouting - The custom routing channels for the topic\n * @returns Promise resolving when update is complete\n * @see https://www.courier.com/docs/reference/user-preferences/update-subscription-topic-preferences\n */\n public async putUserPreferenceTopic(props: {\n topicId: string;\n status: CourierUserPreferencesStatus;\n hasCustomRouting: boolean;\n customRouting: CourierUserPreferencesChannel[];\n }): Promise<void> {\n\n const payload = {\n topic: {\n status: props.status,\n has_custom_routing: props.hasCustomRouting,\n custom_routing: props.customRouting,\n },\n };\n\n await http({\n options: this.options,\n url: `${this.options.apiUrls.courier.rest}/users/${this.options.userId}/preferences/${props.topicId}`,\n method: 'PUT',\n headers: {\n 'Authorization': `Bearer ${this.options.accessToken}`\n },\n body: payload,\n });\n }\n\n /**\n * Get the notification center URL\n * @param clientKey - The client key to use for the URL\n * @returns The notification center URL\n */\n public getNotificationCenterUrl(props: {\n clientKey: string;\n }): string {\n const rootTenantId = decode(props.clientKey);\n const url = encode(`${rootTenantId}#${this.options.userId}${this.options.tenantId ? `#${this.options.tenantId}` : \"\"}#${false}`);\n return `https://view.notificationcenter.app/p/${url}`;\n }\n\n}\n","export function decode(clientKey: string): string {\n const binaryString = atob(clientKey);\n const bytes = new Uint8Array(binaryString.length);\n\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n\n return String.fromCharCode(...bytes);\n}\n\nexport function encode(key: string): string {\n const bytes = new Uint8Array(key.length);\n\n for (let i = 0; i < key.length; i++) {\n bytes[i] = key.charCodeAt(i);\n }\n\n return btoa(String.fromCharCode(...bytes));\n}","import { CourierDevice } from '../types/token';\nimport { http } from '../utils/request';\nimport { Client } from './client';\n\nexport class TokenClient extends Client {\n\n /**\n * Store a push notification token for a user\n * @param token - The push notification token\n * @param provider - The provider of the token\n * @param device - The device information\n * @see https://www.courier.com/docs/reference/token-management/put-token\n */\n public async putUserToken(props: {\n token: string;\n provider: string;\n device?: CourierDevice;\n }): Promise<void> {\n const payload = {\n provider_key: props.provider,\n ...(props.device && {\n device: {\n app_id: props.device.appId,\n ad_id: props.device.adId,\n device_id: props.device.deviceId,\n platform: props.device.platform,\n manufacturer: props.device.manufacturer,\n model: props.device.model\n }\n })\n };\n\n await http({\n options: this.options,\n url: `${this.options.apiUrls.courier.rest}/users/${this.options.userId}/tokens/${props.token}`,\n method: 'PUT',\n headers: {\n 'Authorization': `Bearer ${this.options.accessToken}`\n },\n body: payload,\n validCodes: [200, 204]\n });\n }\n\n /**\n * Delete a push notification token for a user\n * @param token - The push notification token\n * @returns Promise resolving when token is deleted\n */\n public async deleteUserToken(props: {\n token: string;\n }): Promise<void> {\n await http({\n options: this.options,\n url: `${this.options.apiUrls.courier.rest}/users/${this.options.userId}/tokens/${props.token}`,\n method: 'DELETE',\n headers: {\n 'Authorization': `Bearer ${this.options.accessToken}`\n },\n validCodes: [200, 204]\n });\n }\n}\n","import { http } from '../utils/request';\nimport { Client } from './client';\n\nexport class ListClient extends Client {\n\n /**\n * Subscribe a user to a list\n * @param listId - The ID of the list to subscribe to\n * @returns Promise resolving when subscription is complete\n * @see https://www.courier.com/docs/reference/lists/recipient-subscribe\n */\n public async putSubscription(props: {\n listId: string;\n }): Promise<void> {\n return await http({\n url: `${this.options.apiUrls.courier.rest}/lists/${props.listId}/subscriptions/${this.options.userId}`,\n options: this.options,\n method: 'PUT',\n headers: {\n Authorization: `Bearer ${this.options.accessToken}`,\n },\n });\n }\n\n /**\n * Unsubscribe a user from a list\n * @param listId - The ID of the list to unsubscribe from\n * @returns Promise resolving when unsubscription is complete\n * @see https://www.courier.com/docs/reference/lists/delete-subscription\n */\n public async deleteSubscription(props: {\n listId: string;\n }): Promise<void> {\n return await http({\n url: `${this.options.apiUrls.courier.rest}/lists/${props.listId}/subscriptions/${this.options.userId}`,\n options: this.options,\n method: 'DELETE',\n headers: {\n Authorization: `Bearer ${this.options.accessToken}`,\n },\n });\n }\n\n}\n","import { CourierTrackingEvent } from '../types/tracking-event';\nimport { http } from '../utils/request';\nimport { Client } from './client';\n\nexport class TrackingClient extends Client {\n\n /**\n * Post an inbound courier event\n * @param event - The event type: Example: \"New Order Placed\"\n * @param messageId - The message ID\n * @param type - The type of event: Available options: \"track\"\n * @param properties - The properties of the event\n * @returns Promise resolving to the message ID\n * @see https://www.courier.com/docs/reference/inbound/courier-track-event\n */\n public async postInboundCourier(props: {\n event: string;\n messageId: string;\n type: 'track';\n properties?: Record<string, any>;\n }): Promise<{ messageId: string }> {\n return await http({\n url: `${this.options.apiUrls.courier.rest}/inbound/courier`,\n options: this.options,\n method: 'POST',\n headers: {\n Authorization: `Bearer ${this.options.accessToken}`,\n },\n body: {\n ...props,\n userId: this.options.userId\n },\n validCodes: [200, 202]\n });\n }\n\n /**\n * Post a tracking URL event\n * These urls are found in messages sent from Courier\n * @param url - The URL to post the event to\n * @param event - The event type: Available options: \"click\", \"open\", \"unsubscribe\"\n * @returns Promise resolving when the event is posted\n */\n public async postTrackingUrl(props: {\n url: string;\n event: CourierTrackingEvent;\n }): Promise<void> {\n return await http({\n url: props.url,\n options: this.options,\n method: 'POST',\n body: {\n event: props.event\n }\n });\n }\n\n}\n","import { CourierApiUrls, getCourierApiUrls } from '../types/courier-api-urls';\nimport { Logger } from '../utils/logger';\nimport { BrandClient } from './brand-client';\nimport { InboxClient } from './inbox-client';\nimport { PreferenceClient } from './preference-client';\nimport { TokenClient } from './token-client';\nimport { Client } from './client';\nimport { ListClient } from './list-client';\nimport { TrackingClient } from './tracking-client';\n\nexport interface CourierProps {\n jwt?: string; // JWT token for authentication: More info at https://www.courier.com/docs/reference/auth/issue-token\n publicApiKey?: string; // Public API key for authentication\n userId: string; // User ID for the client. This is normally an ID that matches users in your system\n connectionId?: string; // Inbox Websocket connection ID\n tenantId?: string; // Tenant ID. Used for multi-tenant apps\n showLogs?: boolean; // Flag to control logging. Logs are prefixed with [COURIER].\n apiUrls?: CourierApiUrls; // Custom API URLs\n}\n\nexport interface CourierClientOptions {\n readonly jwt?: string; // JWT token for authentication: More info at https://www.courier.com/docs/reference/auth/issue-token\n readonly publicApiKey?: string; // Public API key for authentication\n readonly userId: string; // User ID for the client. This is normally an ID that matches users in your system\n readonly connectionId?: string; // Inbox Websocket connection ID\n readonly tenantId?: string; // Tenant ID. Used for multi-tenant apps\n readonly showLogs?: boolean; // Flag to control logging. Logs are prefixed with [COURIER].\n readonly accessToken?: string; // Combined authentication token (jwt or publicApiKey)\n readonly logger: Logger; // Logger instance\n readonly apiUrls: CourierApiUrls; // Final API URLs configuration\n}\n\nexport class CourierClient extends Client {\n public readonly tokens: TokenClient;\n public readonly brands: BrandClient;\n public readonly preferences: PreferenceClient;\n public readonly inbox: InboxClient;\n public readonly lists: ListClient;\n public readonly tracking: TrackingClient;\n\n constructor(props: CourierProps) {\n\n // Determine if we should show logs based on props or environment\n const showLogs = props.showLogs !== undefined ? props.showLogs : process.env.NODE_ENV === 'development';\n\n // Setup base options with default values\n const baseOptions = {\n ...props,\n showLogs,\n apiUrls: props.apiUrls || getCourierApiUrls(),\n accessToken: props.jwt ?? props.publicApiKey\n };\n\n // Initialize base client with logger and URLs\n super({\n ...baseOptions,\n logger: new Logger(baseOptions.showLogs),\n apiUrls: getCourierApiUrls(baseOptions.apiUrls)\n });\n\n // Initialize all subclients with the configured options\n this.tokens = new TokenClient(this.options);\n this.brands = new BrandClient(this.options);\n this.preferences = new PreferenceClient(this.options);\n this.inbox = new InboxClient(this.options);\n this.lists = new ListClient(this.options);\n this.tracking = new TrackingClient(this.options);\n\n // Warn if no authentication method is provided\n if (!this.options.jwt && !this.options.publicApiKey) {\n this.options.logger.warn('Courier Client initialized with no authentication method. Please provide a JWT or public API key.');\n }\n\n // Warn about using public API key in production\n if (this.options.publicApiKey) {\n this.options.logger?.warn(\n 'Courier Warning: Public API Keys are for testing only. Please use JWTs for production.\\n' +\n 'You can generate a JWT with this endpoint: https://www.courier.com/docs/reference/auth/issue-token\\n' +\n 'This endpoint should be called from your backend server, not the SDK.'\n );\n }\n\n // Warn if both authentication methods are provided\n if (this.options.jwt && this.options.publicApiKey) {\n this.options.logger?.warn(\n 'Courier Warning: Both a JWT and a Public API Key were provided. The Public API Key will be ignored.'\n );\n }\n\n }\n\n}\n","import { Courier } from \"./courier\";\n\nexport class AuthenticationListener {\n readonly callback: (props: { userId?: string }) => void;\n\n constructor(callback: (props: { userId?: string }) => void) {\n this.callback = callback;\n }\n\n public remove(): void {\n Courier.shared.removeAuthenticationListener(this);\n }\n\n}","import { CourierClient, CourierProps } from \"../client/courier-client\";\nimport { AuthenticationListener } from '../shared/authentication-listener';\nimport { UUID } from \"../utils/uuid\";\n\n/**\n * Courier is a singleton class that manages a shared Courier client instance and other resources.\n * UI components will automatically syncronize with this instance.\n * If you only need to call the Courier api, you should consider using the CourierClient directly.\n */\nexport class Courier {\n\n /**\n * The unique identifier for the Courier instance\n */\n public readonly id = UUID.generate();\n\n /**\n * The shared Courier instance\n */\n private static instance: Courier;\n\n /**\n * The Courier client instance\n */\n private instanceClient?: CourierClient;\n\n /**\n * The pagination limit (min: 1, max: 100)\n */\n private _paginationLimit = 24;\n\n public get paginationLimit(): number {\n return this._paginationLimit;\n }\n\n public set paginationLimit(value: number) {\n this._paginationLimit = Math.min(Math.max(value, 1), 100);\n }\n\n /**\n * Get the Courier client instance\n * @returns The Courier client instance or undefined if not signed in\n */\n public get client(): CourierClient | undefined {\n return this.instanceClient;\n }\n\n /**\n * The authentication listeners\n */\n private authenticationListeners: AuthenticationListener[] = [];\n\n /**\n * Get the shared Courier instance\n * @returns The shared Courier instance\n */\n public static get shared(): Courier {\n if (!Courier.instance) {\n Courier.instance = new Courier();\n }\n return Courier.instance;\n }\n\n /**\n * Sign in to Courier\n * @param options - The options for the Courier client\n */\n public signIn(props: CourierProps) {\n const connectionId = props.connectionId ?? UUID.generate();\n this.instanceClient = new CourierClient({ ...props, connectionId });\n this.notifyAuthenticationListeners({ userId: props.userId });\n }\n\n /**\n * Sign out of Courier\n */\n public signOut() {\n this.instanceClient = undefined;\n this.notifyAuthenticationListeners({ userId: undefined });\n }\n\n /**\n * Register a callback to be notified of authentication state changes\n * @param callback - Function to be called when authentication state changes\n * @returns AuthenticationListener instance that can be used to remove the listener\n */\n public addAuthenticationListener(callback: (props: { userId?: string }) => void): AuthenticationListener {\n this.instanceClient?.options.logger.info('Adding authentication listener');\n const listener = new AuthenticationListener(callback);\n this.authenticationListeners.push(listener);\n return listener;\n }\n\n /**\n * Unregister an authentication state change listener\n * @param listener - The AuthenticationListener instance to remove\n */\n public removeAuthenticationListener(listener: AuthenticationListener) {\n this.instanceClient?.options.logger.info('Removing authentication listener');\n this.authenticationListeners = this.authenticationListeners.filter(l => l !== listener);\n }\n\n /**\n * Notify all authentication listeners\n * @param props - The props to notify the listeners with\n */\n private notifyAuthenticationListeners(props: { userId?: string }) {\n this.authenticationListeners.forEach(listener => listener.callback(props));\n }\n\n}\n"],"names":["_CourierSocket","constructor","url","options","__publicField","this","isConnected","webSocket","connect","disconnect","Promise","resolve","reject","WebSocket","onopen","_a","onOpen","call","onmessage","event","onMessageReceived","data","onclose","onClose","code","reason","onerror","error","Error","originalEvent","onError","stopPing","close","NORMAL_CLOSURE_STATUS","send","message","json","JSON","stringify","keepAlive","props","pingInterval","setInterval","async","action","logger","intervalInMillis","clearInterval","CourierSocket","getCourierApiUrls","urls","courier","rest","graphql","inbox","Logger","showLogs","warn","args","console","PREFIX","log","debug","info","UUID","generate","prefix","id","Math","random","toString","substring","CourierRequestError","type","super","name","logRequest","uid","method","query","variables","headers","body","logResponse","status","response","http","validCodes","request","Request","Object","fromEntries","entries","fetch","includes","ok","Client","BrandClient","getBrand","brandId","apiUrls","userId","Authorization","accessToken","brand","InboxSocket","buildUrl","convertToType","parse","messageEvent","receivedMessageEvent","_b","receivedMessage","_c","_d","sendSubscribe","subscription","userAgent","channel","version","connectionId","clientSourceId","tenantId","accountId","InboxClient","socket","getMessages","paginationLimit","startCursor","getArchivedMessages","getUnreadMessageCount","count","click","messageId","trackingId","read","unread","readAll","open","archive","unarchive","archiveRead","archiveAll","PreferenceTransformer","transformItem","item","topicId","topic_id","topicName","topic_name","sectionId","section_id","sectionName","section_name","defaultStatus","default_status","hasCustomRouting","has_custom_routing","customRouting","custom_routing","transform","items","PreferenceClient","arguments","getUserPreferences","paginationCursor","transformer","paging","getUserPreferenceTopic","res","topic","putUserPreferenceTopic","payload","getNotificationCenterUrl","key","bytes","Uint8Array","length","i","charCodeAt","btoa","String","fromCharCode","encode","clientKey","binaryString","atob","decode","TokenClient","putUserToken","provider_key","provider","device","app_id","appId","ad_id","adId","device_id","deviceId","platform","manufacturer","model","token","deleteUserToken","ListClient","putSubscription","listId","deleteSubscription","TrackingClient","postInboundCourier","postTrackingUrl","CourierClient","process","env","NODE_ENV","baseOptions","jwt","publicApiKey","tokens","brands","preferences","lists","tracking","AuthenticationListener","callback","remove","Courier","shared","removeAuthenticationListener","_Courier","_paginationLimit","value","min","max","client","instanceClient","instance","signIn","notifyAuthenticationListeners","signOut","addAuthenticationListener","listener","authenticationListeners","push","filter","l","forEach"],"mappings":"2YAEa,MAAAA,EAAN,MAAMA,EAmBX,WAAAC,CAAYC,EAAaC,GAbaC,EAAAC,KAAA,YAAA,MACQD,EAAAC,KAAA,eAAA,MAGvCD,EAAAC,KAAA,UACAD,EAAAC,KAAA,qBACAD,EAAAC,KAAA,WACAD,EAAAC,KAAA,WAGUD,EAAAC,KAAA,OACRD,EAAAC,KAAA,WAGPA,KAAKH,IAAMA,EACXG,KAAKF,QAAUA,CAAA,CAMjB,eAAWG,GACT,OAA0B,OAAnBD,KAAKE,SAAc,CAG5B,aAAaC,GAIX,OAFAH,KAAKI,aAEE,IAAIC,SAAQ,CAACC,EAASC,KACvB,IACFP,KAAKE,UAAY,IAAIM,UAAUR,KAAKH,KAE/BG,KAAAE,UAAUO,OAAS,WACtB,OAAAC,EAAAV,KAAKW,SAALD,EAAAE,KAAAZ,MACQM,GAAA,EAGLN,KAAAE,UAAUW,UAAaC,UACrB,OAAAJ,EAAAV,KAAAe,gCAAoBD,EAAME,KAAA,EAG5BhB,KAAAE,UAAUe,QAAWH,UACxBd,KAAKE,UAAY,KACjB,OAAAQ,EAAAV,KAAKkB,UAALR,EAAAE,KAAAZ,KAAec,EAAMK,KAAML,EAAMM,OAAA,EAG9BpB,KAAAE,UAAUmB,QAAWP,UACxBd,KAAKE,UAAY,KACX,MAAAoB,EAAQ,IAAIC,MAAM,oCACvBD,EAAcE,cAAgBV,EAC/B,OAAAJ,EAAAV,KAAKyB,UAAUf,EAAAE,KAAAZ,KAAAsB,GACff,EAAOe,EAAK,QAGPA,GACPtB,KAAKE,UAAY,KACjBK,EAAOe,EAAK,IAEf,CAGI,UAAAlB,GACLJ,KAAK0B,WACD1B,KAAKE,YACFF,KAAAE,UAAUyB,MAAMhC,EAAciC,uBACnC5B,KAAKE,UAAY,KACnB,CAGF,UAAa2B,CAAKC,GACZ,IAAC9B,KAAKE,UACD,OAAA,EAGH,MAAA6B,EAAOC,KAAKC,UAAUH,GAC5B,YAAqC,IAA9B9B,KAAKE,UAAU2B,KAAKE,EAAU,CAGhC,SAAAG,CAAUC,GAGfnC,KAAK0B,WACA1B,KAAAoC,aAAeC,aAAYC,gBAC1B,UACItC,KAAK6B,KAAK,CAAEU,OAAQ,oBACnBjB,GACP,OAAAZ,EAAAV,KAAKF,QAAQ0C,SAAQ9B,EAAAY,MAAM,gCAAiCA,EAAK,KAE3D,MAAPa,OAAO,EAAAA,EAAAM,mBAAoB,IAAO,CAG/B,QAAAf,GACF1B,KAAKoC,eACPM,cAAc1C,KAAKoC,cACnBpC,KAAKoC,aAAe,KACtB,GAnGFrC,EAHWJ,EAGa,wBAAwB,KAH3C,IAAMgD,EAANhD,ECSM,MAAAiD,EAAqBC,IAA2C,CAC3EC,QAAS,CACPC,MAAY,MAANF,OAAM,EAAAA,EAAAC,QAAQC,OAAQ,0BAC5BC,SAAe,MAANH,OAAM,EAAAA,EAAAC,QAAQE,UAAW,oCAEpCC,MAAO,CACLD,SAAe,MAANH,OAAM,EAAAA,EAAAI,MAAMD,UAAW,8BAChC9C,WAAiB,MAAN2C,OAAM,EAAAA,EAAAI,MAAM/C,YAAa,+BClBjC,MAAMgD,EAIX,WAAAtD,CAA6BuD,GAFHpD,EAAAC,KAAA,SAAA,aAEGA,KAAAmD,SAAAA,CAAA,CAEtB,IAAAC,CAAKtB,KAAoBuB,GAC1BrD,KAAKmD,UACCG,QAAAF,KAAK,GAAGpD,KAAKuD,UAAUzB,OAAcuB,EAC/C,CAGK,GAAAG,CAAI1B,KAAoBuB,GACzBrD,KAAKmD,UACCG,QAAAE,IAAI,GAAGxD,KAAKuD,UAAUzB,OAAcuB,EAC9C,CAGK,KAAA/B,CAAMQ,KAAoBuB,GAC3BrD,KAAKmD,UACCG,QAAAhC,MAAM,GAAGtB,KAAKuD,UAAUzB,OAAcuB,EAChD,CAGK,KAAAI,CAAM3B,KAAoBuB,GAC3BrD,KAAKmD,UACCG,QAAAG,MAAM,GAAGzD,KAAKuD,UAAUzB,OAAcuB,EAChD,CAGK,IAAAK,CAAK5B,KAAoBuB,GAC1BrD,KAAKmD,UACCG,QAAAI,KAAK,GAAG1D,KAAKuD,UAAUzB,OAAcuB,EAC/C,ECjCG,MAAMM,EAEX,eAAOC,CAASC,GACd,MAAMC,EAAKC,KAAKC,SAASC,SAAS,IAAIC,UAAU,EAAG,IAAMH,KAAKC,SAASC,SAAS,IAAIC,UAAU,EAAG,IAC1F,OAAAL,EAASA,EAASC,EAAKA,CAAA,ECA3B,MAAMK,UAA4B5C,MACvC,WAAA3B,CACSuB,EACPW,EACOsC,GAEPC,MAAMvC,GAJC9B,KAAAmB,KAAAA,EAEAnB,KAAAoE,KAAAA,EAGPpE,KAAKsE,KAAO,qBAAA,EAIhB,SAASC,EAAW/B,EAAgBgC,EAAaJ,EAA0BpD,GAQzEwB,EAAOgB,IAAI,oBACIY,cAAiBI,WAC3BxD,EAAKnB,QACVmB,EAAKyD,OAAS,WAAWzD,EAAKyD,SAAW,OACzCzD,EAAK0D,MAAQ,UAAU1D,EAAK0D,QAAU,OACtC1D,EAAK2D,UAAY,cAAc3C,KAAKC,UAAUjB,EAAK2D,UAAW,KAAM,KAAO,gBAClE3C,KAAKC,UAAUjB,EAAK4D,QAAS,KAAM,aACtC5D,EAAK6D,KAAO7C,KAAKC,UAAUjB,EAAK6D,KAAM,KAAM,GAAK,cAEzD,CAEA,SAASC,EAAYtC,EAAgBgC,EAAaJ,EAA0BpD,GAI1EwB,EAAOgB,IAAI,oBACIY,eAAkBI,mBACpBxD,EAAK+D,0BACH/C,KAAKC,UAAUjB,EAAKgE,SAAU,KAAM,SAErD,CAEA1C,eAAsB2C,EAAK9C,GAQzB,MAAM+C,EAAa/C,EAAM+C,YAAc,CAAC,KAClCV,EAAMrC,EAAMrC,QAAQqD,SAAWQ,EAAKC,gBAAa,EAGjDuB,EAAU,IAAIC,QAAQjD,EAAMtC,IAAK,CACrC4E,OAAQtC,EAAMsC,OACdG,QAAS,CACP,eAAgB,sBACbzC,EAAMyC,SAEXC,KAAM1C,EAAM0C,KAAO7C,KAAKC,UAAUE,EAAM0C,WAAQ,IAI9CL,GACFD,EAAWpC,EAAMrC,QAAQ0C,OAAQgC,EAAK,OAAQ,CAC5C3E,IAAKsF,EAAQtF,IACb4E,OAAQU,EAAQV,OAChBG,QAASS,OAAOC,YAAYH,EAAQP,QAAQW,WAC5CV,KAAM1C,EAAM0C,OAKV,MAAAG,QAAiBQ,MAAML,GAGzB,GAAoB,MAApBH,EAASD,OACX,OAIE,IAAA/D,EACA,IACKA,QAAMgE,EAASjD,aACfT,GAGH,GAAoB,MAApB0D,EAASD,OACX,OAGF,MAAM,IAAIZ,EACRa,EAASD,OACT,mCACA,cACF,CAYF,GARIP,GACFM,EAAY3C,EAAMrC,QAAQ0C,OAAQgC,EAAK,OAAQ,CAC7CO,OAAQC,EAASD,OACjBC,SAAUhE,KAKTkE,EAAWO,SAAST,EAASD,QAChC,MAAM,IAAIZ,EACRa,EAASD,cACT/D,WAAMc,UAAW,gBACX,MAANd,OAAM,EAAAA,EAAAoD,MAIH,OAAApD,CACT,CAEAsB,eAAsBU,EAAQb,GAO5B,MAAMqC,EAAMrC,EAAMrC,QAAQqD,SAAWQ,EAAKC,gBAAa,EAGnDY,GACFD,EAAWpC,EAAMrC,QAAQ0C,OAAQgC,EAAK,UAAW,CAC/C3E,IAAKsC,EAAMtC,IACX+E,QAASzC,EAAMyC,QACfF,MAAOvC,EAAMuC,MACbC,UAAWxC,EAAMwC,YAIrB,MAAMK,QAAiBQ,MAAMrD,EAAMtC,IAAK,CACtC4E,OAAQ,OACRG,QAAS,CACP,eAAgB,sBACbzC,EAAMyC,SAEXC,KAAM7C,KAAKC,UAAU,CACnByC,MAAOvC,EAAMuC,MACbC,UAAWxC,EAAMwC,cAKjB,IAAA3D,EACA,IACKA,QAAMgE,EAASjD,aACfT,GACP,MAAM,IAAI6C,EACRa,EAASD,OACT,mCACA,cACF,CAWE,GAPAP,GACFM,EAAY3C,EAAMrC,QAAQ0C,OAAQgC,EAAK,UAAW,CAChDO,OAAQC,EAASD,OACjBC,SAAUhE,KAITgE,EAASU,GACZ,MAAM,IAAIvB,EACRa,EAASD,cACT/D,WAAMc,UAAW,gBACX,MAANd,OAAM,EAAAA,EAAAoD,MAIH,OAAApD,CACT,CCpLO,MAAM2E,EAEX,WAAA/F,CAA4BE,GAAAE,KAAAF,QAAAA,CAAA,ECAvB,MAAM8F,UAAoBD,EAO/B,cAAaE,CAAS1D,GACpB,MAAMuC,EAAQ,qDAEQvC,EAAM2D,4RA4B5B,aAZmB9C,EAAQ,CACzBlD,QAASE,KAAKF,QACdD,IAAKG,KAAKF,QAAQiG,QAAQjD,QAAQE,QAClC4B,QAAS,CACP,oBAAqB5E,KAAKF,QAAQkG,OAClC,uBAAwB,QACxBC,cAAiB,UAAUjG,KAAKF,QAAQoG,eAE1CxB,QACAC,UAAW,CAAEmB,QAAS3D,EAAM2D,YAGlB9E,KAAKmF,KAAA,ECjBd,MAAMC,UAAoBzD,EAK/B,WAAA/C,CAAYE,GAEVuE,MADY+B,EAAYC,SAASvG,GACtBA,GALNC,EAAAC,KAAA,mBACAD,EAAAC,KAAA,wBAKLA,KAAKe,kBAAqBC,GAAShB,KAAKsG,cAActF,EAAI,CAGpD,aAAAsF,CAActF,eAChB,IAGF,OAFgBgB,KAAKuE,MAAMvF,GAEXoD,MACd,IAAK,QACG,MAAAoC,EAAexE,KAAKuE,MAAMvF,GAChC,OAAAN,EAAAV,KAAKyG,uBAAuB/F,EAAAE,KAAAZ,KAAAwG,GAC5B,MAEF,IAAK,UACG,MAAA1E,EAAUE,KAAKuE,MAAMvF,GAC3B,OAAA0F,EAAA1G,KAAK2G,kBAAkBD,EAAA9F,KAAAZ,KAAA8B,UAGpBR,GACP,OAAAsF,EAAA5G,KAAKF,QAAQ0C,SAAQoE,EAAAtF,MAAM,+BAAgCA,GACvDA,aAAiBC,QACnB,OAAAsF,EAAA7G,KAAKyB,UAAUoF,EAAAjG,KAAAZ,KAAAsB,GACjB,CACF,CAGF,mBAAawF,CAAc3E,SAGzB,MAAM4E,EAAoC,CACxCxE,OAAQ,YACRvB,KAAM,CACJgG,UAAW,aACXC,QAASjH,KAAKF,QAAQkG,OACtBlF,MAAO,IACPoG,eAAS/E,WAAO+E,UAAW,IAK3BlH,KAAKF,QAAQqH,eACFJ,EAAA/F,KAAKoG,eAAiBpH,KAAKF,QAAQqH,cAE9CnH,KAAKF,QAAQuH,WACFN,EAAA/F,KAAKsG,UAAYtH,KAAKF,QAAQuH,UAG7C,OAAA3G,EAAAV,KAAKF,QAAQ0C,SAAQ9B,EAAA+C,MAAM,4BAA6BsD,SAElD/G,KAAK6B,KAAKkF,EAAY,CAG9B,eAAeV,CAASvG,SACtB,IAAID,GAAM,OAAAa,EAAAZ,EAAQiG,cAAR,EAAArF,EAAiBuC,MAAM/C,YAAa,GAMvC,OAJHJ,EAAQoG,cACHrG,GAAA,UAAUC,EAAQoG,eAGpBrG,CAAA,ECtFJ,MAAM0H,UAAoB5B,EAI/B,WAAA/F,CAAYE,GACVuE,MAAMvE,GAHCC,EAAAC,KAAA,UAIFA,KAAAwH,OAAS,IAAIpB,EAAYtG,EAAO,CASvC,iBAAa2H,CAAYtF,GAIvB,MAAMuC,EAAQ,2EAEuB1E,KAAKF,QAAQuH,SAAW,eAAerH,KAAKF,QAAQuH,YAAc,gCACnF,MAAAlF,OAAA,EAAAA,EAAOuF,kBAAmB,qCACzBvF,WAAOwF,aAAc,MAAMxF,EAAMwF,eAAiB,0nBAgCvE,aAAa3E,EAAQ,CACnBlD,QAASE,KAAKF,QACd4E,QACAE,QAAS,CACP,oBAAqB5E,KAAKF,QAAQkG,OAClCC,cAAiB,UAAUjG,KAAKF,QAAQoG,eAE1CrG,IAAKG,KAAKF,QAAQiG,QAAQ9C,MAAMD,SACjC,CASH,yBAAa4E,CAAoBzF,GAI/B,MAAMuC,EAAQ,2EAEuB1E,KAAKF,QAAQuH,SAAW,eAAerH,KAAKF,QAAQuH,YAAc,gDACnF,MAAAlF,OAAA,EAAAA,EAAOuF,kBAAmB,qCACzBvF,WAAOwF,aAAc,MAAMxF,EAAMwF,eAAiB,0nBAgCvE,OAAO3E,EAAQ,CACblD,QAASE,KAAKF,QACd4E,QACAE,QAAS,CACP,oBAAqB5E,KAAKF,QAAQkG,OAClCC,cAAiB,UAAUjG,KAAKF,QAAQoG,eAE1CrG,IAAKG,KAAKF,QAAQiG,QAAQ9C,MAAMD,SACjC,CAOH,2BAAa6E,SACX,MAAMnD,EAAQ,yEAEyB1E,KAAKF,QAAQuH,SAAW,iBAAiBrH,KAAKF,QAAQuH,YAAc,uBAcpG,OAAA,OAAA3G,SAVgBsC,EAAQ,CAC7BlD,QAASE,KAAKF,QACd4E,QACAE,QAAS,CACP,oBAAqB5E,KAAKF,QAAQkG,OAClCC,cAAiB,UAAUjG,KAAKF,QAAQoG,eAE1CrG,IAAKG,KAAKF,QAAQiG,QAAQ9C,MAAMD,WAGlBhC,WAAT,EAAAN,EAAeoH,QAAS,CAAA,CASjC,WAAaC,CAAM5F,GACjB,MAAMuC,EAAQ,8DAEYvC,EAAM6F,4BAA4B7F,EAAM8F,8BAI5DrD,EAAkC,CACtC,oBAAqB5E,KAAKF,QAAQkG,OAClCC,cAAiB,UAAUjG,KAAKF,QAAQoG,eAGtClG,KAAKF,QAAQqH,eACPvC,EAAA,8BAAgC5E,KAAKF,QAAQqH,oBAGjDnE,EAAQ,CACZlD,QAASE,KAAKF,QACd4E,QACAE,UACA/E,IAAKG,KAAKF,QAAQiG,QAAQ9C,MAAMD,SACjC,CAQH,UAAakF,CAAK/F,GAChB,MAAMuC,EAAQ,2DAESvC,EAAM6F,6BAIvBpD,EAAkC,CACtC,oBAAqB5E,KAAKF,QAAQkG,OAClCC,cAAiB,UAAUjG,KAAKF,QAAQoG,eAGtClG,KAAKF,QAAQqH,eACPvC,EAAA,8BAAgC5E,KAAKF,QAAQqH,oBAGjDnE,EAAQ,CACZlD,QAASE,KAAKF,QACd4E,QACAE,UACA/E,IAAKG,KAAKF,QAAQiG,QAAQ9C,MAAMD,SACjC,CAQH,YAAamF,CAAOhG,GAClB,MAAMuC,EAAQ,6DAEWvC,EAAM6F,6BAIzBpD,EAAkC,CACtC,oBAAqB5E,KAAKF,QAAQkG,OAClCC,cAAiB,UAAUjG,KAAKF,QAAQoG,eAGtClG,KAAKF,QAAQqH,eACPvC,EAAA,8BAAgC5E,KAAKF,QAAQqH,oBAGjDnE,EAAQ,CACZlD,QAASE,KAAKF,QACd4E,QACAE,UACA/E,IAAKG,KAAKF,QAAQiG,QAAQ9C,MAAMD,SACjC,CAOH,aAAaoF,GACX,MAMMxD,EAAkC,CACtC,oBAAqB5E,KAAKF,QAAQkG,OAClCC,cAAiB,UAAUjG,KAAKF,QAAQoG,eAGtClG,KAAKF,QAAQqH,eACPvC,EAAA,8BAAgC5E,KAAKF,QAAQqH,oBAGjDnE,EAAQ,CACZlD,QAASE,KAAKF,QACd4E,MAjBY,oEAkBZE,UACA/E,IAAKG,KAAKF,QAAQiG,QAAQ9C,MAAMD,SACjC,CAQH,UAAaqF,CAAKlG,GAChB,MAAMuC,EAAQ,6DAEWvC,EAAM6F,6BAIzBpD,EAAkC,CACtC,oBAAqB5E,KAAKF,QAAQkG,OAClCC,cAAiB,UAAUjG,KAAKF,QAAQoG,eAGtClG,KAAKF,QAAQqH,eACPvC,EAAA,8BAAgC5E,KAAKF,QAAQqH,oBAGjDnE,EAAQ,CACZlD,QAASE,KAAKF,QACd4E,QACAE,UACA/E,IAAKG,KAAKF,QAAQiG,QAAQ9C,MAAMD,SACjC,CAQH,aAAasF,CAAQnG,GACnB,MAAMuC,EAAQ,8DAEYvC,EAAM6F,6BAI1BpD,EAAkC,CACtC,oBAAqB5E,KAAKF,QAAQkG,OAClCC,cAAiB,UAAUjG,KAAKF,QAAQoG,eAGtClG,KAAKF,QAAQqH,eACPvC,EAAA,8BAAgC5E,KAAKF,QAAQqH,oBAGjDnE,EAAQ,CACZlD,QAASE,KAAKF,QACd4E,QACAE,UACA/E,IAAKG,KAAKF,QAAQiG,QAAQ9C,MAAMD,SACjC,CAQH,eAAauF,CAAUpG,GACrB,MAAMuC,EAAQ,gEAEcvC,EAAM6F,6BAI5BpD,EAAkC,CACtC,oBAAqB5E,KAAKF,QAAQkG,OAClCC,cAAiB,UAAUjG,KAAKF,QAAQoG,eAGtClG,KAAKF,QAAQqH,eACPvC,EAAA,8BAAgC5E,KAAKF,QAAQqH,oBAGjDnE,EAAQ,CACZlD,QAASE,KAAKF,QACd4E,QACAE,UACA/E,IAAKG,KAAKF,QAAQiG,QAAQ9C,MAAMD,SACjC,CAMH,iBAAawF,GACX,MAMM5D,EAAkC,CACtC,oBAAqB5E,KAAKF,QAAQkG,OAClCC,cAAiB,UAAUjG,KAAKF,QAAQoG,eAGtClG,KAAKF,QAAQqH,eACPvC,EAAA,8BAAgC5E,KAAKF,QAAQqH,oBAGjDnE,EAAQ,CACZlD,QAASE,KAAKF,QACd4E,MAjBY,oEAkBZE,UACA/E,IAAKG,KAAKF,QAAQiG,QAAQ9C,MAAMD,SACjC,CAMH,gBAAayF,GACX,MAMM7D,EAAkC,CACtC,oBAAqB5E,KAAKF,QAAQkG,OAClCC,cAAiB,UAAUjG,KAAKF,QAAQoG,eAGtClG,KAAKF,QAAQqH,eACPvC,EAAA,8BAAgC5E,KAAKF,QAAQqH,oBAGjDnE,EAAQ,CACZlD,QAASE,KAAKF,QACd4E,MAjBY,mEAkBZE,UACA/E,IAAKG,KAAKF,QAAQiG,QAAQ9C,MAAMD,SACjC,EC1XE,MAAM0F,EAMX,aAAAC,CAAcC,GACL,MAAA,CACLC,QAASD,EAAKE,SACdC,UAAWH,EAAKI,WAChBC,UAAWL,EAAKM,WAChBC,YAAaP,EAAKQ,aAClBrE,OAAQ6D,EAAK7D,OACbsE,cAAeT,EAAKU,eACpBC,iBAAkBX,EAAKY,mBACvBC,cAAeb,EAAKc,gBAAkB,GACxC,CAQF,UAACC,CAAUC,GACT,IAAA,MAAWhB,KAAQgB,QACX5J,KAAK2I,cAAcC,EAC3B,ECnDG,MAAMiB,UAAyBlE,EAA/B,WAAA/F,GAAAyE,SAAAyF,WACG/J,EAAAC,KAAA,cAAc,IAAI0I,EAAsB,CAQhD,wBAAaqB,CAAmB5H,GAG1B,IAAAtC,EAAM,GAAGG,KAAKF,QAAQiG,QAAQjD,QAAQC,cAAc/C,KAAKF,QAAQkG,4BAEjE7D,WAAO6H,oBACFnK,GAAA,WAAWsC,EAAM6H,oBAGpB,MASAhJ,QATaiE,EAAK,CACtBnF,QAASE,KAAKF,QACdD,MACA4E,OAAQ,MACRG,QAAS,CACPqB,cAAiB,UAAUjG,KAAKF,QAAQoG,iBAMrC,MAAA,CACL0D,MAAO,IAAI5J,KAAKiK,YAAYN,UAAU3I,EAAK4I,QAC3CM,OAAQlJ,EAAKkJ,OACf,CASF,4BAAaC,CAAuBhI,GAI5B,MASAiI,QATanF,EAAK,CACtBnF,QAASE,KAAKF,QACdD,IAAK,GAAGG,KAAKF,QAAQiG,QAAQjD,QAAQC,cAAc/C,KAAKF,QAAQkG,sBAAsB7D,EAAM0G,UAC5FpE,OAAQ,MACRG,QAAS,CACPqB,cAAiB,UAAUjG,KAAKF,QAAQoG,iBAK5C,OAAOlG,KAAKiK,YAAYtB,cAAcyB,EAAIC,MAAK,CAYjD,4BAAaC,CAAuBnI,GAOlC,MAAMoI,EAAU,CACdF,MAAO,CACLtF,OAAQ5C,EAAM4C,OACdyE,mBAAoBrH,EAAMoH,iBAC1BG,eAAgBvH,EAAMsH,sBAIpBxE,EAAK,CACTnF,QAASE,KAAKF,QACdD,IAAK,GAAGG,KAAKF,QAAQiG,QAAQjD,QAAQC,cAAc/C,KAAKF,QAAQkG,sBAAsB7D,EAAM0G,UAC5FpE,OAAQ,MACRG,QAAS,CACPqB,cAAiB,UAAUjG,KAAKF,QAAQoG,eAE1CrB,KAAM0F,GACP,CAQI,wBAAAC,CAAyBrI,GAK9B,MAAO,yCCjGJ,SAAgBsI,GACrB,MAAMC,EAAQ,IAAIC,WAAWF,EAAIG,QAEjC,IAAA,IAASC,EAAI,EAAGA,EAAIJ,EAAIG,OAAQC,IAC9BH,EAAMG,GAAKJ,EAAIK,WAAWD,GAG5B,OAAOE,KAAKC,OAAOC,gBAAgBP,GACrC,CDwFgBQ,CAAO,GC3GhB,SAAgBC,GACf,MAAAC,EAAeC,KAAKF,GACpBT,EAAQ,IAAIC,WAAWS,EAAaR,QAE1C,IAAA,IAASC,EAAI,EAAGA,EAAIO,EAAaR,OAAQC,IACvCH,EAAMG,GAAKO,EAAaN,WAAWD,GAG9B,OAAAG,OAAOC,gBAAgBP,EAChC,CDiGyBY,CAAOnJ,EAAMgJ,cACInL,KAAKF,QAAQkG,SAAShG,KAAKF,QAAQuH,SAAW,IAAIrH,KAAKF,QAAQuH,WAAa,aAC/D,EExGhD,MAAMkE,UAAoB5F,EAS/B,kBAAa6F,CAAarJ,GAKxB,MAAMoI,EAAU,CACdkB,aAActJ,EAAMuJ,YAChBvJ,EAAMwJ,QAAU,CAClBA,OAAQ,CACNC,OAAQzJ,EAAMwJ,OAAOE,MACrBC,MAAO3J,EAAMwJ,OAAOI,KACpBC,UAAW7J,EAAMwJ,OAAOM,SACxBC,SAAU/J,EAAMwJ,OAAOO,SACvBC,aAAchK,EAAMwJ,OAAOQ,aAC3BC,MAAOjK,EAAMwJ,OAAOS,eAKpBnH,EAAK,CACTnF,QAASE,KAAKF,QACdD,IAAK,GAAGG,KAAKF,QAAQiG,QAAQjD,QAAQC,cAAc/C,KAAKF,QAAQkG,iBAAiB7D,EAAMkK,QACvF5H,OAAQ,MACRG,QAAS,CACPqB,cAAiB,UAAUjG,KAAKF,QAAQoG,eAE1CrB,KAAM0F,EACNrF,WAAY,CAAC,IAAK,MACnB,CAQH,qBAAaoH,CAAgBnK,SAGrB8C,EAAK,CACTnF,QAASE,KAAKF,QACdD,IAAK,GAAGG,KAAKF,QAAQiG,QAAQjD,QAAQC,cAAc/C,KAAKF,QAAQkG,iBAAiB7D,EAAMkK,QACvF5H,OAAQ,SACRG,QAAS,CACPqB,cAAiB,UAAUjG,KAAKF,QAAQoG,eAE1ChB,WAAY,CAAC,IAAK,MACnB,ECzDE,MAAMqH,UAAmB5G,EAQ9B,qBAAa6G,CAAgBrK,GAG3B,aAAa8C,EAAK,CAChBpF,IAAK,GAAGG,KAAKF,QAAQiG,QAAQjD,QAAQC,cAAcZ,EAAMsK,wBAAwBzM,KAAKF,QAAQkG,SAC9FlG,QAASE,KAAKF,QACd2E,OAAQ,MACRG,QAAS,CACPqB,cAAe,UAAUjG,KAAKF,QAAQoG,gBAEzC,CASH,wBAAawG,CAAmBvK,GAG9B,aAAa8C,EAAK,CAChBpF,IAAK,GAAGG,KAAKF,QAAQiG,QAAQjD,QAAQC,cAAcZ,EAAMsK,wBAAwBzM,KAAKF,QAAQkG,SAC9FlG,QAASE,KAAKF,QACd2E,OAAQ,SACRG,QAAS,CACPqB,cAAe,UAAUjG,KAAKF,QAAQoG,gBAEzC,ECpCE,MAAMyG,UAAuBhH,EAWlC,wBAAaiH,CAAmBzK,GAM9B,aAAa8C,EAAK,CAChBpF,IAAK,GAAGG,KAAKF,QAAQiG,QAAQjD,QAAQC,uBACrCjD,QAASE,KAAKF,QACd2E,OAAQ,OACRG,QAAS,CACPqB,cAAe,UAAUjG,KAAKF,QAAQoG,eAExCrB,KAAM,IACD1C,EACH6D,OAAQhG,KAAKF,QAAQkG,QAEvBd,WAAY,CAAC,IAAK,MACnB,CAUH,qBAAa2H,CAAgB1K,GAI3B,aAAa8C,EAAK,CAChBpF,IAAKsC,EAAMtC,IACXC,QAASE,KAAKF,QACd2E,OAAQ,OACRI,KAAM,CACJ/D,MAAOqB,EAAMrB,QAEhB,ECtBE,MAAMgM,UAAsBnH,EAQjC,WAAA/F,CAAYuC,WAGJ,MAAAgB,OAA8B,IAAnBhB,EAAMgB,SAAyBhB,EAAMgB,SAAoC,gBAAzB4J,QAAQC,IAAIC,SAGvEC,EAAc,IACf/K,EACHgB,WACA4C,QAAS5D,EAAM4D,SAAWnD,IAC1BsD,YAAa/D,EAAMgL,KAAOhL,EAAMiL,cAI5B/I,MAAA,IACD6I,EACH1K,OAAQ,IAAIU,EAAOgK,EAAY/J,UAC/B4C,QAASnD,EAAkBsK,EAAYnH,WAxB3BhG,EAAAC,KAAA,UACAD,EAAAC,KAAA,UACAD,EAAAC,KAAA,eACAD,EAAAC,KAAA,SACAD,EAAAC,KAAA,SACAD,EAAAC,KAAA,YAuBdA,KAAKqN,OAAS,IAAI9B,EAAYvL,KAAKF,SACnCE,KAAKsN,OAAS,IAAI1H,EAAY5F,KAAKF,SACnCE,KAAKuN,YAAc,IAAI1D,EAAiB7J,KAAKF,SAC7CE,KAAKiD,MAAQ,IAAIsE,EAAYvH,KAAKF,SAClCE,KAAKwN,MAAQ,IAAIjB,EAAWvM,KAAKF,SACjCE,KAAKyN,SAAW,IAAId,EAAe3M,KAAKF,SAGnCE,KAAKF,QAAQqN,KAAQnN,KAAKF,QAAQsN,cAChCpN,KAAAF,QAAQ0C,OAAOY,KAAK,qGAIvBpD,KAAKF,QAAQsN,eACf,OAAK1M,EAAAV,KAAAF,QAAQ0C,SAAQ9B,EAAA0C,KACnB,sQAOApD,KAAKF,QAAQqN,KAAOnN,KAAKF,QAAQsN,eACnC,OAAK1G,EAAA1G,KAAAF,QAAQ0C,SAAQkE,EAAAtD,KACnB,uGAEJ,ECrFG,MAAMsK,EAGX,WAAA9N,CAAY+N,GAFH5N,EAAAC,KAAA,YAGPA,KAAK2N,SAAWA,CAAA,CAGX,MAAAC,GACGC,EAAAC,OAAOC,6BAA6B/N,KAAI,ECDvC,MAAAgO,EAAN,MAAMA,EAAN,WAAApO,GAKWG,EAAAC,KAAA,KAAK2D,EAAKC,YAUlB7D,EAAAC,KAAA,kBAKmBD,EAAAC,KAAA,mBAAA,IAqBnBD,EAAAC,KAAA,0BAAoD,GAAC,CAnB7D,mBAAW0H,GACT,OAAO1H,KAAKiO,gBAAA,CAGd,mBAAWvG,CAAgBwG,GACpBlO,KAAAiO,iBAAmBlK,KAAKoK,IAAIpK,KAAKqK,IAAIF,EAAO,GAAI,IAAG,CAO1D,UAAWG,GACT,OAAOrO,KAAKsO,cAAA,CAYd,iBAAkBR,GAIhB,OAHKE,EAAQO,WACHP,EAAAO,SAAW,IAAIP,GAElBA,EAAQO,QAAA,CAOV,MAAAC,CAAOrM,GACZ,MAAMgF,EAAehF,EAAMgF,cAAgBxD,EAAKC,WAChD5D,KAAKsO,eAAiB,IAAIxB,EAAc,IAAK3K,EAAOgF,iBACpDnH,KAAKyO,8BAA8B,CAAEzI,OAAQ7D,EAAM6D,QAAQ,CAMtD,OAAA0I,GACL1O,KAAKsO,oBAAiB,EACtBtO,KAAKyO,8BAA8B,CAAEzI,YAAQ,GAAW,CAQnD,yBAAA2I,CAA0BhB,SAC/B,OAAAjN,EAAAV,KAAKsO,iBAAL5N,EAAqBZ,QAAQ0C,OAAOkB,KAAK,kCACnC,MAAAkL,EAAW,IAAIlB,EAAuBC,GAErC,OADF3N,KAAA6O,wBAAwBC,KAAKF,GAC3BA,CAAA,CAOF,4BAAAb,CAA6Ba,SAClC,OAAAlO,EAAAV,KAAKsO,iBAAL5N,EAAqBZ,QAAQ0C,OAAOkB,KAAK,oCACzC1D,KAAK6O,wBAA0B7O,KAAK6O,wBAAwBE,QAAOC,GAAKA,IAAMJ,GAAQ,CAOhF,6BAAAH,CAA8BtM,GACpCnC,KAAK6O,wBAAwBI,SAAQL,GAAYA,EAASjB,SAASxL,IAAM,GAxF3EpC,EAVWiO,EAUI,YAVV,IAAMH,EAANG"}
package/dist/index.mjs CHANGED
@@ -98,7 +98,7 @@ const getCourierApiUrls = (urls) => ({
98
98
  },
99
99
  inbox: {
100
100
  graphql: (urls == null ? void 0 : urls.inbox.graphql) || "https://inbox.courier.com/q",
101
- webSocket: (urls == null ? void 0 : urls.inbox.webSocket) || "wss://realtime.courier.com"
101
+ webSocket: (urls == null ? void 0 : urls.inbox.webSocket) || "wss://realtime.courier.io"
102
102
  }
103
103
  });
104
104
  class Logger {
@@ -646,6 +646,31 @@ class InboxClient extends Client {
646
646
  url: this.options.apiUrls.inbox.graphql
647
647
  });
648
648
  }
649
+ /**
650
+ * Unarchive a message
651
+ * @param messageId - ID of the message to unarchive
652
+ * @returns Promise resolving when message is unarchived
653
+ */
654
+ async unarchive(props) {
655
+ const query = `
656
+ mutation TrackEvent {
657
+ unarchive(messageId: "${props.messageId}")
658
+ }
659
+ `;
660
+ const headers = {
661
+ "x-courier-user-id": this.options.userId,
662
+ "Authorization": `Bearer ${this.options.accessToken}`
663
+ };
664
+ if (this.options.connectionId) {
665
+ headers["x-courier-client-source-id"] = this.options.connectionId;
666
+ }
667
+ await graphql({
668
+ options: this.options,
669
+ query,
670
+ headers,
671
+ url: this.options.apiUrls.inbox.graphql
672
+ });
673
+ }
649
674
  /**
650
675
  * Archive all read messages.
651
676
  */
@@ -669,6 +694,29 @@ class InboxClient extends Client {
669
694
  url: this.options.apiUrls.inbox.graphql
670
695
  });
671
696
  }
697
+ /**
698
+ * Archive all read messages.
699
+ */
700
+ async archiveAll() {
701
+ const query = `
702
+ mutation TrackEvent {
703
+ archiveAll
704
+ }
705
+ `;
706
+ const headers = {
707
+ "x-courier-user-id": this.options.userId,
708
+ "Authorization": `Bearer ${this.options.accessToken}`
709
+ };
710
+ if (this.options.connectionId) {
711
+ headers["x-courier-client-source-id"] = this.options.connectionId;
712
+ }
713
+ await graphql({
714
+ options: this.options,
715
+ query,
716
+ headers,
717
+ url: this.options.apiUrls.inbox.graphql
718
+ });
719
+ }
672
720
  }
673
721
  class PreferenceTransformer {
674
722
  /**
@@ -1080,3 +1128,4 @@ export {
1080
1128
  PreferenceClient,
1081
1129
  TokenClient
1082
1130
  };
1131
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","sources":["../src/socket/courier-socket.ts","../src/types/courier-api-urls.ts","../src/utils/logger.ts","../src/utils/uuid.ts","../src/utils/request.ts","../src/client/client.ts","../src/client/brand-client.ts","../src/socket/inbox-socket.ts","../src/client/inbox-client.ts","../src/types/preference.ts","../src/utils/coding.ts","../src/client/preference-client.ts","../src/client/token-client.ts","../src/client/list-client.ts","../src/client/tracking-client.ts","../src/client/courier-client.ts","../src/shared/authentication-listener.ts","../src/shared/courier.ts"],"sourcesContent":["import { CourierClientOptions } from \"../client/courier-client\";\n\nexport class CourierSocket {\n\n // Constants\n private static readonly NORMAL_CLOSURE_STATUS = 1000;\n\n // Properties\n private webSocket: WebSocket | null = null;\n private pingInterval: NodeJS.Timeout | null = null;\n\n // Callbacks\n public onOpen?: () => void;\n public onMessageReceived?: (message: string) => void;\n public onClose?: (code: number, reason?: string) => void;\n public onError?: (error: Error) => void;\n\n // Properties\n private readonly url: string;\n readonly options: CourierClientOptions;\n\n constructor(url: string, options: CourierClientOptions) {\n this.url = url;\n this.options = options;\n }\n\n /**\n * Dynamically checks if the WebSocket is connected\n */\n public get isConnected(): boolean {\n return this.webSocket !== null;\n }\n\n public async connect(): Promise<void> {\n // Disconnect if already connected\n this.disconnect();\n\n return new Promise((resolve, reject) => {\n try {\n this.webSocket = new WebSocket(this.url);\n\n this.webSocket.onopen = () => {\n this.onOpen?.();\n resolve();\n };\n\n this.webSocket.onmessage = (event) => {\n this.onMessageReceived?.(event.data);\n };\n\n this.webSocket.onclose = (event) => {\n this.webSocket = null;\n this.onClose?.(event.code, event.reason);\n };\n\n this.webSocket.onerror = (event) => {\n this.webSocket = null;\n const error = new Error('Courier Socket connection failed');\n (error as any).originalEvent = event;\n this.onError?.(error);\n reject(error);\n };\n\n } catch (error) {\n this.webSocket = null;\n reject(error);\n }\n });\n }\n\n public disconnect(): void {\n this.stopPing();\n if (this.webSocket) {\n this.webSocket.close(CourierSocket.NORMAL_CLOSURE_STATUS);\n this.webSocket = null;\n }\n }\n\n public async send(message: Record<string, any>): Promise<boolean> {\n if (!this.webSocket) {\n return false;\n }\n\n const json = JSON.stringify(message);\n return this.webSocket.send(json) !== undefined;\n }\n\n public keepAlive(props?: {\n intervalInMillis?: number;\n }): void {\n this.stopPing();\n this.pingInterval = setInterval(async () => {\n try {\n await this.send({ action: 'keepAlive' });\n } catch (error) {\n this.options.logger?.error('Error occurred on Keep Alive:', error);\n }\n }, props?.intervalInMillis ?? 300_000);\n }\n\n private stopPing(): void {\n if (this.pingInterval) {\n clearInterval(this.pingInterval);\n this.pingInterval = null;\n }\n }\n\n}\n","export interface CourierApiUrls {\n courier: {\n rest: string;\n graphql: string;\n },\n inbox: {\n graphql: string;\n webSocket: string;\n }\n}\n\nexport const getCourierApiUrls = (urls?: CourierApiUrls): CourierApiUrls => ({\n courier: {\n rest: urls?.courier.rest || 'https://api.courier.com',\n graphql: urls?.courier.graphql || 'https://api.courier.com/client/q',\n },\n inbox: {\n graphql: urls?.inbox.graphql || 'https://inbox.courier.com/q',\n webSocket: urls?.inbox.webSocket || 'wss://realtime.courier.io'\n }\n});","export class Logger {\n\n private readonly PREFIX = '[COURIER]';\n\n constructor(private readonly showLogs: boolean) { }\n\n public warn(message: string, ...args: any[]): void {\n if (this.showLogs) {\n console.warn(`${this.PREFIX} ${message}`, ...args);\n }\n }\n\n public log(message: string, ...args: any[]): void {\n if (this.showLogs) {\n console.log(`${this.PREFIX} ${message}`, ...args);\n }\n }\n\n public error(message: string, ...args: any[]): void {\n if (this.showLogs) {\n console.error(`${this.PREFIX} ${message}`, ...args);\n }\n }\n\n public debug(message: string, ...args: any[]): void {\n if (this.showLogs) {\n console.debug(`${this.PREFIX} ${message}`, ...args);\n }\n }\n\n public info(message: string, ...args: any[]): void {\n if (this.showLogs) {\n console.info(`${this.PREFIX} ${message}`, ...args);\n }\n }\n}\n","export class UUID {\n\n static generate(prefix?: string): string {\n const id = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);\n return prefix ? prefix + id : id;\n }\n\n}","import { CourierClientOptions } from \"../client/courier-client\";\nimport { Logger } from \"./logger\";\nimport { UUID } from \"./uuid\";\n\nexport class CourierRequestError extends Error {\n constructor(\n public code: number,\n message: string,\n public type?: string\n ) {\n super(message);\n this.name = 'CourierRequestError';\n }\n}\n\nfunction logRequest(logger: Logger, uid: string, type: 'HTTP' | 'GraphQL', data: {\n url: string;\n method?: string;\n headers: Record<string, string>;\n body?: any;\n query?: string;\n variables?: Record<string, any>;\n}) {\n logger.log(`\nšŸ“” New Courier ${type} Request: ${uid}\nURL: ${data.url}\n${data.method ? `Method: ${data.method}` : ''}\n${data.query ? `Query: ${data.query}` : ''}\n${data.variables ? `Variables: ${JSON.stringify(data.variables, null, 2)}` : ''}\nHeaders: ${JSON.stringify(data.headers, null, 2)}\nBody: ${data.body ? JSON.stringify(data.body, null, 2) : 'Empty'}\n `);\n}\n\nfunction logResponse(logger: Logger, uid: string, type: 'HTTP' | 'GraphQL', data: {\n status: number;\n response: any;\n}) {\n logger.log(`\nšŸ“” New Courier ${type} Response: ${uid}\nStatus Code: ${data.status}\nResponse JSON: ${JSON.stringify(data.response, null, 2)}\n `);\n}\n\nexport async function http(props: {\n url: string,\n options: CourierClientOptions,\n method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH',\n headers?: Record<string, string>,\n body?: any,\n validCodes?: number[]\n}): Promise<any> {\n const validCodes = props.validCodes ?? [200];\n const uid = props.options.showLogs ? UUID.generate() : undefined;\n\n // Create request\n const request = new Request(props.url, {\n method: props.method,\n headers: {\n 'Content-Type': 'application/json',\n ...props.headers\n },\n body: props.body ? JSON.stringify(props.body) : undefined\n });\n\n // Log request if enabled\n if (uid) {\n logRequest(props.options.logger, uid, 'HTTP', {\n url: request.url,\n method: request.method,\n headers: Object.fromEntries(request.headers.entries()),\n body: props.body\n });\n }\n\n // Perform request\n const response = await fetch(request);\n\n // Handle empty responses (like 204 No Content)\n if (response.status === 204) {\n return;\n }\n\n // Try to parse JSON response\n let data;\n try {\n data = await response.json();\n } catch (error) {\n\n // Weird fallback for only tracking url events :facepalm:\n if (response.status === 200) {\n return;\n }\n\n throw new CourierRequestError(\n response.status,\n 'Failed to parse response as JSON',\n 'PARSE_ERROR'\n );\n }\n\n // Log response if enabled\n if (uid) {\n logResponse(props.options.logger, uid, 'HTTP', {\n status: response.status,\n response: data\n });\n }\n\n // Handle invalid status codes\n if (!validCodes.includes(response.status)) {\n throw new CourierRequestError(\n response.status,\n data?.message || 'Unknown Error',\n data?.type\n );\n }\n\n return data;\n}\n\nexport async function graphql(props: {\n url: string,\n options: CourierClientOptions,\n headers: Record<string, string>,\n query: string,\n variables?: Record<string, any>\n}): Promise<any> {\n const uid = props.options.showLogs ? UUID.generate() : undefined;\n\n // Log request if enabled\n if (uid) {\n logRequest(props.options.logger, uid, 'GraphQL', {\n url: props.url,\n headers: props.headers,\n query: props.query,\n variables: props.variables\n });\n }\n\n const response = await fetch(props.url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...props.headers\n },\n body: JSON.stringify({\n query: props.query,\n variables: props.variables\n })\n });\n\n // Try to parse JSON response\n let data;\n try {\n data = await response.json();\n } catch (error) {\n throw new CourierRequestError(\n response.status,\n 'Failed to parse response as JSON',\n 'PARSE_ERROR'\n );\n }\n\n // Log response if enabled\n if (uid) {\n logResponse(props.options.logger, uid, 'GraphQL', {\n status: response.status,\n response: data\n });\n }\n\n if (!response.ok) {\n throw new CourierRequestError(\n response.status,\n data?.message || 'Unknown Error',\n data?.type\n );\n }\n\n return data;\n}\n","import { CourierClientOptions } from \"./courier-client\";\n\nexport class Client {\n\n constructor(public readonly options: CourierClientOptions) { }\n\n}\n","import { CourierBrand } from '../types/brands';\nimport { graphql } from '../utils/request';\nimport { Client } from './client';\n\nexport class BrandClient extends Client {\n\n /**\n * Get a brand by ID using GraphQL\n * @param brandId - The ID of the brand to retrieve\n * @returns Promise resolving to the requested brand\n */\n public async getBrand(props: { brandId: string }): Promise<CourierBrand> {\n const query = `\n query GetBrand {\n brand(brandId: \"${props.brandId}\") {\n settings {\n colors {\n primary\n secondary\n tertiary\n }\n inapp {\n borderRadius\n disableCourierFooter\n }\n }\n }\n }\n `;\n\n const json = await graphql({\n options: this.options,\n url: this.options.apiUrls.courier.graphql,\n headers: {\n 'x-courier-user-id': this.options.userId,\n 'x-courier-client-key': 'empty', // Empty for now. Will be removed in future.\n 'Authorization': `Bearer ${this.options.accessToken}`\n },\n query,\n variables: { brandId: props.brandId }\n });\n\n return json.data.brand as CourierBrand;\n }\n\n}\n","import { CourierSocket } from './courier-socket';\nimport { CourierClientOptions } from '../client/courier-client';\nimport { InboxMessage } from '../types/inbox';\n\ninterface SocketPayload {\n type: 'event' | 'message';\n}\n\nexport interface MessageEvent {\n event: EventType;\n messageId?: string;\n type: string;\n}\n\nexport type EventType =\n | 'archive-read'\n | 'archive'\n | 'click'\n | 'mark-all-read'\n | 'opened'\n | 'read'\n | 'unarchive'\n | 'unopened'\n | 'unread';\n\nexport class InboxSocket extends CourierSocket {\n\n public receivedMessage?: (message: InboxMessage) => void;\n public receivedMessageEvent?: (event: MessageEvent) => void;\n\n constructor(options: CourierClientOptions) {\n const url = InboxSocket.buildUrl(options);\n super(url, options);\n this.onMessageReceived = (data) => this.convertToType(data);\n }\n\n private convertToType(data: string): void {\n try {\n const payload = JSON.parse(data) as SocketPayload;\n\n switch (payload.type) {\n case 'event':\n const messageEvent = JSON.parse(data) as MessageEvent;\n this.receivedMessageEvent?.(messageEvent);\n break;\n\n case 'message':\n const message = JSON.parse(data) as InboxMessage;\n this.receivedMessage?.(message);\n break;\n }\n } catch (error) {\n this.options.logger?.error('Error parsing socket message', error);\n if (error instanceof Error) {\n this.onError?.(error);\n }\n }\n }\n\n public async sendSubscribe(props?: {\n version?: number;\n }): Promise<void> {\n const subscription: Record<string, any> = {\n action: 'subscribe',\n data: {\n userAgent: 'courier-js', // TODO: Equivalent to Courier.agent.value()\n channel: this.options.userId,\n event: '*',\n version: props?.version ?? 5,\n }\n };\n\n // Add optional parameters\n if (this.options.connectionId) {\n subscription.data.clientSourceId = this.options.connectionId;\n }\n if (this.options.tenantId) {\n subscription.data.accountId = this.options.tenantId;\n }\n\n this.options.logger?.debug('Sending subscribe request', subscription);\n\n await this.send(subscription);\n }\n\n private static buildUrl(options: CourierClientOptions): string {\n let url = options.apiUrls?.inbox.webSocket ?? '';\n\n if (options.accessToken) {\n url += `/?auth=${options.accessToken}`;\n }\n\n return url;\n }\n}\n","import { InboxSocket } from '../socket/inbox-socket';\nimport { CourierGetInboxMessagesResponse } from '../types/inbox';\nimport { graphql } from '../utils/request';\nimport { Client } from './client';\nimport { CourierClientOptions } from './courier-client';\n\nexport class InboxClient extends Client {\n\n readonly socket: InboxSocket;\n\n constructor(options: CourierClientOptions) {\n super(options);\n this.socket = new InboxSocket(options);\n }\n\n /**\n * Get paginated messages\n * @param paginationLimit - Number of messages to return per page (default: 24)\n * @param startCursor - Cursor for pagination\n * @returns Promise resolving to paginated messages response\n */\n public async getMessages(props?: {\n paginationLimit?: number;\n startCursor?: string;\n }): Promise<CourierGetInboxMessagesResponse> {\n const query = `\n query GetInboxMessages(\n $params: FilterParamsInput = { ${this.options.tenantId ? `accountId: \"${this.options.tenantId}\"` : ''} }\n $limit: Int = ${props?.paginationLimit ?? 24}\n $after: String ${props?.startCursor ? `= \"${props.startCursor}\"` : ''}\n ) {\n count(params: $params)\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 `;\n\n return await graphql({\n options: this.options,\n query,\n headers: {\n 'x-courier-user-id': this.options.userId,\n 'Authorization': `Bearer ${this.options.accessToken}`\n },\n url: this.options.apiUrls.inbox.graphql,\n });\n }\n\n /**\n * Get paginated archived messages\n * @param paginationLimit - Number of messages to return per page (default: 24)\n * @param startCursor - Cursor for pagination\n * @returns Promise resolving to paginated archived messages response\n */\n public async getArchivedMessages(props?: {\n paginationLimit?: number;\n startCursor?: string;\n }): Promise<CourierGetInboxMessagesResponse> {\n const query = `\n query GetInboxMessages(\n $params: FilterParamsInput = { ${this.options.tenantId ? `accountId: \"${this.options.tenantId}\"` : ''}, archived: true }\n $limit: Int = ${props?.paginationLimit ?? 24}\n $after: String ${props?.startCursor ? `= \"${props.startCursor}\"` : ''}\n ) {\n count(params: $params)\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 `;\n\n return graphql({\n options: this.options,\n query,\n headers: {\n 'x-courier-user-id': this.options.userId,\n 'Authorization': `Bearer ${this.options.accessToken}`\n },\n url: this.options.apiUrls.inbox.graphql,\n });\n }\n\n /**\n * Get unread message count\n * @returns Promise resolving to number of unread messages\n */\n public async getUnreadMessageCount(): Promise<number> {\n const query = `\n query GetMessages {\n count(params: { status: \"unread\" ${this.options.tenantId ? `, accountId: \"${this.options.tenantId}\"` : ''} })\n }\n `;\n\n const response = await graphql({\n options: this.options,\n query,\n headers: {\n 'x-courier-user-id': this.options.userId,\n 'Authorization': `Bearer ${this.options.accessToken}`\n },\n url: this.options.apiUrls.inbox.graphql,\n });\n\n return response.data?.count ?? 0;\n }\n\n /**\n * Track a click event\n * @param messageId - ID of the message\n * @param trackingId - ID for tracking the click\n * @returns Promise resolving when click is tracked\n */\n public async click(props: { messageId: string, trackingId: string }): Promise<void> {\n const query = `\n mutation TrackEvent {\n clicked(messageId: \"${props.messageId}\", trackingId: \"${props.trackingId}\")\n }\n `;\n\n const headers: Record<string, string> = {\n 'x-courier-user-id': this.options.userId,\n 'Authorization': `Bearer ${this.options.accessToken}`\n };\n\n if (this.options.connectionId) {\n headers['x-courier-client-source-id'] = this.options.connectionId;\n }\n\n await graphql({\n options: this.options,\n query,\n headers,\n url: this.options.apiUrls.inbox.graphql,\n });\n }\n\n /**\n * Mark a message as read\n * @param messageId - ID of the message to mark as read\n * @returns Promise resolving when message is marked as read\n */\n public async read(props: { messageId: string }): Promise<void> {\n const query = `\n mutation TrackEvent {\n read(messageId: \"${props.messageId}\")\n }\n `;\n\n const headers: Record<string, string> = {\n 'x-courier-user-id': this.options.userId,\n 'Authorization': `Bearer ${this.options.accessToken}`\n };\n\n if (this.options.connectionId) {\n headers['x-courier-client-source-id'] = this.options.connectionId;\n }\n\n await graphql({\n options: this.options,\n query,\n headers,\n url: this.options.apiUrls.inbox.graphql,\n });\n }\n\n /**\n * Mark a message as unread\n * @param messageId - ID of the message to mark as unread\n * @returns Promise resolving when message is marked as unread\n */\n public async unread(props: { messageId: string }): Promise<void> {\n const query = `\n mutation TrackEvent {\n unread(messageId: \"${props.messageId}\")\n }\n `;\n\n const headers: Record<string, string> = {\n 'x-courier-user-id': this.options.userId,\n 'Authorization': `Bearer ${this.options.accessToken}`\n };\n\n if (this.options.connectionId) {\n headers['x-courier-client-source-id'] = this.options.connectionId;\n }\n\n await graphql({\n options: this.options,\n query,\n headers,\n url: this.options.apiUrls.inbox.graphql,\n });\n }\n\n /**\n * Mark all messages as read\n * @returns Promise resolving when all messages are marked as read\n */\n public async readAll(): Promise<void> {\n const query = `\n mutation TrackEvent {\n markAllRead\n }\n `;\n\n const headers: Record<string, string> = {\n 'x-courier-user-id': this.options.userId,\n 'Authorization': `Bearer ${this.options.accessToken}`\n };\n\n if (this.options.connectionId) {\n headers['x-courier-client-source-id'] = this.options.connectionId;\n }\n\n await graphql({\n options: this.options,\n query,\n headers,\n url: this.options.apiUrls.inbox.graphql,\n });\n }\n\n /**\n * Mark a message as opened\n * @param messageId - ID of the message to mark as opened\n * @returns Promise resolving when message is marked as opened\n */\n public async open(props: { messageId: string }): Promise<void> {\n const query = `\n mutation TrackEvent {\n opened(messageId: \"${props.messageId}\")\n }\n `;\n\n const headers: Record<string, string> = {\n 'x-courier-user-id': this.options.userId,\n 'Authorization': `Bearer ${this.options.accessToken}`\n };\n\n if (this.options.connectionId) {\n headers['x-courier-client-source-id'] = this.options.connectionId;\n }\n\n await graphql({\n options: this.options,\n query,\n headers,\n url: this.options.apiUrls.inbox.graphql,\n });\n }\n\n /**\n * Archive a message\n * @param messageId - ID of the message to archive\n * @returns Promise resolving when message is archived\n */\n public async archive(props: { messageId: string }): Promise<void> {\n const query = `\n mutation TrackEvent {\n archive(messageId: \"${props.messageId}\")\n }\n `;\n\n const headers: Record<string, string> = {\n 'x-courier-user-id': this.options.userId,\n 'Authorization': `Bearer ${this.options.accessToken}`\n };\n\n if (this.options.connectionId) {\n headers['x-courier-client-source-id'] = this.options.connectionId;\n }\n\n await graphql({\n options: this.options,\n query,\n headers,\n url: this.options.apiUrls.inbox.graphql,\n });\n }\n\n /**\n * Unarchive a message\n * @param messageId - ID of the message to unarchive\n * @returns Promise resolving when message is unarchived\n */\n public async unarchive(props: { messageId: string }): Promise<void> {\n const query = `\n mutation TrackEvent {\n unarchive(messageId: \"${props.messageId}\")\n }\n `;\n\n const headers: Record<string, string> = {\n 'x-courier-user-id': this.options.userId,\n 'Authorization': `Bearer ${this.options.accessToken}`\n };\n\n if (this.options.connectionId) {\n headers['x-courier-client-source-id'] = this.options.connectionId;\n }\n\n await graphql({\n options: this.options,\n query,\n headers,\n url: this.options.apiUrls.inbox.graphql,\n });\n }\n\n /**\n * Archive all read messages.\n */\n public async archiveRead(): Promise<void> {\n const query = `\n mutation TrackEvent {\n archiveRead\n }\n `;\n\n const headers: Record<string, string> = {\n 'x-courier-user-id': this.options.userId,\n 'Authorization': `Bearer ${this.options.accessToken}`\n };\n\n if (this.options.connectionId) {\n headers['x-courier-client-source-id'] = this.options.connectionId;\n }\n\n await graphql({\n options: this.options,\n query,\n headers,\n url: this.options.apiUrls.inbox.graphql,\n });\n }\n\n /**\n * Archive all read messages.\n */\n public async archiveAll(): Promise<void> {\n const query = `\n mutation TrackEvent {\n archiveAll\n }\n `;\n\n const headers: Record<string, string> = {\n 'x-courier-user-id': this.options.userId,\n 'Authorization': `Bearer ${this.options.accessToken}`\n };\n\n if (this.options.connectionId) {\n headers['x-courier-client-source-id'] = this.options.connectionId;\n }\n\n await graphql({\n options: this.options,\n query,\n headers,\n url: this.options.apiUrls.inbox.graphql,\n });\n }\n\n}\n","export type CourierUserPreferencesStatus = 'OPTED_IN' | 'OPTED_OUT' | 'REQUIRED' | 'UNKNOWN';\n\nexport type CourierUserPreferencesChannel = 'direct_message' | 'email' | 'push' | 'sms' | 'webhook' | 'unknown';\n\nexport interface CourierUserPreferencesPaging {\n cursor?: string;\n more: boolean;\n}\n\nexport interface CourierUserPreferencesTopic {\n topicId: string;\n topicName: string;\n sectionId: string;\n sectionName: string;\n status: CourierUserPreferencesStatus;\n defaultStatus: CourierUserPreferencesStatus;\n hasCustomRouting: boolean;\n customRouting: CourierUserPreferencesChannel[];\n}\n\nexport interface CourierUserPreferences {\n items: CourierUserPreferencesTopic[];\n paging: CourierUserPreferencesPaging;\n}\n\nexport interface CourierUserPreferencesTopicResponse {\n topic: CourierUserPreferencesTopic;\n}\n\nexport class PreferenceTransformer {\n /**\n * Transforms a single API response item to the CourierUserPreferencesTopic type\n * @param item - The API response item\n * @returns A CourierUserPreferencesTopic object\n */\n transformItem(item: any): CourierUserPreferencesTopic {\n return {\n topicId: item.topic_id,\n topicName: item.topic_name,\n sectionId: item.section_id,\n sectionName: item.section_name,\n status: item.status,\n defaultStatus: item.default_status,\n hasCustomRouting: item.has_custom_routing,\n customRouting: item.custom_routing || []\n };\n }\n\n /**\n * Transforms an array of API response items to CourierUserPreferencesTopic objects\n * @param items - The API response items\n * @returns A generator of CourierUserPreferencesTopic objects\n */\n *transform(items: any[]): Generator<CourierUserPreferencesTopic> {\n for (const item of items) {\n yield this.transformItem(item);\n }\n }\n}","export function decode(clientKey: string): string {\n const binaryString = atob(clientKey);\n const bytes = new Uint8Array(binaryString.length);\n\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n\n return String.fromCharCode(...bytes);\n}\n\nexport function encode(key: string): string {\n const bytes = new Uint8Array(key.length);\n\n for (let i = 0; i < key.length; i++) {\n bytes[i] = key.charCodeAt(i);\n }\n\n return btoa(String.fromCharCode(...bytes));\n}","import { CourierUserPreferences, CourierUserPreferencesChannel, CourierUserPreferencesStatus, CourierUserPreferencesTopic, CourierUserPreferencesTopicResponse, PreferenceTransformer } from '../types/preference';\nimport { decode, encode } from '../utils/coding';\nimport { http } from '../utils/request';\nimport { Client } from './client';\n\nexport class PreferenceClient extends Client {\n private transformer = new PreferenceTransformer();\n\n /**\n * Get all preferences for a user\n * @param paginationCursor - Optional cursor for pagination\n * @returns Promise resolving to user preferences\n * @see https://www.courier.com/docs/reference/user-preferences/list-all-user-preferences\n */\n public async getUserPreferences(props?: {\n paginationCursor?: string;\n }): Promise<CourierUserPreferences> {\n let url = `${this.options.apiUrls.courier.rest}/users/${this.options.userId}/preferences`;\n\n if (props?.paginationCursor) {\n url += `?cursor=${props.paginationCursor}`;\n }\n\n const json = await http({\n options: this.options,\n url,\n method: 'GET',\n headers: {\n 'Authorization': `Bearer ${this.options.accessToken}`\n },\n });\n\n const data = json as CourierUserPreferences;\n\n return {\n items: [...this.transformer.transform(data.items)],\n paging: data.paging\n };\n }\n\n /**\n * Get preferences for a specific topic\n * @param topicId - The ID of the topic to get preferences for\n * @returns Promise resolving to topic preferences\n * @see https://www.courier.com/docs/reference/user-preferences/get-subscription-topic-preferences\n */\n public async getUserPreferenceTopic(props: {\n topicId: string;\n }): Promise<CourierUserPreferencesTopic> {\n\n const json = await http({\n options: this.options,\n url: `${this.options.apiUrls.courier.rest}/users/${this.options.userId}/preferences/${props.topicId}`,\n method: 'GET',\n headers: {\n 'Authorization': `Bearer ${this.options.accessToken}`\n },\n });\n\n const res = json as CourierUserPreferencesTopicResponse;\n return this.transformer.transformItem(res.topic);\n }\n\n /**\n * Update preferences for a specific topic\n * @param topicId - The ID of the topic to update preferences for\n * @param status - The new status for the topic\n * @param hasCustomRouting - Whether the topic has custom routing\n * @param customRouting - The custom routing channels for the topic\n * @returns Promise resolving when update is complete\n * @see https://www.courier.com/docs/reference/user-preferences/update-subscription-topic-preferences\n */\n public async putUserPreferenceTopic(props: {\n topicId: string;\n status: CourierUserPreferencesStatus;\n hasCustomRouting: boolean;\n customRouting: CourierUserPreferencesChannel[];\n }): Promise<void> {\n\n const payload = {\n topic: {\n status: props.status,\n has_custom_routing: props.hasCustomRouting,\n custom_routing: props.customRouting,\n },\n };\n\n await http({\n options: this.options,\n url: `${this.options.apiUrls.courier.rest}/users/${this.options.userId}/preferences/${props.topicId}`,\n method: 'PUT',\n headers: {\n 'Authorization': `Bearer ${this.options.accessToken}`\n },\n body: payload,\n });\n }\n\n /**\n * Get the notification center URL\n * @param clientKey - The client key to use for the URL\n * @returns The notification center URL\n */\n public getNotificationCenterUrl(props: {\n clientKey: string;\n }): string {\n const rootTenantId = decode(props.clientKey);\n const url = encode(`${rootTenantId}#${this.options.userId}${this.options.tenantId ? `#${this.options.tenantId}` : \"\"}#${false}`);\n return `https://view.notificationcenter.app/p/${url}`;\n }\n\n}\n","import { CourierDevice } from '../types/token';\nimport { http } from '../utils/request';\nimport { Client } from './client';\n\nexport class TokenClient extends Client {\n\n /**\n * Store a push notification token for a user\n * @param token - The push notification token\n * @param provider - The provider of the token\n * @param device - The device information\n * @see https://www.courier.com/docs/reference/token-management/put-token\n */\n public async putUserToken(props: {\n token: string;\n provider: string;\n device?: CourierDevice;\n }): Promise<void> {\n const payload = {\n provider_key: props.provider,\n ...(props.device && {\n device: {\n app_id: props.device.appId,\n ad_id: props.device.adId,\n device_id: props.device.deviceId,\n platform: props.device.platform,\n manufacturer: props.device.manufacturer,\n model: props.device.model\n }\n })\n };\n\n await http({\n options: this.options,\n url: `${this.options.apiUrls.courier.rest}/users/${this.options.userId}/tokens/${props.token}`,\n method: 'PUT',\n headers: {\n 'Authorization': `Bearer ${this.options.accessToken}`\n },\n body: payload,\n validCodes: [200, 204]\n });\n }\n\n /**\n * Delete a push notification token for a user\n * @param token - The push notification token\n * @returns Promise resolving when token is deleted\n */\n public async deleteUserToken(props: {\n token: string;\n }): Promise<void> {\n await http({\n options: this.options,\n url: `${this.options.apiUrls.courier.rest}/users/${this.options.userId}/tokens/${props.token}`,\n method: 'DELETE',\n headers: {\n 'Authorization': `Bearer ${this.options.accessToken}`\n },\n validCodes: [200, 204]\n });\n }\n}\n","import { http } from '../utils/request';\nimport { Client } from './client';\n\nexport class ListClient extends Client {\n\n /**\n * Subscribe a user to a list\n * @param listId - The ID of the list to subscribe to\n * @returns Promise resolving when subscription is complete\n * @see https://www.courier.com/docs/reference/lists/recipient-subscribe\n */\n public async putSubscription(props: {\n listId: string;\n }): Promise<void> {\n return await http({\n url: `${this.options.apiUrls.courier.rest}/lists/${props.listId}/subscriptions/${this.options.userId}`,\n options: this.options,\n method: 'PUT',\n headers: {\n Authorization: `Bearer ${this.options.accessToken}`,\n },\n });\n }\n\n /**\n * Unsubscribe a user from a list\n * @param listId - The ID of the list to unsubscribe from\n * @returns Promise resolving when unsubscription is complete\n * @see https://www.courier.com/docs/reference/lists/delete-subscription\n */\n public async deleteSubscription(props: {\n listId: string;\n }): Promise<void> {\n return await http({\n url: `${this.options.apiUrls.courier.rest}/lists/${props.listId}/subscriptions/${this.options.userId}`,\n options: this.options,\n method: 'DELETE',\n headers: {\n Authorization: `Bearer ${this.options.accessToken}`,\n },\n });\n }\n\n}\n","import { CourierTrackingEvent } from '../types/tracking-event';\nimport { http } from '../utils/request';\nimport { Client } from './client';\n\nexport class TrackingClient extends Client {\n\n /**\n * Post an inbound courier event\n * @param event - The event type: Example: \"New Order Placed\"\n * @param messageId - The message ID\n * @param type - The type of event: Available options: \"track\"\n * @param properties - The properties of the event\n * @returns Promise resolving to the message ID\n * @see https://www.courier.com/docs/reference/inbound/courier-track-event\n */\n public async postInboundCourier(props: {\n event: string;\n messageId: string;\n type: 'track';\n properties?: Record<string, any>;\n }): Promise<{ messageId: string }> {\n return await http({\n url: `${this.options.apiUrls.courier.rest}/inbound/courier`,\n options: this.options,\n method: 'POST',\n headers: {\n Authorization: `Bearer ${this.options.accessToken}`,\n },\n body: {\n ...props,\n userId: this.options.userId\n },\n validCodes: [200, 202]\n });\n }\n\n /**\n * Post a tracking URL event\n * These urls are found in messages sent from Courier\n * @param url - The URL to post the event to\n * @param event - The event type: Available options: \"click\", \"open\", \"unsubscribe\"\n * @returns Promise resolving when the event is posted\n */\n public async postTrackingUrl(props: {\n url: string;\n event: CourierTrackingEvent;\n }): Promise<void> {\n return await http({\n url: props.url,\n options: this.options,\n method: 'POST',\n body: {\n event: props.event\n }\n });\n }\n\n}\n","import { CourierApiUrls, getCourierApiUrls } from '../types/courier-api-urls';\nimport { Logger } from '../utils/logger';\nimport { BrandClient } from './brand-client';\nimport { InboxClient } from './inbox-client';\nimport { PreferenceClient } from './preference-client';\nimport { TokenClient } from './token-client';\nimport { Client } from './client';\nimport { ListClient } from './list-client';\nimport { TrackingClient } from './tracking-client';\n\nexport interface CourierProps {\n jwt?: string; // JWT token for authentication: More info at https://www.courier.com/docs/reference/auth/issue-token\n publicApiKey?: string; // Public API key for authentication\n userId: string; // User ID for the client. This is normally an ID that matches users in your system\n connectionId?: string; // Inbox Websocket connection ID\n tenantId?: string; // Tenant ID. Used for multi-tenant apps\n showLogs?: boolean; // Flag to control logging. Logs are prefixed with [COURIER].\n apiUrls?: CourierApiUrls; // Custom API URLs\n}\n\nexport interface CourierClientOptions {\n readonly jwt?: string; // JWT token for authentication: More info at https://www.courier.com/docs/reference/auth/issue-token\n readonly publicApiKey?: string; // Public API key for authentication\n readonly userId: string; // User ID for the client. This is normally an ID that matches users in your system\n readonly connectionId?: string; // Inbox Websocket connection ID\n readonly tenantId?: string; // Tenant ID. Used for multi-tenant apps\n readonly showLogs?: boolean; // Flag to control logging. Logs are prefixed with [COURIER].\n readonly accessToken?: string; // Combined authentication token (jwt or publicApiKey)\n readonly logger: Logger; // Logger instance\n readonly apiUrls: CourierApiUrls; // Final API URLs configuration\n}\n\nexport class CourierClient extends Client {\n public readonly tokens: TokenClient;\n public readonly brands: BrandClient;\n public readonly preferences: PreferenceClient;\n public readonly inbox: InboxClient;\n public readonly lists: ListClient;\n public readonly tracking: TrackingClient;\n\n constructor(props: CourierProps) {\n\n // Determine if we should show logs based on props or environment\n const showLogs = props.showLogs !== undefined ? props.showLogs : process.env.NODE_ENV === 'development';\n\n // Setup base options with default values\n const baseOptions = {\n ...props,\n showLogs,\n apiUrls: props.apiUrls || getCourierApiUrls(),\n accessToken: props.jwt ?? props.publicApiKey\n };\n\n // Initialize base client with logger and URLs\n super({\n ...baseOptions,\n logger: new Logger(baseOptions.showLogs),\n apiUrls: getCourierApiUrls(baseOptions.apiUrls)\n });\n\n // Initialize all subclients with the configured options\n this.tokens = new TokenClient(this.options);\n this.brands = new BrandClient(this.options);\n this.preferences = new PreferenceClient(this.options);\n this.inbox = new InboxClient(this.options);\n this.lists = new ListClient(this.options);\n this.tracking = new TrackingClient(this.options);\n\n // Warn if no authentication method is provided\n if (!this.options.jwt && !this.options.publicApiKey) {\n this.options.logger.warn('Courier Client initialized with no authentication method. Please provide a JWT or public API key.');\n }\n\n // Warn about using public API key in production\n if (this.options.publicApiKey) {\n this.options.logger?.warn(\n 'Courier Warning: Public API Keys are for testing only. Please use JWTs for production.\\n' +\n 'You can generate a JWT with this endpoint: https://www.courier.com/docs/reference/auth/issue-token\\n' +\n 'This endpoint should be called from your backend server, not the SDK.'\n );\n }\n\n // Warn if both authentication methods are provided\n if (this.options.jwt && this.options.publicApiKey) {\n this.options.logger?.warn(\n 'Courier Warning: Both a JWT and a Public API Key were provided. The Public API Key will be ignored.'\n );\n }\n\n }\n\n}\n","import { Courier } from \"./courier\";\n\nexport class AuthenticationListener {\n readonly callback: (props: { userId?: string }) => void;\n\n constructor(callback: (props: { userId?: string }) => void) {\n this.callback = callback;\n }\n\n public remove(): void {\n Courier.shared.removeAuthenticationListener(this);\n }\n\n}","import { CourierClient, CourierProps } from \"../client/courier-client\";\nimport { AuthenticationListener } from '../shared/authentication-listener';\nimport { UUID } from \"../utils/uuid\";\n\n/**\n * Courier is a singleton class that manages a shared Courier client instance and other resources.\n * UI components will automatically syncronize with this instance.\n * If you only need to call the Courier api, you should consider using the CourierClient directly.\n */\nexport class Courier {\n\n /**\n * The unique identifier for the Courier instance\n */\n public readonly id = UUID.generate();\n\n /**\n * The shared Courier instance\n */\n private static instance: Courier;\n\n /**\n * The Courier client instance\n */\n private instanceClient?: CourierClient;\n\n /**\n * The pagination limit (min: 1, max: 100)\n */\n private _paginationLimit = 24;\n\n public get paginationLimit(): number {\n return this._paginationLimit;\n }\n\n public set paginationLimit(value: number) {\n this._paginationLimit = Math.min(Math.max(value, 1), 100);\n }\n\n /**\n * Get the Courier client instance\n * @returns The Courier client instance or undefined if not signed in\n */\n public get client(): CourierClient | undefined {\n return this.instanceClient;\n }\n\n /**\n * The authentication listeners\n */\n private authenticationListeners: AuthenticationListener[] = [];\n\n /**\n * Get the shared Courier instance\n * @returns The shared Courier instance\n */\n public static get shared(): Courier {\n if (!Courier.instance) {\n Courier.instance = new Courier();\n }\n return Courier.instance;\n }\n\n /**\n * Sign in to Courier\n * @param options - The options for the Courier client\n */\n public signIn(props: CourierProps) {\n const connectionId = props.connectionId ?? UUID.generate();\n this.instanceClient = new CourierClient({ ...props, connectionId });\n this.notifyAuthenticationListeners({ userId: props.userId });\n }\n\n /**\n * Sign out of Courier\n */\n public signOut() {\n this.instanceClient = undefined;\n this.notifyAuthenticationListeners({ userId: undefined });\n }\n\n /**\n * Register a callback to be notified of authentication state changes\n * @param callback - Function to be called when authentication state changes\n * @returns AuthenticationListener instance that can be used to remove the listener\n */\n public addAuthenticationListener(callback: (props: { userId?: string }) => void): AuthenticationListener {\n this.instanceClient?.options.logger.info('Adding authentication listener');\n const listener = new AuthenticationListener(callback);\n this.authenticationListeners.push(listener);\n return listener;\n }\n\n /**\n * Unregister an authentication state change listener\n * @param listener - The AuthenticationListener instance to remove\n */\n public removeAuthenticationListener(listener: AuthenticationListener) {\n this.instanceClient?.options.logger.info('Removing authentication listener');\n this.authenticationListeners = this.authenticationListeners.filter(l => l !== listener);\n }\n\n /**\n * Notify all authentication listeners\n * @param props - The props to notify the listeners with\n */\n private notifyAuthenticationListeners(props: { userId?: string }) {\n this.authenticationListeners.forEach(listener => listener.callback(props));\n }\n\n}\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trycourier/courier-js",
3
- "version": "2.0.2-beta",
3
+ "version": "2.0.3-beta",
4
4
  "description": "A browser-safe API wrapper",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",