251 lines
5.7 KiB
TypeScript
Raw Normal View History

import express from 'express';
import Joi from '@hapi/joi';
const allowedActions = [
'info',
'entriesByFolder',
'entriesByFiles',
'getEntry',
'unpublishedEntries',
'unpublishedEntry',
2020-06-18 10:11:37 +03:00
'unpublishedEntryDataFile',
'unpublishedEntryMediaFile',
'deleteUnpublishedEntry',
'persistEntry',
'updateUnpublishedEntryStatus',
'publishUnpublishedEntry',
'getMedia',
'getMediaFile',
'persistMedia',
'deleteFile',
2020-09-20 10:30:46 -07:00
'deleteFiles',
'getDeployPreview',
];
const requiredString = Joi.string().required();
const requiredNumber = Joi.number().required();
const requiredBool = Joi.bool().required();
const collection = requiredString;
const slug = requiredString;
export function defaultSchema({ path = requiredString } = {}) {
const defaultParams = Joi.object({
branch: requiredString,
});
const asset = Joi.object({
path,
content: requiredString,
encoding: requiredString.valid('base64'),
});
2020-09-20 10:30:46 -07:00
const dataFile = Joi.object({
slug: requiredString,
path,
raw: requiredString,
newPath: path.optional(),
});
const params = Joi.when('action', {
switch: [
{
is: 'info',
then: Joi.allow(),
},
{
is: 'entriesByFolder',
then: defaultParams
.keys({
folder: path,
extension: requiredString,
depth: requiredNumber,
})
.required(),
},
{
is: 'entriesByFiles',
then: defaultParams.keys({
files: Joi.array()
.items(Joi.object({ path, label: Joi.string() }))
.required(),
}),
},
{
is: 'getEntry',
then: defaultParams
.keys({
path,
})
.required(),
},
{
is: 'unpublishedEntries',
then: defaultParams.keys({ branch: requiredString }).required(),
},
{
is: 'unpublishedEntry',
2020-06-18 10:11:37 +03:00
then: defaultParams
.keys({
id: Joi.string().optional(),
collection: Joi.string().optional(),
slug: Joi.string().optional(),
cmsLabelPrefix: Joi.string().optional(),
2020-06-18 10:11:37 +03:00
})
.required(),
},
{
is: 'unpublishedEntryDataFile',
then: defaultParams
.keys({
collection,
slug,
id: requiredString,
path: requiredString,
})
.required(),
},
{
is: 'unpublishedEntryMediaFile',
then: defaultParams
.keys({
collection,
slug,
2020-06-18 10:11:37 +03:00
id: requiredString,
path: requiredString,
})
.required(),
},
{
is: 'deleteUnpublishedEntry',
then: defaultParams
.keys({
collection,
slug,
})
.required(),
},
{
is: 'persistEntry',
then: defaultParams
.keys({
cmsLabelPrefix: Joi.string().optional(),
2020-09-20 10:30:46 -07:00
entry: dataFile, // entry is kept for backwards compatibility
dataFiles: Joi.array().items(dataFile),
assets: Joi.array()
.items(asset)
.required(),
options: Joi.object({
collectionName: Joi.string(),
commitMessage: requiredString,
useWorkflow: requiredBool,
status: requiredString,
}).required(),
})
2020-09-20 10:30:46 -07:00
.xor('entry', 'dataFiles')
.required(),
},
{
is: 'updateUnpublishedEntryStatus',
then: defaultParams
.keys({
collection,
slug,
newStatus: requiredString,
cmsLabelPrefix: Joi.string().optional(),
})
.required(),
},
{
is: 'publishUnpublishedEntry',
then: defaultParams
.keys({
collection,
slug,
})
.required(),
},
{
is: 'getMedia',
then: defaultParams
.keys({
mediaFolder: path,
})
.required(),
},
{
is: 'getMediaFile',
then: defaultParams
.keys({
path,
})
.required(),
},
{
is: 'persistMedia',
then: defaultParams
.keys({
asset: asset.required(),
options: Joi.object({
commitMessage: requiredString,
}).required(),
})
.required(),
},
{
is: 'deleteFile',
then: defaultParams
.keys({
path,
options: Joi.object({
commitMessage: requiredString,
}).required(),
})
.required(),
},
2020-09-20 10:30:46 -07:00
{
is: 'deleteFiles',
then: defaultParams
.keys({
paths: Joi.array()
.items(path)
.min(1)
.required(),
options: Joi.object({
commitMessage: requiredString,
}).required(),
})
.required(),
},
{
is: 'getDeployPreview',
then: defaultParams
.keys({
collection,
slug,
})
.required(),
},
],
otherwise: Joi.forbidden(),
});
return Joi.object({
action: Joi.valid(...allowedActions).required(),
params,
});
}
export function joi(schema: Joi.Schema) {
return (req: express.Request, res: express.Response, next: express.NextFunction) => {
const { error } = schema.validate(req.body, { allowUnknown: true });
if (error) {
const { details } = error;
const message = details.map(i => i.message).join(',');
res.status(422).json({ error: message });
} else {
next();
}
};
}