@digicms/cms
Version:
An open source headless CMS solution to create and manage your own API. It provides a powerful dashboard and features to make your life easier. Databases supported: MySQL, MariaDB, PostgreSQL, SQLite
106 lines (85 loc) • 2.72 kB
JavaScript
;
const Router = require('@koa/router');
const _ = require('lodash');
const { has } = require('lodash/fp');
const { yup } = require('@strapi/utils');
const createEndpointComposer = require('./compose-endpoint');
const policyOrMiddlewareSchema = yup.lazy((value) => {
if (typeof value === 'string') {
return yup.string().required();
}
if (typeof value === 'function') {
return yup.mixed().isFunction();
}
return yup.object({
name: yup.string().required(),
options: yup.object().notRequired(), // any options
});
});
const routeSchema = yup.object({
method: yup.string().oneOf(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'ALL']).required(),
path: yup.string().required(),
handler: yup.lazy((value) => {
if (typeof value === 'string') {
return yup.string().required();
}
if (Array.isArray(value)) {
return yup.array().required();
}
return yup.mixed().isFunction().required();
}),
config: yup
.object({
auth: yup.lazy((value) => {
if (value === false) {
return yup.boolean().required();
}
return yup.object({
scope: yup.array().of(yup.string()).required(),
});
}),
policies: yup.array().of(policyOrMiddlewareSchema).notRequired(),
middlewares: yup.array().of(policyOrMiddlewareSchema).notRequired(),
})
.notRequired(),
});
const validateRouteConfig = (routeConfig) => {
try {
return routeSchema.validateSync(routeConfig, {
strict: true,
abortEarly: false,
stripUnknown: true,
});
} catch (error) {
throw new Error('Invalid route config', error.message);
}
};
const createRouteManager = (strapi, opts = {}) => {
const { type } = opts;
const composeEndpoint = createEndpointComposer(strapi);
const createRoute = (route, router) => {
validateRouteConfig(route);
// NOTE: the router type is used to tag controller actions and for authentication / authorization so we need to pass this info down to the route level
_.set(route, 'info.type', type || 'admin');
composeEndpoint(route, { router });
};
const addRoutes = (routes, router) => {
if (Array.isArray(routes)) {
routes.forEach((route) => createRoute(route, router));
} else if (routes.routes) {
const subRouter = new Router({ prefix: routes.prefix });
routes.routes.forEach((route) => {
const hasPrefix = has('prefix', route.config);
createRoute(route, hasPrefix ? router : subRouter);
});
return router.use(subRouter.routes(), subRouter.allowedMethods());
}
};
return {
addRoutes,
};
};
module.exports = {
validateRouteConfig,
createRouteManager,
};