UNPKG

@directus/api

Version:

Directus is a real-time API and App dashboard for managing SQL database content

152 lines (151 loc) 5.42 kB
import { TYPES } from '@directus/constants'; import { isDirectusError } from '@directus/errors'; import { Router } from 'express'; import Joi from 'joi'; import { ALIAS_TYPES } from '../constants.js'; import { ErrorCode, InvalidPayloadError } from '@directus/errors'; import validateCollection from '../middleware/collection-exists.js'; import { respond } from '../middleware/respond.js'; import useCollection from '../middleware/use-collection.js'; import { FieldsService } from '../services/fields.js'; import asyncHandler from '../utils/async-handler.js'; const router = Router(); router.use(useCollection('directus_fields')); router.get('/', asyncHandler(async (req, res, next) => { const service = new FieldsService({ accountability: req.accountability, schema: req.schema, }); const fields = await service.readAll(); res.locals['payload'] = { data: fields || null }; return next(); }), respond); router.get('/:collection', validateCollection, asyncHandler(async (req, res, next) => { const service = new FieldsService({ accountability: req.accountability, schema: req.schema, }); const fields = await service.readAll(req.params['collection']); res.locals['payload'] = { data: fields || null }; return next(); }), respond); router.get('/:collection/:field', validateCollection, asyncHandler(async (req, res, next) => { const service = new FieldsService({ accountability: req.accountability, schema: req.schema, }); const field = await service.readOne(req.params['collection'], req.params['field']); res.locals['payload'] = { data: field || null }; return next(); }), respond); const newFieldSchema = Joi.object({ collection: Joi.string().optional(), field: Joi.string().required(), type: Joi.string() .valid(...TYPES, ...ALIAS_TYPES) .allow(null) .optional(), schema: Joi.object({ default_value: Joi.any(), max_length: [Joi.number(), Joi.string(), Joi.valid(null)], is_nullable: Joi.bool(), }) .unknown() .allow(null), meta: Joi.any(), }); router.post('/:collection', validateCollection, asyncHandler(async (req, res, next) => { const service = new FieldsService({ accountability: req.accountability, schema: req.schema, }); const { error } = newFieldSchema.validate(req.body); if (error) { throw new InvalidPayloadError({ reason: error.message }); } const field = req.body; await service.createField(req.params['collection'], field); try { const createdField = await service.readOne(req.params['collection'], field.field); res.locals['payload'] = { data: createdField || null }; } catch (error) { if (isDirectusError(error, ErrorCode.Forbidden)) { return next(); } throw error; } return next(); }), respond); router.patch('/:collection', validateCollection, asyncHandler(async (req, res, next) => { const service = new FieldsService({ accountability: req.accountability, schema: req.schema, }); if (Array.isArray(req.body) === false) { throw new InvalidPayloadError({ reason: 'Submitted body has to be an array' }); } await service.updateFields(req.params['collection'], req.body); try { const results = []; for (const field of req.body) { const updatedField = await service.readOne(req.params['collection'], field.field); results.push(updatedField); res.locals['payload'] = { data: results || null }; } } catch (error) { if (isDirectusError(error, ErrorCode.Forbidden)) { return next(); } throw error; } return next(); }), respond); const updateSchema = Joi.object({ type: Joi.string() .valid(...TYPES, ...ALIAS_TYPES) .allow(null), schema: Joi.object({ default_value: Joi.any(), max_length: [Joi.number(), Joi.string(), Joi.valid(null)], is_nullable: Joi.bool(), }) .unknown() .allow(null), meta: Joi.any(), }).unknown(); router.patch('/:collection/:field', validateCollection, asyncHandler(async (req, res, next) => { const service = new FieldsService({ accountability: req.accountability, schema: req.schema, }); const { error } = updateSchema.validate(req.body); if (error) { throw new InvalidPayloadError({ reason: error.message }); } const fieldData = req.body; if (!fieldData.field) fieldData.field = req.params['field']; await service.updateField(req.params['collection'], fieldData); try { const updatedField = await service.readOne(req.params['collection'], req.params['field']); res.locals['payload'] = { data: updatedField || null }; } catch (error) { if (isDirectusError(error, ErrorCode.Forbidden)) { return next(); } throw error; } return next(); }), respond); router.delete('/:collection/:field', validateCollection, asyncHandler(async (req, _res, next) => { const service = new FieldsService({ accountability: req.accountability, schema: req.schema, }); await service.deleteField(req.params['collection'], req.params['field']); return next(); }), respond); export default router;