@suprsend/node-sdk 1.11.1 → 1.12.0

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.
@@ -0,0 +1,590 @@
1
+ import { is_object, has_special_char, is_empty, is_string } from "./utils";
2
+ import ALL_LANG_CODES from "./language_codes";
3
+
4
+ // ---------- Identity keys
5
+ const IDENT_KEY_EMAIL = "$email";
6
+ const IDENT_KEY_SMS = "$sms";
7
+ const IDENT_KEY_ANDROIDPUSH = "$androidpush";
8
+ const IDENT_KEY_IOSPUSH = "$iospush";
9
+ const IDENT_KEY_WHATSAPP = "$whatsapp";
10
+ const IDENT_KEY_WEBPUSH = "$webpush";
11
+ const IDENT_KEY_SLACK = "$slack";
12
+ const IDENT_KEY_MS_TEAMS = "$ms_teams";
13
+
14
+ const IDENT_KEYS_ALL = [
15
+ IDENT_KEY_EMAIL,
16
+ IDENT_KEY_SMS,
17
+ IDENT_KEY_ANDROIDPUSH,
18
+ IDENT_KEY_IOSPUSH,
19
+ IDENT_KEY_WHATSAPP,
20
+ IDENT_KEY_WEBPUSH,
21
+ IDENT_KEY_SLACK,
22
+ IDENT_KEY_MS_TEAMS,
23
+ ];
24
+
25
+ const KEY_ID_PROVIDER = "$id_provider";
26
+ const KEY_PREFERRED_LANGUAGE = "$preferred_language";
27
+ const KEY_TIMEZONE = "$timezone";
28
+
29
+ const OTHER_RESERVED_KEYS = [
30
+ "$messenger",
31
+ "$inbox",
32
+ KEY_ID_PROVIDER,
33
+ "$device_id",
34
+ "$insert_id",
35
+ "$time",
36
+ "$set",
37
+ "$set_once",
38
+ "$add",
39
+ "$append",
40
+ "$remove",
41
+ "$unset",
42
+ "$identify",
43
+ "$anon_id",
44
+ "$identified_id",
45
+ KEY_PREFERRED_LANGUAGE,
46
+ KEY_TIMEZONE,
47
+ "$notification_delivered",
48
+ "$notification_dismiss",
49
+ "$notification_clicked",
50
+ ];
51
+
52
+ const SUPER_PROPERTY_KEYS = [
53
+ "$app_version_string",
54
+ "$app_build_number",
55
+ "$brand",
56
+ "$carrier",
57
+ "$manufacturer",
58
+ "$model",
59
+ "$os",
60
+ "$ss_sdk_version",
61
+ "$insert_id",
62
+ "$time",
63
+ ];
64
+
65
+ const ALL_RESERVED_KEYS = [
66
+ ...SUPER_PROPERTY_KEYS,
67
+ ...OTHER_RESERVED_KEYS,
68
+ ...IDENT_KEYS_ALL,
69
+ ];
70
+
71
+ export default class _ObjectEditInternalHelper {
72
+ constructor() {
73
+ this.__dict_set = {};
74
+
75
+ this.__dict_set_once = {};
76
+
77
+ this.__dict_increment = {};
78
+
79
+ this.__dict_append = {};
80
+
81
+ this.__dict_remove = {};
82
+
83
+ this.__list_unset = [];
84
+
85
+ this.__errors = [];
86
+ this.__info = [];
87
+ }
88
+
89
+ reset() {
90
+ this.__dict_set = {};
91
+ this.__dict_set_once = {};
92
+ this.__dict_increment = {};
93
+ this.__dict_append = {};
94
+ this.__dict_remove = {};
95
+ this.__list_unset = [];
96
+ this.__errors = [];
97
+ this.__info = [];
98
+ }
99
+
100
+ _get_operation_result() {
101
+ const operation = this.__form_operation();
102
+ const ret_val = {
103
+ errors: this.__errors,
104
+ info: this.__info,
105
+ operation: operation,
106
+ };
107
+ this.reset();
108
+ return ret_val;
109
+ }
110
+
111
+ __form_operation() {
112
+ const ops = {};
113
+ if (!is_empty(this.__dict_set)) {
114
+ ops["$set"] = this.__dict_set;
115
+ }
116
+ if (!is_empty(this.__dict_set_once)) {
117
+ ops["$set_once"] = this.__dict_set_once;
118
+ }
119
+ if (!is_empty(this.__dict_increment)) {
120
+ ops["$add"] = this.__dict_increment;
121
+ }
122
+ if (!is_empty(this.__dict_append)) {
123
+ ops["$append"] = this.__dict_append;
124
+ }
125
+ if (!is_empty(this.__dict_remove)) {
126
+ ops["$remove"] = this.__dict_remove;
127
+ }
128
+ if (!is_empty(this.__list_unset)) {
129
+ ops["$unset"] = this.__list_unset;
130
+ }
131
+ return ops;
132
+ }
133
+
134
+ __validate_key_basic(key, caller) {
135
+ if (!is_string(key)) {
136
+ this.__info.push(
137
+ `[${caller}] skipping key: ${key}. key must be a string`
138
+ );
139
+ return [key, false];
140
+ }
141
+ key = key.trim();
142
+ if (!key) {
143
+ this.__info.push(`[${caller}] skipping key: empty string`);
144
+ return [key, false];
145
+ }
146
+ return [key, true];
147
+ }
148
+
149
+ __validate_key_prefix(key, caller) {
150
+ if (!ALL_RESERVED_KEYS.includes(key)) {
151
+ if (has_special_char(key)) {
152
+ this.__info.push(
153
+ `[${caller}] skipping key: ${key}. key starting with [$,ss_] are reserved`
154
+ );
155
+ return false;
156
+ }
157
+ }
158
+ return true;
159
+ }
160
+
161
+ __is_identity_key(key) {
162
+ return IDENT_KEYS_ALL.includes(key);
163
+ }
164
+
165
+ _append_kv(key, value, args = {}, caller = "append") {
166
+ const [validated_key, is_k_valid] = this.__validate_key_basic(key, caller);
167
+ if (!is_k_valid) {
168
+ return;
169
+ }
170
+ if (this.__is_identity_key(validated_key)) {
171
+ this.__add_identity(validated_key, value, args, caller);
172
+ } else {
173
+ const is_k_valid = this.__validate_key_prefix(validated_key, caller);
174
+ if (is_k_valid) {
175
+ this.__dict_append[validated_key] = value;
176
+ }
177
+ }
178
+ }
179
+
180
+ _set_kv(key, value, args = {}, caller = "set") {
181
+ const [validated_key, is_k_valid] = this.__validate_key_basic(key, caller);
182
+ if (!is_k_valid) {
183
+ return;
184
+ } else {
185
+ const is_k_valid = this.__validate_key_prefix(validated_key, caller);
186
+ if (is_k_valid) {
187
+ this.__dict_set[validated_key] = value;
188
+ }
189
+ }
190
+ }
191
+
192
+ _set_once_kv(key, value, args = {}, caller = "set_once") {
193
+ const [validated_key, is_k_valid] = this.__validate_key_basic(key, caller);
194
+ if (!is_k_valid) {
195
+ return;
196
+ } else {
197
+ const is_k_valid = this.__validate_key_prefix(validated_key, caller);
198
+ if (is_k_valid) {
199
+ this.__dict_set_once[validated_key] = value;
200
+ }
201
+ }
202
+ }
203
+
204
+ _increment_kv(key, value, args = {}, caller = "increment") {
205
+ const [validated_key, is_k_valid] = this.__validate_key_basic(key, caller);
206
+ if (!is_k_valid) {
207
+ return;
208
+ } else {
209
+ const is_k_valid = this.__validate_key_prefix(validated_key, caller);
210
+ if (is_k_valid) {
211
+ this.__dict_increment[validated_key] = value;
212
+ }
213
+ }
214
+ }
215
+
216
+ _remove_kv(key, value, args = {}, caller = "remove") {
217
+ const [validated_key, is_k_valid] = this.__validate_key_basic(key, caller);
218
+ if (!is_k_valid) {
219
+ return;
220
+ }
221
+ if (this.__is_identity_key(validated_key)) {
222
+ this.__remove_identity(validated_key, value, args, caller);
223
+ } else {
224
+ const is_k_valid = this.__validate_key_prefix(validated_key, caller);
225
+ if (is_k_valid) {
226
+ this.__dict_remove[validated_key] = value;
227
+ }
228
+ }
229
+ }
230
+
231
+ _unset_k(key, caller = "unset") {
232
+ const [validated_key, is_k_valid] = this.__validate_key_basic(key, caller);
233
+ if (!is_k_valid) {
234
+ return;
235
+ }
236
+ this.__list_unset.push(validated_key);
237
+ }
238
+
239
+ _set_preferred_language(lang_code, caller) {
240
+ if (!ALL_LANG_CODES.includes(lang_code)) {
241
+ this.__info.push(`[${caller}] invalid value ${lang_code}`);
242
+ return;
243
+ }
244
+ this.__dict_set[KEY_PREFERRED_LANGUAGE] = lang_code;
245
+ }
246
+
247
+ _set_timezone(timezone, caller) {
248
+ this.__dict_set[KEY_TIMEZONE] = timezone;
249
+ }
250
+
251
+ __add_identity(key, value, args, caller) {
252
+ const new_caller = `${caller}:${key}`;
253
+ switch (key) {
254
+ case IDENT_KEY_EMAIL:
255
+ this._add_email(value, new_caller);
256
+ break;
257
+ case IDENT_KEY_SMS:
258
+ this._add_sms(value, new_caller);
259
+ break;
260
+ case IDENT_KEY_WHATSAPP:
261
+ this._add_whatsapp(value, new_caller);
262
+ break;
263
+ case IDENT_KEY_ANDROIDPUSH:
264
+ this._add_androidpush(value, args[KEY_ID_PROVIDER], new_caller);
265
+ break;
266
+ case IDENT_KEY_IOSPUSH:
267
+ this._add_iospush(value, args[KEY_ID_PROVIDER], new_caller);
268
+ break;
269
+ case IDENT_KEY_WEBPUSH:
270
+ this._add_webpush(value, args[KEY_ID_PROVIDER], new_caller);
271
+ break;
272
+ case IDENT_KEY_SLACK:
273
+ this._add_slack(value, caller);
274
+ break;
275
+ case IDENT_KEY_MS_TEAMS:
276
+ this._add_ms_teams(value, caller);
277
+ break;
278
+ default:
279
+ break;
280
+ }
281
+ }
282
+
283
+ __remove_identity(key, value, args, caller) {
284
+ const new_caller = `${caller}:${key}`;
285
+ switch (key) {
286
+ case IDENT_KEY_EMAIL:
287
+ this._remove_email(value, new_caller);
288
+ break;
289
+ case IDENT_KEY_SMS:
290
+ this._remove_sms(value, new_caller);
291
+ break;
292
+ case IDENT_KEY_WHATSAPP:
293
+ this._remove_whatsapp(value, new_caller);
294
+ break;
295
+ case IDENT_KEY_ANDROIDPUSH:
296
+ this._remove_androidpush(value, args[KEY_ID_PROVIDER], new_caller);
297
+ break;
298
+ case IDENT_KEY_IOSPUSH:
299
+ this._remove_iospush(value, args[KEY_ID_PROVIDER], new_caller);
300
+ break;
301
+ case IDENT_KEY_WEBPUSH:
302
+ this._remove_webpush(value, args[KEY_ID_PROVIDER], new_caller);
303
+ break;
304
+ case IDENT_KEY_SLACK:
305
+ this._remove_slack(val, caller);
306
+ break;
307
+ case IDENT_KEY_MS_TEAMS:
308
+ this._remove_ms_teams(val, caller);
309
+ break;
310
+ default:
311
+ break;
312
+ }
313
+ }
314
+
315
+ __check_ident_val_string(value, caller) {
316
+ const message = "value must be a string with proper value";
317
+ if (!is_string(value)) {
318
+ this.__errors.push(`[${caller}] ${message}`);
319
+ return [value, false];
320
+ }
321
+ value = value.trim();
322
+ if (!value) {
323
+ this.__errors.push(`[${caller}] ${message}`);
324
+ return [value, false];
325
+ }
326
+ return [value, true];
327
+ }
328
+
329
+ // email methods
330
+ __validate_email(value, caller) {
331
+ const [email, is_valid] = this.__check_ident_val_string(value, caller);
332
+ if (!is_valid) {
333
+ return [email, false];
334
+ }
335
+ return [email, true];
336
+ }
337
+
338
+ _add_email(email, caller) {
339
+ const [value, is_valid] = this.__validate_email(email, caller);
340
+ if (!is_valid) {
341
+ return;
342
+ }
343
+ this.__dict_append[IDENT_KEY_EMAIL] = value;
344
+ }
345
+
346
+ _remove_email(email, caller) {
347
+ const [value, is_valid] = this.__validate_email(email, caller);
348
+ if (!is_valid) {
349
+ return;
350
+ }
351
+ this.__dict_remove[IDENT_KEY_EMAIL] = value;
352
+ }
353
+
354
+ // mobile methods
355
+ __validate_mobile_no(value, caller) {
356
+ const [mobile, is_valid] = this.__check_ident_val_string(value, caller);
357
+ if (!is_valid) {
358
+ return [mobile, false];
359
+ }
360
+ return [mobile, true];
361
+ }
362
+
363
+ _add_sms(mobile_no, caller) {
364
+ const [value, is_valid] = this.__validate_mobile_no(mobile_no, caller);
365
+ if (!is_valid) {
366
+ return;
367
+ }
368
+ this.__dict_append[IDENT_KEY_SMS] = value;
369
+ }
370
+
371
+ _remove_sms(mobile_no, caller) {
372
+ const [value, is_valid] = this.__validate_mobile_no(mobile_no, caller);
373
+ if (!is_valid) {
374
+ return;
375
+ }
376
+ this.__dict_remove[IDENT_KEY_SMS] = value;
377
+ }
378
+
379
+ _add_whatsapp(mobile_no, caller) {
380
+ const [value, is_valid] = this.__validate_mobile_no(mobile_no, caller);
381
+ if (!is_valid) {
382
+ return;
383
+ }
384
+ this.__dict_append[IDENT_KEY_WHATSAPP] = value;
385
+ }
386
+
387
+ _remove_whatsapp(mobile_no, caller) {
388
+ const [value, is_valid] = this.__validate_mobile_no(mobile_no, caller);
389
+ if (!is_valid) {
390
+ return;
391
+ }
392
+ this.__dict_remove[IDENT_KEY_WHATSAPP] = value;
393
+ }
394
+
395
+ // android push methods
396
+ __check_androidpush_value(value, provider, caller) {
397
+ let [push_token, is_valid] = this.__check_ident_val_string(value, caller);
398
+ if (!is_valid) {
399
+ return [push_token, provider, false];
400
+ }
401
+
402
+ let [validated_provider, is_provider_valid] = this.__check_ident_val_string(
403
+ value,
404
+ caller
405
+ );
406
+ if (!is_provider_valid) {
407
+ return [push_token, provider, false];
408
+ }
409
+ provider = validated_provider.toLocaleLowerCase();
410
+
411
+ return [push_token, provider, true];
412
+ }
413
+
414
+ _add_androidpush(push_token, provider = "fcm", caller) {
415
+ const [value, vendor, is_valid] = this.__check_androidpush_value(
416
+ push_token,
417
+ provider,
418
+ caller
419
+ );
420
+ if (!is_valid) {
421
+ return;
422
+ }
423
+ this.__dict_append[IDENT_KEY_ANDROIDPUSH] = value;
424
+ this.__dict_append[KEY_ID_PROVIDER] = vendor;
425
+ }
426
+
427
+ _remove_androidpush(push_token, provider = "fcm") {
428
+ const caller = "remove_androidpush";
429
+ const [value, vendor, is_valid] = this.__check_androidpush_value(
430
+ push_token,
431
+ provider,
432
+ caller
433
+ );
434
+ if (!is_valid) {
435
+ return;
436
+ }
437
+ this.__dict_remove[IDENT_KEY_ANDROIDPUSH] = value;
438
+ this.__dict_remove[KEY_ID_PROVIDER] = vendor;
439
+ }
440
+
441
+ // ios push methods
442
+ __check_iospush_value(value, provider, caller) {
443
+ let [push_token, is_valid] = this.__check_ident_val_string(value, caller);
444
+ if (!is_valid) {
445
+ return [push_token, provider, false];
446
+ }
447
+
448
+ let [validated_provider, is_provider_valid] = this.__check_ident_val_string(
449
+ value,
450
+ caller
451
+ );
452
+ if (!is_provider_valid) {
453
+ return [push_token, provider, false];
454
+ }
455
+ provider = validated_provider.toLocaleLowerCase();
456
+
457
+ return [push_token, provider, true];
458
+ }
459
+
460
+ _add_iospush(push_token, provider = "apns", caller) {
461
+ const [value, vendor, is_valid] = this.__check_iospush_value(
462
+ push_token,
463
+ provider,
464
+ caller
465
+ );
466
+ if (!is_valid) {
467
+ return;
468
+ }
469
+ this.__dict_append[IDENT_KEY_IOSPUSH] = value;
470
+ this.__dict_append[KEY_ID_PROVIDER] = vendor;
471
+ }
472
+
473
+ _remove_iospush(push_token, provider = "apns", caller) {
474
+ const [value, vendor, is_valid] = this.__check_iospush_value(
475
+ push_token,
476
+ provider,
477
+ caller
478
+ );
479
+ if (!is_valid) {
480
+ return;
481
+ }
482
+ this.__dict_remove[IDENT_KEY_IOSPUSH] = value;
483
+ this.__dict_remove[KEY_ID_PROVIDER] = vendor;
484
+ }
485
+
486
+ // web push methods
487
+ __check_webpush_dict(value, provider, caller) {
488
+ if (!is_object(value)) {
489
+ this.__errors.push(
490
+ `[${caller}] value must be a valid dict representing webpush-token`
491
+ );
492
+ return [value, provider, false];
493
+ }
494
+
495
+ let [validated_provider, is_provider_valid] = this.__check_ident_val_string(
496
+ value,
497
+ caller
498
+ );
499
+ if (!is_provider_valid) {
500
+ return [value, provider, false];
501
+ }
502
+ provider = validated_provider.toLocaleLowerCase();
503
+
504
+ return [value, provider, true];
505
+ }
506
+
507
+ _add_webpush(push_token, provider = "vapid", caller) {
508
+ const [value, vendor, is_valid] = this.__check_webpush_dict(
509
+ push_token,
510
+ provider,
511
+ caller
512
+ );
513
+ if (!is_valid) {
514
+ return;
515
+ }
516
+ this.__dict_append[IDENT_KEY_WEBPUSH] = value;
517
+ this.__dict_append[KEY_ID_PROVIDER] = vendor;
518
+ }
519
+
520
+ _remove_webpush(push_token, provider = "vapid", caller) {
521
+ const [value, vendor, is_valid] = this.__check_webpush_dict(
522
+ push_token,
523
+ provider,
524
+ caller
525
+ );
526
+ if (!is_valid) {
527
+ return;
528
+ }
529
+ this.__dict_remove[IDENT_KEY_WEBPUSH] = value;
530
+ this.__dict_remove[KEY_ID_PROVIDER] = vendor;
531
+ }
532
+
533
+ __check_slack_dict(value, caller) {
534
+ const msg = "value must be a valid dict/json with proper keys";
535
+ if (!(value && value instanceof Object)) {
536
+ this.__errors.push(`[${caller}] ${msg}`);
537
+ return [value, false];
538
+ } else {
539
+ return [value, true];
540
+ }
541
+ }
542
+
543
+ _add_slack(value, caller) {
544
+ const [validated_value, is_valid] = this.__check_slack_dict(value, caller);
545
+ if (!is_valid) {
546
+ return;
547
+ }
548
+ this.__dict_append[IDENT_KEY_SLACK] = validated_value;
549
+ }
550
+
551
+ _remove_slack(value, caller) {
552
+ const [validated_value, is_valid] = this.__check_slack_dict(value, caller);
553
+ if (!is_valid) {
554
+ return;
555
+ }
556
+ this.__dict_remove[IDENT_KEY_SLACK] = validated_value;
557
+ }
558
+
559
+ __check_ms_teams_dict(value, caller) {
560
+ const msg = "value must be a valid dict/json with proper keys";
561
+ if (!(value && value instanceof Object)) {
562
+ this.__errors.push(`[${caller}] ${msg}`);
563
+ return [value, false];
564
+ } else {
565
+ return [value, true];
566
+ }
567
+ }
568
+
569
+ _add_ms_teams(value, caller) {
570
+ const [validated_value, is_valid] = this.__check_ms_teams_dict(
571
+ value,
572
+ caller
573
+ );
574
+ if (!is_valid) {
575
+ return;
576
+ }
577
+ this.__dict_append[IDENT_KEY_MS_TEAMS] = validated_value;
578
+ }
579
+
580
+ _remove_ms_teams(value, caller) {
581
+ const [validated_value, is_valid] = this.__check_ms_teams_dict(
582
+ value,
583
+ caller
584
+ );
585
+ if (!is_valid) {
586
+ return;
587
+ }
588
+ this.__dict_remove[IDENT_KEY_MS_TEAMS] = validated_value;
589
+ }
590
+ }