{"version":3,"file":"AgentModules.mjs","names":[],"sources":["../../src/agent/AgentModules.ts"],"sourcesContent":["import { CacheModule, SingleContextStorageLruCache } from '../modules/cache'\nimport { DcqlModule } from '../modules/dcql/DcqlModule'\nimport { DidsModule } from '../modules/dids'\nimport { DifPresentationExchangeModule } from '../modules/dif-presentation-exchange'\nimport { GenericRecordsModule } from '../modules/generic-records'\nimport { KeyManagementModule } from '../modules/kms'\nimport { MdocModule } from '../modules/mdoc/MdocModule'\nimport { SdJwtVcModule } from '../modules/sd-jwt-vc'\nimport { W3cCredentialsModule } from '../modules/vc'\nimport { X509Module } from '../modules/x509'\nimport type { ApiModule, DependencyManager, Module } from '../plugins'\nimport type { IsAny } from '../types'\nimport type { Constructor } from '../utils/mixins'\n\n/**\n * Simple utility type that represent a map of modules. This is used to map from moduleKey (api key) to the api in the framework.\n */\nexport type ModulesMap = { [key: string]: Module }\n\n// biome-ignore lint/complexity/noBannedTypes: no explanation\nexport type EmptyModuleMap = {}\n\n/**\n * Default modules can be optionally defined to provide custom configuration. This type makes it so that it is not\n * possible to use a different key for the default modules\n */\nexport type AgentModulesInput = ModulesMap\n\n/**\n * Type that represents the default agent modules. This is the {@link ModulesMap} variant for the default modules in the framework.\n * It uses the return type of the {@link getDefaultAgentModules} method to automatically infer which modules are always available on\n * the agent and in the agent. namespace.\n */\nexport type DefaultAgentModules = {\n  [moduleKey in keyof ReturnType<typeof getDefaultAgentModules>]: ReturnType<\n    ReturnType<typeof getDefaultAgentModules>[moduleKey]\n  >\n}\n\nexport type WithoutDefaultModules<Modules extends ModulesMap> = {\n  [moduleKey in Exclude<keyof Modules, keyof DefaultAgentModules>]: Modules[moduleKey]\n}\n\nexport type ModuleApiInstance<M extends Module> =\n  M['api'] extends Constructor<unknown> ? InstanceType<M['api']> : undefined\n\n/**\n * Type that represents the api object of the agent (`agent.xxx`). It will extract all keys of the modules and map this to the\n * registered {@link Module.api} class instance. If the module does not have an api class registered, the property will be removed\n * and won't be available on the api object.\n *\n * @example\n * If the following AgentModules type was passed:\n * ```ts\n * {\n *   connections: DidCommConnectionsModule\n *   indy: IndyModule\n * }\n * ```\n *\n * And we use the `AgentApi` type like this:\n * ```ts\n * type MyAgentApi = AgentApi<{\n *   connections: DidCommConnectionsModule\n *   indy: IndyModule\n * }>\n * ```\n *\n * the resulting agent api will look like:\n *\n * ```ts\n * {\n *   connections: ConnectionsApi\n * }\n * ```\n *\n * The `indy` module has been ignored because it doesn't define an api class.\n */\nexport type AgentApi<Modules extends ModulesMap> = {\n  [moduleKey in keyof Modules as Modules[moduleKey]['api'] extends Constructor<unknown>\n    ? moduleKey\n    : never]: ModuleApiInstance<Modules[moduleKey]>\n}\n\n/**\n * Returns the `api` type from the CustomModuleType if the module is an ApiModule. If the module is not defined\n * which is the case if you don't configure a default agent module (e.g. credentials module), it will use the default\n * module type and use that for the typing. This will contain the default typing, and thus provide the correct agent api\n * interface\n */\nexport type CustomOrDefaultApi<CustomModuleType, DefaultModuleType extends ApiModule> =\n  IsAny<CustomModuleType> extends true\n    ? InstanceType<DefaultModuleType['api']>\n    : CustomModuleType extends ApiModule\n      ? InstanceType<CustomModuleType['api']>\n      : CustomModuleType extends Module\n        ? never\n        : InstanceType<DefaultModuleType['api']>\n\n/**\n * Method to get the default agent modules to be registered on any agent instance. It doens't configure the modules in any way,\n * and if that's needed the user needs to provide the module in the agent constructor\n */\nfunction getDefaultAgentModules() {\n  return {\n    dcql: () => new DcqlModule(),\n    genericRecords: () => new GenericRecordsModule(),\n    dids: () => new DidsModule(),\n    w3cCredentials: () => new W3cCredentialsModule(),\n    cache: () => new CacheModule({ cache: new SingleContextStorageLruCache({ limit: 500 }) }),\n    pex: () => new DifPresentationExchangeModule(),\n    sdJwtVc: () => new SdJwtVcModule(),\n    x509: () => new X509Module(),\n    mdoc: () => new MdocModule(),\n    kms: () => new KeyManagementModule({}),\n  } as const\n}\n\n/**\n * Extend the provided modules object with the default agent modules. If the modules property already contains a module with the same\n * name as a default module, the module won't be added to the extended module object. This allows users of the framework to override\n * the modules with custom configuration. The agent constructor type ensures you can't provide a different module for a key that registered\n * on the default agent.\n */\nexport function extendModulesWithDefaultModules<AgentModules extends AgentModulesInput>(\n  modules?: AgentModules\n): AgentModules & DefaultAgentModules {\n  const defaultAgentModules = getDefaultAgentModules()\n  const defaultAgentModuleKeys = Object.keys(defaultAgentModules)\n\n  const defaultModules: Array<[string, Module]> = []\n  const customModules: Array<[string, Module]> = Object.entries(modules ?? {}).filter(\n    ([key]) => !defaultAgentModuleKeys.includes(key)\n  )\n\n  // Register all default modules, if not registered yet\n  for (const [moduleKey, getConfiguredModule] of Object.entries(defaultAgentModules)) {\n    // Prefer user-registered module, otherwise initialize the default module\n    defaultModules.push([moduleKey, modules?.[moduleKey] ?? getConfiguredModule()])\n  }\n\n  return Object.fromEntries([...defaultModules, ...customModules]) as AgentModules & DefaultAgentModules\n}\n\n/**\n * Get the agent api object based on the modules registered in the dependency manager. For each registered module on the\n * dependency manager, the method will extract the api class from the module, resolve it and assign it to the module key\n * as provided in the agent constructor (or the {@link getDefaultAgentModules} method).\n *\n * Modules that don't have an api class defined ({@link Module.api} is undefined) will be ignored and won't be added to the\n * api object.\n *\n * If the api of a module is passed in the `excluded` array, the api will not be added to the resulting api object.\n *\n * @example\n * If the dependency manager has the following modules configured:\n * ```ts\n * {\n *   connections: DidCommConnectionsModule\n *   indy: IndyModule\n * }\n * ```\n *\n * And we call the `getAgentApi` method like this:\n * ```ts\n * const api = getAgentApi(dependencyManager)\n * ```\n *\n * the resulting agent api will look like:\n *\n * ```ts\n * {\n *   connections: ConnectionsApi\n * }\n * ```\n *\n * The `indy` module has been ignored because it doesn't define an api class.\n */\nexport function getAgentApi<AgentModules extends ModulesMap>(\n  dependencyManager: DependencyManager,\n  excludedApis: unknown[] = []\n): AgentApi<AgentModules> {\n  // Create the api object based on the `api` properties on the modules. If no `api` exists\n  // on the module it will be ignored.\n  const api = Object.entries(dependencyManager.registeredModules).reduce((api, [moduleKey, module]) => {\n    // Module has no api\n    if (!module.api) return api\n\n    const apiInstance = dependencyManager.resolve(module.api)\n\n    // Api is excluded\n    if (excludedApis.includes(apiInstance)) return api\n    // biome-ignore lint/performance/noAccumulatingSpread: no explanation\n    return { ...api, [moduleKey]: apiInstance }\n  }, {}) as AgentApi<AgentModules>\n\n  return api\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAuGA,SAAS,yBAAyB;AAChC,QAAO;EACL,YAAY,IAAI,YAAY;EAC5B,sBAAsB,IAAI,sBAAsB;EAChD,YAAY,IAAI,YAAY;EAC5B,sBAAsB,IAAI,sBAAsB;EAChD,aAAa,IAAI,YAAY,EAAE,OAAO,IAAI,6BAA6B,EAAE,OAAO,KAAK,CAAC,EAAE,CAAC;EACzF,WAAW,IAAI,+BAA+B;EAC9C,eAAe,IAAI,eAAe;EAClC,YAAY,IAAI,YAAY;EAC5B,YAAY,IAAI,YAAY;EAC5B,WAAW,IAAI,oBAAoB,EAAE,CAAC;EACvC;;;;;;;;AASH,SAAgB,gCACd,SACoC;CACpC,MAAM,sBAAsB,wBAAwB;CACpD,MAAM,yBAAyB,OAAO,KAAK,oBAAoB;CAE/D,MAAM,iBAA0C,EAAE;CAClD,MAAM,gBAAyC,OAAO,QAAQ,WAAW,EAAE,CAAC,CAAC,QAC1E,CAAC,SAAS,CAAC,uBAAuB,SAAS,IAAI,CACjD;AAGD,MAAK,MAAM,CAAC,WAAW,wBAAwB,OAAO,QAAQ,oBAAoB,CAEhF,gBAAe,KAAK,CAAC,WAAW,UAAU,cAAc,qBAAqB,CAAC,CAAC;AAGjF,QAAO,OAAO,YAAY,CAAC,GAAG,gBAAgB,GAAG,cAAc,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqClE,SAAgB,YACd,mBACA,eAA0B,EAAE,EACJ;AAexB,QAZY,OAAO,QAAQ,kBAAkB,kBAAkB,CAAC,QAAQ,KAAK,CAAC,WAAW,YAAY;AAEnG,MAAI,CAAC,OAAO,IAAK,QAAO;EAExB,MAAM,cAAc,kBAAkB,QAAQ,OAAO,IAAI;AAGzD,MAAI,aAAa,SAAS,YAAY,CAAE,QAAO;AAE/C,SAAO;GAAE,GAAG;IAAM,YAAY;GAAa;IAC1C,EAAE,CAAC"}