@opra/mongodb 0.33.13 → 1.0.0-alpha.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 +20 -28
- package/cjs/adapter-utils/prepare-projection.js +40 -39
- package/cjs/index.js +1 -2
- package/cjs/mongo-adapter.js +66 -1
- package/cjs/mongo-collection-service.js +72 -313
- package/cjs/mongo-entity-service.js +329 -0
- package/cjs/{mongo-array-service.js → mongo-nested-service.js} +231 -225
- package/cjs/mongo-service.js +124 -183
- package/cjs/mongo-singleton-service.js +28 -124
- package/esm/adapter-utils/prepare-filter.js +20 -28
- package/esm/adapter-utils/prepare-projection.js +39 -38
- package/esm/index.js +1 -2
- package/esm/mongo-adapter.js +66 -1
- package/esm/mongo-collection-service.js +73 -313
- package/esm/mongo-entity-service.js +324 -0
- package/esm/mongo-nested-service.js +569 -0
- package/esm/mongo-service.js +125 -184
- package/esm/mongo-singleton-service.js +29 -125
- package/package.json +7 -6
- package/types/adapter-utils/prepare-filter.d.ts +2 -3
- package/types/adapter-utils/prepare-projection.d.ts +4 -13
- package/types/index.d.ts +1 -2
- package/types/mongo-adapter.d.ts +14 -1
- package/types/mongo-collection-service.d.ts +88 -251
- package/types/mongo-entity-service.d.ts +149 -0
- package/types/mongo-nested-service.d.ts +258 -0
- package/types/mongo-service.d.ts +208 -82
- package/types/mongo-singleton-service.d.ts +39 -148
- package/cjs/types.js +0 -2
- package/esm/mongo-array-service.js +0 -563
- package/esm/types.js +0 -1
- package/types/mongo-array-service.d.ts +0 -409
- package/types/types.d.ts +0 -3
|
@@ -4,14 +4,14 @@ exports.MongoSingletonService = void 0;
|
|
|
4
4
|
const mongodb_1 = require("mongodb");
|
|
5
5
|
const common_1 = require("@opra/common");
|
|
6
6
|
const mongo_adapter_js_1 = require("./mongo-adapter.js");
|
|
7
|
-
const
|
|
7
|
+
const mongo_entity_service_js_1 = require("./mongo-entity-service.js");
|
|
8
8
|
/**
|
|
9
9
|
* A class that provides access to a MongoDB collection, with support for singleton document operations.
|
|
10
10
|
* @class MongoSingletonService
|
|
11
11
|
* @extends MongoService
|
|
12
12
|
* @template T - The type of document stored in the collection
|
|
13
13
|
*/
|
|
14
|
-
class MongoSingletonService extends
|
|
14
|
+
class MongoSingletonService extends mongo_entity_service_js_1.MongoEntityService {
|
|
15
15
|
/**
|
|
16
16
|
* Constructs a new instance
|
|
17
17
|
*
|
|
@@ -21,14 +21,12 @@ class MongoSingletonService extends mongo_service_js_1.MongoService {
|
|
|
21
21
|
*/
|
|
22
22
|
constructor(dataType, options) {
|
|
23
23
|
super(dataType, options);
|
|
24
|
-
this.collectionKey = this.collectionKey || options?.collectionKey || '_id';
|
|
25
24
|
this._id = this._id || options?._id || new mongodb_1.ObjectId('655608925cad472b75fc6485');
|
|
26
|
-
this.$documentFilter = this.$documentFilter || options?.documentFilter;
|
|
27
|
-
this.$interceptor = this.$interceptor || options?.interceptor;
|
|
28
25
|
}
|
|
29
26
|
/**
|
|
30
27
|
* Asserts the existence of a resource based on the given options.
|
|
31
28
|
*
|
|
29
|
+
* @param {MongoSingletonService.ExistsOptions<T>} [options]
|
|
32
30
|
* @returns {Promise<void>} A Promise that resolves when the resource exists.
|
|
33
31
|
* @throws {ResourceNotAvailableError} If the resource does not exist.
|
|
34
32
|
*/
|
|
@@ -39,37 +37,23 @@ class MongoSingletonService extends mongo_service_js_1.MongoService {
|
|
|
39
37
|
/**
|
|
40
38
|
* Creates the document in the database.
|
|
41
39
|
*
|
|
42
|
-
* @param {
|
|
40
|
+
* @param {PartialDTO<T>} input - The partial input to create the document with.
|
|
43
41
|
* @param {MongoSingletonService.CreateOptions} [options] - The options for creating the document.
|
|
44
42
|
* @return {Promise<PartialDTO<T>>} A promise that resolves to the partial output of the created document.
|
|
45
43
|
* @throws {Error} Throws an error if an unknown error occurs while creating the document.
|
|
46
44
|
*/
|
|
47
45
|
async create(input, options) {
|
|
46
|
+
input._id = this._id;
|
|
48
47
|
const info = {
|
|
49
48
|
crud: 'create',
|
|
50
49
|
method: 'create',
|
|
50
|
+
byId: false,
|
|
51
|
+
documentId: this._id,
|
|
51
52
|
input,
|
|
52
53
|
options,
|
|
53
54
|
};
|
|
54
55
|
return this._intercept(() => this._create(input, options), info);
|
|
55
56
|
}
|
|
56
|
-
async _create(input, options) {
|
|
57
|
-
const encode = this.getEncoder('create');
|
|
58
|
-
const doc = encode(input);
|
|
59
|
-
doc._id = this._id;
|
|
60
|
-
const r = await this.__insertOne(doc, options);
|
|
61
|
-
if (r.insertedId) {
|
|
62
|
-
if (!options)
|
|
63
|
-
return doc;
|
|
64
|
-
const out = await this._findOne(options);
|
|
65
|
-
if (out)
|
|
66
|
-
return out;
|
|
67
|
-
if (!out)
|
|
68
|
-
throw new common_1.ResourceNotAvailableError(this.getResourceName());
|
|
69
|
-
}
|
|
70
|
-
/* istanbul ignore next */
|
|
71
|
-
throw new common_1.InternalServerError(`Unknown error while creating document for "${this.getResourceName()}"`);
|
|
72
|
-
}
|
|
73
57
|
/**
|
|
74
58
|
* Deletes a record from the database
|
|
75
59
|
*
|
|
@@ -80,77 +64,51 @@ class MongoSingletonService extends mongo_service_js_1.MongoService {
|
|
|
80
64
|
const info = {
|
|
81
65
|
crud: 'delete',
|
|
82
66
|
method: 'delete',
|
|
67
|
+
byId: true,
|
|
68
|
+
documentId: this._id,
|
|
83
69
|
options,
|
|
84
70
|
};
|
|
85
71
|
return this._intercept(async () => {
|
|
86
|
-
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([
|
|
87
|
-
|
|
88
|
-
options?.filter
|
|
89
|
-
]);
|
|
90
|
-
return this._delete({ ...options, filter });
|
|
72
|
+
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([await this._getDocumentFilter(info), options?.filter]);
|
|
73
|
+
return this._delete(this._id, { ...options, filter });
|
|
91
74
|
}, info);
|
|
92
75
|
}
|
|
93
|
-
async _delete(options) {
|
|
94
|
-
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([
|
|
95
|
-
{ _id: this._id },
|
|
96
|
-
options?.filter
|
|
97
|
-
]);
|
|
98
|
-
const r = await this.__deleteOne(filter, options);
|
|
99
|
-
return r.deletedCount;
|
|
100
|
-
}
|
|
101
76
|
/**
|
|
102
77
|
* Checks if the document exists in the database.
|
|
103
78
|
*
|
|
104
79
|
* @return {Promise<boolean>} - A promise that resolves to a boolean value indicating if the document exists.
|
|
105
80
|
*/
|
|
106
81
|
async exists(options) {
|
|
107
|
-
return !!(await this.
|
|
82
|
+
return !!(await this.find({ ...options, projection: ['_id'], skip: undefined }));
|
|
108
83
|
}
|
|
109
84
|
/**
|
|
110
85
|
* Fetches the document if it exists. Returns undefined if not found.
|
|
111
86
|
*
|
|
112
|
-
* @param {MongoSingletonService.
|
|
87
|
+
* @param {MongoSingletonService.FindOneOptions<T>} [options] - The options for finding the document.
|
|
113
88
|
* @returns {Promise<PartialDTO<T> | undefined>} - A promise that resolves to the found document or undefined if not found.
|
|
114
89
|
*/
|
|
115
|
-
async
|
|
90
|
+
async find(options) {
|
|
116
91
|
const info = {
|
|
117
92
|
crud: 'read',
|
|
118
93
|
method: 'findOne',
|
|
94
|
+
byId: true,
|
|
95
|
+
documentId: this._id,
|
|
119
96
|
options,
|
|
120
97
|
};
|
|
121
98
|
return this._intercept(async () => {
|
|
122
|
-
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([
|
|
123
|
-
|
|
124
|
-
options?.filter
|
|
125
|
-
]);
|
|
126
|
-
return this._findOne({ ...options, filter });
|
|
99
|
+
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([await this._getDocumentFilter(info), options?.filter]);
|
|
100
|
+
return this._findById(this._id, { ...options, filter });
|
|
127
101
|
}, info);
|
|
128
102
|
}
|
|
129
|
-
async _findOne(options) {
|
|
130
|
-
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([
|
|
131
|
-
{ _id: this._id },
|
|
132
|
-
options?.filter
|
|
133
|
-
]);
|
|
134
|
-
const mongoOptions = {
|
|
135
|
-
...options,
|
|
136
|
-
projection: mongo_adapter_js_1.MongoAdapter.prepareProjection(this.getDataType(), options),
|
|
137
|
-
sort: undefined,
|
|
138
|
-
skip: undefined,
|
|
139
|
-
limit: undefined
|
|
140
|
-
};
|
|
141
|
-
const decoder = this.getDecoder();
|
|
142
|
-
const out = await this.__findOne(filter, mongoOptions);
|
|
143
|
-
return out ? decoder(out) : undefined;
|
|
144
|
-
}
|
|
145
103
|
/**
|
|
146
104
|
* Fetches the document from the Mongo collection service. Throws error if not found.
|
|
147
105
|
*
|
|
148
|
-
* @param {
|
|
106
|
+
* @param {MongoSingletonService.FindOneOptions<T>} options - The options to customize the query.
|
|
149
107
|
* @return {Promise<PartialDTO<T>>} - A promise that resolves to the fetched document.
|
|
150
108
|
* @throws {ResourceNotAvailableError} - If the document is not found in the collection.
|
|
151
109
|
*/
|
|
152
110
|
async get(options) {
|
|
153
|
-
const out = await this.
|
|
111
|
+
const out = await this.find(options);
|
|
154
112
|
if (!out)
|
|
155
113
|
throw new common_1.ResourceNotAvailableError(this.getResourceName());
|
|
156
114
|
return out;
|
|
@@ -167,34 +125,16 @@ class MongoSingletonService extends mongo_service_js_1.MongoService {
|
|
|
167
125
|
const info = {
|
|
168
126
|
crud: 'update',
|
|
169
127
|
method: 'update',
|
|
128
|
+
byId: true,
|
|
129
|
+
documentId: this._id,
|
|
170
130
|
input,
|
|
171
131
|
options,
|
|
172
132
|
};
|
|
173
133
|
return this._intercept(async () => {
|
|
174
|
-
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([
|
|
175
|
-
|
|
176
|
-
options?.filter
|
|
177
|
-
]);
|
|
178
|
-
return this._updateOnly(input, { ...options, filter });
|
|
134
|
+
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([await this._getDocumentFilter(info), options?.filter]);
|
|
135
|
+
return this._updateOnly(this._id, input, { ...options, filter });
|
|
179
136
|
}, info);
|
|
180
137
|
}
|
|
181
|
-
async _updateOnly(input, options) {
|
|
182
|
-
const encode = this.getEncoder('update');
|
|
183
|
-
const doc = encode(input);
|
|
184
|
-
const patch = mongo_adapter_js_1.MongoAdapter.preparePatch(doc);
|
|
185
|
-
const mongoOptions = {
|
|
186
|
-
...options,
|
|
187
|
-
includeResultMetadata: false,
|
|
188
|
-
upsert: undefined,
|
|
189
|
-
projection: mongo_adapter_js_1.MongoAdapter.prepareProjection(this.getDataType(), options),
|
|
190
|
-
};
|
|
191
|
-
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([
|
|
192
|
-
{ _id: this._id },
|
|
193
|
-
options?.filter
|
|
194
|
-
]);
|
|
195
|
-
const r = await this.__updateOne(filter, patch, mongoOptions);
|
|
196
|
-
return r.modifiedCount;
|
|
197
|
-
}
|
|
198
138
|
/**
|
|
199
139
|
* Updates a document in the MongoDB collection.
|
|
200
140
|
*
|
|
@@ -207,51 +147,15 @@ class MongoSingletonService extends mongo_service_js_1.MongoService {
|
|
|
207
147
|
const info = {
|
|
208
148
|
crud: 'update',
|
|
209
149
|
method: 'update',
|
|
150
|
+
byId: true,
|
|
151
|
+
documentId: this._id,
|
|
210
152
|
input,
|
|
211
153
|
options,
|
|
212
154
|
};
|
|
213
155
|
return this._intercept(async () => {
|
|
214
|
-
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([
|
|
215
|
-
|
|
216
|
-
options?.filter
|
|
217
|
-
]);
|
|
218
|
-
return this._update(input, { ...options, filter });
|
|
156
|
+
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([await this._getDocumentFilter(info), options?.filter]);
|
|
157
|
+
return this._update(this._id, input, { ...options, filter });
|
|
219
158
|
}, info);
|
|
220
159
|
}
|
|
221
|
-
async _update(input, options) {
|
|
222
|
-
const encode = this.getEncoder('update');
|
|
223
|
-
const doc = encode(input);
|
|
224
|
-
const patch = mongo_adapter_js_1.MongoAdapter.preparePatch(doc);
|
|
225
|
-
const mongoOptions = {
|
|
226
|
-
...options,
|
|
227
|
-
includeResultMetadata: false,
|
|
228
|
-
upsert: undefined,
|
|
229
|
-
projection: mongo_adapter_js_1.MongoAdapter.prepareProjection(this.getDataType(), options),
|
|
230
|
-
};
|
|
231
|
-
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([
|
|
232
|
-
{ _id: this._id },
|
|
233
|
-
options?.filter
|
|
234
|
-
]);
|
|
235
|
-
const decoder = this.getDecoder();
|
|
236
|
-
const out = await this.__findOneAndUpdate(filter, patch, mongoOptions);
|
|
237
|
-
return out ? decoder(out) : undefined;
|
|
238
|
-
}
|
|
239
|
-
/**
|
|
240
|
-
* Retrieves the common filter used for querying the document.
|
|
241
|
-
* This method is mostly used for security issues like securing multi-tenant applications.
|
|
242
|
-
*
|
|
243
|
-
* @protected
|
|
244
|
-
* @returns {FilterInput | Promise<FilterInput> | undefined} The common filter or a Promise
|
|
245
|
-
* that resolves to the common filter, or undefined if not available.
|
|
246
|
-
*/
|
|
247
|
-
_getDocumentFilter(args) {
|
|
248
|
-
return typeof this.$documentFilter === 'function' ?
|
|
249
|
-
this.$documentFilter(args, this) : this.$documentFilter;
|
|
250
|
-
}
|
|
251
|
-
async _intercept(callback, args) {
|
|
252
|
-
if (this.$interceptor)
|
|
253
|
-
return this.$interceptor(callback, args, this);
|
|
254
|
-
return callback();
|
|
255
|
-
}
|
|
256
160
|
}
|
|
257
161
|
exports.MongoSingletonService = MongoSingletonService;
|
|
@@ -6,7 +6,7 @@ const opMap = {
|
|
|
6
6
|
'>=': '$gte',
|
|
7
7
|
'<': '$lt',
|
|
8
8
|
'<=': '$lte',
|
|
9
|
-
|
|
9
|
+
in: '$in',
|
|
10
10
|
'!in': '$nin',
|
|
11
11
|
};
|
|
12
12
|
/**
|
|
@@ -61,9 +61,7 @@ export default function prepareFilter(filters, options) {
|
|
|
61
61
|
}
|
|
62
62
|
i++;
|
|
63
63
|
}
|
|
64
|
-
return i
|
|
65
|
-
? (options?.fieldPrefix ? addPrefix(out, options.fieldPrefix) : out)
|
|
66
|
-
: undefined;
|
|
64
|
+
return i ? (options?.fieldPrefix ? addPrefix(out, options.fieldPrefix) : out) : undefined;
|
|
67
65
|
}
|
|
68
66
|
function addPrefix(source, prefix) {
|
|
69
67
|
if (typeof source !== 'object')
|
|
@@ -82,10 +80,8 @@ function addPrefix(source, prefix) {
|
|
|
82
80
|
function prepareFilterAst(ast, negative) {
|
|
83
81
|
if (!ast)
|
|
84
82
|
return;
|
|
85
|
-
if (ast instanceof OpraFilter.QualifiedIdentifier
|
|
86
|
-
|
|
87
|
-
}
|
|
88
|
-
if (ast instanceof OpraFilter.NumberLiteral ||
|
|
83
|
+
if (ast instanceof OpraFilter.QualifiedIdentifier ||
|
|
84
|
+
ast instanceof OpraFilter.NumberLiteral ||
|
|
89
85
|
ast instanceof OpraFilter.StringLiteral ||
|
|
90
86
|
ast instanceof OpraFilter.BooleanLiteral ||
|
|
91
87
|
ast instanceof OpraFilter.NullLiteral ||
|
|
@@ -100,9 +96,7 @@ function prepareFilterAst(ast, negative) {
|
|
|
100
96
|
return prepareFilterAst(ast.expression, !negative);
|
|
101
97
|
}
|
|
102
98
|
if (ast instanceof OpraFilter.LogicalExpression) {
|
|
103
|
-
const items = ast.items
|
|
104
|
-
.map(x => prepareFilterAst(x, negative))
|
|
105
|
-
.filter(x => x != null);
|
|
99
|
+
const items = ast.items.map(x => prepareFilterAst(x, negative)).filter(x => x != null);
|
|
106
100
|
if (ast.op === 'or')
|
|
107
101
|
return { $or: items };
|
|
108
102
|
return { $and: items };
|
|
@@ -115,15 +109,13 @@ function prepareFilterAst(ast, negative) {
|
|
|
115
109
|
if (ast.right instanceof OpraFilter.QualifiedIdentifier) {
|
|
116
110
|
const op = opMap[ast.op];
|
|
117
111
|
if (op)
|
|
118
|
-
return { $expr: { [op]: [
|
|
112
|
+
return { $expr: { [op]: ['$' + left, '$' + ast.right.value] } };
|
|
119
113
|
/* istanbul ignore next */
|
|
120
114
|
throw new Error(`Invalid filter query.`);
|
|
121
115
|
}
|
|
122
116
|
let right = prepareFilterAst(ast.right);
|
|
123
117
|
if (right == null) {
|
|
124
|
-
const op = ast.op === '='
|
|
125
|
-
? (negative ? '!=' : '=')
|
|
126
|
-
: (negative ? '=' : '!=');
|
|
118
|
+
const op = ast.op === '=' ? (negative ? '!=' : '=') : negative ? '=' : '!=';
|
|
127
119
|
if (op === '=')
|
|
128
120
|
return { $or: [{ [left]: null }, { [left]: { $exists: false } }] };
|
|
129
121
|
if (op === '!=')
|
|
@@ -143,38 +135,38 @@ function prepareFilterAst(ast, negative) {
|
|
|
143
135
|
[left]: wrapNot({
|
|
144
136
|
$text: {
|
|
145
137
|
$search: '\\"' + right.replace(/\\"/, '"') + '\\"',
|
|
146
|
-
$caseSensitive: true
|
|
147
|
-
}
|
|
148
|
-
}, negative)
|
|
138
|
+
$caseSensitive: true,
|
|
139
|
+
},
|
|
140
|
+
}, negative),
|
|
149
141
|
};
|
|
150
142
|
case 'ilike':
|
|
151
143
|
return {
|
|
152
144
|
[left]: wrapNot({
|
|
153
145
|
$text: {
|
|
154
|
-
$search: '\\"' + right.replace(/\\"/, '"') + '\\"'
|
|
155
|
-
}
|
|
156
|
-
}, negative)
|
|
146
|
+
$search: '\\"' + right.replace(/\\"/, '"') + '\\"',
|
|
147
|
+
},
|
|
148
|
+
}, negative),
|
|
157
149
|
};
|
|
158
150
|
case '!like':
|
|
159
151
|
return {
|
|
160
152
|
[left]: wrapNot({
|
|
161
153
|
$text: {
|
|
162
154
|
$search: '\\"' + right.replace(/\\"/, '"') + '\\"',
|
|
163
|
-
$caseSensitive: true
|
|
164
|
-
}
|
|
165
|
-
}, !negative)
|
|
155
|
+
$caseSensitive: true,
|
|
156
|
+
},
|
|
157
|
+
}, !negative),
|
|
166
158
|
};
|
|
167
159
|
case '!ilike':
|
|
168
160
|
return {
|
|
169
161
|
[left]: wrapNot({
|
|
170
162
|
$text: {
|
|
171
|
-
$search: '\\"' + right.replace(/\\"/, '"') + '\\"'
|
|
172
|
-
}
|
|
173
|
-
}, !negative)
|
|
163
|
+
$search: '\\"' + right.replace(/\\"/, '"') + '\\"',
|
|
164
|
+
},
|
|
165
|
+
}, !negative),
|
|
174
166
|
};
|
|
175
167
|
}
|
|
176
168
|
throw new Error(`Unimplemented ComparisonExpression operation (right side is ${ast.right.kind})`);
|
|
177
169
|
}
|
|
178
170
|
throw new Error(`${ast.kind} is not implemented yet`);
|
|
179
171
|
}
|
|
180
|
-
const wrapNot = (o, negative) => negative ? { $not: o } : o;
|
|
172
|
+
const wrapNot = (o, negative) => (negative ? { $not: o } : o);
|
|
@@ -1,47 +1,48 @@
|
|
|
1
|
-
import { ComplexType,
|
|
2
|
-
export default function prepareProjection(dataType,
|
|
1
|
+
import { ComplexType, parseFieldsProjection } from '@opra/common';
|
|
2
|
+
export default function prepareProjection(dataType, projection) {
|
|
3
|
+
if (projection && typeof projection === 'object' && !Array.isArray(projection))
|
|
4
|
+
return projection;
|
|
3
5
|
const out = {};
|
|
4
|
-
const
|
|
5
|
-
const include = options?.include && pathToObjectTree(options.include);
|
|
6
|
-
const omit = options?.omit && pathToObjectTree(options.omit);
|
|
6
|
+
const projection_ = typeof projection === 'string' || Array.isArray(projection) ? parseFieldsProjection(projection) : projection;
|
|
7
7
|
// const exclusionProjection = !pick && !!omit;
|
|
8
|
-
|
|
9
|
-
pickActivated: !!pick,
|
|
10
|
-
pick,
|
|
11
|
-
include,
|
|
12
|
-
omit
|
|
13
|
-
});
|
|
8
|
+
prepare(dataType, out, projection_);
|
|
14
9
|
return Object.keys(out).length ? out : undefined;
|
|
15
10
|
}
|
|
16
|
-
export function
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
for (
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
11
|
+
export function prepare(dataType, target, projection) {
|
|
12
|
+
const defaultFields = !projection || !Object.values(projection).find(p => !p.sign);
|
|
13
|
+
const projectionKeys = projection && Object.keys(projection).map(x => x.toLowerCase());
|
|
14
|
+
const projectionKeysSet = new Set(projectionKeys);
|
|
15
|
+
let fieldName;
|
|
16
|
+
let field;
|
|
17
|
+
let k;
|
|
18
|
+
/** Add fields from data type */
|
|
19
|
+
for (field of dataType.fields.values()) {
|
|
20
|
+
fieldName = field.name;
|
|
21
|
+
k = fieldName.toLowerCase();
|
|
22
|
+
projectionKeysSet.delete(k);
|
|
23
|
+
const p = projection?.[k];
|
|
24
|
+
if (
|
|
25
|
+
/** Ignore if field is omitted */
|
|
26
|
+
p?.sign === '-' ||
|
|
27
|
+
/** Ignore if default fields and field is not in projection */
|
|
28
|
+
(!defaultFields && !p) ||
|
|
29
|
+
/** Ignore if default fields enabled and fields is exclusive */
|
|
30
|
+
(defaultFields && field.exclusive && !p)) {
|
|
31
31
|
continue;
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
target[k] = {};
|
|
37
|
-
_prepareProjection(f.type, target[k], {
|
|
38
|
-
pickActivated: fieldPick != null && fieldPick !== true,
|
|
39
|
-
include: typeof fieldInclude === 'object' ? fieldInclude : undefined,
|
|
40
|
-
pick: typeof fieldPick === 'object' ? fieldPick : undefined,
|
|
41
|
-
omit: typeof fieldOmit === 'object' ? fieldOmit : undefined
|
|
42
|
-
});
|
|
32
|
+
}
|
|
33
|
+
if (field.type instanceof ComplexType && typeof p?.projection === 'object') {
|
|
34
|
+
target[fieldName] = {};
|
|
35
|
+
prepare(field.type, target[fieldName], p.projection);
|
|
43
36
|
continue;
|
|
44
37
|
}
|
|
45
|
-
target[
|
|
38
|
+
target[fieldName] = 1;
|
|
39
|
+
}
|
|
40
|
+
/** Add additional fields */
|
|
41
|
+
if (dataType.additionalFields) {
|
|
42
|
+
for (k of projectionKeysSet.values()) {
|
|
43
|
+
const n = projectionKeysSet[k];
|
|
44
|
+
if (n?.sign !== '-')
|
|
45
|
+
target[k] = 1;
|
|
46
|
+
}
|
|
46
47
|
}
|
|
47
48
|
}
|
package/esm/index.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
export * from './mongo-adapter.js';
|
|
2
|
-
export * from './mongo-
|
|
2
|
+
export * from './mongo-nested-service.js';
|
|
3
3
|
export * from './mongo-collection-service.js';
|
|
4
4
|
export * from './mongo-service.js';
|
|
5
5
|
export * from './mongo-singleton-service.js';
|
|
6
|
-
export * from './types.js';
|
package/esm/mongo-adapter.js
CHANGED
|
@@ -5,9 +5,74 @@ import _prepareProjection from './adapter-utils/prepare-projection.js';
|
|
|
5
5
|
import _prepareSort from './adapter-utils/prepare-sort.js';
|
|
6
6
|
export var MongoAdapter;
|
|
7
7
|
(function (MongoAdapter) {
|
|
8
|
-
MongoAdapter.prepareKeyValues = _prepareKeyValues;
|
|
9
8
|
MongoAdapter.prepareFilter = _prepareFilter;
|
|
9
|
+
MongoAdapter.prepareKeyValues = _prepareKeyValues;
|
|
10
10
|
MongoAdapter.preparePatch = _preparePatch;
|
|
11
11
|
MongoAdapter.prepareProjection = _prepareProjection;
|
|
12
12
|
MongoAdapter.prepareSort = _prepareSort;
|
|
13
|
+
async function parseRequest(context) {
|
|
14
|
+
const { operation } = context;
|
|
15
|
+
if (operation.composition?.startsWith('Entity.') && operation.compositionOptions?.type) {
|
|
16
|
+
const { compositionOptions } = operation;
|
|
17
|
+
switch (operation.composition) {
|
|
18
|
+
case 'Entity.Create': {
|
|
19
|
+
const data = await context.getBody();
|
|
20
|
+
const options = {
|
|
21
|
+
projection: context.queryParams.projection,
|
|
22
|
+
};
|
|
23
|
+
return { method: 'create', data, options };
|
|
24
|
+
}
|
|
25
|
+
case 'Entity.Delete': {
|
|
26
|
+
const key = context.pathParams[compositionOptions.keyParameter];
|
|
27
|
+
const options = {
|
|
28
|
+
filter: context.queryParams.filter,
|
|
29
|
+
};
|
|
30
|
+
return { method: 'delete', key, options };
|
|
31
|
+
}
|
|
32
|
+
case 'Entity.DeleteMany': {
|
|
33
|
+
const options = {
|
|
34
|
+
filter: context.queryParams.filter,
|
|
35
|
+
};
|
|
36
|
+
return { method: 'deleteMany', options };
|
|
37
|
+
}
|
|
38
|
+
case 'Entity.FindMany': {
|
|
39
|
+
const options = {
|
|
40
|
+
filter: context.queryParams.filter,
|
|
41
|
+
projection: context.queryParams.projection,
|
|
42
|
+
count: context.queryParams.count,
|
|
43
|
+
limit: context.queryParams.limit,
|
|
44
|
+
skip: context.queryParams.skip,
|
|
45
|
+
sort: context.queryParams.sort,
|
|
46
|
+
};
|
|
47
|
+
return { method: 'findMany', options };
|
|
48
|
+
}
|
|
49
|
+
case 'Entity.Get': {
|
|
50
|
+
const key = context.pathParams[compositionOptions.keyParameter];
|
|
51
|
+
const options = {
|
|
52
|
+
projection: context.queryParams.projection,
|
|
53
|
+
filter: context.queryParams.filter,
|
|
54
|
+
};
|
|
55
|
+
return { method: 'get', key, options };
|
|
56
|
+
}
|
|
57
|
+
case 'Entity.Update': {
|
|
58
|
+
const data = await context.getBody();
|
|
59
|
+
const key = context.pathParams[compositionOptions.keyParameter];
|
|
60
|
+
const options = {
|
|
61
|
+
projection: context.queryParams.projection,
|
|
62
|
+
filter: context.queryParams.filter,
|
|
63
|
+
};
|
|
64
|
+
return { method: 'update', key, data, options };
|
|
65
|
+
}
|
|
66
|
+
case 'Entity.UpdateMany': {
|
|
67
|
+
const data = await context.getBody();
|
|
68
|
+
const options = {
|
|
69
|
+
filter: context.queryParams.filter,
|
|
70
|
+
};
|
|
71
|
+
return { method: 'updateMany', data, options };
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
throw new Error(`This operation is not compatible to MongoDB adapter`);
|
|
76
|
+
}
|
|
77
|
+
MongoAdapter.parseRequest = parseRequest;
|
|
13
78
|
})(MongoAdapter || (MongoAdapter = {}));
|