import { Config } from "./builder" import { DeepPartial, Dependencies, Effects, ExpectedExports } from "../types" import { InputSpec } from "./configTypes" import { Utils, nullIfEmpty, once, utils } from "../util" import { TypeFromProps } from "../util/propertiesMatcher" import { GenericManifest } from "../manifest/ManifestTypes" import * as D from "./dependencies" declare const dependencyProof: unique symbol export type DependenciesReceipt = void & { [dependencyProof]: never } export type Save = (options: { effects: Effects input: A utils: Utils dependencies: D.Dependencies }) => Promise export type Read = (options: { effects: Effects utils: Utils }) => Promise> /** * 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, A extends Config, Manifest extends GenericManifest, >( spec: A, write: Save, Manifest>, read: Read>, ) { const validator = once(() => 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" } } await write({ input: JSON.parse(JSON.stringify(input)), effects, utils: utils(effects), dependencies: D.dependenciesSet(), }) }) as ExpectedExports.setConfig, getConfig: (async ({ effects, config }) => { return { spec: spec.build(), config: nullIfEmpty( (await read({ effects, utils: utils(effects) })) || null, ), } }) as ExpectedExports.getConfig, } } export default setupConfig