backendless 6.2.25 → 6.3.3

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/lib/index.js CHANGED
@@ -7,6 +7,8 @@ Object.defineProperty(exports, "__esModule", {
7
7
  });
8
8
  exports["default"] = void 0;
9
9
 
10
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
11
+
10
12
  var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
11
13
 
12
14
  var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
@@ -21,6 +23,10 @@ var _urls = _interopRequireDefault(require("./urls"));
21
23
 
22
24
  var _utils = _interopRequireDefault(require("./utils"));
23
25
 
26
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
27
+
28
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
29
+
24
30
  var DEFAULT_PROPS = {
25
31
  appId: null,
26
32
  apiKey: null,
@@ -71,6 +77,14 @@ var parseInitConfig = function parseInitConfig() {
71
77
  };
72
78
  };
73
79
 
80
+ var validateConfig = function validateConfig(config) {
81
+ if (config.domain) {
82
+ if (!config.domain.startsWith('https://') && !config.domain.startsWith('http://')) {
83
+ throw new Error('When initialize the SDK with a custom domain it should start with http:// or https://, ' + 'for example: Backendless.initApp(\'https://foobar.com\')');
84
+ }
85
+ }
86
+ };
87
+
74
88
  var SERVICES = {
75
89
  'Logging': function Logging() {
76
90
  return require('./logging')["default"];
@@ -129,6 +143,13 @@ var Backendless = /*#__PURE__*/function () {
129
143
  (0, _createClass2["default"])(Backendless, [{
130
144
  key: "initConfig",
131
145
  value: function initConfig(config) {
146
+ config = _objectSpread({}, config);
147
+
148
+ if (config.domain) {
149
+ delete config.appId;
150
+ delete config.apiKey;
151
+ }
152
+
132
153
  for (var key in DEFAULT_PROPS) {
133
154
  if (DEFAULT_PROPS.hasOwnProperty(key)) {
134
155
  var privateKey = "__".concat(key);
@@ -144,7 +165,7 @@ var Backendless = /*#__PURE__*/function () {
144
165
  }
145
166
  /**
146
167
  * @param {string|Object} appId|domain|config
147
- * @param {string} [secretKey]
168
+ * @param {string} [apiKey]
148
169
  * @returns {Backendless}
149
170
  */
150
171
 
@@ -152,6 +173,7 @@ var Backendless = /*#__PURE__*/function () {
152
173
  key: "initApp",
153
174
  value: function initApp() {
154
175
  var config = parseInitConfig.apply(void 0, arguments);
176
+ validateConfig(config);
155
177
  var app = config.standalone ? new Backendless(this) : this;
156
178
  app.initConfig(config);
157
179
  app.resetRT();
@@ -200,24 +222,22 @@ var Backendless = /*#__PURE__*/function () {
200
222
  },
201
223
  set: function set(standalone) {
202
224
  throw new Error('Setting value to Backendless.standalone directly is not possible, ' + "instead you must use Backendless.initApp({ appId: [APP_ID], apiKey: [API_KEY], standalone: ".concat(standalone, " })"));
203
- } ///--------applicationId-------///
204
-
225
+ }
205
226
  }, {
206
- key: "applicationId",
227
+ key: "appId",
207
228
  get: function get() {
208
229
  return this.__appId;
209
230
  },
210
231
  set: function set(appId) {
211
- throw new Error("Setting '".concat(appId, "' value to Backendless.applicationId directly is not possible, ") + "instead you must use Backendless.initApp('".concat(appId, "', API_KEY)"));
212
- } ///--------secretKey-------///
213
-
232
+ throw new Error("Setting '".concat(appId, "' value to Backendless.appId directly is not possible, ") + "instead you must use Backendless.initApp('".concat(appId, "', API_KEY)"));
233
+ }
214
234
  }, {
215
- key: "secretKey",
235
+ key: "apiKey",
216
236
  get: function get() {
217
237
  return this.__apiKey;
218
238
  },
219
239
  set: function set(apiKey) {
220
- throw new Error("Setting '".concat(apiKey, "' value to Backendless.secretKey directly is not possible, ") + "instead you must use Backendless.initApp(APP_ID, '".concat(apiKey, "')"));
240
+ throw new Error("Setting '".concat(apiKey, "' value to Backendless.apiKey directly is not possible, ") + "instead you must use Backendless.initApp(APP_ID, '".concat(apiKey, "')"));
221
241
  } ///--------serverURL-------///
222
242
 
223
243
  }, {
@@ -254,7 +274,7 @@ var Backendless = /*#__PURE__*/function () {
254
274
  return this.domain + this.apiURI;
255
275
  }
256
276
 
257
- return [this.serverURL, this.applicationId, this.secretKey].join('/');
277
+ return [this.serverURL, this.appId, this.apiKey].join('/');
258
278
  },
259
279
  set: function set(appPath) {
260
280
  throw new Error("Setting '".concat(appPath, "' value to Backendless.appPath directly is not possible, ") + 'instead you must use Backendless.initApp(APP_ID, API_KEY) for setup the value');
@@ -439,10 +459,42 @@ var Backendless = /*#__PURE__*/function () {
439
459
  ///-------------------------------------///
440
460
  ///-------------------------------------///
441
461
  ///--------BACKWARD COMPATIBILITY-------///
442
- //TODO: do we need to remove it?
443
462
 
444
463
  /** @deprecated */
445
464
 
465
+ }, {
466
+ key: "applicationId",
467
+ get: function get() {
468
+ // eslint-disable-next-line no-console
469
+ // temporary comment it because it breaks JS-CodeRunner version less than 6.3.0
470
+ // console.warn('getter/setter for Backendless.applicationId is deprecated, instead use Backendless.appId')
471
+ return this.appId;
472
+ }
473
+ /** @deprecated */
474
+ ,
475
+ set: function set(appId) {
476
+ // eslint-disable-next-line no-console
477
+ console.warn('getter/setter for Backendless.applicationId is deprecated, instead use Backendless.appId');
478
+ this.appId = appId;
479
+ }
480
+ /** @deprecated */
481
+
482
+ }, {
483
+ key: "secretKey",
484
+ get: function get() {
485
+ // eslint-disable-next-line no-console
486
+ console.warn('getter/setter for Backendless.secretKey is deprecated, instead use Backendless.apiKey');
487
+ return this.apiKey;
488
+ }
489
+ /** @deprecated */
490
+ ,
491
+ set: function set(apiKey) {
492
+ // eslint-disable-next-line no-console
493
+ console.warn('getter/setter for Backendless.secretKey is deprecated, instead use Backendless.apiKey');
494
+ this.apiKey = apiKey;
495
+ }
496
+ /** @deprecated */
497
+
446
498
  }, {
447
499
  key: "Persistence",
448
500
  get: function get() {
@@ -23,7 +23,7 @@ var LocalCache = /*#__PURE__*/function () {
23
23
  function LocalCache(app) {
24
24
  (0, _classCallCheck2["default"])(this, LocalCache);
25
25
  this.app = app;
26
- this.storageName = "".concat(STORAGE_KEY_NAMESPACE, "_").concat(this.app.applicationId);
26
+ this.storageName = "".concat(STORAGE_KEY_NAMESPACE, "_").concat(this.app.appId);
27
27
  var Storage = _utils["default"].isLocalStorageSupported ? _localStorage["default"] : _virtualStorage["default"];
28
28
  this.setStorage(Storage);
29
29
  this.Keys = {
@@ -21,6 +21,7 @@ var EmailEnvelope = /*#__PURE__*/function () {
21
21
  this.ccAddresses = _utils["default"].castArray(data.ccAddresses);
22
22
  this.bccAddresses = _utils["default"].castArray(data.bccAddresses);
23
23
  this.query = data.query || null;
24
+ this.uniqueEmails = data.uniqueEmails || false;
24
25
  }
25
26
  /**
26
27
  *
@@ -147,6 +148,26 @@ var EmailEnvelope = /*#__PURE__*/function () {
147
148
  value: function getQuery() {
148
149
  return this.query;
149
150
  }
151
+ /**
152
+ * @param {boolean} uniqueEmails
153
+ * @returns {EmailEnvelope}
154
+ */
155
+
156
+ }, {
157
+ key: "setUniqueEmails",
158
+ value: function setUniqueEmails(uniqueEmails) {
159
+ this.uniqueEmails = uniqueEmails;
160
+ return this;
161
+ }
162
+ /**
163
+ * @returns {uniqueEmails|boolean}
164
+ */
165
+
166
+ }, {
167
+ key: "getUniqueEmails",
168
+ value: function getUniqueEmails() {
169
+ return this.uniqueEmails;
170
+ }
150
171
  }, {
151
172
  key: "toJSON",
152
173
  value: function toJSON() {
@@ -168,6 +189,7 @@ var EmailEnvelope = /*#__PURE__*/function () {
168
189
  data.criteria = this.query;
169
190
  }
170
191
 
192
+ data.uniqueEmails = this.uniqueEmails;
171
193
  return data;
172
194
  }
173
195
  }], [{
@@ -247,10 +247,14 @@ var Messaging = /*#__PURE__*/function () {
247
247
  data = envelopeObject.toJSON();
248
248
  data['template-name'] = templateName;
249
249
 
250
- if (templateValues) {
250
+ if (templateValues && !Array.isArray(templateValues)) {
251
251
  data['template-values'] = templateValues;
252
252
  }
253
253
 
254
+ if (Array.isArray(templateValues) && !attachments) {
255
+ attachments = templateValues;
256
+ }
257
+
254
258
  if (attachments) {
255
259
  data.attachment = attachments;
256
260
  }
@@ -260,7 +264,7 @@ var Messaging = /*#__PURE__*/function () {
260
264
  data: data
261
265
  }));
262
266
 
263
- case 9:
267
+ case 10:
264
268
  case "end":
265
269
  return _context4.stop();
266
270
  }
package/lib/rt.js CHANGED
@@ -7,6 +7,10 @@ Object.defineProperty(exports, "__esModule", {
7
7
  });
8
8
  exports["default"] = exports.RTScopeConnector = exports.RTListeners = void 0;
9
9
 
10
+ var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
11
+
12
+ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
13
+
10
14
  var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
11
15
 
12
16
  var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
@@ -17,6 +21,8 @@ var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime
17
21
 
18
22
  var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
19
23
 
24
+ var _backendlessRequest = _interopRequireDefault(require("backendless-request"));
25
+
20
26
  var _backendlessRtClient = _interopRequireDefault(require("backendless-rt-client"));
21
27
 
22
28
  var _utils = _interopRequireDefault(require("./utils"));
@@ -30,6 +36,10 @@ exports.RTListeners = RTListeners;
30
36
  var RTScopeConnector = _backendlessRtClient["default"].ScopeConnector;
31
37
  exports.RTScopeConnector = RTScopeConnector;
32
38
 
39
+ function loadAppInfo(appPath) {
40
+ return _backendlessRequest["default"].get("".concat(appPath, "/info"));
41
+ }
42
+
33
43
  var RT = /*#__PURE__*/function (_BackendlessRTClient) {
34
44
  (0, _inherits2["default"])(RT, _BackendlessRTClient);
35
45
 
@@ -39,8 +49,8 @@ var RT = /*#__PURE__*/function (_BackendlessRTClient) {
39
49
  var _this;
40
50
 
41
51
  (0, _classCallCheck2["default"])(this, RT);
42
- var appId = app.applicationId,
43
- apiKey = app.secretKey,
52
+ var appId = app.appId,
53
+ apiKey = app.apiKey,
44
54
  appPath = app.appPath,
45
55
  debugMode = app.debugMode;
46
56
 
@@ -48,17 +58,55 @@ var RT = /*#__PURE__*/function (_BackendlessRTClient) {
48
58
 
49
59
  var lookupPath = "".concat(appPath, "/rt/lookup");
50
60
  _this = _super.call(this, {
51
- appId: appId,
61
+ appId: appId || undefined,
52
62
  lookupPath: lookupPath,
53
63
  debugMode: debugMode,
54
64
  connectQuery: function connectQuery() {
55
65
  var userToken = app.getCurrentUserToken();
56
66
  return {
57
- apiKey: apiKey,
67
+ apiKey: apiKey || undefined,
58
68
  clientId: clientId,
59
69
  userToken: userToken
60
70
  };
61
- }
71
+ },
72
+ socketConfigTransform: function () {
73
+ var _socketConfigTransform = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee(socketConfig) {
74
+ var appInfo;
75
+ return _regenerator["default"].wrap(function _callee$(_context) {
76
+ while (1) {
77
+ switch (_context.prev = _context.next) {
78
+ case 0:
79
+ if (appId) {
80
+ _context.next = 7;
81
+ break;
82
+ }
83
+
84
+ _context.next = 3;
85
+ return loadAppInfo(appPath);
86
+
87
+ case 3:
88
+ appInfo = _context.sent;
89
+ socketConfig.url = "".concat(socketConfig.host, "/").concat(appInfo.appId);
90
+ socketConfig.options.path = "/".concat(appInfo.appId);
91
+ socketConfig.options.query.apiKey = appInfo.apiKey;
92
+
93
+ case 7:
94
+ return _context.abrupt("return", socketConfig);
95
+
96
+ case 8:
97
+ case "end":
98
+ return _context.stop();
99
+ }
100
+ }
101
+ }, _callee);
102
+ }));
103
+
104
+ function socketConfigTransform(_x) {
105
+ return _socketConfigTransform.apply(this, arguments);
106
+ }
107
+
108
+ return socketConfigTransform;
109
+ }()
62
110
  });
63
111
  _this.app = app;
64
112
  return _this;
@@ -11,6 +11,8 @@ var OperationType = {
11
11
  UPDATE_BULK: 'UPDATE_BULK',
12
12
  DELETE: 'DELETE',
13
13
  DELETE_BULK: 'DELETE_BULK',
14
+ UPSERT: 'UPSERT',
15
+ UPSERT_BULK: 'UPSERT_BULK',
14
16
  FIND: 'FIND',
15
17
  ADD_RELATION: 'ADD_RELATION',
16
18
  SET_RELATION: 'SET_RELATION',
@@ -308,6 +308,37 @@ var UnitOfWork = /*#__PURE__*/function () {
308
308
 
309
309
  return this.addOperations(_constants.OperationType.FIND, tableName, payload);
310
310
  }
311
+ /**
312
+ * upsert(object: object): OpResult;
313
+ * upsert(tableName: string, object: object): OpResult;
314
+ * **/
315
+
316
+ }, {
317
+ key: "upsert",
318
+ value: function upsert() {
319
+ var tableName;
320
+ var changes;
321
+
322
+ if (arguments.length === 1) {
323
+ tableName = _utils["default"].getClassName(arguments.length <= 0 ? undefined : arguments[0]);
324
+ changes = arguments.length <= 0 ? undefined : arguments[0];
325
+ } else if (arguments.length === 2) {
326
+ tableName = arguments.length <= 0 ? undefined : arguments[0];
327
+ changes = arguments.length <= 1 ? undefined : arguments[1];
328
+ } else {
329
+ throw new Error('Invalid arguments');
330
+ }
331
+
332
+ if (!tableName || typeof tableName !== 'string') {
333
+ throw new Error('Invalid arguments');
334
+ }
335
+
336
+ if (!changes || (0, _typeof2["default"])(changes) !== 'object' || Array.isArray(changes)) {
337
+ throw new Error('Invalid arguments');
338
+ }
339
+
340
+ return this.addOperations(_constants.OperationType.UPSERT, tableName, changes);
341
+ }
311
342
  /**
312
343
  * create(object: object): OpResult;
313
344
  * create(tableName: string, object: object): OpResult;
@@ -436,6 +467,29 @@ var UnitOfWork = /*#__PURE__*/function () {
436
467
 
437
468
  return this.addOperations(_constants.OperationType.DELETE, tableName, object);
438
469
  }
470
+ /**
471
+ * bulkUpsert(tableName: string, objects: object[]): OpResult;
472
+ * bulkUpsert(objects: object[]): OpResult;
473
+ * **/
474
+
475
+ }, {
476
+ key: "bulkUpsert",
477
+ value: function bulkUpsert(tableName, objects) {
478
+ if (Array.isArray(tableName)) {
479
+ objects = tableName;
480
+ tableName = _utils["default"].getClassName(objects[0]);
481
+ }
482
+
483
+ if (!objects || !Array.isArray(objects)) {
484
+ throw new Error('Objects must be an array of objects.');
485
+ }
486
+
487
+ if (!tableName || typeof tableName !== 'string') {
488
+ throw new Error('Table Name must be a string.');
489
+ }
490
+
491
+ return this.addOperations(_constants.OperationType.UPSERT_BULK, tableName, objects);
492
+ }
439
493
  /**
440
494
  * bulkCreate(tableName: string, objects: object[]): OpResult;
441
495
  * bulkCreate(objects: object[]): OpResult;
@@ -63,9 +63,14 @@ var OperationJSONAdapter = {
63
63
  payload = _ref3.payload;
64
64
  return uow.update.call(uow, table, resolveOpResultValueReference(uow, payload));
65
65
  },
66
- UPDATE_BULK: function UPDATE_BULK(uow, _ref4) {
66
+ UPSERT: function UPSERT(uow, _ref4) {
67
67
  var table = _ref4.table,
68
68
  payload = _ref4.payload;
69
+ return uow.upsert.call(uow, table, resolveOpResultValueReference(uow, payload));
70
+ },
71
+ UPDATE_BULK: function UPDATE_BULK(uow, _ref5) {
72
+ var table = _ref5.table,
73
+ payload = _ref5.payload;
69
74
  var args = baseBulkArgs(uow, {
70
75
  table: table,
71
76
  payload: payload
@@ -73,55 +78,60 @@ var OperationJSONAdapter = {
73
78
  args.push(resolveOpResultValueReference(uow, payload.changes));
74
79
  return uow.bulkUpdate.apply(uow, args);
75
80
  },
76
- DELETE_BULK: function DELETE_BULK(uow, _ref5) {
77
- var table = _ref5.table,
78
- payload = _ref5.payload;
81
+ DELETE_BULK: function DELETE_BULK(uow, _ref6) {
82
+ var table = _ref6.table,
83
+ payload = _ref6.payload;
79
84
  var args = baseBulkArgs(uow, {
80
85
  table: table,
81
86
  payload: payload
82
87
  });
83
88
  return uow.bulkDelete.apply(uow, args);
84
89
  },
85
- CREATE_BULK: function CREATE_BULK(uow, _ref6) {
86
- var table = _ref6.table,
87
- payload = _ref6.payload;
88
- return uow.bulkCreate.call(uow, table, resolveOpResultValueReference(uow, payload));
89
- },
90
- SET_RELATION: function SET_RELATION(uow, _ref7) {
90
+ CREATE_BULK: function CREATE_BULK(uow, _ref7) {
91
91
  var table = _ref7.table,
92
92
  payload = _ref7.payload;
93
+ return uow.bulkCreate.call(uow, table, resolveOpResultValueReference(uow, payload));
94
+ },
95
+ UPSERT_BULK: function UPSERT_BULK(uow, _ref8) {
96
+ var table = _ref8.table,
97
+ payload = _ref8.payload;
98
+ return uow.bulkUpsert.call(uow, table, resolveOpResultValueReference(uow, payload));
99
+ },
100
+ SET_RELATION: function SET_RELATION(uow, _ref9) {
101
+ var table = _ref9.table,
102
+ payload = _ref9.payload;
93
103
  return updateRelations(uow, 'setRelation', {
94
104
  table: table,
95
105
  payload: payload
96
106
  });
97
107
  },
98
- DELETE_RELATION: function DELETE_RELATION(uow, _ref8) {
99
- var table = _ref8.table,
100
- payload = _ref8.payload;
108
+ DELETE_RELATION: function DELETE_RELATION(uow, _ref10) {
109
+ var table = _ref10.table,
110
+ payload = _ref10.payload;
101
111
  return updateRelations(uow, 'deleteRelation', {
102
112
  table: table,
103
113
  payload: payload
104
114
  });
105
115
  },
106
- ADD_RELATION: function ADD_RELATION(uow, _ref9) {
107
- var table = _ref9.table,
108
- payload = _ref9.payload;
116
+ ADD_RELATION: function ADD_RELATION(uow, _ref11) {
117
+ var table = _ref11.table,
118
+ payload = _ref11.payload;
109
119
  return updateRelations(uow, 'addToRelation', {
110
120
  table: table,
111
121
  payload: payload
112
122
  });
113
123
  },
114
- FIND: function FIND(uow, _ref10) {
115
- var table = _ref10.table,
116
- payload = _ref10.payload;
124
+ FIND: function FIND(uow, _ref12) {
125
+ var table = _ref12.table,
126
+ payload = _ref12.payload;
117
127
  return uow.addOperations(_constants.OperationType.FIND, table, payload);
118
128
  }
119
129
  };
120
130
  exports.OperationJSONAdapter = OperationJSONAdapter;
121
131
 
122
- function baseBulkArgs(uow, _ref11) {
123
- var table = _ref11.table,
124
- payload = _ref11.payload;
132
+ function baseBulkArgs(uow, _ref13) {
133
+ var table = _ref13.table,
134
+ payload = _ref13.payload;
125
135
  var args = [];
126
136
 
127
137
  if (payload.conditional) {
@@ -141,9 +151,9 @@ function baseBulkArgs(uow, _ref11) {
141
151
  return args;
142
152
  }
143
153
 
144
- function updateRelations(uow, method, _ref12) {
145
- var table = _ref12.table,
146
- payload = _ref12.payload;
154
+ function updateRelations(uow, method, _ref14) {
155
+ var table = _ref14.table,
156
+ payload = _ref14.payload;
147
157
  var args = [table];
148
158
 
149
159
  if (typeof payload.parentObject === 'string') {
package/lib/urls.js CHANGED
@@ -142,6 +142,11 @@ var Urls = /*#__PURE__*/function () {
142
142
  value: function dataTable(tableName) {
143
143
  return "".concat(this.data(), "/").concat(tableName);
144
144
  }
145
+ }, {
146
+ key: "dataTableUpsert",
147
+ value: function dataTableUpsert(tableName) {
148
+ return "".concat(this.data(), "/").concat(tableName, "/upsert");
149
+ }
145
150
  }, {
146
151
  key: "dataTableDeepSave",
147
152
  value: function dataTableDeepSave(tableName) {
@@ -182,6 +187,11 @@ var Urls = /*#__PURE__*/function () {
182
187
  value: function dataBulkTable(tableName) {
183
188
  return "".concat(this.data(), "/bulk/").concat(tableName);
184
189
  }
190
+ }, {
191
+ key: "dataBulkTableUpsert",
192
+ value: function dataBulkTableUpsert(tableName) {
193
+ return "".concat(this.data(), "/bulkupsert/").concat(tableName);
194
+ }
185
195
  }, {
186
196
  key: "dataBulkTableDelete",
187
197
  value: function dataBulkTableDelete(tableName) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "backendless",
3
- "version": "6.2.25",
3
+ "version": "6.3.3",
4
4
  "description": "Backendless JavaScript SDK for Node.js and the browser",
5
5
  "browser": "dist/backendless.js",
6
6
  "main": "lib/index.js",
@@ -92,6 +92,6 @@
92
92
  "dependencies": {
93
93
  "@babel/runtime": "^7.14.6",
94
94
  "backendless-request": "^0.1.1",
95
- "backendless-rt-client": "0.0.24"
95
+ "backendless-rt-client": "0.0.25"
96
96
  }
97
97
  }
@@ -1,13 +1,15 @@
1
1
  import { RTListeners } from '../rt'
2
2
 
3
3
  const ChangesTypes = {
4
- CREATED: 'created',
5
- UPDATED: 'updated',
6
- DELETED: 'deleted',
7
-
8
- BULK_CREATED: 'bulk-created',
9
- BULK_UPDATED: 'bulk-updated',
10
- BULK_DELETED: 'bulk-deleted',
4
+ CREATED : 'created',
5
+ UPDATED : 'updated',
6
+ DELETED : 'deleted',
7
+ UPSERTED: 'upserted',
8
+
9
+ BULK_CREATED : 'bulk-created',
10
+ BULK_UPDATED : 'bulk-updated',
11
+ BULK_DELETED : 'bulk-deleted',
12
+ BULK_UPSERTED: 'bulk-upserted',
11
13
  }
12
14
 
13
15
  const RelationsChangesTypes = {
@@ -20,6 +22,7 @@ const SingleChangesTypes = [
20
22
  ChangesTypes.CREATED,
21
23
  ChangesTypes.UPDATED,
22
24
  ChangesTypes.DELETED,
25
+ ChangesTypes.UPSERTED,
23
26
  ]
24
27
 
25
28
  export default class RTHandlers extends RTListeners {
@@ -53,6 +56,22 @@ export default class RTHandlers extends RTListeners {
53
56
  this.removeCreateListeners(undefined, callback)
54
57
  }
55
58
 
59
+ addUpsertListener(whereClause, callback, onError) {
60
+ this.addChangesListener(ChangesTypes.UPSERTED, whereClause, callback, onError)
61
+ }
62
+
63
+ removeUpsertListeners(whereClause, callback) {
64
+ this.removeChangesListeners(ChangesTypes.UPSERTED, whereClause, callback)
65
+ }
66
+
67
+ removeUpsertListener(callback) {
68
+ if (!callback || typeof callback !== 'function') {
69
+ throw new Error('Listener Function must be passed.')
70
+ }
71
+
72
+ this.removeUpsertListeners(undefined, callback)
73
+ }
74
+
56
75
  addUpdateListener(whereClause, callback, onError) {
57
76
  this.addChangesListener(ChangesTypes.UPDATED, whereClause, callback, onError)
58
77
  }
@@ -133,6 +152,22 @@ export default class RTHandlers extends RTListeners {
133
152
  this.removeBulkDeleteListeners(undefined, callback)
134
153
  }
135
154
 
155
+ addBulkUpsertListener(whereClause, callback, onError) {
156
+ this.addChangesListener(ChangesTypes.BULK_UPSERTED, whereClause, callback, onError)
157
+ }
158
+
159
+ removeBulkUpsertListeners() {
160
+ this.removeChangesListeners(ChangesTypes.BULK_UPSERTED)
161
+ }
162
+
163
+ removeBulkUpsertListener(callback) {
164
+ if (!callback || typeof callback !== 'function') {
165
+ throw new Error('Listener Function must be passed.')
166
+ }
167
+
168
+ this.removeChangesListeners(ChangesTypes.BULK_UPSERTED, undefined, callback)
169
+ }
170
+
136
171
  addSetRelationListener(relationColumnName, parentObjects, callback, onError) {
137
172
  this.addRelationsChangesListener(RelationsChangesTypes.SET, relationColumnName, parentObjects, callback, onError)
138
173
  }
package/src/data/store.js CHANGED
@@ -48,10 +48,14 @@ export default class DataStore {
48
48
  return this.rtHandlers = this.rtHandlers || new RTHandlers(this)
49
49
  }
50
50
 
51
- async save(object) {
51
+ async save(object, isUpsert) {
52
+ const url = isUpsert
53
+ ? this.app.urls.dataTableUpsert(this.className)
54
+ : this.app.urls.dataTable(this.className)
55
+
52
56
  return this.app.request
53
57
  .put({
54
- url : this.app.urls.dataTable(this.className),
58
+ url,
55
59
  data: convertToServerRecord(object),
56
60
  })
57
61
  .then(result => this.parseResponse(result))
@@ -229,6 +233,27 @@ export default class DataStore {
229
233
  })
230
234
  }
231
235
 
236
+ async bulkUpsert(objects) {
237
+ const errorMessage = 'Objects must be provided and must be an array of objects.'
238
+
239
+ if (!objects || !Array.isArray(objects) || !objects.length) {
240
+ throw new Error(errorMessage)
241
+ }
242
+
243
+ objects = objects.map(object => {
244
+ if (!object || typeof object !== 'object' || Array.isArray(object)) {
245
+ throw new Error(errorMessage)
246
+ }
247
+
248
+ return object
249
+ })
250
+
251
+ return this.app.request.put({
252
+ url : this.app.urls.dataBulkTableUpsert(this.className),
253
+ data: objects,
254
+ })
255
+ }
256
+
232
257
  async bulkUpdate(condition, changes) {
233
258
  if (!condition || typeof condition !== 'string') {
234
259
  throw new Error('Condition must be provided and must be a string.')