mirror of
https://github.com/directus/directus.git
synced 2026-02-03 01:15:00 -05:00
54 lines
1.6 KiB
TypeScript
54 lines
1.6 KiB
TypeScript
import { RequestHandler } from 'express';
|
|
import Joi from 'joi';
|
|
import { FailedValidationException, InvalidPayloadException } from '../exceptions';
|
|
import asyncHandler from '../utils/async-handler';
|
|
import { sanitizeQuery } from '../utils/sanitize-query';
|
|
|
|
export const validateBatch = (scope: 'read' | 'update' | 'delete'): RequestHandler =>
|
|
asyncHandler(async (req, res, next) => {
|
|
if (req.method.toLowerCase() === 'get') {
|
|
req.body = {};
|
|
return next();
|
|
}
|
|
|
|
if (!req.body) throw new InvalidPayloadException('Payload in body is required');
|
|
|
|
if (req.singleton) return next();
|
|
|
|
// Every cRUD action has either keys or query
|
|
let batchSchema = Joi.object().keys({
|
|
keys: Joi.array().items(Joi.alternatives(Joi.string(), Joi.number())),
|
|
query: Joi.object().unknown(),
|
|
});
|
|
|
|
// In reads, you can't combine the two, and 1 of the two at least is required
|
|
if (scope !== 'read') {
|
|
batchSchema = batchSchema.xor('query', 'keys');
|
|
}
|
|
|
|
// In updates, we add a required `data` that holds the update payload
|
|
if (scope === 'update') {
|
|
batchSchema = batchSchema.keys({
|
|
data: Joi.object().unknown().required(),
|
|
});
|
|
}
|
|
|
|
// In deletes, we want to keep supporting an array of just primary keys
|
|
if (scope === 'delete' && Array.isArray(req.body)) {
|
|
return next();
|
|
}
|
|
|
|
const { error } = batchSchema.validate(req.body);
|
|
|
|
if (error) {
|
|
throw new FailedValidationException(error.details[0]);
|
|
}
|
|
|
|
// In reads, the query in the body should override the query params for searching
|
|
if (scope === 'read' && req.body.query) {
|
|
req.sanitizedQuery = sanitizeQuery(req.body.query, req.accountability);
|
|
}
|
|
|
|
return next();
|
|
});
|