UNPKG

piral-configs

Version:

Plugin for dynamic configurations of pilets in Piral.

70 lines (59 loc) 1.86 kB
import { PiralPlugin } from 'piral-core'; import { Validator, Schema } from 'jsonschema'; import type { PiletConfigsApi } from './types'; /** * Available configuration options for the configs plugin. */ export interface ConfigsConfig { /** * Sets the retriever function for getting the app or user configuration. * @default undefined */ retrieve?<T>(configName: string): T | undefined; } export function createConfigsApi(config: ConfigsConfig = {}): PiralPlugin<PiletConfigsApi> { const readConfig = (name: string, defaultConfig: any) => { const key = `config-${name}`; const current = config.retrieve?.(key); if (typeof current === 'object') { return { ...defaultConfig, ...current, }; } else if (typeof current !== 'undefined') { return current; } else { return undefined; } }; const validate = (schema: Schema, proposedConfig: any, defaultConfig: any) => { const validator = new Validator(); const result = validator.validate(proposedConfig, schema); if (!result.valid) { console.warn( `The given configuration does not match the provided schema. Taking the default configuration.`, proposedConfig, result, ); return defaultConfig; } return proposedConfig; }; return (ctx) => (_, meta) => ({ defineConfigSchema(schema, defaultConfig) { const proposedConfig = readConfig(meta.name, defaultConfig); const current = proposedConfig ? validate(schema, proposedConfig, defaultConfig) : defaultConfig; ctx.dispatch((state) => ({ ...state, configs: { ...state.configs, [meta.name]: current, }, })); return current; }, getCurrentConfig() { return ctx.readState((s) => s.configs[meta.name]) ?? {}; }, }); }