@trycourier/courier-js 1.3.0 → 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.
- package/dist/__tests__/brand-client.test.d.ts +1 -0
- package/dist/__tests__/courier-client.test.d.ts +1 -0
- package/dist/__tests__/inbox-client.test.d.ts +1 -0
- package/dist/__tests__/lists-client.test.d.ts +1 -0
- package/dist/__tests__/preferences-client.test.d.ts +1 -0
- package/dist/__tests__/shared-instance.test.d.ts +1 -0
- package/dist/__tests__/token-client.test.d.ts +1 -0
- package/dist/__tests__/tracking-client.test.d.ts +1 -0
- package/dist/__tests__/utils.d.ts +2 -0
- package/dist/client/brand-client.d.ts +10 -0
- package/dist/client/client.d.ts +5 -0
- package/dist/client/courier-client.d.ts +39 -0
- package/dist/client/inbox-client.d.ts +61 -0
- package/dist/client/list-client.d.ts +17 -0
- package/dist/client/preference-client.d.ts +37 -0
- package/dist/client/token-client.d.ts +19 -0
- package/dist/client/tracking-client.d.ts +24 -0
- package/dist/index.d.ts +19 -39
- package/dist/index.js +1 -189
- package/dist/index.mjs +981 -133
- package/dist/jest.setup.d.ts +0 -0
- package/dist/shared/authentication-listener.d.ts +9 -0
- package/dist/shared/courier.d.ts +68 -0
- package/dist/socket/courier-socket.d.ts +24 -0
- package/dist/socket/inbox-socket.d.ts +19 -0
- package/dist/types/brands.d.ts +36 -0
- package/dist/types/courier-api-urls.d.ts +11 -0
- package/dist/types/inbox.d.ts +43 -0
- package/dist/types/pagination.d.ts +4 -0
- package/dist/types/preference.d.ts +37 -0
- package/dist/types/token.d.ts +12 -0
- package/dist/types/tracking-event.d.ts +1 -0
- package/dist/utils/coding.d.ts +2 -0
- package/dist/utils/logger.d.ts +10 -0
- package/dist/utils/request.d.ts +21 -0
- package/dist/utils/uuid.d.ts +3 -0
- package/package.json +30 -21
- package/README.md +0 -123
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,660 @@
|
|
|
1
|
-
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
|
+
const _CourierSocket = class _CourierSocket {
|
|
5
|
+
constructor(url, options) {
|
|
6
|
+
// Properties
|
|
7
|
+
__publicField(this, "webSocket", null);
|
|
8
|
+
__publicField(this, "pingInterval", null);
|
|
9
|
+
// Callbacks
|
|
10
|
+
__publicField(this, "onOpen");
|
|
11
|
+
__publicField(this, "onMessageReceived");
|
|
12
|
+
__publicField(this, "onClose");
|
|
13
|
+
__publicField(this, "onError");
|
|
14
|
+
// Properties
|
|
15
|
+
__publicField(this, "url");
|
|
16
|
+
__publicField(this, "options");
|
|
17
|
+
this.url = url;
|
|
18
|
+
this.options = options;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Dynamically checks if the WebSocket is connected
|
|
22
|
+
*/
|
|
23
|
+
get isConnected() {
|
|
24
|
+
return this.webSocket !== null;
|
|
25
|
+
}
|
|
26
|
+
async connect() {
|
|
27
|
+
this.disconnect();
|
|
28
|
+
return new Promise((resolve, reject) => {
|
|
29
|
+
try {
|
|
30
|
+
this.webSocket = new WebSocket(this.url);
|
|
31
|
+
this.webSocket.onopen = () => {
|
|
32
|
+
var _a;
|
|
33
|
+
(_a = this.onOpen) == null ? void 0 : _a.call(this);
|
|
34
|
+
resolve();
|
|
35
|
+
};
|
|
36
|
+
this.webSocket.onmessage = (event) => {
|
|
37
|
+
var _a;
|
|
38
|
+
(_a = this.onMessageReceived) == null ? void 0 : _a.call(this, event.data);
|
|
39
|
+
};
|
|
40
|
+
this.webSocket.onclose = (event) => {
|
|
41
|
+
var _a;
|
|
42
|
+
this.webSocket = null;
|
|
43
|
+
(_a = this.onClose) == null ? void 0 : _a.call(this, event.code, event.reason);
|
|
44
|
+
};
|
|
45
|
+
this.webSocket.onerror = (event) => {
|
|
46
|
+
var _a;
|
|
47
|
+
this.webSocket = null;
|
|
48
|
+
const error = new Error("Courier Socket connection failed");
|
|
49
|
+
error.originalEvent = event;
|
|
50
|
+
(_a = this.onError) == null ? void 0 : _a.call(this, error);
|
|
51
|
+
reject(error);
|
|
52
|
+
};
|
|
53
|
+
} catch (error) {
|
|
54
|
+
this.webSocket = null;
|
|
55
|
+
reject(error);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
disconnect() {
|
|
60
|
+
this.stopPing();
|
|
61
|
+
if (this.webSocket) {
|
|
62
|
+
this.webSocket.close(_CourierSocket.NORMAL_CLOSURE_STATUS);
|
|
63
|
+
this.webSocket = null;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
async send(message) {
|
|
67
|
+
if (!this.webSocket) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
const json = JSON.stringify(message);
|
|
71
|
+
return this.webSocket.send(json) !== void 0;
|
|
72
|
+
}
|
|
73
|
+
keepAlive(props) {
|
|
74
|
+
this.stopPing();
|
|
75
|
+
this.pingInterval = setInterval(async () => {
|
|
76
|
+
var _a;
|
|
77
|
+
try {
|
|
78
|
+
await this.send({ action: "keepAlive" });
|
|
79
|
+
} catch (error) {
|
|
80
|
+
(_a = this.options.logger) == null ? void 0 : _a.error("Error occurred on Keep Alive:", error);
|
|
81
|
+
}
|
|
82
|
+
}, (props == null ? void 0 : props.intervalInMillis) ?? 3e5);
|
|
83
|
+
}
|
|
84
|
+
stopPing() {
|
|
85
|
+
if (this.pingInterval) {
|
|
86
|
+
clearInterval(this.pingInterval);
|
|
87
|
+
this.pingInterval = null;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
// Constants
|
|
92
|
+
__publicField(_CourierSocket, "NORMAL_CLOSURE_STATUS", 1e3);
|
|
93
|
+
let CourierSocket = _CourierSocket;
|
|
94
|
+
const getCourierApiUrls = (urls) => ({
|
|
95
|
+
courier: {
|
|
96
|
+
rest: (urls == null ? void 0 : urls.courier.rest) || "https://api.courier.com",
|
|
97
|
+
graphql: (urls == null ? void 0 : urls.courier.graphql) || "https://api.courier.com/client/q"
|
|
98
|
+
},
|
|
99
|
+
inbox: {
|
|
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"
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
class Logger {
|
|
105
|
+
constructor(showLogs) {
|
|
106
|
+
__publicField(this, "PREFIX", "[COURIER]");
|
|
107
|
+
this.showLogs = showLogs;
|
|
108
|
+
}
|
|
109
|
+
warn(message, ...args) {
|
|
110
|
+
if (this.showLogs) {
|
|
111
|
+
console.warn(`${this.PREFIX} ${message}`, ...args);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
log(message, ...args) {
|
|
115
|
+
if (this.showLogs) {
|
|
116
|
+
console.log(`${this.PREFIX} ${message}`, ...args);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
error(message, ...args) {
|
|
120
|
+
if (this.showLogs) {
|
|
121
|
+
console.error(`${this.PREFIX} ${message}`, ...args);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
debug(message, ...args) {
|
|
125
|
+
if (this.showLogs) {
|
|
126
|
+
console.debug(`${this.PREFIX} ${message}`, ...args);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
info(message, ...args) {
|
|
130
|
+
if (this.showLogs) {
|
|
131
|
+
console.info(`${this.PREFIX} ${message}`, ...args);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
class UUID {
|
|
136
|
+
static generate(prefix) {
|
|
137
|
+
const id = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
|
|
138
|
+
return prefix ? prefix + id : id;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
class CourierRequestError extends Error {
|
|
142
|
+
constructor(code, message, type) {
|
|
143
|
+
super(message);
|
|
144
|
+
this.code = code;
|
|
145
|
+
this.type = type;
|
|
146
|
+
this.name = "CourierRequestError";
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
function logRequest(logger, uid, type, data) {
|
|
150
|
+
logger.log(`
|
|
151
|
+
📡 New Courier ${type} Request: ${uid}
|
|
152
|
+
URL: ${data.url}
|
|
153
|
+
${data.method ? `Method: ${data.method}` : ""}
|
|
154
|
+
${data.query ? `Query: ${data.query}` : ""}
|
|
155
|
+
${data.variables ? `Variables: ${JSON.stringify(data.variables, null, 2)}` : ""}
|
|
156
|
+
Headers: ${JSON.stringify(data.headers, null, 2)}
|
|
157
|
+
Body: ${data.body ? JSON.stringify(data.body, null, 2) : "Empty"}
|
|
158
|
+
`);
|
|
159
|
+
}
|
|
160
|
+
function logResponse(logger, uid, type, data) {
|
|
161
|
+
logger.log(`
|
|
162
|
+
📡 New Courier ${type} Response: ${uid}
|
|
163
|
+
Status Code: ${data.status}
|
|
164
|
+
Response JSON: ${JSON.stringify(data.response, null, 2)}
|
|
165
|
+
`);
|
|
166
|
+
}
|
|
167
|
+
async function http(props) {
|
|
168
|
+
const validCodes = props.validCodes ?? [200];
|
|
169
|
+
const uid = props.options.showLogs ? UUID.generate() : void 0;
|
|
170
|
+
const request = new Request(props.url, {
|
|
171
|
+
method: props.method,
|
|
172
|
+
headers: {
|
|
173
|
+
"Content-Type": "application/json",
|
|
174
|
+
...props.headers
|
|
175
|
+
},
|
|
176
|
+
body: props.body ? JSON.stringify(props.body) : void 0
|
|
177
|
+
});
|
|
178
|
+
if (uid) {
|
|
179
|
+
logRequest(props.options.logger, uid, "HTTP", {
|
|
180
|
+
url: request.url,
|
|
181
|
+
method: request.method,
|
|
182
|
+
headers: Object.fromEntries(request.headers.entries()),
|
|
183
|
+
body: props.body
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
const response = await fetch(request);
|
|
187
|
+
if (response.status === 204) {
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
let data;
|
|
191
|
+
try {
|
|
192
|
+
data = await response.json();
|
|
193
|
+
} catch (error) {
|
|
194
|
+
if (response.status === 200) {
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
throw new CourierRequestError(
|
|
198
|
+
response.status,
|
|
199
|
+
"Failed to parse response as JSON",
|
|
200
|
+
"PARSE_ERROR"
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
if (uid) {
|
|
204
|
+
logResponse(props.options.logger, uid, "HTTP", {
|
|
205
|
+
status: response.status,
|
|
206
|
+
response: data
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
if (!validCodes.includes(response.status)) {
|
|
210
|
+
throw new CourierRequestError(
|
|
211
|
+
response.status,
|
|
212
|
+
(data == null ? void 0 : data.message) || "Unknown Error",
|
|
213
|
+
data == null ? void 0 : data.type
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
return data;
|
|
217
|
+
}
|
|
218
|
+
async function graphql(props) {
|
|
219
|
+
const uid = props.options.showLogs ? UUID.generate() : void 0;
|
|
220
|
+
if (uid) {
|
|
221
|
+
logRequest(props.options.logger, uid, "GraphQL", {
|
|
222
|
+
url: props.url,
|
|
223
|
+
headers: props.headers,
|
|
224
|
+
query: props.query,
|
|
225
|
+
variables: props.variables
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
const response = await fetch(props.url, {
|
|
229
|
+
method: "POST",
|
|
230
|
+
headers: {
|
|
231
|
+
"Content-Type": "application/json",
|
|
232
|
+
...props.headers
|
|
233
|
+
},
|
|
234
|
+
body: JSON.stringify({
|
|
235
|
+
query: props.query,
|
|
236
|
+
variables: props.variables
|
|
237
|
+
})
|
|
238
|
+
});
|
|
239
|
+
let data;
|
|
240
|
+
try {
|
|
241
|
+
data = await response.json();
|
|
242
|
+
} catch (error) {
|
|
243
|
+
throw new CourierRequestError(
|
|
244
|
+
response.status,
|
|
245
|
+
"Failed to parse response as JSON",
|
|
246
|
+
"PARSE_ERROR"
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
if (uid) {
|
|
250
|
+
logResponse(props.options.logger, uid, "GraphQL", {
|
|
251
|
+
status: response.status,
|
|
252
|
+
response: data
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
if (!response.ok) {
|
|
256
|
+
throw new CourierRequestError(
|
|
257
|
+
response.status,
|
|
258
|
+
(data == null ? void 0 : data.message) || "Unknown Error",
|
|
259
|
+
data == null ? void 0 : data.type
|
|
260
|
+
);
|
|
261
|
+
}
|
|
262
|
+
return data;
|
|
263
|
+
}
|
|
264
|
+
class Client {
|
|
265
|
+
constructor(options) {
|
|
266
|
+
this.options = options;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
class BrandClient extends Client {
|
|
270
|
+
/**
|
|
271
|
+
* Get a brand by ID using GraphQL
|
|
272
|
+
*/
|
|
273
|
+
async getBrand(props) {
|
|
274
|
+
const query = `
|
|
275
|
+
query GetBrand {
|
|
276
|
+
brand(brandId: "${props.brandId}") {
|
|
277
|
+
settings {
|
|
278
|
+
colors {
|
|
279
|
+
primary
|
|
280
|
+
secondary
|
|
281
|
+
tertiary
|
|
282
|
+
}
|
|
283
|
+
inapp {
|
|
284
|
+
borderRadius
|
|
285
|
+
disableCourierFooter
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
`;
|
|
291
|
+
const json = await graphql({
|
|
292
|
+
options: this.options,
|
|
293
|
+
url: this.options.urls.courier.graphql,
|
|
294
|
+
headers: {
|
|
295
|
+
"x-courier-user-id": this.options.userId,
|
|
296
|
+
"x-courier-client-key": "empty",
|
|
297
|
+
// Empty for now. Will be removed in future.
|
|
298
|
+
"Authorization": `Bearer ${this.options.accessToken}`
|
|
299
|
+
},
|
|
300
|
+
query,
|
|
301
|
+
variables: { brandId: props.brandId }
|
|
302
|
+
});
|
|
303
|
+
return json.data.brand;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
class InboxSocket extends CourierSocket {
|
|
307
|
+
constructor(options) {
|
|
308
|
+
const url = InboxSocket.buildUrl(options);
|
|
309
|
+
super(url, options);
|
|
310
|
+
__publicField(this, "receivedMessage");
|
|
311
|
+
__publicField(this, "receivedMessageEvent");
|
|
312
|
+
this.onMessageReceived = (data) => this.convertToType(data);
|
|
313
|
+
}
|
|
314
|
+
convertToType(data) {
|
|
315
|
+
var _a, _b, _c, _d;
|
|
316
|
+
try {
|
|
317
|
+
const payload = JSON.parse(data);
|
|
318
|
+
switch (payload.type) {
|
|
319
|
+
case "event":
|
|
320
|
+
const messageEvent = JSON.parse(data);
|
|
321
|
+
(_a = this.receivedMessageEvent) == null ? void 0 : _a.call(this, messageEvent);
|
|
322
|
+
break;
|
|
323
|
+
case "message":
|
|
324
|
+
const message = JSON.parse(data);
|
|
325
|
+
(_b = this.receivedMessage) == null ? void 0 : _b.call(this, message);
|
|
326
|
+
break;
|
|
327
|
+
}
|
|
328
|
+
} catch (error) {
|
|
329
|
+
(_c = this.options.logger) == null ? void 0 : _c.error("Error parsing socket message", error);
|
|
330
|
+
if (error instanceof Error) {
|
|
331
|
+
(_d = this.onError) == null ? void 0 : _d.call(this, error);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
async sendSubscribe(props) {
|
|
336
|
+
var _a;
|
|
337
|
+
const subscription = {
|
|
338
|
+
action: "subscribe",
|
|
339
|
+
data: {
|
|
340
|
+
userAgent: "courier-js",
|
|
341
|
+
// TODO: Equivalent to Courier.agent.value()
|
|
342
|
+
channel: this.options.userId,
|
|
343
|
+
event: "*",
|
|
344
|
+
version: (props == null ? void 0 : props.version) ?? 5
|
|
345
|
+
}
|
|
346
|
+
};
|
|
347
|
+
if (this.options.connectionId) {
|
|
348
|
+
subscription.data.clientSourceId = this.options.connectionId;
|
|
349
|
+
}
|
|
350
|
+
if (this.options.tenantId) {
|
|
351
|
+
subscription.data.accountId = this.options.tenantId;
|
|
352
|
+
}
|
|
353
|
+
(_a = this.options.logger) == null ? void 0 : _a.debug("Sending subscribe request", subscription);
|
|
354
|
+
await this.send(subscription);
|
|
355
|
+
}
|
|
356
|
+
static buildUrl(options) {
|
|
357
|
+
var _a;
|
|
358
|
+
let url = ((_a = options.apiUrls) == null ? void 0 : _a.inbox.webSocket) ?? "";
|
|
359
|
+
if (options.accessToken) {
|
|
360
|
+
url += `/?auth=${options.accessToken}`;
|
|
361
|
+
}
|
|
362
|
+
return url;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
class InboxClient extends Client {
|
|
366
|
+
constructor(options) {
|
|
367
|
+
super(options);
|
|
368
|
+
__publicField(this, "socket");
|
|
369
|
+
this.socket = new InboxSocket(options);
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Get paginated messages
|
|
373
|
+
*/
|
|
374
|
+
async getMessages(props) {
|
|
375
|
+
const query = `
|
|
376
|
+
query GetInboxMessages(
|
|
377
|
+
$params: FilterParamsInput = { ${this.options.tenantId ? `accountId: "${this.options.tenantId}"` : ""} }
|
|
378
|
+
$limit: Int = ${(props == null ? void 0 : props.paginationLimit) ?? 24}
|
|
379
|
+
$after: String ${(props == null ? void 0 : props.startCursor) ? `= "${props.startCursor}"` : ""}
|
|
380
|
+
) {
|
|
381
|
+
count(params: $params)
|
|
382
|
+
messages(params: $params, limit: $limit, after: $after) {
|
|
383
|
+
totalCount
|
|
384
|
+
pageInfo {
|
|
385
|
+
startCursor
|
|
386
|
+
hasNextPage
|
|
387
|
+
}
|
|
388
|
+
nodes {
|
|
389
|
+
messageId
|
|
390
|
+
read
|
|
391
|
+
archived
|
|
392
|
+
created
|
|
393
|
+
opened
|
|
394
|
+
title
|
|
395
|
+
preview
|
|
396
|
+
data
|
|
397
|
+
tags
|
|
398
|
+
trackingIds {
|
|
399
|
+
clickTrackingId
|
|
400
|
+
}
|
|
401
|
+
actions {
|
|
402
|
+
content
|
|
403
|
+
data
|
|
404
|
+
href
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
`;
|
|
410
|
+
return await graphql({
|
|
411
|
+
options: this.options,
|
|
412
|
+
query,
|
|
413
|
+
headers: {
|
|
414
|
+
"x-courier-user-id": this.options.userId,
|
|
415
|
+
"Authorization": `Bearer ${this.options.accessToken}`
|
|
416
|
+
},
|
|
417
|
+
url: this.options.urls.inbox.graphql
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* Get paginated archived messages
|
|
422
|
+
*/
|
|
423
|
+
async getArchivedMessages(props) {
|
|
424
|
+
const query = `
|
|
425
|
+
query GetInboxMessages(
|
|
426
|
+
$params: FilterParamsInput = { ${this.options.tenantId ? `accountId: "${this.options.tenantId}"` : ""}, archived: true }
|
|
427
|
+
$limit: Int = ${(props == null ? void 0 : props.paginationLimit) ?? 24}
|
|
428
|
+
$after: String ${(props == null ? void 0 : props.startCursor) ? `= "${props.startCursor}"` : ""}
|
|
429
|
+
) {
|
|
430
|
+
count(params: $params)
|
|
431
|
+
messages(params: $params, limit: $limit, after: $after) {
|
|
432
|
+
totalCount
|
|
433
|
+
pageInfo {
|
|
434
|
+
startCursor
|
|
435
|
+
hasNextPage
|
|
436
|
+
}
|
|
437
|
+
nodes {
|
|
438
|
+
messageId
|
|
439
|
+
read
|
|
440
|
+
archived
|
|
441
|
+
created
|
|
442
|
+
opened
|
|
443
|
+
title
|
|
444
|
+
preview
|
|
445
|
+
data
|
|
446
|
+
tags
|
|
447
|
+
trackingIds {
|
|
448
|
+
clickTrackingId
|
|
449
|
+
}
|
|
450
|
+
actions {
|
|
451
|
+
content
|
|
452
|
+
data
|
|
453
|
+
href
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
`;
|
|
459
|
+
return graphql({
|
|
460
|
+
options: this.options,
|
|
461
|
+
query,
|
|
462
|
+
headers: {
|
|
463
|
+
"x-courier-user-id": this.options.userId,
|
|
464
|
+
"Authorization": `Bearer ${this.options.accessToken}`
|
|
465
|
+
},
|
|
466
|
+
url: this.options.urls.inbox.graphql
|
|
467
|
+
});
|
|
468
|
+
}
|
|
469
|
+
/**
|
|
470
|
+
* Get unread message count
|
|
471
|
+
*/
|
|
472
|
+
async getUnreadMessageCount() {
|
|
473
|
+
var _a;
|
|
474
|
+
const query = `
|
|
475
|
+
query GetMessages {
|
|
476
|
+
count(params: { status: "unread" ${this.options.tenantId ? `, accountId: "${this.options.tenantId}"` : ""} })
|
|
477
|
+
}
|
|
478
|
+
`;
|
|
479
|
+
const response = await graphql({
|
|
480
|
+
options: this.options,
|
|
481
|
+
query,
|
|
482
|
+
headers: {
|
|
483
|
+
"x-courier-user-id": this.options.userId,
|
|
484
|
+
"Authorization": `Bearer ${this.options.accessToken}`
|
|
485
|
+
},
|
|
486
|
+
url: this.options.urls.inbox.graphql
|
|
487
|
+
});
|
|
488
|
+
return ((_a = response.data) == null ? void 0 : _a.count) ?? 0;
|
|
489
|
+
}
|
|
490
|
+
/**
|
|
491
|
+
* Track a click event
|
|
492
|
+
*/
|
|
493
|
+
async click(props) {
|
|
494
|
+
const query = `
|
|
495
|
+
mutation TrackEvent {
|
|
496
|
+
clicked(messageId: "${props.messageId}", trackingId: "${props.trackingId}")
|
|
497
|
+
}
|
|
498
|
+
`;
|
|
499
|
+
const headers = {
|
|
500
|
+
"x-courier-user-id": this.options.userId,
|
|
501
|
+
"Authorization": `Bearer ${this.options.accessToken}`
|
|
502
|
+
};
|
|
503
|
+
if (this.options.connectionId) {
|
|
504
|
+
headers["x-courier-client-source-id"] = this.options.connectionId;
|
|
505
|
+
}
|
|
506
|
+
await graphql({
|
|
507
|
+
options: this.options,
|
|
508
|
+
query,
|
|
509
|
+
headers,
|
|
510
|
+
url: this.options.urls.inbox.graphql
|
|
511
|
+
});
|
|
512
|
+
}
|
|
513
|
+
/**
|
|
514
|
+
* Mark a message as read
|
|
515
|
+
*/
|
|
516
|
+
async read(props) {
|
|
517
|
+
const query = `
|
|
518
|
+
mutation TrackEvent {
|
|
519
|
+
read(messageId: "${props.messageId}")
|
|
520
|
+
}
|
|
521
|
+
`;
|
|
522
|
+
const headers = {
|
|
523
|
+
"x-courier-user-id": this.options.userId,
|
|
524
|
+
"Authorization": `Bearer ${this.options.accessToken}`
|
|
525
|
+
};
|
|
526
|
+
if (this.options.connectionId) {
|
|
527
|
+
headers["x-courier-client-source-id"] = this.options.connectionId;
|
|
528
|
+
}
|
|
529
|
+
await graphql({
|
|
530
|
+
options: this.options,
|
|
531
|
+
query,
|
|
532
|
+
headers,
|
|
533
|
+
url: this.options.urls.inbox.graphql
|
|
534
|
+
});
|
|
535
|
+
}
|
|
536
|
+
/**
|
|
537
|
+
* Mark a message as unread
|
|
538
|
+
*/
|
|
539
|
+
async unread(props) {
|
|
540
|
+
const query = `
|
|
541
|
+
mutation TrackEvent {
|
|
542
|
+
unread(messageId: "${props.messageId}")
|
|
543
|
+
}
|
|
544
|
+
`;
|
|
545
|
+
const headers = {
|
|
546
|
+
"x-courier-user-id": this.options.userId,
|
|
547
|
+
"Authorization": `Bearer ${this.options.accessToken}`
|
|
548
|
+
};
|
|
549
|
+
if (this.options.connectionId) {
|
|
550
|
+
headers["x-courier-client-source-id"] = this.options.connectionId;
|
|
551
|
+
}
|
|
552
|
+
await graphql({
|
|
553
|
+
options: this.options,
|
|
554
|
+
query,
|
|
555
|
+
headers,
|
|
556
|
+
url: this.options.urls.inbox.graphql
|
|
557
|
+
});
|
|
558
|
+
}
|
|
559
|
+
/**
|
|
560
|
+
* Mark all messages as read
|
|
561
|
+
*/
|
|
562
|
+
async readAll() {
|
|
563
|
+
const query = `
|
|
564
|
+
mutation TrackEvent {
|
|
565
|
+
markAllRead
|
|
566
|
+
}
|
|
567
|
+
`;
|
|
568
|
+
const headers = {
|
|
569
|
+
"x-courier-user-id": this.options.userId,
|
|
570
|
+
"Authorization": `Bearer ${this.options.accessToken}`
|
|
571
|
+
};
|
|
572
|
+
if (this.options.connectionId) {
|
|
573
|
+
headers["x-courier-client-source-id"] = this.options.connectionId;
|
|
574
|
+
}
|
|
575
|
+
await graphql({
|
|
576
|
+
options: this.options,
|
|
577
|
+
query,
|
|
578
|
+
headers,
|
|
579
|
+
url: this.options.urls.inbox.graphql
|
|
580
|
+
});
|
|
581
|
+
}
|
|
582
|
+
/**
|
|
583
|
+
* Mark a message as opened
|
|
584
|
+
*/
|
|
585
|
+
async open(props) {
|
|
586
|
+
const query = `
|
|
587
|
+
mutation TrackEvent {
|
|
588
|
+
opened(messageId: "${props.messageId}")
|
|
589
|
+
}
|
|
590
|
+
`;
|
|
591
|
+
const headers = {
|
|
592
|
+
"x-courier-user-id": this.options.userId,
|
|
593
|
+
"Authorization": `Bearer ${this.options.accessToken}`
|
|
594
|
+
};
|
|
595
|
+
if (this.options.connectionId) {
|
|
596
|
+
headers["x-courier-client-source-id"] = this.options.connectionId;
|
|
597
|
+
}
|
|
598
|
+
await graphql({
|
|
599
|
+
options: this.options,
|
|
600
|
+
query,
|
|
601
|
+
headers,
|
|
602
|
+
url: this.options.urls.inbox.graphql
|
|
603
|
+
});
|
|
604
|
+
}
|
|
605
|
+
/**
|
|
606
|
+
* Archive a message
|
|
607
|
+
*/
|
|
608
|
+
async archive(props) {
|
|
609
|
+
const query = `
|
|
610
|
+
mutation TrackEvent {
|
|
611
|
+
archive(messageId: "${props.messageId}")
|
|
612
|
+
}
|
|
613
|
+
`;
|
|
614
|
+
const headers = {
|
|
615
|
+
"x-courier-user-id": this.options.userId,
|
|
616
|
+
"Authorization": `Bearer ${this.options.accessToken}`
|
|
617
|
+
};
|
|
618
|
+
if (this.options.connectionId) {
|
|
619
|
+
headers["x-courier-client-source-id"] = this.options.connectionId;
|
|
620
|
+
}
|
|
621
|
+
await graphql({
|
|
622
|
+
options: this.options,
|
|
623
|
+
query,
|
|
624
|
+
headers,
|
|
625
|
+
url: this.options.urls.inbox.graphql
|
|
626
|
+
});
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
class PreferenceTransformer {
|
|
630
|
+
/**
|
|
631
|
+
* Transforms a single API response item to the CourierUserPreferencesTopic type
|
|
632
|
+
* @param item - The API response item
|
|
633
|
+
* @returns A CourierUserPreferencesTopic object
|
|
634
|
+
*/
|
|
635
|
+
transformItem(item) {
|
|
636
|
+
return {
|
|
637
|
+
topicId: item.topic_id,
|
|
638
|
+
topicName: item.topic_name,
|
|
639
|
+
sectionId: item.section_id,
|
|
640
|
+
sectionName: item.section_name,
|
|
641
|
+
status: item.status,
|
|
642
|
+
defaultStatus: item.default_status,
|
|
643
|
+
hasCustomRouting: item.has_custom_routing,
|
|
644
|
+
customRouting: item.custom_routing || []
|
|
645
|
+
};
|
|
646
|
+
}
|
|
647
|
+
/**
|
|
648
|
+
* Transforms an array of API response items to CourierUserPreferencesTopic objects
|
|
649
|
+
* @param items - The API response items
|
|
650
|
+
* @returns A generator of CourierUserPreferencesTopic objects
|
|
651
|
+
*/
|
|
652
|
+
*transform(items) {
|
|
653
|
+
for (const item of items) {
|
|
654
|
+
yield this.transformItem(item);
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
}
|
|
5
658
|
function decode(clientKey) {
|
|
6
659
|
const binaryString = atob(clientKey);
|
|
7
660
|
const bytes = new Uint8Array(binaryString.length);
|
|
@@ -17,148 +670,343 @@ function encode(key) {
|
|
|
17
670
|
}
|
|
18
671
|
return btoa(String.fromCharCode(...bytes));
|
|
19
672
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const response = await fn();
|
|
25
|
-
if (!response.ok && debug) {
|
|
26
|
-
console.error(
|
|
27
|
-
`Error invoking ${response.url}: ${(_a = response.status) != null ? _a : 404} because ${JSON.stringify((_b = await response.json()) == null ? void 0 : _b.message)}`
|
|
28
|
-
);
|
|
673
|
+
class PreferenceClient extends Client {
|
|
674
|
+
constructor() {
|
|
675
|
+
super(...arguments);
|
|
676
|
+
__publicField(this, "transformer", new PreferenceTransformer());
|
|
29
677
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
this.debug = debug;
|
|
47
|
-
this.userId = userId;
|
|
48
|
-
this.userSignature = userSignature;
|
|
49
|
-
}
|
|
50
|
-
getHeaders() {
|
|
51
|
-
return new Headers({
|
|
52
|
-
"Content-Type": "application/json",
|
|
53
|
-
"x-courier-client-version": `courier-js@${version}`,
|
|
54
|
-
"Access-Control-Allow-Origin": "*",
|
|
55
|
-
...this.authorization && { Authorization: this.authorization },
|
|
56
|
-
...this.userId && { "x-courier-user-id": this.userId },
|
|
57
|
-
...this.userSignature && {
|
|
58
|
-
"x-courier-user-signature": this.userSignature
|
|
59
|
-
},
|
|
60
|
-
...this.clientKey && { "x-courier-client-key": this.clientKey }
|
|
678
|
+
/**
|
|
679
|
+
* Get all preferences for a user
|
|
680
|
+
* @see https://www.courier.com/docs/reference/user-preferences/list-all-user-preferences
|
|
681
|
+
*/
|
|
682
|
+
async getUserPreferences(params) {
|
|
683
|
+
let url = `${this.options.urls.courier.rest}/users/${this.options.userId}/preferences`;
|
|
684
|
+
if (params == null ? void 0 : params.paginationCursor) {
|
|
685
|
+
url += `?cursor=${params.paginationCursor}`;
|
|
686
|
+
}
|
|
687
|
+
const json = await http({
|
|
688
|
+
options: this.options,
|
|
689
|
+
url,
|
|
690
|
+
method: "GET",
|
|
691
|
+
headers: {
|
|
692
|
+
"Authorization": `Bearer ${this.options.accessToken}`
|
|
693
|
+
}
|
|
61
694
|
});
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
body: JSON.stringify(body),
|
|
67
|
-
headers: this.getHeaders(),
|
|
68
|
-
method: "POST"
|
|
69
|
-
});
|
|
695
|
+
const data = json;
|
|
696
|
+
return {
|
|
697
|
+
items: [...this.transformer.transform(data.items)],
|
|
698
|
+
paging: data.paging
|
|
70
699
|
};
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
}
|
|
700
|
+
}
|
|
701
|
+
/**
|
|
702
|
+
* Get preferences for a specific topic
|
|
703
|
+
* @see https://www.courier.com/docs/reference/user-preferences/get-subscription-topic-preferences
|
|
704
|
+
*/
|
|
705
|
+
async getUserPreferenceTopic(params) {
|
|
706
|
+
const json = await http({
|
|
707
|
+
options: this.options,
|
|
708
|
+
url: `${this.options.urls.courier.rest}/users/${this.options.userId}/preferences/${params.topicId}`,
|
|
709
|
+
method: "GET",
|
|
710
|
+
headers: {
|
|
711
|
+
"Authorization": `Bearer ${this.options.accessToken}`
|
|
712
|
+
}
|
|
713
|
+
});
|
|
714
|
+
const res = json;
|
|
715
|
+
return this.transformer.transformItem(res.topic);
|
|
716
|
+
}
|
|
717
|
+
/**
|
|
718
|
+
* Update preferences for a specific topic
|
|
719
|
+
* @see https://www.courier.com/docs/reference/user-preferences/update-subscription-topic-preferences
|
|
720
|
+
*/
|
|
721
|
+
async putUserPreferenceTopic(params) {
|
|
722
|
+
const payload = {
|
|
723
|
+
topic: {
|
|
724
|
+
status: params.status,
|
|
725
|
+
has_custom_routing: params.hasCustomRouting,
|
|
726
|
+
custom_routing: params.customRouting
|
|
727
|
+
}
|
|
80
728
|
};
|
|
81
|
-
await
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
729
|
+
await http({
|
|
730
|
+
options: this.options,
|
|
731
|
+
url: `${this.options.urls.courier.rest}/users/${this.options.userId}/preferences/${params.topicId}`,
|
|
732
|
+
method: "PUT",
|
|
733
|
+
headers: {
|
|
734
|
+
"Authorization": `Bearer ${this.options.accessToken}`
|
|
735
|
+
},
|
|
736
|
+
body: payload
|
|
737
|
+
});
|
|
738
|
+
}
|
|
739
|
+
/**
|
|
740
|
+
* Get the notification center URL
|
|
741
|
+
* @param params
|
|
742
|
+
* @returns
|
|
743
|
+
*/
|
|
744
|
+
getNotificationCenterUrl(params) {
|
|
745
|
+
const rootTenantId = decode(params.clientKey);
|
|
746
|
+
const url = encode(`${rootTenantId}#${this.options.userId}${this.options.tenantId ? `#${this.options.tenantId}` : ""}#${false}`);
|
|
747
|
+
return `https://view.notificationcenter.app/p/${url}`;
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
class TokenClient extends Client {
|
|
751
|
+
/**
|
|
752
|
+
* Store a push notification token for a user
|
|
753
|
+
* @see https://www.courier.com/docs/reference/token-management/put-token
|
|
754
|
+
*/
|
|
755
|
+
async putUserToken(props) {
|
|
756
|
+
const payload = {
|
|
757
|
+
provider_key: props.provider,
|
|
758
|
+
...props.device && {
|
|
759
|
+
device: {
|
|
760
|
+
app_id: props.device.appId,
|
|
761
|
+
ad_id: props.device.adId,
|
|
762
|
+
device_id: props.device.deviceId,
|
|
763
|
+
platform: props.device.platform,
|
|
764
|
+
manufacturer: props.device.manufacturer,
|
|
765
|
+
model: props.device.model
|
|
766
|
+
}
|
|
767
|
+
}
|
|
89
768
|
};
|
|
90
|
-
await
|
|
769
|
+
await http({
|
|
770
|
+
options: this.options,
|
|
771
|
+
url: `${this.options.urls.courier.rest}/users/${this.options.userId}/tokens/${props.token}`,
|
|
772
|
+
method: "PUT",
|
|
773
|
+
headers: {
|
|
774
|
+
"Authorization": `Bearer ${this.options.accessToken}`
|
|
775
|
+
},
|
|
776
|
+
body: payload,
|
|
777
|
+
validCodes: [200, 204]
|
|
778
|
+
});
|
|
91
779
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
780
|
+
/**
|
|
781
|
+
* Delete a push notification token for a user
|
|
782
|
+
*/
|
|
783
|
+
async deleteUserToken(props) {
|
|
784
|
+
await http({
|
|
785
|
+
options: this.options,
|
|
786
|
+
url: `${this.options.urls.courier.rest}/users/${this.options.userId}/tokens/${props.token}`,
|
|
787
|
+
method: "DELETE",
|
|
788
|
+
headers: {
|
|
789
|
+
"Authorization": `Bearer ${this.options.accessToken}`
|
|
790
|
+
},
|
|
791
|
+
validCodes: [200, 204]
|
|
792
|
+
});
|
|
101
793
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
794
|
+
}
|
|
795
|
+
class ListClient extends Client {
|
|
796
|
+
/**
|
|
797
|
+
* Subscribe a user to a list
|
|
798
|
+
* @see https://www.courier.com/docs/reference/lists/recipient-subscribe
|
|
799
|
+
*/
|
|
800
|
+
async putSubscription(props) {
|
|
801
|
+
return await http({
|
|
802
|
+
url: `${this.options.urls.courier.rest}/lists/${props.listId}/subscriptions/${this.options.userId}`,
|
|
803
|
+
options: this.options,
|
|
804
|
+
method: "PUT",
|
|
805
|
+
headers: {
|
|
806
|
+
Authorization: `Bearer ${this.options.accessToken}`
|
|
807
|
+
}
|
|
808
|
+
});
|
|
108
809
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
}
|
|
121
|
-
return this.__instance;
|
|
122
|
-
},
|
|
123
|
-
async identify(userId, payload) {
|
|
124
|
-
if (!userId) {
|
|
125
|
-
throw new Error("userId is required");
|
|
126
|
-
}
|
|
127
|
-
await this.instance.post(`/identify/${userId}`, {
|
|
128
|
-
profile: {
|
|
129
|
-
...payload
|
|
810
|
+
/**
|
|
811
|
+
* Unsubscribe a user from a list
|
|
812
|
+
* @see https://www.courier.com/docs/reference/lists/delete-subscription
|
|
813
|
+
*/
|
|
814
|
+
async deleteSubscription(props) {
|
|
815
|
+
return await http({
|
|
816
|
+
url: `${this.options.urls.courier.rest}/lists/${props.listId}/subscriptions/${this.options.userId}`,
|
|
817
|
+
options: this.options,
|
|
818
|
+
method: "DELETE",
|
|
819
|
+
headers: {
|
|
820
|
+
Authorization: `Bearer ${this.options.accessToken}`
|
|
130
821
|
}
|
|
131
822
|
});
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
class TrackingClient extends Client {
|
|
826
|
+
/**
|
|
827
|
+
* Post an inbound courier event
|
|
828
|
+
* @see https://www.courier.com/docs/reference/inbound/courier-track-event
|
|
829
|
+
*/
|
|
830
|
+
async postInboundCourier(props) {
|
|
831
|
+
return await http({
|
|
832
|
+
url: `${this.options.urls.courier.rest}/inbound/courier`,
|
|
833
|
+
options: this.options,
|
|
834
|
+
method: "POST",
|
|
835
|
+
headers: {
|
|
836
|
+
Authorization: `Bearer ${this.options.accessToken}`
|
|
837
|
+
},
|
|
838
|
+
body: {
|
|
839
|
+
...props,
|
|
840
|
+
userId: this.options.userId
|
|
841
|
+
},
|
|
842
|
+
validCodes: [200, 202]
|
|
843
|
+
});
|
|
844
|
+
}
|
|
845
|
+
/**
|
|
846
|
+
* Post a tracking URL event
|
|
847
|
+
* These urls are found in messages sent from Courier
|
|
848
|
+
*/
|
|
849
|
+
async postTrackingUrl(props) {
|
|
850
|
+
return await http({
|
|
851
|
+
url: props.url,
|
|
852
|
+
options: this.options,
|
|
853
|
+
method: "POST",
|
|
854
|
+
body: {
|
|
855
|
+
event: props.event
|
|
856
|
+
}
|
|
857
|
+
});
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
class CourierClient extends Client {
|
|
861
|
+
constructor(props) {
|
|
862
|
+
var _a, _b;
|
|
863
|
+
const showLogs = props.showLogs !== void 0 ? props.showLogs : process.env.NODE_ENV === "development";
|
|
864
|
+
const baseOptions = {
|
|
865
|
+
...props,
|
|
866
|
+
showLogs,
|
|
867
|
+
apiUrls: props.apiUrls || getCourierApiUrls(),
|
|
868
|
+
accessToken: props.jwt ?? props.publicApiKey
|
|
869
|
+
};
|
|
870
|
+
super({
|
|
871
|
+
...baseOptions,
|
|
872
|
+
logger: new Logger(baseOptions.showLogs),
|
|
873
|
+
urls: getCourierApiUrls(baseOptions.apiUrls)
|
|
874
|
+
});
|
|
875
|
+
__publicField(this, "tokens");
|
|
876
|
+
__publicField(this, "brands");
|
|
877
|
+
__publicField(this, "preferences");
|
|
878
|
+
__publicField(this, "inbox");
|
|
879
|
+
__publicField(this, "lists");
|
|
880
|
+
__publicField(this, "tracking");
|
|
881
|
+
this.tokens = new TokenClient(this.options);
|
|
882
|
+
this.brands = new BrandClient(this.options);
|
|
883
|
+
this.preferences = new PreferenceClient(this.options);
|
|
884
|
+
this.inbox = new InboxClient(this.options);
|
|
885
|
+
this.lists = new ListClient(this.options);
|
|
886
|
+
this.tracking = new TrackingClient(this.options);
|
|
887
|
+
if (!this.options.jwt && !this.options.publicApiKey) {
|
|
888
|
+
this.options.logger.warn("Courier Client initialized with no authentication method. Please provide a JWT or public API key.");
|
|
136
889
|
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
throw new Error("event is required");
|
|
142
|
-
}
|
|
143
|
-
let indempotentKey = self.crypto.randomUUID();
|
|
144
|
-
await this.instance.post(`/inbound/courier`, {
|
|
145
|
-
messageId: indempotentKey,
|
|
146
|
-
type: "track",
|
|
147
|
-
event,
|
|
148
|
-
properties: { ...properties }
|
|
149
|
-
}, false);
|
|
150
|
-
},
|
|
151
|
-
async unsubscribe(userId, listId) {
|
|
152
|
-
if (!userId || !listId) {
|
|
153
|
-
throw new Error("userId is required");
|
|
890
|
+
if (this.options.publicApiKey) {
|
|
891
|
+
(_a = this.options.logger) == null ? void 0 : _a.warn(
|
|
892
|
+
"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."
|
|
893
|
+
);
|
|
154
894
|
}
|
|
155
|
-
this.
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
895
|
+
if (this.options.jwt && this.options.publicApiKey) {
|
|
896
|
+
(_b = this.options.logger) == null ? void 0 : _b.warn(
|
|
897
|
+
"Courier Warning: Both a JWT and a Public API Key were provided. The Public API Key will be ignored."
|
|
898
|
+
);
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
class AuthenticationListener {
|
|
903
|
+
constructor(callback) {
|
|
904
|
+
__publicField(this, "callback");
|
|
905
|
+
this.callback = callback;
|
|
906
|
+
}
|
|
907
|
+
remove() {
|
|
908
|
+
Courier.shared.removeAuthenticationListener(this);
|
|
909
|
+
}
|
|
910
|
+
}
|
|
911
|
+
const _Courier = class _Courier {
|
|
912
|
+
constructor() {
|
|
913
|
+
/**
|
|
914
|
+
* The unique identifier for the Courier instance
|
|
915
|
+
*/
|
|
916
|
+
__publicField(this, "id", UUID.generate());
|
|
917
|
+
/**
|
|
918
|
+
* The Courier client instance
|
|
919
|
+
*/
|
|
920
|
+
__publicField(this, "instanceClient");
|
|
921
|
+
/**
|
|
922
|
+
* The pagination limit (min: 1, max: 100)
|
|
923
|
+
*/
|
|
924
|
+
__publicField(this, "_paginationLimit", 24);
|
|
925
|
+
/**
|
|
926
|
+
* The authentication listeners
|
|
927
|
+
*/
|
|
928
|
+
__publicField(this, "authenticationListeners", []);
|
|
929
|
+
}
|
|
930
|
+
get paginationLimit() {
|
|
931
|
+
return this._paginationLimit;
|
|
932
|
+
}
|
|
933
|
+
set paginationLimit(value) {
|
|
934
|
+
this._paginationLimit = Math.min(Math.max(value, 1), 100);
|
|
935
|
+
}
|
|
936
|
+
/**
|
|
937
|
+
* Get the Courier client instance
|
|
938
|
+
* @returns The Courier client instance or undefined if not signed in
|
|
939
|
+
*/
|
|
940
|
+
get client() {
|
|
941
|
+
return this.instanceClient;
|
|
942
|
+
}
|
|
943
|
+
/**
|
|
944
|
+
* Get the shared Courier instance
|
|
945
|
+
* @returns The shared Courier instance
|
|
946
|
+
*/
|
|
947
|
+
static get shared() {
|
|
948
|
+
if (!_Courier.instance) {
|
|
949
|
+
_Courier.instance = new _Courier();
|
|
950
|
+
}
|
|
951
|
+
return _Courier.instance;
|
|
952
|
+
}
|
|
953
|
+
/**
|
|
954
|
+
* Sign in to Courier
|
|
955
|
+
* @param options - The options for the Courier client
|
|
956
|
+
*/
|
|
957
|
+
signIn(props) {
|
|
958
|
+
const connectionId = props.connectionId ?? UUID.generate();
|
|
959
|
+
this.instanceClient = new CourierClient({ ...props, connectionId });
|
|
960
|
+
this.notifyAuthenticationListeners({ userId: props.userId });
|
|
961
|
+
}
|
|
962
|
+
/**
|
|
963
|
+
* Sign out of Courier
|
|
964
|
+
*/
|
|
965
|
+
signOut() {
|
|
966
|
+
this.instanceClient = void 0;
|
|
967
|
+
this.notifyAuthenticationListeners({ userId: void 0 });
|
|
968
|
+
}
|
|
969
|
+
/**
|
|
970
|
+
* Register a callback to be notified of authentication state changes
|
|
971
|
+
* @param callback - Function to be called when authentication state changes
|
|
972
|
+
* @returns AuthenticationListener instance that can be used to remove the listener
|
|
973
|
+
*/
|
|
974
|
+
addAuthenticationListener(callback) {
|
|
975
|
+
var _a;
|
|
976
|
+
(_a = this.instanceClient) == null ? void 0 : _a.options.logger.info("Adding authentication listener");
|
|
977
|
+
const listener = new AuthenticationListener(callback);
|
|
978
|
+
this.authenticationListeners.push(listener);
|
|
979
|
+
return listener;
|
|
980
|
+
}
|
|
981
|
+
/**
|
|
982
|
+
* Unregister an authentication state change listener
|
|
983
|
+
* @param listener - The AuthenticationListener instance to remove
|
|
984
|
+
*/
|
|
985
|
+
removeAuthenticationListener(listener) {
|
|
986
|
+
var _a;
|
|
987
|
+
(_a = this.instanceClient) == null ? void 0 : _a.options.logger.info("Removing authentication listener");
|
|
988
|
+
this.authenticationListeners = this.authenticationListeners.filter((l) => l !== listener);
|
|
989
|
+
}
|
|
990
|
+
/**
|
|
991
|
+
* Notify all authentication listeners
|
|
992
|
+
* @param props - The props to notify the listeners with
|
|
993
|
+
*/
|
|
994
|
+
notifyAuthenticationListeners(props) {
|
|
995
|
+
this.authenticationListeners.forEach((listener) => listener.callback(props));
|
|
159
996
|
}
|
|
160
997
|
};
|
|
161
|
-
|
|
998
|
+
/**
|
|
999
|
+
* The shared Courier instance
|
|
1000
|
+
*/
|
|
1001
|
+
__publicField(_Courier, "instance");
|
|
1002
|
+
let Courier = _Courier;
|
|
162
1003
|
export {
|
|
163
|
-
|
|
1004
|
+
BrandClient,
|
|
1005
|
+
Courier,
|
|
1006
|
+
CourierClient,
|
|
1007
|
+
CourierSocket,
|
|
1008
|
+
InboxClient,
|
|
1009
|
+
ListClient,
|
|
1010
|
+
PreferenceClient,
|
|
1011
|
+
TokenClient
|
|
164
1012
|
};
|