@vulkano/core 1.20.2 → 1.22.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/README.md +380 -70
- package/controllers/controllers.js +36 -8
- package/database/mongodb.js +11 -4
- package/examples/config/express/cookies.js +15 -0
- package/examples/config/express/cors.js +23 -0
- package/examples/config/express/csp.js +74 -0
- package/examples/config/express/helmet.js +19 -0
- package/examples/config/express/json.js +14 -0
- package/examples/config/express/jwt.js +39 -0
- package/examples/config/express/permissionPolicy.js +24 -0
- package/examples/config/express/settings.js +25 -0
- package/examples/config/middlewares/auth.js +38 -0
- package/examples/config/sockets/adapters/mongodb.js +12 -0
- package/examples/config/sockets/adapters/redis.js +9 -0
- package/examples/config/sockets/config.js +50 -0
- package/examples/config/sockets/cors.js +32 -0
- package/examples/config/sockets/events.js +12 -0
- package/examples/config/sockets/middlewares/auth.js +20 -0
- package/examples/config/views/config.js +8 -0
- package/examples/config/views/filters/example.js +6 -0
- package/examples/config/views/helpers/strpad.js +51 -0
- package/examples/controllers/RestScaffoldController.js +3 -6
- package/examples/models/Example.js +64 -4
- package/examples/routes.js +55 -0
- package/package.json +2 -2
package/database/mongodb.js
CHANGED
|
@@ -175,12 +175,17 @@ module.exports = async function loadDatabaseApplication() {
|
|
|
175
175
|
}
|
|
176
176
|
|
|
177
177
|
// Update
|
|
178
|
+
// Bound to "updateOne" (the Mongoose 8 document method) rather than the
|
|
179
|
+
// legacy "update" hook name: Mongoose no longer fires "update" middleware,
|
|
180
|
+
// and that name collides with the scaffold's own `Model.update()` static
|
|
181
|
+
// (schema.statics.update), which Mongoose auto-wraps with any hook whose
|
|
182
|
+
// name matches an existing static method.
|
|
178
183
|
if (current.beforeUpdate) {
|
|
179
|
-
schema.pre('
|
|
184
|
+
schema.pre('updateOne', { document: true, query: false }, current.beforeUpdate);
|
|
180
185
|
delete schema.statics.beforeUpdate;
|
|
181
186
|
}
|
|
182
187
|
if (current.afterUpdate) {
|
|
183
|
-
schema.post('
|
|
188
|
+
schema.post('updateOne', { document: true, query: false }, current.afterUpdate);
|
|
184
189
|
delete schema.statics.afterUpdate;
|
|
185
190
|
}
|
|
186
191
|
|
|
@@ -195,12 +200,14 @@ module.exports = async function loadDatabaseApplication() {
|
|
|
195
200
|
}
|
|
196
201
|
|
|
197
202
|
// Remove
|
|
203
|
+
// Bound to "deleteOne" (the Mongoose 8 document method): `doc.remove()`
|
|
204
|
+
// and the legacy "remove" hook name were both removed upstream.
|
|
198
205
|
if (current.beforeRemove) {
|
|
199
|
-
schema.pre('
|
|
206
|
+
schema.pre('deleteOne', { document: true, query: false }, current.beforeRemove);
|
|
200
207
|
delete schema.statics.beforeRemove;
|
|
201
208
|
}
|
|
202
209
|
if (current.afterRemove) {
|
|
203
|
-
schema.post('
|
|
210
|
+
schema.post('deleteOne', { document: true, query: false }, current.afterRemove);
|
|
204
211
|
delete schema.statics.afterRemove;
|
|
205
212
|
}
|
|
206
213
|
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cookies Config
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
module.exports = {
|
|
6
|
+
|
|
7
|
+
// Enable cookie parser middleware
|
|
8
|
+
// @type Boolean
|
|
9
|
+
enabled: false,
|
|
10
|
+
|
|
11
|
+
// Secret key used to sign cookies — use https://api.wordpress.org/secret-key/1.1/salt/
|
|
12
|
+
// @type String
|
|
13
|
+
secret: process.env.COOKIES_SECRET_KEY || ''
|
|
14
|
+
|
|
15
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CORS Config
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
module.exports = {
|
|
6
|
+
|
|
7
|
+
// Enable CORS
|
|
8
|
+
// @type Boolean
|
|
9
|
+
enabled: false,
|
|
10
|
+
|
|
11
|
+
// Path where CORS headers are applied
|
|
12
|
+
// @type String
|
|
13
|
+
path: '/',
|
|
14
|
+
|
|
15
|
+
// Allowed origin
|
|
16
|
+
// @type String
|
|
17
|
+
origin: '*',
|
|
18
|
+
|
|
19
|
+
// Additional allowed request headers
|
|
20
|
+
// @type Array
|
|
21
|
+
headers: ['x-token-auth']
|
|
22
|
+
|
|
23
|
+
};
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Content Security Policy
|
|
3
|
+
*
|
|
4
|
+
* Requires an endpoint to receive CSP violation reports.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
module.exports = {
|
|
8
|
+
|
|
9
|
+
// Enable CSP
|
|
10
|
+
enabled: false,
|
|
11
|
+
|
|
12
|
+
// Reporting endpoint
|
|
13
|
+
report: {
|
|
14
|
+
group: 'csp-endpoint',
|
|
15
|
+
max_age: '10886400',
|
|
16
|
+
endpoints: [
|
|
17
|
+
{
|
|
18
|
+
// Replace with your domain
|
|
19
|
+
url: 'https://yourdomain.com/__cspreport__'
|
|
20
|
+
}
|
|
21
|
+
]
|
|
22
|
+
},
|
|
23
|
+
|
|
24
|
+
// CSP rules
|
|
25
|
+
rules: {
|
|
26
|
+
|
|
27
|
+
'default-src': ["'self'"],
|
|
28
|
+
|
|
29
|
+
'form-action': ["'self'"],
|
|
30
|
+
|
|
31
|
+
'font-src': [
|
|
32
|
+
"'self'",
|
|
33
|
+
'data:',
|
|
34
|
+
// 'fonts.googleapis.com',
|
|
35
|
+
// 'fonts.gstatic.com',
|
|
36
|
+
],
|
|
37
|
+
|
|
38
|
+
'img-src': [
|
|
39
|
+
"'self'",
|
|
40
|
+
'data:',
|
|
41
|
+
// '*.google-analytics.com',
|
|
42
|
+
],
|
|
43
|
+
|
|
44
|
+
'script-src': [
|
|
45
|
+
"'self'",
|
|
46
|
+
// "'unsafe-inline'",
|
|
47
|
+
// "'unsafe-eval'",
|
|
48
|
+
],
|
|
49
|
+
|
|
50
|
+
'style-src': [
|
|
51
|
+
"'self'",
|
|
52
|
+
"'unsafe-inline'",
|
|
53
|
+
'cdnjs.cloudflare.com'
|
|
54
|
+
],
|
|
55
|
+
|
|
56
|
+
'style-src-elem': [
|
|
57
|
+
"'self'",
|
|
58
|
+
// 'fonts.googleapis.com',
|
|
59
|
+
],
|
|
60
|
+
|
|
61
|
+
'frame-src': ["'self'"],
|
|
62
|
+
|
|
63
|
+
'frame-ancestors': ["'self'"],
|
|
64
|
+
|
|
65
|
+
'connect-src': [
|
|
66
|
+
"'self'",
|
|
67
|
+
// '*.google-analytics.com',
|
|
68
|
+
],
|
|
69
|
+
|
|
70
|
+
'report-to': ['csp-endpoint']
|
|
71
|
+
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helmet Config
|
|
3
|
+
* See https://helmetjs.github.io/ for all available options
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
module.exports = {
|
|
7
|
+
|
|
8
|
+
// Referrer policy header
|
|
9
|
+
referrerPolicy: {
|
|
10
|
+
policy: 'strict-origin-when-cross-origin'
|
|
11
|
+
},
|
|
12
|
+
|
|
13
|
+
// Disable built-in CSP — managed separately via csp.js
|
|
14
|
+
contentSecurityPolicy: false,
|
|
15
|
+
|
|
16
|
+
// Disable COEP to allow embedding cross-origin resources
|
|
17
|
+
crossOriginEmbedderPolicy: false
|
|
18
|
+
|
|
19
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JWT Config
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
module.exports = {
|
|
6
|
+
|
|
7
|
+
// Enable JWT
|
|
8
|
+
// @type Boolean
|
|
9
|
+
enabled: false,
|
|
10
|
+
|
|
11
|
+
// Secret key — use https://api.wordpress.org/secret-key/1.1/salt/ to generate one
|
|
12
|
+
// @type String
|
|
13
|
+
key: process.env.JWT_SECRET_KEY || '',
|
|
14
|
+
|
|
15
|
+
// Header name used to send the token
|
|
16
|
+
// @type String
|
|
17
|
+
header: 'x-token-auth',
|
|
18
|
+
|
|
19
|
+
// Query parameter name used to send the token
|
|
20
|
+
// @type String
|
|
21
|
+
queryParameter: 'token',
|
|
22
|
+
|
|
23
|
+
// Cookie name used to send the token
|
|
24
|
+
// @type String
|
|
25
|
+
cookieName: 'token',
|
|
26
|
+
|
|
27
|
+
// Path where the token is required
|
|
28
|
+
// @type String
|
|
29
|
+
path: '/api/',
|
|
30
|
+
|
|
31
|
+
// Paths excluded from token verification
|
|
32
|
+
// See https://github.com/jfromaniello/express-unless for pattern examples
|
|
33
|
+
// @type Array
|
|
34
|
+
ignore: [
|
|
35
|
+
'/api/',
|
|
36
|
+
/^\/api\/auth(?!\/(current))/i
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Permission Policy Config
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
module.exports = {
|
|
6
|
+
|
|
7
|
+
// Enable Permission Policy header
|
|
8
|
+
// @type Boolean
|
|
9
|
+
enabled: false,
|
|
10
|
+
|
|
11
|
+
// Browser features to restrict — empty list means blocked for all origins
|
|
12
|
+
// @type Array
|
|
13
|
+
permissions: [
|
|
14
|
+
'accelerometer=()',
|
|
15
|
+
'camera=()',
|
|
16
|
+
'geolocation=()',
|
|
17
|
+
'gyroscope=()',
|
|
18
|
+
'magnetometer=()',
|
|
19
|
+
'microphone=()',
|
|
20
|
+
'payment=()',
|
|
21
|
+
'usb=()'
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Express server settings
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
module.exports = {
|
|
6
|
+
|
|
7
|
+
// Show "X-Powered-By" header
|
|
8
|
+
// @type Boolean
|
|
9
|
+
poweredBy: false,
|
|
10
|
+
|
|
11
|
+
// Request timeout in milliseconds
|
|
12
|
+
// @type Number
|
|
13
|
+
timeout: 120000,
|
|
14
|
+
|
|
15
|
+
// Folder to upload files
|
|
16
|
+
// @type String
|
|
17
|
+
uploadPath: 'public/files',
|
|
18
|
+
|
|
19
|
+
// Number of proxy hops to trust for X-Forwarded-* headers.
|
|
20
|
+
// Use 1 when behind a single load balancer, true to trust all (less secure).
|
|
21
|
+
// See https://expressjs.com/en/guide/behind-proxies.html
|
|
22
|
+
// @type Number | Boolean
|
|
23
|
+
trustProxy: 1
|
|
24
|
+
|
|
25
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Middleware.js
|
|
3
|
+
*
|
|
4
|
+
* This file intercept all requests to make validations before running a controller
|
|
5
|
+
*
|
|
6
|
+
*/
|
|
7
|
+
module.exports = (req, res, next) => {
|
|
8
|
+
|
|
9
|
+
const {
|
|
10
|
+
auth: authEncripted
|
|
11
|
+
} = req;
|
|
12
|
+
|
|
13
|
+
if (authEncripted) {
|
|
14
|
+
const decoded = Jwt.decrypt(authEncripted);
|
|
15
|
+
req.auth = (decoded) ? { ...decoded, token: Jwt.getToken(req) } : {};
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Remove this line if you need make validations
|
|
19
|
+
next();
|
|
20
|
+
|
|
21
|
+
//
|
|
22
|
+
// You can make validations to check ACL or anything before to run a controller
|
|
23
|
+
// Example:
|
|
24
|
+
//
|
|
25
|
+
|
|
26
|
+
/*
|
|
27
|
+
if (req.auth && +req.auth.role !== 1) {
|
|
28
|
+
const data = {
|
|
29
|
+
success: false,
|
|
30
|
+
error: 'You don\'t have permissions to access this option.'
|
|
31
|
+
}
|
|
32
|
+
res.status(403).jsonp(data);
|
|
33
|
+
} else {
|
|
34
|
+
next();
|
|
35
|
+
}
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
|
|
3
|
+
//
|
|
4
|
+
// Connection: you can use the same connection
|
|
5
|
+
// set a custom Mongo URI connection to manage the sockets
|
|
6
|
+
//
|
|
7
|
+
connection: process.env.SOCKETS_MONGO_URI || null,
|
|
8
|
+
|
|
9
|
+
// Collection to save the records
|
|
10
|
+
collection: process.env.SOCKETS_MONGO_COLLECTION || 'socket.io-adapter-events'
|
|
11
|
+
|
|
12
|
+
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* Sockets Config
|
|
4
|
+
*
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
module.exports = {
|
|
8
|
+
|
|
9
|
+
// Enable sockets
|
|
10
|
+
enabled: true,
|
|
11
|
+
|
|
12
|
+
// Socket IO Adapter (redis|mongodb|memory)
|
|
13
|
+
adapter: 'memory',
|
|
14
|
+
|
|
15
|
+
// Socket configuration
|
|
16
|
+
config: {
|
|
17
|
+
|
|
18
|
+
// Transports
|
|
19
|
+
transports: ['websocket', 'polling'],
|
|
20
|
+
|
|
21
|
+
// Socket timeout
|
|
22
|
+
timeout: 4000,
|
|
23
|
+
|
|
24
|
+
// Interval
|
|
25
|
+
interval: 2000,
|
|
26
|
+
|
|
27
|
+
},
|
|
28
|
+
|
|
29
|
+
// Connections
|
|
30
|
+
connections: {
|
|
31
|
+
|
|
32
|
+
users: 0,
|
|
33
|
+
|
|
34
|
+
// Clients connected
|
|
35
|
+
clients: {}
|
|
36
|
+
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
// Event handlers
|
|
40
|
+
// onConnect: (io, socket, clients, counter) => {
|
|
41
|
+
// counter.users++;
|
|
42
|
+
// clients[socket.request.user._id] = socket.id;
|
|
43
|
+
// io.emit('users:counter', counter.users);
|
|
44
|
+
// },
|
|
45
|
+
// onDisconnect: (io, socket, clients, counter) => {
|
|
46
|
+
// counter.users--;
|
|
47
|
+
// delete clients[socket.request.user._id];
|
|
48
|
+
// io.emit('users:counter', counter.users);
|
|
49
|
+
// }
|
|
50
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module.exports = (req, callback) => {
|
|
2
|
+
|
|
3
|
+
const {
|
|
4
|
+
origin,
|
|
5
|
+
host,
|
|
6
|
+
} = req.headers || {};
|
|
7
|
+
|
|
8
|
+
const realOrigin = origin || host;
|
|
9
|
+
|
|
10
|
+
const allowedOrigin = [
|
|
11
|
+
'localhost',
|
|
12
|
+
'yourdomain.com'
|
|
13
|
+
];
|
|
14
|
+
|
|
15
|
+
let found = false;
|
|
16
|
+
|
|
17
|
+
allowedOrigin.forEach((o) => {
|
|
18
|
+
|
|
19
|
+
if ((realOrigin || '').indexOf(o) !== -1) {
|
|
20
|
+
found = true;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
if (found) {
|
|
26
|
+
callback(null, true);
|
|
27
|
+
} else {
|
|
28
|
+
console.log('Invalid origin', realOrigin || 'No Origin');
|
|
29
|
+
callback(new Error(`Invalid origin ${realOrigin} - Socket CORS`));
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
|
|
3
|
+
// Examples Chat
|
|
4
|
+
// event:action: folder.YourController.method
|
|
5
|
+
//
|
|
6
|
+
// 'chat:signin': 'sockets.ChatController.signin',
|
|
7
|
+
// 'chat:message': 'sockets.ChatController.save',
|
|
8
|
+
// 'chat:history': 'sockets.ChatController.get'
|
|
9
|
+
|
|
10
|
+
'echo': 'sockets.EchoController.echo'
|
|
11
|
+
|
|
12
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module.exports = (socket, next) => {
|
|
2
|
+
|
|
3
|
+
// Security
|
|
4
|
+
const user = Jwt.socket(socket);
|
|
5
|
+
|
|
6
|
+
const {
|
|
7
|
+
_id
|
|
8
|
+
} = user || {};
|
|
9
|
+
|
|
10
|
+
if (!_id) {
|
|
11
|
+
console.log('Sockets Middleware: Invalid ID');
|
|
12
|
+
next(new Error(`Invalid user ${_id || 'or token'}`));
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// eslint-disable-next-line no-param-reassign
|
|
16
|
+
socket.request.user = user || {};
|
|
17
|
+
|
|
18
|
+
next();
|
|
19
|
+
|
|
20
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pads a string to a certain length with another string.
|
|
3
|
+
* The padding is applied from the left, right, or both sides of the string.
|
|
4
|
+
*
|
|
5
|
+
* Example: {{ strpad('hello world', 20, '*', 'left') }} => '*********hello world'
|
|
6
|
+
*
|
|
7
|
+
* @param {*} str
|
|
8
|
+
* @param {*} _len
|
|
9
|
+
* @param {*} _pad
|
|
10
|
+
* @param {*} _dir
|
|
11
|
+
* @returns String
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
module.exports = (str, _len, _pad, _dir) => {
|
|
15
|
+
|
|
16
|
+
const STR_PAD_LEFT = 1;
|
|
17
|
+
const STR_PAD_RIGHT = 2;
|
|
18
|
+
const STR_PAD_BOTH = 3;
|
|
19
|
+
|
|
20
|
+
const len = _len || 0;
|
|
21
|
+
const pad = _pad || ' ';
|
|
22
|
+
const dir = _dir || STR_PAD_RIGHT;
|
|
23
|
+
|
|
24
|
+
let newStr = '';
|
|
25
|
+
|
|
26
|
+
if (len + 1 >= str.length) {
|
|
27
|
+
|
|
28
|
+
const padlen = len - str.length;
|
|
29
|
+
const right = Math.ceil(padlen / 2);
|
|
30
|
+
const left = padlen - right;
|
|
31
|
+
|
|
32
|
+
switch (dir) {
|
|
33
|
+
case STR_PAD_LEFT:
|
|
34
|
+
newStr = Array(len + 1 - str.length).join(pad) + str;
|
|
35
|
+
break;
|
|
36
|
+
case 'left':
|
|
37
|
+
newStr = Array(len + 1 - str.length).join(pad) + str;
|
|
38
|
+
break;
|
|
39
|
+
case STR_PAD_BOTH:
|
|
40
|
+
newStr = Array(left + 1).join(pad) + str + Array(right + 1).join(pad);
|
|
41
|
+
break;
|
|
42
|
+
default:
|
|
43
|
+
newStr = str + Array(len + 1 - str.length).join(pad);
|
|
44
|
+
break;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return newStr;
|
|
50
|
+
|
|
51
|
+
};
|
|
@@ -9,13 +9,10 @@
|
|
|
9
9
|
|
|
10
10
|
module.exports = {
|
|
11
11
|
|
|
12
|
-
//
|
|
13
|
-
scaffold:
|
|
12
|
+
// Model to CRUD (create, read, update, and delete) records — must exist as global.ExampleWithScaffold
|
|
13
|
+
scaffold: 'ExampleWithScaffold',
|
|
14
14
|
|
|
15
15
|
// Allowed methods
|
|
16
|
-
allowedMethods: ['get', 'post', 'put', 'delete']
|
|
17
|
-
|
|
18
|
-
// Model to CRUD (create, read, update, and delete) records
|
|
19
|
-
model: 'ExampleWithScaffold'
|
|
16
|
+
allowedMethods: ['get', 'post', 'put', 'delete']
|
|
20
17
|
|
|
21
18
|
};
|
|
@@ -53,6 +53,7 @@ module.exports = {
|
|
|
53
53
|
const defaultProps = {
|
|
54
54
|
sort: 'createdAt|DESC',
|
|
55
55
|
searchBy: ['name'],
|
|
56
|
+
fields: ['name', 'age', 'active', 'createdAt', 'updatedAt'],
|
|
56
57
|
filter: {
|
|
57
58
|
active: true
|
|
58
59
|
},
|
|
@@ -145,16 +146,45 @@ module.exports = {
|
|
|
145
146
|
|
|
146
147
|
},
|
|
147
148
|
|
|
149
|
+
/**
|
|
150
|
+
* Before validate callback — runs before beforeSave, as part of obj.save()
|
|
151
|
+
* (create() above). Does NOT run for update()/delete(): Mongoose's update
|
|
152
|
+
* validators (runValidators) validate each changed path directly and never
|
|
153
|
+
* go through this callback, even when a validator rejects the value.
|
|
154
|
+
* @param {Callback} cb
|
|
155
|
+
*/
|
|
156
|
+
beforeValidate(cb) {
|
|
157
|
+
|
|
158
|
+
console.log('Running callback before validate');
|
|
159
|
+
|
|
160
|
+
// All good!
|
|
161
|
+
cb();
|
|
162
|
+
|
|
163
|
+
},
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Callback after validate
|
|
167
|
+
* @param {Callback} cb
|
|
168
|
+
*/
|
|
169
|
+
afterValidate(cb) {
|
|
170
|
+
|
|
171
|
+
console.log('Running callback after validate');
|
|
172
|
+
|
|
173
|
+
// All good!
|
|
174
|
+
cb();
|
|
175
|
+
|
|
176
|
+
},
|
|
177
|
+
|
|
148
178
|
/**
|
|
149
179
|
* Before save callback
|
|
150
180
|
* @param {Callback} cb
|
|
151
181
|
*/
|
|
152
182
|
beforeSave(cb) {
|
|
153
183
|
|
|
154
|
-
const
|
|
184
|
+
const doc = this;
|
|
155
185
|
|
|
156
186
|
console.log('Running callback before save');
|
|
157
|
-
console.log(
|
|
187
|
+
console.log(doc);
|
|
158
188
|
|
|
159
189
|
// All good!
|
|
160
190
|
cb();
|
|
@@ -165,10 +195,40 @@ module.exports = {
|
|
|
165
195
|
* Callback after save
|
|
166
196
|
* @param {Callback} cb
|
|
167
197
|
*/
|
|
168
|
-
afterSave(
|
|
198
|
+
afterSave(doc, cb) {
|
|
169
199
|
|
|
170
200
|
console.log('Running callback after save');
|
|
171
|
-
console.log(
|
|
201
|
+
console.log(doc);
|
|
202
|
+
|
|
203
|
+
// All good!
|
|
204
|
+
cb();
|
|
205
|
+
|
|
206
|
+
},
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Before findOneAndUpdate callback — runs on update() and delete() above,
|
|
210
|
+
* since both call Example.findOneAndUpdate() directly. `this` is the Query,
|
|
211
|
+
* not the document.
|
|
212
|
+
* @param {Callback} cb
|
|
213
|
+
*/
|
|
214
|
+
beforeFindOneAndUpdate(cb) {
|
|
215
|
+
|
|
216
|
+
console.log('Running callback before findOneAndUpdate');
|
|
217
|
+
|
|
218
|
+
// All good!
|
|
219
|
+
cb();
|
|
220
|
+
|
|
221
|
+
},
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Callback after findOneAndUpdate
|
|
225
|
+
* @param {Object} doc Updated document
|
|
226
|
+
* @param {Callback} cb
|
|
227
|
+
*/
|
|
228
|
+
afterFindOneAndUpdate(doc, cb) {
|
|
229
|
+
|
|
230
|
+
console.log('Running callback after findOneAndUpdate');
|
|
231
|
+
console.log(doc);
|
|
172
232
|
|
|
173
233
|
// All good!
|
|
174
234
|
cb();
|