@opra/mongodb 1.4.3 → 1.5.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/adapter/mongo-adapter.js +41 -12
- package/cjs/adapter/mongo-patch-generator.js +14 -4
- package/cjs/adapter/prepare-filter.js +11 -3
- package/cjs/adapter/prepare-projection.js +14 -7
- package/cjs/services/mongo-collection-service.js +61 -15
- package/cjs/services/mongo-entity-service.js +36 -12
- package/cjs/services/mongo-nested-service.js +137 -37
- package/cjs/services/mongo-service.js +32 -10
- package/cjs/services/mongo-singleton-service.js +20 -5
- package/esm/adapter/mongo-adapter.js +41 -12
- package/esm/adapter/mongo-patch-generator.js +14 -4
- package/esm/adapter/prepare-filter.js +11 -3
- package/esm/adapter/prepare-projection.js +15 -8
- package/esm/services/mongo-collection-service.js +61 -15
- package/esm/services/mongo-entity-service.js +36 -12
- package/esm/services/mongo-nested-service.js +138 -38
- package/esm/services/mongo-service.js +33 -11
- package/esm/services/mongo-singleton-service.js +20 -5
- package/package.json +4 -4
- package/types/adapter/prepare-projection.d.ts +2 -2
- package/types/services/mongo-service.d.ts +6 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DATATYPE_METADATA } from '@opra/common';
|
|
2
2
|
import { ServiceBase } from '@opra/core';
|
|
3
|
-
import { ObjectId } from 'mongodb';
|
|
3
|
+
import { ObjectId, } from 'mongodb';
|
|
4
4
|
import { MongoAdapter } from '../adapter/mongo-adapter.js';
|
|
5
5
|
const transactionKey = Symbol.for('transaction');
|
|
6
6
|
/**
|
|
@@ -42,10 +42,12 @@ export class MongoService extends ServiceBase {
|
|
|
42
42
|
for(context, overwriteProperties, overwriteContext) {
|
|
43
43
|
if (overwriteProperties?.documentFilter && this.documentFilter) {
|
|
44
44
|
overwriteProperties.documentFilter = [
|
|
45
|
-
...(Array.isArray(this.documentFilter)
|
|
45
|
+
...(Array.isArray(this.documentFilter)
|
|
46
|
+
? this.documentFilter
|
|
47
|
+
: [this.documentFilter]),
|
|
46
48
|
...(Array.isArray(overwriteProperties?.documentFilter)
|
|
47
|
-
? overwriteProperties
|
|
48
|
-
: [overwriteProperties
|
|
49
|
+
? overwriteProperties.documentFilter
|
|
50
|
+
: [overwriteProperties.documentFilter]),
|
|
49
51
|
];
|
|
50
52
|
}
|
|
51
53
|
return super.for(context, overwriteProperties, overwriteContext);
|
|
@@ -58,7 +60,9 @@ export class MongoService extends ServiceBase {
|
|
|
58
60
|
* @throws {Error} If the collection name is not defined.
|
|
59
61
|
*/
|
|
60
62
|
getCollectionName() {
|
|
61
|
-
const out = typeof this.collectionName === 'function'
|
|
63
|
+
const out = typeof this.collectionName === 'function'
|
|
64
|
+
? this.collectionName(this)
|
|
65
|
+
: this.collectionName;
|
|
62
66
|
if (out)
|
|
63
67
|
return out;
|
|
64
68
|
throw new Error('collectionName is not defined');
|
|
@@ -71,7 +75,9 @@ export class MongoService extends ServiceBase {
|
|
|
71
75
|
* @throws {Error} If the resource name is not defined.
|
|
72
76
|
*/
|
|
73
77
|
getResourceName() {
|
|
74
|
-
const out = typeof this.resourceName === 'function'
|
|
78
|
+
const out = typeof this.resourceName === 'function'
|
|
79
|
+
? this.resourceName(this)
|
|
80
|
+
: this.resourceName || this.getCollectionName();
|
|
75
81
|
if (out)
|
|
76
82
|
return out;
|
|
77
83
|
throw new Error('resourceName is not defined');
|
|
@@ -82,8 +88,14 @@ export class MongoService extends ServiceBase {
|
|
|
82
88
|
* @throws {NotAcceptableError} If the data type is not a ComplexType.
|
|
83
89
|
*/
|
|
84
90
|
get dataType() {
|
|
91
|
+
if (this._dataType && this._dataTypeScope !== this.scopes)
|
|
92
|
+
this._dataType = undefined;
|
|
85
93
|
if (!this._dataType)
|
|
86
94
|
this._dataType = this.context.documentNode.getComplexType(this._dataType_);
|
|
95
|
+
this._dataTypeScope = this.scopes;
|
|
96
|
+
this._dataTypeScopes = this.scopes
|
|
97
|
+
? this.scopes?.split(/\s*,\s*/)
|
|
98
|
+
: undefined;
|
|
87
99
|
return this._dataType;
|
|
88
100
|
}
|
|
89
101
|
/**
|
|
@@ -181,7 +193,9 @@ export class MongoService extends ServiceBase {
|
|
|
181
193
|
* @returns {MongoAdapter.AnyId} The generated ID.
|
|
182
194
|
*/
|
|
183
195
|
_generateId(command) {
|
|
184
|
-
return typeof this.idGenerator === 'function'
|
|
196
|
+
return typeof this.idGenerator === 'function'
|
|
197
|
+
? this.idGenerator(command, this)
|
|
198
|
+
: new ObjectId();
|
|
185
199
|
}
|
|
186
200
|
/**
|
|
187
201
|
* Retrieves the common filter used for querying documents.
|
|
@@ -192,8 +206,10 @@ export class MongoService extends ServiceBase {
|
|
|
192
206
|
* that resolves to the common filter, or undefined if not available.
|
|
193
207
|
*/
|
|
194
208
|
_getDocumentFilter(command) {
|
|
195
|
-
const commonFilter = Array.isArray(this.documentFilter)
|
|
196
|
-
|
|
209
|
+
const commonFilter = Array.isArray(this.documentFilter)
|
|
210
|
+
? this.documentFilter
|
|
211
|
+
: [this.documentFilter];
|
|
212
|
+
const mapped = commonFilter.map(f => typeof f === 'function' ? f(command, this) : f);
|
|
197
213
|
return mapped.length > 1 ? MongoAdapter.prepareFilter(mapped) : mapped[0];
|
|
198
214
|
}
|
|
199
215
|
async _executeCommand(command, commandFn) {
|
|
@@ -201,7 +217,8 @@ export class MongoService extends ServiceBase {
|
|
|
201
217
|
const next = async () => {
|
|
202
218
|
proto = proto ? Object.getPrototypeOf(proto) : this;
|
|
203
219
|
while (proto) {
|
|
204
|
-
if (proto.interceptor &&
|
|
220
|
+
if (proto.interceptor &&
|
|
221
|
+
Object.prototype.hasOwnProperty.call(proto, 'interceptor')) {
|
|
205
222
|
return await proto.interceptor.call(this, next, command, this);
|
|
206
223
|
}
|
|
207
224
|
proto = Object.getPrototypeOf(proto);
|
|
@@ -229,6 +246,7 @@ export class MongoService extends ServiceBase {
|
|
|
229
246
|
if (validator)
|
|
230
247
|
return validator;
|
|
231
248
|
const options = { projection: '*' };
|
|
249
|
+
options.scope = this._dataTypeScopes;
|
|
232
250
|
if (operation === 'update') {
|
|
233
251
|
options.partial = 'deep';
|
|
234
252
|
options.allowPatchOperators = true;
|
|
@@ -245,7 +263,11 @@ export class MongoService extends ServiceBase {
|
|
|
245
263
|
let validator = this._outputCodecs[operation];
|
|
246
264
|
if (validator)
|
|
247
265
|
return validator;
|
|
248
|
-
const options = {
|
|
266
|
+
const options = {
|
|
267
|
+
projection: '*',
|
|
268
|
+
partial: 'deep',
|
|
269
|
+
scope: this._dataTypeScopes,
|
|
270
|
+
};
|
|
249
271
|
const dataType = this.dataType;
|
|
250
272
|
validator = dataType.generateCodec('decode', options);
|
|
251
273
|
this._outputCodecs[operation] = validator;
|
|
@@ -91,7 +91,10 @@ export class MongoSingletonService extends MongoEntityService {
|
|
|
91
91
|
options,
|
|
92
92
|
};
|
|
93
93
|
return this._executeCommand(command, async () => {
|
|
94
|
-
const filter = MongoAdapter.prepareFilter([
|
|
94
|
+
const filter = MongoAdapter.prepareFilter([
|
|
95
|
+
await this._getDocumentFilter(command),
|
|
96
|
+
command.options?.filter,
|
|
97
|
+
]);
|
|
95
98
|
command.options = { ...command.options, filter };
|
|
96
99
|
return this._delete(command);
|
|
97
100
|
});
|
|
@@ -112,7 +115,10 @@ export class MongoSingletonService extends MongoEntityService {
|
|
|
112
115
|
};
|
|
113
116
|
return this._executeCommand(command, async () => {
|
|
114
117
|
const documentFilter = await this._getDocumentFilter(command);
|
|
115
|
-
const filter = MongoAdapter.prepareFilter([
|
|
118
|
+
const filter = MongoAdapter.prepareFilter([
|
|
119
|
+
documentFilter,
|
|
120
|
+
command.options?.filter,
|
|
121
|
+
]);
|
|
116
122
|
const findCommand = command;
|
|
117
123
|
findCommand.options = { ...command.options, filter, projection: ['_id'] };
|
|
118
124
|
return !!(await this._findById(findCommand));
|
|
@@ -128,7 +134,10 @@ export class MongoSingletonService extends MongoEntityService {
|
|
|
128
134
|
};
|
|
129
135
|
return this._executeCommand(command, async () => {
|
|
130
136
|
const documentFilter = await this._getDocumentFilter(command);
|
|
131
|
-
const filter = MongoAdapter.prepareFilter([
|
|
137
|
+
const filter = MongoAdapter.prepareFilter([
|
|
138
|
+
documentFilter,
|
|
139
|
+
command.options?.filter,
|
|
140
|
+
]);
|
|
132
141
|
command.options = { ...command.options, filter };
|
|
133
142
|
return this._findById(command);
|
|
134
143
|
});
|
|
@@ -151,7 +160,10 @@ export class MongoSingletonService extends MongoEntityService {
|
|
|
151
160
|
options,
|
|
152
161
|
};
|
|
153
162
|
return this._executeCommand(command, async () => {
|
|
154
|
-
const filter = MongoAdapter.prepareFilter([
|
|
163
|
+
const filter = MongoAdapter.prepareFilter([
|
|
164
|
+
await this._getDocumentFilter(command),
|
|
165
|
+
command.options?.filter,
|
|
166
|
+
]);
|
|
155
167
|
command.options = { ...command.options, filter };
|
|
156
168
|
const matchCount = await this._updateOnly(command);
|
|
157
169
|
if (matchCount) {
|
|
@@ -186,7 +198,10 @@ export class MongoSingletonService extends MongoEntityService {
|
|
|
186
198
|
options,
|
|
187
199
|
};
|
|
188
200
|
return this._executeCommand(command, async () => {
|
|
189
|
-
const filter = MongoAdapter.prepareFilter([
|
|
201
|
+
const filter = MongoAdapter.prepareFilter([
|
|
202
|
+
await this._getDocumentFilter(command),
|
|
203
|
+
command.options?.filter,
|
|
204
|
+
]);
|
|
190
205
|
command.options = { ...command.options, filter };
|
|
191
206
|
return this._updateOnly(command);
|
|
192
207
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opra/mongodb",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "Opra MongoDB adapter package",
|
|
5
5
|
"author": "Panates",
|
|
6
6
|
"license": "MIT",
|
|
@@ -10,9 +10,9 @@
|
|
|
10
10
|
"valgen": "^5.12.0"
|
|
11
11
|
},
|
|
12
12
|
"peerDependencies": {
|
|
13
|
-
"@opra/common": "^1.
|
|
14
|
-
"@opra/core": "^1.
|
|
15
|
-
"@opra/http": "^1.
|
|
13
|
+
"@opra/common": "^1.5.0",
|
|
14
|
+
"@opra/core": "^1.5.0",
|
|
15
|
+
"@opra/http": "^1.5.0",
|
|
16
16
|
"mongodb": ">= 6.0.0"
|
|
17
17
|
},
|
|
18
18
|
"type": "module",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { ComplexType, FieldsProjection } from '@opra/common';
|
|
2
2
|
import mongodb, { type Document } from 'mongodb';
|
|
3
|
-
export default function prepareProjection(dataType: ComplexType, projection?: string | string[] | Document | '*'): mongodb.Document | undefined;
|
|
4
|
-
export declare function prepare(dataType: ComplexType, target: mongodb.Document, projection?: FieldsProjection): void;
|
|
3
|
+
export default function prepareProjection(dataType: ComplexType, projection?: string | string[] | Document | '*', scopes?: string[]): mongodb.Document | undefined;
|
|
4
|
+
export declare function prepare(dataType: ComplexType, target: mongodb.Document, projection?: FieldsProjection, scopes?: string[]): void;
|
|
@@ -152,10 +152,16 @@ export interface MongoService {
|
|
|
152
152
|
* @template T - The type of the documents in the collection.
|
|
153
153
|
*/
|
|
154
154
|
export declare class MongoService<T extends mongodb.Document = mongodb.Document> extends ServiceBase {
|
|
155
|
+
protected _dataTypeScope?: string;
|
|
156
|
+
protected _dataTypeScopes?: string[];
|
|
155
157
|
protected _dataType_: Type | string;
|
|
156
158
|
protected _dataType?: ComplexType;
|
|
157
159
|
protected _inputCodecs: Record<string, IsObject.Validator<T>>;
|
|
158
160
|
protected _outputCodecs: Record<string, IsObject.Validator<T>>;
|
|
161
|
+
/**
|
|
162
|
+
* Defines comma delimited scopes for api document
|
|
163
|
+
*/
|
|
164
|
+
scopes?: string;
|
|
159
165
|
/**
|
|
160
166
|
* Represents the name of a collection in MongoDB
|
|
161
167
|
*/
|