wingbot-mongodb 2.22.0-alpha.6 → 2.22.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.
@@ -1 +1 @@
1
- {"parent":null,"pid":85364,"argv":["/usr/local/bin/node","/Users/david/Development/wingbot-mongodb/node_modules/.bin/mocha","./test"],"execArgv":[],"cwd":"/Users/david/Development/wingbot-mongodb","time":1651496192378,"ppid":85363,"coverageFilename":"/Users/david/Development/wingbot-mongodb/.nyc_output/81c4e49f-c93d-4e44-b749-eec4d22cfcf1.json","externalId":"","uuid":"81c4e49f-c93d-4e44-b749-eec4d22cfcf1","files":["/Users/david/Development/wingbot-mongodb/src/BaseStorage.js","/Users/david/Development/wingbot-mongodb/src/defaultLogger.js","/Users/david/Development/wingbot-mongodb/src/AttachmentCache.js","/Users/david/Development/wingbot-mongodb/src/AuditLogStorage.js","/Users/david/Development/wingbot-mongodb/src/BotConfigStorage.js","/Users/david/Development/wingbot-mongodb/src/BotTokenStorage.js","/Users/david/Development/wingbot-mongodb/src/tokenFactory.js","/Users/david/Development/wingbot-mongodb/src/ChatLogStorage.js","/Users/david/Development/wingbot-mongodb/src/NotificationsStorage.js","/Users/david/Development/wingbot-mongodb/src/StateStorage.js"]}
1
+ {"parent":null,"pid":17347,"argv":["/usr/local/bin/node","/Users/david/Development/wingbot-mongodb/node_modules/.bin/mocha","./test"],"execArgv":[],"cwd":"/Users/david/Development/wingbot-mongodb","time":1669369533432,"ppid":17346,"coverageFilename":"/Users/david/Development/wingbot-mongodb/.nyc_output/0d879467-0e5f-4098-bea4-73c520af6dcd.json","externalId":"","uuid":"0d879467-0e5f-4098-bea4-73c520af6dcd","files":["/Users/david/Development/wingbot-mongodb/src/BaseStorage.js","/Users/david/Development/wingbot-mongodb/src/defaultLogger.js","/Users/david/Development/wingbot-mongodb/src/AttachmentCache.js","/Users/david/Development/wingbot-mongodb/src/AuditLogStorage.js","/Users/david/Development/wingbot-mongodb/src/BotConfigStorage.js","/Users/david/Development/wingbot-mongodb/src/BotTokenStorage.js","/Users/david/Development/wingbot-mongodb/src/tokenFactory.js","/Users/david/Development/wingbot-mongodb/src/ChatLogStorage.js","/Users/david/Development/wingbot-mongodb/src/NotificationsStorage.js","/Users/david/Development/wingbot-mongodb/src/StateStorage.js"]}
@@ -1 +1 @@
1
- {"processes":{"81c4e49f-c93d-4e44-b749-eec4d22cfcf1":{"parent":null,"children":[]}},"files":{"/Users/david/Development/wingbot-mongodb/src/BaseStorage.js":["81c4e49f-c93d-4e44-b749-eec4d22cfcf1"],"/Users/david/Development/wingbot-mongodb/src/defaultLogger.js":["81c4e49f-c93d-4e44-b749-eec4d22cfcf1"],"/Users/david/Development/wingbot-mongodb/src/AttachmentCache.js":["81c4e49f-c93d-4e44-b749-eec4d22cfcf1"],"/Users/david/Development/wingbot-mongodb/src/AuditLogStorage.js":["81c4e49f-c93d-4e44-b749-eec4d22cfcf1"],"/Users/david/Development/wingbot-mongodb/src/BotConfigStorage.js":["81c4e49f-c93d-4e44-b749-eec4d22cfcf1"],"/Users/david/Development/wingbot-mongodb/src/BotTokenStorage.js":["81c4e49f-c93d-4e44-b749-eec4d22cfcf1"],"/Users/david/Development/wingbot-mongodb/src/tokenFactory.js":["81c4e49f-c93d-4e44-b749-eec4d22cfcf1"],"/Users/david/Development/wingbot-mongodb/src/ChatLogStorage.js":["81c4e49f-c93d-4e44-b749-eec4d22cfcf1"],"/Users/david/Development/wingbot-mongodb/src/NotificationsStorage.js":["81c4e49f-c93d-4e44-b749-eec4d22cfcf1"],"/Users/david/Development/wingbot-mongodb/src/StateStorage.js":["81c4e49f-c93d-4e44-b749-eec4d22cfcf1"]},"externalIds":{}}
1
+ {"processes":{"0d879467-0e5f-4098-bea4-73c520af6dcd":{"parent":null,"children":[]}},"files":{"/Users/david/Development/wingbot-mongodb/src/BaseStorage.js":["0d879467-0e5f-4098-bea4-73c520af6dcd"],"/Users/david/Development/wingbot-mongodb/src/defaultLogger.js":["0d879467-0e5f-4098-bea4-73c520af6dcd"],"/Users/david/Development/wingbot-mongodb/src/AttachmentCache.js":["0d879467-0e5f-4098-bea4-73c520af6dcd"],"/Users/david/Development/wingbot-mongodb/src/AuditLogStorage.js":["0d879467-0e5f-4098-bea4-73c520af6dcd"],"/Users/david/Development/wingbot-mongodb/src/BotConfigStorage.js":["0d879467-0e5f-4098-bea4-73c520af6dcd"],"/Users/david/Development/wingbot-mongodb/src/BotTokenStorage.js":["0d879467-0e5f-4098-bea4-73c520af6dcd"],"/Users/david/Development/wingbot-mongodb/src/tokenFactory.js":["0d879467-0e5f-4098-bea4-73c520af6dcd"],"/Users/david/Development/wingbot-mongodb/src/ChatLogStorage.js":["0d879467-0e5f-4098-bea4-73c520af6dcd"],"/Users/david/Development/wingbot-mongodb/src/NotificationsStorage.js":["0d879467-0e5f-4098-bea4-73c520af6dcd"],"/Users/david/Development/wingbot-mongodb/src/StateStorage.js":["0d879467-0e5f-4098-bea4-73c520af6dcd"]},"externalIds":{}}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wingbot-mongodb",
3
- "version": "2.22.0-alpha.6",
3
+ "version": "2.22.0",
4
4
  "description": "MongoDB storage for wingbot.ai",
5
5
  "main": "src/main.js",
6
6
  "scripts": {
@@ -45,12 +45,12 @@
45
45
  "jsdoc-to-markdown": "^7.1.1",
46
46
  "jsdoc-tsimport-plugin": "^1.0.5",
47
47
  "mocha": "^9.2.2",
48
- "mongodb": "^4.5.0",
48
+ "mongodb": "^3.7.3",
49
49
  "nyc": "^15.1.0",
50
- "wingbot": "^3.30.2"
50
+ "wingbot": "^3.34.0"
51
51
  },
52
52
  "peerDependencies": {
53
- "mongodb": "^4.0.0"
53
+ "mongodb": "^3.0.0"
54
54
  },
55
55
  "optionalDependencies": {
56
56
  "wingbot": "^3.0.0"
@@ -3,8 +3,7 @@
3
3
  */
4
4
  'use strict';
5
5
 
6
- /** @typedef {import('mongodb').Db} Db */
7
- /** @typedef {import('mongodb').Collection} Collection */
6
+ const mongodb = require('mongodb'); // eslint-disable-line no-unused-vars
8
7
 
9
8
  /**
10
9
  * Cache storage for Facebook attachments
@@ -15,7 +14,7 @@ class AttachmentCache {
15
14
 
16
15
  /**
17
16
  *
18
- * @param {Db|{():Promise<Db>}} mongoDb
17
+ * @param {mongodb.Db|{():Promise<mongodb.Db>}} mongoDb
19
18
  * @param {string} collectionName
20
19
  */
21
20
  constructor (mongoDb, collectionName = 'attachments') {
@@ -23,13 +22,13 @@ class AttachmentCache {
23
22
  this._collectionName = collectionName;
24
23
 
25
24
  /**
26
- * @type {Collection}
25
+ * @type {mongodb.Collection}
27
26
  */
28
27
  this._collection = null;
29
28
  }
30
29
 
31
30
  /**
32
- * @returns {Promise<Collection>}
31
+ * @returns {Promise<mongodb.Collection>}
33
32
  */
34
33
  async _getCollection () {
35
34
  if (this._collection === null) {
@@ -5,7 +5,8 @@
5
5
 
6
6
  const jsonwebtoken = require('jsonwebtoken');
7
7
  const BaseStorage = require('./BaseStorage');
8
- const defaultLogger = require('./defaultLogger');
8
+
9
+ /** @typedef {import('mongodb/lib/db')} Db */
9
10
 
10
11
  const LEVEL_CRITICAL = 'Critical';
11
12
  const LEVEL_IMPORTANT = 'Important';
@@ -90,9 +91,6 @@ const TYPE_INFO = 'Info';
90
91
  * @returns {Promise}
91
92
  */
92
93
 
93
- /** @typedef {import('mongodb').Db} Db */
94
- /** @typedef {import('mongodb').Collection} Collection */
95
-
96
94
  /**
97
95
  * Storage for audit logs with signatures chain
98
96
  */
@@ -107,7 +105,7 @@ class AuditLogStorage extends BaseStorage {
107
105
  * @param {string|Promise<string>} [secret]
108
106
  * @param {string|Promise<string>} [jwtVerifier]
109
107
  */
110
- constructor (mongoDb, collectionName = 'auditlog', log = defaultLogger, isCosmo = false, secret = null, jwtVerifier = null) {
108
+ constructor (mongoDb, collectionName = 'auditlog', log = console, isCosmo = false, secret = null, jwtVerifier = null) {
111
109
  super(mongoDb, collectionName, log, isCosmo);
112
110
 
113
111
  this.addIndex({
@@ -3,33 +3,11 @@
3
3
  */
4
4
  'use strict';
5
5
 
6
- const { ObjectId } = require('mongodb');
6
+ const mongodb = require('mongodb'); // eslint-disable-line no-unused-vars
7
7
  const crypto = require('crypto');
8
- const defaultLogger = require('./defaultLogger');
9
8
 
10
- /** @typedef {import('mongodb').Db} Db */
11
- /** @typedef {import('mongodb').Collection} Collection */
12
- /** @typedef {import('mongodb').CreateIndexesOptions} CreateIndexesOptions */
13
-
14
- /**
15
- *
16
- * @param {any} obj
17
- * @param {boolean} nested
18
- * @param {string} [attr]
19
- * @param {object} [ret]
20
- * @returns {object}
21
- */
22
- function getNestedObjects (obj, nested, attr = null, ret = {}) {
23
- if (typeof obj !== 'object' || !obj || nested === null || Array.isArray(obj)) {
24
- Object.assign(ret, { [attr]: obj === undefined ? null : obj });
25
- } else {
26
- Object.entries(obj)
27
- .forEach(([key, val]) => {
28
- getNestedObjects(val, nested || null, attr ? `${attr}.${key}` : key, ret);
29
- });
30
- }
31
- return ret;
32
- }
9
+ /** @typedef {import('mongodb/lib/db')} Db */
10
+ /** @typedef {import('mongodb/lib/collection')} Collection */
33
11
 
34
12
  class BaseStorage {
35
13
 
@@ -45,7 +23,7 @@ class BaseStorage {
45
23
  *
46
24
  * class MyCoolDataStorage extends BaseStorage {
47
25
  *
48
- * constructor (mongoDb, collectionName, log = undefined, isCosmo = false) {
26
+ * constructor (mongoDb, collectionName = 'myCoolData', log = console, isCosmo = false) {
49
27
  * super(mongoDb, collectionName, log, isCosmo);
50
28
  *
51
29
  * this.addIndex({
@@ -64,7 +42,7 @@ class BaseStorage {
64
42
  *
65
43
  * }
66
44
  */
67
- constructor (mongoDb, collectionName, log = defaultLogger, isCosmo = false) {
45
+ constructor (mongoDb, collectionName, log = console, isCosmo = false) {
68
46
  this._mongoDb = mongoDb;
69
47
  this._collectionName = collectionName;
70
48
  this._isCosmo = isCosmo;
@@ -83,6 +61,21 @@ class BaseStorage {
83
61
  this.systemIndexes = ['_id_', '_id'];
84
62
 
85
63
  this._fixtures = [];
64
+
65
+ if (isCosmo && !process.argv.some((a) => a.endsWith('mocha'))) {
66
+ process.nextTick(() => {
67
+ const hasUniqueIndex = this._indexes.some((i) => i.options.unique);
68
+
69
+ if (hasUniqueIndex) {
70
+ this._getCollection()
71
+ .catch((e) => log.error(`DB.${this._collectionName} index pre-heat FAILED`, e));
72
+ }
73
+ });
74
+ }
75
+ }
76
+
77
+ preHeat () {
78
+ return this._getCollection();
86
79
  }
87
80
 
88
81
  /**
@@ -98,7 +91,7 @@ class BaseStorage {
98
91
  * Add custom indexing rule
99
92
  *
100
93
  * @param {object} index
101
- * @param {CreateIndexesOptions} options
94
+ * @param {mongodb.IndexOptions} options
102
95
  */
103
96
  addIndex (index, options) {
104
97
  if (!options.name) {
@@ -110,36 +103,6 @@ class BaseStorage {
110
103
  });
111
104
  }
112
105
 
113
- /**
114
- * @example
115
- * {
116
- * _id: ObjectId.isValid(id) ? new ObjectId(input) : input
117
- * }
118
- *
119
- * @protected
120
- * @param {string} id
121
- * @returns {string|ObjectId}
122
- */
123
- _id (id) {
124
- return ObjectId.isValid(id) && `${id}`.length === 24
125
- ? new ObjectId(id)
126
- : id;
127
- }
128
-
129
- /**
130
- *
131
- * @param {string|null} attr
132
- * @param {{[key: string]: any}} obj
133
- * @param {boolean} [nested]
134
- * @returns {{[key: string]: any}}
135
- */
136
- _expandObjectToSet (attr, obj, nested = false) {
137
- if (Object.keys(obj).length === 0) {
138
- return null;
139
- }
140
- return getNestedObjects(obj, nested, attr);
141
- }
142
-
143
106
  async _getOrCreateCollection (name) {
144
107
  const db = typeof this._mongoDb === 'function'
145
108
  ? await this._mongoDb()
@@ -261,7 +224,7 @@ class BaseStorage {
261
224
 
262
225
  /**
263
226
  *
264
- * @protected
227
+ * @private
265
228
  * @template T
266
229
  * @param {T} object
267
230
  * @returns {T}
@@ -11,8 +11,8 @@ try {
11
11
  // noop
12
12
  }
13
13
 
14
- /** @typedef {import('mongodb').Db} Db */
15
- /** @typedef {import('mongodb').Collection} Collection */
14
+ /** @typedef {import('mongodb/lib/db')} Db */
15
+ /** @typedef {import('mongodb/lib/collection')} Collection */
16
16
 
17
17
  const CONFIG_ID = 'config';
18
18
 
@@ -3,6 +3,7 @@
3
3
  */
4
4
  'use strict';
5
5
 
6
+ const mongodb = require('mongodb'); // eslint-disable-line no-unused-vars
6
7
  const tokenFactory = require('./tokenFactory');
7
8
 
8
9
  const TOKEN_INDEX = 'token-index';
@@ -15,9 +16,6 @@ const USER_INDEX = 'user-page-index';
15
16
  * @prop {string} token
16
17
  */
17
18
 
18
- /** @typedef {import('mongodb').Db} Db */
19
- /** @typedef {import('mongodb').Collection} Collection */
20
-
21
19
  /**
22
20
  * Storage for webview tokens
23
21
  *
@@ -27,7 +25,7 @@ class BotTokenStorage {
27
25
 
28
26
  /**
29
27
  *
30
- * @param {Db|{():Promise<Db>}} mongoDb
28
+ * @param {mongodb.Db|{():Promise<mongodb.Db>}} mongoDb
31
29
  * @param {string} collectionName
32
30
  */
33
31
  constructor (mongoDb, collectionName = 'tokens') {
@@ -35,13 +33,13 @@ class BotTokenStorage {
35
33
  this._collectionName = collectionName;
36
34
 
37
35
  /**
38
- * @type {Collection}
36
+ * @type {mongodb.Collection}
39
37
  */
40
38
  this._collection = null;
41
39
  }
42
40
 
43
41
  /**
44
- * @returns {Promise<Collection>}
42
+ * @returns {Promise<mongodb.Collection>}
45
43
  */
46
44
  async _getCollection () {
47
45
  if (this._collection === null) {
@@ -62,7 +60,8 @@ class BotTokenStorage {
62
60
  token: 1
63
61
  }, {
64
62
  unique: true,
65
- name: TOKEN_INDEX
63
+ name: TOKEN_INDEX,
64
+ dropDups: true
66
65
  });
67
66
  }
68
67
  try {
@@ -76,7 +75,8 @@ class BotTokenStorage {
76
75
  pageId: 1
77
76
  }, {
78
77
  unique: true,
79
- name: USER_INDEX
78
+ name: USER_INDEX,
79
+ dropDups: true
80
80
  });
81
81
  }
82
82
  }
@@ -4,12 +4,11 @@
4
4
  'use strict';
5
5
 
6
6
  const BaseStorage = require('./BaseStorage');
7
- const defaultLogger = require('./defaultLogger');
8
7
 
9
8
  const PAGE_SENDER_TIMESTAMP = 'pageId_1_senderId_1_timestamp_-1';
10
9
  const TIMESTAMP = 'timestamp_1';
11
10
 
12
- /** @typedef {import('mongodb').Db} Db */
11
+ /** @typedef {import('mongodb/lib/db')} Db */
13
12
 
14
13
  /**
15
14
  * Storage for conversation logs
@@ -26,7 +25,7 @@ class ChatLogStorage extends BaseStorage {
26
25
  * @param {boolean} [isCosmo]
27
26
  * @param {string|Promise<string>} [secret]
28
27
  */
29
- constructor (mongoDb, collectionName = 'chatlogs', log = defaultLogger, isCosmo = false, secret = null) {
28
+ constructor (mongoDb, collectionName = 'chatlogs', log = console, isCosmo = false, secret = null) {
30
29
  super(mongoDb, collectionName, log, isCosmo);
31
30
 
32
31
  this.addIndex({
@@ -4,9 +4,8 @@
4
4
  'use strict';
5
5
 
6
6
  const mongodb = require('mongodb');
7
- const defaultLogger = require('./defaultLogger');
8
7
 
9
- const { ObjectId } = mongodb;
8
+ const { ObjectID } = mongodb;
10
9
 
11
10
  /**
12
11
  * @typedef Target {Object}
@@ -22,7 +21,7 @@ const { ObjectId } = mongodb;
22
21
  */
23
22
 
24
23
  /**
25
- * @typedef Campaign {object}
24
+ * @typedef Campaign {object}
26
25
  * @prop {string} id
27
26
  * @prop {string} name
28
27
  *
@@ -85,7 +84,7 @@ class NotificationsStorage {
85
84
  * @param {{error:Function,log:Function}} [log] - console like logger
86
85
  * @param {boolean} isCosmo
87
86
  */
88
- constructor (mongoDb, collectionsPrefix = '', log = defaultLogger, isCosmo = false) {
87
+ constructor (mongoDb, collectionsPrefix = '', log = console, isCosmo = false) {
89
88
  this._mongoDb = mongoDb;
90
89
 
91
90
  this.taksCollection = `${collectionsPrefix}notification-tasks`;
@@ -101,6 +100,17 @@ class NotificationsStorage {
101
100
  * @type {Map<string,Promise<mongodb.Collection>>}
102
101
  */
103
102
  this._collections = new Map();
103
+
104
+ if (isCosmo && !process.argv.some((a) => a.endsWith('mocha'))) {
105
+ process.nextTick(() => {
106
+ Promise.all([
107
+ this._getCollection(this.taksCollection),
108
+ this._getCollection(this.campaignsCollection),
109
+ this._getCollection(this.subscribtionsCollection)
110
+ ])
111
+ .catch((e) => log.error('DB.<NotificationsStorage> index pre-heat FAILED', e));
112
+ });
113
+ }
104
114
  }
105
115
 
106
116
  async _getOrCreateCollection (name) {
@@ -243,8 +253,7 @@ class NotificationsStorage {
243
253
  if (i.isTextIndex) {
244
254
  this._doesNotSupportTextIndex = true;
245
255
  } else {
246
- this._log.error(`failed to create index ${i.options.name} on ${collection.collectionName}`);
247
- throw e;
256
+ this._log.error(`failed to create index ${i.options.name} on ${collection.collectionName}`, e);
248
257
  }
249
258
  })));
250
259
  }
@@ -453,8 +462,8 @@ class NotificationsStorage {
453
462
  const c = await this._getCollection(this.taksCollection);
454
463
 
455
464
  const res = await c.findOne({
456
- _id: ObjectId.isValid(taskId)
457
- ? ObjectId.createFromHexString(taskId)
465
+ _id: ObjectID.isValid(taskId)
466
+ ? ObjectID.createFromHexString(taskId)
458
467
  : taskId
459
468
  });
460
469
 
@@ -470,8 +479,8 @@ class NotificationsStorage {
470
479
  const c = await this._getCollection(this.taksCollection);
471
480
 
472
481
  const res = await c.findOneAndUpdate({
473
- _id: ObjectId.isValid(taskId)
474
- ? ObjectId.createFromHexString(taskId)
482
+ _id: ObjectID.isValid(taskId)
483
+ ? ObjectID.createFromHexString(taskId)
475
484
  : taskId
476
485
  }, {
477
486
  $set: data
@@ -607,7 +616,7 @@ class NotificationsStorage {
607
616
  });
608
617
  ret = this._mapCampaign(res.value);
609
618
  } else {
610
- const id = new ObjectId();
619
+ const id = new ObjectID();
611
620
  ret = { id: id.toHexString(), _id: id, ...campaign };
612
621
  if (updateCampaign) {
613
622
  Object.assign(ret, updateCampaign);
@@ -740,7 +749,7 @@ class NotificationsStorage {
740
749
  useCondition = {
741
750
  ...useCondition,
742
751
  _id: {
743
- $lt: ObjectId.createFromHexString(key._id)
752
+ $lt: ObjectID.createFromHexString(key._id)
744
753
  }
745
754
  };
746
755
  }
@@ -899,7 +908,7 @@ class NotificationsStorage {
899
908
  condition = {
900
909
  ...condition,
901
910
  _id: {
902
- $gt: ObjectId.createFromHexString(key._id)
911
+ $gt: ObjectID.createFromHexString(key._id)
903
912
  }
904
913
  };
905
914
  }
@@ -3,12 +3,13 @@
3
3
  */
4
4
  'use strict';
5
5
 
6
+ const mongodb = require('mongodb'); // eslint-disable-line no-unused-vars
6
7
  const BaseStorage = require('./BaseStorage');
7
- const defaultLogger = require('./defaultLogger');
8
8
 
9
9
  const USER_INDEX = 'senderId_1_pageId_1';
10
10
  const LAST_INTERACTION_INDEX = 'lastInteraction_1';
11
11
  const SEARCH = 'search-text';
12
+ const NAME = 'name_1';
12
13
 
13
14
  /**
14
15
  * @typedef {object} State
@@ -22,8 +23,6 @@ const SEARCH = 'search-text';
22
23
  * @prop {string} [search]
23
24
  */
24
25
 
25
- /** @typedef {import('mongodb').Db} Db */
26
-
27
26
  /**
28
27
  * Storage for chat states
29
28
  *
@@ -33,24 +32,29 @@ class StateStorage extends BaseStorage {
33
32
 
34
33
  /**
35
34
  *
36
- * @param {Db|{():Promise<Db>}} mongoDb
35
+ * @param {mongodb.Db|{():Promise<mongodb.Db>}} mongoDb
37
36
  * @param {string} collectionName
38
37
  * @param {{error:Function,log:Function}} [log] - console like logger
39
38
  * @param {boolean} isCosmo
40
39
  */
41
- constructor (mongoDb, collectionName = 'states', log = defaultLogger, isCosmo = false) {
40
+ constructor (mongoDb, collectionName = 'states', log = console, isCosmo = false) {
42
41
  super(mongoDb, collectionName, log, isCosmo);
43
42
 
44
43
  this.addIndex(
45
44
  { senderId: 1, pageId: 1 },
46
- { name: USER_INDEX, unique: true }
45
+ { name: USER_INDEX, unique: true, dropDups: true }
47
46
  );
48
47
  this.addIndex(
49
48
  { lastInteraction: isCosmo ? 1 : -1 },
50
49
  { name: LAST_INTERACTION_INDEX }
51
50
  );
52
51
 
53
- if (!isCosmo) {
52
+ if (isCosmo) {
53
+ this.addIndex(
54
+ { name: 1 },
55
+ { name: NAME }
56
+ );
57
+ } else {
54
58
  this.addIndex(
55
59
  { '$**': 'text' },
56
60
  { name: SEARCH }
@@ -79,9 +83,7 @@ class StateStorage extends BaseStorage {
79
83
  */
80
84
  async getState (senderId, pageId) {
81
85
  const c = await this._getCollection();
82
- const doc = await c.findOne({ senderId, pageId }, { projection: { _id: 0 } });
83
- // @ts-ignore
84
- return doc;
86
+ return c.findOne({ senderId, pageId }, { projection: { _id: 0 } });
85
87
  }
86
88
 
87
89
  /**
@@ -160,8 +162,12 @@ class StateStorage extends BaseStorage {
160
162
 
161
163
  if (searchStates) {
162
164
  if (this._isCosmo) {
165
+ const $regex = `^${condition.search.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&')}`;
163
166
  Object.assign(useCondition, {
164
- name: { $regex: condition.search, $options: 'i' }
167
+ $or: [
168
+ { senderId: { $regex } },
169
+ { name: { $regex } }
170
+ ]
165
171
  });
166
172
  } else {
167
173
  Object.assign(useCondition, {