{"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 { Core, UID } from '@strapi/types';\nimport { errors } from '@strapi/utils';\nimport Router from '@koa/router';\n\nimport compose from 'koa-compose';\nimport { resolveRouteMiddlewares } from './middleware';\nimport { createPolicicesMiddleware } from './policy';\n\nconst getMethod = (route: Core.Route) => {\n  return trim(toLower(route.method)) as Lowercase<Core.Route['method']>;\n};\n\nconst getPath = (route: Core.Route) => trim(route.path);\n\nconst createRouteInfoMiddleware =\n  (routeInfo: Core.Route): Core.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: Core.Strapi): Core.MiddlewareHandler =>\n  async (ctx, next) => {\n    const { auth, route } = ctx.state;\n\n    const authService = strapi.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        // allow PolicyError as an exception to throw a publicly visible message in the API\n        if (error instanceof errors.PolicyError) {\n          throw error;\n        }\n        return ctx.forbidden();\n      }\n\n      throw error;\n    }\n  };\n\nconst createAuthenticateMiddleware =\n  (strapi: Core.Strapi): Core.MiddlewareHandler =>\n  async (ctx, next) => {\n    return strapi.get('auth').authenticate(ctx, next);\n  };\n\nconst returnBodyMiddleware: Core.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: Core.Strapi) => {\n  const authenticate = createAuthenticateMiddleware(strapi);\n  const authorize = createAuthorizeMiddleware(strapi);\n\n  return (route: Core.Route, { router }: { router: Router }) => {\n    try {\n      const method = getMethod(route);\n      const path = getPath(route);\n\n      const middlewares = resolveRouteMiddlewares(route, strapi);\n\n      const action = getAction(route, strapi);\n\n      const routeHandler = compose([\n        createRouteInfoMiddleware(route),\n        authenticate,\n        authorize,\n        createPolicicesMiddleware(route, strapi),\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 = (\n  name: string,\n  { pluginName, apiName }: Core.RouteInfo,\n  strapi: Core.Strapi\n) => {\n  let ctrl: Core.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 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: Core.Route, strapi: Core.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":["getMethod","route","trim","toLower","method","getPath","path","createRouteInfoMiddleware","routeInfo","ctx","next","config","state","getAuthConfig","prop","createAuthorizeMiddleware","strapi","auth","authService","get","verify","error","errors","UnauthorizedError","unauthorized","ForbiddenError","PolicyError","forbidden","createAuthenticateMiddleware","authenticate","returnBodyMiddleware","values","isNil","body","authorize","router","middlewares","resolveRouteMiddlewares","action","getAction","routeHandler","compose","createPolicicesMiddleware","castArray","Error","message","getController","name","pluginName","apiName","ctrl","controller","plugin","extractHandlerParts","controllerName","slice","lastIndexOf","actionName","handler","info","type","Array","isArray","Symbol","for","push","bind"],"mappings":"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"}