@opra/mongodb 0.16.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022 Panates
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,3 @@
1
+ # @opra/mongodb
2
+
3
+ OPRA MongoDB package.
package/cjs/index.js ADDED
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ tslib_1.__exportStar(require("./mongo-adapter.js"), exports);
5
+ tslib_1.__exportStar(require("./mongo-collection-resource.js"), exports);
6
+ tslib_1.__exportStar(require("./mongo-entity-service.js"), exports);
7
+ tslib_1.__exportStar(require("./mongo-singleton-resource.js"), exports);
@@ -0,0 +1,109 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MongoAdapter = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const lodash_isnil_1 = tslib_1.__importDefault(require("lodash.isnil"));
6
+ const lodash_omitby_1 = tslib_1.__importDefault(require("lodash.omitby"));
7
+ const common_1 = require("@opra/common");
8
+ const transform_filter_js_1 = tslib_1.__importDefault(require("./transform-filter.js"));
9
+ const transform_key_values_js_1 = tslib_1.__importDefault(require("./transform-key-values.js"));
10
+ const transform_patch_js_1 = tslib_1.__importDefault(require("./transform-patch.js"));
11
+ const transform_projection_js_1 = tslib_1.__importDefault(require("./transform-projection.js"));
12
+ const transform_sort_js_1 = tslib_1.__importDefault(require("./transform-sort.js"));
13
+ var MongoAdapter;
14
+ (function (MongoAdapter) {
15
+ MongoAdapter.transformFilter = transform_filter_js_1.default;
16
+ MongoAdapter.transformKeyValues = transform_key_values_js_1.default;
17
+ MongoAdapter.transformPatch = transform_patch_js_1.default;
18
+ MongoAdapter.transformProjection = transform_projection_js_1.default;
19
+ MongoAdapter.transformSort = transform_sort_js_1.default;
20
+ function transformRequest(request) {
21
+ const { resource } = request;
22
+ if (resource instanceof common_1.Collection || resource instanceof common_1.Singleton) {
23
+ const { args, operation } = request;
24
+ let options = {};
25
+ let filter;
26
+ if (operation === 'create' || operation === 'update' ||
27
+ operation === 'get' || operation === 'findMany') {
28
+ options.projection = MongoAdapter.transformProjection(resource.type, args);
29
+ }
30
+ if (resource instanceof common_1.Collection &&
31
+ (operation === 'delete' || operation === 'get' || operation === 'update')) {
32
+ filter = MongoAdapter.transformKeyValues(resource, args.key);
33
+ }
34
+ if (args.filter) {
35
+ const f = MongoAdapter.transformFilter(args.filter);
36
+ filter = filter ? { $and: [filter, f] } : f;
37
+ }
38
+ if (operation === 'findMany') {
39
+ options.sort = args.sort?.length ? args.sort : undefined;
40
+ options.limit = args.limit;
41
+ options.skip = args.skip;
42
+ options.distinct = args.distinct;
43
+ options.count = args.count;
44
+ }
45
+ options = (0, lodash_omitby_1.default)(options, lodash_isnil_1.default);
46
+ switch (operation) {
47
+ case 'create': {
48
+ return {
49
+ method: 'insertOne',
50
+ data: args.data,
51
+ options,
52
+ args: [args.data, options]
53
+ };
54
+ }
55
+ case 'delete':
56
+ case 'deleteMany': {
57
+ return {
58
+ method: (operation === 'delete' ? 'deleteOne' : 'deleteMany'),
59
+ filter,
60
+ options,
61
+ args: [filter, options]
62
+ };
63
+ }
64
+ case 'get': {
65
+ return {
66
+ method: 'findOne',
67
+ filter,
68
+ options,
69
+ args: [filter, options]
70
+ };
71
+ }
72
+ case 'findMany': {
73
+ const out = {
74
+ method: 'find',
75
+ filter,
76
+ options,
77
+ args: [filter, options]
78
+ };
79
+ if (args.count)
80
+ out.count = args.count;
81
+ return out;
82
+ }
83
+ case 'update': {
84
+ const update = MongoAdapter.transformPatch(args.data);
85
+ filter = filter || {};
86
+ return {
87
+ method: 'updateOne',
88
+ filter,
89
+ update,
90
+ options,
91
+ args: [filter, update, options]
92
+ };
93
+ }
94
+ case 'updateMany': {
95
+ const update = MongoAdapter.transformPatch(args.data);
96
+ return {
97
+ method: 'updateMany',
98
+ filter,
99
+ update,
100
+ options,
101
+ args: [filter, update, options]
102
+ };
103
+ }
104
+ }
105
+ }
106
+ throw new TypeError(`Unimplemented request kind (${request.resourceKind}.${request.operation})`);
107
+ }
108
+ MongoAdapter.transformRequest = transformRequest;
109
+ })(MongoAdapter = exports.MongoAdapter || (exports.MongoAdapter = {}));
@@ -0,0 +1,103 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MongoCollectionResource = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const common_1 = require("@opra/common");
6
+ const mongo_adapter_js_1 = require("./mongo-adapter.js");
7
+ class MongoCollectionResource {
8
+ constructor() {
9
+ this.defaultLimit = 100;
10
+ }
11
+ async create(ctx) {
12
+ const prepared = mongo_adapter_js_1.MongoAdapter.transformRequest(ctx.request);
13
+ const service = await this.getService(ctx);
14
+ return service.insertOne(prepared.data, prepared.options);
15
+ }
16
+ async delete(ctx) {
17
+ const prepared = mongo_adapter_js_1.MongoAdapter.transformRequest(ctx.request);
18
+ const service = await this.getService(ctx);
19
+ return service.deleteOne(prepared.filter, prepared.options);
20
+ }
21
+ async deleteMany(ctx) {
22
+ const prepared = mongo_adapter_js_1.MongoAdapter.transformRequest(ctx.request);
23
+ const service = await this.getService(ctx);
24
+ return service.deleteMany(prepared.filter, prepared.options);
25
+ }
26
+ async get(ctx) {
27
+ const prepared = mongo_adapter_js_1.MongoAdapter.transformRequest(ctx.request);
28
+ const service = await this.getService(ctx);
29
+ const out = await service.findOne(prepared.filter, prepared.options);
30
+ if (!out)
31
+ throw new common_1.ResourceNotFoundError(service.collectionName, prepared.filter._id);
32
+ return out;
33
+ }
34
+ async update(ctx) {
35
+ const prepared = mongo_adapter_js_1.MongoAdapter.transformRequest(ctx.request);
36
+ const service = await this.getService(ctx);
37
+ const out = await service.updateOne(prepared.filter, prepared.update, prepared.options);
38
+ if (!out)
39
+ throw new common_1.ResourceNotFoundError(service.collectionName, prepared.filter._id);
40
+ return out;
41
+ }
42
+ async updateMany(ctx) {
43
+ const prepared = mongo_adapter_js_1.MongoAdapter.transformRequest(ctx.request);
44
+ const service = await this.getService(ctx);
45
+ return service.updateMany(prepared.filter, prepared.update, prepared.options);
46
+ }
47
+ async search(ctx) {
48
+ const prepared = mongo_adapter_js_1.MongoAdapter.transformRequest(ctx.request);
49
+ const service = await this.getService(ctx);
50
+ if (prepared.count) {
51
+ const [items, count] = await Promise.all([
52
+ service.find(prepared.filter, prepared.options),
53
+ service.count(prepared.filter, prepared.options)
54
+ ]);
55
+ ctx.response.count = count;
56
+ return items;
57
+ }
58
+ return service.find(prepared.filter, prepared.options);
59
+ }
60
+ }
61
+ tslib_1.__decorate([
62
+ common_1.Collection.Create(),
63
+ tslib_1.__metadata("design:type", Function),
64
+ tslib_1.__metadata("design:paramtypes", [Object]),
65
+ tslib_1.__metadata("design:returntype", Promise)
66
+ ], MongoCollectionResource.prototype, "create", null);
67
+ tslib_1.__decorate([
68
+ common_1.Collection.Delete(),
69
+ tslib_1.__metadata("design:type", Function),
70
+ tslib_1.__metadata("design:paramtypes", [Object]),
71
+ tslib_1.__metadata("design:returntype", Promise)
72
+ ], MongoCollectionResource.prototype, "delete", null);
73
+ tslib_1.__decorate([
74
+ common_1.Collection.DeleteMany(),
75
+ tslib_1.__metadata("design:type", Function),
76
+ tslib_1.__metadata("design:paramtypes", [Object]),
77
+ tslib_1.__metadata("design:returntype", Promise)
78
+ ], MongoCollectionResource.prototype, "deleteMany", null);
79
+ tslib_1.__decorate([
80
+ common_1.Collection.Get(),
81
+ tslib_1.__metadata("design:type", Function),
82
+ tslib_1.__metadata("design:paramtypes", [Object]),
83
+ tslib_1.__metadata("design:returntype", Promise)
84
+ ], MongoCollectionResource.prototype, "get", null);
85
+ tslib_1.__decorate([
86
+ common_1.Collection.Update(),
87
+ tslib_1.__metadata("design:type", Function),
88
+ tslib_1.__metadata("design:paramtypes", [Object]),
89
+ tslib_1.__metadata("design:returntype", Promise)
90
+ ], MongoCollectionResource.prototype, "update", null);
91
+ tslib_1.__decorate([
92
+ common_1.Collection.UpdateMany(),
93
+ tslib_1.__metadata("design:type", Function),
94
+ tslib_1.__metadata("design:paramtypes", [Object]),
95
+ tslib_1.__metadata("design:returntype", Promise)
96
+ ], MongoCollectionResource.prototype, "updateMany", null);
97
+ tslib_1.__decorate([
98
+ common_1.Collection.FindMany(),
99
+ tslib_1.__metadata("design:type", Function),
100
+ tslib_1.__metadata("design:paramtypes", [Object]),
101
+ tslib_1.__metadata("design:returntype", Promise)
102
+ ], MongoCollectionResource.prototype, "search", null);
103
+ exports.MongoCollectionResource = MongoCollectionResource;
@@ -0,0 +1,179 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MongoEntityService = void 0;
4
+ class MongoEntityService {
5
+ constructor(collectionName, options) {
6
+ this.collectionName = collectionName;
7
+ this.db = options?.db;
8
+ this.defaultLimit = options?.defaultLimit || 10;
9
+ }
10
+ async count(filter, options) {
11
+ const collection = (await this.getDatabase()).collection(this.collectionName);
12
+ options = {
13
+ ...options,
14
+ session: options?.session || this.session
15
+ };
16
+ try {
17
+ return await collection.count(filter, options) || 0;
18
+ }
19
+ catch (e) {
20
+ await this._onError(e);
21
+ throw e;
22
+ }
23
+ }
24
+ async deleteOne(filter, options) {
25
+ const collection = (await this.getDatabase()).collection(this.collectionName);
26
+ options = {
27
+ ...options,
28
+ session: options?.session || this.session
29
+ };
30
+ try {
31
+ const r = await collection.deleteOne(filter, options);
32
+ return r.deletedCount;
33
+ }
34
+ catch (e) {
35
+ await this._onError(e);
36
+ throw e;
37
+ }
38
+ }
39
+ async deleteMany(filter, options) {
40
+ const collection = (await this.getDatabase()).collection(this.collectionName);
41
+ options = {
42
+ ...options,
43
+ session: options?.session || this.session
44
+ };
45
+ try {
46
+ const r = await collection.deleteMany(filter, options);
47
+ return r.deletedCount;
48
+ }
49
+ catch (e) {
50
+ await this._onError(e);
51
+ throw e;
52
+ }
53
+ }
54
+ async findOne(filter, options) {
55
+ const collection = (await this.getDatabase()).collection(this.collectionName);
56
+ options = {
57
+ ...options,
58
+ session: options?.session || this.session
59
+ };
60
+ let out;
61
+ try {
62
+ out = await collection.findOne(filter, options);
63
+ }
64
+ catch (e) {
65
+ await this._onError(e);
66
+ throw e;
67
+ }
68
+ if (this.onTransformRow)
69
+ out = this.onTransformRow(out);
70
+ return out;
71
+ }
72
+ async find(filter, options) {
73
+ const collection = (await this.getDatabase()).collection(this.collectionName);
74
+ options = {
75
+ ...options,
76
+ limit: options?.limit || this.defaultLimit,
77
+ session: options?.session || this.session
78
+ };
79
+ const out = [];
80
+ try {
81
+ const cursor = collection.find(filter, options);
82
+ let row;
83
+ while (row = await cursor.next()) {
84
+ if (this.onTransformRow)
85
+ row = this.onTransformRow(row);
86
+ out.push(row);
87
+ }
88
+ }
89
+ catch (e) {
90
+ await this._onError(e);
91
+ throw e;
92
+ }
93
+ return out;
94
+ }
95
+ async insertOne(doc, options) {
96
+ const collection = (await this.getDatabase()).collection(this.collectionName);
97
+ let out;
98
+ options = {
99
+ ...options,
100
+ session: options?.session || this.session
101
+ };
102
+ try {
103
+ const r = await collection.insertOne(doc, options);
104
+ if (r.insertedId)
105
+ out = await collection.findOne({ _id: r.insertedId }, options);
106
+ }
107
+ catch (e) {
108
+ await this._onError(e);
109
+ throw e;
110
+ }
111
+ if (this.onTransformRow)
112
+ out = this.onTransformRow(out);
113
+ if (!out)
114
+ throw new Error('"insertOne" operation returned no result!');
115
+ return out;
116
+ }
117
+ async updateOne(filter, doc, options) {
118
+ const collection = (await this.getDatabase()).collection(this.collectionName);
119
+ let out;
120
+ options = {
121
+ ...options,
122
+ session: options?.session || this.session
123
+ };
124
+ try {
125
+ const r = await collection.updateOne(filter, doc, options);
126
+ if (r.matchedCount)
127
+ out = await collection.findOne((r.upsertedId ? { _id: r.upsertedId } : filter), options);
128
+ }
129
+ catch (e) {
130
+ await this._onError(e);
131
+ throw e;
132
+ }
133
+ if (this.onTransformRow)
134
+ out = this.onTransformRow(out);
135
+ return out;
136
+ }
137
+ async updateMany(filter, doc, options) {
138
+ const collection = (await this.getDatabase()).collection(this.collectionName);
139
+ options = {
140
+ ...options,
141
+ session: options?.session || this.session,
142
+ upsert: false
143
+ };
144
+ try {
145
+ const r = await collection.updateMany(filter, doc, options);
146
+ return r.matchedCount;
147
+ }
148
+ catch (e) {
149
+ await this._onError(e);
150
+ throw e;
151
+ }
152
+ }
153
+ with(context, db, session) {
154
+ if (this.context === context && this.db === db && this.session === session)
155
+ return this;
156
+ const instance = { context };
157
+ // Should reset session if db changed
158
+ if (db) {
159
+ instance.db = db;
160
+ instance.session = session;
161
+ }
162
+ if (session)
163
+ instance.session = session;
164
+ Object.setPrototypeOf(instance, this);
165
+ return instance;
166
+ }
167
+ async _onError(error) {
168
+ if (this.onError)
169
+ await this.onError(error);
170
+ }
171
+ getDatabase() {
172
+ if (!this.context)
173
+ throw new Error(`Context not set!`);
174
+ if (!this.db)
175
+ throw new Error(`Database not set!`);
176
+ return this.db;
177
+ }
178
+ }
179
+ exports.MongoEntityService = MongoEntityService;
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MongoSingletonResource = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const common_1 = require("@opra/common");
6
+ const mongo_adapter_js_1 = require("./mongo-adapter.js");
7
+ class MongoSingletonResource {
8
+ constructor() {
9
+ this.defaultLimit = 100;
10
+ }
11
+ async create(ctx) {
12
+ const prepared = mongo_adapter_js_1.MongoAdapter.transformRequest(ctx.request);
13
+ const service = await this.getService(ctx);
14
+ await service.deleteMany();
15
+ return service.insertOne(prepared.data, prepared.options);
16
+ }
17
+ async delete(ctx) {
18
+ const prepared = mongo_adapter_js_1.MongoAdapter.transformRequest(ctx.request);
19
+ const service = await this.getService(ctx);
20
+ return service.deleteOne(prepared.filter, prepared.options);
21
+ }
22
+ async get(ctx) {
23
+ const prepared = mongo_adapter_js_1.MongoAdapter.transformRequest(ctx.request);
24
+ const service = await this.getService(ctx);
25
+ const out = await service.findOne(prepared.filter, prepared.options);
26
+ if (!out)
27
+ throw new common_1.ResourceNotFoundError(service.collectionName);
28
+ return out;
29
+ }
30
+ async update(ctx) {
31
+ const prepared = mongo_adapter_js_1.MongoAdapter.transformRequest(ctx.request);
32
+ const service = await this.getService(ctx);
33
+ const out = await service.updateOne(prepared.filter, prepared.update, prepared.options);
34
+ if (!out)
35
+ throw new common_1.ResourceNotFoundError(service.collectionName, prepared.filter._id);
36
+ return out;
37
+ }
38
+ }
39
+ tslib_1.__decorate([
40
+ common_1.Singleton.Create(),
41
+ tslib_1.__metadata("design:type", Function),
42
+ tslib_1.__metadata("design:paramtypes", [Object]),
43
+ tslib_1.__metadata("design:returntype", Promise)
44
+ ], MongoSingletonResource.prototype, "create", null);
45
+ tslib_1.__decorate([
46
+ common_1.Singleton.Delete(),
47
+ tslib_1.__metadata("design:type", Function),
48
+ tslib_1.__metadata("design:paramtypes", [Object]),
49
+ tslib_1.__metadata("design:returntype", Promise)
50
+ ], MongoSingletonResource.prototype, "delete", null);
51
+ tslib_1.__decorate([
52
+ common_1.Singleton.Get(),
53
+ tslib_1.__metadata("design:type", Function),
54
+ tslib_1.__metadata("design:paramtypes", [Object]),
55
+ tslib_1.__metadata("design:returntype", Promise)
56
+ ], MongoSingletonResource.prototype, "get", null);
57
+ tslib_1.__decorate([
58
+ common_1.Singleton.Update(),
59
+ tslib_1.__metadata("design:type", Function),
60
+ tslib_1.__metadata("design:paramtypes", [Object]),
61
+ tslib_1.__metadata("design:returntype", Promise)
62
+ ], MongoSingletonResource.prototype, "update", null);
63
+ exports.MongoSingletonResource = MongoSingletonResource;
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "commonjs"
3
+ }
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const common_1 = require("@opra/common");
4
+ function transformFilter(str) {
5
+ const ast = typeof str === 'string' ? (0, common_1.parseFilter)(str) : str;
6
+ if (!ast)
7
+ return;
8
+ if (ast instanceof common_1.ComparisonExpression) {
9
+ const left = ast.left instanceof common_1.QualifiedIdentifier
10
+ ? ast.left.value
11
+ : transformFilter(ast.left);
12
+ const right = transformFilter(ast.right);
13
+ switch (ast.op) {
14
+ case '=':
15
+ return { [left]: right };
16
+ case '!=':
17
+ return { [left]: { $ne: right } };
18
+ case '>':
19
+ return { [left]: { $gt: right } };
20
+ case '>=':
21
+ return { [left]: { $gte: right } };
22
+ case '<':
23
+ return { [left]: { $lt: right } };
24
+ case '<=':
25
+ return { [left]: { $lte: right } };
26
+ case 'in':
27
+ return { [left]: { $in: Array.isArray(right) ? right : [right] } };
28
+ case '!in':
29
+ return { [left]: { $nin: Array.isArray(right) ? right : [right] } };
30
+ case 'like':
31
+ return {
32
+ [left]: {
33
+ $text: {
34
+ $search: '\\"' + right.replace(/\\"/, '"') + '\\"',
35
+ $caseSensitive: true
36
+ }
37
+ }
38
+ };
39
+ case 'ilike':
40
+ return {
41
+ [left]: {
42
+ $text: {
43
+ $search: '\\"' + right.replace(/\\"/, '"') + '\\"'
44
+ }
45
+ }
46
+ };
47
+ case '!like':
48
+ return {
49
+ [left]: {
50
+ $not: {
51
+ $text: {
52
+ $search: '\\"' + right.replace(/\\"/, '"') + '\\"',
53
+ $caseSensitive: true
54
+ }
55
+ }
56
+ }
57
+ };
58
+ case '!ilike':
59
+ return {
60
+ [left]: {
61
+ $not: {
62
+ $text: {
63
+ $search: '\\"' + right.replace(/\\"/, '"') + '\\"'
64
+ }
65
+ }
66
+ }
67
+ };
68
+ default:
69
+ throw new Error(`ComparisonExpression operator (${ast.op}) not implemented yet`);
70
+ }
71
+ }
72
+ if (ast instanceof common_1.QualifiedIdentifier) {
73
+ return ast.value;
74
+ }
75
+ if (ast instanceof common_1.NumberLiteral ||
76
+ ast instanceof common_1.StringLiteral ||
77
+ ast instanceof common_1.BooleanLiteral ||
78
+ ast instanceof common_1.NullLiteral ||
79
+ ast instanceof common_1.DateLiteral ||
80
+ ast instanceof common_1.TimeLiteral) {
81
+ return ast.value;
82
+ }
83
+ if (ast instanceof common_1.ArrayExpression) {
84
+ return ast.items.map(transformFilter);
85
+ }
86
+ if (ast instanceof common_1.LogicalExpression) {
87
+ if (ast.op === 'or')
88
+ return { $or: ast.items.map(transformFilter) };
89
+ return { $and: ast.items.map(transformFilter) };
90
+ }
91
+ if (ast instanceof common_1.ParenthesesExpression) {
92
+ return transformFilter(ast.expression);
93
+ }
94
+ throw new Error(`${ast.type} is not implemented yet`);
95
+ }
96
+ exports.default = transformFilter;
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ function transformKeyValues(resource, keyValues) {
4
+ const { primaryKey } = resource;
5
+ if (primaryKey.length > 1) {
6
+ const query = {};
7
+ primaryKey.forEach((k, i) => {
8
+ query[k] = typeof keyValues === 'object' ? keyValues[k] : keyValues[i];
9
+ });
10
+ return query;
11
+ }
12
+ return { [primaryKey[0]]: keyValues };
13
+ }
14
+ exports.default = transformKeyValues;
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ function transformPatch(doc) {
4
+ const trg = {};
5
+ _transformPatch(doc, trg);
6
+ return trg;
7
+ }
8
+ exports.default = transformPatch;
9
+ function _transformPatch(src, trg = {}, path = '') {
10
+ let fieldName;
11
+ for (const [k, v] of Object.entries(src)) {
12
+ fieldName = k.startsWith('*') ? k.substring(1) : k;
13
+ const key = path ? path + '.' + fieldName : fieldName;
14
+ if (v == null) {
15
+ trg.$unset = trg.$unset || {};
16
+ trg.$unset[key] = '';
17
+ continue;
18
+ }
19
+ if (v && typeof v === 'object') {
20
+ // If field name starts with "*", do "replace" operation except "merge"
21
+ if (!k.startsWith('*')) {
22
+ _transformPatch(v, trg, key);
23
+ continue;
24
+ }
25
+ }
26
+ trg.$set = trg.$set || {};
27
+ trg.$set[key] = v;
28
+ }
29
+ return trg;
30
+ }