@opra/mongodb 0.31.4 → 0.31.5
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/{transform-filter.js → adapter-utils/prepare-filter.js} +22 -9
- package/cjs/adapter-utils/prepare-key-values.js +21 -0
- package/cjs/{transform-patch.js → adapter-utils/prepare-patch.js} +5 -5
- package/cjs/{transform-projection.js → adapter-utils/prepare-projection.js} +11 -11
- package/cjs/{transform-sort.js → adapter-utils/prepare-sort.js} +2 -2
- package/cjs/index.js +3 -4
- package/cjs/mongo-adapter.js +10 -100
- package/cjs/mongo-collection-service.js +131 -0
- package/cjs/{mongo-entity-service-base.js → mongo-service.js} +47 -69
- package/cjs/mongo-singleton-service.js +88 -0
- package/esm/{transform-filter.js → adapter-utils/prepare-filter.js} +21 -8
- package/esm/adapter-utils/prepare-key-values.js +17 -0
- package/esm/{transform-patch.js → adapter-utils/prepare-patch.js} +4 -4
- package/esm/{transform-projection.js → adapter-utils/prepare-projection.js} +7 -7
- package/esm/{transform-sort.js → adapter-utils/prepare-sort.js} +1 -1
- package/esm/index.js +3 -4
- package/esm/mongo-adapter.js +10 -100
- package/esm/mongo-collection-service.js +126 -0
- package/esm/{mongo-entity-service-base.js → mongo-service.js} +45 -67
- package/esm/mongo-singleton-service.js +83 -0
- package/package.json +4 -7
- package/types/adapter-utils/prepare-filter.d.ts +4 -0
- package/types/adapter-utils/prepare-key-values.d.ts +1 -0
- package/types/adapter-utils/prepare-patch.d.ts +1 -0
- package/types/adapter-utils/prepare-projection.d.ts +9 -0
- package/types/adapter-utils/prepare-sort.d.ts +2 -0
- package/types/index.d.ts +3 -4
- package/types/mongo-adapter.d.ts +10 -19
- package/types/mongo-collection-service.d.ts +70 -0
- package/types/mongo-service.d.ts +39 -0
- package/types/mongo-singleton-service.d.ts +48 -0
- package/cjs/mongo-collection.js +0 -79
- package/cjs/mongo-entity-service.js +0 -34
- package/cjs/mongo-singleton.js +0 -44
- package/cjs/transform-key-values.js +0 -14
- package/esm/mongo-collection.js +0 -75
- package/esm/mongo-entity-service.js +0 -30
- package/esm/mongo-singleton.js +0 -40
- package/esm/transform-key-values.js +0 -11
- package/types/mongo-collection.d.ts +0 -32
- package/types/mongo-entity-service-base.d.ts +0 -32
- package/types/mongo-entity-service.d.ts +0 -20
- package/types/mongo-singleton.d.ts +0 -19
- package/types/transform-filter.d.ts +0 -3
- package/types/transform-key-values.d.ts +0 -3
- package/types/transform-patch.d.ts +0 -1
- package/types/transform-projection.d.ts +0 -9
- package/types/transform-sort.d.ts +0 -2
|
@@ -1,49 +1,64 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.MongoService = void 0;
|
|
4
|
+
const common_1 = require("@opra/common");
|
|
4
5
|
const core_1 = require("@opra/core");
|
|
5
|
-
class
|
|
6
|
-
constructor(
|
|
6
|
+
class MongoService extends core_1.ApiService {
|
|
7
|
+
constructor(dataType, options) {
|
|
7
8
|
super();
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
this._collectionName = arg0;
|
|
9
|
+
this._dataType = dataType;
|
|
10
|
+
this.collectionName = options?.collectionName;
|
|
11
11
|
this.db = options?.db;
|
|
12
|
-
this.
|
|
12
|
+
if (!this.collectionName) {
|
|
13
|
+
if (typeof dataType === 'string')
|
|
14
|
+
this.collectionName = dataType;
|
|
15
|
+
if (typeof dataType === 'function') {
|
|
16
|
+
const metadata = Reflect.getMetadata(common_1.DATATYPE_METADATA, dataType);
|
|
17
|
+
if (metadata)
|
|
18
|
+
this.collectionName = metadata.name;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
this.resourceName = options?.resourceName || this.collectionName;
|
|
22
|
+
}
|
|
23
|
+
forContext(context, options) {
|
|
24
|
+
return super.forContext(context, {
|
|
25
|
+
newInstance: options?.newInstance ||
|
|
26
|
+
(options?.db && this.db !== options?.db) ||
|
|
27
|
+
(options?.session && this.session !== options?.session)
|
|
28
|
+
});
|
|
13
29
|
}
|
|
14
|
-
async
|
|
30
|
+
async _rawInsertOne(doc, options) {
|
|
15
31
|
const db = await this.getDatabase();
|
|
16
32
|
const collection = await this.getCollection(db);
|
|
17
33
|
options = {
|
|
18
34
|
...options,
|
|
19
|
-
limit: undefined,
|
|
20
35
|
session: options?.session || this.session
|
|
21
36
|
};
|
|
22
37
|
try {
|
|
23
|
-
return await collection.
|
|
38
|
+
return await collection.insertOne(doc, options);
|
|
24
39
|
}
|
|
25
40
|
catch (e) {
|
|
26
41
|
await this._onError(e);
|
|
27
42
|
throw e;
|
|
28
43
|
}
|
|
29
44
|
}
|
|
30
|
-
async
|
|
45
|
+
async _rawCountDocuments(filter, options) {
|
|
31
46
|
const db = await this.getDatabase();
|
|
32
47
|
const collection = await this.getCollection(db);
|
|
33
48
|
options = {
|
|
34
49
|
...options,
|
|
50
|
+
limit: undefined,
|
|
35
51
|
session: options?.session || this.session
|
|
36
52
|
};
|
|
37
53
|
try {
|
|
38
|
-
|
|
39
|
-
return r.deletedCount;
|
|
54
|
+
return await collection.countDocuments(filter, options) || 0;
|
|
40
55
|
}
|
|
41
56
|
catch (e) {
|
|
42
57
|
await this._onError(e);
|
|
43
58
|
throw e;
|
|
44
59
|
}
|
|
45
60
|
}
|
|
46
|
-
async
|
|
61
|
+
async _rawDeleteOne(filter, options) {
|
|
47
62
|
const db = await this.getDatabase();
|
|
48
63
|
const collection = await this.getCollection(db);
|
|
49
64
|
options = {
|
|
@@ -51,105 +66,74 @@ class MongoEntityServiceBase extends core_1.ApiService {
|
|
|
51
66
|
session: options?.session || this.session
|
|
52
67
|
};
|
|
53
68
|
try {
|
|
54
|
-
|
|
55
|
-
return r.deletedCount;
|
|
69
|
+
return await collection.deleteOne(filter, options);
|
|
56
70
|
}
|
|
57
71
|
catch (e) {
|
|
58
72
|
await this._onError(e);
|
|
59
73
|
throw e;
|
|
60
74
|
}
|
|
61
75
|
}
|
|
62
|
-
async
|
|
76
|
+
async _rawDeleteMany(filter, options) {
|
|
63
77
|
const db = await this.getDatabase();
|
|
64
78
|
const collection = await this.getCollection(db);
|
|
65
79
|
options = {
|
|
66
80
|
...options,
|
|
67
81
|
session: options?.session || this.session
|
|
68
82
|
};
|
|
69
|
-
let out;
|
|
70
83
|
try {
|
|
71
|
-
|
|
84
|
+
return await collection.deleteMany(filter, options);
|
|
72
85
|
}
|
|
73
86
|
catch (e) {
|
|
74
87
|
await this._onError(e);
|
|
75
88
|
throw e;
|
|
76
89
|
}
|
|
77
|
-
return out;
|
|
78
90
|
}
|
|
79
|
-
async
|
|
91
|
+
async _rawFindOne(filter, options) {
|
|
80
92
|
const db = await this.getDatabase();
|
|
81
93
|
const collection = await this.getCollection(db);
|
|
82
94
|
options = {
|
|
83
95
|
...options,
|
|
84
|
-
limit: options?.limit || this.defaultLimit,
|
|
85
96
|
session: options?.session || this.session
|
|
86
97
|
};
|
|
87
|
-
const out = [];
|
|
88
|
-
let cursor;
|
|
89
98
|
try {
|
|
90
|
-
|
|
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
|
-
}
|
|
99
|
+
return await collection.findOne(filter, options);
|
|
97
100
|
}
|
|
98
101
|
catch (e) {
|
|
99
102
|
await this._onError(e);
|
|
100
103
|
throw e;
|
|
101
104
|
}
|
|
102
|
-
finally {
|
|
103
|
-
if (cursor)
|
|
104
|
-
await cursor.close();
|
|
105
|
-
}
|
|
106
|
-
return out;
|
|
107
105
|
}
|
|
108
|
-
async
|
|
106
|
+
async _rawFind(filter, options) {
|
|
109
107
|
const db = await this.getDatabase();
|
|
110
108
|
const collection = await this.getCollection(db);
|
|
111
|
-
let out;
|
|
112
109
|
options = {
|
|
113
110
|
...options,
|
|
114
111
|
session: options?.session || this.session
|
|
115
112
|
};
|
|
116
113
|
try {
|
|
117
|
-
|
|
118
|
-
if (r.insertedId)
|
|
119
|
-
out = await collection.findOne({ _id: r.insertedId }, options);
|
|
114
|
+
return collection.find(filter, options);
|
|
120
115
|
}
|
|
121
116
|
catch (e) {
|
|
122
117
|
await this._onError(e);
|
|
123
118
|
throw e;
|
|
124
119
|
}
|
|
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
120
|
}
|
|
131
|
-
async
|
|
121
|
+
async _rawUpdateOne(filter, doc, options) {
|
|
132
122
|
const db = await this.getDatabase();
|
|
133
123
|
const collection = await this.getCollection(db);
|
|
134
|
-
let out;
|
|
135
124
|
options = {
|
|
136
125
|
...options,
|
|
137
126
|
session: options?.session || this.session
|
|
138
127
|
};
|
|
139
128
|
try {
|
|
140
|
-
|
|
141
|
-
if (r.matchedCount)
|
|
142
|
-
out = await collection.findOne((r.upsertedId ? { _id: r.upsertedId } : filter), options);
|
|
129
|
+
return await collection.updateOne(filter, doc, options);
|
|
143
130
|
}
|
|
144
131
|
catch (e) {
|
|
145
132
|
await this._onError(e);
|
|
146
133
|
throw e;
|
|
147
134
|
}
|
|
148
|
-
if (this.transformData)
|
|
149
|
-
out = this.transformData(out);
|
|
150
|
-
return out;
|
|
151
135
|
}
|
|
152
|
-
async
|
|
136
|
+
async _rawUpdateMany(filter, doc, options) {
|
|
153
137
|
const db = await this.getDatabase();
|
|
154
138
|
const collection = await this.getCollection(db);
|
|
155
139
|
options = {
|
|
@@ -158,20 +142,13 @@ class MongoEntityServiceBase extends core_1.ApiService {
|
|
|
158
142
|
upsert: false
|
|
159
143
|
};
|
|
160
144
|
try {
|
|
161
|
-
|
|
162
|
-
return r.matchedCount;
|
|
145
|
+
return await collection.updateMany(filter, doc, options);
|
|
163
146
|
}
|
|
164
147
|
catch (e) {
|
|
165
148
|
await this._onError(e);
|
|
166
149
|
throw e;
|
|
167
150
|
}
|
|
168
151
|
}
|
|
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
152
|
async _onError(error) {
|
|
176
153
|
if (this.onError)
|
|
177
154
|
await this.onError(error);
|
|
@@ -183,15 +160,16 @@ class MongoEntityServiceBase extends core_1.ApiService {
|
|
|
183
160
|
throw new Error(`Database not set!`);
|
|
184
161
|
return this.db;
|
|
185
162
|
}
|
|
163
|
+
getDataType() {
|
|
164
|
+
return this.context.api.getComplexType(this._dataType);
|
|
165
|
+
}
|
|
186
166
|
async getCollection(db) {
|
|
187
|
-
if (!this._collectionName)
|
|
188
|
-
throw new Error('collectionName is not assigned');
|
|
189
167
|
return db.collection(this.getCollectionName());
|
|
190
168
|
}
|
|
191
169
|
getCollectionName() {
|
|
192
|
-
if (
|
|
193
|
-
|
|
194
|
-
|
|
170
|
+
if (this.collectionName)
|
|
171
|
+
return this.collectionName;
|
|
172
|
+
throw new Error('collectionName is not defined');
|
|
195
173
|
}
|
|
196
174
|
}
|
|
197
|
-
exports.
|
|
175
|
+
exports.MongoService = MongoService;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MongoSingletonService = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const mongodb_1 = require("mongodb");
|
|
6
|
+
const common_1 = require("@opra/common");
|
|
7
|
+
const OpraCommon = tslib_1.__importStar(require("@opra/common"));
|
|
8
|
+
const mongo_adapter_js_1 = require("./mongo-adapter.js");
|
|
9
|
+
const mongo_service_js_1 = require("./mongo-service.js");
|
|
10
|
+
/**
|
|
11
|
+
*
|
|
12
|
+
* @class MongoSingletonService
|
|
13
|
+
*/
|
|
14
|
+
class MongoSingletonService extends mongo_service_js_1.MongoService {
|
|
15
|
+
constructor(dataType, options) {
|
|
16
|
+
super(dataType, options);
|
|
17
|
+
this._id = options?._id || new mongodb_1.ObjectId('655608925cad472b75fc6485');
|
|
18
|
+
}
|
|
19
|
+
get resource() {
|
|
20
|
+
const resource = this.context.request.resource;
|
|
21
|
+
if (resource instanceof OpraCommon.Singleton)
|
|
22
|
+
return resource;
|
|
23
|
+
throw new TypeError(`"${resource}" resource is not a Singleton`);
|
|
24
|
+
}
|
|
25
|
+
async create(doc, options) {
|
|
26
|
+
const r = await this._rawInsertOne({ ...doc, _id: this._id }, options);
|
|
27
|
+
if (r.insertedId) {
|
|
28
|
+
const out = await this.get(options);
|
|
29
|
+
if (out)
|
|
30
|
+
return out;
|
|
31
|
+
}
|
|
32
|
+
/* istanbul ignore next */
|
|
33
|
+
throw new Error('Unknown error while creating document');
|
|
34
|
+
}
|
|
35
|
+
async delete(options) {
|
|
36
|
+
const filter = { _id: this._id };
|
|
37
|
+
const optionsFilter = mongo_adapter_js_1.MongoAdapter.prepareFilter(options?.filter);
|
|
38
|
+
if (optionsFilter)
|
|
39
|
+
filter.$and = [...(Array.isArray(optionsFilter) ? optionsFilter : [optionsFilter])];
|
|
40
|
+
const r = await this._rawDeleteOne(filter, options);
|
|
41
|
+
return r.deletedCount;
|
|
42
|
+
}
|
|
43
|
+
async get(options) {
|
|
44
|
+
const out = await this.find(options);
|
|
45
|
+
if (!out)
|
|
46
|
+
throw new common_1.ResourceNotFoundError(this.resource.name);
|
|
47
|
+
return out;
|
|
48
|
+
}
|
|
49
|
+
async find(options) {
|
|
50
|
+
const filter = { _id: this._id };
|
|
51
|
+
const optionsFilter = mongo_adapter_js_1.MongoAdapter.prepareFilter(options?.filter);
|
|
52
|
+
if (optionsFilter)
|
|
53
|
+
filter.$and = [...(Array.isArray(optionsFilter) ? optionsFilter : [optionsFilter])];
|
|
54
|
+
const mongoOptions = {
|
|
55
|
+
...options,
|
|
56
|
+
projection: mongo_adapter_js_1.MongoAdapter.prepareProjection(this.resource.type, options),
|
|
57
|
+
sort: undefined,
|
|
58
|
+
skip: undefined,
|
|
59
|
+
limit: undefined
|
|
60
|
+
};
|
|
61
|
+
const out = await this._rawFindOne(filter, mongoOptions);
|
|
62
|
+
if (out) {
|
|
63
|
+
if (this.transformData)
|
|
64
|
+
return this.transformData(out);
|
|
65
|
+
return out;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
async update(doc, options) {
|
|
69
|
+
// Prevent upsert with different _id field
|
|
70
|
+
if (options?.upsert)
|
|
71
|
+
doc._id = this._id;
|
|
72
|
+
else
|
|
73
|
+
delete doc._id;
|
|
74
|
+
const patch = mongo_adapter_js_1.MongoAdapter.preparePatch(doc);
|
|
75
|
+
const mongoOptions = {
|
|
76
|
+
...options,
|
|
77
|
+
upsert: undefined
|
|
78
|
+
};
|
|
79
|
+
const filter = { _id: this._id };
|
|
80
|
+
const optionsFilter = mongo_adapter_js_1.MongoAdapter.prepareFilter(options?.filter);
|
|
81
|
+
if (optionsFilter)
|
|
82
|
+
filter.$and = [...(Array.isArray(optionsFilter) ? optionsFilter : [optionsFilter])];
|
|
83
|
+
const r = await this._rawUpdateOne(filter, patch, mongoOptions);
|
|
84
|
+
if (r.matchedCount)
|
|
85
|
+
return await this.get(options);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
exports.MongoSingletonService = MongoSingletonService;
|
|
@@ -10,7 +10,17 @@ const opMap = {
|
|
|
10
10
|
'in': '$in',
|
|
11
11
|
'!in': '$nin',
|
|
12
12
|
};
|
|
13
|
-
export default function
|
|
13
|
+
export default function prepareFilter(filter) {
|
|
14
|
+
if (!filter)
|
|
15
|
+
return;
|
|
16
|
+
if (typeof filter === 'string')
|
|
17
|
+
return prepareFilterAst(OpraFilter.parse(filter));
|
|
18
|
+
else if (filter instanceof OpraFilter.Expression)
|
|
19
|
+
return prepareFilterAst(filter);
|
|
20
|
+
else
|
|
21
|
+
return filter;
|
|
22
|
+
}
|
|
23
|
+
function prepareFilterAst(ast, negative) {
|
|
14
24
|
if (!ast)
|
|
15
25
|
return;
|
|
16
26
|
if (ast instanceof OpraFilter.QualifiedIdentifier) {
|
|
@@ -25,21 +35,24 @@ export default function transformFilter(ast, negative) {
|
|
|
25
35
|
return ast.value;
|
|
26
36
|
}
|
|
27
37
|
if (ast instanceof OpraFilter.ArrayExpression) {
|
|
28
|
-
return ast.items.map(x =>
|
|
38
|
+
return ast.items.map(x => prepareFilterAst(x, negative));
|
|
29
39
|
}
|
|
30
40
|
if (ast instanceof OpraFilter.NegativeExpression) {
|
|
31
|
-
return
|
|
41
|
+
return prepareFilterAst(ast.expression, !negative);
|
|
32
42
|
}
|
|
33
43
|
if (ast instanceof OpraFilter.LogicalExpression) {
|
|
44
|
+
const items = ast.items
|
|
45
|
+
.map(x => prepareFilterAst(x, negative))
|
|
46
|
+
.filter(x => x != null);
|
|
34
47
|
if (ast.op === 'or')
|
|
35
|
-
return { $or:
|
|
36
|
-
return { $and:
|
|
48
|
+
return { $or: items };
|
|
49
|
+
return { $and: items };
|
|
37
50
|
}
|
|
38
51
|
if (ast instanceof OpraFilter.ParenthesizedExpression) {
|
|
39
|
-
return
|
|
52
|
+
return prepareFilterAst(ast.expression, negative);
|
|
40
53
|
}
|
|
41
54
|
if (ast instanceof OpraFilter.ComparisonExpression) {
|
|
42
|
-
const left =
|
|
55
|
+
const left = prepareFilterAst(ast.left, negative);
|
|
43
56
|
if (ast.right instanceof OpraFilter.QualifiedIdentifier) {
|
|
44
57
|
const op = opMap[ast.op];
|
|
45
58
|
if (op)
|
|
@@ -47,7 +60,7 @@ export default function transformFilter(ast, negative) {
|
|
|
47
60
|
/* istanbul ignore next */
|
|
48
61
|
throw new Error(`Invalid filter query.`);
|
|
49
62
|
}
|
|
50
|
-
let right =
|
|
63
|
+
let right = prepareFilterAst(ast.right);
|
|
51
64
|
if (right == null) {
|
|
52
65
|
const op = ast.op === '='
|
|
53
66
|
? (negative ? '!=' : '=')
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import isPlainObject from 'putil-isplainobject';
|
|
2
|
+
const defaultPrimaryKey = ['_id'];
|
|
3
|
+
export default function prepareKeyValues(keyValue, primaryKey) {
|
|
4
|
+
primaryKey = primaryKey || defaultPrimaryKey;
|
|
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`);
|
|
8
|
+
if (primaryKey.length > 1 || b) {
|
|
9
|
+
return primaryKey.reduce((o, k) => {
|
|
10
|
+
o[k] = keyValue[k];
|
|
11
|
+
if (o[k] == null)
|
|
12
|
+
new Error(`Value of key "${k}" is required`);
|
|
13
|
+
return o;
|
|
14
|
+
}, {});
|
|
15
|
+
}
|
|
16
|
+
return { [primaryKey[0]]: keyValue };
|
|
17
|
+
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
export default function
|
|
1
|
+
export default function preparePatch(doc) {
|
|
2
2
|
const trg = {};
|
|
3
|
-
|
|
3
|
+
_preparePatch(doc, trg);
|
|
4
4
|
return trg;
|
|
5
5
|
}
|
|
6
|
-
function
|
|
6
|
+
function _preparePatch(src, trg = {}, path = '') {
|
|
7
7
|
let fieldName;
|
|
8
8
|
for (const [k, v] of Object.entries(src)) {
|
|
9
9
|
fieldName = k.startsWith('*') ? k.substring(1) : k;
|
|
@@ -16,7 +16,7 @@ function _transformPatch(src, trg = {}, path = '') {
|
|
|
16
16
|
if (v && typeof v === 'object') {
|
|
17
17
|
// If field name starts with "*", do "replace" operation except "merge"
|
|
18
18
|
if (!k.startsWith('*')) {
|
|
19
|
-
|
|
19
|
+
_preparePatch(v, trg, key);
|
|
20
20
|
continue;
|
|
21
21
|
}
|
|
22
22
|
}
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { ComplexType, pathToObjectTree } from '@opra/common';
|
|
2
|
-
export default function
|
|
2
|
+
export default function prepareProjection(dataType, args) {
|
|
3
3
|
const out = {};
|
|
4
4
|
// omitExclusiveFields(dataType, out);
|
|
5
5
|
const pick = args?.pick && pathToObjectTree(args.include ? [...args.pick, ...args.include] : args.pick);
|
|
6
6
|
const include = !args?.pick && args?.include && pathToObjectTree(args.include);
|
|
7
7
|
const omit = args?.omit && pathToObjectTree(args.omit);
|
|
8
8
|
if (pick || include) {
|
|
9
|
-
|
|
9
|
+
_prepareInclusionProjection(dataType, out, pick, include, omit);
|
|
10
10
|
}
|
|
11
11
|
else
|
|
12
|
-
|
|
12
|
+
_prepareExclusionProjection(dataType, out, omit, !omit);
|
|
13
13
|
return Object.keys(out).length ? out : undefined;
|
|
14
14
|
}
|
|
15
|
-
export function
|
|
15
|
+
export function _prepareInclusionProjection(dataType, target, pick, include, omit, defaultFields) {
|
|
16
16
|
defaultFields = defaultFields ?? !pick;
|
|
17
17
|
let n;
|
|
18
18
|
for (const [k, f] of dataType.fields.entries()) {
|
|
@@ -23,21 +23,21 @@ export function _transformInclusionProjection(dataType, target, pick, include, o
|
|
|
23
23
|
if (n) {
|
|
24
24
|
if (f.type instanceof ComplexType && (typeof n === 'object' || typeof omit?.[k] === 'object')) {
|
|
25
25
|
target[k] = {};
|
|
26
|
-
|
|
26
|
+
_prepareInclusionProjection(f.type, target[k], pick?.[k] || include?.[k], undefined, omit?.[k], defaultFields);
|
|
27
27
|
continue;
|
|
28
28
|
}
|
|
29
29
|
target[k] = 1;
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
|
-
export function
|
|
33
|
+
export function _prepareExclusionProjection(dataType, target, omit, omitExclusiveFields) {
|
|
34
34
|
let n;
|
|
35
35
|
for (const [k, f] of dataType.fields.entries()) {
|
|
36
36
|
n = omit?.[k] || (omitExclusiveFields && f.exclusive);
|
|
37
37
|
if (n) {
|
|
38
38
|
if (f.type instanceof ComplexType && typeof n === 'object') {
|
|
39
39
|
target[k] = {};
|
|
40
|
-
|
|
40
|
+
_prepareExclusionProjection(f.type, target[k], omit?.[k], omitExclusiveFields);
|
|
41
41
|
continue;
|
|
42
42
|
}
|
|
43
43
|
target[k] = 0;
|
package/esm/index.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
export * from './mongo-adapter.js';
|
|
2
|
-
export * from './mongo-collection.js';
|
|
3
|
-
export * from './mongo-
|
|
4
|
-
export * from './mongo-
|
|
5
|
-
export * from './mongo-singleton.js';
|
|
2
|
+
export * from './mongo-collection-service.js';
|
|
3
|
+
export * from './mongo-service.js';
|
|
4
|
+
export * from './mongo-singleton-service.js';
|
package/esm/mongo-adapter.js
CHANGED
|
@@ -1,103 +1,13 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import _transformPatch from './transform-patch.js';
|
|
7
|
-
import _transformProjection from './transform-projection.js';
|
|
8
|
-
import _transformSort from './transform-sort.js';
|
|
1
|
+
import _prepareFilter from './adapter-utils/prepare-filter.js';
|
|
2
|
+
import _prepareKeyValues from './adapter-utils/prepare-key-values.js';
|
|
3
|
+
import _preparePatch from './adapter-utils/prepare-patch.js';
|
|
4
|
+
import _prepareProjection from './adapter-utils/prepare-projection.js';
|
|
5
|
+
import _prepareSort from './adapter-utils/prepare-sort.js';
|
|
9
6
|
export var MongoAdapter;
|
|
10
7
|
(function (MongoAdapter) {
|
|
11
|
-
MongoAdapter.
|
|
12
|
-
MongoAdapter.
|
|
13
|
-
MongoAdapter.
|
|
14
|
-
MongoAdapter.
|
|
15
|
-
MongoAdapter.
|
|
16
|
-
function transformRequest(request) {
|
|
17
|
-
const { resource } = request;
|
|
18
|
-
if (resource instanceof Collection || resource instanceof Singleton) {
|
|
19
|
-
const { params, endpoint } = request;
|
|
20
|
-
let options = {};
|
|
21
|
-
let filter;
|
|
22
|
-
const operation = endpoint.name;
|
|
23
|
-
if (operation === 'create' || operation === 'update' ||
|
|
24
|
-
operation === 'get' || operation === 'findMany') {
|
|
25
|
-
options.projection = MongoAdapter.transformProjection(resource.type, params);
|
|
26
|
-
}
|
|
27
|
-
if (resource instanceof Collection &&
|
|
28
|
-
(operation === 'delete' || operation === 'get' || operation === 'update')) {
|
|
29
|
-
filter = MongoAdapter.transformKeyValues(resource, request.key);
|
|
30
|
-
}
|
|
31
|
-
if (params?.filter) {
|
|
32
|
-
const f = MongoAdapter.transformFilter(params.filter);
|
|
33
|
-
filter = filter ? { $and: [filter, f] } : f;
|
|
34
|
-
}
|
|
35
|
-
if (operation === 'findMany') {
|
|
36
|
-
options.sort = params?.sort;
|
|
37
|
-
options.limit = params?.limit;
|
|
38
|
-
options.skip = params?.skip;
|
|
39
|
-
options.distinct = params?.distinct;
|
|
40
|
-
options.count = params?.count;
|
|
41
|
-
}
|
|
42
|
-
options = omitBy(options, isNil);
|
|
43
|
-
switch (operation) {
|
|
44
|
-
case 'create': {
|
|
45
|
-
return {
|
|
46
|
-
method: 'insertOne',
|
|
47
|
-
data: request.data,
|
|
48
|
-
options,
|
|
49
|
-
args: [request.data, options]
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
case 'delete':
|
|
53
|
-
case 'deleteMany': {
|
|
54
|
-
return {
|
|
55
|
-
method: (operation === 'delete' ? 'deleteOne' : 'deleteMany'),
|
|
56
|
-
filter,
|
|
57
|
-
options,
|
|
58
|
-
args: [filter, options]
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
case 'get': {
|
|
62
|
-
return {
|
|
63
|
-
method: 'findOne',
|
|
64
|
-
filter,
|
|
65
|
-
options,
|
|
66
|
-
args: [filter, options]
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
case 'findMany': {
|
|
70
|
-
return {
|
|
71
|
-
method: 'find',
|
|
72
|
-
filter,
|
|
73
|
-
options,
|
|
74
|
-
args: [filter, options]
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
|
-
case 'update': {
|
|
78
|
-
const data = MongoAdapter.transformPatch(request.data);
|
|
79
|
-
filter = filter || {};
|
|
80
|
-
return {
|
|
81
|
-
method: 'updateOne',
|
|
82
|
-
filter,
|
|
83
|
-
data,
|
|
84
|
-
options,
|
|
85
|
-
args: [filter, data, options]
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
case 'updateMany': {
|
|
89
|
-
const data = MongoAdapter.transformPatch(request.data);
|
|
90
|
-
return {
|
|
91
|
-
method: 'updateMany',
|
|
92
|
-
filter,
|
|
93
|
-
data,
|
|
94
|
-
options,
|
|
95
|
-
args: [filter, data, options]
|
|
96
|
-
};
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
throw new TypeError(`Unimplemented request kind (${request.resource.kind}.${request.endpoint.name})`);
|
|
101
|
-
}
|
|
102
|
-
MongoAdapter.transformRequest = transformRequest;
|
|
8
|
+
MongoAdapter.prepareKeyValues = _prepareKeyValues;
|
|
9
|
+
MongoAdapter.prepareFilter = _prepareFilter;
|
|
10
|
+
MongoAdapter.preparePatch = _preparePatch;
|
|
11
|
+
MongoAdapter.prepareProjection = _prepareProjection;
|
|
12
|
+
MongoAdapter.prepareSort = _prepareSort;
|
|
103
13
|
})(MongoAdapter || (MongoAdapter = {}));
|