@storecraft/database-mongodb 1.0.15 → 1.0.17
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/README.md +71 -4
- package/index.js +5 -0
- package/package.json +2 -1
- package/src/con.auth_users.js +25 -19
- package/src/con.collections.js +70 -6
- package/src/con.customers.js +37 -10
- package/src/con.discounts.js +103 -11
- package/src/con.posts.js +1 -1
- package/src/con.products.js +61 -20
- package/src/con.search.js +4 -4
- package/src/con.shared.js +86 -46
- package/src/con.shipping.js +1 -3
- package/src/con.storefronts.js +113 -94
- package/src/utils.funcs.js +31 -45
- package/src/utils.relations.js +5 -17
- package/src/utils.types.d.ts +12 -0
- package/tests/docker-compose.yml +23 -0
- package/tests/runner.test.js +7 -3
- package/tests/{sandbox.test.js → sandbox.js} +10 -29
- package/vector-store/index.js +24 -8
- package/vector-store/types.d.ts +3 -1
package/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Storecraft MongoDB driver for
|
1
|
+
# Storecraft MongoDB driver for node / deno / bun
|
2
2
|
|
3
3
|
<div style="text-align:center">
|
4
4
|
<img src='https://storecraft.app/storecraft-color.svg'
|
@@ -28,14 +28,27 @@ import { MongoVectorStore } from '@storecraft/database-mongodb/vector-store'
|
|
28
28
|
|
29
29
|
const app = new App()
|
30
30
|
.withPlatform(new NodePlatform())
|
31
|
-
.withDatabase(
|
31
|
+
.withDatabase(
|
32
|
+
new MongoDB(
|
33
|
+
{
|
34
|
+
url: process.env.MONGODB_URL,
|
35
|
+
db_name: process.env.MONGODB_NAME,
|
36
|
+
}
|
37
|
+
)
|
38
|
+
)
|
32
39
|
.withVectorStore(
|
33
|
-
new MongoVectorStore(
|
40
|
+
new MongoVectorStore(
|
41
|
+
{
|
42
|
+
embedder: new OpenAIEmbedder(),
|
43
|
+
url: process.env.MONGODB_VECTOR_STORE_URL ?? process.env.MONGODB_URL,
|
44
|
+
db_name: process.env.MONGODB_VECTOR_STORE_DB_NAME ?? process.env.MONGODB_NAME,
|
45
|
+
}
|
46
|
+
)
|
34
47
|
)
|
35
48
|
|
36
49
|
await app.init();
|
37
50
|
await migrateToLatest(app.db, false);
|
38
|
-
//
|
51
|
+
// create if not exists
|
39
52
|
await app.vectorstore.createVectorIndex(false, false);
|
40
53
|
|
41
54
|
const server = http.createServer(app.handler).listen(
|
@@ -48,6 +61,60 @@ const server = http.createServer(app.handler).listen(
|
|
48
61
|
```
|
49
62
|
|
50
63
|
|
64
|
+
Storecraft will search the following `env` variables
|
65
|
+
|
66
|
+
```bash
|
67
|
+
MONGODB_NAME=main
|
68
|
+
MONGODB_URL='mongodb-connection-string'
|
69
|
+
|
70
|
+
// also, this will default into `MONGODB_NAME`
|
71
|
+
MONGODB_VECTOR_STORE_DB_NAME=vector-store
|
72
|
+
// also, this will default into `MONGODB_URL`
|
73
|
+
MONGODB_VECTOR_STORE_URL='mongodb-connection-string'
|
74
|
+
```
|
75
|
+
|
76
|
+
So, you can instantiate with empty config
|
77
|
+
|
78
|
+
```ts
|
79
|
+
.withDatabase(
|
80
|
+
new MongoDB()
|
81
|
+
)
|
82
|
+
.withVectorStore(
|
83
|
+
new MongoVectorStore(
|
84
|
+
{
|
85
|
+
embedder: new OpenAIEmbedder(),
|
86
|
+
}
|
87
|
+
)
|
88
|
+
)
|
89
|
+
```
|
90
|
+
|
91
|
+
|
92
|
+
## Testing Locally (I recommend to use `Atlas`)
|
93
|
+
|
94
|
+
1. First start a `mongo-db` server
|
95
|
+
First, make sure you have `docker` installed,
|
96
|
+
Then, run
|
97
|
+
|
98
|
+
```bash
|
99
|
+
npm run database-mongodb:docker-compose-up
|
100
|
+
```
|
101
|
+
|
102
|
+
2. create Environment
|
103
|
+
|
104
|
+
create `.env` file with
|
105
|
+
|
106
|
+
```bash
|
107
|
+
MONGODB_URL="mongodb://127.0.0.1:27017/?replicaSet=rs0"
|
108
|
+
MONGODB_NAME="main"
|
109
|
+
```
|
110
|
+
|
111
|
+
3. Run `tests/runner.test.js`
|
112
|
+
|
113
|
+
```bash
|
114
|
+
npm run database-mongodb:test
|
115
|
+
```
|
116
|
+
|
117
|
+
|
51
118
|
```text
|
52
119
|
Author: Tomer Shalev <tomer.shalev@gmail.com>
|
53
120
|
```
|
package/index.js
CHANGED
@@ -68,6 +68,7 @@ export class MongoDB {
|
|
68
68
|
constructor(config) {
|
69
69
|
this.#is_ready = false;
|
70
70
|
this.#config = {
|
71
|
+
db_name: 'main',
|
71
72
|
options: {
|
72
73
|
ignoreUndefined: true,
|
73
74
|
serverApi: {
|
@@ -161,6 +162,10 @@ export class MongoDB {
|
|
161
162
|
return this.#mongo_client;
|
162
163
|
}
|
163
164
|
|
165
|
+
get db() {
|
166
|
+
return this.mongo_client.db(this.name);
|
167
|
+
}
|
168
|
+
|
164
169
|
/**
|
165
170
|
*
|
166
171
|
* @description Get the config object
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@storecraft/database-mongodb",
|
3
|
-
"version": "1.0.
|
3
|
+
"version": "1.0.17",
|
4
4
|
"description": "Storecraft database driver for mongodb on node / bun / deno platform",
|
5
5
|
"license": "MIT",
|
6
6
|
"author": "Tomer Shalev (https://github.com/store-craft)",
|
@@ -33,6 +33,7 @@
|
|
33
33
|
}
|
34
34
|
},
|
35
35
|
"scripts": {
|
36
|
+
"database-mongodb:docker-compose-up": "docker compose -f ./tests/docker-compose.yml up -d ",
|
36
37
|
"database-mongodb:test": "node ./tests/runner.test.js",
|
37
38
|
"test": "npm run database-mongodb:test",
|
38
39
|
"prepublishOnly": "npm version patch --force",
|
package/src/con.auth_users.js
CHANGED
@@ -6,6 +6,7 @@
|
|
6
6
|
import { MongoDB } from '../index.js'
|
7
7
|
import { Collection } from 'mongodb'
|
8
8
|
import {
|
9
|
+
handle_or_id,
|
9
10
|
objid_or_else_filter, sanitize_one, to_objid_safe
|
10
11
|
} from './utils.funcs.js'
|
11
12
|
import {
|
@@ -62,32 +63,37 @@ const getByEmail = (driver) => {
|
|
62
63
|
|
63
64
|
/**
|
64
65
|
* @param {MongoDB} driver
|
65
|
-
*
|
66
|
-
*
|
67
66
|
* @returns {db_col["remove"]}
|
68
67
|
*/
|
69
68
|
const remove = (driver) => {
|
70
|
-
return async (
|
69
|
+
return async (id_or_handle) => {
|
70
|
+
|
71
|
+
const session = driver.mongo_client.startSession();
|
72
|
+
try {
|
73
|
+
await session.withTransaction(
|
74
|
+
async () => {
|
75
|
+
const filter = handle_or_id(id_or_handle);
|
76
|
+
await col(driver).deleteOne(
|
77
|
+
filter,
|
78
|
+
{ session }
|
79
|
+
);
|
80
|
+
// customer and auth_user have the same object-id and handle
|
81
|
+
// so we can use the same filter
|
82
|
+
await driver.resources.customers._col.deleteOne(
|
83
|
+
filter,
|
84
|
+
{ session }
|
85
|
+
);
|
71
86
|
|
72
|
-
let filter;
|
73
|
-
|
74
|
-
{
|
75
|
-
if(to_objid_safe(id)) {
|
76
|
-
filter = {
|
77
|
-
_id: to_objid_safe(id)
|
78
|
-
}
|
79
|
-
} else {
|
80
|
-
filter = {
|
81
|
-
email: id
|
82
87
|
}
|
83
|
-
|
88
|
+
);
|
89
|
+
} catch(e) {
|
90
|
+
console.log(e);
|
91
|
+
return false;
|
92
|
+
} finally {
|
93
|
+
await session.endSession();
|
84
94
|
}
|
85
95
|
|
86
|
-
|
87
|
-
filter
|
88
|
-
);
|
89
|
-
|
90
|
-
return Boolean(res.deletedCount)
|
96
|
+
return true;
|
91
97
|
}
|
92
98
|
}
|
93
99
|
|
package/src/con.collections.js
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
/**
|
2
2
|
* @import { db_collections as db_col } from '@storecraft/core/database'
|
3
3
|
* @import { ProductType, VariantType } from '@storecraft/core/api'
|
4
|
-
* @import { WithRelations } from './utils.
|
4
|
+
* @import { WithRelations } from './utils.types.js'
|
5
5
|
* @import { Filter } from 'mongodb'
|
6
6
|
*/
|
7
7
|
|
@@ -27,8 +27,6 @@ const transactionOptions = {
|
|
27
27
|
|
28
28
|
/**
|
29
29
|
* @param {MongoDB} d
|
30
|
-
*
|
31
|
-
*
|
32
30
|
* @returns {Collection<WithRelations<db_col["$type_get"]>>}
|
33
31
|
*/
|
34
32
|
const col = (d) => d.collection('collections');
|
@@ -169,8 +167,6 @@ const count = (driver) => count_regular(driver, col(driver));
|
|
169
167
|
|
170
168
|
/**
|
171
169
|
* @param {MongoDB} driver
|
172
|
-
*
|
173
|
-
*
|
174
170
|
* @returns {db_col["list_collection_products"]}
|
175
171
|
*/
|
176
172
|
const list_collection_products = (driver) => {
|
@@ -213,6 +209,72 @@ const list_collection_products = (driver) => {
|
|
213
209
|
}
|
214
210
|
}
|
215
211
|
|
212
|
+
|
213
|
+
/**
|
214
|
+
* @param {MongoDB} driver
|
215
|
+
* @returns {db_col["count_collection_products"]}
|
216
|
+
*/
|
217
|
+
const count_collection_products = (driver) => {
|
218
|
+
return async (handle_or_id, query) => {
|
219
|
+
|
220
|
+
const {
|
221
|
+
filter: filter_query, sort, reverse_sign
|
222
|
+
} = query_to_mongo(query);
|
223
|
+
|
224
|
+
/**
|
225
|
+
* @type {Filter<WithRelations<ProductType | VariantType>>
|
226
|
+
* }
|
227
|
+
*/
|
228
|
+
const filter = {
|
229
|
+
$and: [
|
230
|
+
{ '_relations.search': `col:${handle_or_id}` },
|
231
|
+
]
|
232
|
+
};
|
233
|
+
|
234
|
+
// add the query filter
|
235
|
+
isDef(filter_query) && filter.$and.push(filter_query);
|
236
|
+
|
237
|
+
const count = await driver.resources.products._col.countDocuments(
|
238
|
+
filter
|
239
|
+
);
|
240
|
+
|
241
|
+
return count;
|
242
|
+
}
|
243
|
+
}
|
244
|
+
|
245
|
+
|
246
|
+
|
247
|
+
/**
|
248
|
+
* @param {MongoDB} driver
|
249
|
+
* @returns {db_col["list_used_products_tags"]}
|
250
|
+
*/
|
251
|
+
const list_used_products_tags = (driver) => {
|
252
|
+
return async (handle_or_id) => {
|
253
|
+
const items = await driver.resources.products._col.find(
|
254
|
+
{
|
255
|
+
'_relations.search': `col:${handle_or_id}`
|
256
|
+
},
|
257
|
+
{
|
258
|
+
projection: {
|
259
|
+
tags: 1
|
260
|
+
}
|
261
|
+
}
|
262
|
+
).toArray();
|
263
|
+
|
264
|
+
const set = (items ?? []).reduce(
|
265
|
+
(p, c) => {
|
266
|
+
c.tags.forEach(
|
267
|
+
(tag) => p.add(tag)
|
268
|
+
);
|
269
|
+
return p;
|
270
|
+
}, new Set()
|
271
|
+
)
|
272
|
+
// return array from set
|
273
|
+
return Array.from(set);
|
274
|
+
}
|
275
|
+
}
|
276
|
+
|
277
|
+
|
216
278
|
/**
|
217
279
|
* @param {MongoDB} driver
|
218
280
|
*
|
@@ -228,6 +290,8 @@ export const impl = (driver) => {
|
|
228
290
|
remove: remove(driver),
|
229
291
|
list: list(driver),
|
230
292
|
count: count(driver),
|
231
|
-
list_collection_products: list_collection_products(driver)
|
293
|
+
list_collection_products: list_collection_products(driver),
|
294
|
+
count_collection_products: count_collection_products(driver),
|
295
|
+
list_used_products_tags: list_used_products_tags(driver),
|
232
296
|
}
|
233
297
|
}
|
package/src/con.customers.js
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
/**
|
2
2
|
* @import { db_customers as db_col } from '@storecraft/core/database'
|
3
3
|
* @import { OrderData } from '@storecraft/core/api'
|
4
|
-
* @import { WithRelations } from './utils.
|
4
|
+
* @import { WithRelations } from './utils.types.js'
|
5
5
|
* @import { Filter } from 'mongodb'
|
6
6
|
*/
|
7
7
|
|
@@ -9,7 +9,7 @@ import { Collection, ObjectId } from 'mongodb'
|
|
9
9
|
import { MongoDB } from '../index.js'
|
10
10
|
import { count_regular, get_regular, list_regular,
|
11
11
|
upsert_regular } from './con.shared.js'
|
12
|
-
import { isDef, sanitize_array, to_objid } from './utils.funcs.js'
|
12
|
+
import { handle_or_id, isDef, sanitize_array, to_objid } from './utils.funcs.js'
|
13
13
|
import { query_to_mongo } from './utils.query.js';
|
14
14
|
|
15
15
|
/**
|
@@ -62,8 +62,6 @@ export const email_or_id = (email_or_id) => {
|
|
62
62
|
|
63
63
|
/**
|
64
64
|
* @param {MongoDB} driver
|
65
|
-
*
|
66
|
-
*
|
67
65
|
* @returns {db_col["remove"]}
|
68
66
|
*/
|
69
67
|
const remove = (driver) => {
|
@@ -74,7 +72,7 @@ const remove = (driver) => {
|
|
74
72
|
await session.withTransaction(
|
75
73
|
async () => {
|
76
74
|
const res = await col(driver).findOneAndDelete(
|
77
|
-
|
75
|
+
handle_or_id(id),
|
78
76
|
{ session }
|
79
77
|
);
|
80
78
|
|
@@ -120,10 +118,10 @@ const list_customer_orders = (driver) => {
|
|
120
118
|
|
121
119
|
const { filter: filter_query, sort, reverse_sign } = query_to_mongo(query);
|
122
120
|
|
123
|
-
console.log('query', query)
|
124
|
-
console.log('filter', JSON.stringify(filter_query, null, 2))
|
125
|
-
console.log('sort', sort)
|
126
|
-
console.log('expand', query?.expand)
|
121
|
+
// console.log('query', query)
|
122
|
+
// console.log('filter', JSON.stringify(filter_query, null, 2))
|
123
|
+
// console.log('sort', sort)
|
124
|
+
// console.log('expand', query?.expand)
|
127
125
|
|
128
126
|
/** @type {Filter<WithRelations<OrderData>>} */
|
129
127
|
const filter = {
|
@@ -147,6 +145,34 @@ const list_customer_orders = (driver) => {
|
|
147
145
|
}
|
148
146
|
}
|
149
147
|
|
148
|
+
/**
|
149
|
+
* @param {MongoDB} driver
|
150
|
+
* @returns {db_col["count_customer_orders"]}
|
151
|
+
*/
|
152
|
+
const count_customer_orders = (driver) => {
|
153
|
+
return async (customer_id, query) => {
|
154
|
+
|
155
|
+
const { filter: filter_query } = query_to_mongo(query);
|
156
|
+
|
157
|
+
/** @type {Filter<WithRelations<OrderData>>} */
|
158
|
+
const filter = {
|
159
|
+
$and: [
|
160
|
+
{'_relations.search': `customer:${customer_id}` },
|
161
|
+
]
|
162
|
+
};
|
163
|
+
|
164
|
+
// add the query filter
|
165
|
+
isDef(filter_query) && filter.$and.push(filter_query);
|
166
|
+
|
167
|
+
const count = await driver.resources.orders._col.countDocuments(
|
168
|
+
filter
|
169
|
+
);
|
170
|
+
|
171
|
+
return count;
|
172
|
+
}
|
173
|
+
}
|
174
|
+
|
175
|
+
|
150
176
|
/**
|
151
177
|
* @param {MongoDB} driver
|
152
178
|
*
|
@@ -163,6 +189,7 @@ export const impl = (driver) => {
|
|
163
189
|
remove: remove(driver),
|
164
190
|
list: list(driver),
|
165
191
|
count: count(driver),
|
166
|
-
list_customer_orders: list_customer_orders(driver)
|
192
|
+
list_customer_orders: list_customer_orders(driver),
|
193
|
+
count_customer_orders: count_customer_orders(driver),
|
167
194
|
}
|
168
195
|
}
|
package/src/con.discounts.js
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
/**
|
2
2
|
* @import { db_discounts as db_col } from '@storecraft/core/database'
|
3
3
|
* @import { ProductType, VariantType } from '@storecraft/core/api'
|
4
|
-
* @import { WithRelations } from './utils.
|
4
|
+
* @import { WithRelations } from './utils.types.js'
|
5
5
|
* @import { Filter } from 'mongodb'
|
6
6
|
*/
|
7
7
|
|
@@ -23,7 +23,10 @@ import {
|
|
23
23
|
save_me,
|
24
24
|
update_entry_on_all_connection_of_relation
|
25
25
|
} from './utils.relations.js'
|
26
|
-
|
26
|
+
import {
|
27
|
+
helper_compute_product_extra_search_keywords_because_of_discount_side_effect_for_db,
|
28
|
+
helper_compute_product_extra_tags_because_of_discount_side_effect_for_db
|
29
|
+
} from '@storecraft/core/database'
|
27
30
|
|
28
31
|
/**
|
29
32
|
* @param {MongoDB} d
|
@@ -54,16 +57,27 @@ const upsert = (driver) => {
|
|
54
57
|
// SEARCH
|
55
58
|
add_search_terms_relation_on(data, search_terms);
|
56
59
|
|
57
|
-
|
58
60
|
////
|
59
61
|
// PRODUCT --> DISCOUNTS RELATION
|
60
62
|
////
|
63
|
+
const extra_search_for_products =
|
64
|
+
helper_compute_product_extra_search_keywords_because_of_discount_side_effect_for_db(
|
65
|
+
data
|
66
|
+
);
|
67
|
+
|
68
|
+
const extra_tags_for_products =
|
69
|
+
helper_compute_product_extra_tags_because_of_discount_side_effect_for_db(
|
70
|
+
data
|
71
|
+
);
|
61
72
|
|
62
73
|
// first remove discount from anywhere
|
63
74
|
await remove_entry_from_all_connection_of_relation(
|
64
75
|
driver, 'products', 'discounts', objid, session,
|
65
|
-
[
|
66
|
-
|
76
|
+
[ // remove search terms
|
77
|
+
...extra_search_for_products
|
78
|
+
],
|
79
|
+
[ // remove tags
|
80
|
+
...extra_tags_for_products
|
67
81
|
]
|
68
82
|
);
|
69
83
|
|
@@ -77,8 +91,11 @@ const upsert = (driver) => {
|
|
77
91
|
$addToSet: {
|
78
92
|
'_relations.discounts.ids': objid,
|
79
93
|
'_relations.search': {
|
80
|
-
$each :
|
81
|
-
}
|
94
|
+
$each : extra_search_for_products
|
95
|
+
},
|
96
|
+
'tags': {
|
97
|
+
$each : extra_tags_for_products
|
98
|
+
}
|
82
99
|
},
|
83
100
|
|
84
101
|
},
|
@@ -145,13 +162,27 @@ const remove = (driver) => {
|
|
145
162
|
try {
|
146
163
|
await session.withTransaction(
|
147
164
|
async () => {
|
165
|
+
|
166
|
+
const extra_search_for_products =
|
167
|
+
helper_compute_product_extra_search_keywords_because_of_discount_side_effect_for_db(
|
168
|
+
item
|
169
|
+
);
|
170
|
+
|
171
|
+
const extra_tags_for_products =
|
172
|
+
helper_compute_product_extra_tags_because_of_discount_side_effect_for_db(
|
173
|
+
item
|
174
|
+
);
|
175
|
+
|
148
176
|
////
|
149
177
|
// PRODUCT -> DISCOUNTS RELATION
|
150
178
|
////
|
151
179
|
await remove_entry_from_all_connection_of_relation(
|
152
180
|
driver, 'products', 'discounts', objid, session,
|
153
181
|
[
|
154
|
-
|
182
|
+
...extra_search_for_products
|
183
|
+
],
|
184
|
+
[
|
185
|
+
...extra_tags_for_products
|
155
186
|
]
|
156
187
|
);
|
157
188
|
|
@@ -196,8 +227,6 @@ const count = (driver) => count_regular(driver, col(driver));
|
|
196
227
|
|
197
228
|
/**
|
198
229
|
* @param {MongoDB} driver
|
199
|
-
*
|
200
|
-
*
|
201
230
|
* @returns {db_col["list_discount_products"]}
|
202
231
|
*/
|
203
232
|
const list_discount_products = (driver) => {
|
@@ -235,6 +264,67 @@ const list_discount_products = (driver) => {
|
|
235
264
|
}
|
236
265
|
}
|
237
266
|
|
267
|
+
|
268
|
+
/**
|
269
|
+
* @param {MongoDB} driver
|
270
|
+
* @returns {db_col["list_all_discount_products_tags"]}
|
271
|
+
*/
|
272
|
+
const list_all_discount_products_tags = (driver) => {
|
273
|
+
return async (handle_or_id) => {
|
274
|
+
const items = await driver.resources.products._col.find(
|
275
|
+
{
|
276
|
+
'_relations.search': `discount:${handle_or_id}`
|
277
|
+
},
|
278
|
+
{
|
279
|
+
projection: {
|
280
|
+
tags: 1
|
281
|
+
}
|
282
|
+
}
|
283
|
+
).toArray();
|
284
|
+
|
285
|
+
const set = (items ?? []).reduce(
|
286
|
+
(p, c) => {
|
287
|
+
c.tags.forEach(
|
288
|
+
(tag) => p.add(tag)
|
289
|
+
);
|
290
|
+
return p;
|
291
|
+
}, new Set()
|
292
|
+
);
|
293
|
+
|
294
|
+
// return array from set
|
295
|
+
return Array.from(set);
|
296
|
+
}
|
297
|
+
}
|
298
|
+
|
299
|
+
|
300
|
+
/**
|
301
|
+
* @param {MongoDB} driver
|
302
|
+
* @returns {db_col["count_discount_products"]}
|
303
|
+
*/
|
304
|
+
const count_discount_products = (driver) => {
|
305
|
+
return async (handle_or_id, query) => {
|
306
|
+
|
307
|
+
const { filter: filter_query, sort, reverse_sign } = query_to_mongo(query);
|
308
|
+
|
309
|
+
/** @type {Filter<WithRelations<ProductType | VariantType>>} */
|
310
|
+
const filter = {
|
311
|
+
$and: [
|
312
|
+
{ '_relations.search': `discount:${handle_or_id}` },
|
313
|
+
]
|
314
|
+
};
|
315
|
+
|
316
|
+
// add the query filter
|
317
|
+
isDef(filter_query) && filter.$and.push(filter_query);
|
318
|
+
|
319
|
+
const count = await driver.resources.products._col.countDocuments(
|
320
|
+
filter
|
321
|
+
);
|
322
|
+
|
323
|
+
return count;
|
324
|
+
}
|
325
|
+
}
|
326
|
+
|
327
|
+
|
238
328
|
/**
|
239
329
|
* @param {MongoDB} driver
|
240
330
|
*
|
@@ -251,6 +341,8 @@ export const impl = (driver) => {
|
|
251
341
|
remove: remove(driver),
|
252
342
|
list: list(driver),
|
253
343
|
count: count(driver),
|
254
|
-
list_discount_products: list_discount_products(driver)
|
344
|
+
list_discount_products: list_discount_products(driver),
|
345
|
+
list_all_discount_products_tags: list_all_discount_products_tags(driver),
|
346
|
+
count_discount_products: count_discount_products(driver)
|
255
347
|
}
|
256
348
|
}
|