{"version":3,"file":"compose-endpoint.mjs","sources":["../../../src/services/server/compose-endpoint.ts"],"sourcesContent":["import { toLower, castArray, trim, prop, isNil } from 'lodash/fp';\nimport type { Strapi, Common } from '@strapi/types';\nimport { errors } from '@strapi/utils';\nimport Router from '@koa/router';\n\nimport compose from 'koa-compose';\nimport { resolveRouteMiddlewares } from './middleware';\nimport { resolvePolicies } from './policy';\n\nconst getMethod = (route: Common.Route) => {\n  return trim(toLower(route.method)) as Lowercase<Common.Route['method']>;\n};\n\nconst getPath = (route: Common.Route) => trim(route.path);\n\nconst createRouteInfoMiddleware =\n  (routeInfo: Common.Route): Common.MiddlewareHandler =>\n  (ctx, next) => {\n    const route = {\n      ...routeInfo,\n      config: routeInfo.config || {},\n    };\n\n    ctx.state.route = route;\n    return next();\n  };\n\nconst getAuthConfig = prop('config.auth');\n\nconst createAuthorizeMiddleware =\n  (strapi: Strapi): Common.MiddlewareHandler =>\n  async (ctx, next) => {\n    const { auth, route } = ctx.state;\n\n    const authService = strapi.container.get('auth');\n\n    try {\n      await authService.verify(auth, getAuthConfig(route));\n\n      return await next();\n    } catch (error) {\n      if (error instanceof errors.UnauthorizedError) {\n        return ctx.unauthorized();\n      }\n\n      if (error instanceof errors.ForbiddenError) {\n        return ctx.forbidden();\n      }\n\n      throw error;\n    }\n  };\n\nconst createAuthenticateMiddleware =\n  (strapi: Strapi): Common.MiddlewareHandler =>\n  async (ctx, next) => {\n    return strapi.container.get('auth').authenticate(ctx, next);\n  };\n\nconst returnBodyMiddleware: Common.MiddlewareHandler = async (ctx, next) => {\n  const values = await next();\n\n  if (isNil(ctx.body) && !isNil(values)) {\n    ctx.body = values;\n  }\n};\n\nexport default (strapi: Strapi) => {\n  const authenticate = createAuthenticateMiddleware(strapi);\n  const authorize = createAuthorizeMiddleware(strapi);\n\n  return (route: Common.Route, { router }: { router: Router }) => {\n    try {\n      const method = getMethod(route);\n      const path = getPath(route);\n\n      const middlewares = resolveRouteMiddlewares(route, strapi);\n      const policies = resolvePolicies(route);\n\n      const action = getAction(route, strapi);\n\n      const routeHandler = compose([\n        createRouteInfoMiddleware(route),\n        authenticate,\n        authorize,\n        ...policies,\n        ...middlewares,\n        returnBodyMiddleware,\n        ...castArray(action),\n      ]);\n\n      router[method](path, routeHandler);\n    } catch (error) {\n      if (error instanceof Error) {\n        error.message = `Error creating endpoint ${route.method} ${route.path}: ${error.message}`;\n      }\n\n      throw error;\n    }\n  };\n};\n\nconst getController = (name: string, { pluginName, apiName }: Common.RouteInfo, strapi: Strapi) => {\n  let ctrl: Common.Controller | undefined;\n\n  if (pluginName) {\n    if (pluginName === 'admin') {\n      ctrl = strapi.controller(`admin::${name}`);\n    } else {\n      ctrl = strapi.plugin(pluginName).controller(name);\n    }\n  } else if (apiName) {\n    ctrl = strapi.controller(`api::${apiName}.${name}`);\n  }\n\n  if (!ctrl) {\n    return strapi.controller(name as Common.UID.Controller);\n  }\n\n  return ctrl;\n};\n\nconst extractHandlerParts = (name: string) => {\n  const controllerName = name.slice(0, name.lastIndexOf('.'));\n  const actionName = name.slice(name.lastIndexOf('.') + 1);\n\n  return { controllerName, actionName };\n};\n\nconst getAction = (route: Common.Route, strapi: Strapi) => {\n  const { handler, info } = route;\n  const { pluginName, apiName, type } = info ?? {};\n\n  if (Array.isArray(handler) || typeof handler === 'function') {\n    return handler;\n  }\n\n  const { controllerName, actionName } = extractHandlerParts(trim(handler));\n\n  const controller = getController(controllerName, { pluginName, apiName, type }, strapi);\n\n  if (typeof controller[actionName] !== 'function') {\n    throw new Error(`Handler not found \"${handler}\"`);\n  }\n\n  if (Symbol.for('__type__') in controller[actionName]) {\n    (controller[actionName] as any)[Symbol.for('__type__')].push(type);\n  } else {\n    (controller[actionName] as any)[Symbol.for('__type__')] = [type];\n  }\n\n  return controller[actionName].bind(controller);\n};\n"],"names":[],"mappings":"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"}