@formio/appserver 2.0.0-rc.1 → 2.0.0-rc.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.
Files changed (46) hide show
  1. package/README.md +12 -6
  2. package/lib/actions/index.d.ts +11 -11
  3. package/lib/actions/login/LoginAction.d.ts +3 -2
  4. package/lib/actions/login/LoginAction.spec.d.ts +1 -0
  5. package/lib/actions/login/LoginAction.spec.js +15 -0
  6. package/lib/actions/role/RoleAction.spec.d.ts +1 -0
  7. package/lib/actions/role/RoleAction.spec.js +15 -0
  8. package/lib/actions/save/SaveAction.spec.d.ts +1 -0
  9. package/lib/actions/save/SaveAction.spec.js +15 -0
  10. package/lib/modules/auth/auth.spec.d.ts +1 -0
  11. package/lib/modules/auth/auth.spec.js +93 -0
  12. package/lib/modules/index.d.ts +1 -1
  13. package/lib/modules/index.js +2 -2
  14. package/lib/modules/mongodb/db.d.ts +128 -0
  15. package/lib/modules/mongodb/db.js +706 -0
  16. package/lib/modules/mongodb/db.spec.d.ts +1 -0
  17. package/lib/modules/mongodb/db.spec.js +714 -0
  18. package/lib/server.d.ts +3 -6
  19. package/lib/server.js +8 -12
  20. package/package.json +20 -20
  21. package/lib/prepare/access.d.ts +0 -3
  22. package/lib/prepare/access.js +0 -62
  23. package/lib/prepare/bcrypt.d.ts +0 -3
  24. package/lib/prepare/bcrypt.js +0 -25
  25. package/lib/prepare/index.d.ts +0 -11
  26. package/lib/prepare/index.js +0 -60
  27. package/lib/prepare/password.d.ts +0 -3
  28. package/lib/prepare/password.js +0 -27
  29. package/lib/prepare/persist.d.ts +0 -3
  30. package/lib/prepare/persist.js +0 -24
  31. package/lib/prepare/protect.d.ts +0 -3
  32. package/lib/prepare/protect.js +0 -28
  33. package/lib/prepare/reference.d.ts +0 -3
  34. package/lib/prepare/reference.js +0 -71
  35. package/lib/types/action.d.ts +0 -7
  36. package/lib/types/action.js +0 -2
  37. package/lib/types/form.d.ts +0 -4
  38. package/lib/types/form.js +0 -2
  39. package/lib/types/index.d.ts +0 -5
  40. package/lib/types/index.js +0 -21
  41. package/lib/types/project.d.ts +0 -4
  42. package/lib/types/project.js +0 -2
  43. package/lib/types/server.d.ts +0 -102
  44. package/lib/types/server.js +0 -2
  45. package/lib/types/submission.d.ts +0 -47
  46. package/lib/types/submission.js +0 -2
@@ -0,0 +1,706 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.Database = void 0;
13
+ const mongodb_1 = require("mongodb");
14
+ const lodash_1 = require("lodash");
15
+ const core_1 = require("@formio/core");
16
+ const debug = require('debug')('formio:db');
17
+ const error = require('debug')('formio:error');
18
+ class Database {
19
+ constructor(config) {
20
+ this.config = config;
21
+ this.prefix = '';
22
+ this.db = null;
23
+ this.client = null; // Add this line
24
+ this.currentCollectionName = 'submissions';
25
+ this.currentCollection = null;
26
+ this.defaultCollection = null;
27
+ }
28
+ ObjectId(id) {
29
+ if (id === null || id === void 0 ? void 0 : id.hasOwnProperty('$in')) {
30
+ return { $in: id['$in'].map((_id) => this.ObjectId(_id)) };
31
+ }
32
+ try {
33
+ return id ? (new mongodb_1.ObjectId(id)) : null;
34
+ }
35
+ catch (e) {
36
+ return id;
37
+ }
38
+ }
39
+ collectionName(name) {
40
+ return `${this.prefix}${name}`;
41
+ }
42
+ /**
43
+ * Connect to the database.
44
+ * @param {*} scope
45
+ * @returns
46
+ */
47
+ connect() {
48
+ return __awaiter(this, arguments, void 0, function* (prefix = '') {
49
+ this.prefix = prefix ? `${prefix}.` : '';
50
+ try {
51
+ debug('db.connect()');
52
+ let config = {};
53
+ if (this.config.config) {
54
+ config = (typeof this.config.config === 'string') ? JSON.parse(this.config.config) : this.config.config;
55
+ }
56
+ this.client = new mongodb_1.MongoClient(this.config.url, config); // Store the client
57
+ yield this.client.connect();
58
+ this.db = yield this.client.db();
59
+ if (this.config.dropOnConnect) {
60
+ yield this.db.dropDatabase();
61
+ }
62
+ this.addIndex(this.collection('project'), 'name');
63
+ this.defaultCollection = this.collection('submissions');
64
+ yield this.setupIndexes(this.defaultCollection);
65
+ debug('Connected to database');
66
+ }
67
+ catch (err) {
68
+ error(err.message);
69
+ process.exit();
70
+ }
71
+ });
72
+ }
73
+ // Add a close method
74
+ close() {
75
+ return __awaiter(this, void 0, void 0, function* () {
76
+ if (this.client) {
77
+ yield this.client.close();
78
+ this.client = null;
79
+ this.db = null;
80
+ }
81
+ });
82
+ }
83
+ collection(name) {
84
+ return this.db ? this.db.collection(this.collectionName(name)) : null;
85
+ }
86
+ // Generic save record method.
87
+ save(collectionName, item) {
88
+ return __awaiter(this, void 0, void 0, function* () {
89
+ if (!this.db) {
90
+ return null;
91
+ }
92
+ const collection = this.collection(collectionName);
93
+ if (!collection) {
94
+ return null;
95
+ }
96
+ let result;
97
+ try {
98
+ debug('db.save()', collectionName);
99
+ if (item._id) {
100
+ yield collection.updateOne({ _id: this.ObjectId(item._id) }, { $set: (0, lodash_1.omit)(item, '_id') });
101
+ return yield collection.findOne({ _id: this.ObjectId(item._id) });
102
+ }
103
+ else {
104
+ result = yield collection.insertOne(item);
105
+ return yield collection.findOne({ _id: this.ObjectId(result.insertedId) });
106
+ }
107
+ }
108
+ catch (err) {
109
+ error(err.message);
110
+ }
111
+ return null;
112
+ });
113
+ }
114
+ saveOne(collectionName, item) {
115
+ return __awaiter(this, void 0, void 0, function* () {
116
+ if (!this.db) {
117
+ return null;
118
+ }
119
+ const collection = this.collection(collectionName);
120
+ if (!collection) {
121
+ return null;
122
+ }
123
+ if (!item._id) {
124
+ // Try to load an existing record if one exists.
125
+ let existing = yield this.load(collectionName);
126
+ if (existing && !existing._id) {
127
+ existing._id = new mongodb_1.ObjectId();
128
+ const result = yield collection.insertOne(existing);
129
+ existing = yield collection.findOne({ _id: this.ObjectId(result.insertedId) });
130
+ }
131
+ item._id = existing === null || existing === void 0 ? void 0 : existing._id;
132
+ }
133
+ return yield this.save(collectionName, item);
134
+ });
135
+ }
136
+ // Generic load record method.
137
+ load(collectionName_1) {
138
+ return __awaiter(this, arguments, void 0, function* (collectionName, query = {}) {
139
+ if (!this.db) {
140
+ return null;
141
+ }
142
+ debug('db.load()', collectionName);
143
+ const collection = this.collection(collectionName);
144
+ if (!collection) {
145
+ return null;
146
+ }
147
+ let item;
148
+ try {
149
+ item = yield collection.findOne(query);
150
+ }
151
+ catch (err) {
152
+ error(err.message);
153
+ }
154
+ return item;
155
+ });
156
+ }
157
+ // Generic delete record method.
158
+ remove(collectionName_1) {
159
+ return __awaiter(this, arguments, void 0, function* (collectionName, query = {}) {
160
+ if (!this.db) {
161
+ return null;
162
+ }
163
+ debug('db.remove()', collectionName);
164
+ const collection = this.collection(collectionName);
165
+ if (!collection) {
166
+ return null;
167
+ }
168
+ let result;
169
+ try {
170
+ result = yield collection.deleteOne(query);
171
+ }
172
+ catch (err) {
173
+ error(err.message);
174
+ }
175
+ return result ? result.deletedCount : null;
176
+ });
177
+ }
178
+ /**
179
+ * Ensures the form collection is created an returns it.
180
+ * @param scope
181
+ * @returns
182
+ */
183
+ formCollection(scope) {
184
+ return __awaiter(this, void 0, void 0, function* () {
185
+ if (this.db && scope && scope.form && scope.form.settings && scope.form.settings.collection) {
186
+ if (this.currentCollection && this.currentCollectionName === scope.form.settings.collection) {
187
+ return this.currentCollection;
188
+ }
189
+ let collection = null;
190
+ try {
191
+ debug('db.createCollection()', scope.form.settings.collection);
192
+ yield this.db.createCollection(this.collectionName(scope.form.settings.collection));
193
+ collection = this.collection(scope.form.settings.collection);
194
+ this.setupIndexes(collection, scope);
195
+ }
196
+ catch (err) {
197
+ error(err.message);
198
+ }
199
+ this.currentCollection = collection || this.collection(scope.form.settings.collection);
200
+ this.currentCollectionName = scope.form.settings.collection;
201
+ return this.currentCollection;
202
+ }
203
+ return this.defaultCollection;
204
+ });
205
+ }
206
+ /**
207
+ * Setup indexes.
208
+ */
209
+ setupIndexes(collection, scope) {
210
+ return __awaiter(this, void 0, void 0, function* () {
211
+ if (!collection) {
212
+ return;
213
+ }
214
+ this.addIndex(collection, 'project');
215
+ this.addIndex(collection, 'form');
216
+ this.addIndex(collection, 'deleted');
217
+ this.addIndex(collection, 'modified');
218
+ // If TTL index is needed add that here.
219
+ if (this.config.ttl) {
220
+ try {
221
+ collection.createIndex({
222
+ created: 1
223
+ }, {
224
+ background: true,
225
+ expireAfterSeconds: this.config.ttl
226
+ });
227
+ }
228
+ catch (err) {
229
+ error('Cannot add TTL index', err.message);
230
+ }
231
+ }
232
+ else {
233
+ this.addIndex(collection, 'created');
234
+ }
235
+ if (scope && scope.form && scope.form.components) {
236
+ scope.utils.eachComponent(scope.form.components, (component, path) => {
237
+ if (component.dbIndex) {
238
+ this.addIndex(collection, `data.${path}`);
239
+ }
240
+ });
241
+ }
242
+ });
243
+ }
244
+ /**
245
+ * Add a field index
246
+ */
247
+ addIndex(collection, path) {
248
+ return __awaiter(this, void 0, void 0, function* () {
249
+ if (!collection) {
250
+ return;
251
+ }
252
+ const index = {};
253
+ index[path] = 1;
254
+ try {
255
+ debug('db.addIndex()', path);
256
+ collection.createIndex(index, { background: true });
257
+ }
258
+ catch (err) {
259
+ error(`Cannot add index ${path}`, err.message);
260
+ }
261
+ });
262
+ }
263
+ /**
264
+ * Adds new indexes to the forms submission collection.
265
+ * @param scope
266
+ * @param indexes
267
+ * @returns
268
+ */
269
+ addIndexes(scope, indexes) {
270
+ return __awaiter(this, void 0, void 0, function* () {
271
+ const collection = yield this.formCollection(scope);
272
+ if (!collection) {
273
+ return;
274
+ }
275
+ for (const path of indexes) {
276
+ yield this.addIndex(collection, `data.${path}`);
277
+ }
278
+ });
279
+ }
280
+ /**
281
+ * Remove a field index.
282
+ */
283
+ removeIndex(collection, path) {
284
+ return __awaiter(this, void 0, void 0, function* () {
285
+ const index = {};
286
+ index[path] = 1;
287
+ try {
288
+ debug('db.removeIndex()', path);
289
+ yield collection.dropIndex(index);
290
+ }
291
+ catch (err) {
292
+ error(`Cannot remove index ${path}`, err.message);
293
+ }
294
+ });
295
+ }
296
+ /**
297
+ * Removes indexes to the forms submission collection.
298
+ * @param scope
299
+ * @param indexes
300
+ * @returns
301
+ */
302
+ removeIndexes(scope, indexes) {
303
+ return __awaiter(this, void 0, void 0, function* () {
304
+ const collection = yield this.formCollection(scope);
305
+ if (!collection) {
306
+ return;
307
+ }
308
+ for (const path of indexes) {
309
+ yield this.removeIndex(collection, `data.${path}`);
310
+ }
311
+ });
312
+ }
313
+ /**
314
+ * Fetch a list of submissions from a table/collection.
315
+ * @param {*} table
316
+ * @param {*} query
317
+ */
318
+ index(scope_1) {
319
+ return __awaiter(this, arguments, void 0, function* (scope, query = {}, collection = null) {
320
+ let items = [], skip = 0, limit = 10, count = 0;
321
+ try {
322
+ limit = query.limit || 10;
323
+ skip = query.skip || 0;
324
+ const sort = query.sort || { created: -1 };
325
+ const includeDeleted = query.includeDeleted || false;
326
+ let project = {};
327
+ if (query.select) {
328
+ if (typeof query.select === 'string') {
329
+ const fields = query.select.split(',');
330
+ fields.forEach((field) => {
331
+ project[field] = true;
332
+ });
333
+ }
334
+ else {
335
+ Object.keys(query.select).forEach((field) => {
336
+ project[field] = true;
337
+ });
338
+ }
339
+ }
340
+ delete query.limit;
341
+ delete query.skip;
342
+ delete query.sort;
343
+ delete query.select;
344
+ delete query.includeDeleted;
345
+ debug('db.index()', query);
346
+ items = (yield this.find(scope, query, limit, skip, sort, project, collection, includeDeleted)) || [];
347
+ count = yield this.count(scope, query, collection, includeDeleted);
348
+ }
349
+ catch (err) {
350
+ error(err.message);
351
+ }
352
+ return { items, limit, skip, count };
353
+ });
354
+ }
355
+ /**
356
+ * Perform a count of the amount of documents within a collection.
357
+ * @param scope
358
+ * @param query
359
+ * @returns
360
+ */
361
+ count(scope_1) {
362
+ return __awaiter(this, arguments, void 0, function* (scope, query = {}, inCollection = null, includeDeleted = false) {
363
+ let count = 0;
364
+ try {
365
+ debug('db.count()', query);
366
+ const collection = inCollection || (yield this.formCollection(scope));
367
+ if (!collection) {
368
+ return 0;
369
+ }
370
+ count = yield collection.countDocuments(this.query(scope, query, includeDeleted));
371
+ }
372
+ catch (err) {
373
+ error(err.message);
374
+ }
375
+ return count;
376
+ });
377
+ }
378
+ /**
379
+ * Create a new record.
380
+ */
381
+ create(scope_1, record_1) {
382
+ return __awaiter(this, arguments, void 0, function* (scope, record, allowFields = []) {
383
+ record.deleted = null;
384
+ record.created = new Date();
385
+ record.modified = new Date();
386
+ if (scope.form && scope.form._id) {
387
+ record.form = this.ObjectId(scope.form._id);
388
+ }
389
+ if (scope.project && scope.project._id) {
390
+ record.project = this.ObjectId(scope.project._id);
391
+ }
392
+ if (record.owner) {
393
+ record.owner = this.ObjectId(record.owner);
394
+ }
395
+ const collection = yield this.formCollection(scope);
396
+ try {
397
+ debug('db.create()', record);
398
+ const result = yield collection.insertOne((0, lodash_1.pick)(record, [
399
+ 'data',
400
+ 'metadata',
401
+ 'modified',
402
+ 'created',
403
+ 'deleted',
404
+ 'form',
405
+ 'project',
406
+ 'owner',
407
+ 'access',
408
+ 'state'
409
+ ].concat(allowFields)));
410
+ if (!result.insertedId) {
411
+ return null;
412
+ }
413
+ return yield this.read(scope, result.insertedId);
414
+ }
415
+ catch (err) {
416
+ error(err.message);
417
+ }
418
+ });
419
+ }
420
+ /**
421
+ * Return a query for a single mongo record.
422
+ * @param {*} form
423
+ * @param {*} id
424
+ * @returns
425
+ */
426
+ query(scope, query = {}, includeAll = false) {
427
+ if (query._id) {
428
+ query._id = this.ObjectId(query._id);
429
+ }
430
+ if (query.owner) {
431
+ query.owner = this.ObjectId(query.owner);
432
+ }
433
+ if (query.form) {
434
+ query.form = this.ObjectId(query.form);
435
+ }
436
+ else if (!includeAll && scope.form && scope.form._id) {
437
+ query.form = this.ObjectId(scope.form._id);
438
+ }
439
+ if (!includeAll && scope.project && scope.project._id) {
440
+ query.project = this.ObjectId(scope.project._id);
441
+ }
442
+ if (!includeAll) {
443
+ query.deleted = { $eq: null };
444
+ }
445
+ // Handle nested queries.
446
+ ['$or', '$and'].forEach((key) => {
447
+ if (query[key]) {
448
+ query[key].forEach((subQuery) => this.query(scope, subQuery, true));
449
+ }
450
+ });
451
+ return query;
452
+ }
453
+ /**
454
+ * Find many records that match a query.
455
+ */
456
+ find(scope_1) {
457
+ return __awaiter(this, arguments, void 0, function* (scope, query = {}, limit = 10, skip = 0, sort = { created: -1 }, select = {}, inCollection = null, includeDeleted = false) {
458
+ try {
459
+ debug('db.find()', query);
460
+ const collection = inCollection || (yield this.formCollection(scope));
461
+ if (!collection) {
462
+ return [];
463
+ }
464
+ return yield collection.find(this.query(scope, query, includeDeleted)).limit(limit).skip(skip).sort(sort).project(select).toArray();
465
+ }
466
+ catch (err) {
467
+ error(err.message);
468
+ }
469
+ return [];
470
+ });
471
+ }
472
+ /**
473
+ * Find a record for a provided query.
474
+ */
475
+ findOne(scope_1) {
476
+ return __awaiter(this, arguments, void 0, function* (scope, query = {}, options = {}) {
477
+ try {
478
+ debug('db.findOne()', query);
479
+ const collection = yield this.formCollection(scope);
480
+ if (!collection) {
481
+ return null;
482
+ }
483
+ return yield collection.findOne(this.query(scope, query));
484
+ }
485
+ catch (err) {
486
+ error(err.message);
487
+ }
488
+ return null;
489
+ });
490
+ }
491
+ /**
492
+ * Read a single submission from a form
493
+ *
494
+ * @param {*} table
495
+ * @param {*} query
496
+ */
497
+ read(scope, id) {
498
+ return __awaiter(this, void 0, void 0, function* () {
499
+ try {
500
+ debug('db.read()', id);
501
+ if (!id) {
502
+ return null;
503
+ }
504
+ const collection = yield this.formCollection(scope);
505
+ if (!collection) {
506
+ return null;
507
+ }
508
+ return yield collection.findOne(this.query(scope, { _id: this.ObjectId(id) }));
509
+ }
510
+ catch (err) {
511
+ error(err.message);
512
+ }
513
+ return null;
514
+ });
515
+ }
516
+ /**
517
+ * Update a single submission of a form.
518
+ *
519
+ * @param {*} table
520
+ * @param {*} query
521
+ */
522
+ update(scope_1, id_1, update_1) {
523
+ return __awaiter(this, arguments, void 0, function* (scope, id, update, allowFields = []) {
524
+ if (!id || !update) {
525
+ return null;
526
+ }
527
+ update.modified = new Date();
528
+ try {
529
+ debug('db.update()', id, update);
530
+ const collection = yield this.formCollection(scope);
531
+ if (!collection) {
532
+ return null;
533
+ }
534
+ const result = yield collection.updateOne(this.query(scope, { _id: this.ObjectId(id) }), {
535
+ $set: (0, lodash_1.pick)(update, ['data', 'metadata', 'modified', 'state'].concat(allowFields))
536
+ });
537
+ if (result.modifiedCount === 0) {
538
+ return null;
539
+ }
540
+ return yield this.read(scope, id);
541
+ }
542
+ catch (err) {
543
+ error(err.message);
544
+ }
545
+ return null;
546
+ });
547
+ }
548
+ /**
549
+ * Delete a record from the database.
550
+ */
551
+ delete(scope_1, id_1) {
552
+ return __awaiter(this, arguments, void 0, function* (scope, id, hard = false) {
553
+ if (!id) {
554
+ return false;
555
+ }
556
+ try {
557
+ debug('db.delete()', id, hard ? '(hard)' : '(soft)');
558
+ const collection = yield this.formCollection(scope);
559
+ if (!collection) {
560
+ return false;
561
+ }
562
+ if (hard) {
563
+ // Hard delete - completely remove the record from the database
564
+ const result = yield collection.deleteOne(this.query(scope, { _id: this.ObjectId(id) }, true));
565
+ return result.deletedCount > 0;
566
+ }
567
+ else {
568
+ // Soft delete - set deleted timestamp
569
+ const result = yield collection.updateOne(this.query(scope, { _id: this.ObjectId(id) }), {
570
+ $set: {
571
+ deleted: new Date(),
572
+ modified: new Date()
573
+ }
574
+ });
575
+ return result.modifiedCount > 0;
576
+ }
577
+ }
578
+ catch (err) {
579
+ error(err.message);
580
+ }
581
+ return false;
582
+ });
583
+ }
584
+ addPathQueryParams(pathQueryParams, query, path) {
585
+ const pathArray = path.split(/\[\d+\]?./);
586
+ const needValuesInArray = pathArray.length > 1;
587
+ let pathToValue = path;
588
+ if (needValuesInArray) {
589
+ pathToValue = pathArray.shift();
590
+ if (!pathToValue) {
591
+ return;
592
+ }
593
+ const pathQueryObj = {};
594
+ (0, lodash_1.reduce)(pathArray, (pathQueryPath, pathPart, index) => {
595
+ const isLastPathPart = index === (pathArray.length - 1);
596
+ const obj = (0, lodash_1.get)(pathQueryObj, pathQueryPath, pathQueryObj);
597
+ const addedPath = `$elemMatch['${pathPart}']`;
598
+ (0, lodash_1.set)(obj, addedPath, isLastPathPart ? pathQueryParams : {});
599
+ return pathQueryPath ? `${pathQueryPath}.${addedPath}` : addedPath;
600
+ }, '');
601
+ query[pathToValue] = pathQueryObj;
602
+ }
603
+ else {
604
+ query[pathToValue] = pathQueryParams;
605
+ }
606
+ }
607
+ /**
608
+ * Performs a unique query on the database to see if a value is unique.
609
+ * - If the value is unique, it returns true.
610
+ * - If the value is not unique, it returns the id of the non-unique submission.
611
+ * - If an error occurs, or uniqueness cannot be determined, it will throw an error.
612
+ *
613
+ * @param scope
614
+ * @param context
615
+ * @param value
616
+ * @returns
617
+ */
618
+ isUnique(scope, context, value) {
619
+ return __awaiter(this, void 0, void 0, function* () {
620
+ const { component, submission, form } = context;
621
+ const path = `data.${context.path}`;
622
+ if (!form) {
623
+ return false;
624
+ }
625
+ // Build the query
626
+ const query = { form: form._id };
627
+ let options = {};
628
+ if ((0, lodash_1.isString)(value)) {
629
+ if (component.dbIndex) {
630
+ this.addPathQueryParams(value, query, path);
631
+ }
632
+ else if (component.type === 'email' ||
633
+ (component.type === 'textfield' &&
634
+ component.validate &&
635
+ component.validate.pattern === '[A-Za-z0-9]+')) {
636
+ this.addPathQueryParams(value, query, path);
637
+ options = { collation: { locale: 'en', strength: 2 } };
638
+ }
639
+ else {
640
+ this.addPathQueryParams({
641
+ $regex: new RegExp(`^${(0, core_1.escapeRegExCharacters)(value)}$`),
642
+ $options: 'i'
643
+ }, query, path);
644
+ }
645
+ }
646
+ // FOR-213 - Pluck the unique location id
647
+ else if ((0, lodash_1.isPlainObject)(value) &&
648
+ value.address &&
649
+ value.address['address_components'] &&
650
+ value.address['place_id']) {
651
+ this.addPathQueryParams({
652
+ $regex: new RegExp(`^${(0, core_1.escapeRegExCharacters)(value.address['place_id'])}$`),
653
+ $options: 'i'
654
+ }, query, `${path}.address.place_id`);
655
+ }
656
+ // Compare the contents of arrays vs the order.
657
+ else if ((0, lodash_1.isArray)(value)) {
658
+ this.addPathQueryParams({ $all: value }, query, path);
659
+ }
660
+ else if ((0, lodash_1.isObject)(value) || (0, lodash_1.isNumber)(value)) {
661
+ this.addPathQueryParams({ $eq: value }, query, path);
662
+ }
663
+ // Only search for non-deleted items
664
+ query.deleted = { $eq: null };
665
+ query.state = 'submitted';
666
+ // Perform the query.
667
+ let result = null;
668
+ try {
669
+ result = yield this.findOne(scope, query, options);
670
+ if (!result || ((result === null || result === void 0 ? void 0 : result._id.toString()) === (submission === null || submission === void 0 ? void 0 : submission._id))) {
671
+ return true;
672
+ }
673
+ else {
674
+ return result._id.toString();
675
+ }
676
+ }
677
+ catch (err) {
678
+ if (options.collation) {
679
+ // presume this error comes from db compatibility, try again as regex
680
+ delete query[path];
681
+ this.addPathQueryParams({
682
+ $regex: new RegExp(`^${(0, core_1.escapeRegExCharacters)(value)}$`),
683
+ $options: 'i'
684
+ }, query, path);
685
+ try {
686
+ result = yield this.findOne(scope, query);
687
+ if (!result || ((result === null || result === void 0 ? void 0 : result._id.toString()) === (submission === null || submission === void 0 ? void 0 : submission._id))) {
688
+ return true;
689
+ }
690
+ else {
691
+ component.conflictId = result._id.toString();
692
+ return component.conflictId;
693
+ }
694
+ }
695
+ catch (err) {
696
+ throw err;
697
+ }
698
+ }
699
+ else {
700
+ throw err;
701
+ }
702
+ }
703
+ });
704
+ }
705
+ }
706
+ exports.Database = Database;
@@ -0,0 +1 @@
1
+ export {};