import { DeepPartial, Dependencies, Effects, ExpectedExports } from "../types" import { InputSpec } from "./configTypes" import { SDKManifest } from "../manifest/ManifestTypes" import * as D from "./dependencies" import { Config, ExtractConfigType } from "./builder/config" import { Utils, utils } from "../util" import nullIfEmpty from "../util/nullIfEmpty" declare const dependencyProof: unique symbol export type DependenciesReceipt = void & { [dependencyProof]: never } export type Save< WD, A extends Record | Config, any>, Manifest extends SDKManifest, > = (options: { effects: Effects input: ExtractConfigType & Record utils: Utils dependencies: D.Dependencies }) => Promise<{ dependenciesReceipt: DependenciesReceipt restart: boolean }> export type Read< WD, A extends Record | Config, any>, > = (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< WD, ConfigType extends Record | Config, Manifest extends SDKManifest, Type extends Record = ExtractConfigType, >( spec: Config, write: Save, read: Read, ) { const validator = spec.validator return { setConfig: (async ({ effects, input }) => { if (!validator.test(input)) { await effects.console.error(String(validator.errorMessage(input))) return { error: "Set config type error for config" } } const { restart } = await write({ input: JSON.parse(JSON.stringify(input)), effects, utils: utils(effects), dependencies: D.dependenciesSet(), }) 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, }), config: configValue, } }) as ExpectedExports.getConfig, } } export default setupConfig