@opra/mongodb 0.29.0 → 0.30.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.
package/cjs/index.js CHANGED
@@ -3,5 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  tslib_1.__exportStar(require("./mongo-adapter.js"), exports);
5
5
  tslib_1.__exportStar(require("./mongo-collection.js"), exports);
6
+ tslib_1.__exportStar(require("./mongo-entity-service-base.js"), exports);
6
7
  tslib_1.__exportStar(require("./mongo-entity-service.js"), exports);
7
8
  tslib_1.__exportStar(require("./mongo-singleton.js"), exports);
@@ -11,36 +11,37 @@ class MongoCollection {
11
11
  }
12
12
  async create(ctx) {
13
13
  const prepared = await this._prepare(ctx);
14
- const service = await this.getService(ctx);
15
- return service.insertOne(prepared.data, prepared.options);
14
+ return this._create(ctx, prepared);
16
15
  }
17
16
  async delete(ctx) {
18
17
  const prepared = await this._prepare(ctx);
19
- const service = await this.getService(ctx);
20
- return service.deleteOne(prepared.filter, prepared.options);
18
+ return this._delete(ctx, prepared);
21
19
  }
22
20
  async deleteMany(ctx) {
23
21
  const prepared = await this._prepare(ctx);
24
- const service = await this.getService(ctx);
25
- return service.deleteMany(prepared.filter, prepared.options);
22
+ return this._deleteMany(ctx, prepared);
26
23
  }
27
24
  async get(ctx) {
28
25
  const prepared = await this._prepare(ctx);
29
- const service = await this.getService(ctx);
30
- return service.findOne(prepared.filter, prepared.options);
26
+ return this._get(ctx, prepared);
31
27
  }
32
28
  async update(ctx) {
33
29
  const prepared = await this._prepare(ctx);
34
- const service = await this.getService(ctx);
35
- return service.updateOne(prepared.filter, prepared.data, prepared.options);
30
+ return this._update(ctx, prepared);
36
31
  }
37
32
  async updateMany(ctx) {
38
33
  const prepared = await this._prepare(ctx);
39
- const service = await this.getService(ctx);
40
- return service.updateMany(prepared.filter, prepared.data, prepared.options);
34
+ return this._updateMany(ctx, prepared);
41
35
  }
42
36
  async findMany(ctx) {
43
37
  const prepared = await this._prepare(ctx);
38
+ return this._findMany(ctx, prepared);
39
+ }
40
+ async _prepare(ctx) {
41
+ const prepared = mongo_adapter_js_1.MongoAdapter.transformRequest(ctx.request);
42
+ return (this.onPrepare && await this.onPrepare(ctx, prepared)) || prepared;
43
+ }
44
+ async _findMany(ctx, prepared) {
44
45
  const service = await this.getService(ctx);
45
46
  if (prepared.options.count) {
46
47
  const [items, count] = await Promise.all([
@@ -52,9 +53,29 @@ class MongoCollection {
52
53
  }
53
54
  return service.find(prepared.filter, prepared.options);
54
55
  }
55
- async _prepare(ctx) {
56
- const prepared = mongo_adapter_js_1.MongoAdapter.transformRequest(ctx.request);
57
- return (this.onPrepare && await this.onPrepare(ctx, prepared)) || prepared;
56
+ async _create(ctx, prepared) {
57
+ const service = await this.getService(ctx);
58
+ return service.insertOne(prepared.data, prepared.options);
59
+ }
60
+ async _delete(ctx, prepared) {
61
+ const service = await this.getService(ctx);
62
+ return service.deleteOne(prepared.filter, prepared.options);
63
+ }
64
+ async _deleteMany(ctx, prepared) {
65
+ const service = await this.getService(ctx);
66
+ return service.deleteMany(prepared.filter, prepared.options);
67
+ }
68
+ async _get(ctx, prepared) {
69
+ const service = await this.getService(ctx);
70
+ return service.findOne(prepared.filter, prepared.options);
71
+ }
72
+ async _update(ctx, prepared) {
73
+ const service = await this.getService(ctx);
74
+ return service.updateOne(prepared.filter, prepared.data, prepared.options);
75
+ }
76
+ async _updateMany(ctx, prepared) {
77
+ const service = await this.getService(ctx);
78
+ return service.updateMany(prepared.filter, prepared.data, prepared.options);
58
79
  }
59
80
  }
60
81
  exports.MongoCollection = MongoCollection;
@@ -0,0 +1,197 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MongoEntityServiceBase = void 0;
4
+ const core_1 = require("@opra/core");
5
+ class MongoEntityServiceBase extends core_1.ApiService {
6
+ constructor(arg0, arg1) {
7
+ super();
8
+ const options = typeof arg0 === 'object' ? arg0 : arg1;
9
+ if (typeof arg0 === 'string')
10
+ this._collectionName = arg0;
11
+ this.db = options?.db;
12
+ this.defaultLimit = options?.defaultLimit || 10;
13
+ }
14
+ async _count(filter, options) {
15
+ const db = await this.getDatabase();
16
+ const collection = await this.getCollection(db);
17
+ options = {
18
+ ...options,
19
+ limit: undefined,
20
+ session: options?.session || this.session
21
+ };
22
+ try {
23
+ return await collection.countDocuments(filter, options) || 0;
24
+ }
25
+ catch (e) {
26
+ await this._onError(e);
27
+ throw e;
28
+ }
29
+ }
30
+ async _deleteOne(filter, options) {
31
+ const db = await this.getDatabase();
32
+ const collection = await this.getCollection(db);
33
+ options = {
34
+ ...options,
35
+ session: options?.session || this.session
36
+ };
37
+ try {
38
+ const r = await collection.deleteOne(filter, options);
39
+ return r.deletedCount;
40
+ }
41
+ catch (e) {
42
+ await this._onError(e);
43
+ throw e;
44
+ }
45
+ }
46
+ async _deleteMany(filter, options) {
47
+ const db = await this.getDatabase();
48
+ const collection = await this.getCollection(db);
49
+ options = {
50
+ ...options,
51
+ session: options?.session || this.session
52
+ };
53
+ try {
54
+ const r = await collection.deleteMany(filter, options);
55
+ return r.deletedCount;
56
+ }
57
+ catch (e) {
58
+ await this._onError(e);
59
+ throw e;
60
+ }
61
+ }
62
+ async _findOne(filter, options) {
63
+ const db = await this.getDatabase();
64
+ const collection = await this.getCollection(db);
65
+ options = {
66
+ ...options,
67
+ session: options?.session || this.session
68
+ };
69
+ let out;
70
+ try {
71
+ out = await collection.findOne(filter, options);
72
+ }
73
+ catch (e) {
74
+ await this._onError(e);
75
+ throw e;
76
+ }
77
+ return out;
78
+ }
79
+ async _find(filter, options) {
80
+ const db = await this.getDatabase();
81
+ const collection = await this.getCollection(db);
82
+ options = {
83
+ ...options,
84
+ limit: options?.limit || this.defaultLimit,
85
+ session: options?.session || this.session
86
+ };
87
+ const out = [];
88
+ let cursor;
89
+ try {
90
+ cursor = collection.find(filter, options);
91
+ let obj;
92
+ while (out.length < this.defaultLimit && (obj = await cursor.next())) {
93
+ const v = this.transformData ? this.transformData(obj) : obj;
94
+ if (v)
95
+ out.push(obj);
96
+ }
97
+ }
98
+ catch (e) {
99
+ await this._onError(e);
100
+ throw e;
101
+ }
102
+ finally {
103
+ if (cursor)
104
+ await cursor.close();
105
+ }
106
+ return out;
107
+ }
108
+ async _insertOne(doc, options) {
109
+ const db = await this.getDatabase();
110
+ const collection = await this.getCollection(db);
111
+ let out;
112
+ options = {
113
+ ...options,
114
+ session: options?.session || this.session
115
+ };
116
+ try {
117
+ const r = await collection.insertOne(doc, options);
118
+ if (r.insertedId)
119
+ out = await collection.findOne({ _id: r.insertedId }, options);
120
+ }
121
+ catch (e) {
122
+ await this._onError(e);
123
+ throw e;
124
+ }
125
+ if (this.transformData)
126
+ out = this.transformData(out);
127
+ if (!out)
128
+ throw new Error('"insertOne" endpoint returned no result!');
129
+ return out;
130
+ }
131
+ async _updateOne(filter, doc, options) {
132
+ const db = await this.getDatabase();
133
+ const collection = await this.getCollection(db);
134
+ let out;
135
+ options = {
136
+ ...options,
137
+ session: options?.session || this.session
138
+ };
139
+ try {
140
+ const r = await collection.updateOne(filter, doc, options);
141
+ if (r.matchedCount)
142
+ out = await collection.findOne((r.upsertedId ? { _id: r.upsertedId } : filter), options);
143
+ }
144
+ catch (e) {
145
+ await this._onError(e);
146
+ throw e;
147
+ }
148
+ if (this.transformData)
149
+ out = this.transformData(out);
150
+ return out;
151
+ }
152
+ async _updateMany(filter, doc, options) {
153
+ const db = await this.getDatabase();
154
+ const collection = await this.getCollection(db);
155
+ options = {
156
+ ...options,
157
+ session: options?.session || this.session,
158
+ upsert: false
159
+ };
160
+ try {
161
+ const r = await collection.updateMany(filter, doc, options);
162
+ return r.matchedCount;
163
+ }
164
+ catch (e) {
165
+ await this._onError(e);
166
+ throw e;
167
+ }
168
+ }
169
+ forContext(context, db, session) {
170
+ const instance = super.forContext(context);
171
+ instance.db = db || this.db;
172
+ instance.session = session || this.session;
173
+ return instance;
174
+ }
175
+ async _onError(error) {
176
+ if (this.onError)
177
+ await this.onError(error);
178
+ }
179
+ getDatabase() {
180
+ if (!this.context)
181
+ throw new Error(`Context not set!`);
182
+ if (!this.db)
183
+ throw new Error(`Database not set!`);
184
+ return this.db;
185
+ }
186
+ async getCollection(db) {
187
+ if (!this._collectionName)
188
+ throw new Error('collectionName is not assigned');
189
+ return db.collection(this.getCollectionName());
190
+ }
191
+ getCollectionName() {
192
+ if (!this._collectionName)
193
+ throw new Error('collectionName is not defined');
194
+ return this._collectionName;
195
+ }
196
+ }
197
+ exports.MongoEntityServiceBase = MongoEntityServiceBase;
@@ -1,200 +1,34 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MongoEntityService = void 0;
4
- const core_1 = require("@opra/core");
5
- class MongoEntityService extends core_1.ApiService {
4
+ const mongo_entity_service_base_js_1 = require("./mongo-entity-service-base.js");
5
+ class MongoEntityService extends mongo_entity_service_base_js_1.MongoEntityServiceBase {
6
6
  constructor(arg0, arg1) {
7
- super();
8
- const options = typeof arg0 === 'object' ? arg0 : arg1;
9
- if (typeof arg0 === 'string')
10
- this._collectionName = arg0;
11
- this.db = options?.db;
12
- this.defaultLimit = options?.defaultLimit || 10;
7
+ super(arg0, arg1);
13
8
  }
14
9
  async count(filter, options) {
15
- const db = await this.getDatabase();
16
- const collection = await this.getCollection(db);
17
- options = {
18
- ...options,
19
- limit: undefined,
20
- session: options?.session || this.session
21
- };
22
- try {
23
- return await collection.count(filter, options) || 0;
24
- }
25
- catch (e) {
26
- await this._onError(e);
27
- throw e;
28
- }
10
+ return super._count(filter, options);
29
11
  }
30
12
  async deleteOne(filter, options) {
31
- const db = await this.getDatabase();
32
- const collection = await this.getCollection(db);
33
- options = {
34
- ...options,
35
- session: options?.session || this.session
36
- };
37
- try {
38
- const r = await collection.deleteOne(filter, options);
39
- return r.deletedCount;
40
- }
41
- catch (e) {
42
- await this._onError(e);
43
- throw e;
44
- }
13
+ return super._deleteOne(filter, options);
45
14
  }
46
15
  async deleteMany(filter, options) {
47
- const db = await this.getDatabase();
48
- const collection = await this.getCollection(db);
49
- options = {
50
- ...options,
51
- session: options?.session || this.session
52
- };
53
- try {
54
- const r = await collection.deleteMany(filter, options);
55
- return r.deletedCount;
56
- }
57
- catch (e) {
58
- await this._onError(e);
59
- throw e;
60
- }
16
+ return super._deleteMany(filter, options);
61
17
  }
62
18
  async findOne(filter, options) {
63
- const db = await this.getDatabase();
64
- const collection = await this.getCollection(db);
65
- options = {
66
- ...options,
67
- session: options?.session || this.session
68
- };
69
- let out;
70
- try {
71
- out = await collection.findOne(filter, options);
72
- }
73
- catch (e) {
74
- await this._onError(e);
75
- throw e;
76
- }
77
- return out;
19
+ return super._findOne(filter, options);
78
20
  }
79
21
  async find(filter, options) {
80
- const db = await this.getDatabase();
81
- const collection = await this.getCollection(db);
82
- options = {
83
- ...options,
84
- limit: options?.limit || this.defaultLimit,
85
- session: options?.session || this.session
86
- };
87
- const out = [];
88
- let cursor;
89
- try {
90
- cursor = collection.find(filter, options);
91
- let obj;
92
- while (out.length < this.defaultLimit && (obj = await cursor.next())) {
93
- const v = this.transformData ? this.transformData(obj) : obj;
94
- if (v)
95
- out.push(obj);
96
- }
97
- }
98
- catch (e) {
99
- await this._onError(e);
100
- throw e;
101
- }
102
- finally {
103
- if (cursor)
104
- await cursor.close();
105
- }
106
- return out;
22
+ return super._find(filter, options);
107
23
  }
108
24
  async insertOne(doc, options) {
109
- const db = await this.getDatabase();
110
- const collection = await this.getCollection(db);
111
- let out;
112
- options = {
113
- ...options,
114
- session: options?.session || this.session
115
- };
116
- try {
117
- const r = await collection.insertOne(doc, options);
118
- if (r.insertedId)
119
- out = await collection.findOne({ _id: r.insertedId }, options);
120
- }
121
- catch (e) {
122
- await this._onError(e);
123
- throw e;
124
- }
125
- if (this.transformData)
126
- out = this.transformData(out);
127
- if (!out)
128
- throw new Error('"insertOne" endpoint returned no result!');
129
- return out;
25
+ return super._insertOne(doc, options);
130
26
  }
131
27
  async updateOne(filter, doc, options) {
132
- const db = await this.getDatabase();
133
- const collection = await this.getCollection(db);
134
- let out;
135
- options = {
136
- ...options,
137
- session: options?.session || this.session
138
- };
139
- try {
140
- const r = await collection.updateOne(filter, doc, options);
141
- if (r.matchedCount)
142
- out = await collection.findOne((r.upsertedId ? { _id: r.upsertedId } : filter), options);
143
- }
144
- catch (e) {
145
- await this._onError(e);
146
- throw e;
147
- }
148
- if (this.transformData)
149
- out = this.transformData(out);
150
- return out;
28
+ return this._updateOne(filter, doc, options);
151
29
  }
152
30
  async updateMany(filter, doc, options) {
153
- const db = await this.getDatabase();
154
- const collection = await this.getCollection(db);
155
- options = {
156
- ...options,
157
- session: options?.session || this.session,
158
- upsert: false
159
- };
160
- try {
161
- const r = await collection.updateMany(filter, doc, options);
162
- return r.matchedCount;
163
- }
164
- catch (e) {
165
- await this._onError(e);
166
- throw e;
167
- }
168
- }
169
- with(context, db, session) {
170
- return this.forContext(context, db, session);
171
- }
172
- forContext(context, db, session) {
173
- const instance = super.forContext(context);
174
- instance.db = db || this.db;
175
- instance.session = session || this.session;
176
- return instance;
177
- }
178
- async _onError(error) {
179
- if (this.onError)
180
- await this.onError(error);
181
- }
182
- getDatabase() {
183
- if (!this.context)
184
- throw new Error(`Context not set!`);
185
- if (!this.db)
186
- throw new Error(`Database not set!`);
187
- return this.db;
188
- }
189
- async getCollection(db) {
190
- if (!this._collectionName)
191
- throw new Error('collectionName is not assigned');
192
- return db.collection(this.getCollectionName());
193
- }
194
- getCollectionName() {
195
- if (!this._collectionName)
196
- throw new Error('collectionName is not defined');
197
- return this._collectionName;
31
+ return super._updateMany(filter, doc, options);
198
32
  }
199
33
  }
200
34
  exports.MongoEntityService = MongoEntityService;
@@ -7,22 +7,34 @@ const mongo_adapter_js_1 = require("./mongo-adapter.js");
7
7
  class MongoSingleton {
8
8
  async create(ctx) {
9
9
  const prepared = await this._prepare(ctx);
10
+ return this._create(ctx, prepared);
11
+ }
12
+ async delete(ctx) {
13
+ const prepared = await this._prepare(ctx);
14
+ return this._delete(ctx, prepared);
15
+ }
16
+ async get(ctx) {
17
+ const prepared = await this._prepare(ctx);
18
+ return this._get(ctx, prepared);
19
+ }
20
+ async update(ctx) {
21
+ const prepared = await this._prepare(ctx);
22
+ return this._update(ctx, prepared);
23
+ }
24
+ async _create(ctx, prepared) {
10
25
  const service = await this.getService(ctx);
11
26
  await service.deleteMany();
12
27
  return service.insertOne(prepared.data, prepared.options);
13
28
  }
14
- async delete(ctx) {
15
- const prepared = await this._prepare(ctx);
29
+ async _delete(ctx, prepared) {
16
30
  const service = await this.getService(ctx);
17
31
  return service.deleteOne(prepared.filter, prepared.options);
18
32
  }
19
- async get(ctx) {
20
- const prepared = await this._prepare(ctx);
33
+ async _get(ctx, prepared) {
21
34
  const service = await this.getService(ctx);
22
35
  return service.findOne(prepared.filter, prepared.options);
23
36
  }
24
- async update(ctx) {
25
- const prepared = await this._prepare(ctx);
37
+ async _update(ctx, prepared) {
26
38
  const service = await this.getService(ctx);
27
39
  return service.updateOne(prepared.filter, prepared.data, prepared.options);
28
40
  }
package/esm/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './mongo-adapter.js';
2
2
  export * from './mongo-collection.js';
3
+ export * from './mongo-entity-service-base.js';
3
4
  export * from './mongo-entity-service.js';
4
5
  export * from './mongo-singleton.js';
@@ -8,36 +8,37 @@ export class MongoCollection {
8
8
  }
9
9
  async create(ctx) {
10
10
  const prepared = await this._prepare(ctx);
11
- const service = await this.getService(ctx);
12
- return service.insertOne(prepared.data, prepared.options);
11
+ return this._create(ctx, prepared);
13
12
  }
14
13
  async delete(ctx) {
15
14
  const prepared = await this._prepare(ctx);
16
- const service = await this.getService(ctx);
17
- return service.deleteOne(prepared.filter, prepared.options);
15
+ return this._delete(ctx, prepared);
18
16
  }
19
17
  async deleteMany(ctx) {
20
18
  const prepared = await this._prepare(ctx);
21
- const service = await this.getService(ctx);
22
- return service.deleteMany(prepared.filter, prepared.options);
19
+ return this._deleteMany(ctx, prepared);
23
20
  }
24
21
  async get(ctx) {
25
22
  const prepared = await this._prepare(ctx);
26
- const service = await this.getService(ctx);
27
- return service.findOne(prepared.filter, prepared.options);
23
+ return this._get(ctx, prepared);
28
24
  }
29
25
  async update(ctx) {
30
26
  const prepared = await this._prepare(ctx);
31
- const service = await this.getService(ctx);
32
- return service.updateOne(prepared.filter, prepared.data, prepared.options);
27
+ return this._update(ctx, prepared);
33
28
  }
34
29
  async updateMany(ctx) {
35
30
  const prepared = await this._prepare(ctx);
36
- const service = await this.getService(ctx);
37
- return service.updateMany(prepared.filter, prepared.data, prepared.options);
31
+ return this._updateMany(ctx, prepared);
38
32
  }
39
33
  async findMany(ctx) {
40
34
  const prepared = await this._prepare(ctx);
35
+ return this._findMany(ctx, prepared);
36
+ }
37
+ async _prepare(ctx) {
38
+ const prepared = MongoAdapter.transformRequest(ctx.request);
39
+ return (this.onPrepare && await this.onPrepare(ctx, prepared)) || prepared;
40
+ }
41
+ async _findMany(ctx, prepared) {
41
42
  const service = await this.getService(ctx);
42
43
  if (prepared.options.count) {
43
44
  const [items, count] = await Promise.all([
@@ -49,9 +50,29 @@ export class MongoCollection {
49
50
  }
50
51
  return service.find(prepared.filter, prepared.options);
51
52
  }
52
- async _prepare(ctx) {
53
- const prepared = MongoAdapter.transformRequest(ctx.request);
54
- return (this.onPrepare && await this.onPrepare(ctx, prepared)) || prepared;
53
+ async _create(ctx, prepared) {
54
+ const service = await this.getService(ctx);
55
+ return service.insertOne(prepared.data, prepared.options);
56
+ }
57
+ async _delete(ctx, prepared) {
58
+ const service = await this.getService(ctx);
59
+ return service.deleteOne(prepared.filter, prepared.options);
60
+ }
61
+ async _deleteMany(ctx, prepared) {
62
+ const service = await this.getService(ctx);
63
+ return service.deleteMany(prepared.filter, prepared.options);
64
+ }
65
+ async _get(ctx, prepared) {
66
+ const service = await this.getService(ctx);
67
+ return service.findOne(prepared.filter, prepared.options);
68
+ }
69
+ async _update(ctx, prepared) {
70
+ const service = await this.getService(ctx);
71
+ return service.updateOne(prepared.filter, prepared.data, prepared.options);
72
+ }
73
+ async _updateMany(ctx, prepared) {
74
+ const service = await this.getService(ctx);
75
+ return service.updateMany(prepared.filter, prepared.data, prepared.options);
55
76
  }
56
77
  }
57
78
  __decorate([
@@ -0,0 +1,193 @@
1
+ import { ApiService } from '@opra/core';
2
+ export class MongoEntityServiceBase extends ApiService {
3
+ constructor(arg0, arg1) {
4
+ super();
5
+ const options = typeof arg0 === 'object' ? arg0 : arg1;
6
+ if (typeof arg0 === 'string')
7
+ this._collectionName = arg0;
8
+ this.db = options?.db;
9
+ this.defaultLimit = options?.defaultLimit || 10;
10
+ }
11
+ async _count(filter, options) {
12
+ const db = await this.getDatabase();
13
+ const collection = await this.getCollection(db);
14
+ options = {
15
+ ...options,
16
+ limit: undefined,
17
+ session: options?.session || this.session
18
+ };
19
+ try {
20
+ return await collection.countDocuments(filter, options) || 0;
21
+ }
22
+ catch (e) {
23
+ await this._onError(e);
24
+ throw e;
25
+ }
26
+ }
27
+ async _deleteOne(filter, options) {
28
+ const db = await this.getDatabase();
29
+ const collection = await this.getCollection(db);
30
+ options = {
31
+ ...options,
32
+ session: options?.session || this.session
33
+ };
34
+ try {
35
+ const r = await collection.deleteOne(filter, options);
36
+ return r.deletedCount;
37
+ }
38
+ catch (e) {
39
+ await this._onError(e);
40
+ throw e;
41
+ }
42
+ }
43
+ async _deleteMany(filter, options) {
44
+ const db = await this.getDatabase();
45
+ const collection = await this.getCollection(db);
46
+ options = {
47
+ ...options,
48
+ session: options?.session || this.session
49
+ };
50
+ try {
51
+ const r = await collection.deleteMany(filter, options);
52
+ return r.deletedCount;
53
+ }
54
+ catch (e) {
55
+ await this._onError(e);
56
+ throw e;
57
+ }
58
+ }
59
+ async _findOne(filter, options) {
60
+ const db = await this.getDatabase();
61
+ const collection = await this.getCollection(db);
62
+ options = {
63
+ ...options,
64
+ session: options?.session || this.session
65
+ };
66
+ let out;
67
+ try {
68
+ out = await collection.findOne(filter, options);
69
+ }
70
+ catch (e) {
71
+ await this._onError(e);
72
+ throw e;
73
+ }
74
+ return out;
75
+ }
76
+ async _find(filter, options) {
77
+ const db = await this.getDatabase();
78
+ const collection = await this.getCollection(db);
79
+ options = {
80
+ ...options,
81
+ limit: options?.limit || this.defaultLimit,
82
+ session: options?.session || this.session
83
+ };
84
+ const out = [];
85
+ let cursor;
86
+ try {
87
+ cursor = collection.find(filter, options);
88
+ let obj;
89
+ while (out.length < this.defaultLimit && (obj = await cursor.next())) {
90
+ const v = this.transformData ? this.transformData(obj) : obj;
91
+ if (v)
92
+ out.push(obj);
93
+ }
94
+ }
95
+ catch (e) {
96
+ await this._onError(e);
97
+ throw e;
98
+ }
99
+ finally {
100
+ if (cursor)
101
+ await cursor.close();
102
+ }
103
+ return out;
104
+ }
105
+ async _insertOne(doc, options) {
106
+ const db = await this.getDatabase();
107
+ const collection = await this.getCollection(db);
108
+ let out;
109
+ options = {
110
+ ...options,
111
+ session: options?.session || this.session
112
+ };
113
+ try {
114
+ const r = await collection.insertOne(doc, options);
115
+ if (r.insertedId)
116
+ out = await collection.findOne({ _id: r.insertedId }, options);
117
+ }
118
+ catch (e) {
119
+ await this._onError(e);
120
+ throw e;
121
+ }
122
+ if (this.transformData)
123
+ out = this.transformData(out);
124
+ if (!out)
125
+ throw new Error('"insertOne" endpoint returned no result!');
126
+ return out;
127
+ }
128
+ async _updateOne(filter, doc, options) {
129
+ const db = await this.getDatabase();
130
+ const collection = await this.getCollection(db);
131
+ let out;
132
+ options = {
133
+ ...options,
134
+ session: options?.session || this.session
135
+ };
136
+ try {
137
+ const r = await collection.updateOne(filter, doc, options);
138
+ if (r.matchedCount)
139
+ out = await collection.findOne((r.upsertedId ? { _id: r.upsertedId } : filter), options);
140
+ }
141
+ catch (e) {
142
+ await this._onError(e);
143
+ throw e;
144
+ }
145
+ if (this.transformData)
146
+ out = this.transformData(out);
147
+ return out;
148
+ }
149
+ async _updateMany(filter, doc, options) {
150
+ const db = await this.getDatabase();
151
+ const collection = await this.getCollection(db);
152
+ options = {
153
+ ...options,
154
+ session: options?.session || this.session,
155
+ upsert: false
156
+ };
157
+ try {
158
+ const r = await collection.updateMany(filter, doc, options);
159
+ return r.matchedCount;
160
+ }
161
+ catch (e) {
162
+ await this._onError(e);
163
+ throw e;
164
+ }
165
+ }
166
+ forContext(context, db, session) {
167
+ const instance = super.forContext(context);
168
+ instance.db = db || this.db;
169
+ instance.session = session || this.session;
170
+ return instance;
171
+ }
172
+ async _onError(error) {
173
+ if (this.onError)
174
+ await this.onError(error);
175
+ }
176
+ getDatabase() {
177
+ if (!this.context)
178
+ throw new Error(`Context not set!`);
179
+ if (!this.db)
180
+ throw new Error(`Database not set!`);
181
+ return this.db;
182
+ }
183
+ async getCollection(db) {
184
+ if (!this._collectionName)
185
+ throw new Error('collectionName is not assigned');
186
+ return db.collection(this.getCollectionName());
187
+ }
188
+ getCollectionName() {
189
+ if (!this._collectionName)
190
+ throw new Error('collectionName is not defined');
191
+ return this._collectionName;
192
+ }
193
+ }
@@ -1,196 +1,30 @@
1
- import { ApiService } from '@opra/core';
2
- export class MongoEntityService extends ApiService {
1
+ import { MongoEntityServiceBase } from './mongo-entity-service-base.js';
2
+ export class MongoEntityService extends MongoEntityServiceBase {
3
3
  constructor(arg0, arg1) {
4
- super();
5
- const options = typeof arg0 === 'object' ? arg0 : arg1;
6
- if (typeof arg0 === 'string')
7
- this._collectionName = arg0;
8
- this.db = options?.db;
9
- this.defaultLimit = options?.defaultLimit || 10;
4
+ super(arg0, arg1);
10
5
  }
11
6
  async count(filter, options) {
12
- const db = await this.getDatabase();
13
- const collection = await this.getCollection(db);
14
- options = {
15
- ...options,
16
- limit: undefined,
17
- session: options?.session || this.session
18
- };
19
- try {
20
- return await collection.count(filter, options) || 0;
21
- }
22
- catch (e) {
23
- await this._onError(e);
24
- throw e;
25
- }
7
+ return super._count(filter, options);
26
8
  }
27
9
  async deleteOne(filter, options) {
28
- const db = await this.getDatabase();
29
- const collection = await this.getCollection(db);
30
- options = {
31
- ...options,
32
- session: options?.session || this.session
33
- };
34
- try {
35
- const r = await collection.deleteOne(filter, options);
36
- return r.deletedCount;
37
- }
38
- catch (e) {
39
- await this._onError(e);
40
- throw e;
41
- }
10
+ return super._deleteOne(filter, options);
42
11
  }
43
12
  async deleteMany(filter, options) {
44
- const db = await this.getDatabase();
45
- const collection = await this.getCollection(db);
46
- options = {
47
- ...options,
48
- session: options?.session || this.session
49
- };
50
- try {
51
- const r = await collection.deleteMany(filter, options);
52
- return r.deletedCount;
53
- }
54
- catch (e) {
55
- await this._onError(e);
56
- throw e;
57
- }
13
+ return super._deleteMany(filter, options);
58
14
  }
59
15
  async findOne(filter, options) {
60
- const db = await this.getDatabase();
61
- const collection = await this.getCollection(db);
62
- options = {
63
- ...options,
64
- session: options?.session || this.session
65
- };
66
- let out;
67
- try {
68
- out = await collection.findOne(filter, options);
69
- }
70
- catch (e) {
71
- await this._onError(e);
72
- throw e;
73
- }
74
- return out;
16
+ return super._findOne(filter, options);
75
17
  }
76
18
  async find(filter, options) {
77
- const db = await this.getDatabase();
78
- const collection = await this.getCollection(db);
79
- options = {
80
- ...options,
81
- limit: options?.limit || this.defaultLimit,
82
- session: options?.session || this.session
83
- };
84
- const out = [];
85
- let cursor;
86
- try {
87
- cursor = collection.find(filter, options);
88
- let obj;
89
- while (out.length < this.defaultLimit && (obj = await cursor.next())) {
90
- const v = this.transformData ? this.transformData(obj) : obj;
91
- if (v)
92
- out.push(obj);
93
- }
94
- }
95
- catch (e) {
96
- await this._onError(e);
97
- throw e;
98
- }
99
- finally {
100
- if (cursor)
101
- await cursor.close();
102
- }
103
- return out;
19
+ return super._find(filter, options);
104
20
  }
105
21
  async insertOne(doc, options) {
106
- const db = await this.getDatabase();
107
- const collection = await this.getCollection(db);
108
- let out;
109
- options = {
110
- ...options,
111
- session: options?.session || this.session
112
- };
113
- try {
114
- const r = await collection.insertOne(doc, options);
115
- if (r.insertedId)
116
- out = await collection.findOne({ _id: r.insertedId }, options);
117
- }
118
- catch (e) {
119
- await this._onError(e);
120
- throw e;
121
- }
122
- if (this.transformData)
123
- out = this.transformData(out);
124
- if (!out)
125
- throw new Error('"insertOne" endpoint returned no result!');
126
- return out;
22
+ return super._insertOne(doc, options);
127
23
  }
128
24
  async updateOne(filter, doc, options) {
129
- const db = await this.getDatabase();
130
- const collection = await this.getCollection(db);
131
- let out;
132
- options = {
133
- ...options,
134
- session: options?.session || this.session
135
- };
136
- try {
137
- const r = await collection.updateOne(filter, doc, options);
138
- if (r.matchedCount)
139
- out = await collection.findOne((r.upsertedId ? { _id: r.upsertedId } : filter), options);
140
- }
141
- catch (e) {
142
- await this._onError(e);
143
- throw e;
144
- }
145
- if (this.transformData)
146
- out = this.transformData(out);
147
- return out;
25
+ return this._updateOne(filter, doc, options);
148
26
  }
149
27
  async updateMany(filter, doc, options) {
150
- const db = await this.getDatabase();
151
- const collection = await this.getCollection(db);
152
- options = {
153
- ...options,
154
- session: options?.session || this.session,
155
- upsert: false
156
- };
157
- try {
158
- const r = await collection.updateMany(filter, doc, options);
159
- return r.matchedCount;
160
- }
161
- catch (e) {
162
- await this._onError(e);
163
- throw e;
164
- }
165
- }
166
- with(context, db, session) {
167
- return this.forContext(context, db, session);
168
- }
169
- forContext(context, db, session) {
170
- const instance = super.forContext(context);
171
- instance.db = db || this.db;
172
- instance.session = session || this.session;
173
- return instance;
174
- }
175
- async _onError(error) {
176
- if (this.onError)
177
- await this.onError(error);
178
- }
179
- getDatabase() {
180
- if (!this.context)
181
- throw new Error(`Context not set!`);
182
- if (!this.db)
183
- throw new Error(`Database not set!`);
184
- return this.db;
185
- }
186
- async getCollection(db) {
187
- if (!this._collectionName)
188
- throw new Error('collectionName is not assigned');
189
- return db.collection(this.getCollectionName());
190
- }
191
- getCollectionName() {
192
- if (!this._collectionName)
193
- throw new Error('collectionName is not defined');
194
- return this._collectionName;
28
+ return super._updateMany(filter, doc, options);
195
29
  }
196
30
  }
@@ -4,22 +4,34 @@ import { MongoAdapter } from './mongo-adapter.js';
4
4
  export class MongoSingleton {
5
5
  async create(ctx) {
6
6
  const prepared = await this._prepare(ctx);
7
+ return this._create(ctx, prepared);
8
+ }
9
+ async delete(ctx) {
10
+ const prepared = await this._prepare(ctx);
11
+ return this._delete(ctx, prepared);
12
+ }
13
+ async get(ctx) {
14
+ const prepared = await this._prepare(ctx);
15
+ return this._get(ctx, prepared);
16
+ }
17
+ async update(ctx) {
18
+ const prepared = await this._prepare(ctx);
19
+ return this._update(ctx, prepared);
20
+ }
21
+ async _create(ctx, prepared) {
7
22
  const service = await this.getService(ctx);
8
23
  await service.deleteMany();
9
24
  return service.insertOne(prepared.data, prepared.options);
10
25
  }
11
- async delete(ctx) {
12
- const prepared = await this._prepare(ctx);
26
+ async _delete(ctx, prepared) {
13
27
  const service = await this.getService(ctx);
14
28
  return service.deleteOne(prepared.filter, prepared.options);
15
29
  }
16
- async get(ctx) {
17
- const prepared = await this._prepare(ctx);
30
+ async _get(ctx, prepared) {
18
31
  const service = await this.getService(ctx);
19
32
  return service.findOne(prepared.filter, prepared.options);
20
33
  }
21
- async update(ctx) {
22
- const prepared = await this._prepare(ctx);
34
+ async _update(ctx, prepared) {
23
35
  const service = await this.getService(ctx);
24
36
  return service.updateOne(prepared.filter, prepared.data, prepared.options);
25
37
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opra/mongodb",
3
- "version": "0.29.0",
3
+ "version": "0.30.0",
4
4
  "description": "Opra MongoDB adapter package",
5
5
  "author": "Panates",
6
6
  "license": "MIT",
@@ -36,8 +36,8 @@
36
36
  "ts-gems": "^2.5.0"
37
37
  },
38
38
  "peerDependencies": {
39
- "@opra/common": "^0.29.0",
40
- "@opra/core": "^0.29.0",
39
+ "@opra/common": "^0.30.0",
40
+ "@opra/core": "^0.30.0",
41
41
  "mongodb": ">=6.x.x"
42
42
  },
43
43
  "type": "module",
@@ -61,4 +61,4 @@
61
61
  "mongodb",
62
62
  "adapter"
63
63
  ]
64
- }
64
+ }
package/types/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './mongo-adapter.js';
2
2
  export * from './mongo-collection.js';
3
+ export * from './mongo-entity-service-base.js';
3
4
  export * from './mongo-entity-service.js';
4
5
  export * from './mongo-singleton.js';
@@ -20,6 +20,13 @@ export declare abstract class MongoCollection<T extends mongodb.Document> implem
20
20
  updateMany?(ctx: RequestContext): Promise<number>;
21
21
  findMany?(ctx: RequestContext): Promise<PartialOutput<T>[]>;
22
22
  protected _prepare(ctx: RequestContext): Promise<MongoAdapter.TransformedRequest>;
23
+ protected _findMany(ctx: RequestContext, prepared: MongoAdapter.TransformedRequest): Promise<PartialOutput<T>[]>;
24
+ protected _create(ctx: Collection.Create.Context, prepared: MongoAdapter.TransformedRequest): Promise<PartialOutput<T>>;
25
+ protected _delete(ctx: RequestContext, prepared: MongoAdapter.TransformedRequest): Promise<number>;
26
+ protected _deleteMany(ctx: RequestContext, prepared: MongoAdapter.TransformedRequest): Promise<number>;
27
+ protected _get(ctx: RequestContext, prepared: MongoAdapter.TransformedRequest): Promise<Maybe<PartialOutput<T>>>;
28
+ protected _update(ctx: RequestContext, prepared: MongoAdapter.TransformedRequest): Promise<Maybe<PartialOutput<T>>>;
29
+ protected _updateMany(ctx: RequestContext, prepared: MongoAdapter.TransformedRequest): Promise<number>;
23
30
  protected onPrepare?(ctx: RequestContext, prepared: MongoAdapter.TransformedRequest): MongoAdapter.TransformedRequest | Promise<MongoAdapter.TransformedRequest>;
24
31
  protected abstract getService(ctx: RequestContext): MongoEntityService<T> | Promise<MongoEntityService<T>>;
25
32
  }
@@ -0,0 +1,32 @@
1
+ import mongodb, { UpdateFilter } from 'mongodb';
2
+ import { StrictOmit } from 'ts-gems';
3
+ import { ApiService, PartialOutput, RequestContext } from '@opra/core';
4
+ export declare namespace MongoEntityServiceBase {
5
+ interface Options {
6
+ db?: mongodb.Db;
7
+ defaultLimit?: number;
8
+ }
9
+ }
10
+ export declare class MongoEntityServiceBase<T extends mongodb.Document> extends ApiService {
11
+ protected _collectionName: string;
12
+ defaultLimit: number;
13
+ db?: mongodb.Db;
14
+ session?: mongodb.ClientSession;
15
+ constructor(options?: MongoEntityServiceBase.Options);
16
+ constructor(collectionName: string, options?: MongoEntityServiceBase.Options);
17
+ protected _count(filter?: mongodb.Filter<T>, options?: mongodb.CountOptions): Promise<number>;
18
+ protected _deleteOne(filter?: mongodb.Filter<T>, options?: mongodb.DeleteOptions): Promise<number>;
19
+ protected _deleteMany(filter?: mongodb.Filter<T>, options?: mongodb.DeleteOptions): Promise<number>;
20
+ protected _findOne(filter: mongodb.Filter<T>, options?: mongodb.FindOptions): Promise<PartialOutput<T> | undefined>;
21
+ protected _find(filter: mongodb.Filter<T>, options?: mongodb.FindOptions): Promise<PartialOutput<T>[]>;
22
+ protected _insertOne(doc: mongodb.OptionalUnlessRequiredId<T>, options?: mongodb.InsertOneOptions): Promise<PartialOutput<T>>;
23
+ protected _updateOne(filter: mongodb.Filter<T>, doc: UpdateFilter<T> | Partial<T>, options?: mongodb.UpdateOptions): Promise<PartialOutput<T> | undefined>;
24
+ protected _updateMany(filter: mongodb.Filter<T>, doc: UpdateFilter<T> | Partial<T>, options?: StrictOmit<mongodb.UpdateOptions, 'upsert'>): Promise<number>;
25
+ forContext(context: RequestContext, db?: mongodb.Db, session?: mongodb.ClientSession): typeof this;
26
+ protected _onError(error: unknown): Promise<void>;
27
+ protected getDatabase(): mongodb.Db | Promise<mongodb.Db>;
28
+ protected getCollection(db: mongodb.Db): Promise<mongodb.Collection<T>>;
29
+ protected getCollectionName(): string;
30
+ protected onError?(error: unknown): void | Promise<void>;
31
+ protected transformData?(row: PartialOutput<T>): PartialOutput<T>;
32
+ }
@@ -1,17 +1,12 @@
1
1
  import mongodb, { UpdateFilter } from 'mongodb';
2
2
  import { StrictOmit } from 'ts-gems';
3
- import { ApiService, PartialOutput, RequestContext } from '@opra/core';
3
+ import { PartialOutput } from '@opra/core';
4
+ import { MongoEntityServiceBase } from './mongo-entity-service-base.js';
4
5
  export declare namespace MongoEntityService {
5
- interface Options {
6
- db?: mongodb.Db;
7
- defaultLimit?: number;
6
+ interface Options extends MongoEntityServiceBase.Options {
8
7
  }
9
8
  }
10
- export declare class MongoEntityService<T extends mongodb.Document> extends ApiService {
11
- protected _collectionName: string;
12
- defaultLimit: number;
13
- db?: mongodb.Db;
14
- session?: mongodb.ClientSession;
9
+ export declare class MongoEntityService<T extends mongodb.Document> extends MongoEntityServiceBase<T> {
15
10
  constructor(options?: MongoEntityService.Options);
16
11
  constructor(collectionName: string, options?: MongoEntityService.Options);
17
12
  count(filter?: mongodb.Filter<T>, options?: mongodb.CountOptions): Promise<number>;
@@ -22,12 +17,4 @@ export declare class MongoEntityService<T extends mongodb.Document> extends ApiS
22
17
  insertOne(doc: mongodb.OptionalUnlessRequiredId<T>, options?: mongodb.InsertOneOptions): Promise<PartialOutput<T>>;
23
18
  updateOne(filter: mongodb.Filter<T>, doc: UpdateFilter<T> | Partial<T>, options?: mongodb.UpdateOptions): Promise<PartialOutput<T> | undefined>;
24
19
  updateMany(filter: mongodb.Filter<T>, doc: UpdateFilter<T> | Partial<T>, options?: StrictOmit<mongodb.UpdateOptions, 'upsert'>): Promise<number>;
25
- with(context: RequestContext, db?: mongodb.Db, session?: mongodb.ClientSession): MongoEntityService<T>;
26
- forContext(context: RequestContext, db?: mongodb.Db, session?: mongodb.ClientSession): typeof this;
27
- protected _onError(error: unknown): Promise<void>;
28
- protected getDatabase(): mongodb.Db | Promise<mongodb.Db>;
29
- protected getCollection(db: mongodb.Db): Promise<mongodb.Collection<T>>;
30
- protected getCollectionName(): string;
31
- protected onError?(error: unknown): void | Promise<void>;
32
- protected transformData?(row: PartialOutput<T>): PartialOutput<T>;
33
20
  }
@@ -9,6 +9,10 @@ export declare abstract class MongoSingleton<T extends mongodb.Document> impleme
9
9
  delete?(ctx: RequestContext): Promise<number>;
10
10
  get?(ctx: RequestContext): Promise<Maybe<PartialOutput<T>>>;
11
11
  update?(ctx: RequestContext): Promise<Maybe<PartialOutput<T>>>;
12
+ protected _create(ctx: RequestContext, prepared: MongoAdapter.TransformedRequest): Promise<PartialOutput<T>>;
13
+ protected _delete(ctx: RequestContext, prepared: MongoAdapter.TransformedRequest): Promise<number>;
14
+ protected _get(ctx: RequestContext, prepared: MongoAdapter.TransformedRequest): Promise<Maybe<PartialOutput<T>>>;
15
+ protected _update(ctx: RequestContext, prepared: MongoAdapter.TransformedRequest): Promise<Maybe<PartialOutput<T>>>;
12
16
  protected _prepare(ctx: RequestContext): Promise<MongoAdapter.TransformedRequest>;
13
17
  protected onPrepare?(ctx: RequestContext, prepared: MongoAdapter.TransformedRequest): MongoAdapter.TransformedRequest | Promise<MongoAdapter.TransformedRequest>;
14
18
  protected abstract getService(ctx: RequestContext): MongoEntityService<T> | Promise<MongoEntityService<T>>;