import { Effects, ExpectedExports } from "../types" import { SDKManifest } from "../manifest/ManifestTypes" import * as D from "./configDependencies" import { Config, ExtractConfigType } from "./builder/config" import { Utils, utils } from "../util/utils" import nullIfEmpty from "../util/nullIfEmpty" import { InterfaceReceipt } from "../interfaces/interfaceReceipt" import { InterfacesReceipt as InterfacesReceipt } from "../interfaces/setupInterfaces" declare const dependencyProof: unique symbol export type DependenciesReceipt = void & { [dependencyProof]: never } export type Save< Store, A extends | Record | Config, any> | Config, never>, Manifest extends SDKManifest, > = (options: { effects: Effects input: ExtractConfigType & Record utils: Utils dependencies: D.ConfigDependencies }) => Promise<{ dependenciesReceipt: DependenciesReceipt interfacesReceipt: InterfacesReceipt restart: boolean }> export type Read< Manifest extends SDKManifest, Store, A extends | Record | Config, any> | Config, never>, > = (options: { effects: Effects utils: Utils }) => Promise & Record)> /** * We want to setup a config export with a get and set, this * is going to be the default helper to setup config, because it will help * enforce that we have a spec, write, and reading. * @param options * @returns */ export function setupConfig< Store, ConfigType extends | Record | Config | Config, Manifest extends SDKManifest, Type extends Record = ExtractConfigType, >( spec: Config | Config, write: Save, read: Read, ) { const validator = spec.validator return { setConfig: (async ({ effects, input }) => { if (!validator.test(input)) { await console.error(String(validator.errorMessage(input))) return { error: "Set config type error for config" } } await effects.clearBindings() await effects.clearNetworkInterfaces() const { restart } = await write({ input: JSON.parse(JSON.stringify(input)), effects, utils: utils(effects), dependencies: D.configDependenciesSet(), }) if (restart) { await effects.restart() } }) as ExpectedExports.setConfig, getConfig: (async ({ effects }) => { const myUtils = utils(effects) const configValue = nullIfEmpty( (await read({ effects, utils: myUtils })) || null, ) return { spec: await spec.build({ effects, utils: myUtils as any, }), config: configValue, } }) as ExpectedExports.getConfig, } } export default setupConfig