packages/charts/src/common/config_objects.ts (60 lines of code) (raw):

/* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License * 2.0 and the Server Side Public License, v 1; you may not use this file except * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ interface PlainConfigItem { type: 'group' | 'color' | 'string' | 'boolean' | 'number'; dflt?: any; min?: number; max?: number; reconfigurable?: boolean | string; values?: unknown; documentation?: string; } interface GroupConfigItem extends PlainConfigItem { type: 'group'; values: Record<string, PlainConfigItem>; } // switching to `io-ts` style, generic way of combining static and runtime type info - 1st step class Type<A> { dflt: A; reconfigurable: boolean | string; documentation: string; constructor(dflt: A, reconfigurable: boolean | string, documentation: string) { this.dflt = dflt; this.reconfigurable = reconfigurable; this.documentation = documentation; } } /** @internal */ export class Numeric extends Type<number> { min: number; max: number; type = 'number'; constructor({ dflt, min, max, reconfigurable, documentation, }: { dflt: number; min: number; max: number; reconfigurable: boolean | string; documentation: string; }) { super(dflt, reconfigurable, documentation); this.min = min; this.max = max; } } /** @internal */ export type ConfigItem = PlainConfigItem | Numeric; function isGroupConfigItem(item: ConfigItem): item is GroupConfigItem { return item.type === 'group'; } /** todo switch to `io-ts` style, generic way of combining static and runtime type info * @internal */ export function configMap<Conf>(mapper: (v: ConfigItem) => unknown, cfgMetadata: Record<string, ConfigItem>): Conf { return Object.assign( {}, ...Object.entries(cfgMetadata).map(([k, v]: [string, ConfigItem]) => { if (isGroupConfigItem(v)) { return { [k]: configMap<Conf>(mapper, v.values) }; } return { [k]: mapper(v) }; }), ); }