@suprsend/node-sdk 0.1.1 → 1.0.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,26 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports["default"] = get_attachment_json_for_file;
9
+
10
+ var _path = _interopRequireDefault(require("path"));
11
+
12
+ var _mimeTypes = _interopRequireDefault(require("mime-types"));
13
+
14
+ var _utils = require("./utils");
15
+
16
+ function get_attachment_json_for_file(file_path) {
17
+ var abs_path = _path["default"].resolve((0, _utils.resolveTilde)(file_path));
18
+
19
+ return {
20
+ filename: _path["default"].basename(abs_path),
21
+ contentType: _mimeTypes["default"].lookup(abs_path),
22
+ data: (0, _utils.base64Encode)(abs_path)
23
+ };
24
+ }
25
+
26
+ module.exports = exports.default;
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports["default"] = void 0;
9
+
10
+ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
11
+
12
+ var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
13
+
14
+ var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
15
+
16
+ var BulkResponse = /*#__PURE__*/function () {
17
+ function BulkResponse() {
18
+ (0, _classCallCheck2["default"])(this, BulkResponse);
19
+ this.status;
20
+ this.failed_records = [];
21
+ this.total = 0;
22
+ this.success = 0;
23
+ this.failure = 0;
24
+ this.warnings = [];
25
+ }
26
+
27
+ (0, _createClass2["default"])(BulkResponse, [{
28
+ key: "merge_chunk_response",
29
+ value: function merge_chunk_response(ch_resp) {
30
+ if (!ch_resp) {
31
+ return;
32
+ } // possible status: success/partial/fail
33
+
34
+
35
+ if (!this.status) {
36
+ this.status = ch_resp["status"];
37
+ } else {
38
+ if (this.status === "success") {
39
+ if (ch_resp.status === "fail") {
40
+ this.status = "partial";
41
+ }
42
+ } else if (this.status === "fail") {
43
+ if (ch_resp.status === "success") {
44
+ this.status = "partial";
45
+ }
46
+ }
47
+ }
48
+
49
+ this.total += ch_resp.total || 0;
50
+ this.success += ch_resp.success || 0;
51
+ this.failure += ch_resp.failure || 0;
52
+ var failed_recs = ch_resp.failed_records || [];
53
+ this.failed_records = [].concat((0, _toConsumableArray2["default"])(this.failed_records), (0, _toConsumableArray2["default"])(failed_recs));
54
+ }
55
+ }]);
56
+ return BulkResponse;
57
+ }();
58
+
59
+ exports["default"] = BulkResponse;
60
+ module.exports = exports.default;
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.WORKFLOW_RUNTIME_KEYS_POTENTIAL_SIZE_IN_BYTES = exports.MAX_WORKFLOWS_IN_BULK_API = exports.MAX_IDENTITY_EVENTS_IN_BULK_API = exports.MAX_EVENTS_IN_BULK_API = exports.IDENTITY_SINGLE_EVENT_MAX_APPARENT_SIZE_IN_BYTES_READABLE = exports.IDENTITY_SINGLE_EVENT_MAX_APPARENT_SIZE_IN_BYTES = exports.DEFAULT_URL = exports.DEFAULT_UAT_URL = exports.BODY_MAX_APPARENT_SIZE_IN_BYTES_READABLE = exports.BODY_MAX_APPARENT_SIZE_IN_BYTES = exports.ATTACHMENT_URL_POTENTIAL_SIZE_IN_BYTES = exports.ATTACHMENT_UPLOAD_ENABLED = exports.ALLOW_ATTACHMENTS_IN_BULK_API = void 0;
7
+ // Default urls
8
+ var DEFAULT_URL = "https://hub.suprsend.com/";
9
+ exports.DEFAULT_URL = DEFAULT_URL;
10
+ var DEFAULT_UAT_URL = "https://collector-staging.suprsend.workers.dev/"; // a API call should not have apparent body size of more than 800KB
11
+
12
+ exports.DEFAULT_UAT_URL = DEFAULT_UAT_URL;
13
+ var BODY_MAX_APPARENT_SIZE_IN_BYTES = 800 * 1024; // 800 * 1024
14
+
15
+ exports.BODY_MAX_APPARENT_SIZE_IN_BYTES = BODY_MAX_APPARENT_SIZE_IN_BYTES;
16
+ var BODY_MAX_APPARENT_SIZE_IN_BYTES_READABLE = "800KB"; // in general url-size wont exceed 2048 chars or 2048 utf-8 bytes
17
+
18
+ exports.BODY_MAX_APPARENT_SIZE_IN_BYTES_READABLE = BODY_MAX_APPARENT_SIZE_IN_BYTES_READABLE;
19
+ var ATTACHMENT_URL_POTENTIAL_SIZE_IN_BYTES = 2100; // few keys added in-flight, amounting to almost 200 bytes increase per workflow-body
20
+
21
+ exports.ATTACHMENT_URL_POTENTIAL_SIZE_IN_BYTES = ATTACHMENT_URL_POTENTIAL_SIZE_IN_BYTES;
22
+ var WORKFLOW_RUNTIME_KEYS_POTENTIAL_SIZE_IN_BYTES = 200; // max workflow-records in one bulk api call.
23
+
24
+ exports.WORKFLOW_RUNTIME_KEYS_POTENTIAL_SIZE_IN_BYTES = WORKFLOW_RUNTIME_KEYS_POTENTIAL_SIZE_IN_BYTES;
25
+ var MAX_WORKFLOWS_IN_BULK_API = 100; // max event-records in one bulk api call
26
+
27
+ exports.MAX_WORKFLOWS_IN_BULK_API = MAX_WORKFLOWS_IN_BULK_API;
28
+ var MAX_EVENTS_IN_BULK_API = 100;
29
+ exports.MAX_EVENTS_IN_BULK_API = MAX_EVENTS_IN_BULK_API;
30
+ var ALLOW_ATTACHMENTS_IN_BULK_API = false;
31
+ exports.ALLOW_ATTACHMENTS_IN_BULK_API = ALLOW_ATTACHMENTS_IN_BULK_API;
32
+ var ATTACHMENT_UPLOAD_ENABLED = false; // -- single Identity event limit
33
+
34
+ exports.ATTACHMENT_UPLOAD_ENABLED = ATTACHMENT_UPLOAD_ENABLED;
35
+ var IDENTITY_SINGLE_EVENT_MAX_APPARENT_SIZE_IN_BYTES = 2 * 1024;
36
+ exports.IDENTITY_SINGLE_EVENT_MAX_APPARENT_SIZE_IN_BYTES = IDENTITY_SINGLE_EVENT_MAX_APPARENT_SIZE_IN_BYTES;
37
+ var IDENTITY_SINGLE_EVENT_MAX_APPARENT_SIZE_IN_BYTES_READABLE = "2KB";
38
+ exports.IDENTITY_SINGLE_EVENT_MAX_APPARENT_SIZE_IN_BYTES_READABLE = IDENTITY_SINGLE_EVENT_MAX_APPARENT_SIZE_IN_BYTES_READABLE;
39
+ var MAX_IDENTITY_EVENTS_IN_BULK_API = 400;
40
+ exports.MAX_IDENTITY_EVENTS_IN_BULK_API = MAX_IDENTITY_EVENTS_IN_BULK_API;
package/dist/event.js CHANGED
@@ -5,12 +5,14 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
5
5
  Object.defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
- exports["default"] = void 0;
8
+ exports["default"] = exports.EventCollector = void 0;
9
9
 
10
10
  var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
11
11
 
12
12
  var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
13
13
 
14
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
15
+
14
16
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
15
17
 
16
18
  var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
@@ -21,25 +23,133 @@ var _utils = require("./utils");
21
23
 
22
24
  var _signature = _interopRequireDefault(require("./signature"));
23
25
 
24
- var _jsonschema = require("jsonschema");
25
-
26
26
  var _axios = _interopRequireDefault(require("axios"));
27
27
 
28
+ var _attachment = _interopRequireDefault(require("./attachment"));
29
+
30
+ var _constants = require("./constants");
31
+
28
32
  function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
29
33
 
30
34
  function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
31
35
 
32
- var event_schema = require("./request_json/event.json");
33
-
34
36
  var RESERVED_EVENT_NAMES = ["$identify", "$notification_delivered", "$notification_dismiss", "$notification_clicked", "$app_launched", "$user_login", "$user_logout"];
35
37
 
38
+ var Event = /*#__PURE__*/function () {
39
+ function Event(distinct_id, event_name, properties, idempotency_key) {
40
+ (0, _classCallCheck2["default"])(this, Event);
41
+ this.distinct_id = distinct_id;
42
+ this.event_name = event_name;
43
+ this.properties = properties;
44
+ this.idempotency_key = idempotency_key; // --- validate
45
+
46
+ this.__validate_distinct_id();
47
+
48
+ this.__validate_event_name();
49
+
50
+ this.__validate_properties();
51
+ }
52
+
53
+ (0, _createClass2["default"])(Event, [{
54
+ key: "__validate_distinct_id",
55
+ value: function __validate_distinct_id() {
56
+ if (this.distinct_id instanceof String) {
57
+ throw new _utils.SuprsendError("distinct_id must be a string. an Id which uniquely identify a user in your app");
58
+ }
59
+
60
+ var distinct_id = this.distinct_id.trim();
61
+
62
+ if (!distinct_id) {
63
+ throw new _utils.SuprsendError("distinct_id missing");
64
+ }
65
+
66
+ this.distinct_id = distinct_id;
67
+ }
68
+ }, {
69
+ key: "__validate_properties",
70
+ value: function __validate_properties() {
71
+ if (!this.properties) {
72
+ this.properties = {};
73
+ }
74
+
75
+ if (!(this.properties instanceof Object)) {
76
+ throw new _utils.SuprsendError("properties must be a dictionary");
77
+ }
78
+ }
79
+ }, {
80
+ key: "__check_event_prefix",
81
+ value: function __check_event_prefix(event_name) {
82
+ if (!RESERVED_EVENT_NAMES.includes(event_name)) {
83
+ if ((0, _utils.has_special_char)(event_name)) {
84
+ throw new _utils.SuprsendError("event_names starting with [$,ss_] are reserved by SuprSend");
85
+ }
86
+ }
87
+ }
88
+ }, {
89
+ key: "__validate_event_name",
90
+ value: function __validate_event_name() {
91
+ if (!(0, _utils.is_string)(this.event_name)) {
92
+ throw new _utils.SuprsendError("event_name must be a string");
93
+ }
94
+
95
+ var event_name = this.event_name.trim();
96
+
97
+ this.__check_event_prefix(event_name);
98
+
99
+ this.event_name = event_name;
100
+ }
101
+ }, {
102
+ key: "add_attachment",
103
+ value: function add_attachment(file_path) {
104
+ var attachment = (0, _attachment["default"])(file_path); // --- add the attachment to properties->$attachments
105
+
106
+ if (!this.properties["$attachments"]) {
107
+ this.properties["$attachments"] = [];
108
+ }
109
+
110
+ this.properties["$attachments"].push(attachment);
111
+ }
112
+ }, {
113
+ key: "get_final_json",
114
+ value: function get_final_json(config) {
115
+ var is_part_of_bulk = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
116
+ var super_props = {
117
+ $ss_sdk_version: config.user_agent
118
+ };
119
+ var event_dict = {
120
+ $insert_id: (0, _utils.uuid)(),
121
+ $time: (0, _utils.epoch_milliseconds)(),
122
+ event: this.event_name,
123
+ env: config.workspace_key,
124
+ distinct_id: this.distinct_id,
125
+ properties: _objectSpread(_objectSpread({}, this.properties), super_props)
126
+ };
127
+
128
+ if (this.idempotency_key) {
129
+ event_dict["$idempotency_key"] = this.idempotency_key;
130
+ }
131
+
132
+ event_dict = (0, _utils.validate_track_event_schema)(event_dict);
133
+ var apparent_size = (0, _utils.get_apparent_event_size)(event_dict, is_part_of_bulk);
134
+
135
+ if (apparent_size > _constants.BODY_MAX_APPARENT_SIZE_IN_BYTES) {
136
+ throw new _utils.SuprsendError("Event properties too big - ".concat(apparent_size, " Bytes,must not cross ").concat(_constants.BODY_MAX_APPARENT_SIZE_IN_BYTES_READABLE));
137
+ }
138
+
139
+ return [event_dict, apparent_size];
140
+ }
141
+ }]);
142
+ return Event;
143
+ }();
144
+
145
+ exports["default"] = Event;
146
+
36
147
  var EventCollector = /*#__PURE__*/function () {
37
148
  function EventCollector(config) {
38
149
  (0, _classCallCheck2["default"])(this, EventCollector);
39
150
  this.config = config;
40
151
  this.__url = this.__get_url();
41
152
  this.__headers = this.__common_headers();
42
- this.__supr_props = this.__super_properties();
43
153
  }
44
154
 
45
155
  (0, _createClass2["default"])(EventCollector, [{
@@ -72,81 +182,21 @@ var EventCollector = /*#__PURE__*/function () {
72
182
  Date: new Date().toUTCString()
73
183
  };
74
184
  }
75
- }, {
76
- key: "__super_properties",
77
- value: function __super_properties() {
78
- return {
79
- $ss_sdk_version: this.config.user_agent
80
- };
81
- }
82
- }, {
83
- key: "__check_event_prefix",
84
- value: function __check_event_prefix(event_name) {
85
- if (!RESERVED_EVENT_NAMES.includes(event_name)) {
86
- if ((0, _utils.has_special_char)(event_name)) {
87
- throw new _utils.SuprsendError("event_names starting with [$,ss_] are reserved");
88
- }
89
- }
90
- }
91
- }, {
92
- key: "__validate_event_name",
93
- value: function __validate_event_name(event_name) {
94
- if (!(0, _utils.is_string)(event_name)) {
95
- throw new _utils.SuprsendError("event_name must be a string");
96
- }
97
-
98
- event_name = event_name.trim();
99
-
100
- this.__check_event_prefix(event_name);
101
-
102
- return event_name;
103
- }
104
- }, {
105
- key: "validate_track_event_schema",
106
- value: function validate_track_event_schema(data) {
107
- if (!data["properties"]) {
108
- data["properties"] = {};
109
- }
110
-
111
- var schema = event_schema;
112
- var v = new _jsonschema.Validator();
113
- var validated_data = v.validate(data, schema);
114
-
115
- if (validated_data.valid) {
116
- return data;
117
- } else {
118
- var error_obj = validated_data.errors[0];
119
- var error_msg = "".concat(error_obj.property, " ").concat(error_obj.message);
120
- throw new _utils.SuprsendError(error_msg);
121
- }
122
- }
123
185
  }, {
124
186
  key: "collect",
125
- value: function collect(distinct_id, event_name) {
126
- var properties = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
127
- event_name = this.__validate_event_name(event_name);
187
+ value: function collect(event) {
188
+ var _event$get_final_json = event.get_final_json(this.config, false),
189
+ _event$get_final_json2 = (0, _slicedToArray2["default"])(_event$get_final_json, 2),
190
+ event_dict = _event$get_final_json2[0],
191
+ event_size = _event$get_final_json2[1];
128
192
 
129
- if (!(0, _utils.is_object)(properties)) {
130
- throw new _utils.SuprsendError("properties must be a dictionary");
131
- }
132
-
133
- properties = _objectSpread(_objectSpread({}, properties), this.__supr_props);
134
- var event = {
135
- $insert_id: (0, _utils.uuid)(),
136
- $time: (0, _utils.epoch_milliseconds)(),
137
- event: event_name,
138
- env: this.config.env_key,
139
- distinct_id: distinct_id,
140
- properties: properties
141
- };
142
- event = this.validate_track_event_schema(event);
143
- return this.send(event);
193
+ return this.send(event_dict);
144
194
  }
145
195
  }, {
146
196
  key: "send",
147
197
  value: function () {
148
198
  var _send = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee(event) {
149
- var headers, content_text, signature, response;
199
+ var headers, content_text, signature, response, ok_response;
150
200
  return _regenerator["default"].wrap(function _callee$(_context) {
151
201
  while (1) {
152
202
  switch (_context.prev = _context.next) {
@@ -155,8 +205,8 @@ var EventCollector = /*#__PURE__*/function () {
155
205
  content_text = JSON.stringify(event);
156
206
 
157
207
  if (this.config.auth_enabled) {
158
- signature = (0, _signature["default"])(this.__url, "POST", content_text, headers, this.config.env_secret);
159
- headers["Authorization"] = "".concat(this.config.env_key, ":").concat(signature);
208
+ signature = (0, _signature["default"])(this.__url, "POST", content_text, headers, this.config.workspace_secret);
209
+ headers["Authorization"] = "".concat(this.config.workspace_key, ":").concat(signature);
160
210
  }
161
211
 
162
212
  _context.prev = 3;
@@ -167,27 +217,48 @@ var EventCollector = /*#__PURE__*/function () {
167
217
 
168
218
  case 6:
169
219
  response = _context.sent;
220
+ ok_response = Math.floor(response.status / 100) == 2;
221
+
222
+ if (!ok_response) {
223
+ _context.next = 12;
224
+ break;
225
+ }
226
+
170
227
  return _context.abrupt("return", {
171
- status_code: response.status,
172
228
  success: true,
229
+ status: "success",
230
+ status_code: response.status,
173
231
  message: response.statusText
174
232
  });
175
233
 
176
- case 10:
177
- _context.prev = 10;
234
+ case 12:
235
+ return _context.abrupt("return", {
236
+ success: false,
237
+ status: "fail",
238
+ status_code: response.status,
239
+ message: response.statusText
240
+ });
241
+
242
+ case 13:
243
+ _context.next = 18;
244
+ break;
245
+
246
+ case 15:
247
+ _context.prev = 15;
178
248
  _context.t0 = _context["catch"](3);
179
249
  return _context.abrupt("return", {
180
- status_code: 400,
181
250
  success: false,
251
+ status: "fail",
252
+ status_code: _context.t0.status || 500,
182
253
  message: _context.t0.message
183
254
  });
184
255
 
185
- case 13:
256
+ case 18:
186
257
  case "end":
187
258
  return _context.stop();
188
259
  }
189
260
  }
190
- }, _callee, this, [[3, 10]]);
261
+ }, _callee, this, [[3, 15]]);
191
262
  }));
192
263
 
193
264
  function send(_x) {
@@ -200,6 +271,4 @@ var EventCollector = /*#__PURE__*/function () {
200
271
  return EventCollector;
201
272
  }();
202
273
 
203
- var _default = EventCollector;
204
- exports["default"] = _default;
205
- module.exports = exports.default;
274
+ exports.EventCollector = EventCollector;