Files
directus/api/src/controllers/relations.ts
Nicola Krumschmidt d64ca14348 Explicitly set catch parameters to any type (#7654)
This fixes not being able to build the repo due to type issues
introduced by the Typescript 4.4 option "useUnknownInCatchVariables",
which is enabled by default in strict mode.
2021-08-27 10:33:30 -04:00

166 lines
3.8 KiB
TypeScript

import express from 'express';
import { ForbiddenException, InvalidPayloadException } from '../exceptions';
import { respond } from '../middleware/respond';
import useCollection from '../middleware/use-collection';
import { RelationsService } from '../services';
import asyncHandler from '../utils/async-handler';
import validateCollection from '../middleware/collection-exists';
import Joi from 'joi';
const router = express.Router();
router.use(useCollection('directus_relations'));
router.get(
'/',
asyncHandler(async (req, res, next) => {
const service = new RelationsService({
accountability: req.accountability,
schema: req.schema,
});
const relations = await service.readAll();
res.locals.payload = { data: relations || null };
return next();
}),
respond
);
router.get(
'/:collection',
validateCollection,
asyncHandler(async (req, res, next) => {
const service = new RelationsService({
accountability: req.accountability,
schema: req.schema,
});
const relations = await service.readAll(req.params.collection);
res.locals.payload = { data: relations || null };
return next();
}),
respond
);
router.get(
'/:collection/:field',
validateCollection,
asyncHandler(async (req, res, next) => {
const service = new RelationsService({
accountability: req.accountability,
schema: req.schema,
});
const relation = await service.readOne(req.params.collection, req.params.field);
res.locals.payload = { data: relation || null };
return next();
}),
respond
);
const newRelationSchema = Joi.object({
collection: Joi.string().required(),
field: Joi.string().required(),
related_collection: Joi.string().allow(null).optional(),
schema: Joi.object({
on_delete: Joi.string().valid('NO ACTION', 'SET NULL', 'SET DEFAULT', 'CASCADE', 'RESTRICT'),
})
.unknown()
.allow(null),
meta: Joi.any(),
});
router.post(
'/',
asyncHandler(async (req, res, next) => {
const service = new RelationsService({
accountability: req.accountability,
schema: req.schema,
});
const { error } = newRelationSchema.validate(req.body);
if (error) {
throw new InvalidPayloadException(error.message);
}
await service.createOne(req.body);
try {
const createdRelation = await service.readOne(req.body.collection, req.body.field);
res.locals.payload = { data: createdRelation || null };
} catch (error: any) {
if (error instanceof ForbiddenException) {
return next();
}
throw error;
}
return next();
}),
respond
);
const updateRelationSchema = Joi.object({
collection: Joi.string().optional(),
field: Joi.string().optional(),
related_collection: Joi.string().allow(null).optional(),
schema: Joi.object({
on_delete: Joi.string().valid('NO ACTION', 'SET NULL', 'SET DEFAULT', 'CASCADE', 'RESTRICT'),
})
.unknown()
.allow(null),
meta: Joi.any(),
});
router.patch(
'/:collection/:field',
validateCollection,
asyncHandler(async (req, res, next) => {
const service = new RelationsService({
accountability: req.accountability,
schema: req.schema,
});
const { error } = updateRelationSchema.validate(req.body);
if (error) {
throw new InvalidPayloadException(error.message);
}
await service.updateOne(req.params.collection, req.params.field, req.body);
try {
const updatedField = await service.readOne(req.params.collection, req.params.field);
res.locals.payload = { data: updatedField || null };
} catch (error: any) {
if (error instanceof ForbiddenException) {
return next();
}
throw error;
}
return next();
}),
respond
);
router.delete(
'/:collection/:field',
validateCollection,
asyncHandler(async (req, res, next) => {
const service = new RelationsService({
accountability: req.accountability,
schema: req.schema,
});
await service.deleteOne(req.params.collection, req.params.field);
return next();
}),
respond
);
export default router;