@opra/mongodb 0.33.13 → 1.0.0-alpha.10

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.
Files changed (37) hide show
  1. package/cjs/adapter-utils/prepare-filter.js +22 -28
  2. package/cjs/adapter-utils/prepare-key-values.js +4 -3
  3. package/cjs/adapter-utils/prepare-patch.js +2 -1
  4. package/cjs/adapter-utils/prepare-projection.js +40 -39
  5. package/cjs/index.js +1 -2
  6. package/cjs/mongo-adapter.js +71 -1
  7. package/cjs/mongo-collection-service.js +73 -314
  8. package/cjs/mongo-entity-service.js +335 -0
  9. package/cjs/{mongo-array-service.js → mongo-nested-service.js} +252 -244
  10. package/cjs/mongo-service.js +146 -202
  11. package/cjs/mongo-singleton-service.js +29 -125
  12. package/esm/adapter-utils/prepare-filter.js +22 -28
  13. package/esm/adapter-utils/prepare-key-values.js +4 -3
  14. package/esm/adapter-utils/prepare-patch.js +2 -1
  15. package/esm/adapter-utils/prepare-projection.js +39 -38
  16. package/esm/index.js +1 -2
  17. package/esm/mongo-adapter.js +71 -1
  18. package/esm/mongo-collection-service.js +73 -313
  19. package/esm/mongo-entity-service.js +330 -0
  20. package/esm/mongo-nested-service.js +571 -0
  21. package/esm/mongo-service.js +147 -203
  22. package/esm/mongo-singleton-service.js +29 -125
  23. package/package.json +16 -10
  24. package/types/adapter-utils/prepare-filter.d.ts +2 -3
  25. package/types/adapter-utils/prepare-projection.d.ts +4 -13
  26. package/types/index.d.ts +1 -2
  27. package/types/mongo-adapter.d.ts +14 -1
  28. package/types/mongo-collection-service.d.ts +88 -251
  29. package/types/mongo-entity-service.d.ts +149 -0
  30. package/types/mongo-nested-service.d.ts +258 -0
  31. package/types/mongo-service.d.ts +218 -91
  32. package/types/mongo-singleton-service.d.ts +39 -148
  33. package/cjs/types.js +0 -2
  34. package/esm/mongo-array-service.js +0 -563
  35. package/esm/types.js +0 -1
  36. package/types/mongo-array-service.d.ts +0 -409
  37. package/types/types.d.ts +0 -3
@@ -1,17 +1,17 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MongoSingletonService = void 0;
4
- const mongodb_1 = require("mongodb");
5
4
  const common_1 = require("@opra/common");
5
+ const mongodb_1 = require("mongodb");
6
6
  const mongo_adapter_js_1 = require("./mongo-adapter.js");
7
- const mongo_service_js_1 = require("./mongo-service.js");
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 mongo_service_js_1.MongoService {
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 {DTO<T>} input - The partial input to create the document with.
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
- await this._getDocumentFilter(info),
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.findOne({ ...options, pick: ['_id'], omit: undefined, include: undefined }));
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.FindOptions<T>} [options] - The options for finding the document.
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 findOne(options) {
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
- await this._getDocumentFilter(info),
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 {MongoCollectionService.FindOneOptions} options - The options to customize the query.
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.findOne(options);
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
- await this._getDocumentFilter(info),
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
- await this._getDocumentFilter(info),
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
- 'in': '$in',
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
- return ast.value;
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]: ["$" + left, "$" + ast.right.value] } };
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,40 @@ 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
  };
167
+ default:
168
+ break;
175
169
  }
176
170
  throw new Error(`Unimplemented ComparisonExpression operation (right side is ${ast.right.kind})`);
177
171
  }
178
172
  throw new Error(`${ast.kind} is not implemented yet`);
179
173
  }
180
- const wrapNot = (o, negative) => negative ? { $not: o } : o;
174
+ const wrapNot = (o, negative) => (negative ? { $not: o } : o);
@@ -3,13 +3,14 @@ const defaultPrimaryKey = ['_id'];
3
3
  export default function prepareKeyValues(keyValue, primaryKey) {
4
4
  primaryKey = primaryKey || defaultPrimaryKey;
5
5
  const b = isPlainObject(keyValue);
6
- if (primaryKey.length > 1 && !b)
7
- new TypeError(`Argument "keyValue" must be an object that contains all key values`);
6
+ if (primaryKey.length > 1 && !b) {
7
+ throw new TypeError(`Argument "keyValue" must be an object that contains all key values`);
8
+ }
8
9
  if (primaryKey.length > 1 || b) {
9
10
  return primaryKey.reduce((o, k) => {
10
11
  o[k] = keyValue[k];
11
12
  if (o[k] == null)
12
- new Error(`Value of key "${k}" is required`);
13
+ throw new Error(`Value of key "${k}" is required`);
13
14
  return o;
14
15
  }, {});
15
16
  }
@@ -4,10 +4,11 @@ export default function preparePatch(doc, options) {
4
4
  trg.$set = trg.$set || {};
5
5
  return trg;
6
6
  }
7
- function _preparePatch(src, trg = {}, path, options) {
7
+ function _preparePatch(src, trg, path, options) {
8
8
  let f;
9
9
  let key;
10
10
  let field;
11
+ trg = trg || {};
11
12
  const fieldPrefix = options?.fieldPrefix;
12
13
  for (const [k, v] of Object.entries(src)) {
13
14
  f = k.startsWith('*') ? k.substring(1) : k;
@@ -1,47 +1,48 @@
1
- import { ComplexType, pathToObjectTree } from '@opra/common';
2
- export default function prepareProjection(dataType, options) {
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 pick = options?.pick && pathToObjectTree(options.pick);
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
- _prepareProjection(dataType, out, {
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 _prepareProjection(dataType, target,
17
- // exclusionProjection: boolean,
18
- options) {
19
- // const defaultFields = options?.defaultFields ?? !options?.pick;
20
- const optionsOmit = options?.omit;
21
- const optionsPick = options?.pick;
22
- const optionsInclude = options?.include;
23
- const pickActivated = options?.pickActivated;
24
- for (const [k, f] of dataType.fields.entries()) {
25
- const fieldOmit = optionsOmit?.[k];
26
- const fieldInclude = optionsInclude?.[k];
27
- const fieldPick = optionsPick?.[k];
28
- if (fieldOmit === true ||
29
- !((pickActivated && fieldPick) ||
30
- (!pickActivated && (!f.exclusive || fieldInclude))))
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
- if (f.type instanceof ComplexType &&
33
- (typeof fieldInclude === 'object' ||
34
- typeof fieldPick === 'object' ||
35
- typeof fieldOmit === 'object')) {
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[k] = 1;
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-array-service.js';
3
2
  export * from './mongo-collection-service.js';
3
+ export * from './mongo-nested-service.js';
4
4
  export * from './mongo-service.js';
5
5
  export * from './mongo-singleton-service.js';
6
- export * from './types.js';
@@ -5,9 +5,79 @@ 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 controller = operation.owner;
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 keyParam = operation.parameters.find(p => p.keyParam) || controller.parameters.find(p => p.keyParam);
27
+ const key = keyParam && context.pathParams[String(keyParam.name)];
28
+ const options = {
29
+ filter: context.queryParams.filter,
30
+ };
31
+ return { method: 'delete', key, options };
32
+ }
33
+ case 'Entity.DeleteMany': {
34
+ const options = {
35
+ filter: context.queryParams.filter,
36
+ };
37
+ return { method: 'deleteMany', options };
38
+ }
39
+ case 'Entity.FindMany': {
40
+ const options = {
41
+ filter: context.queryParams.filter,
42
+ projection: context.queryParams.projection,
43
+ count: context.queryParams.count,
44
+ limit: context.queryParams.limit,
45
+ skip: context.queryParams.skip,
46
+ sort: context.queryParams.sort,
47
+ };
48
+ return { method: 'findMany', options };
49
+ }
50
+ case 'Entity.Get': {
51
+ const keyParam = operation.parameters.find(p => p.keyParam) || controller.parameters.find(p => p.keyParam);
52
+ const key = keyParam && context.pathParams[String(keyParam.name)];
53
+ const options = {
54
+ projection: context.queryParams.projection,
55
+ filter: context.queryParams.filter,
56
+ };
57
+ return { method: 'get', key, options };
58
+ }
59
+ case 'Entity.Update': {
60
+ const data = await context.getBody();
61
+ const keyParam = operation.parameters.find(p => p.keyParam) || controller.parameters.find(p => p.keyParam);
62
+ const key = keyParam && context.pathParams[String(keyParam.name)];
63
+ const options = {
64
+ projection: context.queryParams.projection,
65
+ filter: context.queryParams.filter,
66
+ };
67
+ return { method: 'update', key, data, options };
68
+ }
69
+ case 'Entity.UpdateMany': {
70
+ const data = await context.getBody();
71
+ const options = {
72
+ filter: context.queryParams.filter,
73
+ };
74
+ return { method: 'updateMany', data, options };
75
+ }
76
+ default:
77
+ break;
78
+ }
79
+ }
80
+ throw new Error(`This operation is not compatible to MongoDB adapter`);
81
+ }
82
+ MongoAdapter.parseRequest = parseRequest;
13
83
  })(MongoAdapter || (MongoAdapter = {}));