{"version":3,"file":"index.mjs","sources":["../../../src/domain/module/index.ts"],"sourcesContent":["import _, { type PropertyPath, flatten } from 'lodash';\nimport { yup } from '@strapi/utils';\nimport type { Core, UID, Struct } from '@strapi/types';\n\nimport { removeNamespace } from '../../registries/namespace';\nimport { validateModule } from './validation';\n\ninterface LifecyclesState {\n  bootstrap?: boolean;\n  register?: boolean;\n  destroy?: boolean;\n}\n\nexport interface RawModule {\n  config?: Record<string, unknown>;\n  routes?: Core.Module['routes'];\n  controllers?: Core.Module['controllers'];\n  services?: Core.Module['services'];\n  contentTypes?: Core.Module['contentTypes'];\n  policies?: Core.Module['policies'];\n  middlewares?: Core.Module['middlewares'];\n  bootstrap?: (params: { strapi: Core.Strapi }) => Promise<void>;\n  register?: (params: { strapi: Core.Strapi }) => Promise<void>;\n  destroy?: (params: { strapi: Core.Strapi }) => Promise<void>;\n}\n\nexport interface Module {\n  bootstrap: () => Promise<void>;\n  register: () => Promise<void>;\n  destroy: () => Promise<void>;\n  load: () => void;\n  routes: Core.Module['routes'];\n  config<T = unknown>(key: PropertyPath, defaultVal?: T): T; // TODO: this mirrors ConfigProvider.get, we should use it directly\n  contentType: (ctName: UID.ContentType) => Struct.ContentTypeSchema;\n  contentTypes: Record<string, Struct.ContentTypeSchema>;\n  service: (serviceName: UID.Service) => Core.Service;\n  services: Record<string, Core.Service>;\n  policy: (policyName: UID.Policy) => Core.Policy;\n  policies: Record<string, Core.Policy>;\n  middleware: (middlewareName: UID.Middleware) => Core.Middleware;\n  middlewares: Record<string, Core.Middleware>;\n  controller: (controllerName: UID.Controller) => Core.Controller;\n  controllers: Record<string, Core.Controller>;\n}\n\n// Removes the namespace from a map with keys prefixed with a namespace\nconst removeNamespacedKeys = <T extends Record<string, unknown>>(map: T, namespace: string) => {\n  return _.mapKeys(map, (value, key) => removeNamespace(key, namespace));\n};\n\nconst defaultModule = {\n  config: {},\n  routes: [],\n  controllers: {},\n  services: {},\n  contentTypes: {},\n  policies: {},\n  middlewares: {},\n};\n\nexport const createModule = (\n  namespace: string,\n  rawModule: RawModule,\n  strapi: Core.Strapi\n): Module => {\n  _.defaults(rawModule, defaultModule);\n\n  try {\n    validateModule(rawModule);\n  } catch (e) {\n    if (e instanceof yup.ValidationError) {\n      throw new Error(`strapi-server.js is invalid for '${namespace}'.\\n${e.errors.join('\\n')}`);\n    }\n  }\n\n  const called: LifecyclesState = {};\n  return {\n    async bootstrap() {\n      if (called.bootstrap) {\n        throw new Error(`Bootstrap for ${namespace} has already been called`);\n      }\n      called.bootstrap = true;\n      await (rawModule.bootstrap && rawModule.bootstrap({ strapi }));\n    },\n    async register() {\n      if (called.register) {\n        throw new Error(`Register for ${namespace} has already been called`);\n      }\n      called.register = true;\n      await (rawModule.register && rawModule.register({ strapi }));\n    },\n    async destroy() {\n      if (called.destroy) {\n        throw new Error(`Destroy for ${namespace} has already been called`);\n      }\n      called.destroy = true;\n      await (rawModule.destroy && rawModule.destroy({ strapi }));\n    },\n    load() {\n      strapi.get('content-types').add(namespace, rawModule.contentTypes);\n      strapi.get('services').add(namespace, rawModule.services);\n      strapi.get('policies').add(namespace, rawModule.policies);\n      strapi.get('middlewares').add(namespace, rawModule.middlewares);\n      strapi.get('controllers').add(namespace, rawModule.controllers);\n      strapi.get('config').set(namespace, rawModule.config);\n    },\n    get routes() {\n      return rawModule.routes ?? {};\n    },\n    config(path: PropertyPath, defaultValue: unknown) {\n      const pathArray = flatten([namespace, path]);\n      return strapi.get('config').get(pathArray, defaultValue);\n    },\n    contentType(ctName: UID.ContentType) {\n      return strapi.get('content-types').get(`${namespace}.${ctName}`);\n    },\n    get contentTypes() {\n      const contentTypes = strapi.get('content-types').getAll(namespace);\n      return removeNamespacedKeys(contentTypes, namespace);\n    },\n    service(serviceName: UID.Service) {\n      return strapi.get('services').get(`${namespace}.${serviceName}`);\n    },\n    get services() {\n      const services = strapi.get('services').getAll(namespace);\n      return removeNamespacedKeys(services, namespace);\n    },\n    policy(policyName: UID.Policy) {\n      return strapi.get('policies').get(`${namespace}.${policyName}`);\n    },\n    get policies() {\n      const policies = strapi.get('policies').getAll(namespace);\n      return removeNamespacedKeys(policies, namespace);\n    },\n    middleware(middlewareName: UID.Middleware) {\n      return strapi.get('middlewares').get(`${namespace}.${middlewareName}`);\n    },\n    get middlewares() {\n      const middlewares = strapi.get('middlewares').getAll(namespace);\n      return removeNamespacedKeys(middlewares, namespace);\n    },\n    controller(controllerName: UID.Controller) {\n      return strapi.get('controllers').get(`${namespace}.${controllerName}`);\n    },\n    get controllers() {\n      const controllers = strapi.get('controllers').getAll(namespace);\n      return removeNamespacedKeys(controllers, namespace);\n    },\n  };\n};\n"],"names":[],"mappings":"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"}