@bedrockio/model 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -0
- package/dist/cjs/access.js +4 -0
- package/dist/cjs/assign.js +2 -3
- package/dist/cjs/disallowed.js +40 -0
- package/dist/cjs/include.js +3 -2
- package/dist/cjs/load.js +15 -3
- package/dist/cjs/schema.js +29 -12
- package/dist/cjs/search.js +16 -16
- package/dist/cjs/serialization.js +2 -3
- package/dist/cjs/soft-delete.js +234 -55
- package/dist/cjs/testing.js +8 -0
- package/dist/cjs/validation.js +109 -43
- package/package.json +9 -7
- package/src/access.js +3 -0
- package/src/disallowed.js +63 -0
- package/src/include.js +1 -0
- package/src/load.js +12 -1
- package/src/schema.js +25 -5
- package/src/search.js +21 -10
- package/src/soft-delete.js +238 -85
- package/src/testing.js +7 -0
- package/src/validation.js +134 -43
- package/types/access.d.ts +7 -0
- package/types/access.d.ts.map +1 -0
- package/types/assign.d.ts +2 -0
- package/types/assign.d.ts.map +1 -0
- package/types/const.d.ts +9 -0
- package/types/const.d.ts.map +1 -0
- package/types/disallowed.d.ts +2 -0
- package/types/disallowed.d.ts.map +1 -0
- package/types/errors.d.ts +9 -0
- package/types/errors.d.ts.map +1 -0
- package/types/include.d.ts +4 -0
- package/types/include.d.ts.map +1 -0
- package/types/index.d.ts +6 -0
- package/types/index.d.ts.map +1 -0
- package/types/load.d.ts +15 -0
- package/types/load.d.ts.map +1 -0
- package/types/references.d.ts +2 -0
- package/types/references.d.ts.map +1 -0
- package/types/schema.d.ts +71 -0
- package/types/schema.d.ts.map +1 -0
- package/types/search.d.ts +303 -0
- package/types/search.d.ts.map +1 -0
- package/types/serialization.d.ts +6 -0
- package/types/serialization.d.ts.map +1 -0
- package/types/slug.d.ts +2 -0
- package/types/slug.d.ts.map +1 -0
- package/types/soft-delete.d.ts +4 -0
- package/types/soft-delete.d.ts.map +1 -0
- package/types/testing.d.ts +11 -0
- package/types/testing.d.ts.map +1 -0
- package/types/utils.d.ts +8 -0
- package/types/utils.d.ts.map +1 -0
- package/types/validation.d.ts +13 -0
- package/types/validation.d.ts.map +1 -0
- package/types/warn.d.ts +2 -0
- package/types/warn.d.ts.map +1 -0
- package/babel.config.cjs +0 -41
- package/jest.config.js +0 -8
- package/test/assign.test.js +0 -225
- package/test/definitions/custom-model.json +0 -9
- package/test/definitions/special-category.json +0 -18
- package/test/include.test.js +0 -896
- package/test/load.test.js +0 -47
- package/test/references.test.js +0 -71
- package/test/schema.test.js +0 -919
- package/test/search.test.js +0 -652
- package/test/serialization.test.js +0 -748
- package/test/setup.js +0 -27
- package/test/slug.test.js +0 -112
- package/test/soft-delete.test.js +0 -333
- package/test/validation.test.js +0 -1925
package/README.md
CHANGED
|
@@ -378,6 +378,30 @@ Due to ambiguity with the soft delete module, the following methods will throw a
|
|
|
378
378
|
- `Model.findOneAndRemove` - Use `Model.findOneAndDelete` instead.
|
|
379
379
|
- `Model.findByIdAndRemove` - Use `Model.findByIdAndDelete` instead.
|
|
380
380
|
|
|
381
|
+
#### Unique Constraints
|
|
382
|
+
|
|
383
|
+
Note that although monogoose allows a `unique` option on fields, this will add a unique index to the mongo collection itself which is incompatible with soft deletion.
|
|
384
|
+
|
|
385
|
+
This package will intercept `unique: true` to create a soft delete compatible validation which will:
|
|
386
|
+
|
|
387
|
+
- Throw an error if other non-deleted documents with the same fields exist when calling:
|
|
388
|
+
- `Document.save`
|
|
389
|
+
- `Document.update`
|
|
390
|
+
- `Document.restore`
|
|
391
|
+
- `Model.updateOne` (see note below)
|
|
392
|
+
- `Model.updateMany` (see note below)
|
|
393
|
+
- `Model.restoreOne`
|
|
394
|
+
- `Model.restoreMany`
|
|
395
|
+
- `Model.insertMany`
|
|
396
|
+
- `Model.replaceOne`
|
|
397
|
+
- Append the same validation to `Model.getCreateSchema` and `Model.getUpdateSchema` to allow this constraint to trickle down to the API.
|
|
398
|
+
|
|
399
|
+
> :warning: updateOne and updateMany
|
|
400
|
+
>
|
|
401
|
+
> Note that calling `Model.updateOne` will throw an error when a unique field exists on any document **including the document being updated**. This is an intentional constraint that allows `updateOne` better peformance by not having to fetch the ids of the documents being updated in order to exclude them. To avoid this call `Document.save` instead.
|
|
402
|
+
>
|
|
403
|
+
> Note also that calling `Model.updateMany` with a unique field passed will always throw an error as the result would inherently be non-unique.
|
|
404
|
+
|
|
381
405
|
### Validation
|
|
382
406
|
|
|
383
407
|
Models are extended with methods that allow complex validation that derives from the schema. Bedrock validation is generally used at the API level:
|
package/dist/cjs/access.js
CHANGED
|
@@ -15,6 +15,10 @@ function hasReadAccess(allowed, options) {
|
|
|
15
15
|
function hasWriteAccess(allowed, options) {
|
|
16
16
|
return hasAccess('write', allowed, options);
|
|
17
17
|
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @param {string|string[]} allowed
|
|
21
|
+
*/
|
|
18
22
|
function hasAccess(type, allowed = 'all', options = {}) {
|
|
19
23
|
if (allowed === 'all') {
|
|
20
24
|
return true;
|
package/dist/cjs/assign.js
CHANGED
|
@@ -4,9 +4,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.applyAssign = applyAssign;
|
|
7
|
-
var
|
|
7
|
+
var _lodash = require("lodash");
|
|
8
8
|
var _utils = require("./utils");
|
|
9
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
10
9
|
function applyAssign(schema) {
|
|
11
10
|
schema.method('assign', function assign(fields) {
|
|
12
11
|
unsetReferenceFields(fields, schema.obj);
|
|
@@ -40,7 +39,7 @@ function unsetReferenceFields(fields, schema = {}) {
|
|
|
40
39
|
function flattenObject(obj, root = {}, rootPath = []) {
|
|
41
40
|
for (let [key, val] of Object.entries(obj)) {
|
|
42
41
|
const path = [...rootPath, key];
|
|
43
|
-
if ((0,
|
|
42
|
+
if ((0, _lodash.isPlainObject)(val)) {
|
|
44
43
|
flattenObject(val, root, path);
|
|
45
44
|
} else {
|
|
46
45
|
root[path.join('.')] = val;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.applyDisallowed = applyDisallowed;
|
|
7
|
+
var _warn = _interopRequireDefault(require("./warn"));
|
|
8
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
9
|
+
function applyDisallowed(schema) {
|
|
10
|
+
schema.method('remove', function () {
|
|
11
|
+
(0, _warn.default)('The "remove" method on documents is disallowed due to ambiguity.', 'To permanently delete a document use "destroy", otherwise "delete".');
|
|
12
|
+
throw new Error('Method not allowed.');
|
|
13
|
+
}, {
|
|
14
|
+
suppressWarning: true
|
|
15
|
+
});
|
|
16
|
+
schema.method('update', function () {
|
|
17
|
+
(0, _warn.default)('The "update" method on documents is deprecated. Use "updateOne" instead.');
|
|
18
|
+
throw new Error('Method not allowed.');
|
|
19
|
+
});
|
|
20
|
+
schema.method('deleteOne', function () {
|
|
21
|
+
(0, _warn.default)('The "deleteOne" method on documents is disallowed due to ambiguity', 'Use either "delete" or "deleteOne" on the model.');
|
|
22
|
+
throw new Error('Method not allowed.');
|
|
23
|
+
});
|
|
24
|
+
schema.static('remove', function () {
|
|
25
|
+
(0, _warn.default)('The "remove" method on models is disallowed due to ambiguity.', 'To permanently delete a document use "destroyMany", otherwise "deleteMany".');
|
|
26
|
+
throw new Error('Method not allowed.');
|
|
27
|
+
});
|
|
28
|
+
schema.static('findOneAndRemove', function () {
|
|
29
|
+
(0, _warn.default)('The "findOneAndRemove" method on models is disallowed due to ambiguity.', 'To permanently delete a document use "findOneAndDestroy", otherwise "findOneAndDelete".');
|
|
30
|
+
throw new Error('Method not allowed.');
|
|
31
|
+
});
|
|
32
|
+
schema.static('findByIdAndRemove', function () {
|
|
33
|
+
(0, _warn.default)('The "findByIdAndRemove" method on models is disallowed due to ambiguity.', 'To permanently delete a document use "findByIdAndDestroy", otherwise "findByIdAndDelete".');
|
|
34
|
+
throw new Error('Method not allowed.');
|
|
35
|
+
});
|
|
36
|
+
schema.static('count', function () {
|
|
37
|
+
(0, _warn.default)('The "count" method on models is deprecated. Use "countDocuments" instead.');
|
|
38
|
+
throw new Error('Method not allowed.');
|
|
39
|
+
});
|
|
40
|
+
}
|
package/dist/cjs/include.js
CHANGED
|
@@ -6,11 +6,12 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.applyInclude = applyInclude;
|
|
7
7
|
exports.checkSelects = checkSelects;
|
|
8
8
|
exports.getIncludes = getIncludes;
|
|
9
|
-
var _escapeRegExp2 = _interopRequireDefault(require("lodash/escapeRegExp"));
|
|
10
9
|
var _mongoose = _interopRequireDefault(require("mongoose"));
|
|
10
|
+
var _lodash = require("lodash");
|
|
11
11
|
var _utils = require("./utils");
|
|
12
12
|
var _const = require("./const");
|
|
13
13
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
14
|
+
// @ts-ignore
|
|
14
15
|
// Overloading mongoose Query prototype to
|
|
15
16
|
// allow an "include" method for queries.
|
|
16
17
|
_mongoose.default.Query.prototype.include = function include(paths) {
|
|
@@ -205,7 +206,7 @@ function setNodePath(node, options) {
|
|
|
205
206
|
function resolvePaths(schema, str) {
|
|
206
207
|
let paths;
|
|
207
208
|
if (str.includes('*')) {
|
|
208
|
-
let source = (0,
|
|
209
|
+
let source = (0, _lodash.escapeRegExp)(str);
|
|
209
210
|
source = source.replaceAll('\\*\\*', '.+');
|
|
210
211
|
source = source.replaceAll('\\*', '[^.]+');
|
|
211
212
|
source = `^${source}$`;
|
package/dist/cjs/load.js
CHANGED
|
@@ -5,12 +5,18 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.loadModel = loadModel;
|
|
7
7
|
exports.loadModelDir = loadModelDir;
|
|
8
|
-
var _startCase2 = _interopRequireDefault(require("lodash/startCase"));
|
|
9
8
|
var _fs = _interopRequireDefault(require("fs"));
|
|
10
9
|
var _path = _interopRequireDefault(require("path"));
|
|
11
10
|
var _mongoose = _interopRequireDefault(require("mongoose"));
|
|
11
|
+
var _lodash = require("lodash");
|
|
12
12
|
var _schema = require("./schema");
|
|
13
13
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
14
|
+
/**
|
|
15
|
+
* Loads a single model by definition and name.
|
|
16
|
+
* @param {object} definition
|
|
17
|
+
* @param {string} name
|
|
18
|
+
* @returns mongoose.Model
|
|
19
|
+
*/
|
|
14
20
|
function loadModel(definition, name) {
|
|
15
21
|
if (!definition.attributes) {
|
|
16
22
|
throw new Error(`Invalid model definition for ${name}, need attributes`);
|
|
@@ -22,15 +28,21 @@ function loadModel(definition, name) {
|
|
|
22
28
|
throw new Error(`${err.message} (loading ${name})`);
|
|
23
29
|
}
|
|
24
30
|
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Loads all model definitions in the given directory.
|
|
34
|
+
* Returns the full loaded model set.
|
|
35
|
+
* @param {string} dirPath
|
|
36
|
+
*/
|
|
25
37
|
function loadModelDir(dirPath) {
|
|
26
38
|
const files = _fs.default.readdirSync(dirPath);
|
|
27
39
|
for (const file of files) {
|
|
28
40
|
const basename = _path.default.basename(file, '.json');
|
|
29
41
|
if (file.match(/\.json$/)) {
|
|
30
42
|
const filePath = _path.default.join(dirPath, file);
|
|
31
|
-
const data = _fs.default.readFileSync(filePath);
|
|
43
|
+
const data = _fs.default.readFileSync(filePath, 'utf-8');
|
|
32
44
|
const definition = JSON.parse(data);
|
|
33
|
-
const modelName = definition.modelName || (0,
|
|
45
|
+
const modelName = definition.modelName || (0, _lodash.startCase)(basename).replace(/\s/g, '');
|
|
34
46
|
if (!_mongoose.default.models[modelName]) {
|
|
35
47
|
loadModel(definition, modelName);
|
|
36
48
|
}
|
package/dist/cjs/schema.js
CHANGED
|
@@ -6,11 +6,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.RESERVED_FIELDS = void 0;
|
|
7
7
|
exports.createSchema = createSchema;
|
|
8
8
|
exports.normalizeAttributes = normalizeAttributes;
|
|
9
|
-
var _camelCase2 = _interopRequireDefault(require("lodash/camelCase"));
|
|
10
|
-
var _capitalize2 = _interopRequireDefault(require("lodash/capitalize"));
|
|
11
|
-
var _isPlainObject2 = _interopRequireDefault(require("lodash/isPlainObject"));
|
|
12
|
-
var _pick2 = _interopRequireDefault(require("lodash/pick"));
|
|
13
9
|
var _mongoose = _interopRequireDefault(require("mongoose"));
|
|
10
|
+
var _lodash = require("lodash");
|
|
14
11
|
var _utils = require("./utils");
|
|
15
12
|
var _serialization = require("./serialization");
|
|
16
13
|
var _slug = require("./slug");
|
|
@@ -19,9 +16,19 @@ var _assign = require("./assign");
|
|
|
19
16
|
var _include = require("./include");
|
|
20
17
|
var _references = require("./references");
|
|
21
18
|
var _softDelete = require("./soft-delete");
|
|
19
|
+
var _disallowed = require("./disallowed");
|
|
22
20
|
var _validation = require("./validation");
|
|
23
21
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
24
22
|
const RESERVED_FIELDS = ['createdAt', 'updatedAt', 'deletedAt', 'deleted'];
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Creates a new Mongoose schema with Bedrock extensions
|
|
26
|
+
* applied. For more about syntax and functionality see
|
|
27
|
+
* [the documentation](https://github.com/bedrockio/model#schemas).
|
|
28
|
+
* @param {object} definition
|
|
29
|
+
* @param {mongoose.SchemaOptions} options
|
|
30
|
+
* @returns mongoose.Schema
|
|
31
|
+
*/
|
|
25
32
|
exports.RESERVED_FIELDS = RESERVED_FIELDS;
|
|
26
33
|
function createSchema(definition, options = {}) {
|
|
27
34
|
const schema = new _mongoose.default.Schema(attributesToMongoose(normalizeAttributes({
|
|
@@ -42,13 +49,14 @@ function createSchema(definition, options = {}) {
|
|
|
42
49
|
toObject: _serialization.serializeOptions,
|
|
43
50
|
...options
|
|
44
51
|
});
|
|
45
|
-
(0, _softDelete.applySoftDelete)(schema, definition);
|
|
46
52
|
(0, _validation.applyValidation)(schema, definition);
|
|
47
|
-
(0, _references.applyReferences)(schema, definition);
|
|
48
|
-
(0, _include.applyInclude)(schema, definition);
|
|
49
53
|
(0, _search.applySearch)(schema, definition);
|
|
50
|
-
(0,
|
|
51
|
-
(0,
|
|
54
|
+
(0, _softDelete.applySoftDelete)(schema);
|
|
55
|
+
(0, _references.applyReferences)(schema);
|
|
56
|
+
(0, _disallowed.applyDisallowed)(schema);
|
|
57
|
+
(0, _include.applyInclude)(schema);
|
|
58
|
+
(0, _assign.applyAssign)(schema);
|
|
59
|
+
(0, _slug.applySlug)(schema);
|
|
52
60
|
return schema;
|
|
53
61
|
}
|
|
54
62
|
function normalizeAttributes(arg, path = []) {
|
|
@@ -115,7 +123,7 @@ function attributesToMongoose(attributes) {
|
|
|
115
123
|
// Allow custom mongoose validation function that derives from the schema.
|
|
116
124
|
val = (0, _validation.getNamedValidator)(val);
|
|
117
125
|
}
|
|
118
|
-
} else if ((0,
|
|
126
|
+
} else if ((0, _lodash.isPlainObject)(val)) {
|
|
119
127
|
if (isScopeExtension(val)) {
|
|
120
128
|
applyScopeExtension(val, definition);
|
|
121
129
|
continue;
|
|
@@ -160,7 +168,7 @@ function assertRefs(field, path) {
|
|
|
160
168
|
}
|
|
161
169
|
}
|
|
162
170
|
function camelUpper(str) {
|
|
163
|
-
return (0,
|
|
171
|
+
return (0, _lodash.capitalize)((0, _lodash.camelCase)(str));
|
|
164
172
|
}
|
|
165
173
|
function isObjectIdType(type) {
|
|
166
174
|
return type === 'ObjectId' || type === _mongoose.default.Schema.Types.ObjectId;
|
|
@@ -170,6 +178,7 @@ function isMongooseType(type) {
|
|
|
170
178
|
}
|
|
171
179
|
function applyExtensions(typedef) {
|
|
172
180
|
applySyntaxExtensions(typedef);
|
|
181
|
+
applyUniqueExtension(typedef);
|
|
173
182
|
applyTupleExtension(typedef);
|
|
174
183
|
}
|
|
175
184
|
function applySyntaxExtensions(typedef) {
|
|
@@ -192,7 +201,7 @@ function applySyntaxExtensions(typedef) {
|
|
|
192
201
|
// Hoist read/write scopes from a nested element.
|
|
193
202
|
// See the readme for more.
|
|
194
203
|
function applyOptionHoisting(typedef) {
|
|
195
|
-
Object.assign(typedef, (0,
|
|
204
|
+
Object.assign(typedef, (0, _lodash.pick)(typedef.type[0], 'readAccess', 'writeAccess'));
|
|
196
205
|
}
|
|
197
206
|
function isExtendedSyntax(typedef) {
|
|
198
207
|
const {
|
|
@@ -228,6 +237,14 @@ function applyTupleExtension(typedef) {
|
|
|
228
237
|
typedef.validate = (0, _validation.getTupleValidator)(type);
|
|
229
238
|
}
|
|
230
239
|
}
|
|
240
|
+
|
|
241
|
+
// Intercepts "unique" options and changes to "softUnique".
|
|
242
|
+
function applyUniqueExtension(typedef) {
|
|
243
|
+
if (typedef.unique === true) {
|
|
244
|
+
typedef.softUnique = true;
|
|
245
|
+
delete typedef.unique;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
231
248
|
function applyArrayValidators(typedef) {
|
|
232
249
|
let {
|
|
233
250
|
minLength,
|
package/dist/cjs/search.js
CHANGED
|
@@ -5,13 +5,12 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.applySearch = applySearch;
|
|
7
7
|
exports.searchValidation = searchValidation;
|
|
8
|
-
var _isPlainObject2 = _interopRequireDefault(require("lodash/isPlainObject"));
|
|
9
|
-
var _isEmpty2 = _interopRequireDefault(require("lodash/isEmpty"));
|
|
10
|
-
var _pick2 = _interopRequireDefault(require("lodash/pick"));
|
|
11
8
|
var _yada = _interopRequireDefault(require("@bedrockio/yada"));
|
|
12
9
|
var _mongoose = _interopRequireDefault(require("mongoose"));
|
|
10
|
+
var _lodash = require("lodash");
|
|
13
11
|
var _utils = require("./utils");
|
|
14
12
|
var _const = require("./const");
|
|
13
|
+
var _validation = require("./validation");
|
|
15
14
|
var _warn = _interopRequireDefault(require("./warn"));
|
|
16
15
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
17
16
|
const {
|
|
@@ -20,7 +19,7 @@ const {
|
|
|
20
19
|
const SORT_SCHEMA = _yada.default.object({
|
|
21
20
|
field: _yada.default.string().required(),
|
|
22
21
|
order: _yada.default.string().allow('desc', 'asc').required()
|
|
23
|
-
});
|
|
22
|
+
}).description('An object describing the sort order of results.');
|
|
24
23
|
function applySearch(schema, definition) {
|
|
25
24
|
validateDefinition(definition);
|
|
26
25
|
schema.static('search', function search(body = {}) {
|
|
@@ -75,22 +74,23 @@ function applySearch(schema, definition) {
|
|
|
75
74
|
});
|
|
76
75
|
}
|
|
77
76
|
function searchValidation(definition, options = {}) {
|
|
77
|
+
options = {
|
|
78
|
+
..._const.SEARCH_DEFAULTS,
|
|
79
|
+
...(0, _lodash.pick)(definition.search, 'limit', 'sort'),
|
|
80
|
+
...options
|
|
81
|
+
};
|
|
78
82
|
const {
|
|
79
83
|
limit,
|
|
80
84
|
sort,
|
|
81
85
|
...rest
|
|
82
|
-
} =
|
|
83
|
-
..._const.SEARCH_DEFAULTS,
|
|
84
|
-
...(0, _pick2.default)(definition.search, 'limit', 'sort'),
|
|
85
|
-
...options
|
|
86
|
-
};
|
|
86
|
+
} = options;
|
|
87
87
|
return {
|
|
88
|
-
ids: _yada.default.array(
|
|
89
|
-
keyword: _yada.default.string(),
|
|
90
|
-
include: _yada.default.string(),
|
|
91
|
-
skip: _yada.default.number().default(0),
|
|
88
|
+
ids: _yada.default.array(_validation.OBJECT_ID_SCHEMA),
|
|
89
|
+
keyword: _yada.default.string().description('A keyword to perform a text search against.'),
|
|
90
|
+
include: _yada.default.string().description('Fields to be selected or populated.'),
|
|
91
|
+
skip: _yada.default.number().default(0).description('Number of records to skip.'),
|
|
92
92
|
sort: _yada.default.allow(SORT_SCHEMA, _yada.default.array(SORT_SCHEMA)).default(sort),
|
|
93
|
-
limit: _yada.default.number().positive().default(limit),
|
|
93
|
+
limit: _yada.default.number().positive().default(limit).description('Limits the number of results.'),
|
|
94
94
|
...rest
|
|
95
95
|
};
|
|
96
96
|
}
|
|
@@ -202,7 +202,7 @@ function normalizeQuery(query, schema, root = {}, rootPath = []) {
|
|
|
202
202
|
for (let [key, value] of Object.entries(query)) {
|
|
203
203
|
const path = [...rootPath, key];
|
|
204
204
|
if (isRangeQuery(schema, key, value)) {
|
|
205
|
-
if (!(0,
|
|
205
|
+
if (!(0, _lodash.isEmpty)(value)) {
|
|
206
206
|
root[path.join('.')] = mapOperatorQuery(value);
|
|
207
207
|
}
|
|
208
208
|
} else if (isNestedQuery(key, value)) {
|
|
@@ -220,7 +220,7 @@ function normalizeQuery(query, schema, root = {}, rootPath = []) {
|
|
|
220
220
|
return root;
|
|
221
221
|
}
|
|
222
222
|
function isNestedQuery(key, value) {
|
|
223
|
-
if (isMongoOperator(key) || !(0,
|
|
223
|
+
if (isMongoOperator(key) || !(0, _lodash.isPlainObject)(value)) {
|
|
224
224
|
return false;
|
|
225
225
|
}
|
|
226
226
|
return Object.keys(value).every(key => {
|
|
@@ -4,11 +4,10 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.serializeOptions = void 0;
|
|
7
|
-
var
|
|
7
|
+
var _lodash = require("lodash");
|
|
8
8
|
var _include = require("./include");
|
|
9
9
|
var _access = require("./access");
|
|
10
10
|
var _utils = require("./utils");
|
|
11
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
12
11
|
const serializeOptions = {
|
|
13
12
|
getters: true,
|
|
14
13
|
versionKey: false,
|
|
@@ -24,7 +23,7 @@ function transformField(obj, field, options) {
|
|
|
24
23
|
for (let el of obj) {
|
|
25
24
|
transformField(el, field, options);
|
|
26
25
|
}
|
|
27
|
-
} else if ((0,
|
|
26
|
+
} else if ((0, _lodash.isPlainObject)(obj)) {
|
|
28
27
|
for (let [key, val] of Object.entries(obj)) {
|
|
29
28
|
if (!isAllowedField(key, field, options)) {
|
|
30
29
|
delete obj[key];
|