import { childScope, has, makeParser, numberIn, optionalNumberIn, report, type Scope, } from './parse-helpers'; import type { WaterContentConfig } from './rule-config.types'; const MIN_WATER_PERCENT = 10; const MAX_WATER_PERCENT = 30; const MAX_HONEY_TYPES = 50; const MAX_HONEY_TYPE_LENGTH = 100; export const DEFAULT_WATER_CONTENT_CONFIG: WaterContentConfig = { warnAbovePercent: 18, confirmAbovePercent: 20, byHoneyType: {}, }; function percent(scope: Scope, key: string, fallback: number): number { return numberIn(scope, key, fallback, MIN_WATER_PERCENT, MAX_WATER_PERCENT); } const ORDER_MESSAGE = 'Die Warnschwelle darf nicht über der Bestätigungsschwelle liegen.'; function readHoneyTypes(scope: Scope): WaterContentConfig['byHoneyType'] { const types = childScope(scope, 'byHoneyType'); const names = Object.keys(types.raw); if (names.length > MAX_HONEY_TYPES) { report(scope, 'byHoneyType', `Höchstens ${MAX_HONEY_TYPES} Sorten.`); return {}; } const entries: [ string, { warnAbovePercent?: number; confirmAbovePercent?: number }, ][] = []; for (const name of names) { if (name.length === 0 || name.length > MAX_HONEY_TYPE_LENGTH) { report(types, name.slice(0, 30), 'Der Sortenname ist ungültig.'); continue; } const entry = childScope(types, name); const before = entry.issues.length; const value: { warnAbovePercent?: number; confirmAbovePercent?: number } = {}; const warn = optionalNumberIn( entry, 'warnAbovePercent', MIN_WATER_PERCENT, MAX_WATER_PERCENT, ); const confirm = optionalNumberIn( entry, 'confirmAbovePercent', MIN_WATER_PERCENT, MAX_WATER_PERCENT, ); if (warn !== undefined && confirm !== undefined && warn > confirm) { report(entry, 'warnAbovePercent', ORDER_MESSAGE); } if (entry.issues.length > before) { continue; } if (warn !== undefined) { value.warnAbovePercent = warn; } if (confirm !== undefined) { value.confirmAbovePercent = confirm; } entries.push([name, value]); } // fromEntries defines own properties, so a name like "__proto__" is harmless. return Object.fromEntries(entries); } export const waterContentParser = makeParser( 'HONEY_WATER_CONTENT', DEFAULT_WATER_CONTENT_CONFIG, (scope) => { const d = DEFAULT_WATER_CONTENT_CONFIG; let warnAbovePercent = percent( scope, 'warnAbovePercent', d.warnAbovePercent, ); let confirmAbovePercent = percent( scope, 'confirmAbovePercent', d.confirmAbovePercent, ); if (warnAbovePercent > confirmAbovePercent) { report( scope, has(scope, 'warnAbovePercent') ? 'warnAbovePercent' : 'confirmAbovePercent', ORDER_MESSAGE, ); warnAbovePercent = d.warnAbovePercent; confirmAbovePercent = d.confirmAbovePercent; } return { warnAbovePercent, confirmAbovePercent, byHoneyType: readHoneyTypes(scope), }; }, );