@feathersjs/mongodb 5.0.0-pre.19
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/CHANGELOG.md +11 -0
- package/LICENSE +22 -0
- package/README.md +22 -0
- package/lib/adapter.d.ts +53 -0
- package/lib/adapter.js +216 -0
- package/lib/adapter.js.map +1 -0
- package/lib/error-handler.d.ts +2 -0
- package/lib/error-handler.js +16 -0
- package/lib/error-handler.js.map +1 -0
- package/lib/index.d.ts +22 -0
- package/lib/index.js +42 -0
- package/lib/index.js.map +1 -0
- package/package.json +71 -0
- package/src/adapter.ts +279 -0
- package/src/error-handler.ts +14 -0
- package/src/index.ts +42 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Change Log
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
|
+
|
|
6
|
+
# [5.0.0-pre.19](https://github.com/feathersjs/feathers/compare/v5.0.0-pre.18...v5.0.0-pre.19) (2022-05-01)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* **mongodb:** Add feathers-mongodb adapter as @feathersjs/mongodb ([#2610](https://github.com/feathersjs/feathers/issues/2610)) ([6d43734](https://github.com/feathersjs/feathers/commit/6d43734a53db02c435cafc52a22dca414e5d0940))
|
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2022 Feathers
|
|
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.
|
|
22
|
+
|
package/README.md
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# @feathersjs/mongodb
|
|
2
|
+
|
|
3
|
+
[](https://github.com/feathersjs/feathers/actions?query=workflow%3ACI)
|
|
4
|
+
[](https://www.npmjs.com/package/@feathersjs/mongodb)
|
|
5
|
+
|
|
6
|
+
> Feathers MongoDB service adapter
|
|
7
|
+
|
|
8
|
+
## Installation
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
npm install @feathersjs/mongodb --save
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Documentation
|
|
15
|
+
|
|
16
|
+
Refer to the [Feathers documentation](https://docs.feathersjs.com) for more details.
|
|
17
|
+
|
|
18
|
+
## License
|
|
19
|
+
|
|
20
|
+
Copyright (c) 2022 [Feathers contributors](https://github.com/feathersjs/feathers/graphs/contributors)
|
|
21
|
+
|
|
22
|
+
Licensed under the [MIT license](LICENSE).
|
package/lib/adapter.d.ts
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { ObjectId, Collection, FindOptions, BulkWriteOptions, InsertOneOptions, DeleteOptions, CountDocumentsOptions, ReplaceOptions } from 'mongodb';
|
|
2
|
+
import { AdapterBase, AdapterParams, AdapterServiceOptions, PaginationOptions, AdapterQuery } from '@feathersjs/adapter-commons';
|
|
3
|
+
import { NullableId, Id, Paginated } from '@feathersjs/feathers';
|
|
4
|
+
export interface MongoDBAdapterOptions extends AdapterServiceOptions {
|
|
5
|
+
Model: Collection | Promise<Collection>;
|
|
6
|
+
disableObjectify?: boolean;
|
|
7
|
+
useEstimatedDocumentCount?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export interface MongoDBAdapterParams<Q = AdapterQuery> extends AdapterParams<Q, Partial<MongoDBAdapterOptions>> {
|
|
10
|
+
mongodb?: BulkWriteOptions | FindOptions | InsertOneOptions | DeleteOptions | CountDocumentsOptions | ReplaceOptions;
|
|
11
|
+
}
|
|
12
|
+
export declare class MongoDbAdapter<T, D = Partial<T>, P extends MongoDBAdapterParams = MongoDBAdapterParams> extends AdapterBase<T, D, P, MongoDBAdapterOptions> {
|
|
13
|
+
constructor(options: MongoDBAdapterOptions);
|
|
14
|
+
getObjectId(id: Id | ObjectId): ObjectId | Id;
|
|
15
|
+
filterQuery(id: NullableId, params: P): {
|
|
16
|
+
filters: {
|
|
17
|
+
$select: string[];
|
|
18
|
+
$sort: {
|
|
19
|
+
[key: string]: 1 | -1;
|
|
20
|
+
};
|
|
21
|
+
$limit: number;
|
|
22
|
+
$skip: number;
|
|
23
|
+
};
|
|
24
|
+
query: {
|
|
25
|
+
[key: string]: any;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
getSelect(select: string[] | {
|
|
29
|
+
[key: string]: number;
|
|
30
|
+
}): {
|
|
31
|
+
[key: string]: number;
|
|
32
|
+
};
|
|
33
|
+
$findOrGet(id: NullableId, params: P): Promise<T | Paginated<T> | T[]>;
|
|
34
|
+
normalizeId(id: NullableId, data: Partial<D>): Partial<D>;
|
|
35
|
+
$get(id: Id, params?: P): Promise<T>;
|
|
36
|
+
$find(params?: P & {
|
|
37
|
+
paginate?: PaginationOptions;
|
|
38
|
+
}): Promise<Paginated<T>>;
|
|
39
|
+
$find(params?: P & {
|
|
40
|
+
paginate: false;
|
|
41
|
+
}): Promise<T[]>;
|
|
42
|
+
$find(params?: P): Promise<Paginated<T> | T[]>;
|
|
43
|
+
$create(data: Partial<D>, params?: P): Promise<T>;
|
|
44
|
+
$create(data: Partial<D>[], params?: P): Promise<T[]>;
|
|
45
|
+
$create(data: Partial<D> | Partial<D>[], _params?: P): Promise<T | T[]>;
|
|
46
|
+
$patch(id: null, data: Partial<D>, params?: P): Promise<T[]>;
|
|
47
|
+
$patch(id: Id, data: Partial<D>, params?: P): Promise<T>;
|
|
48
|
+
$patch(id: NullableId, data: Partial<D>, _params?: P): Promise<T | T[]>;
|
|
49
|
+
$update(id: Id, data: D, params?: P): Promise<T>;
|
|
50
|
+
$remove(id: null, params?: P): Promise<T[]>;
|
|
51
|
+
$remove(id: Id, params?: P): Promise<T>;
|
|
52
|
+
$remove(id: NullableId, _params?: P): Promise<T | T[]>;
|
|
53
|
+
}
|
package/lib/adapter.js
ADDED
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MongoDbAdapter = void 0;
|
|
4
|
+
const mongodb_1 = require("mongodb");
|
|
5
|
+
const errors_1 = require("@feathersjs/errors");
|
|
6
|
+
const commons_1 = require("@feathersjs/commons");
|
|
7
|
+
const adapter_commons_1 = require("@feathersjs/adapter-commons");
|
|
8
|
+
const error_handler_1 = require("./error-handler");
|
|
9
|
+
// Create the service.
|
|
10
|
+
class MongoDbAdapter extends adapter_commons_1.AdapterBase {
|
|
11
|
+
constructor(options) {
|
|
12
|
+
if (!options) {
|
|
13
|
+
throw new Error('MongoDB options have to be provided');
|
|
14
|
+
}
|
|
15
|
+
super({
|
|
16
|
+
id: '_id',
|
|
17
|
+
...options
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
getObjectId(id) {
|
|
21
|
+
if (this.options.disableObjectify) {
|
|
22
|
+
return id;
|
|
23
|
+
}
|
|
24
|
+
if (this.id === '_id' && mongodb_1.ObjectId.isValid(id)) {
|
|
25
|
+
id = new mongodb_1.ObjectId(id.toString());
|
|
26
|
+
}
|
|
27
|
+
return id;
|
|
28
|
+
}
|
|
29
|
+
filterQuery(id, params) {
|
|
30
|
+
const { $select, $sort, $limit, $skip, ...query } = (params.query || {});
|
|
31
|
+
if (id !== null) {
|
|
32
|
+
query.$and = (query.$and || []).concat({ [this.id]: this.getObjectId(id) });
|
|
33
|
+
}
|
|
34
|
+
if (query[this.id]) {
|
|
35
|
+
query[this.id] = this.getObjectId(query[this.id]);
|
|
36
|
+
}
|
|
37
|
+
return {
|
|
38
|
+
filters: { $select, $sort, $limit, $skip },
|
|
39
|
+
query
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
getSelect(select) {
|
|
43
|
+
if (Array.isArray(select)) {
|
|
44
|
+
return select.reduce((value, name) => ({
|
|
45
|
+
...value,
|
|
46
|
+
[name]: 1
|
|
47
|
+
}), {});
|
|
48
|
+
}
|
|
49
|
+
return select;
|
|
50
|
+
}
|
|
51
|
+
async $findOrGet(id, params) {
|
|
52
|
+
return id === null ? await this.$find(params) : await this.$get(id, params);
|
|
53
|
+
}
|
|
54
|
+
normalizeId(id, data) {
|
|
55
|
+
if (this.id === '_id') {
|
|
56
|
+
// Default Mongo IDs cannot be updated. The Mongo library handles
|
|
57
|
+
// this automatically.
|
|
58
|
+
return commons_1._.omit(data, this.id);
|
|
59
|
+
}
|
|
60
|
+
else if (id !== null) {
|
|
61
|
+
// If not using the default Mongo _id field set the ID to its
|
|
62
|
+
// previous value. This prevents orphaned documents.
|
|
63
|
+
return {
|
|
64
|
+
...data,
|
|
65
|
+
[this.id]: id
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
return data;
|
|
69
|
+
}
|
|
70
|
+
async $get(id, params = {}) {
|
|
71
|
+
const { Model } = this.getOptions(params);
|
|
72
|
+
const { query, filters: { $select } } = this.filterQuery(id, params);
|
|
73
|
+
const projection = $select ? {
|
|
74
|
+
projection: {
|
|
75
|
+
...this.getSelect($select),
|
|
76
|
+
[this.id]: 1
|
|
77
|
+
}
|
|
78
|
+
} : {};
|
|
79
|
+
const findOptions = {
|
|
80
|
+
...params.mongodb,
|
|
81
|
+
...projection
|
|
82
|
+
};
|
|
83
|
+
return Promise.resolve(Model).then(model => model.findOne(query, findOptions))
|
|
84
|
+
.then(data => {
|
|
85
|
+
if (data == null) {
|
|
86
|
+
throw new errors_1.NotFound(`No record found for id '${id}'`);
|
|
87
|
+
}
|
|
88
|
+
return data;
|
|
89
|
+
})
|
|
90
|
+
.catch(error_handler_1.errorHandler);
|
|
91
|
+
}
|
|
92
|
+
async $find(params = {}) {
|
|
93
|
+
const { filters, query } = this.filterQuery(null, params);
|
|
94
|
+
const { paginate, Model, useEstimatedDocumentCount } = this.getOptions(params);
|
|
95
|
+
const findOptions = { ...params.mongodb };
|
|
96
|
+
const model = await Promise.resolve(Model);
|
|
97
|
+
const q = model.find(query, findOptions);
|
|
98
|
+
if (filters.$select !== undefined) {
|
|
99
|
+
q.project(this.getSelect(filters.$select));
|
|
100
|
+
}
|
|
101
|
+
if (filters.$sort !== undefined) {
|
|
102
|
+
q.sort(filters.$sort);
|
|
103
|
+
}
|
|
104
|
+
if (filters.$limit !== undefined) {
|
|
105
|
+
q.limit(filters.$limit);
|
|
106
|
+
}
|
|
107
|
+
if (filters.$skip !== undefined) {
|
|
108
|
+
q.skip(filters.$skip);
|
|
109
|
+
}
|
|
110
|
+
const runQuery = async (total) => ({
|
|
111
|
+
total,
|
|
112
|
+
limit: filters.$limit,
|
|
113
|
+
skip: filters.$skip || 0,
|
|
114
|
+
data: filters.$limit === 0 ? [] : (await q.toArray())
|
|
115
|
+
});
|
|
116
|
+
if (paginate && paginate.default) {
|
|
117
|
+
if (useEstimatedDocumentCount && (typeof model.estimatedDocumentCount === 'function')) {
|
|
118
|
+
return model.estimatedDocumentCount().then(runQuery);
|
|
119
|
+
}
|
|
120
|
+
return model.countDocuments(query, findOptions).then(runQuery);
|
|
121
|
+
}
|
|
122
|
+
return runQuery(0).then(page => page.data);
|
|
123
|
+
}
|
|
124
|
+
async $create(data, params = {}) {
|
|
125
|
+
const writeOptions = params.mongodb;
|
|
126
|
+
const { Model } = this.getOptions(params);
|
|
127
|
+
const model = await Promise.resolve(Model);
|
|
128
|
+
const setId = (item) => {
|
|
129
|
+
const entry = Object.assign({}, item);
|
|
130
|
+
// Generate a MongoId if we use a custom id
|
|
131
|
+
if (this.id !== '_id' && typeof entry[this.id] === 'undefined') {
|
|
132
|
+
return {
|
|
133
|
+
[this.id]: new mongodb_1.ObjectId().toHexString(),
|
|
134
|
+
...entry
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
return entry;
|
|
138
|
+
};
|
|
139
|
+
const promise = Array.isArray(data)
|
|
140
|
+
? model.insertMany(data.map(setId), writeOptions).then(async (result) => Promise.all(Object.values(result.insertedIds).map(async (_id) => model.findOne({ _id }))))
|
|
141
|
+
: model.insertOne(setId(data), writeOptions).then(async (result) => model.findOne({ _id: result.insertedId }));
|
|
142
|
+
return promise.then((0, adapter_commons_1.select)(params, this.id)).catch(error_handler_1.errorHandler);
|
|
143
|
+
}
|
|
144
|
+
async $patch(id, _data, params = {}) {
|
|
145
|
+
const data = this.normalizeId(id, _data);
|
|
146
|
+
const { Model } = this.getOptions(params);
|
|
147
|
+
const model = await Promise.resolve(Model);
|
|
148
|
+
const { query, filters: { $select, $limit } } = this.filterQuery(id, params);
|
|
149
|
+
const updateOptions = { ...params.mongodb };
|
|
150
|
+
const modifier = Object.keys(data).reduce((current, key) => {
|
|
151
|
+
const value = data[key];
|
|
152
|
+
if (key.charAt(0) !== '$') {
|
|
153
|
+
current.$set = {
|
|
154
|
+
...current.$set,
|
|
155
|
+
[key]: value
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
current[key] = value;
|
|
160
|
+
}
|
|
161
|
+
return current;
|
|
162
|
+
}, {});
|
|
163
|
+
const originalIds = await this.$findOrGet(id, {
|
|
164
|
+
...params,
|
|
165
|
+
query: {
|
|
166
|
+
...query,
|
|
167
|
+
$select: [this.id]
|
|
168
|
+
},
|
|
169
|
+
paginate: false
|
|
170
|
+
});
|
|
171
|
+
const items = (Array.isArray(originalIds) ? originalIds : [originalIds]);
|
|
172
|
+
const idList = items.map((item) => item[this.id]);
|
|
173
|
+
const findParams = {
|
|
174
|
+
...params,
|
|
175
|
+
paginate: false,
|
|
176
|
+
query: {
|
|
177
|
+
...($limit === 0 ? { $limit: 0 } : {}),
|
|
178
|
+
[this.id]: { $in: idList },
|
|
179
|
+
$select
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
await model.updateMany(query, modifier, updateOptions);
|
|
183
|
+
return this.$findOrGet(id, findParams).catch(error_handler_1.errorHandler);
|
|
184
|
+
}
|
|
185
|
+
async $update(id, data, params = {}) {
|
|
186
|
+
const { Model } = this.getOptions(params);
|
|
187
|
+
const model = await Promise.resolve(Model);
|
|
188
|
+
const { query } = this.filterQuery(id, params);
|
|
189
|
+
const replaceOptions = { ...params.mongodb };
|
|
190
|
+
await model.replaceOne(query, this.normalizeId(id, data), replaceOptions);
|
|
191
|
+
return this.$findOrGet(id, params).catch(error_handler_1.errorHandler);
|
|
192
|
+
}
|
|
193
|
+
async $remove(id, params = {}) {
|
|
194
|
+
const { Model } = this.getOptions(params);
|
|
195
|
+
const model = await Promise.resolve(Model);
|
|
196
|
+
const { query, filters: { $select, $limit } } = this.filterQuery(id, params);
|
|
197
|
+
const deleteOptions = { ...params.mongodb };
|
|
198
|
+
const findParams = {
|
|
199
|
+
...params,
|
|
200
|
+
paginate: false,
|
|
201
|
+
query: {
|
|
202
|
+
...query,
|
|
203
|
+
...($limit === 0 ? { $limit: 0 } : {}),
|
|
204
|
+
$select
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
return this.$findOrGet(id, findParams)
|
|
208
|
+
.then(async (items) => {
|
|
209
|
+
await model.deleteMany(query, deleteOptions);
|
|
210
|
+
return items;
|
|
211
|
+
})
|
|
212
|
+
.catch(error_handler_1.errorHandler);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
exports.MongoDbAdapter = MongoDbAdapter;
|
|
216
|
+
//# sourceMappingURL=adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.errorHandler = void 0;
|
|
4
|
+
const errors_1 = require("@feathersjs/errors");
|
|
5
|
+
function errorHandler(error) {
|
|
6
|
+
// See https://github.com/mongodb/mongo/blob/master/docs/errors.md
|
|
7
|
+
if (error && error.name && error.name.startsWith('Mongo')) {
|
|
8
|
+
throw new errors_1.GeneralError(error, {
|
|
9
|
+
name: error.name,
|
|
10
|
+
code: error.code
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
throw error;
|
|
14
|
+
}
|
|
15
|
+
exports.errorHandler = errorHandler;
|
|
16
|
+
//# sourceMappingURL=error-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-handler.js","sourceRoot":"","sources":["../src/error-handler.ts"],"names":[],"mappings":";;;AAAA,+CAAiD;AAGjD,SAAgB,YAAY,CAAE,KAAiB;IAC7C,kEAAkE;IAClE,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE;QACzD,MAAM,IAAI,qBAAY,CAAC,KAAK,EAAE;YAC5B,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,IAAI,EAAE,KAAK,CAAC,IAAI;SACjB,CAAC,CAAA;KACH;IAED,MAAM,KAAK,CAAA;AACb,CAAC;AAVD,oCAUC"}
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { PaginationOptions } from '@feathersjs/adapter-commons';
|
|
2
|
+
import { Paginated, ServiceMethods, Id } from '@feathersjs/feathers';
|
|
3
|
+
import { MongoDbAdapter, MongoDBAdapterParams } from './adapter';
|
|
4
|
+
export * from './adapter';
|
|
5
|
+
export * from './error-handler';
|
|
6
|
+
export declare class MongoDBService<T = any, D = Partial<T>, P extends MongoDBAdapterParams = MongoDBAdapterParams> extends MongoDbAdapter<T, D, P> implements ServiceMethods<T | Paginated<T>, D, P> {
|
|
7
|
+
find(params?: P & {
|
|
8
|
+
paginate?: PaginationOptions;
|
|
9
|
+
}): Promise<Paginated<T>>;
|
|
10
|
+
find(params?: P & {
|
|
11
|
+
paginate: false;
|
|
12
|
+
}): Promise<T[]>;
|
|
13
|
+
find(params?: P): Promise<Paginated<T> | T[]>;
|
|
14
|
+
get(id: Id, params?: P): Promise<T>;
|
|
15
|
+
create(data: Partial<D>, params?: P): Promise<T>;
|
|
16
|
+
create(data: Partial<D>[], params?: P): Promise<T[]>;
|
|
17
|
+
update(id: Id, data: D, params?: P): Promise<T>;
|
|
18
|
+
patch(id: Id, data: Partial<D>, params?: P): Promise<T>;
|
|
19
|
+
patch(id: null, data: Partial<D>, params?: P): Promise<T[]>;
|
|
20
|
+
remove(id: Id, params?: P): Promise<T>;
|
|
21
|
+
remove(id: null, params?: P): Promise<T[]>;
|
|
22
|
+
}
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.MongoDBService = void 0;
|
|
18
|
+
const adapter_1 = require("./adapter");
|
|
19
|
+
__exportStar(require("./adapter"), exports);
|
|
20
|
+
__exportStar(require("./error-handler"), exports);
|
|
21
|
+
class MongoDBService extends adapter_1.MongoDbAdapter {
|
|
22
|
+
async find(params) {
|
|
23
|
+
return this._find(params);
|
|
24
|
+
}
|
|
25
|
+
async get(id, params) {
|
|
26
|
+
return this._get(id, params);
|
|
27
|
+
}
|
|
28
|
+
async create(data, params) {
|
|
29
|
+
return this._create(data, params);
|
|
30
|
+
}
|
|
31
|
+
async update(id, data, params) {
|
|
32
|
+
return this._update(id, data, params);
|
|
33
|
+
}
|
|
34
|
+
async patch(id, data, params) {
|
|
35
|
+
return this._patch(id, data, params);
|
|
36
|
+
}
|
|
37
|
+
async remove(id, params) {
|
|
38
|
+
return this._remove(id, params);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
exports.MongoDBService = MongoDBService;
|
|
42
|
+
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAEA,uCAAgE;AAEhE,4CAAyB;AACzB,kDAA+B;AAE/B,MAAa,cACX,SAAQ,wBAAuB;IAI/B,KAAK,CAAC,IAAI,CAAE,MAAU;QACpB,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAQ,CAAA;IAClC,CAAC;IAED,KAAK,CAAC,GAAG,CAAE,EAAM,EAAE,MAAU;QAC3B,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,MAAM,CAAC,CAAA;IAC9B,CAAC;IAID,KAAK,CAAC,MAAM,CAAE,IAA6B,EAAE,MAAU;QACrD,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;IACnC,CAAC;IAED,KAAK,CAAC,MAAM,CAAE,EAAM,EAAE,IAAO,EAAE,MAAU;QACvC,OAAO,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,CAAA;IACvC,CAAC;IAID,KAAK,CAAC,KAAK,CAAE,EAAc,EAAE,IAAgB,EAAE,MAAU;QACvD,OAAO,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,CAAA;IACtC,CAAC;IAID,KAAK,CAAC,MAAM,CAAE,EAAc,EAAE,MAAU;QACtC,OAAO,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,MAAM,CAAC,CAAA;IACjC,CAAC;CACF;AAlCD,wCAkCC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@feathersjs/mongodb",
|
|
3
|
+
"description": "Feathers MongoDB service adapter",
|
|
4
|
+
"version": "5.0.0-pre.19",
|
|
5
|
+
"homepage": "https://feathersjs.com",
|
|
6
|
+
"main": "lib/",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"feathers",
|
|
9
|
+
"feathers-plugin"
|
|
10
|
+
],
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"funding": {
|
|
13
|
+
"type": "github",
|
|
14
|
+
"url": "https://github.com/sponsors/daffl"
|
|
15
|
+
},
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "git://github.com/feathersjs/feathers.git"
|
|
19
|
+
},
|
|
20
|
+
"author": {
|
|
21
|
+
"name": "Feathers contributors",
|
|
22
|
+
"email": "hello@feathersjs.com",
|
|
23
|
+
"url": "https://feathersjs.com"
|
|
24
|
+
},
|
|
25
|
+
"contributors": [],
|
|
26
|
+
"bugs": {
|
|
27
|
+
"url": "https://github.com/feathersjs/feathers/issues"
|
|
28
|
+
},
|
|
29
|
+
"engines": {
|
|
30
|
+
"node": ">= 14"
|
|
31
|
+
},
|
|
32
|
+
"files": [
|
|
33
|
+
"CHANGELOG.md",
|
|
34
|
+
"LICENSE",
|
|
35
|
+
"README.md",
|
|
36
|
+
"src/**",
|
|
37
|
+
"lib/**",
|
|
38
|
+
"*.d.ts",
|
|
39
|
+
"*.js"
|
|
40
|
+
],
|
|
41
|
+
"scripts": {
|
|
42
|
+
"prepublish": "npm run compile",
|
|
43
|
+
"compile": "shx rm -rf lib/ && tsc",
|
|
44
|
+
"test": "mocha --config ../../.mocharc.json --recursive test/**.test.ts test/**/*.test.ts"
|
|
45
|
+
},
|
|
46
|
+
"directories": {
|
|
47
|
+
"lib": "lib"
|
|
48
|
+
},
|
|
49
|
+
"publishConfig": {
|
|
50
|
+
"access": "public"
|
|
51
|
+
},
|
|
52
|
+
"dependencies": {
|
|
53
|
+
"@feathersjs/adapter-commons": "^5.0.0-pre.19",
|
|
54
|
+
"@feathersjs/commons": "^5.0.0-pre.19",
|
|
55
|
+
"@feathersjs/errors": "^5.0.0-pre.19",
|
|
56
|
+
"@feathersjs/feathers": "^5.0.0-pre.19"
|
|
57
|
+
},
|
|
58
|
+
"peerDependencies": {
|
|
59
|
+
"mongodb": "^4.5.0"
|
|
60
|
+
},
|
|
61
|
+
"devDependencies": {
|
|
62
|
+
"@feathersjs/adapter-tests": "^5.0.0-pre.19",
|
|
63
|
+
"@types/mocha": "^9.1.1",
|
|
64
|
+
"@types/node": "^17.0.31",
|
|
65
|
+
"mocha": "^10.0.0",
|
|
66
|
+
"mongodb-memory-server": "^8.5.2",
|
|
67
|
+
"shx": "^0.3.4",
|
|
68
|
+
"typescript": "^4.6.4"
|
|
69
|
+
},
|
|
70
|
+
"gitHead": "57f3e18bb62735e1869ffafee90286498738fdfa"
|
|
71
|
+
}
|
package/src/adapter.ts
ADDED
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ObjectId, Collection, FindOptions, BulkWriteOptions,
|
|
3
|
+
InsertOneOptions, DeleteOptions, CountDocumentsOptions, ReplaceOptions
|
|
4
|
+
} from 'mongodb'
|
|
5
|
+
import { NotFound } from '@feathersjs/errors'
|
|
6
|
+
import { _ } from '@feathersjs/commons'
|
|
7
|
+
import { AdapterBase, select, AdapterParams, AdapterServiceOptions, PaginationOptions, AdapterQuery } from '@feathersjs/adapter-commons'
|
|
8
|
+
import { NullableId, Id, Paginated } from '@feathersjs/feathers'
|
|
9
|
+
import { errorHandler } from './error-handler'
|
|
10
|
+
|
|
11
|
+
export interface MongoDBAdapterOptions extends AdapterServiceOptions {
|
|
12
|
+
Model: Collection|Promise<Collection>,
|
|
13
|
+
disableObjectify?: boolean,
|
|
14
|
+
useEstimatedDocumentCount?: boolean
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface MongoDBAdapterParams<Q = AdapterQuery> extends AdapterParams<Q, Partial<MongoDBAdapterOptions>> {
|
|
18
|
+
mongodb?: BulkWriteOptions|FindOptions|InsertOneOptions|DeleteOptions|CountDocumentsOptions|ReplaceOptions
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Create the service.
|
|
22
|
+
export class MongoDbAdapter<T, D = Partial<T>, P extends MongoDBAdapterParams = MongoDBAdapterParams>
|
|
23
|
+
extends AdapterBase<T, D, P, MongoDBAdapterOptions> {
|
|
24
|
+
constructor (options: MongoDBAdapterOptions) {
|
|
25
|
+
if (!options) {
|
|
26
|
+
throw new Error('MongoDB options have to be provided')
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
super({
|
|
30
|
+
id: '_id',
|
|
31
|
+
...options
|
|
32
|
+
})
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
getObjectId (id: Id|ObjectId) {
|
|
36
|
+
if (this.options.disableObjectify) {
|
|
37
|
+
return id
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (this.id === '_id' && ObjectId.isValid(id)) {
|
|
41
|
+
id = new ObjectId(id.toString())
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return id
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
filterQuery (id: NullableId, params: P) {
|
|
48
|
+
const { $select, $sort, $limit, $skip, ...query } = (params.query || {}) as AdapterQuery;
|
|
49
|
+
|
|
50
|
+
if (id !== null) {
|
|
51
|
+
query.$and = (query.$and || []).concat({ [this.id]: this.getObjectId(id) })
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (query[this.id]) {
|
|
55
|
+
query[this.id] = this.getObjectId(query[this.id])
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return {
|
|
59
|
+
filters: { $select, $sort, $limit, $skip },
|
|
60
|
+
query
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
getSelect (select: string[]|{ [key: string]: number }) {
|
|
65
|
+
if (Array.isArray(select)) {
|
|
66
|
+
return select.reduce<{ [key: string]: number }>((value, name) => ({
|
|
67
|
+
...value,
|
|
68
|
+
[name]: 1
|
|
69
|
+
}), {})
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return select
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
async $findOrGet (id: NullableId, params: P) {
|
|
76
|
+
return id === null ? await this.$find(params) : await this.$get(id, params)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
normalizeId (id: NullableId, data: Partial<D>): Partial<D> {
|
|
80
|
+
if (this.id === '_id') {
|
|
81
|
+
// Default Mongo IDs cannot be updated. The Mongo library handles
|
|
82
|
+
// this automatically.
|
|
83
|
+
return _.omit(data, this.id)
|
|
84
|
+
} else if (id !== null) {
|
|
85
|
+
// If not using the default Mongo _id field set the ID to its
|
|
86
|
+
// previous value. This prevents orphaned documents.
|
|
87
|
+
return {
|
|
88
|
+
...data,
|
|
89
|
+
[this.id]: id
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return data
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
async $get (id: Id, params: P = {} as P): Promise<T> {
|
|
96
|
+
const { Model } = this.getOptions(params);
|
|
97
|
+
const { query, filters: { $select } } = this.filterQuery(id, params);
|
|
98
|
+
const projection = $select ? {
|
|
99
|
+
projection: {
|
|
100
|
+
...this.getSelect($select),
|
|
101
|
+
[this.id]: 1
|
|
102
|
+
}
|
|
103
|
+
} : {}
|
|
104
|
+
const findOptions: FindOptions = {
|
|
105
|
+
...params.mongodb,
|
|
106
|
+
...projection
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return Promise.resolve(Model).then(model => model.findOne(query, findOptions))
|
|
110
|
+
.then(data => {
|
|
111
|
+
if (data == null) {
|
|
112
|
+
throw new NotFound(`No record found for id '${id}'`)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return data
|
|
116
|
+
})
|
|
117
|
+
.catch(errorHandler)
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
async $find (params?: P & { paginate?: PaginationOptions }): Promise<Paginated<T>>;
|
|
121
|
+
async $find (params?: P & { paginate: false }): Promise<T[]>;
|
|
122
|
+
async $find (params?: P): Promise<Paginated<T>|T[]>;
|
|
123
|
+
async $find (params: P = {} as P): Promise<Paginated<T>|T[]> {
|
|
124
|
+
const { filters, query } = this.filterQuery(null, params)
|
|
125
|
+
const { paginate, Model, useEstimatedDocumentCount } = this.getOptions(params)
|
|
126
|
+
const findOptions = { ...params.mongodb }
|
|
127
|
+
const model = await Promise.resolve(Model)
|
|
128
|
+
const q = model.find(query, findOptions)
|
|
129
|
+
|
|
130
|
+
if (filters.$select !== undefined) {
|
|
131
|
+
q.project(this.getSelect(filters.$select))
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (filters.$sort !== undefined) {
|
|
135
|
+
q.sort(filters.$sort)
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (filters.$limit !== undefined) {
|
|
139
|
+
q.limit(filters.$limit)
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (filters.$skip !== undefined) {
|
|
143
|
+
q.skip(filters.$skip)
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const runQuery = async (total: number) => ({
|
|
147
|
+
total,
|
|
148
|
+
limit: filters.$limit,
|
|
149
|
+
skip: filters.$skip || 0,
|
|
150
|
+
data: filters.$limit === 0 ? [] : (await q.toArray()) as any as T[]
|
|
151
|
+
})
|
|
152
|
+
|
|
153
|
+
if (paginate && paginate.default) {
|
|
154
|
+
if (useEstimatedDocumentCount && (typeof model.estimatedDocumentCount === 'function')) {
|
|
155
|
+
return model.estimatedDocumentCount().then(runQuery)
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return model.countDocuments(query, findOptions).then(runQuery)
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return runQuery(0).then(page => page.data)
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
async $create (data: Partial<D>, params?: P): Promise<T>;
|
|
165
|
+
async $create (data: Partial<D>[], params?: P): Promise<T[]>;
|
|
166
|
+
async $create (data: Partial<D>|Partial<D>[], _params?: P): Promise<T|T[]>;
|
|
167
|
+
async $create (data: Partial<D>|Partial<D>[], params: P = {} as P): Promise<T|T[]> {
|
|
168
|
+
const writeOptions = params.mongodb
|
|
169
|
+
const { Model } = this.getOptions(params)
|
|
170
|
+
const model = await Promise.resolve(Model)
|
|
171
|
+
const setId = (item: any) => {
|
|
172
|
+
const entry = Object.assign({}, item)
|
|
173
|
+
|
|
174
|
+
// Generate a MongoId if we use a custom id
|
|
175
|
+
if (this.id !== '_id' && typeof entry[this.id] === 'undefined') {
|
|
176
|
+
return {
|
|
177
|
+
[this.id]: new ObjectId().toHexString(),
|
|
178
|
+
...entry
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return entry
|
|
183
|
+
}
|
|
184
|
+
const promise = Array.isArray(data)
|
|
185
|
+
? model.insertMany(data.map(setId), writeOptions).then(async result =>
|
|
186
|
+
Promise.all(Object.values(result.insertedIds).map(async _id => model.findOne({ _id })))
|
|
187
|
+
)
|
|
188
|
+
: model.insertOne(setId(data), writeOptions).then(async result =>
|
|
189
|
+
model.findOne({ _id: result.insertedId })
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
return promise.then(select(params, this.id)).catch(errorHandler)
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
async $patch (id: null, data: Partial<D>, params?: P): Promise<T[]>;
|
|
196
|
+
async $patch (id: Id, data: Partial<D>, params?: P): Promise<T>;
|
|
197
|
+
async $patch (id: NullableId, data: Partial<D>, _params?: P): Promise<T|T[]>;
|
|
198
|
+
async $patch (id: NullableId, _data: Partial<D>, params: P = {} as P): Promise<T|T[]> {
|
|
199
|
+
const data = this.normalizeId(id, _data)
|
|
200
|
+
const { Model } = this.getOptions(params)
|
|
201
|
+
const model = await Promise.resolve(Model)
|
|
202
|
+
const { query, filters: { $select, $limit } } = this.filterQuery(id, params)
|
|
203
|
+
const updateOptions = { ...params.mongodb }
|
|
204
|
+
const modifier = Object.keys(data).reduce((current, key) => {
|
|
205
|
+
const value = (data as any)[key]
|
|
206
|
+
|
|
207
|
+
if (key.charAt(0) !== '$') {
|
|
208
|
+
current.$set = {
|
|
209
|
+
...current.$set,
|
|
210
|
+
[key]: value
|
|
211
|
+
}
|
|
212
|
+
} else {
|
|
213
|
+
current[key] = value
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
return current
|
|
217
|
+
}, {} as any)
|
|
218
|
+
const originalIds = await this.$findOrGet(id, {
|
|
219
|
+
...params,
|
|
220
|
+
query: {
|
|
221
|
+
...query,
|
|
222
|
+
$select: [ this.id ]
|
|
223
|
+
},
|
|
224
|
+
paginate: false
|
|
225
|
+
})
|
|
226
|
+
const items = (Array.isArray(originalIds) ? originalIds : [originalIds])
|
|
227
|
+
const idList = items.map((item: any) => item[this.id])
|
|
228
|
+
const findParams = {
|
|
229
|
+
...params,
|
|
230
|
+
paginate: false,
|
|
231
|
+
query: {
|
|
232
|
+
...($limit === 0 ? { $limit: 0 } : {}),
|
|
233
|
+
[this.id]: { $in: idList },
|
|
234
|
+
$select
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
await model.updateMany(query, modifier, updateOptions)
|
|
239
|
+
|
|
240
|
+
return this.$findOrGet(id, findParams).catch(errorHandler)
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
async $update (id: Id, data: D, params: P = {} as P): Promise<T> {
|
|
244
|
+
const { Model } = this.getOptions(params)
|
|
245
|
+
const model = await Promise.resolve(Model)
|
|
246
|
+
const { query } = this.filterQuery(id, params)
|
|
247
|
+
const replaceOptions = { ...params.mongodb }
|
|
248
|
+
|
|
249
|
+
await model.replaceOne(query, this.normalizeId(id, data), replaceOptions)
|
|
250
|
+
|
|
251
|
+
return this.$findOrGet(id, params).catch(errorHandler)
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
async $remove (id: null, params?: P): Promise<T[]>;
|
|
255
|
+
async $remove (id: Id, params?: P): Promise<T>;
|
|
256
|
+
async $remove (id: NullableId, _params?: P): Promise<T|T[]>;
|
|
257
|
+
async $remove (id: NullableId, params: P = {} as P): Promise<T|T[]> {
|
|
258
|
+
const { Model } = this.getOptions(params)
|
|
259
|
+
const model = await Promise.resolve(Model)
|
|
260
|
+
const { query, filters: { $select, $limit } } = this.filterQuery(id, params)
|
|
261
|
+
const deleteOptions = { ...params.mongodb }
|
|
262
|
+
const findParams = {
|
|
263
|
+
...params,
|
|
264
|
+
paginate: false,
|
|
265
|
+
query: {
|
|
266
|
+
...query,
|
|
267
|
+
...($limit === 0 ? { $limit: 0 } : {}),
|
|
268
|
+
$select
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
return this.$findOrGet(id, findParams)
|
|
273
|
+
.then(async items => {
|
|
274
|
+
await model.deleteMany(query, deleteOptions)
|
|
275
|
+
return items
|
|
276
|
+
})
|
|
277
|
+
.catch(errorHandler)
|
|
278
|
+
}
|
|
279
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { GeneralError } from '@feathersjs/errors'
|
|
2
|
+
import { MongoError } from 'mongodb'
|
|
3
|
+
|
|
4
|
+
export function errorHandler (error: MongoError): any {
|
|
5
|
+
// See https://github.com/mongodb/mongo/blob/master/docs/errors.md
|
|
6
|
+
if (error && error.name && error.name.startsWith('Mongo')) {
|
|
7
|
+
throw new GeneralError(error, {
|
|
8
|
+
name: error.name,
|
|
9
|
+
code: error.code
|
|
10
|
+
})
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
throw error
|
|
14
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { PaginationOptions } from '@feathersjs/adapter-commons'
|
|
2
|
+
import { Paginated, ServiceMethods, Id, NullableId } from '@feathersjs/feathers'
|
|
3
|
+
import { MongoDbAdapter, MongoDBAdapterParams } from './adapter'
|
|
4
|
+
|
|
5
|
+
export * from './adapter'
|
|
6
|
+
export * from './error-handler'
|
|
7
|
+
|
|
8
|
+
export class MongoDBService<T = any, D = Partial<T>, P extends MongoDBAdapterParams = MongoDBAdapterParams>
|
|
9
|
+
extends MongoDbAdapter<T, D, P> implements ServiceMethods<T|Paginated<T>, D, P> {
|
|
10
|
+
async find (params?: P & { paginate?: PaginationOptions }): Promise<Paginated<T>>;
|
|
11
|
+
async find (params?: P & { paginate: false }): Promise<T[]>;
|
|
12
|
+
async find (params?: P): Promise<Paginated<T>|T[]>;
|
|
13
|
+
async find (params?: P): Promise<Paginated<T>|T[]> {
|
|
14
|
+
return this._find(params) as any
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async get (id: Id, params?: P): Promise<T> {
|
|
18
|
+
return this._get(id, params)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async create (data: Partial<D>, params?: P): Promise<T>;
|
|
22
|
+
async create (data: Partial<D>[], params?: P): Promise<T[]>;
|
|
23
|
+
async create (data: Partial<D>|Partial<D>[], params?: P): Promise<T|T[]> {
|
|
24
|
+
return this._create(data, params)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async update (id: Id, data: D, params?: P): Promise<T> {
|
|
28
|
+
return this._update(id, data, params)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async patch (id: Id, data: Partial<D>, params?: P): Promise<T>;
|
|
32
|
+
async patch (id: null, data: Partial<D>, params?: P): Promise<T[]>;
|
|
33
|
+
async patch (id: NullableId, data: Partial<D>, params?: P): Promise<T | T[]> {
|
|
34
|
+
return this._patch(id, data, params)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async remove (id: Id, params?: P): Promise<T>;
|
|
38
|
+
async remove (id: null, params?: P): Promise<T[]>;
|
|
39
|
+
async remove (id: NullableId, params?: P): Promise<T | T[]> {
|
|
40
|
+
return this._remove(id, params)
|
|
41
|
+
}
|
|
42
|
+
}
|