@suprsend/node-sdk 1.7.1 → 1.8.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.
package/src/workflow.js CHANGED
@@ -4,6 +4,7 @@ import {
4
4
  SuprsendError,
5
5
  validate_workflow_body_schema,
6
6
  get_apparent_workflow_body_size,
7
+ InputValueError,
7
8
  } from "./utils";
8
9
  import get_attachment_json from "./attachment";
9
10
  import {
@@ -14,7 +15,7 @@ import {
14
15
  export default class Workflow {
15
16
  constructor(body, kwargs = {}) {
16
17
  if (!(body instanceof Object)) {
17
- throw new SuprsendError("workflow body must be a json/dictionary");
18
+ throw new InputValueError("workflow body must be a json/dictionary");
18
19
  }
19
20
  this.body = body;
20
21
  this.idempotency_key = kwargs?.idempotency_key;
@@ -24,18 +25,26 @@ export default class Workflow {
24
25
  add_attachment(file_path = "", kwargs = {}) {
25
26
  const file_name = kwargs?.file_name;
26
27
  const ignore_if_error = kwargs?.ignore_if_error ?? false;
27
- if (!this.body.data) {
28
+ if (!this.body?.data) {
28
29
  this.body.data = {};
29
30
  }
30
- if (!(this.body instanceof Object)) {
31
- throw new SuprsendError("data must be a dictionary");
31
+ // if body["data"] is not a dict, not raising error while adding attachment.
32
+ if (!(this.body["data"] instanceof Object)) {
33
+ console.log(
34
+ `WARNING: attachment cannot be added. please make sure body['data'] is a dictionary. Workflow ${JSON.stringify(
35
+ this.as_json()
36
+ )}`
37
+ );
38
+ return;
32
39
  }
33
40
  const attachment = get_attachment_json(
34
41
  file_path,
35
42
  file_name,
36
43
  ignore_if_error
37
44
  );
38
-
45
+ if (!attachment) {
46
+ return;
47
+ }
39
48
  if (!this.body.data["$attachments"]) {
40
49
  this.body["data"]["$attachments"] = [];
41
50
  }
@@ -56,12 +65,23 @@ export default class Workflow {
56
65
  is_part_of_bulk
57
66
  ); // review
58
67
  if (apparent_size > SINGLE_EVENT_MAX_APPARENT_SIZE_IN_BYTES) {
59
- throw new SuprsendError(
68
+ throw new InputValueError(
60
69
  `workflow body too big - ${apparent_size} Bytes, must not cross ${SINGLE_EVENT_MAX_APPARENT_SIZE_IN_BYTES_READABLE}`
61
70
  );
62
71
  }
63
72
  return [this.body, apparent_size];
64
73
  }
74
+
75
+ as_json() {
76
+ const body_dict = { ...this.body };
77
+ if (this.idempotency_key) {
78
+ body_dict["$idempotency_key"] = this.idempotency_key;
79
+ }
80
+ if (this.brand_id) {
81
+ body_dict["brand_id"] = this.brand_id;
82
+ }
83
+ return body_dict;
84
+ }
65
85
  }
66
86
 
67
87
  export class _WorkflowTrigger {
@@ -6,7 +6,7 @@ import {
6
6
  MAX_WORKFLOWS_IN_BULK_API,
7
7
  ALLOW_ATTACHMENTS_IN_BULK_API,
8
8
  } from "./constants";
9
- import { SuprsendError } from "./utils";
9
+ import { SuprsendError, invalid_record_json, InputValueError } from "./utils";
10
10
  import Workflow from "./workflow";
11
11
  import { cloneDeep } from "lodash";
12
12
  import axios from "axios";
@@ -78,7 +78,7 @@ class _BulkWorkflowsChunk {
78
78
  return false;
79
79
  }
80
80
  if (body_size > SINGLE_EVENT_MAX_APPARENT_SIZE_IN_BYTES) {
81
- throw new SuprsendError(
81
+ throw new InputValueError(
82
82
  `workflow body too big - ${body_size} Bytes, must not cross ${SINGLE_EVENT_MAX_APPARENT_SIZE_IN_BYTES_READABLE}`
83
83
  );
84
84
  }
@@ -158,19 +158,23 @@ class BulkWorkflows {
158
158
  this.__pending_records = [];
159
159
  this.chunks = [];
160
160
  this.response = new BulkResponse();
161
+ // invalid_record json: {"record": workflow-json, "error": error_str, "code": 500}
162
+ this.__invalid_records = [];
161
163
  }
162
164
 
163
165
  __validate_workflows() {
164
- if (!this.__workflows) {
165
- throw new SuprsendError("workflow list is empty in bulk request");
166
- }
167
166
  for (let wf of this.__workflows) {
168
- const is_part_of_bulk = true;
169
- const [wf_body, body_size] = wf.get_final_json(
170
- this.config,
171
- is_part_of_bulk
172
- );
173
- this.__pending_records.push([wf_body, body_size]);
167
+ try {
168
+ const is_part_of_bulk = true;
169
+ const [wf_body, body_size] = wf.get_final_json(
170
+ this.config,
171
+ is_part_of_bulk
172
+ );
173
+ this.__pending_records.push([wf_body, body_size]);
174
+ } catch (ex) {
175
+ const inv_rec = invalid_record_json(wf.as_json(), ex);
176
+ this.__invalid_records.push(inv_rec);
177
+ }
174
178
  }
175
179
  }
176
180
 
@@ -190,37 +194,41 @@ class BulkWorkflows {
190
194
  }
191
195
 
192
196
  append(...workflows) {
193
- if (!workflows) {
194
- throw new SuprsendError(
195
- "workflow list empty. must pass one or more valid workflow instances"
196
- );
197
- }
198
197
  for (let wf of workflows) {
199
- if (!wf) {
200
- throw new SuprsendError("null/empty element found in bulk instance");
201
- }
202
- if (!(wf instanceof Workflow)) {
203
- throw new SuprsendError(
204
- "element must be an instance of suprsend.Workflow"
205
- );
198
+ if (wf && wf instanceof Workflow) {
199
+ const wf_copy = cloneDeep(wf);
200
+ this.__workflows.push(wf_copy);
206
201
  }
207
- const wf_copy = cloneDeep(wf);
208
- this.__workflows.push(wf_copy);
209
202
  }
210
203
  }
211
204
 
212
205
  async trigger() {
213
206
  this.__validate_workflows();
214
- this.__chunkify();
215
- for (const [c_idx, ch] of this.chunks.entries()) {
216
- if (this.config.req_log_level > 0) {
217
- console.log(`DEBUG: triggering api call for chunk: ${c_idx}`);
207
+ if (this.__invalid_records.length > 0) {
208
+ const ch_response = BulkResponse.invalid_records_chunk_response(
209
+ this.__invalid_records
210
+ );
211
+ this.response.merge_chunk_response(ch_response);
212
+ }
213
+ if (this.__pending_records.length) {
214
+ this.__chunkify();
215
+ for (const [c_idx, ch] of this.chunks.entries()) {
216
+ if (this.config.req_log_level > 0) {
217
+ console.log(`DEBUG: triggering api call for chunk: ${c_idx}`);
218
+ }
219
+ // do api call
220
+ await ch.trigger();
221
+ // merge response
222
+ this.response.merge_chunk_response(ch.response);
223
+ }
224
+ } else {
225
+ if (this.__invalid_records.length === 0) {
226
+ this.response.merge_chunk_response(
227
+ BulkResponse.empty_chunk_success_response()
228
+ );
218
229
  }
219
- // do api call
220
- await ch.trigger();
221
- // merge response
222
- this.response.merge_chunk_response(ch.response);
223
230
  }
231
+
224
232
  return this.response;
225
233
  }
226
234
  }
package/types/index.d.ts CHANGED
@@ -137,6 +137,11 @@ declare namespace suprsend {
137
137
  body: Dictionary,
138
138
  kwargs?: { idempotency_key?: string; brand_id?: string }
139
139
  ): SubscriberListBroadcast;
140
+
141
+ add_attachment(
142
+ file_path: string,
143
+ kwargs?: { file_name?: string; ignore_if_error?: boolean }
144
+ ): void;
140
145
  }
141
146
 
142
147
  interface SubscriberListsApi {