export type Severity = "off" | "info" | "warning" | "error"; export function toSeverity(str: string): Severity { if (str === "off" || str === "info" || str === "warning" || str === "error") { return str; } else { throw new Error(`Invalid severity: ${str}`); } } export class Options { readonly severity: Severity; private readonly custom: any; constructor(severity: Severity, custom: any) { this.severity = severity; this.custom = custom; } number(option: string): number; number(option: string, or: number): number; number(option: string, or: null): number | null; number(option: string, or?: number | null): number | null { const value = this.custom[option]; if (value !== undefined && value !== null) { const parsed = parseFloat(value); if (isNaN(parsed)) { throw invalidValue(option, value); } return parsed; } if (or === undefined) { throw missingOption(option); } return or; } string(option: string): string; string(option: string, or: string): string; string(option: string, or: null): string | null; string(option: string, or?: string | null): string | null { const value = this.custom[option]; if (value !== undefined && value !== null) { if (typeof value !== "string") { throw invalidValue(option, value); } return value; } if (or === undefined) { throw missingOption(option); } return or; } stringList(option: string): string[] { const value = this.custom[option]; if (value !== undefined && value !== null) { if (typeof value === "string") { return [value]; } else if (Array.isArray(value)) { for (const item of value) { if (typeof item !== "string") { throw invalidValue(option, item); } } return value; } throw invalidValue(option, value); } return []; } } function invalidValue(option, value) { return new Error(`Invalid value for ${option}: ${value}`); } function missingOption(option) { return new Error(`Missing option: ${option}`); }