import { Configuration } from "./configuration.ts"; import { Structure } from "./structure.ts"; export interface ConfigurationDescription { fallback: unknown; fields: Record[]; } export interface ConfigurationSpecification { (property: string): ConfigurationDescription; } export function getSpecification( value: any, ): ConfigurationSpecification | undefined { return typeof value[Configuration.spec] === "function" ? value[Configuration.spec] : undefined; } export function _objectSpec( options: Record>, ): ConfigurationSpecification { return (property: string) => { const fallback: Record = {}; const fields: Record[] = []; for (const [key, struct] of Object.entries(options)) { const childName = (property ? property + "." : "") + key; const childSpec = getSpecification(struct)?.(childName); if (childSpec) { fallback[key] = childSpec.fallback; fields.push(...childSpec.fields); } } return { fallback, fields }; }; } export function _arraySpec( options: Structure, ): ConfigurationSpecification { return (property: string) => { const childName = !property ? "[]" : property + "[]"; const childSpec = getSpecification(options)?.(childName); if (!childSpec) return { fallback: [], fields: [] }; return { fallback: [], fields: childSpec.fields, }; }; } export interface PrimativeOptions { variable?: string; flag?: string; fallback: T; } export function _primativeSpec(type: string, options: PrimativeOptions) { return (property: string) => ({ fallback: options.fallback, fields: [ { ...options, name: property, type: type, fallback: options.fallback?.toString(), }, ], }); }