import GlobalDefinition from './GlobalDefinition'; import { assertDefined, assertNot } from './assert'; import GlobalValue from './GlobalValue'; export default class Globals { map: Map; constructor(globals?: Globals) { this.map = globals ? new Map(globals.map) : new Map(); } keys(): string[] { return [...this.map.keys()]; } isDefined(definition: GlobalDefinition): boolean { return typeof this.map.get(definition.key) !== 'undefined'; } get(definition: GlobalDefinition): T { const element = this.map.get(definition.key) as T; assertDefined( element, `No global with key '${definition.key}' registered. Only [${[...this.map.keys()].join(',')}]`, ); return element; } getOptional(definition: GlobalDefinition): T | undefined { return this.map.get(definition.key) as T; } set(definition: GlobalDefinition, value: T) { assertNot(this.isDefined(definition), `Global with key '${definition.key}' already registered.`); this.map.set(definition.key, value); } override(definition: GlobalDefinition, value: T) { this.map.set(definition.key, value); } withValues(values: GlobalValue[] | undefined): Globals { values?.forEach((value) => { if (value.override) { this.override(value.definition, value.value); } else { this.set(value.definition, value.value); } }); return this; } }