import * as plugins from '../../plugins.ts'; import { logger } from '../../logging.ts'; import type { OpsServer } from '../classes.opsserver.ts'; import * as interfaces from '../../../ts_interfaces/index.ts'; import { requireValidIdentity } from '../helpers/guards.ts'; export class AppStoreHandler { public typedrouter = new plugins.typedrequest.TypedRouter(); constructor(private opsServerRef: OpsServer) { this.opsServerRef.typedrouter.addTypedRouter(this.typedrouter); this.registerHandlers(); } private registerHandlers(): void { // Get app templates (catalog) this.typedrouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'getAppTemplates', async (dataArg) => { await requireValidIdentity(this.opsServerRef.adminHandler, dataArg); const apps = await this.opsServerRef.oneboxRef.appStore.getApps(); return { apps }; }, ), ); // Get app config for a specific version this.typedrouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'getAppConfig', async (dataArg) => { await requireValidIdentity(this.opsServerRef.adminHandler, dataArg); const config = await this.opsServerRef.oneboxRef.appStore.getAppVersionConfig( dataArg.appId, dataArg.version, ); const appMeta = await this.opsServerRef.oneboxRef.appStore.getAppMeta(dataArg.appId); return { config, appMeta }; }, ), ); // Get services with available upgrades this.typedrouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'getUpgradeableServices', async (dataArg) => { await requireValidIdentity(this.opsServerRef.adminHandler, dataArg); const services = await this.opsServerRef.oneboxRef.appStore.getUpgradeableServices(); return { services }; }, ), ); // Upgrade a service to a new template version this.typedrouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'upgradeService', async (dataArg) => { await requireValidIdentity(this.opsServerRef.adminHandler, dataArg); const existingService = this.opsServerRef.oneboxRef.database.getServiceByName(dataArg.serviceName); if (!existingService) { throw new plugins.typedrequest.TypedResponseError(`Service not found: ${dataArg.serviceName}`); } if (!existingService.appTemplateId) { throw new plugins.typedrequest.TypedResponseError('Service was not deployed from an app template'); } if (!existingService.appTemplateVersion) { throw new plugins.typedrequest.TypedResponseError('Service has no tracked template version'); } logger.info(`Upgrading service '${dataArg.serviceName}' from v${existingService.appTemplateVersion} to v${dataArg.targetVersion}`); // Execute migration const migrationResult = await this.opsServerRef.oneboxRef.appStore.executeMigration( existingService, existingService.appTemplateVersion, dataArg.targetVersion, ); if (!migrationResult.success) { throw new plugins.typedrequest.TypedResponseError( `Migration failed: ${migrationResult.warnings.join('; ')}`, ); } // Apply the upgrade const updatedService = await this.opsServerRef.oneboxRef.appStore.applyUpgrade( dataArg.serviceName, migrationResult, dataArg.targetVersion, ); return { service: updatedService, warnings: migrationResult.warnings, }; }, ), ); } }