UNPKG

@bernierllc/validators-html-syntax

Version:

HTML syntax validation primitive - malformed tags, nesting, duplicate IDs, unclosed tags

122 lines (120 loc) 4.34 kB
"use strict"; /* Copyright (c) 2025 Bernier LLC This file is licensed to the client under a limited-use license. The client may use and modify this code *only within the scope of the project it was delivered for*. Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.validateHtmlSyntax = validateHtmlSyntax; exports.createHtmlSyntaxValidator = createHtmlSyntaxValidator; const validators_core_1 = require("@bernierllc/validators-core"); const duplicate_ids_1 = require("./rules/duplicate-ids"); const unclosed_tags_1 = require("./rules/unclosed-tags"); const invalid_nesting_1 = require("./rules/invalid-nesting"); const malformed_attributes_1 = require("./rules/malformed-attributes"); const types_1 = require("./types"); /** * HTML Syntax Validator * * Validates HTML syntax for well-formedness, proper nesting, duplicate IDs, * unclosed tags, and malformed attributes. Pure parsing validation without * semantic or accessibility concerns. * * @example * ```typescript * import { validateHtmlSyntax } from '@bernierllc/validators-html-syntax'; * * const html = '<div><p>Hello</div>'; * const result = await validateHtmlSyntax(html); * * if (result.problems.length > 0) { * console.log('HTML syntax issues found:', result.problems); * } * ``` */ async function validateHtmlSyntax(html, options = {}, utils) { const startTime = Date.now(); const opts = { ...types_1.DEFAULT_HTML_SYNTAX_OPTIONS, ...options }; const problems = []; // Collect enabled rules based on options const enabledRules = []; if (opts.checkDuplicateIds) { enabledRules.push(duplicate_ids_1.duplicateIdsRule); } if (opts.checkUnclosedTags) { enabledRules.push(unclosed_tags_1.unclosedTagsRule); } if (opts.checkInvalidNesting) { enabledRules.push(invalid_nesting_1.invalidNestingRule); } if (opts.checkMalformedAttributes) { enabledRules.push(malformed_attributes_1.malformedAttributesRule); } // Run each enabled rule for (const rule of enabledRules) { const context = (0, validators_core_1.createRuleContext)(rule.meta.id, {}, // Rules operate on string (HTML), options are passed via env/options separately utils, {}, (problem) => { problems.push(problem); }); const ruleValidator = rule.create(context); await ruleValidator(html); } const durationMs = Date.now() - startTime; return { problems, stats: { targets: 1, durationMs, rulesApplied: enabledRules.map((rule) => rule.meta.id), }, }; } /** * Create a configured HTML syntax validator * * @example * ```typescript * import { createHtmlSyntaxValidator } from '@bernierllc/validators-html-syntax'; * * const validator = createHtmlSyntaxValidator({ * checkDuplicateIds: true, * checkUnclosedTags: true, * checkInvalidNesting: false, // Disable nesting checks * }); * * const result = await validator.validate('<div id="test"><p>Content</p></div>', utils); * ``` */ function createHtmlSyntaxValidator(options = {}) { return { /** * Validate HTML syntax */ async validate(html, utils) { return validateHtmlSyntax(html, options, utils); }, /** * Get validator metadata */ getMeta() { const opts = { ...types_1.DEFAULT_HTML_SYNTAX_OPTIONS, ...options }; const enabledRules = []; if (opts.checkDuplicateIds) enabledRules.push('html-syntax/duplicate-ids'); if (opts.checkUnclosedTags) enabledRules.push('html-syntax/unclosed-tags'); if (opts.checkInvalidNesting) enabledRules.push('html-syntax/invalid-nesting'); if (opts.checkMalformedAttributes) enabledRules.push('html-syntax/malformed-attributes'); return { name: '@bernierllc/validators-html-syntax', version: '0.1.0', description: 'HTML syntax validation primitive', domain: 'parsing', enabledRules, }; }, }; }