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/src/index.js CHANGED
@@ -56,6 +56,17 @@ const parseInitConfig = (...args) => {
56
56
  }
57
57
  }
58
58
 
59
+ const validateConfig = config => {
60
+ if (config.domain) {
61
+ if (!config.domain.startsWith('https://') && !config.domain.startsWith('http://')) {
62
+ throw new Error(
63
+ 'When initialize the SDK with a custom domain it should start with http:// or https://, ' +
64
+ 'for example: Backendless.initApp(\'https://foobar.com\')'
65
+ )
66
+ }
67
+ }
68
+ }
69
+
59
70
  const SERVICES = {
60
71
  'Logging' : () => require('./logging').default,
61
72
  'Counters' : () => require('./counters').default,
@@ -86,6 +97,13 @@ class Backendless {
86
97
  * @param {Object} config
87
98
  */
88
99
  initConfig(config) {
100
+ config = { ...config }
101
+
102
+ if (config.domain) {
103
+ delete config.appId
104
+ delete config.apiKey
105
+ }
106
+
89
107
  for (const key in DEFAULT_PROPS) {
90
108
  if (DEFAULT_PROPS.hasOwnProperty(key)) {
91
109
  const privateKey = `__${key}`
@@ -107,12 +125,14 @@ class Backendless {
107
125
 
108
126
  /**
109
127
  * @param {string|Object} appId|domain|config
110
- * @param {string} [secretKey]
128
+ * @param {string} [apiKey]
111
129
  * @returns {Backendless}
112
130
  */
113
131
  initApp() {
114
132
  const config = parseInitConfig(...arguments)
115
133
 
134
+ validateConfig(config)
135
+
116
136
  const app = config.standalone
117
137
  ? new Backendless(this)
118
138
  : this
@@ -170,26 +190,24 @@ class Backendless {
170
190
  )
171
191
  }
172
192
 
173
- ///--------applicationId-------///
174
- get applicationId() {
193
+ get appId() {
175
194
  return this.__appId
176
195
  }
177
196
 
178
- set applicationId(appId) {
197
+ set appId(appId) {
179
198
  throw new Error(
180
- `Setting '${appId}' value to Backendless.applicationId directly is not possible, ` +
199
+ `Setting '${appId}' value to Backendless.appId directly is not possible, ` +
181
200
  `instead you must use Backendless.initApp('${appId}', API_KEY)`
182
201
  )
183
202
  }
184
203
 
185
- ///--------secretKey-------///
186
- get secretKey() {
204
+ get apiKey() {
187
205
  return this.__apiKey
188
206
  }
189
207
 
190
- set secretKey(apiKey) {
208
+ set apiKey(apiKey) {
191
209
  throw new Error(
192
- `Setting '${apiKey}' value to Backendless.secretKey directly is not possible, ` +
210
+ `Setting '${apiKey}' value to Backendless.apiKey directly is not possible, ` +
193
211
  `instead you must use Backendless.initApp(APP_ID, '${apiKey}')`
194
212
  )
195
213
  }
@@ -227,7 +245,7 @@ class Backendless {
227
245
  return this.domain + this.apiURI
228
246
  }
229
247
 
230
- return [this.serverURL, this.applicationId, this.secretKey].join('/')
248
+ return [this.serverURL, this.appId, this.apiKey].join('/')
231
249
  }
232
250
 
233
251
  set appPath(appPath) {
@@ -399,7 +417,38 @@ class Backendless {
399
417
  ///-------------------------------------///
400
418
  ///--------BACKWARD COMPATIBILITY-------///
401
419
 
402
- //TODO: do we need to remove it?
420
+ /** @deprecated */
421
+ get applicationId() {
422
+ // eslint-disable-next-line no-console
423
+ // temporary comment it because it breaks JS-CodeRunner version less than 6.3.0
424
+ // console.warn('getter/setter for Backendless.applicationId is deprecated, instead use Backendless.appId')
425
+
426
+ return this.appId
427
+ }
428
+
429
+ /** @deprecated */
430
+ set applicationId(appId) {
431
+ // eslint-disable-next-line no-console
432
+ console.warn('getter/setter for Backendless.applicationId is deprecated, instead use Backendless.appId')
433
+
434
+ this.appId = appId
435
+ }
436
+
437
+ /** @deprecated */
438
+ get secretKey() {
439
+ // eslint-disable-next-line no-console
440
+ console.warn('getter/setter for Backendless.secretKey is deprecated, instead use Backendless.apiKey')
441
+
442
+ return this.apiKey
443
+ }
444
+
445
+ /** @deprecated */
446
+ set secretKey(apiKey) {
447
+ // eslint-disable-next-line no-console
448
+ console.warn('getter/setter for Backendless.secretKey is deprecated, instead use Backendless.apiKey')
449
+
450
+ this.apiKey = apiKey
451
+ }
403
452
 
404
453
  /** @deprecated */
405
454
  get Persistence() {
@@ -9,7 +9,7 @@ export default class LocalCache {
9
9
  constructor(app) {
10
10
  this.app = app
11
11
 
12
- this.storageName = `${STORAGE_KEY_NAMESPACE}_${this.app.applicationId}`
12
+ this.storageName = `${STORAGE_KEY_NAMESPACE}_${this.app.appId}`
13
13
 
14
14
  const Storage = Utils.isLocalStorageSupported
15
15
  ? LocalStorage
@@ -18,6 +18,7 @@ export default class EmailEnvelope {
18
18
  this.ccAddresses = Utils.castArray(data.ccAddresses)
19
19
  this.bccAddresses = Utils.castArray(data.bccAddresses)
20
20
  this.query = data.query || null
21
+ this.uniqueEmails = data.uniqueEmails || false
21
22
  }
22
23
 
23
24
  /**
@@ -129,6 +130,23 @@ export default class EmailEnvelope {
129
130
  return this.query
130
131
  }
131
132
 
133
+ /**
134
+ * @param {boolean} uniqueEmails
135
+ * @returns {EmailEnvelope}
136
+ */
137
+ setUniqueEmails(uniqueEmails) {
138
+ this.uniqueEmails = uniqueEmails
139
+
140
+ return this
141
+ }
142
+
143
+ /**
144
+ * @returns {uniqueEmails|boolean}
145
+ */
146
+ getUniqueEmails() {
147
+ return this.uniqueEmails
148
+ }
149
+
132
150
  toJSON() {
133
151
  const data = {}
134
152
 
@@ -148,6 +166,8 @@ export default class EmailEnvelope {
148
166
  data.criteria = this.query
149
167
  }
150
168
 
169
+ data.uniqueEmails = this.uniqueEmails
170
+
151
171
  return data
152
172
  }
153
173
  }
@@ -118,10 +118,14 @@ export default class Messaging {
118
118
 
119
119
  data['template-name'] = templateName
120
120
 
121
- if (templateValues) {
121
+ if (templateValues && !Array.isArray(templateValues)) {
122
122
  data['template-values'] = templateValues
123
123
  }
124
124
 
125
+ if (Array.isArray(templateValues) && !attachments) {
126
+ attachments = templateValues
127
+ }
128
+
125
129
  if (attachments) {
126
130
  data.attachment = attachments
127
131
  }
package/src/rt.js CHANGED
@@ -1,3 +1,4 @@
1
+ import Request from 'backendless-request'
1
2
  import BackendlessRTClient from 'backendless-rt-client'
2
3
 
3
4
  import Utils from './utils'
@@ -5,25 +6,41 @@ import Utils from './utils'
5
6
  export const RTListeners = BackendlessRTClient.Listeners
6
7
  export const RTScopeConnector = BackendlessRTClient.ScopeConnector
7
8
 
9
+ function loadAppInfo(appPath) {
10
+ return Request.get(`${appPath}/info`)
11
+ }
12
+
8
13
  export default class RT extends BackendlessRTClient {
9
14
  constructor(app) {
10
- const { applicationId: appId, secretKey: apiKey, appPath, debugMode } = app
15
+ const { appId, apiKey, appPath, debugMode } = app
11
16
 
12
17
  const clientId = Utils.uuid()
13
18
  const lookupPath = `${appPath}/rt/lookup`
14
19
 
15
20
  super({
16
- appId,
21
+ appId: appId || undefined,
17
22
  lookupPath,
18
23
  debugMode,
19
24
  connectQuery() {
20
25
  const userToken = app.getCurrentUserToken()
21
26
 
22
27
  return {
23
- apiKey,
28
+ apiKey: apiKey || undefined,
24
29
  clientId,
25
30
  userToken,
26
31
  }
32
+ },
33
+
34
+ socketConfigTransform: async socketConfig => {
35
+ if (!appId) {
36
+ const appInfo = await loadAppInfo(appPath)
37
+
38
+ socketConfig.url = `${socketConfig.host}/${appInfo.appId}`
39
+ socketConfig.options.path = `/${appInfo.appId}`
40
+ socketConfig.options.query.apiKey = appInfo.apiKey
41
+ }
42
+
43
+ return socketConfig
27
44
  }
28
45
  })
29
46
 
@@ -5,6 +5,8 @@ export const OperationType = {
5
5
  UPDATE_BULK : 'UPDATE_BULK',
6
6
  DELETE : 'DELETE',
7
7
  DELETE_BULK : 'DELETE_BULK',
8
+ UPSERT : 'UPSERT',
9
+ UPSERT_BULK : 'UPSERT_BULK',
8
10
  FIND : 'FIND',
9
11
  ADD_RELATION : 'ADD_RELATION',
10
12
  SET_RELATION : 'SET_RELATION',
@@ -219,6 +219,35 @@ class UnitOfWork {
219
219
  return this.addOperations(OperationType.FIND, tableName, payload)
220
220
  }
221
221
 
222
+ /**
223
+ * upsert(object: object): OpResult;
224
+ * upsert(tableName: string, object: object): OpResult;
225
+ * **/
226
+ upsert(...args) {
227
+ let tableName
228
+ let changes
229
+
230
+ if (args.length === 1) {
231
+ tableName = Utils.getClassName(args[0])
232
+ changes = args[0]
233
+ } else if (args.length === 2) {
234
+ tableName = args[0]
235
+ changes = args[1]
236
+ } else {
237
+ throw new Error('Invalid arguments')
238
+ }
239
+
240
+ if (!tableName || typeof tableName !== 'string') {
241
+ throw new Error('Invalid arguments')
242
+ }
243
+
244
+ if (!changes || typeof changes !== 'object' || Array.isArray(changes)) {
245
+ throw new Error('Invalid arguments')
246
+ }
247
+
248
+ return this.addOperations(OperationType.UPSERT, tableName, changes)
249
+ }
250
+
222
251
  /**
223
252
  * create(object: object): OpResult;
224
253
  * create(tableName: string, object: object): OpResult;
@@ -342,6 +371,27 @@ class UnitOfWork {
342
371
  return this.addOperations(OperationType.DELETE, tableName, object)
343
372
  }
344
373
 
374
+ /**
375
+ * bulkUpsert(tableName: string, objects: object[]): OpResult;
376
+ * bulkUpsert(objects: object[]): OpResult;
377
+ * **/
378
+ bulkUpsert(tableName, objects) {
379
+ if (Array.isArray(tableName)) {
380
+ objects = tableName
381
+ tableName = Utils.getClassName(objects[0])
382
+ }
383
+
384
+ if (!objects || !Array.isArray(objects)) {
385
+ throw new Error('Objects must be an array of objects.')
386
+ }
387
+
388
+ if (!tableName || typeof tableName !== 'string') {
389
+ throw new Error('Table Name must be a string.')
390
+ }
391
+
392
+ return this.addOperations(OperationType.UPSERT_BULK, tableName, objects)
393
+ }
394
+
345
395
  /**
346
396
  * bulkCreate(tableName: string, objects: object[]): OpResult;
347
397
  * bulkCreate(objects: object[]): OpResult;
@@ -600,7 +650,7 @@ export default function UnitOfWorkService(app) {
600
650
 
601
651
  opResult.setOpResultId(op.opResultId)
602
652
  })
603
-
653
+
604
654
  return uow
605
655
  }
606
656
 
@@ -41,6 +41,8 @@ export const OperationJSONAdapter = {
41
41
 
42
42
  UPDATE: (uow, { table, payload }) => uow.update.call(uow, table, resolveOpResultValueReference(uow, payload)),
43
43
 
44
+ UPSERT: (uow, { table, payload }) => uow.upsert.call(uow, table, resolveOpResultValueReference(uow, payload)),
45
+
44
46
  UPDATE_BULK: (uow, { table, payload }) => {
45
47
  const args = baseBulkArgs(uow, { table, payload })
46
48
 
@@ -59,6 +61,10 @@ export const OperationJSONAdapter = {
59
61
  return uow.bulkCreate.call(uow, table, resolveOpResultValueReference(uow, payload))
60
62
  },
61
63
 
64
+ UPSERT_BULK: (uow, { table, payload }) => {
65
+ return uow.bulkUpsert.call(uow, table, resolveOpResultValueReference(uow, payload))
66
+ },
67
+
62
68
  SET_RELATION: (uow, { table, payload }) => updateRelations(uow, 'setRelation', { table, payload }),
63
69
 
64
70
  DELETE_RELATION: (uow, { table, payload }) => updateRelations(uow, 'deleteRelation', { table, payload }),
package/src/urls.js CHANGED
@@ -109,6 +109,10 @@ export default class Urls {
109
109
  return `${this.data()}/${tableName}`
110
110
  }
111
111
 
112
+ dataTableUpsert(tableName) {
113
+ return `${this.data()}/${tableName}/upsert`
114
+ }
115
+
112
116
  dataTableDeepSave(tableName) {
113
117
  return `${this.data()}/${tableName}/deep-save`
114
118
  }
@@ -141,6 +145,10 @@ export default class Urls {
141
145
  return `${this.data()}/bulk/${tableName}`
142
146
  }
143
147
 
148
+ dataBulkTableUpsert(tableName) {
149
+ return `${this.data()}/bulkupsert/${tableName}`
150
+ }
151
+
144
152
  dataBulkTableDelete(tableName) {
145
153
  return `${this.dataBulkTable(tableName)}/delete`
146
154
  }