@opra/mongodb 1.0.0-alpha.9 → 1.0.0-beta.1
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/adapter-utils/prepare-filter.js +1 -1
- package/cjs/adapter-utils/prepare-key-values.js +1 -1
- package/cjs/adapter-utils/prepare-patch.js +1 -1
- package/cjs/adapter-utils/prepare-projection.js +6 -7
- package/cjs/adapter-utils/prepare-sort.js +1 -1
- package/cjs/index.js +1 -0
- package/cjs/mongo-adapter.js +4 -4
- package/cjs/mongo-collection-service.js +123 -141
- package/cjs/mongo-entity-service.js +259 -131
- package/cjs/mongo-nested-service.js +416 -211
- package/cjs/mongo-service.js +79 -239
- package/cjs/mongo-singleton-service.js +101 -63
- package/esm/adapter-utils/prepare-projection.js +4 -4
- package/esm/index.js +1 -0
- package/esm/mongo-adapter.js +4 -4
- package/esm/mongo-collection-service.js +122 -141
- package/esm/mongo-entity-service.js +259 -131
- package/esm/mongo-nested-service.js +416 -211
- package/esm/mongo-service.js +79 -239
- package/esm/mongo-singleton-service.js +100 -63
- package/esm/package.json +3 -0
- package/package.json +27 -33
- package/types/adapter-utils/prepare-filter.d.ts +2 -2
- package/types/adapter-utils/prepare-projection.d.ts +1 -1
- package/types/index.d.cts +6 -0
- package/types/index.d.ts +1 -0
- package/types/mongo-adapter.d.ts +1 -1
- package/types/mongo-collection-service.d.ts +44 -64
- package/types/mongo-entity-service.d.ts +91 -53
- package/types/mongo-nested-service.d.ts +107 -43
- package/types/mongo-service.d.ts +55 -153
- package/types/mongo-singleton-service.d.ts +34 -31
package/esm/mongo-service.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { DATATYPE_METADATA } from '@opra/common';
|
|
2
2
|
import { ServiceBase } from '@opra/core';
|
|
3
3
|
import { ObjectId } from 'mongodb';
|
|
4
|
+
import { MongoAdapter } from './mongo-adapter.js';
|
|
4
5
|
/**
|
|
5
6
|
* Class representing a MongoDB service for interacting with a collection.
|
|
6
7
|
* @extends ServiceBase
|
|
@@ -20,20 +21,33 @@ export class MongoService extends ServiceBase {
|
|
|
20
21
|
this._outputCodecs = {};
|
|
21
22
|
this._dataType_ = dataType;
|
|
22
23
|
this.db = options?.db;
|
|
23
|
-
this
|
|
24
|
-
this
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
this.documentFilter = options?.documentFilter;
|
|
25
|
+
this.interceptor = options?.interceptor;
|
|
26
|
+
if (options?.collectionName)
|
|
27
|
+
this.collectionName = options?.collectionName;
|
|
28
|
+
else {
|
|
27
29
|
if (typeof dataType === 'string')
|
|
28
|
-
this
|
|
30
|
+
this.collectionName = dataType;
|
|
29
31
|
if (typeof dataType === 'function') {
|
|
30
32
|
const metadata = Reflect.getMetadata(DATATYPE_METADATA, dataType);
|
|
31
33
|
if (metadata)
|
|
32
|
-
this
|
|
34
|
+
this.collectionName = metadata.name;
|
|
33
35
|
}
|
|
34
36
|
}
|
|
35
|
-
this
|
|
36
|
-
this
|
|
37
|
+
this.resourceName = options?.resourceName;
|
|
38
|
+
this.idGenerator = options?.idGenerator;
|
|
39
|
+
this.onError = options?.onError;
|
|
40
|
+
}
|
|
41
|
+
for(context, overwriteProperties, overwriteContext) {
|
|
42
|
+
if (overwriteProperties?.documentFilter && this.documentFilter) {
|
|
43
|
+
overwriteProperties.documentFilter = [
|
|
44
|
+
...(Array.isArray(this.documentFilter) ? this.documentFilter : [this.documentFilter]),
|
|
45
|
+
...(Array.isArray(overwriteProperties?.documentFilter)
|
|
46
|
+
? overwriteProperties?.documentFilter
|
|
47
|
+
: [overwriteProperties?.documentFilter]),
|
|
48
|
+
];
|
|
49
|
+
}
|
|
50
|
+
return super.for(context, overwriteProperties, overwriteContext);
|
|
37
51
|
}
|
|
38
52
|
/**
|
|
39
53
|
* Retrieves the collection name.
|
|
@@ -43,7 +57,7 @@ export class MongoService extends ServiceBase {
|
|
|
43
57
|
* @throws {Error} If the collection name is not defined.
|
|
44
58
|
*/
|
|
45
59
|
getCollectionName() {
|
|
46
|
-
const out = typeof this
|
|
60
|
+
const out = typeof this.collectionName === 'function' ? this.collectionName(this) : this.collectionName;
|
|
47
61
|
if (out)
|
|
48
62
|
return out;
|
|
49
63
|
throw new Error('collectionName is not defined');
|
|
@@ -53,12 +67,10 @@ export class MongoService extends ServiceBase {
|
|
|
53
67
|
*
|
|
54
68
|
* @protected
|
|
55
69
|
* @returns {string} The resource name.
|
|
56
|
-
* @throws {Error} If the
|
|
70
|
+
* @throws {Error} If the resource name is not defined.
|
|
57
71
|
*/
|
|
58
72
|
getResourceName() {
|
|
59
|
-
const out = typeof this
|
|
60
|
-
? this.$resourceName(this)
|
|
61
|
-
: this.$resourceName || this.getCollectionName();
|
|
73
|
+
const out = typeof this.resourceName === 'function' ? this.resourceName(this) : this.resourceName || this.getCollectionName();
|
|
62
74
|
if (out)
|
|
63
75
|
return out;
|
|
64
76
|
throw new Error('resourceName is not defined');
|
|
@@ -73,36 +85,6 @@ export class MongoService extends ServiceBase {
|
|
|
73
85
|
this._dataType = this.context.document.node.getComplexType(this._dataType_);
|
|
74
86
|
return this._dataType;
|
|
75
87
|
}
|
|
76
|
-
/**
|
|
77
|
-
* Retrieves the codec for the specified operation.
|
|
78
|
-
*
|
|
79
|
-
* @param operation - The operation to retrieve the encoder for. Valid values are 'create' and 'update'.
|
|
80
|
-
*/
|
|
81
|
-
getInputCodec(operation) {
|
|
82
|
-
let validator = this._inputCodecs[operation];
|
|
83
|
-
if (validator)
|
|
84
|
-
return validator;
|
|
85
|
-
const options = { projection: '*' };
|
|
86
|
-
if (operation === 'update')
|
|
87
|
-
options.partial = 'deep';
|
|
88
|
-
const dataType = this.dataType;
|
|
89
|
-
validator = dataType.generateCodec('decode', options);
|
|
90
|
-
this._inputCodecs[operation] = validator;
|
|
91
|
-
return validator;
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* Retrieves the codec.
|
|
95
|
-
*/
|
|
96
|
-
getOutputCodec(operation) {
|
|
97
|
-
let validator = this._outputCodecs[operation];
|
|
98
|
-
if (validator)
|
|
99
|
-
return validator;
|
|
100
|
-
const options = { projection: '*', partial: 'deep' };
|
|
101
|
-
const dataType = this.dataType;
|
|
102
|
-
validator = dataType.generateCodec('decode', options);
|
|
103
|
-
this._outputCodecs[operation] = validator;
|
|
104
|
-
return validator;
|
|
105
|
-
}
|
|
106
88
|
/**
|
|
107
89
|
* Executes the provided function within a transaction.
|
|
108
90
|
*
|
|
@@ -144,191 +126,6 @@ export class MongoService extends ServiceBase {
|
|
|
144
126
|
await session.endSession();
|
|
145
127
|
}
|
|
146
128
|
}
|
|
147
|
-
/**
|
|
148
|
-
* Gets the number of documents matching the filter.
|
|
149
|
-
*
|
|
150
|
-
* @param filter - The filter used to match documents.
|
|
151
|
-
* @param options - The options for counting documents.
|
|
152
|
-
* @protected
|
|
153
|
-
*/
|
|
154
|
-
async _dbCountDocuments(filter, options) {
|
|
155
|
-
const db = this.getDatabase();
|
|
156
|
-
const collection = await this.getCollection(db);
|
|
157
|
-
options = {
|
|
158
|
-
...options,
|
|
159
|
-
limit: undefined,
|
|
160
|
-
session: options?.session || this.getSession(),
|
|
161
|
-
};
|
|
162
|
-
return (await collection.countDocuments(filter || {}, options)) || 0;
|
|
163
|
-
}
|
|
164
|
-
/**
|
|
165
|
-
* Acquires a connection and performs Collection.deleteOne operation
|
|
166
|
-
*
|
|
167
|
-
* @param filter - The filter used to select the document to remove
|
|
168
|
-
* @param options - Optional settings for the command
|
|
169
|
-
* @protected
|
|
170
|
-
*/
|
|
171
|
-
async _dbDeleteOne(filter, options) {
|
|
172
|
-
const db = this.getDatabase();
|
|
173
|
-
const collection = await this.getCollection(db);
|
|
174
|
-
options = {
|
|
175
|
-
...options,
|
|
176
|
-
session: options?.session || this.getSession(),
|
|
177
|
-
};
|
|
178
|
-
return await collection.deleteOne(filter || {}, options);
|
|
179
|
-
}
|
|
180
|
-
/**
|
|
181
|
-
* Acquires a connection and performs Collection.deleteMany operation
|
|
182
|
-
*
|
|
183
|
-
* @param filter - The filter used to select the documents to remove
|
|
184
|
-
* @param options - Optional settings for the command
|
|
185
|
-
* @protected
|
|
186
|
-
*/
|
|
187
|
-
async _dbDeleteMany(filter, options) {
|
|
188
|
-
const db = this.getDatabase();
|
|
189
|
-
const collection = await this.getCollection(db);
|
|
190
|
-
options = {
|
|
191
|
-
...options,
|
|
192
|
-
session: options?.session || this.getSession(),
|
|
193
|
-
};
|
|
194
|
-
return await collection.deleteMany(filter || {}, options);
|
|
195
|
-
}
|
|
196
|
-
/**
|
|
197
|
-
* Acquires a connection and performs Collection.distinct operation
|
|
198
|
-
*
|
|
199
|
-
* @param field - Field of the document to find distinct values for
|
|
200
|
-
* @param filter - The filter for filtering the set of documents to which we apply the distinct filter.
|
|
201
|
-
* @param options - Optional settings for the command
|
|
202
|
-
* @protected
|
|
203
|
-
*/
|
|
204
|
-
async _dbDistinct(field, filter, options) {
|
|
205
|
-
const db = this.getDatabase();
|
|
206
|
-
const collection = await this.getCollection(db);
|
|
207
|
-
options = {
|
|
208
|
-
...options,
|
|
209
|
-
session: options?.session || this.getSession(),
|
|
210
|
-
};
|
|
211
|
-
return await collection.distinct(field, filter || {}, options);
|
|
212
|
-
}
|
|
213
|
-
/**
|
|
214
|
-
* Acquires a connection and performs Collection.aggregate operation
|
|
215
|
-
*
|
|
216
|
-
* @param pipeline - An array of aggregation pipelines to execute
|
|
217
|
-
* @param options - Optional settings for the command
|
|
218
|
-
* @protected
|
|
219
|
-
*/
|
|
220
|
-
async _dbAggregate(pipeline, options) {
|
|
221
|
-
const db = this.getDatabase();
|
|
222
|
-
const collection = await this.getCollection(db);
|
|
223
|
-
options = {
|
|
224
|
-
...options,
|
|
225
|
-
session: options?.session || this.getSession(),
|
|
226
|
-
};
|
|
227
|
-
return await collection.aggregate(pipeline, options);
|
|
228
|
-
}
|
|
229
|
-
/**
|
|
230
|
-
* Acquires a connection and performs Collection.findOne operation
|
|
231
|
-
*
|
|
232
|
-
* @param filter - Query for find Operation
|
|
233
|
-
* @param options - Optional settings for the command
|
|
234
|
-
* @protected
|
|
235
|
-
*/
|
|
236
|
-
async _dbFindOne(filter, options) {
|
|
237
|
-
const db = this.getDatabase();
|
|
238
|
-
const collection = await this.getCollection(db);
|
|
239
|
-
options = {
|
|
240
|
-
...options,
|
|
241
|
-
session: options?.session || this.getSession(),
|
|
242
|
-
};
|
|
243
|
-
return (await collection.findOne(filter || {}, options));
|
|
244
|
-
}
|
|
245
|
-
/**
|
|
246
|
-
* Acquires a connection and performs Collection.find operation
|
|
247
|
-
*
|
|
248
|
-
* @param filter - The filter predicate. If unspecified,
|
|
249
|
-
* then all documents in the collection will match the predicate
|
|
250
|
-
* @param options - Optional settings for the command
|
|
251
|
-
* @protected
|
|
252
|
-
*/
|
|
253
|
-
async _dbFind(filter, options) {
|
|
254
|
-
const db = this.getDatabase();
|
|
255
|
-
const collection = await this.getCollection(db);
|
|
256
|
-
options = {
|
|
257
|
-
...options,
|
|
258
|
-
session: options?.session || this.getSession(),
|
|
259
|
-
};
|
|
260
|
-
return collection.find(filter || {}, options);
|
|
261
|
-
}
|
|
262
|
-
/**
|
|
263
|
-
* Acquires a connection and performs Collection.insertOne operation
|
|
264
|
-
*
|
|
265
|
-
* @param doc - The document to insert
|
|
266
|
-
* @param options - Optional settings for the command
|
|
267
|
-
* @protected
|
|
268
|
-
*/
|
|
269
|
-
async _dbInsertOne(doc, options) {
|
|
270
|
-
const db = this.getDatabase();
|
|
271
|
-
const collection = await this.getCollection(db);
|
|
272
|
-
options = {
|
|
273
|
-
...options,
|
|
274
|
-
session: options?.session || this.getSession(),
|
|
275
|
-
};
|
|
276
|
-
return await collection.insertOne(doc, options);
|
|
277
|
-
}
|
|
278
|
-
/**
|
|
279
|
-
* Acquires a connection and performs Collection.updateOne operation
|
|
280
|
-
*
|
|
281
|
-
* @param filter - The filter used to select the document to update
|
|
282
|
-
* @param update - The update operations to be applied to the document
|
|
283
|
-
* @param options - Optional settings for the command
|
|
284
|
-
* @protected
|
|
285
|
-
*/
|
|
286
|
-
async _dbUpdateOne(filter, update, options) {
|
|
287
|
-
const db = this.getDatabase();
|
|
288
|
-
const collection = await this.getCollection(db);
|
|
289
|
-
options = {
|
|
290
|
-
...options,
|
|
291
|
-
session: options?.session || this.getSession(),
|
|
292
|
-
};
|
|
293
|
-
return collection.updateOne(filter || {}, update, options);
|
|
294
|
-
}
|
|
295
|
-
/**
|
|
296
|
-
* Acquires a connection and performs Collection.findOneAndUpdate operation
|
|
297
|
-
*
|
|
298
|
-
* @param filter - The filter used to select the document to update
|
|
299
|
-
* @param update - Update operations to be performed on the document
|
|
300
|
-
* @param options - Optional settings for the command
|
|
301
|
-
* @protected
|
|
302
|
-
*/
|
|
303
|
-
async _dbFindOneAndUpdate(filter, update, options) {
|
|
304
|
-
const db = this.getDatabase();
|
|
305
|
-
const collection = await this.getCollection(db);
|
|
306
|
-
const opts = {
|
|
307
|
-
returnDocument: 'after',
|
|
308
|
-
includeResultMetadata: false,
|
|
309
|
-
...options,
|
|
310
|
-
session: options?.session || this.getSession(),
|
|
311
|
-
};
|
|
312
|
-
return await collection.findOneAndUpdate(filter || {}, update, opts);
|
|
313
|
-
}
|
|
314
|
-
/**
|
|
315
|
-
* Acquires a connection and performs Collection.updateMany operation
|
|
316
|
-
*
|
|
317
|
-
* @param filter - The filter used to select the documents to update
|
|
318
|
-
* @param update - The update operations to be applied to the documents
|
|
319
|
-
* @param options - Optional settings for the command
|
|
320
|
-
* @protected
|
|
321
|
-
*/
|
|
322
|
-
async _dbUpdateMany(filter, update, options) {
|
|
323
|
-
const db = this.getDatabase();
|
|
324
|
-
const collection = await this.getCollection(db);
|
|
325
|
-
options = {
|
|
326
|
-
...options,
|
|
327
|
-
session: options?.session || this.getSession(),
|
|
328
|
-
upsert: false,
|
|
329
|
-
};
|
|
330
|
-
return await collection.updateMany(filter || {}, update, options);
|
|
331
|
-
}
|
|
332
129
|
/**
|
|
333
130
|
* Retrieves the database connection.
|
|
334
131
|
*
|
|
@@ -367,8 +164,8 @@ export class MongoService extends ServiceBase {
|
|
|
367
164
|
* @protected
|
|
368
165
|
* @returns {MongoAdapter.AnyId} The generated ID.
|
|
369
166
|
*/
|
|
370
|
-
_generateId() {
|
|
371
|
-
return typeof this
|
|
167
|
+
_generateId(command) {
|
|
168
|
+
return typeof this.idGenerator === 'function' ? this.idGenerator(command, this) : new ObjectId();
|
|
372
169
|
}
|
|
373
170
|
/**
|
|
374
171
|
* Retrieves the common filter used for querying documents.
|
|
@@ -378,19 +175,62 @@ export class MongoService extends ServiceBase {
|
|
|
378
175
|
* @returns {FilterInput | Promise<FilterInput> | undefined} The common filter or a Promise
|
|
379
176
|
* that resolves to the common filter, or undefined if not available.
|
|
380
177
|
*/
|
|
381
|
-
_getDocumentFilter(
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
178
|
+
_getDocumentFilter(command) {
|
|
179
|
+
const commonFilter = Array.isArray(this.documentFilter) ? this.documentFilter : [this.documentFilter];
|
|
180
|
+
const mapped = commonFilter.map(f => (typeof f === 'function' ? f(command, this) : f));
|
|
181
|
+
return mapped.length > 1 ? MongoAdapter.prepareFilter(mapped) : mapped[0];
|
|
182
|
+
}
|
|
183
|
+
async _executeCommand(command, commandFn) {
|
|
184
|
+
let proto;
|
|
185
|
+
const next = async () => {
|
|
186
|
+
proto = proto ? Object.getPrototypeOf(proto) : this;
|
|
187
|
+
while (proto) {
|
|
188
|
+
if (proto.interceptor && Object.prototype.hasOwnProperty.call(proto, 'interceptor')) {
|
|
189
|
+
return await proto.interceptor.call(this, next, command, this);
|
|
190
|
+
}
|
|
191
|
+
proto = Object.getPrototypeOf(proto);
|
|
192
|
+
if (!(proto instanceof MongoService))
|
|
193
|
+
break;
|
|
194
|
+
}
|
|
195
|
+
return commandFn();
|
|
196
|
+
};
|
|
385
197
|
try {
|
|
386
|
-
|
|
387
|
-
return this.$interceptor(callback, info, this);
|
|
388
|
-
return callback();
|
|
198
|
+
return await next();
|
|
389
199
|
}
|
|
390
200
|
catch (e) {
|
|
391
|
-
Error.captureStackTrace(e, this.
|
|
392
|
-
await this
|
|
201
|
+
Error.captureStackTrace(e, this._executeCommand);
|
|
202
|
+
await this.onError?.(e, this);
|
|
393
203
|
throw e;
|
|
394
204
|
}
|
|
395
205
|
}
|
|
206
|
+
/**
|
|
207
|
+
* Retrieves the codec for the specified operation.
|
|
208
|
+
*
|
|
209
|
+
* @param operation - The operation to retrieve the encoder for. Valid values are 'create' and 'update'.
|
|
210
|
+
*/
|
|
211
|
+
_getInputCodec(operation) {
|
|
212
|
+
let validator = this._inputCodecs[operation];
|
|
213
|
+
if (validator)
|
|
214
|
+
return validator;
|
|
215
|
+
const options = { projection: '*' };
|
|
216
|
+
if (operation === 'update')
|
|
217
|
+
options.partial = 'deep';
|
|
218
|
+
const dataType = this.dataType;
|
|
219
|
+
validator = dataType.generateCodec('decode', options);
|
|
220
|
+
this._inputCodecs[operation] = validator;
|
|
221
|
+
return validator;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Retrieves the codec.
|
|
225
|
+
*/
|
|
226
|
+
_getOutputCodec(operation) {
|
|
227
|
+
let validator = this._outputCodecs[operation];
|
|
228
|
+
if (validator)
|
|
229
|
+
return validator;
|
|
230
|
+
const options = { projection: '*', partial: 'deep' };
|
|
231
|
+
const dataType = this.dataType;
|
|
232
|
+
validator = dataType.generateCodec('decode', options);
|
|
233
|
+
this._outputCodecs[operation] = validator;
|
|
234
|
+
return validator;
|
|
235
|
+
}
|
|
396
236
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ResourceNotAvailableError } from '@opra/common';
|
|
2
|
+
import omit from 'lodash.omit';
|
|
2
3
|
import { ObjectId } from 'mongodb';
|
|
3
4
|
import { MongoAdapter } from './mongo-adapter.js';
|
|
4
5
|
import { MongoEntityService } from './mongo-entity-service.js';
|
|
@@ -18,12 +19,12 @@ export class MongoSingletonService extends MongoEntityService {
|
|
|
18
19
|
*/
|
|
19
20
|
constructor(dataType, options) {
|
|
20
21
|
super(dataType, options);
|
|
21
|
-
this._id =
|
|
22
|
+
this._id = options?._id || new ObjectId('655608925cad472b75fc6485');
|
|
22
23
|
}
|
|
23
24
|
/**
|
|
24
25
|
* Asserts the existence of a resource based on the given options.
|
|
25
26
|
*
|
|
26
|
-
* @param {
|
|
27
|
+
* @param {MongoEntityService.ExistsOptions<T>} [options]
|
|
27
28
|
* @returns {Promise<void>} A Promise that resolves when the resource exists.
|
|
28
29
|
* @throws {ResourceNotAvailableError} If the resource does not exist.
|
|
29
30
|
*/
|
|
@@ -31,127 +32,163 @@ export class MongoSingletonService extends MongoEntityService {
|
|
|
31
32
|
if (!(await this.exists(options)))
|
|
32
33
|
throw new ResourceNotAvailableError(this.getResourceName());
|
|
33
34
|
}
|
|
35
|
+
async create(input, options) {
|
|
36
|
+
const command = {
|
|
37
|
+
crud: 'create',
|
|
38
|
+
method: 'create',
|
|
39
|
+
byId: false,
|
|
40
|
+
input,
|
|
41
|
+
options,
|
|
42
|
+
};
|
|
43
|
+
input._id = this._id;
|
|
44
|
+
return this._executeCommand(command, async () => {
|
|
45
|
+
const r = await this._create(command);
|
|
46
|
+
if (!command.options?.projection)
|
|
47
|
+
return r;
|
|
48
|
+
const findCommand = {
|
|
49
|
+
...command,
|
|
50
|
+
crud: 'read',
|
|
51
|
+
byId: true,
|
|
52
|
+
documentId: r._id,
|
|
53
|
+
options: omit(options, 'filter'),
|
|
54
|
+
};
|
|
55
|
+
const out = await this._findById(findCommand);
|
|
56
|
+
if (out)
|
|
57
|
+
return out;
|
|
58
|
+
});
|
|
59
|
+
}
|
|
34
60
|
/**
|
|
35
61
|
* Creates the document in the database.
|
|
36
62
|
*
|
|
37
|
-
* @param {
|
|
38
|
-
* @param {
|
|
39
|
-
* @
|
|
63
|
+
* @param {DTO<T>} input - The partial input to create the document with.
|
|
64
|
+
* @param {MongoEntityService.CreateOptions} [options] - The options for creating the document.
|
|
65
|
+
* @returns {Promise<MongoEntityService.CreateResult<T>>} A promise that resolves create operation result
|
|
40
66
|
* @throws {Error} Throws an error if an unknown error occurs while creating the document.
|
|
41
67
|
*/
|
|
42
|
-
async
|
|
43
|
-
|
|
44
|
-
const info = {
|
|
68
|
+
async createOnly(input, options) {
|
|
69
|
+
const command = {
|
|
45
70
|
crud: 'create',
|
|
46
|
-
method: '
|
|
71
|
+
method: 'createOnly',
|
|
47
72
|
byId: false,
|
|
48
|
-
documentId: this._id,
|
|
49
73
|
input,
|
|
50
74
|
options,
|
|
51
75
|
};
|
|
52
|
-
|
|
76
|
+
input._id = this._id;
|
|
77
|
+
return this._executeCommand(command, () => this._create(command));
|
|
53
78
|
}
|
|
54
79
|
/**
|
|
55
80
|
* Deletes a record from the database
|
|
56
81
|
*
|
|
57
|
-
* @param {
|
|
82
|
+
* @param {MongoEntityService.DeleteOptions<T>} options - The options for deleting the record
|
|
58
83
|
* @returns {Promise<number>} The number of records deleted
|
|
59
84
|
*/
|
|
60
85
|
async delete(options) {
|
|
61
|
-
const
|
|
86
|
+
const command = {
|
|
62
87
|
crud: 'delete',
|
|
63
88
|
method: 'delete',
|
|
64
89
|
byId: true,
|
|
65
90
|
documentId: this._id,
|
|
66
91
|
options,
|
|
67
92
|
};
|
|
68
|
-
return this.
|
|
69
|
-
const filter = MongoAdapter.prepareFilter([await this._getDocumentFilter(
|
|
70
|
-
|
|
71
|
-
|
|
93
|
+
return this._executeCommand(command, async () => {
|
|
94
|
+
const filter = MongoAdapter.prepareFilter([await this._getDocumentFilter(command), command.options?.filter]);
|
|
95
|
+
command.options = { ...command.options, filter };
|
|
96
|
+
return this._delete(command);
|
|
97
|
+
});
|
|
72
98
|
}
|
|
73
99
|
/**
|
|
74
100
|
* Checks if the document exists in the database.
|
|
75
101
|
*
|
|
102
|
+
* @param {MongoEntityService.FindOneOptions<T>} [options] - The options for finding the document.
|
|
76
103
|
* @return {Promise<boolean>} - A promise that resolves to a boolean value indicating if the document exists.
|
|
77
104
|
*/
|
|
78
105
|
async exists(options) {
|
|
79
|
-
|
|
106
|
+
const command = {
|
|
107
|
+
crud: 'read',
|
|
108
|
+
method: 'exists',
|
|
109
|
+
byId: true,
|
|
110
|
+
documentId: this._id,
|
|
111
|
+
options,
|
|
112
|
+
};
|
|
113
|
+
return this._executeCommand(command, async () => {
|
|
114
|
+
const documentFilter = await this._getDocumentFilter(command);
|
|
115
|
+
const filter = MongoAdapter.prepareFilter([documentFilter, command.options?.filter]);
|
|
116
|
+
const findCommand = command;
|
|
117
|
+
findCommand.options = { ...command.options, filter, projection: ['_id'] };
|
|
118
|
+
return !!(await this._findById(findCommand));
|
|
119
|
+
});
|
|
80
120
|
}
|
|
81
|
-
/**
|
|
82
|
-
* Fetches the document if it exists. Returns undefined if not found.
|
|
83
|
-
*
|
|
84
|
-
* @param {MongoSingletonService.FindOneOptions<T>} [options] - The options for finding the document.
|
|
85
|
-
* @returns {Promise<PartialDTO<T> | undefined>} - A promise that resolves to the found document or undefined if not found.
|
|
86
|
-
*/
|
|
87
121
|
async find(options) {
|
|
88
|
-
const
|
|
122
|
+
const command = {
|
|
89
123
|
crud: 'read',
|
|
90
|
-
method: '
|
|
124
|
+
method: 'findById',
|
|
91
125
|
byId: true,
|
|
92
126
|
documentId: this._id,
|
|
93
127
|
options,
|
|
94
128
|
};
|
|
95
|
-
return this.
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
|
|
129
|
+
return this._executeCommand(command, async () => {
|
|
130
|
+
const documentFilter = await this._getDocumentFilter(command);
|
|
131
|
+
const filter = MongoAdapter.prepareFilter([documentFilter, command.options?.filter]);
|
|
132
|
+
command.options = { ...command.options, filter };
|
|
133
|
+
return this._findById(command);
|
|
134
|
+
});
|
|
99
135
|
}
|
|
100
|
-
/**
|
|
101
|
-
* Fetches the document from the Mongo collection service. Throws error if not found.
|
|
102
|
-
*
|
|
103
|
-
* @param {MongoSingletonService.FindOneOptions<T>} options - The options to customize the query.
|
|
104
|
-
* @return {Promise<PartialDTO<T>>} - A promise that resolves to the fetched document.
|
|
105
|
-
* @throws {ResourceNotAvailableError} - If the document is not found in the collection.
|
|
106
|
-
*/
|
|
107
136
|
async get(options) {
|
|
108
137
|
const out = await this.find(options);
|
|
109
138
|
if (!out)
|
|
110
139
|
throw new ResourceNotAvailableError(this.getResourceName());
|
|
111
140
|
return out;
|
|
112
141
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
* @param {PatchDTO<T>} input - The partial input to update the document.
|
|
117
|
-
* @param {MongoSingletonService.UpdateOptions<T>} [options] - The update options.
|
|
118
|
-
*
|
|
119
|
-
* @return {Promise<number>} - A promise that resolves to the updated document or undefined if not found.
|
|
120
|
-
*/
|
|
121
|
-
async updateOnly(input, options) {
|
|
122
|
-
const info = {
|
|
142
|
+
async update(input, options) {
|
|
143
|
+
const isUpdateFilter = Array.isArray(input) || !!Object.keys(input).find(x => x.startsWith('$'));
|
|
144
|
+
const command = {
|
|
123
145
|
crud: 'update',
|
|
124
146
|
method: 'update',
|
|
125
|
-
byId: true,
|
|
126
147
|
documentId: this._id,
|
|
127
|
-
|
|
148
|
+
byId: true,
|
|
149
|
+
input: isUpdateFilter ? undefined : input,
|
|
150
|
+
inputRaw: isUpdateFilter ? input : undefined,
|
|
128
151
|
options,
|
|
129
152
|
};
|
|
130
|
-
return this.
|
|
131
|
-
const filter = MongoAdapter.prepareFilter([await this._getDocumentFilter(
|
|
132
|
-
|
|
133
|
-
|
|
153
|
+
return this._executeCommand(command, async () => {
|
|
154
|
+
const filter = MongoAdapter.prepareFilter([await this._getDocumentFilter(command), command.options?.filter]);
|
|
155
|
+
command.options = { ...command.options, filter };
|
|
156
|
+
const matchCount = await this._updateOnly(command);
|
|
157
|
+
if (matchCount) {
|
|
158
|
+
const findCommand = {
|
|
159
|
+
...command,
|
|
160
|
+
crud: 'read',
|
|
161
|
+
byId: true,
|
|
162
|
+
documentId: this._id,
|
|
163
|
+
options: omit(options, ['filter', 'sort']),
|
|
164
|
+
};
|
|
165
|
+
const out = await this._findById(findCommand);
|
|
166
|
+
if (out)
|
|
167
|
+
return out;
|
|
168
|
+
}
|
|
169
|
+
});
|
|
134
170
|
}
|
|
135
171
|
/**
|
|
136
172
|
* Updates a document in the MongoDB collection.
|
|
137
173
|
*
|
|
138
174
|
* @param {PatchDTO<T>} input - The partial input to update the document.
|
|
139
|
-
* @param {
|
|
175
|
+
* @param {MongoEntityService.UpdateOneOptions<T>} [options] - The update options.
|
|
140
176
|
*
|
|
141
|
-
* @return {Promise<
|
|
177
|
+
* @return {Promise<number>} - A promise that resolves to the updated document or undefined if not found.
|
|
142
178
|
*/
|
|
143
|
-
async
|
|
144
|
-
const
|
|
179
|
+
async updateOnly(input, options) {
|
|
180
|
+
const command = {
|
|
145
181
|
crud: 'update',
|
|
146
|
-
method: '
|
|
147
|
-
byId: true,
|
|
182
|
+
method: 'updateOnly',
|
|
148
183
|
documentId: this._id,
|
|
184
|
+
byId: true,
|
|
149
185
|
input,
|
|
150
186
|
options,
|
|
151
187
|
};
|
|
152
|
-
return this.
|
|
153
|
-
const filter = MongoAdapter.prepareFilter([await this._getDocumentFilter(
|
|
154
|
-
|
|
155
|
-
|
|
188
|
+
return this._executeCommand(command, async () => {
|
|
189
|
+
const filter = MongoAdapter.prepareFilter([await this._getDocumentFilter(command), command.options?.filter]);
|
|
190
|
+
command.options = { ...command.options, filter };
|
|
191
|
+
return this._updateOnly(command);
|
|
192
|
+
});
|
|
156
193
|
}
|
|
157
194
|
}
|
package/esm/package.json
ADDED