@suprsend/node-sdk 1.11.1 → 1.13.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.
Files changed (48) hide show
  1. package/dist/constants.js +2 -8
  2. package/dist/event.js +2 -2
  3. package/dist/events_bulk.js +2 -2
  4. package/dist/index.js +25 -2
  5. package/dist/object_edit.js +352 -0
  6. package/dist/object_edit_internal_helper.js +395 -0
  7. package/dist/objects_api.js +527 -0
  8. package/dist/request_json/workflow.json +7 -29
  9. package/dist/request_json/workflow_trigger.json +7 -29
  10. package/dist/subscriber.js +12 -28
  11. package/dist/subscriber_helper.js +40 -363
  12. package/dist/subscriber_list.js +2 -2
  13. package/dist/user_edit.js +412 -0
  14. package/dist/user_edit_internal_helper.js +363 -0
  15. package/dist/users_api.js +535 -0
  16. package/dist/users_edit_bulk.js +312 -0
  17. package/dist/workflow.js +2 -2
  18. package/dist/workflow_request.js +2 -2
  19. package/dist/workflow_trigger_bulk.js +2 -2
  20. package/dist/workflows_bulk.js +2 -2
  21. package/package.json +1 -1
  22. package/src/constants.js +0 -4
  23. package/src/event.js +4 -5
  24. package/src/events_bulk.js +3 -5
  25. package/src/index.js +9 -1
  26. package/src/object_edit.js +308 -0
  27. package/src/object_edit_internal_helper.js +332 -0
  28. package/src/objects_api.js +320 -0
  29. package/src/request_json/workflow.json +7 -29
  30. package/src/request_json/workflow_trigger.json +7 -29
  31. package/src/subscriber.js +10 -21
  32. package/src/subscriber_helper.js +41 -365
  33. package/src/subscriber_list.js +4 -4
  34. package/src/user_edit.js +360 -0
  35. package/src/user_edit_internal_helper.js +297 -0
  36. package/src/users_api.js +301 -0
  37. package/src/users_edit_bulk.js +211 -0
  38. package/src/workflow.js +4 -5
  39. package/src/workflow_request.js +4 -4
  40. package/src/workflow_trigger_bulk.js +2 -4
  41. package/src/workflows_bulk.js +3 -5
  42. package/types/index.d.ts +168 -13
  43. package/dist/language_codes.js +0 -197
  44. package/dist/object.js +0 -919
  45. package/dist/object_helper.js +0 -659
  46. package/src/language_codes.js +0 -188
  47. package/src/object.js +0 -621
  48. package/src/object_helper.js +0 -593
@@ -1,12 +1,4 @@
1
- import {
2
- is_object,
3
- has_special_char,
4
- epoch_milliseconds,
5
- uuid,
6
- is_empty,
7
- is_string,
8
- } from "./utils";
9
- import ALL_LANG_CODES from "./language_codes";
1
+ import { is_empty, is_string } from "./utils";
10
2
 
11
3
  // ---------- Identity keys
12
4
  const IDENT_KEY_EMAIL = "$email";
@@ -29,55 +21,10 @@ const IDENT_KEYS_ALL = [
29
21
  IDENT_KEY_MS_TEAMS,
30
22
  ];
31
23
 
32
- const KEY_PUSHVENDOR = "$pushvendor";
24
+ const KEY_ID_PROVIDER = "$id_provider";
33
25
  const KEY_PREFERRED_LANGUAGE = "$preferred_language";
34
26
  const KEY_TIMEZONE = "$timezone";
35
27
 
36
- const OTHER_RESERVED_KEYS = [
37
- "$messenger",
38
- "$inbox",
39
- KEY_PUSHVENDOR,
40
- "$device_id",
41
- "$insert_id",
42
- "$time",
43
- "$set",
44
- "$set_once",
45
- "$add",
46
- "$append",
47
- "$remove",
48
- "$unset",
49
- "$identify",
50
- "$anon_id",
51
- "$identified_id",
52
- KEY_PREFERRED_LANGUAGE,
53
- KEY_TIMEZONE,
54
- "$notification_delivered",
55
- "$notification_dismiss",
56
- "$notification_clicked",
57
- ];
58
-
59
- const SUPER_PROPERTY_KEYS = [
60
- "$app_version_string",
61
- "$app_build_number",
62
- "$brand",
63
- "$carrier",
64
- "$manufacturer",
65
- "$model",
66
- "$os",
67
- "$ss_sdk_version",
68
- "$insert_id",
69
- "$time",
70
- ];
71
-
72
- const ALL_RESERVED_KEYS = [
73
- ...SUPER_PROPERTY_KEYS,
74
- ...OTHER_RESERVED_KEYS,
75
- ...IDENT_KEYS_ALL,
76
- ];
77
-
78
- const EMAIL_REGEX = /\S+@\S+\.\S+/;
79
- const MOBILE_REGEX = /^\+[0-9\s]+/;
80
-
81
28
  export default class _SubscriberInternalHelper {
82
29
  constructor(distinct_id, workspace_key) {
83
30
  this.distinct_id = distinct_id;
@@ -159,18 +106,6 @@ export default class _SubscriberInternalHelper {
159
106
  return [key, true];
160
107
  }
161
108
 
162
- __validate_key_prefix(key, caller) {
163
- if (!ALL_RESERVED_KEYS.includes(key)) {
164
- if (has_special_char(key)) {
165
- this.__info.push(
166
- `[${caller}] skipping key: ${key}. key starting with [$,ss_] are reserved`
167
- );
168
- return false;
169
- }
170
- }
171
- return true;
172
- }
173
-
174
109
  __is_identity_key(key) {
175
110
  return IDENT_KEYS_ALL.includes(key);
176
111
  }
@@ -183,10 +118,7 @@ export default class _SubscriberInternalHelper {
183
118
  if (this.__is_identity_key(validated_key)) {
184
119
  this.__add_identity(validated_key, value, args, caller);
185
120
  } else {
186
- const is_k_valid = this.__validate_key_prefix(validated_key, caller);
187
- if (is_k_valid) {
188
- this.__dict_append[validated_key] = value;
189
- }
121
+ this.__dict_append[validated_key] = value;
190
122
  }
191
123
  }
192
124
 
@@ -195,10 +127,7 @@ export default class _SubscriberInternalHelper {
195
127
  if (!is_k_valid) {
196
128
  return;
197
129
  } else {
198
- const is_k_valid = this.__validate_key_prefix(validated_key, caller);
199
- if (is_k_valid) {
200
- this.__dict_set[validated_key] = value;
201
- }
130
+ this.__dict_set[validated_key] = value;
202
131
  }
203
132
  }
204
133
 
@@ -207,10 +136,7 @@ export default class _SubscriberInternalHelper {
207
136
  if (!is_k_valid) {
208
137
  return;
209
138
  } else {
210
- const is_k_valid = this.__validate_key_prefix(validated_key, caller);
211
- if (is_k_valid) {
212
- this.__dict_set_once[validated_key] = value;
213
- }
139
+ this.__dict_set_once[validated_key] = value;
214
140
  }
215
141
  }
216
142
 
@@ -219,10 +145,7 @@ export default class _SubscriberInternalHelper {
219
145
  if (!is_k_valid) {
220
146
  return;
221
147
  } else {
222
- const is_k_valid = this.__validate_key_prefix(validated_key, caller);
223
- if (is_k_valid) {
224
- this.__dict_increment[validated_key] = value;
225
- }
148
+ this.__dict_increment[validated_key] = value;
226
149
  }
227
150
  }
228
151
 
@@ -234,10 +157,7 @@ export default class _SubscriberInternalHelper {
234
157
  if (this.__is_identity_key(validated_key)) {
235
158
  this.__remove_identity(validated_key, value, args, caller);
236
159
  } else {
237
- const is_k_valid = this.__validate_key_prefix(validated_key, caller);
238
- if (is_k_valid) {
239
- this.__dict_remove[validated_key] = value;
240
- }
160
+ this.__dict_remove[validated_key] = value;
241
161
  }
242
162
  }
243
163
 
@@ -250,10 +170,6 @@ export default class _SubscriberInternalHelper {
250
170
  }
251
171
 
252
172
  _set_preferred_language(lang_code, caller) {
253
- if (!ALL_LANG_CODES.includes(lang_code)) {
254
- this.__info.push(`[${caller}] invalid value ${lang_code}`);
255
- return;
256
- }
257
173
  this.__dict_set[KEY_PREFERRED_LANGUAGE] = lang_code;
258
174
  }
259
175
 
@@ -274,13 +190,13 @@ export default class _SubscriberInternalHelper {
274
190
  this._add_whatsapp(value, new_caller);
275
191
  break;
276
192
  case IDENT_KEY_ANDROIDPUSH:
277
- this._add_androidpush(value, args[KEY_PUSHVENDOR], new_caller);
193
+ this._add_androidpush(value, args[KEY_ID_PROVIDER], new_caller);
278
194
  break;
279
195
  case IDENT_KEY_IOSPUSH:
280
- this._add_iospush(value, args[KEY_PUSHVENDOR], new_caller);
196
+ this._add_iospush(value, args[KEY_ID_PROVIDER], new_caller);
281
197
  break;
282
198
  case IDENT_KEY_WEBPUSH:
283
- this._add_webpush(value, args[KEY_PUSHVENDOR], new_caller);
199
+ this._add_webpush(value, args[KEY_ID_PROVIDER], new_caller);
284
200
  break;
285
201
  case IDENT_KEY_SLACK:
286
202
  this._add_slack(value, caller);
@@ -306,13 +222,13 @@ export default class _SubscriberInternalHelper {
306
222
  this._remove_whatsapp(value, new_caller);
307
223
  break;
308
224
  case IDENT_KEY_ANDROIDPUSH:
309
- this._remove_androidpush(value, args[KEY_PUSHVENDOR], new_caller);
225
+ this._remove_androidpush(value, args[KEY_ID_PROVIDER], new_caller);
310
226
  break;
311
227
  case IDENT_KEY_IOSPUSH:
312
- this._remove_iospush(value, args[KEY_PUSHVENDOR], new_caller);
228
+ this._remove_iospush(value, args[KEY_ID_PROVIDER], new_caller);
313
229
  break;
314
230
  case IDENT_KEY_WEBPUSH:
315
- this._remove_webpush(value, args[KEY_PUSHVENDOR], new_caller);
231
+ this._remove_webpush(value, args[KEY_ID_PROVIDER], new_caller);
316
232
  break;
317
233
  case IDENT_KEY_SLACK:
318
234
  this._remove_slack(val, caller);
@@ -325,313 +241,73 @@ export default class _SubscriberInternalHelper {
325
241
  }
326
242
  }
327
243
 
328
- __check_ident_val_string(value, caller) {
329
- const message = "value must be a string with proper value";
330
- if (!is_string(value)) {
331
- this.__errors.push(`[${caller}] ${message}`);
332
- return [value, false];
333
- }
334
- value = value.trim();
335
- if (!value) {
336
- this.__errors.push(`[${caller}] ${message}`);
337
- return [value, false];
338
- }
339
- return [value, true];
340
- }
341
-
342
- // email methods
343
- __validate_email(value, caller) {
344
- const [email, is_valid] = this.__check_ident_val_string(value, caller);
345
- if (!is_valid) {
346
- return [email, false];
347
- }
348
- const message = "value in email format required. e.g. user@example.com";
349
- const min_length = 6;
350
- const max_length = 127;
351
- const is_valid_email = EMAIL_REGEX.test(email);
352
- if (!is_valid_email) {
353
- this.__errors.push(`[${caller}] invalid value ${email}. ${message}`);
354
- return [email, false];
355
- }
356
- if (email.length < min_length || email.length > max_length) {
357
- this.__errors.push(
358
- `[${caller}] invalid value ${email}. must be 6 <= email.length <= 127`
359
- );
360
- return [email, false];
361
- }
362
- return [email, true];
363
- }
364
-
365
244
  _add_email(email, caller) {
366
- const [value, is_valid] = this.__validate_email(email, caller);
367
- if (!is_valid) {
368
- return;
369
- }
370
- this.__dict_append[IDENT_KEY_EMAIL] = value;
245
+ this.__dict_append[IDENT_KEY_EMAIL] = email;
371
246
  }
372
247
 
373
248
  _remove_email(email, caller) {
374
- const [value, is_valid] = this.__validate_email(email, caller);
375
- if (!is_valid) {
376
- return;
377
- }
378
- this.__dict_remove[IDENT_KEY_EMAIL] = value;
379
- }
380
-
381
- // mobile methods
382
- __validate_mobile_no(value, caller) {
383
- const [mobile, is_valid] = this.__check_ident_val_string(value, caller);
384
- if (!is_valid) {
385
- return [mobile, false];
386
- }
387
- const message =
388
- "number must start with + and must contain country code. e.g. +41446681800";
389
- const min_length = 8;
390
- const is_valid_mobile = MOBILE_REGEX.test(mobile);
391
- if (!is_valid_mobile) {
392
- this.__errors.push(`[${caller}] invalid value ${mobile}. ${message}`);
393
- return [mobile, false];
394
- }
395
- if (mobile.length < min_length) {
396
- this.__errors.push(
397
- `[${caller}] invalid value ${mobile}. mobile_no.length must be >= 8`
398
- );
399
- return [mobile, false];
400
- }
401
- return [mobile, true];
249
+ this.__dict_remove[IDENT_KEY_EMAIL] = email;
402
250
  }
403
251
 
404
252
  _add_sms(mobile_no, caller) {
405
- const [value, is_valid] = this.__validate_mobile_no(mobile_no, caller);
406
- if (!is_valid) {
407
- return;
408
- }
409
- this.__dict_append[IDENT_KEY_SMS] = value;
253
+ this.__dict_append[IDENT_KEY_SMS] = mobile_no;
410
254
  }
411
255
 
412
256
  _remove_sms(mobile_no, caller) {
413
- const [value, is_valid] = this.__validate_mobile_no(mobile_no, caller);
414
- if (!is_valid) {
415
- return;
416
- }
417
- this.__dict_remove[IDENT_KEY_SMS] = value;
257
+ this.__dict_remove[IDENT_KEY_SMS] = mobile_no;
418
258
  }
419
259
 
420
260
  _add_whatsapp(mobile_no, caller) {
421
- const [value, is_valid] = this.__validate_mobile_no(mobile_no, caller);
422
- if (!is_valid) {
423
- return;
424
- }
425
- this.__dict_append[IDENT_KEY_WHATSAPP] = value;
261
+ this.__dict_append[IDENT_KEY_WHATSAPP] = mobile_no;
426
262
  }
427
263
 
428
264
  _remove_whatsapp(mobile_no, caller) {
429
- const [value, is_valid] = this.__validate_mobile_no(mobile_no, caller);
430
- if (!is_valid) {
431
- return;
432
- }
433
- this.__dict_remove[IDENT_KEY_WHATSAPP] = value;
434
- }
435
-
436
- // android push methods
437
- __check_androidpush_value(value, provider, caller) {
438
- const [push_token, is_valid] = this.__check_ident_val_string(value, caller);
439
- if (!is_valid) {
440
- return [push_token, provider, false];
441
- }
442
- if (!provider) {
443
- provider = "fcm";
444
- }
445
- if (typeof provider === "string") {
446
- provider = provider.toLocaleLowerCase();
447
- }
448
- if (!["fcm", "xiaomi", "oppo"].includes(provider)) {
449
- this.__errors.push(
450
- `[${caller}] unsupported androidpush provider ${provider}`
451
- );
452
- return [push_token, provider, false];
453
- }
454
- return [push_token, provider, true];
455
- }
456
-
457
- _add_androidpush(push_token, provider = "fcm", caller) {
458
- const [value, vendor, is_valid] = this.__check_androidpush_value(
459
- push_token,
460
- provider,
461
- caller
462
- );
463
- if (!is_valid) {
464
- return;
465
- }
466
- this.__dict_append[IDENT_KEY_ANDROIDPUSH] = value;
467
- this.__dict_append[KEY_PUSHVENDOR] = vendor;
468
- }
469
-
470
- _remove_androidpush(push_token, provider = "fcm") {
471
- const caller = "remove_androidpush";
472
- const [value, vendor, is_valid] = this.__check_androidpush_value(
473
- push_token,
474
- provider,
475
- caller
476
- );
477
- if (!is_valid) {
478
- return;
479
- }
480
- this.__dict_remove[IDENT_KEY_ANDROIDPUSH] = value;
481
- this.__dict_remove[KEY_PUSHVENDOR] = vendor;
482
- }
483
-
484
- // ios push methods
485
- __check_iospush_value(value, provider, caller) {
486
- const [push_token, is_valid] = this.__check_ident_val_string(value, caller);
487
- if (!is_valid) {
488
- return [push_token, provider, false];
489
- }
490
- if (!provider) {
491
- provider = "apns";
492
- }
493
- if (typeof provider === "string") {
494
- provider = provider.toLocaleLowerCase();
495
- }
496
- if (!["apns"].includes(provider)) {
497
- this.__errors.push(
498
- `[${caller}] unsupported iospush provider ${provider}`
499
- );
500
- return [push_token, provider, false];
501
- }
502
- return [push_token, provider, true];
265
+ this.__dict_remove[IDENT_KEY_WHATSAPP] = mobile_no;
503
266
  }
504
267
 
505
- _add_iospush(push_token, provider = "apns", caller) {
506
- const [value, vendor, is_valid] = this.__check_iospush_value(
507
- push_token,
508
- provider,
509
- caller
510
- );
511
- if (!is_valid) {
512
- return;
513
- }
514
- this.__dict_append[IDENT_KEY_IOSPUSH] = value;
515
- this.__dict_append[KEY_PUSHVENDOR] = vendor;
268
+ _add_androidpush(push_token, provider, caller) {
269
+ this.__dict_append[IDENT_KEY_ANDROIDPUSH] = push_token;
270
+ this.__dict_append[KEY_ID_PROVIDER] = provider;
516
271
  }
517
272
 
518
- _remove_iospush(push_token, provider = "apns", caller) {
519
- const [value, vendor, is_valid] = this.__check_iospush_value(
520
- push_token,
521
- provider,
522
- caller
523
- );
524
- if (!is_valid) {
525
- return;
526
- }
527
- this.__dict_remove[IDENT_KEY_IOSPUSH] = value;
528
- this.__dict_remove[KEY_PUSHVENDOR] = vendor;
273
+ _remove_androidpush(push_token, provider) {
274
+ this.__dict_remove[IDENT_KEY_ANDROIDPUSH] = push_token;
275
+ this.__dict_remove[KEY_ID_PROVIDER] = provider;
529
276
  }
530
277
 
531
- // web push methods
532
- __check_webpush_dict(value, provider, caller) {
533
- if (!is_object(value)) {
534
- this.__errors.push(
535
- `[${caller}] value must be a valid dict representing webpush-token`
536
- );
537
- return [value, provider, false];
538
- }
539
- if (!provider) {
540
- provider = "vapid";
541
- }
542
- if (typeof provider === "string") {
543
- provider = provider.toLocaleLowerCase();
544
- }
545
- if (!["vapid"].includes(provider)) {
546
- this.__errors.push(
547
- `[${caller}] unsupported webpush provider ${provider}`
548
- );
549
- return [value, provider, false];
550
- }
551
- return [value, provider, true];
278
+ _add_iospush(push_token, provider, caller) {
279
+ this.__dict_append[IDENT_KEY_IOSPUSH] = push_token;
280
+ this.__dict_append[KEY_ID_PROVIDER] = provider;
552
281
  }
553
282
 
554
- _add_webpush(push_token, provider = "vapid", caller) {
555
- const [value, vendor, is_valid] = this.__check_webpush_dict(
556
- push_token,
557
- provider,
558
- caller
559
- );
560
- if (!is_valid) {
561
- return;
562
- }
563
- this.__dict_append[IDENT_KEY_WEBPUSH] = value;
564
- this.__dict_append[KEY_PUSHVENDOR] = vendor;
283
+ _remove_iospush(push_token, provider, caller) {
284
+ this.__dict_remove[IDENT_KEY_IOSPUSH] = push_token;
285
+ this.__dict_remove[KEY_ID_PROVIDER] = provider;
565
286
  }
566
287
 
567
- _remove_webpush(push_token, provider = "vapid", caller) {
568
- const [value, vendor, is_valid] = this.__check_webpush_dict(
569
- push_token,
570
- provider,
571
- caller
572
- );
573
- if (!is_valid) {
574
- return;
575
- }
576
- this.__dict_remove[IDENT_KEY_WEBPUSH] = value;
577
- this.__dict_remove[KEY_PUSHVENDOR] = vendor;
288
+ _add_webpush(push_token, provider, caller) {
289
+ this.__dict_append[IDENT_KEY_WEBPUSH] = push_token;
290
+ this.__dict_append[KEY_ID_PROVIDER] = provider;
578
291
  }
579
292
 
580
- __check_slack_dict(value, caller) {
581
- const msg = "value must be a valid dict/json with proper keys";
582
- if (!(value && value instanceof Object)) {
583
- this.__errors.push(`[${caller}] ${msg}`);
584
- return [value, false];
585
- } else {
586
- return [value, true];
587
- }
293
+ _remove_webpush(push_token, provider, caller) {
294
+ this.__dict_remove[IDENT_KEY_WEBPUSH] = push_token;
295
+ this.__dict_remove[KEY_ID_PROVIDER] = provider;
588
296
  }
589
297
 
590
298
  _add_slack(value, caller) {
591
- const [validated_value, is_valid] = this.__check_slack_dict(value, caller);
592
- if (!is_valid) {
593
- return;
594
- }
595
- this.__dict_append[IDENT_KEY_SLACK] = validated_value;
299
+ this.__dict_append[IDENT_KEY_SLACK] = value;
596
300
  }
597
301
 
598
302
  _remove_slack(value, caller) {
599
- const [validated_value, is_valid] = this.__check_slack_dict(value, caller);
600
- if (!is_valid) {
601
- return;
602
- }
603
- this.__dict_remove[IDENT_KEY_SLACK] = validated_value;
604
- }
605
-
606
- __check_ms_teams_dict(value, caller) {
607
- const msg = "value must be a valid dict/json with proper keys";
608
- if (!(value && value instanceof Object)) {
609
- this.__errors.push(`[${caller}] ${msg}`);
610
- return [value, false];
611
- } else {
612
- return [value, true];
613
- }
303
+ this.__dict_remove[IDENT_KEY_SLACK] = value;
614
304
  }
615
305
 
616
306
  _add_ms_teams(value, caller) {
617
- const [validated_value, is_valid] = this.__check_ms_teams_dict(
618
- value,
619
- caller
620
- );
621
- if (!is_valid) {
622
- return;
623
- }
624
- this.__dict_append[IDENT_KEY_MS_TEAMS] = validated_value;
307
+ this.__dict_append[IDENT_KEY_MS_TEAMS] = value;
625
308
  }
626
309
 
627
310
  _remove_ms_teams(value, caller) {
628
- const [validated_value, is_valid] = this.__check_ms_teams_dict(
629
- value,
630
- caller
631
- );
632
- if (!is_valid) {
633
- return;
634
- }
635
- this.__dict_remove[IDENT_KEY_MS_TEAMS] = validated_value;
311
+ this.__dict_remove[IDENT_KEY_MS_TEAMS] = value;
636
312
  }
637
313
  }
@@ -10,8 +10,8 @@ import {
10
10
  import get_request_signature from "./signature";
11
11
  import axios from "axios";
12
12
  import {
13
- SINGLE_EVENT_MAX_APPARENT_SIZE_IN_BYTES,
14
- SINGLE_EVENT_MAX_APPARENT_SIZE_IN_BYTES_READABLE,
13
+ BODY_MAX_APPARENT_SIZE_IN_BYTES,
14
+ BODY_MAX_APPARENT_SIZE_IN_BYTES_READABLE,
15
15
  } from "./constants";
16
16
  import get_attachment_json from "./attachment";
17
17
 
@@ -73,9 +73,9 @@ class SubscriberListBroadcast {
73
73
  }
74
74
  this.body = validate_list_broadcast_body_schema(this.body);
75
75
  const apparent_size = get_apparent_list_broadcast_body_size(this.body);
76
- if (apparent_size > SINGLE_EVENT_MAX_APPARENT_SIZE_IN_BYTES) {
76
+ if (apparent_size > BODY_MAX_APPARENT_SIZE_IN_BYTES) {
77
77
  throw new InputValueError(
78
- `SubscriberListBroadcast body too big - ${apparent_size} Bytes, must not cross ${SINGLE_EVENT_MAX_APPARENT_SIZE_IN_BYTES_READABLE}`
78
+ `SubscriberListBroadcast body too big - ${apparent_size} Bytes, must not cross ${BODY_MAX_APPARENT_SIZE_IN_BYTES_READABLE}`
79
79
  );
80
80
  }
81
81
  return [this.body, apparent_size];