{"version":3,"file":"UpdateAssistant.mjs","names":[],"sources":["../../../src/storage/migration/UpdateAssistant.ts"],"sourcesContent":["import type { BaseAgent } from '../../agent/BaseAgent'\nimport { CredoError } from '../../error'\nimport type { Module } from '../../plugins'\nimport { isFirstVersionEqualToSecond, isFirstVersionHigherThanSecond, parseVersionString } from '../../utils/version'\nimport { StorageUpdateError } from './error/StorageUpdateError'\n\nimport { StorageUpdateService } from './StorageUpdateService'\nimport type { Update, UpdateConfig, UpdateToVersion } from './updates'\nimport { CURRENT_FRAMEWORK_STORAGE_VERSION, DEFAULT_UPDATE_CONFIG, supportedUpdates } from './updates'\n\nexport interface UpdateAssistantUpdateOptions {\n  updateToVersion?: UpdateToVersion\n}\n\n// biome-ignore lint/suspicious/noExplicitAny: no explanation\nexport class UpdateAssistant<Agent extends BaseAgent<any> = BaseAgent> {\n  private agent: Agent\n  private storageUpdateService: StorageUpdateService\n  private updateConfig: UpdateConfig\n\n  public constructor(agent: Agent, updateConfig: UpdateConfig = DEFAULT_UPDATE_CONFIG) {\n    this.agent = agent\n    this.updateConfig = updateConfig\n\n    this.storageUpdateService = this.agent.dependencyManager.resolve(StorageUpdateService)\n  }\n\n  public async initialize() {\n    if (this.agent.isInitialized) {\n      throw new CredoError(\"Can't initialize UpdateAssistant after agent is initialized\")\n    }\n  }\n\n  public async isUpToDate(updateToVersion?: UpdateToVersion) {\n    return this.storageUpdateService.isUpToDate(this.agent.context, updateToVersion)\n  }\n\n  public async getCurrentAgentStorageVersion() {\n    return this.storageUpdateService.getCurrentStorageVersion(this.agent.context)\n  }\n\n  public static get frameworkStorageVersion() {\n    return CURRENT_FRAMEWORK_STORAGE_VERSION\n  }\n\n  public async getNeededUpdates(toVersion?: UpdateToVersion) {\n    const currentStorageVersion = parseVersionString(\n      await this.storageUpdateService.getCurrentStorageVersion(this.agent.context)\n    )\n\n    const parsedToVersion = toVersion ? parseVersionString(toVersion) : undefined\n\n    // If the current storage version is higher or equal to the toVersion, we can't update, so return empty array\n    if (\n      parsedToVersion &&\n      (isFirstVersionHigherThanSecond(currentStorageVersion, parsedToVersion) ||\n        isFirstVersionEqualToSecond(currentStorageVersion, parsedToVersion))\n    ) {\n      return []\n    }\n\n    // Filter updates. We don't want older updates we already applied\n    // or aren't needed because the wallet was created after the update script was made\n    const neededUpdates = supportedUpdates.filter((update) => {\n      const updateToVersion = parseVersionString(update.toVersion)\n\n      // If the update toVersion is higher than the wanted toVersion, we skip the update\n      if (parsedToVersion && isFirstVersionHigherThanSecond(updateToVersion, parsedToVersion)) {\n        return false\n      }\n\n      // if an update toVersion is higher than currentStorageVersion we want to to include the update\n      return isFirstVersionHigherThanSecond(updateToVersion, currentStorageVersion)\n    })\n\n    // The current storage version is too old to update\n    if (\n      neededUpdates.length > 0 &&\n      isFirstVersionHigherThanSecond(parseVersionString(neededUpdates[0].fromVersion), currentStorageVersion)\n    ) {\n      throw new CredoError(\n        `First fromVersion is higher than current storage version. You need to use an older version of the framework to update to at least version ${neededUpdates[0].fromVersion}`\n      )\n    }\n\n    const lastUpdateToVersion = neededUpdates.length > 0 ? neededUpdates[neededUpdates.length - 1].toVersion : undefined\n    if (toVersion && lastUpdateToVersion && lastUpdateToVersion !== toVersion) {\n      throw new CredoError(\n        `No update found for toVersion ${toVersion}. Make sure the toVersion is a valid version you can update to`\n      )\n    }\n\n    return neededUpdates\n  }\n\n  public async update(options?: UpdateAssistantUpdateOptions) {\n    const updateIdentifier = Date.now().toString()\n    const updateToVersion = options?.updateToVersion\n\n    try {\n      this.agent.config.logger.info(`Starting update of agent storage with updateIdentifier ${updateIdentifier}`)\n      const neededUpdates = await this.getNeededUpdates(updateToVersion)\n\n      const currentStorageVersion = parseVersionString(\n        await this.storageUpdateService.getCurrentStorageVersion(this.agent.context)\n      )\n      const parsedToVersion = updateToVersion ? parseVersionString(updateToVersion) : undefined\n\n      // If the current storage version is higher or equal to the toVersion, we can't update.\n      if (\n        parsedToVersion &&\n        (isFirstVersionHigherThanSecond(currentStorageVersion, parsedToVersion) ||\n          isFirstVersionEqualToSecond(currentStorageVersion, parsedToVersion))\n      ) {\n        throw new StorageUpdateError(\n          `Can't update to version ${updateToVersion} because it is lower or equal to the current agent storage version ${currentStorageVersion[0]}.${currentStorageVersion[1]}}`\n        )\n      }\n\n      if (neededUpdates.length === 0) {\n        this.agent.config.logger.info('No update needed. Agent storage is up to date.')\n        return\n      }\n\n      const fromVersion = neededUpdates[0].fromVersion\n      const toVersion = neededUpdates[neededUpdates.length - 1].toVersion\n\n      this.agent.config.logger.info(\n        `Starting update process. Total of ${neededUpdates.length} update(s) will be applied to update the agent storage from version ${fromVersion} to version ${toVersion}`\n      )\n\n      try {\n        for (const update of neededUpdates) {\n          const registeredModules = Object.values(this.agent.dependencyManager.registeredModules)\n          const modulesWithUpdate: Array<{ module: Module; update: Update }> = []\n\n          // Filter modules that have an update script for the current update\n          for (const registeredModule of registeredModules) {\n            const moduleUpdate = registeredModule.updates?.find(\n              (module) => module.fromVersion === update.fromVersion && module.toVersion === update.toVersion\n            )\n\n            if (moduleUpdate) {\n              modulesWithUpdate.push({\n                module: registeredModule,\n                update: moduleUpdate,\n              })\n            }\n          }\n\n          this.agent.config.logger.info(\n            `Starting update of agent storage from version ${update.fromVersion} to version ${update.toVersion}. Found ${modulesWithUpdate.length} extension module(s) with update scripts`\n          )\n          await update.doUpdate(this.agent)\n\n          this.agent.config.logger.info(\n            `Finished update of core agent storage from version ${update.fromVersion} to version ${update.toVersion}. Starting update of extension modules`\n          )\n\n          for (const moduleWithUpdate of modulesWithUpdate) {\n            this.agent.config.logger.info(\n              `Starting update of extension module ${moduleWithUpdate.module.constructor.name} from version ${moduleWithUpdate.update.fromVersion} to version ${moduleWithUpdate.update.toVersion}`\n            )\n            await moduleWithUpdate.update.doUpdate(this.agent, this.updateConfig)\n            this.agent.config.logger.info(\n              `Finished update of extension module ${moduleWithUpdate.module.constructor.name} from version ${moduleWithUpdate.update.fromVersion} to version ${moduleWithUpdate.update.toVersion}`\n            )\n          }\n\n          // Update the framework version in storage\n          await this.storageUpdateService.setCurrentStorageVersion(this.agent.context, update.toVersion)\n          this.agent.config.logger.info(\n            `Successfully updated agent storage from version ${update.fromVersion} to version ${update.toVersion}`\n          )\n        }\n      } catch (error) {\n        this.agent.config.logger.fatal('An error occurred while updating the wallet.', {\n          error,\n        })\n\n        throw error\n      }\n    } catch (error) {\n      this.agent.config.logger.error(`Error updating storage (updateIdentifier: ${updateIdentifier})`, {\n        cause: error,\n      })\n\n      throw new StorageUpdateError(`Error updating storage (updateIdentifier: ${updateIdentifier}): ${error.message}`, {\n        cause: error,\n      })\n    }\n\n    return updateIdentifier\n  }\n}\n"],"mappings":"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"}