@storecraft/database-mongodb 1.0.19 → 1.0.21

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 CHANGED
@@ -91,7 +91,8 @@ So, you can instantiate with empty config
91
91
 
92
92
  ## Testing Locally (I recommend to use `Atlas`)
93
93
 
94
- 1. First start a `mongo-db` server
94
+ 1. Start a `mongo-db` server with `docker`
95
+
95
96
  First, make sure you have `docker` installed,
96
97
  Then, run
97
98
 
package/index.js CHANGED
@@ -1,8 +1,6 @@
1
1
  /**
2
2
  * @import { Config } from './types.public.js'
3
- * @import { MongoClientOptions } from 'mongodb'
4
3
  * @import { db_driver } from '@storecraft/core/database'
5
- * @import { BaseType } from '@storecraft/core/api'
6
4
  * @import { ENV } from '@storecraft/core'
7
5
  */
8
6
  import { App } from '@storecraft/core';
@@ -24,7 +22,6 @@ import { impl as search } from './src/con.search.js';
24
22
  export { migrateToLatest } from './migrate.js';
25
23
  export { MongoVectorStore } from './vector-store/index.js';
26
24
 
27
-
28
25
  /**
29
26
  * @implements {db_driver}
30
27
  */
@@ -36,34 +33,22 @@ export class MongoDB {
36
33
  url: 'MONGODB_URL',
37
34
  });
38
35
 
39
- /**
40
- *
41
- * @type {boolean}
42
- */
36
+ /** @type {boolean} */
43
37
  #is_ready;
44
38
 
45
- /**
46
- *
47
- * @type {App<any, any, any>}
48
- */
39
+ /** @type {App<any, any, any>} */
49
40
  #app;
50
41
 
51
- /**
52
- *
53
- * @type {MongoClient}
54
- */
42
+ /** @type {MongoClient} */
55
43
  #mongo_client;
56
44
 
57
- /**
58
- *
59
- * @type {Config}
60
- */
45
+ /** @type {Config} */
61
46
  #config;
62
47
 
63
48
  /**
64
- *
65
49
  * @param {Config} [config] config, if undefined,
66
- * env variables `MONGODB_URL` will be used for uri upon init later
50
+ * env variables `MONGODB_URL` will be used for
51
+ * uri upon init later
67
52
  */
68
53
  constructor(config) {
69
54
  this.#is_ready = false;
@@ -81,18 +66,20 @@ export class MongoDB {
81
66
  };
82
67
  }
83
68
 
84
- /**
85
- * @type {db_driver["init"]}
86
- */
69
+ /** @type {db_driver["init"]} */
87
70
  init(app) {
88
71
  if(this.isReady)
89
72
  return this;
73
+
90
74
  const c = this.#config;
75
+
91
76
  c.db_name ??= app.platform.env[MongoDB.EnvConfig.db_name];
92
77
  c.url ??= app.platform.env[MongoDB.EnvConfig.url] ?? 'main';
93
78
 
94
79
  if(!this.config.db_name || !this.config.url) {
95
- throw new Error('MongoVectorStore::client() - missing url or db_name');
80
+ throw new Error(
81
+ 'MongoVectorStore::client() - missing url or db_name'
82
+ );
96
83
  }
97
84
 
98
85
  this.#app = app;
@@ -120,6 +107,7 @@ export class MongoDB {
120
107
 
121
108
  async disconnect() {
122
109
  await this.mongo_client.close(true);
110
+
123
111
  return true;
124
112
  }
125
113
 
@@ -131,7 +119,6 @@ export class MongoDB {
131
119
  }
132
120
 
133
121
  /**
134
- *
135
122
  * @description database name
136
123
  */
137
124
  get name () {
@@ -139,7 +126,6 @@ export class MongoDB {
139
126
  }
140
127
 
141
128
  /**
142
- *
143
129
  * @description Get the `storecraft` app
144
130
  */
145
131
  get app() {
@@ -147,12 +133,13 @@ export class MongoDB {
147
133
  }
148
134
 
149
135
  /**
150
- *
151
136
  * @description Get the native `mongodb` client
152
137
  */
153
138
  get mongo_client() {
154
139
  if(!this.config.db_name || !this.config.url) {
155
- throw new Error('MongoVectorStore::client() - missing url or db_name');
140
+ throw new Error(
141
+ 'MongoVectorStore::client() - missing url or db_name'
142
+ );
156
143
  }
157
144
 
158
145
  this.#mongo_client = this.#mongo_client ?? new MongoClient(
@@ -167,7 +154,6 @@ export class MongoDB {
167
154
  }
168
155
 
169
156
  /**
170
- *
171
157
  * @description Get the config object
172
158
  */
173
159
  get config() {
@@ -175,13 +161,8 @@ export class MongoDB {
175
161
  }
176
162
 
177
163
  /**
178
- *
179
- * @template {BaseType} T
180
- *
181
- *
164
+ * @template T
182
165
  * @param {string} name
183
- *
184
- *
185
166
  * @returns {Collection<T>}
186
167
  */
187
168
  collection(name) {
package/migrate.js CHANGED
@@ -7,7 +7,6 @@ const __filename = fileURLToPath(import.meta.url);
7
7
  const __dirname = path.dirname(__filename);
8
8
 
9
9
  /**
10
- *
11
10
  * @param {MongoDB} driver
12
11
  * @param {boolean} [destroy_db_upon_completion=true]
13
12
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@storecraft/database-mongodb",
3
- "version": "1.0.19",
3
+ "version": "1.0.21",
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)",
@@ -1,22 +1,18 @@
1
1
  /**
2
2
  * @import { db_auth_users as db_col } from '@storecraft/core/database'
3
- * @import { AuthUserType } from '@storecraft/core/api'
4
3
  */
5
-
6
4
  import { MongoDB } from '../index.js'
7
5
  import { Collection } from 'mongodb'
8
6
  import {
9
7
  handle_or_id,
10
- objid_or_else_filter, sanitize_one, to_objid_safe
8
+ objid_or_else_filter, sanitize_one
11
9
  } from './utils.funcs.js'
12
10
  import {
13
- count_regular, get_regular, list_regular, upsert_regular
11
+ count_regular, list_regular, upsert_regular
14
12
  } from './con.shared.js'
15
13
 
16
14
  /**
17
15
  * @param {MongoDB} d
18
- *
19
- *
20
16
  * @returns {Collection<db_col["$type_get"]>}
21
17
  */
22
18
  const col = (d) => d.collection('auth_users');
@@ -29,8 +25,6 @@ const upsert = (driver) => upsert_regular(driver, col(driver));
29
25
 
30
26
  /**
31
27
  * @param {MongoDB} driver
32
- *
33
- *
34
28
  * @returns {db_col["getByEmail"]}
35
29
  */
36
30
  const get = (driver) => {
@@ -46,8 +40,6 @@ const get = (driver) => {
46
40
 
47
41
  /**
48
42
  * @param {MongoDB} driver
49
- *
50
- *
51
43
  * @returns {db_col["getByEmail"]}
52
44
  */
53
45
  const getByEmail = (driver) => {
@@ -99,8 +91,6 @@ const remove = (driver) => {
99
91
 
100
92
  /**
101
93
  * @param {MongoDB} driver
102
- *
103
- *
104
94
  * @returns {db_col["removeByEmail"]}
105
95
  */
106
96
  const removeByEmail = (driver) => {
@@ -125,10 +115,8 @@ const count = (driver) => count_regular(driver, col(driver));
125
115
 
126
116
  /**
127
117
  * @param {MongoDB} driver
128
- *
129
- *
130
118
  * @return {db_col & { _col: ReturnType<col>}}
131
- * */
119
+ */
132
120
  export const impl = (driver) => {
133
121
 
134
122
  return {
@@ -4,7 +4,6 @@
4
4
  * @import { WithRelations } from './utils.types.js'
5
5
  * @import { Filter } from 'mongodb'
6
6
  */
7
-
8
7
  import { Collection } from 'mongodb'
9
8
  import { MongoDB } from '../index.js'
10
9
  import { count_regular, expand, get_regular, list_regular } from './con.shared.js'
@@ -18,7 +17,6 @@ import {
18
17
  update_entry_on_all_connection_of_relation
19
18
  } from './utils.relations.js'
20
19
 
21
-
22
20
  const transactionOptions = {
23
21
  readPreference: 'primary',
24
22
  readConcern: { level: 'local' },
@@ -94,8 +92,6 @@ const get = (driver) => get_regular(driver, col(driver));
94
92
 
95
93
  /**
96
94
  * @param {MongoDB} driver
97
- *
98
- *
99
95
  * @returns {db_col["remove"]}
100
96
  */
101
97
  const remove = (driver) => {
@@ -221,10 +217,7 @@ const count_collection_products = (driver) => {
221
217
  filter: filter_query, sort, reverse_sign
222
218
  } = query_to_mongo(query);
223
219
 
224
- /**
225
- * @type {Filter<WithRelations<ProductType | VariantType>>
226
- * }
227
- */
220
+ /** @type {Filter<WithRelations<ProductType | VariantType>>} */
228
221
  const filter = {
229
222
  $and: [
230
223
  { '_relations.search': `col:${handle_or_id}` },
@@ -277,10 +270,8 @@ const list_used_products_tags = (driver) => {
277
270
 
278
271
  /**
279
272
  * @param {MongoDB} driver
280
- *
281
- *
282
273
  * @return {db_col & { _col: ReturnType<col>}}
283
- * */
274
+ */
284
275
  export const impl = (driver) => {
285
276
 
286
277
  return {
@@ -4,17 +4,17 @@
4
4
  * @import { WithRelations } from './utils.types.js'
5
5
  * @import { Filter } from 'mongodb'
6
6
  */
7
-
8
7
  import { Collection, ObjectId } from 'mongodb'
9
8
  import { MongoDB } from '../index.js'
10
- import { count_regular, get_regular, list_regular,
11
- upsert_regular } from './con.shared.js'
9
+ import {
10
+ count_regular, get_regular, list_regular,
11
+ upsert_regular
12
+ } from './con.shared.js'
12
13
  import { handle_or_id, isDef, sanitize_array, to_objid } from './utils.funcs.js'
13
14
  import { query_to_mongo } from './utils.query.js';
14
15
 
15
16
  /**
16
17
  * @param {MongoDB} d
17
- *
18
18
  * @returns {Collection<db_col["$type_get"]>}
19
19
  */
20
20
  const col = (d) => d.collection('customers');
@@ -31,8 +31,6 @@ const get = (driver) => get_regular(driver, col(driver));
31
31
 
32
32
  /**
33
33
  * @param {MongoDB} driver
34
- *
35
- *
36
34
  * @returns {db_col["getByEmail"]}
37
35
  */
38
36
  const getByEmail = (driver) => {
@@ -44,10 +42,7 @@ const getByEmail = (driver) => {
44
42
  }
45
43
 
46
44
  /**
47
- *
48
45
  * @param {string} email_or_id
49
- *
50
- *
51
46
  * @returns { {_id:ObjectId} | {email: string}}
52
47
  */
53
48
  export const email_or_id = (email_or_id) => {
@@ -109,14 +104,14 @@ const count = (driver) => count_regular(driver, col(driver));
109
104
 
110
105
  /**
111
106
  * @param {MongoDB} driver
112
- *
113
- *
114
107
  * @returns {db_col["list_customer_orders"]}
115
108
  */
116
109
  const list_customer_orders = (driver) => {
117
- return async (customer_id, query) => {
110
+ return async (customer_id_or_email, query) => {
118
111
 
119
- const { filter: filter_query, sort, reverse_sign } = query_to_mongo(query);
112
+ const {
113
+ filter: filter_query, sort, reverse_sign
114
+ } = query_to_mongo(query);
120
115
 
121
116
  // console.log('query', query)
122
117
  // console.log('filter', JSON.stringify(filter_query, null, 2))
@@ -126,7 +121,7 @@ const list_customer_orders = (driver) => {
126
121
  /** @type {Filter<WithRelations<OrderData>>} */
127
122
  const filter = {
128
123
  $and: [
129
- {'_relations.search': `customer:${customer_id}` },
124
+ {'_relations.search': `customer:${customer_id_or_email}` },
130
125
  ]
131
126
  };
132
127
 
@@ -175,10 +170,8 @@ const count_customer_orders = (driver) => {
175
170
 
176
171
  /**
177
172
  * @param {MongoDB} driver
178
- *
179
- *
180
173
  * @return {db_col & { _col: ReturnType<col>}}
181
- * */
174
+ */
182
175
  export const impl = (driver) => {
183
176
 
184
177
  return {
@@ -4,7 +4,6 @@
4
4
  * @import { WithRelations } from './utils.types.js'
5
5
  * @import { Filter } from 'mongodb'
6
6
  */
7
-
8
7
  import { Collection } from 'mongodb'
9
8
  import { MongoDB } from '../index.js'
10
9
  import {
@@ -13,7 +12,7 @@ import {
13
12
  import {
14
13
  handle_or_id, isDef, sanitize_array, to_objid
15
14
  } from './utils.funcs.js'
16
- import { discount_to_mongo_conjunctions } from './con.discounts.utils.js'
15
+ import { discount_to_mongo_conjunctions, is_order_discount } from './con.discounts.utils.js'
17
16
  import { query_to_mongo } from './utils.query.js'
18
17
  import { report_document_media } from './con.images.js'
19
18
  import { enums } from '@storecraft/core/api'
@@ -30,8 +29,6 @@ import {
30
29
 
31
30
  /**
32
31
  * @param {MongoDB} d
33
- *
34
- *
35
32
  * @returns {Collection<db_col["$type_get"]>}
36
33
  */
37
34
  const col = (d) => d.collection('discounts');
@@ -39,8 +36,6 @@ const col = (d) => d.collection('discounts');
39
36
 
40
37
  /**
41
38
  * @param {MongoDB} driver
42
- *
43
- *
44
39
  * @returns {db_col["upsert"]}
45
40
  */
46
41
  const upsert = (driver) => {
@@ -82,7 +77,11 @@ const upsert = (driver) => {
82
77
  );
83
78
 
84
79
  // now filter and update for products
85
- if(data.active && data.application.id===enums.DiscountApplicationEnum.Auto.id) {
80
+ if(
81
+ data.active &&
82
+ data.application.id===enums.DiscountApplicationEnum.Auto.id &&
83
+ !is_order_discount(data)
84
+ ) {
86
85
  const conjunctions = discount_to_mongo_conjunctions(data);
87
86
  await driver.resources.products._col.updateMany(
88
87
  conjunctions.length ? { $and: conjunctions } : {},
@@ -143,8 +142,6 @@ const get = (driver) => get_regular(driver, col(driver));
143
142
 
144
143
  /**
145
144
  * @param {MongoDB} driver
146
- *
147
- *
148
145
  * @returns {db_col["remove"]}
149
146
  */
150
147
  const remove = (driver) => {
@@ -327,8 +324,6 @@ const count_discount_products = (driver) => {
327
324
 
328
325
  /**
329
326
  * @param {MongoDB} driver
330
- *
331
- *
332
327
  * @return {db_col & { _col: ReturnType<col>}}
333
328
  */
334
329
  export const impl = (driver) => {
@@ -1,21 +1,24 @@
1
1
  /**
2
2
  * @import {
3
- * DiscountType, FilterValue_p_in_price_range, FilterValue_p_not_in_collections,
4
- * FilterValue_p_in_collections, FilterValue_p_not_in_tags, FilterValue_p_in_tags,
5
- * FilterValue_p_in_products, FilterValue_p_not_in_products
3
+ * DiscountType, Filter_p_in_price_range, Filter_p_not_in_collections,
4
+ * Filter_p_in_collections, Filter_p_not_in_tags, Filter_p_in_tags,
5
+ * Filter_p_in_products, Filter_p_not_in_products
6
6
  * } from '@storecraft/core/api'
7
7
  */
8
-
9
8
  import { enums } from "@storecraft/core/api";
10
9
  import { to_objid_safe } from "./utils.funcs.js";
11
10
 
12
11
  /** @param {DiscountType} d */
13
- const is_order_discount = d => {
14
- return (d.info.details.meta.id===enums.DiscountMetaEnum.order.id);
12
+ export const is_order_discount = d => {
13
+ return (
14
+ (d.info.details.type===enums.DiscountMetaEnum.order.type) ||
15
+ // @ts-ignore
16
+ (d.info.details.meta?.type===enums.DiscountMetaEnum.order.type)
17
+ );
15
18
  }
16
19
 
17
20
  /** @param {DiscountType} d */
18
- const is_automatic_discount = d => {
21
+ export const is_automatic_discount = d => {
19
22
  return (d.application.id===enums.DiscountApplicationEnum.Auto.id);
20
23
  }
21
24
 
@@ -40,7 +43,7 @@ export const discount_to_mongo_conjunctions = d => {
40
43
  const filters = d.info.filters;
41
44
 
42
45
  for(const filter of filters) {
43
- const op = filter.meta.op;
46
+ const op = filter.op ?? filter.meta.op;
44
47
 
45
48
  switch (op) {
46
49
  case enums.FilterMetaEnum.p_all.op:
@@ -48,58 +51,64 @@ export const discount_to_mongo_conjunctions = d => {
48
51
  break;
49
52
  case enums.FilterMetaEnum.p_in_products.op:
50
53
  {
51
- const cast = /** @type {FilterValue_p_in_products} */ (
52
- filter.value ?? []
54
+ const filter_cast = /** @type {Filter_p_in_products} */ (
55
+ filter
53
56
  );
57
+ const value = filter_cast?.value ?? [];
54
58
 
55
59
  conjunctions.push(
56
- { handle: { $in: cast.map(it => it.handle) } }
60
+ { handle: { $in: value.map(it => it.handle) } }
57
61
  );
58
62
  }
59
63
  break;
60
64
  case enums.FilterMetaEnum.p_not_in_products.op:
61
65
  {
62
- const cast = /** @type {FilterValue_p_not_in_products} */(
63
- filter.value ?? []
66
+ const filter_cast = /** @type {Filter_p_not_in_products} */ (
67
+ filter
64
68
  );
69
+
70
+ const value = filter_cast?.value ?? [];
65
71
 
66
72
  conjunctions.push(
67
- { handle: { $nin: cast.map(it => it.handle) } }
73
+ { handle: { $nin: value.map(it => it.handle) } }
68
74
  );
69
75
  }
70
76
  break;
71
77
  case enums.FilterMetaEnum.p_in_tags.op:
72
78
  {
73
- const cast = /** @type {FilterValue_p_in_tags} */ (
74
- filter.value ?? []
79
+ const filter_cast = /** @type {Filter_p_in_tags} */ (
80
+ filter
75
81
  );
82
+ const value = filter_cast?.value ?? [];
76
83
 
77
84
  conjunctions.push(
78
- { tags: { $in: cast } }
85
+ { tags: { $in: value } }
79
86
  );
80
87
  }
81
88
  break;
82
89
  case enums.FilterMetaEnum.p_not_in_tags.op:
83
90
  {
84
- const cast = /** @type {FilterValue_p_not_in_tags} */(
85
- filter.value ?? []
91
+ const filter_cast = /** @type {Filter_p_not_in_tags} */ (
92
+ filter
86
93
  );
94
+ const value = filter_cast?.value ?? [];
87
95
 
88
96
  conjunctions.push(
89
- { tags: { $nin: cast } }
97
+ { tags: { $nin: value } }
90
98
  );
91
99
  }
92
100
  break;
93
101
  case enums.FilterMetaEnum.p_in_collections.op:
94
102
  {
95
- const cast = /** @type {FilterValue_p_in_collections} */ (
96
- filter.value ?? []
103
+ const filter_cast = /** @type {Filter_p_in_collections} */ (
104
+ filter
97
105
  );
98
-
106
+ const value = filter_cast?.value ?? [];
107
+
99
108
  conjunctions.push(
100
109
  {
101
110
  '_relations.collections.ids': {
102
- $in: cast.map(c => to_objid_safe(c.id)).filter(Boolean)
111
+ $in: value.map(c => to_objid_safe(c.id)).filter(Boolean)
103
112
  }
104
113
  }
105
114
  );
@@ -107,14 +116,15 @@ export const discount_to_mongo_conjunctions = d => {
107
116
  break;
108
117
  case enums.FilterMetaEnum.p_not_in_collections.op:
109
118
  {
110
- const cast = /** @type {FilterValue_p_not_in_collections} */ (
111
- filter.value ?? []
119
+ const filter_cast = /** @type {Filter_p_not_in_collections} */ (
120
+ filter
112
121
  );
122
+ const value = filter_cast?.value ?? [];
113
123
 
114
124
  conjunctions.push(
115
125
  {
116
126
  '_relations.collections.ids': {
117
- $nin: cast.map(c => to_objid_safe(c.id)).filter(Boolean)
127
+ $nin: value.map(c => to_objid_safe(c.id)).filter(Boolean)
118
128
  }
119
129
  }
120
130
  );
@@ -122,16 +132,19 @@ export const discount_to_mongo_conjunctions = d => {
122
132
  break;
123
133
  case enums.FilterMetaEnum.p_in_price_range.op:
124
134
  {
125
- const cast = /** @type {FilterValue_p_in_price_range} */ (
135
+ const filter_cast = /** @type {Filter_p_in_price_range} */ (
136
+ filter
137
+ );
138
+ const value = /** @type {Filter_p_in_price_range["value"]} */ (
126
139
  {
127
140
  from: 0,
128
141
  to: Number.POSITIVE_INFINITY,
129
- ...(filter?.value ?? {})
142
+ ...(filter_cast?.value ?? {})
130
143
  }
131
144
  );
132
145
 
133
- const from = extract_abs_number(cast.from);
134
- const to = extract_abs_number(cast.to);
146
+ const from = extract_abs_number(value.from);
147
+ const to = extract_abs_number(value.to);
135
148
 
136
149
  const conj = { price: { $and: [] } };
137
150
 
package/src/con.images.js CHANGED
@@ -1,13 +1,14 @@
1
1
  /**
2
2
  * @import { db_images as db_col } from '@storecraft/core/database'
3
3
  * @import { ImageType } from '@storecraft/core/api'
4
- * @import { Filter, AnyBulkWriteOperation } from 'mongodb'
4
+ * @import { AnyBulkWriteOperation } from 'mongodb'
5
5
  */
6
-
7
6
  import { Collection } from 'mongodb'
8
7
  import { MongoDB } from '../index.js'
9
- import { count_regular, get_regular, list_regular,
10
- upsert_regular } from './con.shared.js'
8
+ import {
9
+ count_regular, get_regular, list_regular,
10
+ upsert_regular
11
+ } from './con.shared.js'
11
12
  import { handle_or_id, to_objid } from './utils.funcs.js';
12
13
  import { func } from '@storecraft/core/api';
13
14
  import { ID } from '@storecraft/core/api/utils.func.js';
@@ -34,8 +35,6 @@ const get = (driver) => get_regular(driver, col(driver));
34
35
 
35
36
  /**
36
37
  * @param {MongoDB} driver
37
- *
38
- *
39
38
  * @returns {db_col["remove"]}
40
39
  */
41
40
  const remove = (driver) => {
@@ -85,12 +84,8 @@ const remove = (driver) => {
85
84
  }
86
85
 
87
86
  /**
88
- * report media usages
89
- *
90
- *
87
+ * @description report media usages
91
88
  * @param {MongoDB} driver
92
- *
93
- *
94
89
  * @returns {db_col["report_document_media"]}
95
90
  */
96
91
  export const report_document_media = (driver) => {
@@ -99,15 +94,14 @@ export const report_document_media = (driver) => {
99
94
  return;
100
95
 
101
96
  const add_to_search_index = func.union(
102
- data['title'], func.to_tokens(data['title'])
97
+ data['title'],
98
+ func.to_tokens(data['title'])
103
99
  );
104
100
 
105
101
  const dates = func.apply_dates({});
106
102
 
107
103
  /**
108
104
  * @param {string} url
109
- *
110
- *
111
105
  * @returns {AnyBulkWriteOperation<ImageType>}
112
106
  */
113
107
  const url_to_update = url => {
@@ -156,10 +150,8 @@ const count = (driver) => count_regular(driver, col(driver));
156
150
 
157
151
  /**
158
152
  * @param {MongoDB} driver
159
- *
160
- *
161
153
  * @return {db_col & { _col: ReturnType<col>}}
162
- * */
154
+ */
163
155
  export const impl = (driver) => {
164
156
 
165
157
  return {