import { Document , Element } from "parse5" ; import { isElement } from "./helpers/nodeMatchers" ; const assertIsString = ( str , name ) : string => { if ( typeof str === "undefined" ) { throw new TypeError ( `Microformats parser: ${ name } not provided` ) ; } if ( typeof str !== "string" ) { throw new TypeError ( `Microformats parser: ${ name } is not a string` ) ; } if ( str === "" ) { throw new TypeError ( `Microformats parser: ${ name } cannot be empty` ) ; } return str ; } ; const assertIsBoolean = ( bool , name ) : boolean => { if ( typeof bool !== "boolean" ) { throw new TypeError ( `Microformats parser: ${ name } is not a boolean` ) ; } return bool ; } ; const assertIsObject = ( obj , allowedKeys , name ) : Record < string , unknown > => { if ( typeof obj === "undefined" ) { throw new TypeError ( `Microformats parser: ${ name } is not provided` ) ; } if ( typeof obj !== "object" ) { throw new TypeError ( `Microformats parser: ${ name } is not an object` ) ; } if ( Array . isArray ( obj ) ) { throw new TypeError ( `Microformats parser: ${ name } is not an object` ) ; } if ( obj === null ) { throw new TypeError ( `Microformats parser: ${ name } cannot be null` ) ; } const unknownKeys = Object . keys ( obj ) . filter ( ( key ) => ! allowedKeys . includes ( key ) ) ; if ( unknownKeys . length ) { throw new TypeError ( `Microformats parser: ${ name } contains unknown properties: ${ unknownKeys . join ( ", " ) }` ) ; } return obj as Record < string , unknown > ; } ; export const validator = ( unknownHtml , unknownOptions ) : void => { assertIsString ( unknownHtml , "HTML" ) ; const options = assertIsObject ( unknownOptions , [ "baseUrl" , "experimental" ] , "options" ) ; const baseUrl = assertIsString ( options . baseUrl , "baseUrl" ) ; new URL ( baseUrl ) ; if ( "experimental" in options ) { const experimental = assertIsObject ( options . experimental , [ "lang" , "textContent" ] , "experimental" ) ; if ( "lang" in experimental ) { assertIsBoolean ( experimental . lang , "experimental.lang" ) ; } if ( "textContent" in experimental ) { assertIsBoolean ( experimental . textContent , "experimental.textContent" ) ; } } } ; export const validateParsedHtml = ( doc ) : void => { const html = doc . childNodes . find ( ( child ) : child is Element => isElement ( child ) && child . tagName === "html" ) ; if ( ! html ) { throw new Error ( "Microformats parser: No <html> element found" ) ; } const body = html . childNodes . find ( ( child ) : child is Element => isElement ( child ) && child . tagName === "body" ) ; if ( ! body ) { throw new Error ( "Microformats parser: No <body> element found" ) ; } if ( ! body . childNodes . filter ( isElement ) . length ) { throw new Error ( "Microformats parser: unable to parse HTML" ) ; } } ;