backend-manager 4.0.13 → 4.0.14

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.
@@ -18,6 +18,8 @@ function Settings(m) {
18
18
 
19
19
  Settings.prototype.resolve = function (assistant, schema, settings, options) {
20
20
  const self = this;
21
+
22
+ // Shortcuts
21
23
  const Manager = self.Manager;
22
24
 
23
25
  // Set settings
@@ -28,6 +30,8 @@ Settings.prototype.resolve = function (assistant, schema, settings, options) {
28
30
  options = options || {};
29
31
  options.dir = typeof options.dir === 'undefined' ? `${Manager.cwd}/schemas` : options.dir;
30
32
  options.schema = typeof options.schema === 'undefined' ? undefined : options.schema;
33
+ options.user = options.user || assistant.request.user;
34
+ options.checkRequired = typeof options.checkRequired === 'undefined' ? true : options.checkRequired;
31
35
 
32
36
  // Load schema if not provided and schema is defined in options
33
37
  // console.log('----schema:', schema);
@@ -40,7 +44,7 @@ Settings.prototype.resolve = function (assistant, schema, settings, options) {
40
44
  ) {
41
45
  const schemaPath = path.resolve(options.dir, `${options.schema.replace('.js', '')}.js`);
42
46
 
43
- schema = loadSchema(assistant, schemaPath, settings);
47
+ schema = loadSchema(assistant, schemaPath, settings, options);
44
48
  }
45
49
 
46
50
  // Resolve settings
@@ -66,7 +70,7 @@ Settings.prototype.resolve = function (assistant, schema, settings, options) {
66
70
  // Check if this node is marked as required
67
71
  let isRequired = false;
68
72
  if (typeof schemaNode.required === 'function') {
69
- isRequired = schemaNode.required(assistant);
73
+ isRequired = schemaNode.required(assistant, schemaPath, settings, options);
70
74
  } else if (typeof schemaNode.required === 'boolean') {
71
75
  isRequired = schemaNode.required;
72
76
  }
@@ -74,7 +78,7 @@ Settings.prototype.resolve = function (assistant, schema, settings, options) {
74
78
  // assistant.log('isRequired:', isRequired);
75
79
 
76
80
  // If the key is required and the original value is undefined, throw an error
77
- if (isRequired && typeof originalValue === 'undefined') {
81
+ if (options.checkRequired && isRequired && typeof originalValue === 'undefined') {
78
82
  throw assistant.errorify(`Required key {${path}} is missing in settings`, {code: 400});
79
83
  }
80
84
 
@@ -144,10 +148,12 @@ function processSchema(schema, fn, path) {
144
148
  });
145
149
  }
146
150
 
147
- function loadSchema(assistant, schema, settings) {
148
- const planId = assistant.request.user.plan.id;
151
+ function loadSchema(assistant, schema, settings, options) {
152
+ // Get plan ID
153
+ const planId = options?.user?.plan?.id || 'basic';
149
154
 
150
- const lib = require(schema)(assistant);
155
+ // Load schema
156
+ const lib = require(schema)(assistant, schema, settings, options);
151
157
  const def = lib.defaults;
152
158
  const plan = lib[planId];
153
159
 
@@ -4,19 +4,27 @@ let _;
4
4
  function Utilities(Manager) {
5
5
  const self = this;
6
6
 
7
+ // Libraries
7
8
  _ = require('lodash');
8
9
 
10
+ // Cache
9
11
  self.cache = {};
10
12
 
13
+ // Set Manager
11
14
  self.Manager = Manager;
12
15
  }
13
16
 
14
17
  Utilities.prototype.iterateCollection = function (callback, options) {
15
18
  const self = this;
19
+
20
+ // Shortcuts
16
21
  const Manager = self.Manager;
17
- const admin = Manager.libraries.admin;
18
22
 
19
23
  return new Promise(function(resolve, reject) {
24
+ // Libraries
25
+ const { admin } = Manager.libraries;
26
+
27
+ // Set counters
20
28
  let batch = -1;
21
29
  let collectionCount = 0;
22
30
 
@@ -147,33 +155,43 @@ Utilities.prototype.iterateCollection = function (callback, options) {
147
155
 
148
156
  Utilities.prototype.iterateUsers = function (callback, options) {
149
157
  const self = this;
158
+
159
+ // Shortcuts
150
160
  const Manager = self.Manager;
151
- const admin = Manager.libraries.admin;
152
161
 
153
162
  return new Promise(function(resolve, reject) {
163
+ // Libraries
164
+ const { admin } = Manager.libraries;
165
+
166
+ // Set counters
154
167
  let batch = -1;
155
168
 
169
+ // Set defaults
156
170
  options = options || {};
157
171
  options.batchSize = options.batchSize || 1000;
158
172
  options.log = options.log;
159
173
  options.pageToken = options.pageToken;
160
174
 
175
+ // List all users
161
176
  function listAllUsers(nextPageToken) {
162
177
  // List batch of users, 1000 at a time.
163
178
  admin.auth()
164
179
  .listUsers(options.batchSize, nextPageToken)
165
180
  .then(async (listUsersResult) => {
166
-
181
+ // Increment batch
167
182
  batch++;
168
183
 
184
+ // If no users, resolve
169
185
  if (listUsersResult.users.length === 0) {
170
186
  return resolve();
171
187
  }
172
188
 
189
+ // Log
173
190
  if (options.log) {
174
191
  console.log('Processing batch:', batch);
175
192
  }
176
193
 
194
+ // Callback
177
195
  callback({
178
196
  snap: listUsersResult,
179
197
  users: listUsersResult.users,
@@ -190,7 +208,6 @@ Utilities.prototype.iterateUsers = function (callback, options) {
190
208
  console.error('Callback failed', e);
191
209
  return reject(e)
192
210
  });
193
-
194
211
  })
195
212
  .catch((e) => {
196
213
  console.error('Query failed', e);
@@ -198,33 +215,157 @@ Utilities.prototype.iterateUsers = function (callback, options) {
198
215
  });
199
216
  }
200
217
 
218
+ // Run
201
219
  listAllUsers(options.pageToken);
202
220
  });
203
221
  };
204
222
 
223
+ Utilities.prototype.getDocumentWithOwnerUser = function (path, options) {
224
+ const self = this;
225
+
226
+ // Shortcuts
227
+ const Manager = self.Manager;
228
+
229
+ return new Promise(async function(resolve, reject) {
230
+ // Libraries
231
+ const { admin } = Manager.libraries;
232
+
233
+ // Set options
234
+ path = path || '';
235
+
236
+ // Set defaults
237
+ options = options || {};
238
+ options.owner = options.owner || 'owner.uid';
239
+ options.log = typeof options.log === 'undefined' ? false : options.log;
240
+
241
+ // Set resolve/schema options
242
+ options.resolve = options.resolve || {};
243
+ options.resolve.schema = options.resolve.schema || '';
244
+ options.resolve.checkRequired = options.resolve.checkRequired;
245
+ options.resolve.assistant = options.resolve.assistant;
246
+
247
+ // If no doc is provided, throw an error
248
+ if (!path) {
249
+ return reject(new Error('No document provided'));
250
+ }
251
+
252
+ // Get document
253
+ const document = await admin.firestore().doc(path)
254
+ .get()
255
+ .then(doc => {
256
+ const data = doc.data();
257
+
258
+ // If the document doesn't exist, throw an error
259
+ if (!doc.exists) {
260
+ return reject(new Error(`Document {${path}} not found`));
261
+ }
262
+
263
+ // Return
264
+ return data;
265
+ })
266
+ .catch((e) => e);
267
+
268
+ // Check for errors
269
+ if (document instanceof Error) {
270
+ return reject(document);
271
+ }
272
+
273
+ // Log the document
274
+ if (options.log) {
275
+ console.log('Document:', document);
276
+ }
277
+
278
+ // Resolve owner UID
279
+ const ownerUID = _.get(document, options.owner);
280
+
281
+ // Get the owner user
282
+ const user = admin.firestore().doc(`users/${ownerUID}`)
283
+ .get()
284
+ .then(doc => {
285
+ const data = doc.data();
286
+
287
+ // If the user doesn't exist, throw an error
288
+ if (!doc.exists) {
289
+ return reject(new Error(`User {${ownerUID}} not found`));
290
+ }
291
+
292
+ // Return
293
+ return data;
294
+ })
295
+ .catch((e) => e);
296
+
297
+ // Check for errors
298
+ if (user instanceof Error) {
299
+ return reject(user);
300
+ }
301
+
302
+ // Create the resolved user
303
+ const userResolved = Manager.User(user).properties;
304
+
305
+ // Log the user
306
+ if (options.log) {
307
+ console.log('User:', user);
308
+ console.log('User (resolved):', userResolved);
309
+ }
310
+
311
+ // Resolve with schema
312
+ if (options.resolve.schema) {
313
+ const documentResolved = Manager.Settings().resolve(options.resolve.assistant, undefined, document, {
314
+ schema: options.resolve.schema,
315
+ user: userResolved,
316
+ checkRequired: options.resolve.checkRequired,
317
+ });
318
+
319
+ // Log the resolved document
320
+ if (options.log) {
321
+ console.log('Document (resolved):', documentResolved);
322
+ }
323
+
324
+ // Return
325
+ return resolve({
326
+ document: documentResolved,
327
+ user: userResolved,
328
+ });
329
+ }
330
+
331
+ // Return without schema resolution
332
+ return resolve({
333
+ document: document,
334
+ user: userResolved,
335
+ });
336
+ });
337
+ };
338
+
205
339
  Utilities.prototype.randomId = function (options) {
206
340
  const self = this;
207
341
 
342
+ // Set defaults
208
343
  options = options || {};
209
344
  options.size = options.size || 14;
210
345
 
211
- if (!nanoId) {
212
- nanoId = require('nanoid');
346
+ // Load library
347
+ nanoId = nanoId
348
+ ? nanoId
349
+ : require('nanoid');
213
350
 
214
- nanoId = nanoId.customAlphabet(
215
- nanoId.urlAlphabet.replace(/_|-/g, ''),
216
- options.size,
217
- )
218
- }
351
+ // Custom alphabet
352
+ const alphabet = nanoId.customAlphabet(
353
+ nanoId.urlAlphabet.replace(/_|-/g, ''),
354
+ options.size,
355
+ )
219
356
 
220
- return nanoId();
357
+ // Return
358
+ return alphabet();
221
359
  };
222
360
 
223
361
  Utilities.prototype.get = function (docPath, options) {
224
362
  const self = this;
225
363
 
364
+ // Shortcuts
365
+ const Manager = self.Manager;
366
+
226
367
  return new Promise(function(resolve, reject) {
227
- const Manager = self.Manager;
368
+ // Libraries
228
369
  const { admin } = Manager.libraries;
229
370
 
230
371
  // Set defaults