@trycourier/courier-js 2.0.1-beta ā 2.0.2-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.
- package/README.md +22 -0
- package/dist/client/inbox-client.d.ts +4 -0
- package/dist/index.js +1 -1
- package/dist/index.mjs +23 -0
- package/dist/socket/inbox-socket.d.ts +1 -1
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# @trycourier/courier-js
|
|
2
|
+
|
|
3
|
+
The base API client and shared instance singleton for Courier's JavaScript Browser SDK.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
npm i @trycourier/courier-js@2.0.1-beta
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
const courierClient = new CourierClient({
|
|
15
|
+
userId: 'mike',
|
|
16
|
+
jwt: 'ey...n0'
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
// Fetch the inbox messages for the user
|
|
20
|
+
const messages = await courierClient.inbox.getMessages();
|
|
21
|
+
console.log(messages);
|
|
22
|
+
```
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
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})}}class b{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 v extends p{constructor(){super(...arguments),s(this,"transformer",new b)}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 v(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=v,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.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"})}));
|
package/dist/index.mjs
CHANGED
|
@@ -646,6 +646,29 @@ class InboxClient extends Client {
|
|
|
646
646
|
url: this.options.apiUrls.inbox.graphql
|
|
647
647
|
});
|
|
648
648
|
}
|
|
649
|
+
/**
|
|
650
|
+
* Archive all read messages.
|
|
651
|
+
*/
|
|
652
|
+
async archiveRead() {
|
|
653
|
+
const query = `
|
|
654
|
+
mutation TrackEvent {
|
|
655
|
+
archiveRead
|
|
656
|
+
}
|
|
657
|
+
`;
|
|
658
|
+
const headers = {
|
|
659
|
+
"x-courier-user-id": this.options.userId,
|
|
660
|
+
"Authorization": `Bearer ${this.options.accessToken}`
|
|
661
|
+
};
|
|
662
|
+
if (this.options.connectionId) {
|
|
663
|
+
headers["x-courier-client-source-id"] = this.options.connectionId;
|
|
664
|
+
}
|
|
665
|
+
await graphql({
|
|
666
|
+
options: this.options,
|
|
667
|
+
query,
|
|
668
|
+
headers,
|
|
669
|
+
url: this.options.apiUrls.inbox.graphql
|
|
670
|
+
});
|
|
671
|
+
}
|
|
649
672
|
}
|
|
650
673
|
class PreferenceTransformer {
|
|
651
674
|
/**
|
|
@@ -6,7 +6,7 @@ export interface MessageEvent {
|
|
|
6
6
|
messageId?: string;
|
|
7
7
|
type: string;
|
|
8
8
|
}
|
|
9
|
-
export type EventType = 'read' | '
|
|
9
|
+
export type EventType = 'archive-read' | 'archive' | 'click' | 'mark-all-read' | 'opened' | 'read' | 'unarchive' | 'unopened' | 'unread';
|
|
10
10
|
export declare class InboxSocket extends CourierSocket {
|
|
11
11
|
receivedMessage?: (message: InboxMessage) => void;
|
|
12
12
|
receivedMessageEvent?: (event: MessageEvent) => void;
|