import { ValidationError } from "../ValidationError.js"; export class DnsTool { static allowWhitespaceAroundSeparator; static fields = []; constructor(text) { this.text = text; } tokenize() { throw new Error("Unimplemented"); } getKeyValues() { const result = []; for (const token of this.tokenize()) { const key = token.match(/^\w*/)[0]; const field = this.constructor.fields.find(f => f.key === key); if (!field) { throw new ValidationError(`Unknown field: ${key}`); } const wsp = this.constructor.allowWhitespaceAroundSeparator ? "\\s*" : ""; const separator = new RegExp(wsp + field.separator + wsp); const value = token.split(separator)[1]; if (!value) { throw new ValidationError(`Field "${key}" is missing a value`); } result.push({ key, value }); } return result; } validate() { const values = this.getKeyValues(); for (const field of this.constructor.fields) { if (field.isRequired && !values.some(v => v.key === field.key)) { throw new ValidationError(`Field "${field.key}" is required`); } } let lastPos = 0; for (let i = 0; i < values.length; i++) { const input = values[i]; const field = this.constructor.fields.find(f => f.key === input.key); if (!field) { throw new ValidationError(`Unknown field: ${input.key}`); } if (field.position < lastPos) { const lastField = this.constructor.fields.find(f => f.key === values[i-1].key); throw new ValidationError(`Field "${lastField.key}" must come after "${field.key}"`); } field.validate(input.value); lastPos = field.position; } return true; } }