@bedrockio/model 0.2.1 → 0.2.3
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 +5 -6
- package/dist/cjs/soft-delete.js +8 -1
- package/dist/cjs/validation.js +8 -8
- package/jest-mongodb-config.js +3 -1
- package/package.json +4 -4
- package/src/soft-delete.js +7 -1
- package/src/validation.js +8 -6
- package/types/soft-delete.d.ts.map +1 -1
- package/types/validation.d.ts.map +1 -1
- package/yarn-error.log +0 -6211
package/README.md
CHANGED
|
@@ -436,8 +436,7 @@ validation which will:
|
|
|
436
436
|
- Append the same validation to `Model.getCreateSchema` and
|
|
437
437
|
`Model.getUpdateSchema` to allow this constraint to trickle down to the API.
|
|
438
438
|
|
|
439
|
-
>
|
|
440
|
-
>
|
|
439
|
+
> [!WARNING]
|
|
441
440
|
> Note that calling `Model.updateOne` will throw an error when a unique field
|
|
442
441
|
> exists on any document **including the document being updated**. This is an
|
|
443
442
|
> intentional constraint that allows `updateOne` better peformance by not having
|
|
@@ -951,7 +950,7 @@ is set after verification:
|
|
|
951
950
|
A user is allowed to update the name of their own shop and admins can as well.
|
|
952
951
|
However, only admins can set the owner of the shop:
|
|
953
952
|
|
|
954
|
-
```
|
|
953
|
+
```jsonc
|
|
955
954
|
// shop.json
|
|
956
955
|
{
|
|
957
956
|
"name": {
|
|
@@ -1010,7 +1009,7 @@ check the document is the same as `authUser`.
|
|
|
1010
1009
|
Delete hooks are a powerful way to define what actions are taken on document
|
|
1011
1010
|
deletion. They are defined in the `onDelete` field of the model definition file:
|
|
1012
1011
|
|
|
1013
|
-
```
|
|
1012
|
+
```jsonc
|
|
1014
1013
|
// user.json
|
|
1015
1014
|
{
|
|
1016
1015
|
"attributes": {
|
|
@@ -1026,7 +1025,7 @@ deletion. They are defined in the `onDelete` field of the model definition file:
|
|
|
1026
1025
|
"foreign": {
|
|
1027
1026
|
Shop: "owner"
|
|
1028
1027
|
},
|
|
1029
|
-
}
|
|
1028
|
+
},
|
|
1030
1029
|
"errorOnReferenced": {
|
|
1031
1030
|
"except": ["AuditEntry"]
|
|
1032
1031
|
}
|
|
@@ -1094,7 +1093,7 @@ Models that have delete hooks defined on them will keep a reference of the
|
|
|
1094
1093
|
documents that were deleted. Calling `.restore()` on the document will also
|
|
1095
1094
|
restore these references.
|
|
1096
1095
|
|
|
1097
|
-
> [!
|
|
1096
|
+
> [!WARNING]
|
|
1098
1097
|
> Delete hooks are **only** run on a single document (`.delete` or `.restore`).
|
|
1099
1098
|
> They will not be run when using model methods like `deleteOne` or
|
|
1100
1099
|
> `deleteMany`.
|
package/dist/cjs/soft-delete.js
CHANGED
|
@@ -6,8 +6,10 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.applySoftDelete = applySoftDelete;
|
|
7
7
|
exports.assertUnique = assertUnique;
|
|
8
8
|
exports.hasUniqueConstraints = hasUniqueConstraints;
|
|
9
|
+
var _mongoose = _interopRequireDefault(require("mongoose"));
|
|
9
10
|
var _lodash = require("lodash");
|
|
10
11
|
var _query = require("./query");
|
|
12
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
11
13
|
function applySoftDelete(schema) {
|
|
12
14
|
applyQueries(schema);
|
|
13
15
|
applyUniqueConstraints(schema);
|
|
@@ -219,7 +221,7 @@ function applyUniqueConstraints(schema) {
|
|
|
219
221
|
return;
|
|
220
222
|
}
|
|
221
223
|
schema.pre('save', async function () {
|
|
222
|
-
await assertUnique(this
|
|
224
|
+
await assertUnique(this, {
|
|
223
225
|
operation: this.isNew ? 'create' : 'update',
|
|
224
226
|
model: this.constructor,
|
|
225
227
|
schema
|
|
@@ -340,6 +342,11 @@ function resolveUnique(schema, obj, map = {}, path = []) {
|
|
|
340
342
|
for (let el of obj) {
|
|
341
343
|
resolveUnique(schema, el, map, path);
|
|
342
344
|
}
|
|
345
|
+
} else if (obj instanceof _mongoose.default.Document) {
|
|
346
|
+
obj.schema.eachPath(key => {
|
|
347
|
+
const val = obj.get(key);
|
|
348
|
+
resolveUnique(schema, val, map, [...path, key]);
|
|
349
|
+
});
|
|
343
350
|
} else if (obj && typeof obj === 'object') {
|
|
344
351
|
for (let [key, val] of Object.entries(obj)) {
|
|
345
352
|
resolveUnique(schema, val, map, [...path, key]);
|
package/dist/cjs/validation.js
CHANGED
|
@@ -131,7 +131,7 @@ function applyValidation(schema, definition) {
|
|
|
131
131
|
allowInclude: true,
|
|
132
132
|
expandDotSyntax: true,
|
|
133
133
|
unwindArrayFields: true,
|
|
134
|
-
|
|
134
|
+
requireSearchAccess: true,
|
|
135
135
|
stripDeleted: !includeDeleted,
|
|
136
136
|
appendSchema: (0, _search.searchValidation)({
|
|
137
137
|
defaults,
|
|
@@ -297,7 +297,7 @@ function getSchemaForTypedef(typedef, options = {}) {
|
|
|
297
297
|
if (options.allowSearch) {
|
|
298
298
|
schema = getSearchSchema(schema, type);
|
|
299
299
|
}
|
|
300
|
-
if (typedef.readAccess && options.
|
|
300
|
+
if (typedef.readAccess && options.requireSearchAccess) {
|
|
301
301
|
schema = validateReadAccess(schema, typedef.readAccess, options);
|
|
302
302
|
}
|
|
303
303
|
if (typedef.writeAccess && options.requireWriteAccess) {
|
|
@@ -375,13 +375,13 @@ function isRequired(typedef, options) {
|
|
|
375
375
|
}
|
|
376
376
|
function isExcludedField(field, options) {
|
|
377
377
|
if ((0, _utils.isSchemaTypedef)(field)) {
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
return false;
|
|
378
|
+
if (options.requireWriteAccess) {
|
|
379
|
+
return field.writeAccess === 'none';
|
|
380
|
+
} else if (options.requireSearchAccess) {
|
|
381
|
+
return field.readAccess === 'none' || field.readAccess === 'self';
|
|
382
|
+
}
|
|
384
383
|
}
|
|
384
|
+
return false;
|
|
385
385
|
}
|
|
386
386
|
function validateReadAccess(schema, allowed, options) {
|
|
387
387
|
return validateAccess('read', schema, allowed, options);
|
package/jest-mongodb-config.js
CHANGED
package/package.json
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bedrockio/model",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"description": "Bedrock utilities for model creation.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"test": "jest",
|
|
8
|
+
"types": "tsc",
|
|
8
9
|
"lint": "eslint",
|
|
9
10
|
"build": "scripts/build",
|
|
10
|
-
"
|
|
11
|
+
"eject": "scripts/eject.js",
|
|
11
12
|
"prepublishOnly": "yarn build && yarn types"
|
|
12
13
|
},
|
|
13
14
|
"main": "dist/cjs/index.js",
|
|
@@ -39,12 +40,11 @@
|
|
|
39
40
|
"@bedrockio/prettier-config": "^1.0.2",
|
|
40
41
|
"@bedrockio/yada": "^1.0.34",
|
|
41
42
|
"@shelf/jest-mongodb": "^4.1.7",
|
|
42
|
-
"babel-plugin-import-replacement": "^1.0.1",
|
|
43
43
|
"eslint": "^8.33.0",
|
|
44
44
|
"eslint-plugin-bedrock": "^1.0.26",
|
|
45
45
|
"jest": "^29.4.1",
|
|
46
46
|
"jest-environment-node": "^29.4.1",
|
|
47
|
-
"mongodb": "^
|
|
47
|
+
"mongodb": "^6.2.0",
|
|
48
48
|
"mongoose": "^7.6.4",
|
|
49
49
|
"prettier-eslint": "^15.0.1",
|
|
50
50
|
"typescript": "^4.9.5"
|
package/src/soft-delete.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import mongoose from 'mongoose';
|
|
1
2
|
import { isEqual } from 'lodash';
|
|
2
3
|
|
|
3
4
|
import { wrapQuery } from './query';
|
|
@@ -251,7 +252,7 @@ function applyUniqueConstraints(schema) {
|
|
|
251
252
|
}
|
|
252
253
|
|
|
253
254
|
schema.pre('save', async function () {
|
|
254
|
-
await assertUnique(this
|
|
255
|
+
await assertUnique(this, {
|
|
255
256
|
operation: this.isNew ? 'create' : 'update',
|
|
256
257
|
model: this.constructor,
|
|
257
258
|
schema,
|
|
@@ -367,6 +368,11 @@ function resolveUnique(schema, obj, map = {}, path = []) {
|
|
|
367
368
|
for (let el of obj) {
|
|
368
369
|
resolveUnique(schema, el, map, path);
|
|
369
370
|
}
|
|
371
|
+
} else if (obj instanceof mongoose.Document) {
|
|
372
|
+
obj.schema.eachPath((key) => {
|
|
373
|
+
const val = obj.get(key);
|
|
374
|
+
resolveUnique(schema, val, map, [...path, key]);
|
|
375
|
+
});
|
|
370
376
|
} else if (obj && typeof obj === 'object') {
|
|
371
377
|
for (let [key, val] of Object.entries(obj)) {
|
|
372
378
|
resolveUnique(schema, val, map, [...path, key]);
|
package/src/validation.js
CHANGED
|
@@ -145,7 +145,7 @@ export function applyValidation(schema, definition) {
|
|
|
145
145
|
allowInclude: true,
|
|
146
146
|
expandDotSyntax: true,
|
|
147
147
|
unwindArrayFields: true,
|
|
148
|
-
|
|
148
|
+
requireSearchAccess: true,
|
|
149
149
|
stripDeleted: !includeDeleted,
|
|
150
150
|
appendSchema: searchValidation({
|
|
151
151
|
defaults,
|
|
@@ -314,7 +314,7 @@ function getSchemaForTypedef(typedef, options = {}) {
|
|
|
314
314
|
if (options.allowSearch) {
|
|
315
315
|
schema = getSearchSchema(schema, type);
|
|
316
316
|
}
|
|
317
|
-
if (typedef.readAccess && options.
|
|
317
|
+
if (typedef.readAccess && options.requireSearchAccess) {
|
|
318
318
|
schema = validateReadAccess(schema, typedef.readAccess, options);
|
|
319
319
|
}
|
|
320
320
|
if (typedef.writeAccess && options.requireWriteAccess) {
|
|
@@ -430,11 +430,13 @@ function isRequired(typedef, options) {
|
|
|
430
430
|
|
|
431
431
|
function isExcludedField(field, options) {
|
|
432
432
|
if (isSchemaTypedef(field)) {
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
433
|
+
if (options.requireWriteAccess) {
|
|
434
|
+
return field.writeAccess === 'none';
|
|
435
|
+
} else if (options.requireSearchAccess) {
|
|
436
|
+
return field.readAccess === 'none' || field.readAccess === 'self';
|
|
437
|
+
}
|
|
437
438
|
}
|
|
439
|
+
return false;
|
|
438
440
|
}
|
|
439
441
|
|
|
440
442
|
function validateReadAccess(schema, allowed, options) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"soft-delete.d.ts","sourceRoot":"","sources":["../src/soft-delete.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"soft-delete.d.ts","sourceRoot":"","sources":["../src/soft-delete.js"],"names":[],"mappings":"AAKA,mDAIC;AAiRD,oEAsBC;AAgDD,2DAKC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../src/validation.js"],"names":[],"mappings":"AAiFA,kDAEC;AAED,oEAkFC;AAsBD,wEAkBC;
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../src/validation.js"],"names":[],"mappings":"AAiFA,kDAEC;AAED,oEAkFC;AAsBD,wEAkBC;AA0RD;;;EAEC;AAED;;;EAOC;AAleD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAQK"}
|