UNPKG

@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
'use strict'; 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, };