import { AutoConfigure, DeepPartial, Effects, ExpectedExports } from "../types" import { Utils, utils } from "../util" import { deepEqual } from "../util/deepEqual" import { deepMerge } from "../util/deepMerge" export type AutoConfigFrom = { [key in keyof NestedConfigs & string]: (options: { effects: Effects localConfig: Input remoteConfig: NestedConfigs[key] utils: Utils }) => Promise> } export class AutoConfig { constructor( readonly configs: AutoConfigFrom, readonly path: keyof AutoConfigFrom, ) {} async check( options: Parameters[0], ): ReturnType { const origConfig = JSON.parse(JSON.stringify(options.localConfig)) const newOptions = { ...options, utils: utils(options.effects), localConfig: options.localConfig as Input, remoteConfig: options.remoteConfig as any, } if ( !deepEqual( origConfig, deepMerge( {}, options.localConfig, await this.configs[this.path](newOptions), ), ) ) throw new Error(`Check failed for ${this.path}`) } async autoConfigure( options: Parameters[0], ): ReturnType { const newOptions = { ...options, utils: utils(options.effects), localConfig: options.localConfig as Input, remoteConfig: options.remoteConfig as any, } return deepMerge( {}, options.localConfig, await this.configs[this.path](newOptions), ) } }