@trycourier/courier-js 1.4.2 → 2.0.0-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.
Files changed (38) hide show
  1. package/dist/__tests__/brand-client.test.d.ts +1 -0
  2. package/dist/__tests__/courier-client.test.d.ts +1 -0
  3. package/dist/__tests__/inbox-client.test.d.ts +1 -0
  4. package/dist/__tests__/lists-client.test.d.ts +1 -0
  5. package/dist/__tests__/preferences-client.test.d.ts +1 -0
  6. package/dist/__tests__/shared-instance.test.d.ts +1 -0
  7. package/dist/__tests__/token-client.test.d.ts +1 -0
  8. package/dist/__tests__/tracking-client.test.d.ts +1 -0
  9. package/dist/__tests__/utils.d.ts +2 -0
  10. package/dist/client/brand-client.d.ts +10 -0
  11. package/dist/client/client.d.ts +5 -0
  12. package/dist/client/courier-client.d.ts +39 -0
  13. package/dist/client/inbox-client.d.ts +61 -0
  14. package/dist/client/list-client.d.ts +17 -0
  15. package/dist/client/preference-client.d.ts +37 -0
  16. package/dist/client/token-client.d.ts +19 -0
  17. package/dist/client/tracking-client.d.ts +24 -0
  18. package/dist/index.d.ts +19 -40
  19. package/dist/index.js +1 -189
  20. package/dist/index.mjs +981 -133
  21. package/dist/jest.setup.d.ts +0 -0
  22. package/dist/shared/authentication-listener.d.ts +9 -0
  23. package/dist/shared/courier.d.ts +68 -0
  24. package/dist/socket/courier-socket.d.ts +24 -0
  25. package/dist/socket/inbox-socket.d.ts +19 -0
  26. package/dist/types/brands.d.ts +36 -0
  27. package/dist/types/courier-api-urls.d.ts +11 -0
  28. package/dist/types/inbox.d.ts +43 -0
  29. package/dist/types/pagination.d.ts +4 -0
  30. package/dist/types/preference.d.ts +37 -0
  31. package/dist/types/token.d.ts +12 -0
  32. package/dist/types/tracking-event.d.ts +1 -0
  33. package/dist/utils/coding.d.ts +2 -0
  34. package/dist/utils/logger.d.ts +10 -0
  35. package/dist/utils/request.d.ts +21 -0
  36. package/dist/utils/uuid.d.ts +3 -0
  37. package/package.json +30 -21
  38. package/README.md +0 -123
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ import { CourierClient } from '../client/courier-client';
2
+ export declare function getClient(tenantId?: string): CourierClient;
@@ -0,0 +1,10 @@
1
+ import { CourierBrand } from '../types/brands';
2
+ import { Client } from './client';
3
+ export declare class BrandClient extends Client {
4
+ /**
5
+ * Get a brand by ID using GraphQL
6
+ */
7
+ getBrand(props: {
8
+ brandId: string;
9
+ }): Promise<CourierBrand>;
10
+ }
@@ -0,0 +1,5 @@
1
+ import { CourierClientOptions } from './courier-client';
2
+ export declare class Client {
3
+ readonly options: CourierClientOptions;
4
+ constructor(options: CourierClientOptions);
5
+ }
@@ -0,0 +1,39 @@
1
+ import { CourierApiUrls } from '../types/courier-api-urls';
2
+ import { Logger } from '../utils/logger';
3
+ import { BrandClient } from './brand-client';
4
+ import { InboxClient } from './inbox-client';
5
+ import { PreferenceClient } from './preference-client';
6
+ import { TokenClient } from './token-client';
7
+ import { Client } from './client';
8
+ import { ListClient } from './list-client';
9
+ import { TrackingClient } from './tracking-client';
10
+ export interface CourierProps {
11
+ jwt?: string;
12
+ publicApiKey?: string;
13
+ userId: string;
14
+ connectionId?: string;
15
+ tenantId?: string;
16
+ showLogs?: boolean;
17
+ apiUrls?: CourierApiUrls;
18
+ }
19
+ export interface CourierClientOptions {
20
+ readonly jwt?: string;
21
+ readonly publicApiKey?: string;
22
+ readonly userId: string;
23
+ readonly connectionId?: string;
24
+ readonly tenantId?: string;
25
+ readonly showLogs?: boolean;
26
+ readonly apiUrls?: CourierApiUrls;
27
+ readonly accessToken?: string;
28
+ readonly logger: Logger;
29
+ readonly urls: CourierApiUrls;
30
+ }
31
+ export declare class CourierClient extends Client {
32
+ readonly tokens: TokenClient;
33
+ readonly brands: BrandClient;
34
+ readonly preferences: PreferenceClient;
35
+ readonly inbox: InboxClient;
36
+ readonly lists: ListClient;
37
+ readonly tracking: TrackingClient;
38
+ constructor(props: CourierProps);
39
+ }
@@ -0,0 +1,61 @@
1
+ import { InboxSocket } from '../socket/inbox-socket';
2
+ import { CourierGetInboxMessagesResponse } from '../types/inbox';
3
+ import { Client } from './client';
4
+ import { CourierClientOptions } from './courier-client';
5
+ export declare class InboxClient extends Client {
6
+ readonly socket: InboxSocket;
7
+ constructor(options: CourierClientOptions);
8
+ /**
9
+ * Get paginated messages
10
+ */
11
+ getMessages(props?: {
12
+ paginationLimit?: number;
13
+ startCursor?: string;
14
+ }): Promise<CourierGetInboxMessagesResponse>;
15
+ /**
16
+ * Get paginated archived messages
17
+ */
18
+ getArchivedMessages(props?: {
19
+ paginationLimit?: number;
20
+ startCursor?: string;
21
+ }): Promise<CourierGetInboxMessagesResponse>;
22
+ /**
23
+ * Get unread message count
24
+ */
25
+ getUnreadMessageCount(): Promise<number>;
26
+ /**
27
+ * Track a click event
28
+ */
29
+ click(props: {
30
+ messageId: string;
31
+ trackingId: string;
32
+ }): Promise<void>;
33
+ /**
34
+ * Mark a message as read
35
+ */
36
+ read(props: {
37
+ messageId: string;
38
+ }): Promise<void>;
39
+ /**
40
+ * Mark a message as unread
41
+ */
42
+ unread(props: {
43
+ messageId: string;
44
+ }): Promise<void>;
45
+ /**
46
+ * Mark all messages as read
47
+ */
48
+ readAll(): Promise<void>;
49
+ /**
50
+ * Mark a message as opened
51
+ */
52
+ open(props: {
53
+ messageId: string;
54
+ }): Promise<void>;
55
+ /**
56
+ * Archive a message
57
+ */
58
+ archive(props: {
59
+ messageId: string;
60
+ }): Promise<void>;
61
+ }
@@ -0,0 +1,17 @@
1
+ import { Client } from './client';
2
+ export declare class ListClient extends Client {
3
+ /**
4
+ * Subscribe a user to a list
5
+ * @see https://www.courier.com/docs/reference/lists/recipient-subscribe
6
+ */
7
+ putSubscription(props: {
8
+ listId: string;
9
+ }): Promise<void>;
10
+ /**
11
+ * Unsubscribe a user from a list
12
+ * @see https://www.courier.com/docs/reference/lists/delete-subscription
13
+ */
14
+ deleteSubscription(props: {
15
+ listId: string;
16
+ }): Promise<void>;
17
+ }
@@ -0,0 +1,37 @@
1
+ import { CourierUserPreferences, CourierUserPreferencesChannel, CourierUserPreferencesStatus, CourierUserPreferencesTopic } from '../types/preference';
2
+ import { Client } from './client';
3
+ export declare class PreferenceClient extends Client {
4
+ private transformer;
5
+ /**
6
+ * Get all preferences for a user
7
+ * @see https://www.courier.com/docs/reference/user-preferences/list-all-user-preferences
8
+ */
9
+ getUserPreferences(params?: {
10
+ paginationCursor?: string;
11
+ }): Promise<CourierUserPreferences>;
12
+ /**
13
+ * Get preferences for a specific topic
14
+ * @see https://www.courier.com/docs/reference/user-preferences/get-subscription-topic-preferences
15
+ */
16
+ getUserPreferenceTopic(params: {
17
+ topicId: string;
18
+ }): Promise<CourierUserPreferencesTopic>;
19
+ /**
20
+ * Update preferences for a specific topic
21
+ * @see https://www.courier.com/docs/reference/user-preferences/update-subscription-topic-preferences
22
+ */
23
+ putUserPreferenceTopic(params: {
24
+ topicId: string;
25
+ status: CourierUserPreferencesStatus;
26
+ hasCustomRouting: boolean;
27
+ customRouting: CourierUserPreferencesChannel[];
28
+ }): Promise<void>;
29
+ /**
30
+ * Get the notification center URL
31
+ * @param params
32
+ * @returns
33
+ */
34
+ getNotificationCenterUrl(params: {
35
+ clientKey: string;
36
+ }): string;
37
+ }
@@ -0,0 +1,19 @@
1
+ import { CourierDevice } from '../types/token';
2
+ import { Client } from './client';
3
+ export declare class TokenClient extends Client {
4
+ /**
5
+ * Store a push notification token for a user
6
+ * @see https://www.courier.com/docs/reference/token-management/put-token
7
+ */
8
+ putUserToken(props: {
9
+ token: string;
10
+ provider: string;
11
+ device?: CourierDevice;
12
+ }): Promise<void>;
13
+ /**
14
+ * Delete a push notification token for a user
15
+ */
16
+ deleteUserToken(props: {
17
+ token: string;
18
+ }): Promise<void>;
19
+ }
@@ -0,0 +1,24 @@
1
+ import { CourierTrackingEvent } from '../types/tracking-event';
2
+ import { Client } from './client';
3
+ export declare class TrackingClient extends Client {
4
+ /**
5
+ * Post an inbound courier event
6
+ * @see https://www.courier.com/docs/reference/inbound/courier-track-event
7
+ */
8
+ postInboundCourier(props: {
9
+ event: string;
10
+ messageId: string;
11
+ type: 'track';
12
+ properties?: Record<string, any>;
13
+ }): Promise<{
14
+ messageId: string;
15
+ }>;
16
+ /**
17
+ * Post a tracking URL event
18
+ * These urls are found in messages sent from Courier
19
+ */
20
+ postTrackingUrl(props: {
21
+ url: string;
22
+ event: CourierTrackingEvent;
23
+ }): Promise<void>;
24
+ }
package/dist/index.d.ts CHANGED
@@ -1,40 +1,19 @@
1
- type CourierOptions = {
2
- authorization?: string;
3
- baseUrl?: string;
4
- clientKey?: string;
5
- debug?: boolean;
6
- userId?: string;
7
- userSignature?: string;
8
- };
9
- type PreferenceLinkOptions = {
10
- brandId?: string;
11
- tenantId?: string;
12
- };
13
- declare class Courier {
14
- private authorization?;
15
- private baseUrl;
16
- private clientKey;
17
- private debug?;
18
- private userId?;
19
- private userSignature?;
20
- constructor({ authorization, baseUrl, clientKey, debug, userId, userSignature, }: CourierOptions);
21
- private getHeaders;
22
- post<T>(path: string, body: T, useClientPath?: boolean): Promise<void>;
23
- put<T>(path: string, body?: T, useClientPath?: boolean): Promise<void>;
24
- delete(path: string, useClientPath?: boolean): Promise<void>;
25
- generatePreferencesUrl(userId: string, options?: PreferenceLinkOptions): string;
26
- private getPathURL;
27
- }
28
-
29
- declare const client: {
30
- __instance: Courier | null;
31
- init(options: CourierOptions): void;
32
- readonly instance: Courier;
33
- identify(userId: string, payload: Record<string, unknown>): Promise<void>;
34
- subscribe(userId: string, listId: string): Promise<void>;
35
- track(event: string, properties?: Record<string, unknown>): Promise<void>;
36
- unsubscribe(userId: string, listId: string): Promise<void>;
37
- generatePreferencesUrl(userId: string, options?: PreferenceLinkOptions): string;
38
- };
39
-
40
- export { client as default };
1
+ import { CourierApiUrls } from './types/courier-api-urls';
2
+ import { CourierBrand } from './types/brands';
3
+ import { CourierUserPreferences, CourierUserPreferencesStatus, CourierUserPreferencesChannel, CourierUserPreferencesPaging, CourierUserPreferencesTopic, CourierUserPreferencesTopicResponse } from './types/preference';
4
+ import { CourierDevice, CourierToken } from './types/token';
5
+ import { CourierGetInboxMessageResponse, CourierGetInboxMessagesResponse, InboxMessage, InboxAction } from './types/inbox';
6
+ import { MessageEvent, EventType } from './socket/inbox-socket';
7
+ import { CourierSocket } from './socket/courier-socket';
8
+ import { CourierClient, CourierClientOptions, CourierProps } from './client/courier-client';
9
+ import { BrandClient } from './client/brand-client';
10
+ import { TokenClient } from './client/token-client';
11
+ import { PreferenceClient } from './client/preference-client';
12
+ import { InboxClient } from './client/inbox-client';
13
+ import { ListClient } from './client/list-client';
14
+ import { AuthenticationListener } from './shared/authentication-listener';
15
+ import { Courier } from './shared/courier';
16
+ export type { CourierProps, CourierClientOptions, CourierBrand, CourierApiUrls, CourierUserPreferences, CourierUserPreferencesStatus, CourierUserPreferencesChannel, CourierUserPreferencesPaging, CourierUserPreferencesTopic, CourierUserPreferencesTopicResponse, CourierDevice, CourierToken, CourierGetInboxMessageResponse, CourierGetInboxMessagesResponse, InboxMessage, InboxAction, MessageEvent, EventType, };
17
+ export { CourierClient, BrandClient, TokenClient, PreferenceClient, InboxClient, ListClient, CourierSocket };
18
+ export type { AuthenticationListener };
19
+ export { Courier };
package/dist/index.js CHANGED
@@ -1,189 +1 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
-
20
- // src/index.ts
21
- var src_exports = {};
22
- __export(src_exports, {
23
- default: () => src_default
24
- });
25
- module.exports = __toCommonJS(src_exports);
26
-
27
- // package.json
28
- var version = "1.4.2";
29
-
30
- // src/helpers/decode.ts
31
- function decode(clientKey) {
32
- const binaryString = atob(clientKey);
33
- const bytes = new Uint8Array(binaryString.length);
34
- for (let i = 0; i < binaryString.length; i++) {
35
- bytes[i] = binaryString.charCodeAt(i);
36
- }
37
- return String.fromCharCode(...bytes);
38
- }
39
- function encode(key) {
40
- const bytes = new Uint8Array(key.length);
41
- for (let i = 0; i < key.length; i++) {
42
- bytes[i] = key.charCodeAt(i);
43
- }
44
- return btoa(String.fromCharCode(...bytes));
45
- }
46
-
47
- // src/helpers/client.ts
48
- async function tryCatch(fn, debug = true) {
49
- var _a, _b;
50
- const response = await fn();
51
- if (!response.ok && debug) {
52
- console.error(
53
- `Error invoking ${response.url}: ${(_a = response.status) != null ? _a : 404} because ${JSON.stringify((_b = await response.json()) == null ? void 0 : _b.message)}`
54
- );
55
- }
56
- }
57
- var Courier = class {
58
- constructor({
59
- authorization,
60
- baseUrl,
61
- clientKey,
62
- debug = false,
63
- userId,
64
- userSignature
65
- }) {
66
- if (!clientKey) {
67
- throw new Error("Courier client key is required");
68
- }
69
- this.authorization = authorization;
70
- this.baseUrl = `${baseUrl != null ? baseUrl : "https://api.courier.com"}`;
71
- this.clientKey = clientKey;
72
- this.debug = debug;
73
- this.userId = userId;
74
- this.userSignature = userSignature;
75
- }
76
- getHeaders() {
77
- return new Headers({
78
- "Content-Type": "application/json",
79
- "x-courier-client-version": `courier-js@${version}`,
80
- "Access-Control-Allow-Origin": "*",
81
- ...this.authorization && { Authorization: this.authorization },
82
- ...this.userId && { "x-courier-user-id": this.userId },
83
- ...this.userSignature && {
84
- "x-courier-user-signature": this.userSignature
85
- },
86
- ...this.clientKey && { "x-courier-client-key": this.clientKey }
87
- });
88
- }
89
- async post(path, body, useClientPath = true) {
90
- const postFn = () => {
91
- return fetch(this.getPathURL(path, useClientPath), {
92
- body: JSON.stringify(body),
93
- headers: this.getHeaders(),
94
- method: "POST"
95
- });
96
- };
97
- await tryCatch(postFn, this.debug);
98
- }
99
- async put(path, body, useClientPath = true) {
100
- const putFn = () => {
101
- return fetch(this.getPathURL(path, useClientPath), {
102
- ...body ? { body: JSON.stringify(body) } : {},
103
- headers: this.getHeaders(),
104
- method: "PUT"
105
- });
106
- };
107
- await tryCatch(putFn, this.debug);
108
- }
109
- async delete(path, useClientPath = true) {
110
- const deleteFn = () => {
111
- return fetch(this.getPathURL(path, useClientPath), {
112
- headers: this.getHeaders(),
113
- method: "DELETE"
114
- });
115
- };
116
- await tryCatch(deleteFn, this.debug);
117
- }
118
- generatePreferencesUrl(userId, options) {
119
- var _a;
120
- if (!userId) {
121
- throw new Error("User ID is required to generate preferences URL");
122
- }
123
- const id = decode(this.clientKey);
124
- return `https://view.notificationcenter.app/p/${encode(
125
- `${id}#${(_a = options == null ? void 0 : options.brandId) != null ? _a : ""}#${userId}${(options == null ? void 0 : options.tenantId) ? `#${options.tenantId}` : ""}#${false}`
126
- )}`;
127
- }
128
- getPathURL(path, useClientPath) {
129
- let pathUrl = this.baseUrl;
130
- if (useClientPath) {
131
- pathUrl = pathUrl.concat("/client");
132
- }
133
- return pathUrl.concat(path);
134
- }
135
- };
136
-
137
- // src/index.ts
138
- var client = {
139
- __instance: null,
140
- init(options) {
141
- this.__instance = new Courier(options);
142
- },
143
- get instance() {
144
- if (!this.__instance) {
145
- throw new Error("Courier instance not initialized");
146
- }
147
- return this.__instance;
148
- },
149
- async identify(userId, payload) {
150
- if (!userId) {
151
- throw new Error("userId is required");
152
- }
153
- await this.instance.post(`/identify/${userId}`, {
154
- profile: {
155
- ...payload
156
- }
157
- });
158
- },
159
- async subscribe(userId, listId) {
160
- if (!userId || !listId) {
161
- throw new Error("userId is required");
162
- }
163
- await this.instance.put(`/lists/${listId}/subscribe/${userId}`);
164
- },
165
- async track(event, properties) {
166
- if (!event) {
167
- throw new Error("event is required");
168
- }
169
- let indempotentKey = self.crypto.randomUUID ? self.crypto.randomUUID() : Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
170
- await this.instance.post(`/inbound/courier`, {
171
- messageId: indempotentKey,
172
- type: "track",
173
- event,
174
- properties: { ...properties }
175
- }, false);
176
- },
177
- async unsubscribe(userId, listId) {
178
- if (!userId || !listId) {
179
- throw new Error("userId is required");
180
- }
181
- this.instance.delete(`/lists/${listId}/unsubscribe/${userId}`);
182
- },
183
- generatePreferencesUrl(userId, options) {
184
- return this.instance.generatePreferencesUrl(userId, options);
185
- }
186
- };
187
- var src_default = client;
188
- // Annotate the CommonJS export names for ESM import in node:
189
- 0 && (module.exports = {});
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 o=n;const i=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 o=await fetch(n);if(204===o.status)return;let i;try{i=await o.json()}catch(r){if(200===o.status)return;throw new c(o.status,"Failed to parse response as JSON","PARSE_ERROR")}if(s&&h(t.options.logger,s,"HTTP",{status:o.status,response:i}),!e.includes(o.status))throw new c(o.status,(null==i?void 0:i.message)||"Unknown Error",null==i?void 0:i.type);return i}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(o){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.urls.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 o{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,o;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 o=JSON.parse(t);null==(s=this.receivedMessage)||s.call(this,o)}}catch(i){null==(n=this.options.logger)||n.error("Error parsing socket message",i),i instanceof Error&&(null==(o=this.onError)||o.call(this,i))}}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.urls.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.urls.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.urls.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.urls.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.urls.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.urls.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.urls.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.urls.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.urls.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.urls.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.urls.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.urls.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.urls.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.urls.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.urls.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.urls.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.urls.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 o=void 0!==t.showLogs?t.showLogs:"development"===process.env.NODE_ENV,a={...t,showLogs:o,apiUrls:t.apiUrls||i(),accessToken:t.jwt??t.publicApiKey};super({...a,logger:new r(a.showLogs),urls:i(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=o,t.InboxClient=I,t.ListClient=w,t.PreferenceClient=v,t.TokenClient=y,Object.defineProperty(t,Symbol.toStringTag,{value:"Module"})}));